OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "media/filters/h264_bitstream_buffer.h" | |
6 | |
7 #include "base/sys_byteorder.h" | |
8 #include "cc/base/util.h" | |
9 | |
10 namespace media { | |
11 | |
12 H264BitstreamBuffer::H264BitstreamBuffer() : data_(NULL) { | |
13 Reset(); | |
14 } | |
15 | |
16 H264BitstreamBuffer::~H264BitstreamBuffer() { | |
17 free(data_); | |
18 data_ = NULL; | |
19 } | |
20 | |
21 void H264BitstreamBuffer::Reset() { | |
22 free(data_); | |
23 data_ = NULL; | |
24 | |
25 capacity_ = 0; | |
26 pos_ = 0; | |
27 reg_ = 0; | |
28 | |
29 Grow(); | |
30 | |
31 bits_left_in_reg_ = kRegBitSize; | |
32 } | |
33 | |
34 void H264BitstreamBuffer::Grow() { | |
35 data_ = static_cast<uint8*>(realloc(data_, capacity_ + kGrowBytes)); | |
36 CHECK(data_) << "Failed growing the buffer"; | |
wuchengli
2014/06/18 15:57:44
This is not a programming error and shouldn't use
Pawel Osciak
2014/06/19 01:31:11
It actually would be. Allocations in Chrome cannot
wuchengli
2014/06/19 04:28:34
Interesting. You mean we should CHECK the result o
Pawel Osciak
2014/06/19 04:57:42
No, I'm just overly fastidious.
Check out https://
| |
37 capacity_ += kGrowBytes; | |
38 } | |
39 | |
40 void H264BitstreamBuffer::FlushReg() { | |
41 // Flush all bytes that have at least one bit cached, but not more | |
42 // (on Flush(), reg_ may not be full). | |
43 size_t bits_in_reg = kRegBitSize - bits_left_in_reg_; | |
44 if (bits_in_reg == 0) | |
45 return; | |
46 | |
47 size_t bytes_in_reg = (bits_in_reg + 7) / 8; | |
48 reg_ <<= (kRegBitSize - bits_in_reg); | |
49 | |
50 // Convert to MSB and append as such to the stream. | |
51 reg_ = base::HostToNet64(reg_); | |
52 | |
53 // Make sure we have enough space. Grow() will CHECK() on allocation failure. | |
54 if (pos_ + bytes_in_reg < capacity_) | |
55 Grow(); | |
56 | |
57 memcpy(data_ + pos_, ®_, bytes_in_reg); | |
58 pos_ += bytes_in_reg; | |
59 | |
60 reg_ = 0; | |
61 bits_left_in_reg_ = kRegBitSize; | |
62 } | |
63 | |
64 void H264BitstreamBuffer::AppendU64(size_t num_bits, uint64 val) { | |
65 CHECK_LE(num_bits, kRegBitSize); | |
66 | |
67 while (num_bits > 0) { | |
68 if (bits_left_in_reg_ == 0) | |
69 FlushReg(); | |
70 | |
71 uint64 bits_to_write = | |
72 num_bits > bits_left_in_reg_ ? bits_left_in_reg_ : num_bits; | |
73 uint64 val_to_write = (val >> (num_bits - bits_to_write)); | |
74 if (bits_to_write < 64) | |
75 val_to_write &= ((1ull << bits_to_write) - 1); | |
76 reg_ <<= bits_to_write; | |
77 reg_ |= val_to_write; | |
78 num_bits -= bits_to_write; | |
79 bits_left_in_reg_ -= bits_to_write; | |
80 } | |
81 } | |
82 | |
83 void H264BitstreamBuffer::AppendBool(bool val) { | |
84 if (bits_left_in_reg_ == 0) | |
85 FlushReg(); | |
86 | |
87 reg_ <<= 1; | |
88 reg_ |= (static_cast<uint64>(val) & 1); | |
89 --bits_left_in_reg_; | |
90 } | |
91 | |
92 void H264BitstreamBuffer::AppendSE(int val) { | |
93 if (val > 0) | |
94 AppendUE(val * 2 - 1); | |
95 else | |
96 AppendUE(-val * 2); | |
97 } | |
98 | |
99 void H264BitstreamBuffer::AppendUE(unsigned int val) { | |
100 size_t num_zeros = 0; | |
101 unsigned int v = val + 1; | |
102 | |
103 while (v > 1) { | |
104 v >>= 1; | |
105 ++num_zeros; | |
106 } | |
107 | |
108 AppendBits(num_zeros, 0); | |
109 AppendBits(num_zeros + 1, val + 1); | |
110 } | |
111 | |
112 #define DCHECK_FINISHED() \ | |
113 DCHECK_EQ(bits_left_in_reg_, kRegBitSize) << "Pending bits not yet written " \ | |
114 "to the buffer, call " \ | |
115 "FinishNALU() first." | |
116 | |
117 void H264BitstreamBuffer::BeginNALU(H264NALU::Type nalu_type, int nal_ref_idc) { | |
118 DCHECK_FINISHED(); | |
119 | |
120 DCHECK_LE(nalu_type, H264NALU::kEOStream); | |
121 DCHECK_GE(nal_ref_idc, 0); | |
122 DCHECK_LE(nal_ref_idc, 3); | |
123 | |
124 AppendBits(32, 0x00000001); | |
125 AppendBits(1, 0); // forbidden_zero_bit | |
126 AppendBits(2, nal_ref_idc); | |
127 AppendBits(5, nalu_type); | |
128 } | |
129 | |
130 void H264BitstreamBuffer::FinishNALU() { | |
131 // RBSP stop one bit. | |
132 AppendBits(1, 1); | |
133 | |
134 // Byte-alignment zero bits. | |
135 AppendBits(bits_left_in_reg_ % 8, 0); | |
136 | |
137 if (bits_left_in_reg_ != kRegBitSize) | |
138 FlushReg(); | |
139 } | |
140 | |
141 size_t H264BitstreamBuffer::BytesInBuffer() { | |
142 DCHECK_FINISHED(); | |
143 return pos_; | |
144 } | |
145 | |
146 uint8* H264BitstreamBuffer::data() { | |
147 DCHECK(data_); | |
148 DCHECK_FINISHED(); | |
149 | |
150 return data_; | |
151 } | |
152 | |
153 } // namespace media | |
OLD | NEW |