1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 // Derived from Stagefright's ABitReader.
11 BitReader::BitReader(const mozilla::MediaByteBuffer
* aBuffer
)
12 : BitReader(aBuffer
->Elements(), aBuffer
->Length() * 8) {}
14 BitReader::BitReader(const mozilla::MediaByteBuffer
* aBuffer
, size_t aBits
)
15 : BitReader(aBuffer
->Elements(), aBits
) {}
17 BitReader::BitReader(const uint8_t* aBuffer
, size_t aBits
)
19 mOriginalBitSize(aBits
),
20 mTotalBitsLeft(aBits
),
21 mSize((aBits
+ 7) / 8),
25 BitReader::~BitReader() = default;
27 uint32_t BitReader::ReadBits(size_t aNum
) {
28 MOZ_ASSERT(aNum
<= 32);
29 if (mTotalBitsLeft
< aNum
) {
30 NS_WARNING("Reading past end of buffer");
35 if (mNumBitsLeft
== 0) {
40 if (m
> mNumBitsLeft
) {
48 result
= (result
<< m
) | (mReservoir
>> (32 - m
));
60 // Read unsigned integer Exp-Golomb-coded.
61 uint32_t BitReader::ReadUE() {
64 while (ReadBit() == 0 && i
< 32) {
68 // This can happen if the data is invalid, or if it's
69 // short, since ReadBit() will return 0 when it runs
70 // off the end of the buffer.
71 NS_WARNING("Invalid H.264 data");
74 uint32_t r
= ReadBits(i
);
75 r
+= (uint32_t(1) << i
) - 1;
80 // Read signed integer Exp-Golomb-coded.
81 int32_t BitReader::ReadSE() {
90 uint64_t BitReader::ReadU64() {
91 uint64_t hi
= ReadU32();
92 uint32_t lo
= ReadU32();
93 return (hi
<< 32) | lo
;
96 CheckedUint64
BitReader::ReadULEB128() {
97 // See https://en.wikipedia.org/wiki/LEB128#Decode_unsigned_integer
98 CheckedUint64 value
= 0;
99 for (size_t i
= 0; i
< sizeof(uint64_t) * 8 / 7; i
++) {
100 bool more
= ReadBit();
101 value
+= static_cast<uint64_t>(ReadBits(7)) << (i
* 7);
109 uint64_t BitReader::ReadUTF8() {
110 int64_t val
= ReadBits(8);
111 uint32_t top
= (val
& 0x80) >> 1;
113 if ((val
& 0xc0) == 0x80 || val
>= 0xFE) {
118 int tmp
= ReadBits(8) - 128;
123 val
= (val
<< 6) + tmp
;
126 val
&= (top
<< 1) - 1;
130 size_t BitReader::BitCount() const { return mOriginalBitSize
- mTotalBitsLeft
; }
132 size_t BitReader::BitsLeft() const { return mTotalBitsLeft
; }
134 void BitReader::FillReservoir() {
136 NS_ASSERTION(false, "Attempting to fill reservoir from past end of data");
142 for (i
= 0; mSize
> 0 && i
< 4; i
++) {
143 mReservoir
= (mReservoir
<< 8) | *mData
;
148 mNumBitsLeft
= 8 * i
;
149 mReservoir
<<= 32 - mNumBitsLeft
;
153 uint32_t BitReader::GetBitLength(const mozilla::MediaByteBuffer
* aNAL
) {
154 size_t size
= aNAL
->Length();
156 while (size
> 0 && aNAL
->ElementAt(size
- 1) == 0) {
164 if (size
> UINT32_MAX
/ 8) {
165 // We can't represent it, we'll use as much as we can.
169 uint8_t v
= aNAL
->ElementAt(size
- 1);
172 // Remove the stop bit and following trailing zeros.
174 // Count the consecutive zero bits (trailing) on the right by binary search.
175 // Adapted from Matt Whitlock algorithm to only bother with 8 bits integers.
178 // Special case for odd v (assumed to happen half of the time).
182 if ((v
& 0xf) == 0) {
186 if ((v
& 0x3) == 0) {
197 } // namespace mozilla