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