Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 862f8455 authored by Chong Zhang's avatar Chong Zhang
Browse files

handle emulation_prevention_three_bytes for AVC

bug: 15917805
Change-Id: I824fe7eea807f8faba6b149c31890b7a5df87825
parent e8f2c6cf
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -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);
@@ -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_
+2 −2
Original line number Diff line number Diff line
@@ -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;
+68 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ ABitReader::ABitReader(const uint8_t *data, size_t size)
      mNumBitsLeft(0) {
}

ABitReader::~ABitReader() {
}

void ABitReader::fillReservoir() {
    CHECK_GT(mSize, 0u);

@@ -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