BitReader.cpp (4879B)
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/. */ 4 5 // Derived from Stagefright's ABitReader. 6 7 #include "BitReader.h" 8 9 #include "nsStringFwd.h" 10 11 namespace mozilla { 12 13 BitReader::BitReader(const mozilla::MediaByteBuffer* aBuffer) 14 : BitReader(aBuffer->Elements(), aBuffer->Length() * 8) {} 15 16 BitReader::BitReader(const mozilla::MediaByteBuffer* aBuffer, size_t aBits) 17 : BitReader(aBuffer->Elements(), aBits) {} 18 19 BitReader::BitReader(const uint8_t* aBuffer, size_t aBits) 20 : mData(aBuffer), 21 mOriginalBitSize(aBits), 22 mTotalBitsLeft(aBits), 23 mSize((aBits + 7) / 8), 24 mReservoir(0), 25 mNumBitsLeft(0) {} 26 27 BitReader::~BitReader() = default; 28 29 uint32_t BitReader::ReadBits(size_t aNum) { 30 MOZ_ASSERT(aNum <= 32); 31 if (mTotalBitsLeft < aNum) { 32 #ifdef DEBUG 33 nsAutoCString msg; 34 msg.AppendFmt("Reading past end of buffer, totalBitsLeft={}, num={}", 35 mTotalBitsLeft, aNum); 36 NS_WARNING(msg.get()); 37 #endif 38 return 0; 39 } 40 uint32_t result = 0; 41 while (aNum > 0) { 42 if (mNumBitsLeft == 0) { 43 FillReservoir(); 44 } 45 46 size_t m = aNum; 47 if (m > mNumBitsLeft) { 48 m = mNumBitsLeft; 49 } 50 51 if (m == 32) { 52 result = mReservoir; 53 mReservoir = 0; 54 } else { 55 result = (result << m) | (mReservoir >> (32 - m)); 56 mReservoir <<= m; 57 } 58 mNumBitsLeft -= m; 59 mTotalBitsLeft -= m; 60 61 aNum -= m; 62 } 63 64 return result; 65 } 66 67 // Read unsigned integer Exp-Golomb-coded. 68 uint32_t BitReader::ReadUE() { 69 uint32_t i = 0; 70 71 while (ReadBit() == 0 && i < 32) { 72 i++; 73 } 74 if (i == 32) { 75 // This can happen if the data is invalid, or if it's 76 // short, since ReadBit() will return 0 when it runs 77 // off the end of the buffer. 78 NS_WARNING("Invalid H.264 data"); 79 return 0; 80 } 81 uint32_t r = ReadBits(i); 82 r += (uint32_t(1) << i) - 1; 83 84 return r; 85 } 86 87 // Read signed integer Exp-Golomb-coded. 88 int32_t BitReader::ReadSE() { 89 int32_t r = ReadUE(); 90 if (r & 1) { 91 return (r + 1) / 2; 92 } else { 93 return -r / 2; 94 } 95 } 96 97 uint64_t BitReader::ReadU64() { 98 uint64_t hi = ReadU32(); 99 uint32_t lo = ReadU32(); 100 return (hi << 32) | lo; 101 } 102 103 CheckedUint64 BitReader::ReadULEB128() { 104 // See https://en.wikipedia.org/wiki/LEB128#Decode_unsigned_integer 105 CheckedUint64 value = 0; 106 for (size_t i = 0; i < sizeof(uint64_t) * 8 / 7; i++) { 107 bool more = ReadBit(); 108 value += static_cast<uint64_t>(ReadBits(7)) << (i * 7); 109 if (!more) { 110 break; 111 } 112 } 113 return value; 114 } 115 116 uint64_t BitReader::ReadUTF8() { 117 int64_t val = ReadBits(8); 118 uint32_t top = (val & 0x80) >> 1; 119 120 if ((val & 0xc0) == 0x80 || val >= 0xFE) { 121 // error. 122 return -1; 123 } 124 while (val & top) { 125 int tmp = ReadBits(8) - 128; 126 if (tmp >> 6) { 127 // error. 128 return -1; 129 } 130 val = (val << 6) + tmp; 131 top <<= 5; 132 } 133 val &= (top << 1) - 1; 134 return val; 135 } 136 137 size_t BitReader::BitCount() const { return mOriginalBitSize - mTotalBitsLeft; } 138 139 size_t BitReader::BitsLeft() const { return mTotalBitsLeft; } 140 141 void BitReader::FillReservoir() { 142 if (mSize == 0) { 143 NS_ASSERTION(false, "Attempting to fill reservoir from past end of data"); 144 return; 145 } 146 147 mReservoir = 0; 148 size_t i; 149 for (i = 0; mSize > 0 && i < 4; i++) { 150 mReservoir = (mReservoir << 8) | *mData; 151 mData++; 152 mSize--; 153 } 154 155 mNumBitsLeft = 8 * i; 156 mReservoir <<= 32 - mNumBitsLeft; 157 } 158 159 /* static */ 160 uint32_t BitReader::GetBitLength(const mozilla::MediaByteBuffer* aNAL) { 161 size_t size = aNAL->Length(); 162 163 while (size > 0 && aNAL->ElementAt(size - 1) == 0) { 164 size--; 165 } 166 167 if (!size) { 168 return 0; 169 } 170 171 if (size > UINT32_MAX / 8) { 172 // We can't represent it, we'll use as much as we can. 173 return UINT32_MAX; 174 } 175 176 uint8_t v = aNAL->ElementAt(size - 1); 177 size *= 8; 178 179 // Remove the stop bit and following trailing zeros. 180 if (v) { 181 // Count the consecutive zero bits (trailing) on the right by binary search. 182 // Adapted from Matt Whitlock algorithm to only bother with 8 bits integers. 183 uint32_t c; 184 if (v & 1) { 185 // Special case for odd v (assumed to happen half of the time). 186 c = 0; 187 } else { 188 c = 1; 189 if ((v & 0xf) == 0) { 190 v >>= 4; 191 c += 4; 192 } 193 if ((v & 0x3) == 0) { 194 v >>= 2; 195 c += 2; 196 } 197 c -= v & 0x1; 198 } 199 size -= c + 1; 200 } 201 return size; 202 } 203 204 size_t BitReader::AdvanceBits(size_t aNum) { 205 const size_t advanceBits = std::min(aNum, BitsLeft()); 206 size_t temp = advanceBits; 207 while (temp > 0) { 208 uint32_t readBits = temp > 32 ? 32 : temp; 209 // TODO : return error if reading less bits than expectation in bug 1972401. 210 (void)ReadBits(readBits); 211 temp -= readBits; 212 } 213 return advanceBits; 214 } 215 216 } // namespace mozilla