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

Commit f4893ba2 authored by Lajos Molnar's avatar Lajos Molnar Committed by android-build-merger
Browse files

Merge "stagefright: allow ABitReader to fail gracefully" into nyc-dev

am: 5c8f37fd

* commit '5c8f37fd':
  stagefright: allow ABitReader to fail gracefully

Change-Id: I2c0830ff9a65d55eb5dc3e6a874924e3b043e8f3
parents 34b97d53 5c8f37fd
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -30,23 +30,44 @@ public:
    ABitReader(const uint8_t *data, size_t size);
    virtual ~ABitReader();

    // Tries to get |n| bits. If not successful, returns |fallback|. Otherwise, returns result.
    // Reading 0 bits will always succeed and return 0.
    uint32_t getBitsWithFallback(size_t n, uint32_t fallback);

    // Tries to get |n| bits. If not successful, returns false. Otherwise, stores result in |out|
    // and returns true. Use !overRead() to determine if this call was successful. Reading 0 bits
    // will always succeed and write 0 in |out|.
    bool getBitsGraceful(size_t n, uint32_t *out);

    // Gets |n| bits and returns result. ABORTS if unsuccessful. Reading 0 bits will always
    // succeed.
    uint32_t getBits(size_t n);
    void skipBits(size_t n);

    // Tries to skip |n| bits. Returns true iff successful. Skipping 0 bits will always succeed.
    bool skipBits(size_t n);

    // "Puts" |n| bits with the value |x| back virtually into the bit stream. The put-back bits
    // are not actually written into the data, but are tracked in a separate buffer that can
    // store at most 32 bits. This is a no-op if the stream has already been over-read.
    void putBits(uint32_t x, size_t n);

    size_t numBitsLeft() const;

    const uint8_t *data() const;

    // Returns true iff the stream was over-read (e.g. any getBits operation has been unsuccessful
    // due to overread (and not trying to read >32 bits).)
    bool overRead() const { return mOverRead; }

protected:
    const uint8_t *mData;
    size_t mSize;

    uint32_t mReservoir;  // left-aligned bits
    size_t mNumBitsLeft;
    bool mOverRead;

    virtual void fillReservoir();
    virtual bool fillReservoir();

    DISALLOW_EVIL_CONSTRUCTORS(ABitReader);
};
@@ -60,7 +81,7 @@ public:
private:
    int32_t mNumZeros;

    virtual void fillReservoir();
    virtual bool fillReservoir();

    DISALLOW_EVIL_CONSTRUCTORS(NALBitReader);
};
+45 −11
Original line number Diff line number Diff line
@@ -24,14 +24,18 @@ ABitReader::ABitReader(const uint8_t *data, size_t size)
    : mData(data),
      mSize(size),
      mReservoir(0),
      mNumBitsLeft(0) {
      mNumBitsLeft(0),
      mOverRead(false) {
}

ABitReader::~ABitReader() {
}

void ABitReader::fillReservoir() {
    CHECK_GT(mSize, 0u);
bool ABitReader::fillReservoir() {
    if (mSize == 0) {
        mOverRead = true;
        return false;
    }

    mReservoir = 0;
    size_t i;
@@ -44,15 +48,32 @@ void ABitReader::fillReservoir() {

    mNumBitsLeft = 8 * i;
    mReservoir <<= 32 - mNumBitsLeft;
    return true;
}

uint32_t ABitReader::getBits(size_t n) {
    CHECK_LE(n, 32u);
    uint32_t ret;
    CHECK(getBitsGraceful(n, &ret));
    return ret;
}

uint32_t ABitReader::getBitsWithFallback(size_t n, uint32_t fallback) {
    uint32_t ret = fallback;
    (void)getBitsGraceful(n, &ret);
    return ret;
}

bool ABitReader::getBitsGraceful(size_t n, uint32_t *out) {
    if (n > 32) {
        return false;
    }

    uint32_t result = 0;
    while (n > 0) {
        if (mNumBitsLeft == 0) {
            fillReservoir();
            if (!fillReservoir()) {
                return false;
            }
        }

        size_t m = n;
@@ -67,21 +88,30 @@ uint32_t ABitReader::getBits(size_t n) {
        n -= m;
    }

    return result;
    *out = result;
    return true;
}

void ABitReader::skipBits(size_t n) {
bool ABitReader::skipBits(size_t n) {
    uint32_t dummy;
    while (n > 32) {
        getBits(32);
        if (!getBitsGraceful(32, &dummy)) {
            return false;
        }
        n -= 32;
    }

    if (n > 0) {
        getBits(n);
        return getBitsGraceful(n, &dummy);
    }
    return true;
}

void ABitReader::putBits(uint32_t x, size_t n) {
    if (mOverRead) {
        return;
    }

    CHECK_LE(n, 32u);

    while (mNumBitsLeft + n > 32) {
@@ -139,8 +169,11 @@ bool NALBitReader::atLeastNumBitsLeft(size_t n) const {
    return (numBitsRemaining <= 0);
}

void NALBitReader::fillReservoir() {
    CHECK_GT(mSize, 0u);
bool NALBitReader::fillReservoir() {
    if (mSize == 0) {
        mOverRead = true;
        return false;
    }

    mReservoir = 0;
    size_t i = 0;
@@ -165,6 +198,7 @@ void NALBitReader::fillReservoir() {

    mNumBitsLeft = 8 * i;
    mReservoir <<= 32 - mNumBitsLeft;
    return true;
}

}  // namespace android