1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "ABitReader.h"
18
19#include <media/stagefright/foundation/ADebug.h>
20
21namespace android {
22
23ABitReader::ABitReader(const uint8_t *data, size_t size)
24    : mData(data),
25      mSize(size),
26      mReservoir(0),
27      mNumBitsLeft(0) {
28}
29
30ABitReader::~ABitReader() {
31}
32
33void ABitReader::fillReservoir() {
34    CHECK_GT(mSize, 0u);
35
36    mReservoir = 0;
37    size_t i;
38    for (i = 0; mSize > 0 && i < 4; ++i) {
39        mReservoir = (mReservoir << 8) | *mData;
40
41        ++mData;
42        --mSize;
43    }
44
45    mNumBitsLeft = 8 * i;
46    mReservoir <<= 32 - mNumBitsLeft;
47}
48
49uint32_t ABitReader::getBits(size_t n) {
50    CHECK_LE(n, 32u);
51
52    uint32_t result = 0;
53    while (n > 0) {
54        if (mNumBitsLeft == 0) {
55            fillReservoir();
56        }
57
58        size_t m = n;
59        if (m > mNumBitsLeft) {
60            m = mNumBitsLeft;
61        }
62
63        result = (result << m) | (mReservoir >> (32 - m));
64        mReservoir <<= m;
65        mNumBitsLeft -= m;
66
67        n -= m;
68    }
69
70    return result;
71}
72
73void ABitReader::skipBits(size_t n) {
74    while (n > 32) {
75        getBits(32);
76        n -= 32;
77    }
78
79    if (n > 0) {
80        getBits(n);
81    }
82}
83
84void ABitReader::putBits(uint32_t x, size_t n) {
85    CHECK_LE(n, 32u);
86
87    while (mNumBitsLeft + n > 32) {
88        mNumBitsLeft -= 8;
89        --mData;
90        ++mSize;
91    }
92
93    mReservoir = (mReservoir >> n) | (x << (32 - n));
94    mNumBitsLeft += n;
95}
96
97size_t ABitReader::numBitsLeft() const {
98    return mSize * 8 + mNumBitsLeft;
99}
100
101const uint8_t *ABitReader::data() const {
102    return mData - (mNumBitsLeft + 7) / 8;
103}
104
105NALBitReader::NALBitReader(const uint8_t *data, size_t size)
106    : ABitReader(data, size),
107      mNumZeros(0) {
108}
109
110bool NALBitReader::atLeastNumBitsLeft(size_t n) const {
111    // check against raw size and reservoir bits first
112    size_t numBits = numBitsLeft();
113    if (n > numBits) {
114        return false;
115    }
116
117    ssize_t numBitsRemaining = n - mNumBitsLeft;
118
119    size_t size = mSize;
120    const uint8_t *data = mData;
121    int32_t numZeros = mNumZeros;
122    while (size > 0 && numBitsRemaining > 0) {
123        bool isEmulationPreventionByte = (numZeros >= 2 && *data == 3);
124
125        if (*data == 0) {
126            ++numZeros;
127        } else {
128            numZeros = 0;
129        }
130
131        if (!isEmulationPreventionByte) {
132            numBitsRemaining -= 8;
133        }
134
135        ++data;
136        --size;
137    }
138
139    return (numBitsRemaining <= 0);
140}
141
142void NALBitReader::fillReservoir() {
143    CHECK_GT(mSize, 0u);
144
145    mReservoir = 0;
146    size_t i = 0;
147    while (mSize > 0 && i < 4) {
148        bool isEmulationPreventionByte = (mNumZeros >= 2 && *mData == 3);
149
150        if (*mData == 0) {
151            ++mNumZeros;
152        } else {
153            mNumZeros = 0;
154        }
155
156        // skip emulation_prevention_three_byte
157        if (!isEmulationPreventionByte) {
158            mReservoir = (mReservoir << 8) | *mData;
159            ++i;
160        }
161
162        ++mData;
163        --mSize;
164    }
165
166    mNumBitsLeft = 8 * i;
167    mReservoir <<= 32 - mNumBitsLeft;
168}
169
170}  // namespace android
171