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
21 namespace android {
22
ABitReader(const uint8_t * data,size_t size)23 ABitReader::ABitReader(const uint8_t *data, size_t size)
24 : mData(data),
25 mSize(size),
26 mReservoir(0),
27 mNumBitsLeft(0) {
28 }
29
~ABitReader()30 ABitReader::~ABitReader() {
31 }
32
fillReservoir()33 void 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
getBits(size_t n)49 uint32_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
skipBits(size_t n)73 void 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
putBits(uint32_t x,size_t n)84 void 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
numBitsLeft() const97 size_t ABitReader::numBitsLeft() const {
98 return mSize * 8 + mNumBitsLeft;
99 }
100
data() const101 const uint8_t *ABitReader::data() const {
102 return mData - (mNumBitsLeft + 7) / 8;
103 }
104
NALBitReader(const uint8_t * data,size_t size)105 NALBitReader::NALBitReader(const uint8_t *data, size_t size)
106 : ABitReader(data, size),
107 mNumZeros(0) {
108 }
109
atLeastNumBitsLeft(size_t n) const110 bool 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
fillReservoir()142 void 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