Loading include/media/stagefright/foundation/ABitReader.h +19 −3 Original line number Diff line number Diff line Loading @@ -25,8 +25,10 @@ namespace android { struct ABitReader { class ABitReader { public: ABitReader(const uint8_t *data, size_t size); virtual ~ABitReader(); uint32_t getBits(size_t n); void skipBits(size_t n); Loading @@ -37,18 +39,32 @@ struct ABitReader { const uint8_t *data() const; private: protected: const uint8_t *mData; size_t mSize; uint32_t mReservoir; // left-aligned bits size_t mNumBitsLeft; void fillReservoir(); virtual void fillReservoir(); DISALLOW_EVIL_CONSTRUCTORS(ABitReader); }; class NALBitReader : public ABitReader { public: NALBitReader(const uint8_t *data, size_t size); bool atLeastNumBitsLeft(size_t n) const; private: int32_t mNumZeros; virtual void fillReservoir(); DISALLOW_EVIL_CONSTRUCTORS(NALBitReader); }; } // namespace android #endif // A_BIT_READER_H_ media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -674,9 +674,9 @@ bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) { bool hasCC = false; ABitReader br(sei->data() + 1, sei->size() - 1); NALBitReader br(sei->data() + 1, sei->size() - 1); // sei_message() while (br.numBitsLeft() >= 16) { // at least 16-bit for sei_message() while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message() uint32_t payload_type = 0; size_t payload_size = 0; uint8_t last_byte; Loading media/libstagefright/foundation/ABitReader.cpp +68 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ ABitReader::ABitReader(const uint8_t *data, size_t size) mNumBitsLeft(0) { } ABitReader::~ABitReader() { } void ABitReader::fillReservoir() { CHECK_GT(mSize, 0u); Loading Loading @@ -99,4 +102,69 @@ const uint8_t *ABitReader::data() const { return mData - (mNumBitsLeft + 7) / 8; } NALBitReader::NALBitReader(const uint8_t *data, size_t size) : ABitReader(data, size), mNumZeros(0) { } bool NALBitReader::atLeastNumBitsLeft(size_t n) const { // check against raw size and reservoir bits first size_t numBits = numBitsLeft(); if (n > numBits) { return false; } ssize_t numBitsRemaining = n - mNumBitsLeft; size_t size = mSize; const uint8_t *data = mData; int32_t numZeros = mNumZeros; while (size > 0 && numBitsRemaining > 0) { bool isEmulationPreventionByte = (numZeros >= 2 && *data == 3); if (*data == 0) { ++numZeros; } else { numZeros = 0; } if (!isEmulationPreventionByte) { numBitsRemaining -= 8; } ++data; --size; } return (numBitsRemaining <= 0); } void NALBitReader::fillReservoir() { CHECK_GT(mSize, 0u); mReservoir = 0; size_t i = 0; while (mSize > 0 && i < 4) { bool isEmulationPreventionByte = (mNumZeros >= 2 && *mData == 3); if (*mData == 0) { ++mNumZeros; } else { mNumZeros = 0; } // skip emulation_prevention_three_byte if (!isEmulationPreventionByte) { mReservoir = (mReservoir << 8) | *mData; ++i; } ++mData; --mSize; } mNumBitsLeft = 8 * i; mReservoir <<= 32 - mNumBitsLeft; } } // namespace android Loading
include/media/stagefright/foundation/ABitReader.h +19 −3 Original line number Diff line number Diff line Loading @@ -25,8 +25,10 @@ namespace android { struct ABitReader { class ABitReader { public: ABitReader(const uint8_t *data, size_t size); virtual ~ABitReader(); uint32_t getBits(size_t n); void skipBits(size_t n); Loading @@ -37,18 +39,32 @@ struct ABitReader { const uint8_t *data() const; private: protected: const uint8_t *mData; size_t mSize; uint32_t mReservoir; // left-aligned bits size_t mNumBitsLeft; void fillReservoir(); virtual void fillReservoir(); DISALLOW_EVIL_CONSTRUCTORS(ABitReader); }; class NALBitReader : public ABitReader { public: NALBitReader(const uint8_t *data, size_t size); bool atLeastNumBitsLeft(size_t n) const; private: int32_t mNumZeros; virtual void fillReservoir(); DISALLOW_EVIL_CONSTRUCTORS(NALBitReader); }; } // namespace android #endif // A_BIT_READER_H_
media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -674,9 +674,9 @@ bool NuPlayer::CCDecoder::extractFromSEI(const sp<ABuffer> &accessUnit) { bool hasCC = false; ABitReader br(sei->data() + 1, sei->size() - 1); NALBitReader br(sei->data() + 1, sei->size() - 1); // sei_message() while (br.numBitsLeft() >= 16) { // at least 16-bit for sei_message() while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message() uint32_t payload_type = 0; size_t payload_size = 0; uint8_t last_byte; Loading
media/libstagefright/foundation/ABitReader.cpp +68 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,9 @@ ABitReader::ABitReader(const uint8_t *data, size_t size) mNumBitsLeft(0) { } ABitReader::~ABitReader() { } void ABitReader::fillReservoir() { CHECK_GT(mSize, 0u); Loading Loading @@ -99,4 +102,69 @@ const uint8_t *ABitReader::data() const { return mData - (mNumBitsLeft + 7) / 8; } NALBitReader::NALBitReader(const uint8_t *data, size_t size) : ABitReader(data, size), mNumZeros(0) { } bool NALBitReader::atLeastNumBitsLeft(size_t n) const { // check against raw size and reservoir bits first size_t numBits = numBitsLeft(); if (n > numBits) { return false; } ssize_t numBitsRemaining = n - mNumBitsLeft; size_t size = mSize; const uint8_t *data = mData; int32_t numZeros = mNumZeros; while (size > 0 && numBitsRemaining > 0) { bool isEmulationPreventionByte = (numZeros >= 2 && *data == 3); if (*data == 0) { ++numZeros; } else { numZeros = 0; } if (!isEmulationPreventionByte) { numBitsRemaining -= 8; } ++data; --size; } return (numBitsRemaining <= 0); } void NALBitReader::fillReservoir() { CHECK_GT(mSize, 0u); mReservoir = 0; size_t i = 0; while (mSize > 0 && i < 4) { bool isEmulationPreventionByte = (mNumZeros >= 2 && *mData == 3); if (*mData == 0) { ++mNumZeros; } else { mNumZeros = 0; } // skip emulation_prevention_three_byte if (!isEmulationPreventionByte) { mReservoir = (mReservoir << 8) | *mData; ++i; } ++mData; --mSize; } mNumBitsLeft = 8 * i; mReservoir <<= 32 - mNumBitsLeft; } } // namespace android