1cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber/*
2cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Copyright (C) 2010 The Android Open Source Project
3cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
4cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * you may not use this file except in compliance with the License.
6cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * You may obtain a copy of the License at
7cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
8cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber *
10cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * Unless required by applicable law or agreed to in writing, software
11cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * See the License for the specific language governing permissions and
14cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber * limitations under the License.
15cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber */
16cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
17cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include "ABitReader.h"
18cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
19cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber#include <media/stagefright/foundation/ADebug.h>
20cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
21cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubernamespace android {
22cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
23cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas HuberABitReader::ABitReader(const uint8_t *data, size_t size)
24cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    : mData(data),
25cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mSize(size),
26cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber      mReservoir(0),
273be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar      mNumBitsLeft(0),
283be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar      mOverRead(false) {
29cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
30cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
31862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong ZhangABitReader::~ABitReader() {
32862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang}
33862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
343be85f905e5c63e1552554622a80fd8bee695044Lajos Molnarbool ABitReader::fillReservoir() {
353be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    if (mSize == 0) {
363be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar        mOverRead = true;
373be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar        return false;
383be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    }
39cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
40cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mReservoir = 0;
41cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    size_t i;
42cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    for (i = 0; mSize > 0 && i < 4; ++i) {
43cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        mReservoir = (mReservoir << 8) | *mData;
44cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
45cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        ++mData;
46cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        --mSize;
47cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
48cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
49cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mNumBitsLeft = 8 * i;
50cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mReservoir <<= 32 - mNumBitsLeft;
513be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    return true;
52cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
53cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
54cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberuint32_t ABitReader::getBits(size_t n) {
553be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    uint32_t ret;
563be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    CHECK(getBitsGraceful(n, &ret));
573be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    return ret;
583be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar}
593be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar
603be85f905e5c63e1552554622a80fd8bee695044Lajos Molnaruint32_t ABitReader::getBitsWithFallback(size_t n, uint32_t fallback) {
613be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    uint32_t ret = fallback;
623be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    (void)getBitsGraceful(n, &ret);
633be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    return ret;
643be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar}
653be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar
663be85f905e5c63e1552554622a80fd8bee695044Lajos Molnarbool ABitReader::getBitsGraceful(size_t n, uint32_t *out) {
673be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    if (n > 32) {
683be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar        return false;
693be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    }
70cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
71cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    uint32_t result = 0;
72cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    while (n > 0) {
73cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (mNumBitsLeft == 0) {
743be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar            if (!fillReservoir()) {
753be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar                return false;
763be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar            }
77cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
78cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
79cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        size_t m = n;
80cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        if (m > mNumBitsLeft) {
81cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber            m = mNumBitsLeft;
82cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        }
83cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
84cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        result = (result << m) | (mReservoir >> (32 - m));
85cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        mReservoir <<= m;
86cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        mNumBitsLeft -= m;
87cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
88cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        n -= m;
89cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
90cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
913be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    *out = result;
923be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    return true;
93cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
94cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
953be85f905e5c63e1552554622a80fd8bee695044Lajos Molnarbool ABitReader::skipBits(size_t n) {
963be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    uint32_t dummy;
97cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    while (n > 32) {
983be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar        if (!getBitsGraceful(32, &dummy)) {
993be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar            return false;
1003be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar        }
101cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber        n -= 32;
102cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
103cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
104cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    if (n > 0) {
1053be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar        return getBitsGraceful(n, &dummy);
106cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    }
1073be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    return true;
108cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
109cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
110cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubervoid ABitReader::putBits(uint32_t x, size_t n) {
1113be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    if (mOverRead) {
1123be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar        return;
1133be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    }
1143be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar
1151906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber    CHECK_LE(n, 32u);
1161906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber
1171906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber    while (mNumBitsLeft + n > 32) {
1181906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        mNumBitsLeft -= 8;
1191906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        --mData;
1201906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber        ++mSize;
1211906e5c7492b9cbc88601365536a69e9a490c963Andreas Huber    }
122cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
123cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mReservoir = (mReservoir >> n) | (x << (32 - n));
124cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    mNumBitsLeft += n;
125cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
126cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
127cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Hubersize_t ABitReader::numBitsLeft() const {
128cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber    return mSize * 8 + mNumBitsLeft;
129cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
130cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
131cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huberconst uint8_t *ABitReader::data() const {
13255e26193c885b7d5acdae9978848e6587987790fAndreas Huber    return mData - (mNumBitsLeft + 7) / 8;
133cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}
134cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber
135862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong ZhangNALBitReader::NALBitReader(const uint8_t *data, size_t size)
136862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    : ABitReader(data, size),
137862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang      mNumZeros(0) {
138862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang}
139862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
140862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhangbool NALBitReader::atLeastNumBitsLeft(size_t n) const {
141862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    // check against raw size and reservoir bits first
142862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    size_t numBits = numBitsLeft();
143862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    if (n > numBits) {
144862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        return false;
145862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    }
146862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
147afe8d851a19f10f86726591bb684ecb515ac6974Robert Shih    ssize_t numBitsRemaining = (ssize_t)n - (ssize_t)mNumBitsLeft;
148862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
149862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    size_t size = mSize;
150862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    const uint8_t *data = mData;
151862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    int32_t numZeros = mNumZeros;
152862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    while (size > 0 && numBitsRemaining > 0) {
153862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        bool isEmulationPreventionByte = (numZeros >= 2 && *data == 3);
154862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
155862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        if (*data == 0) {
156862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang            ++numZeros;
157862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        } else {
158862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang            numZeros = 0;
159862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        }
160862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
161862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        if (!isEmulationPreventionByte) {
162862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang            numBitsRemaining -= 8;
163862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        }
164862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
165862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        ++data;
166862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        --size;
167862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    }
168862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
169862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    return (numBitsRemaining <= 0);
170862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang}
171862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
1723be85f905e5c63e1552554622a80fd8bee695044Lajos Molnarbool NALBitReader::fillReservoir() {
1733be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    if (mSize == 0) {
1743be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar        mOverRead = true;
1753be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar        return false;
1763be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    }
177862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
178862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    mReservoir = 0;
179862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    size_t i = 0;
180862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    while (mSize > 0 && i < 4) {
181862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        bool isEmulationPreventionByte = (mNumZeros >= 2 && *mData == 3);
182862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
183862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        if (*mData == 0) {
184862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang            ++mNumZeros;
185862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        } else {
186862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang            mNumZeros = 0;
187862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        }
188862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
189862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        // skip emulation_prevention_three_byte
190862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        if (!isEmulationPreventionByte) {
191862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang            mReservoir = (mReservoir << 8) | *mData;
192862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang            ++i;
193862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        }
194862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
195862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        ++mData;
196862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang        --mSize;
197862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    }
198862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
199862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    mNumBitsLeft = 8 * i;
200862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang    mReservoir <<= 32 - mNumBitsLeft;
2013be85f905e5c63e1552554622a80fd8bee695044Lajos Molnar    return true;
202862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang}
203862f8455eaacc1ffb5d8911f0bc7ecc3cf7ec46cChong Zhang
204cda17c606b0fe3ccda4dc68a6d43882410ea2462Andreas Huber}  // namespace android
205