1 // Copyright 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.
5 #include "media/filters/h264_bitstream_buffer.h"
7 #include "base/sys_byteorder.h"
11 H264BitstreamBuffer::H264BitstreamBuffer() : data_(NULL
) {
15 H264BitstreamBuffer::~H264BitstreamBuffer() {
20 void H264BitstreamBuffer::Reset() {
30 bits_left_in_reg_
= kRegBitSize
;
33 void H264BitstreamBuffer::Grow() {
34 data_
= static_cast<uint8
*>(realloc(data_
, capacity_
+ kGrowBytes
));
35 CHECK(data_
) << "Failed growing the buffer";
36 capacity_
+= kGrowBytes
;
39 void H264BitstreamBuffer::FlushReg() {
40 // Flush all bytes that have at least one bit cached, but not more
41 // (on Flush(), reg_ may not be full).
42 size_t bits_in_reg
= kRegBitSize
- bits_left_in_reg_
;
46 size_t bytes_in_reg
= (bits_in_reg
+ 7) / 8;
47 reg_
<<= (kRegBitSize
- bits_in_reg
);
49 // Convert to MSB and append as such to the stream.
50 reg_
= base::HostToNet64(reg_
);
52 // Make sure we have enough space. Grow() will CHECK() on allocation failure.
53 if (pos_
+ bytes_in_reg
< capacity_
)
56 memcpy(data_
+ pos_
, ®_
, bytes_in_reg
);
60 bits_left_in_reg_
= kRegBitSize
;
63 void H264BitstreamBuffer::AppendU64(size_t num_bits
, uint64 val
) {
64 CHECK_LE(num_bits
, kRegBitSize
);
66 while (num_bits
> 0) {
67 if (bits_left_in_reg_
== 0)
70 uint64 bits_to_write
=
71 num_bits
> bits_left_in_reg_
? bits_left_in_reg_
: num_bits
;
72 uint64 val_to_write
= (val
>> (num_bits
- bits_to_write
));
73 if (bits_to_write
< 64)
74 val_to_write
&= ((1ull << bits_to_write
) - 1);
75 reg_
<<= bits_to_write
;
77 num_bits
-= bits_to_write
;
78 bits_left_in_reg_
-= bits_to_write
;
82 void H264BitstreamBuffer::AppendBool(bool val
) {
83 if (bits_left_in_reg_
== 0)
87 reg_
|= (static_cast<uint64
>(val
) & 1);
91 void H264BitstreamBuffer::AppendSE(int val
) {
93 AppendUE(val
* 2 - 1);
98 void H264BitstreamBuffer::AppendUE(unsigned int val
) {
100 unsigned int v
= val
+ 1;
107 AppendBits(num_zeros
, 0);
108 AppendBits(num_zeros
+ 1, val
+ 1);
111 #define DCHECK_FINISHED() \
112 DCHECK_EQ(bits_left_in_reg_, kRegBitSize) << "Pending bits not yet written " \
113 "to the buffer, call " \
114 "FinishNALU() first."
116 void H264BitstreamBuffer::BeginNALU(H264NALU::Type nalu_type
, int nal_ref_idc
) {
119 DCHECK_LE(nalu_type
, H264NALU::kEOStream
);
120 DCHECK_GE(nal_ref_idc
, 0);
121 DCHECK_LE(nal_ref_idc
, 3);
123 AppendBits(32, 0x00000001);
124 AppendBits(1, 0); // forbidden_zero_bit
125 AppendBits(2, nal_ref_idc
);
126 AppendBits(5, nalu_type
);
129 void H264BitstreamBuffer::FinishNALU() {
130 // RBSP stop one bit.
133 // Byte-alignment zero bits.
134 AppendBits(bits_left_in_reg_
% 8, 0);
136 if (bits_left_in_reg_
!= kRegBitSize
)
140 size_t H264BitstreamBuffer::BytesInBuffer() {
145 uint8
* H264BitstreamBuffer::data() {