1*abb65b4bSAndroid Build Coastguard Worker /*
2*abb65b4bSAndroid Build Coastguard Worker * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3*abb65b4bSAndroid Build Coastguard Worker * All Rights Reserved.
4*abb65b4bSAndroid Build Coastguard Worker *
5*abb65b4bSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*abb65b4bSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*abb65b4bSAndroid Build Coastguard Worker *
8*abb65b4bSAndroid Build Coastguard Worker * - Redistributions of source code must retain the above copyright notice,
9*abb65b4bSAndroid Build Coastguard Worker * this list of conditions and the following disclaimer.
10*abb65b4bSAndroid Build Coastguard Worker *
11*abb65b4bSAndroid Build Coastguard Worker * - Redistributions in binary form must reproduce the above copyright notice,
12*abb65b4bSAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation
13*abb65b4bSAndroid Build Coastguard Worker * and/or other materials provided with the distribution.
14*abb65b4bSAndroid Build Coastguard Worker *
15*abb65b4bSAndroid Build Coastguard Worker * - Neither the name of the copyright owner, nor the names of its contributors
16*abb65b4bSAndroid Build Coastguard Worker * may be used to endorse or promote products derived from this software
17*abb65b4bSAndroid Build Coastguard Worker * without specific prior written permission.
18*abb65b4bSAndroid Build Coastguard Worker *
19*abb65b4bSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*abb65b4bSAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*abb65b4bSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*abb65b4bSAndroid Build Coastguard Worker * ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23*abb65b4bSAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*abb65b4bSAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*abb65b4bSAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*abb65b4bSAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*abb65b4bSAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*abb65b4bSAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*abb65b4bSAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
30*abb65b4bSAndroid Build Coastguard Worker */
31*abb65b4bSAndroid Build Coastguard Worker
32*abb65b4bSAndroid Build Coastguard Worker #include "oapv_def.h"
33*abb65b4bSAndroid Build Coastguard Worker
34*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
35*abb65b4bSAndroid Build Coastguard Worker // start of encoder code
36*abb65b4bSAndroid Build Coastguard Worker #if ENABLE_ENCODER
37*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
38*abb65b4bSAndroid Build Coastguard Worker /* number of bytes to be sunk */
39*abb65b4bSAndroid Build Coastguard Worker #define BSW_GET_SINK_BYTE(bs) ((32 - (bs)->leftbits + 7) >> 3)
40*abb65b4bSAndroid Build Coastguard Worker
bsw_flush(oapv_bs_t * bs,int bytes)41*abb65b4bSAndroid Build Coastguard Worker static int bsw_flush(oapv_bs_t *bs, int bytes)
42*abb65b4bSAndroid Build Coastguard Worker {
43*abb65b4bSAndroid Build Coastguard Worker if(bytes == 0)
44*abb65b4bSAndroid Build Coastguard Worker bytes = BSW_GET_SINK_BYTE(bs);
45*abb65b4bSAndroid Build Coastguard Worker
46*abb65b4bSAndroid Build Coastguard Worker while(bytes--) {
47*abb65b4bSAndroid Build Coastguard Worker *bs->cur++ = (bs->code >> 24) & 0xFF;
48*abb65b4bSAndroid Build Coastguard Worker bs->code <<= 8;
49*abb65b4bSAndroid Build Coastguard Worker }
50*abb65b4bSAndroid Build Coastguard Worker
51*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 32;
52*abb65b4bSAndroid Build Coastguard Worker
53*abb65b4bSAndroid Build Coastguard Worker return 0;
54*abb65b4bSAndroid Build Coastguard Worker }
55*abb65b4bSAndroid Build Coastguard Worker
oapv_bsw_init(oapv_bs_t * bs,u8 * buf,int size,oapv_bs_fn_flush_t fn_flush)56*abb65b4bSAndroid Build Coastguard Worker void oapv_bsw_init(oapv_bs_t *bs, u8 *buf, int size, oapv_bs_fn_flush_t fn_flush)
57*abb65b4bSAndroid Build Coastguard Worker {
58*abb65b4bSAndroid Build Coastguard Worker bs->size = size;
59*abb65b4bSAndroid Build Coastguard Worker bs->beg = buf;
60*abb65b4bSAndroid Build Coastguard Worker bs->cur = buf;
61*abb65b4bSAndroid Build Coastguard Worker bs->end = buf + size - 1;
62*abb65b4bSAndroid Build Coastguard Worker bs->code = 0;
63*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 32;
64*abb65b4bSAndroid Build Coastguard Worker bs->fn_flush = (fn_flush == NULL ? bsw_flush : fn_flush);
65*abb65b4bSAndroid Build Coastguard Worker bs->is_bin_count = 0;
66*abb65b4bSAndroid Build Coastguard Worker bs->bin_count = 0;
67*abb65b4bSAndroid Build Coastguard Worker }
68*abb65b4bSAndroid Build Coastguard Worker
oapv_bsw_deinit(oapv_bs_t * bs)69*abb65b4bSAndroid Build Coastguard Worker void oapv_bsw_deinit(oapv_bs_t *bs)
70*abb65b4bSAndroid Build Coastguard Worker {
71*abb65b4bSAndroid Build Coastguard Worker bs->fn_flush(bs, 0);
72*abb65b4bSAndroid Build Coastguard Worker }
73*abb65b4bSAndroid Build Coastguard Worker
oapv_bsw_sink(oapv_bs_t * bs)74*abb65b4bSAndroid Build Coastguard Worker void *oapv_bsw_sink(oapv_bs_t *bs)
75*abb65b4bSAndroid Build Coastguard Worker {
76*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(bs->cur + BSW_GET_SINK_BYTE(bs) <= bs->end, NULL);
77*abb65b4bSAndroid Build Coastguard Worker bs->fn_flush(bs, 0);
78*abb65b4bSAndroid Build Coastguard Worker bs->code = 0;
79*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 32;
80*abb65b4bSAndroid Build Coastguard Worker return (void *)bs->cur;
81*abb65b4bSAndroid Build Coastguard Worker }
82*abb65b4bSAndroid Build Coastguard Worker
oapv_bsw_write_direct(void * bits,u32 val,int len)83*abb65b4bSAndroid Build Coastguard Worker int oapv_bsw_write_direct(void *bits, u32 val, int len)
84*abb65b4bSAndroid Build Coastguard Worker {
85*abb65b4bSAndroid Build Coastguard Worker int i;
86*abb65b4bSAndroid Build Coastguard Worker unsigned char *p = (unsigned char *)bits;
87*abb65b4bSAndroid Build Coastguard Worker
88*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv((len & 0x7) == 0, -1); // len should be byte-aligned
89*abb65b4bSAndroid Build Coastguard Worker
90*abb65b4bSAndroid Build Coastguard Worker val <<= (32 - len);
91*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < (len >> 3); i++) {
92*abb65b4bSAndroid Build Coastguard Worker p[i] = (val >> 24) & 0xFF;
93*abb65b4bSAndroid Build Coastguard Worker val <<= 8;
94*abb65b4bSAndroid Build Coastguard Worker }
95*abb65b4bSAndroid Build Coastguard Worker return 0;
96*abb65b4bSAndroid Build Coastguard Worker }
97*abb65b4bSAndroid Build Coastguard Worker
oapv_bsw_write1(oapv_bs_t * bs,int val)98*abb65b4bSAndroid Build Coastguard Worker int oapv_bsw_write1(oapv_bs_t *bs, int val)
99*abb65b4bSAndroid Build Coastguard Worker {
100*abb65b4bSAndroid Build Coastguard Worker oapv_assert(bs);
101*abb65b4bSAndroid Build Coastguard Worker
102*abb65b4bSAndroid Build Coastguard Worker if(bs->is_bin_count) {
103*abb65b4bSAndroid Build Coastguard Worker bs->bin_count++;
104*abb65b4bSAndroid Build Coastguard Worker return 0;
105*abb65b4bSAndroid Build Coastguard Worker }
106*abb65b4bSAndroid Build Coastguard Worker
107*abb65b4bSAndroid Build Coastguard Worker bs->leftbits--;
108*abb65b4bSAndroid Build Coastguard Worker bs->code |= ((val & 0x1) << bs->leftbits);
109*abb65b4bSAndroid Build Coastguard Worker
110*abb65b4bSAndroid Build Coastguard Worker if(bs->leftbits == 0) {
111*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(bs->cur <= bs->end, -1);
112*abb65b4bSAndroid Build Coastguard Worker bs->fn_flush(bs, 0);
113*abb65b4bSAndroid Build Coastguard Worker
114*abb65b4bSAndroid Build Coastguard Worker bs->code = 0;
115*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 32;
116*abb65b4bSAndroid Build Coastguard Worker }
117*abb65b4bSAndroid Build Coastguard Worker
118*abb65b4bSAndroid Build Coastguard Worker return 0;
119*abb65b4bSAndroid Build Coastguard Worker }
120*abb65b4bSAndroid Build Coastguard Worker
oapv_bsw_write(oapv_bs_t * bs,u32 val,int len)121*abb65b4bSAndroid Build Coastguard Worker int oapv_bsw_write(oapv_bs_t *bs, u32 val, int len) /* len(1 ~ 32) */
122*abb65b4bSAndroid Build Coastguard Worker {
123*abb65b4bSAndroid Build Coastguard Worker int leftbits;
124*abb65b4bSAndroid Build Coastguard Worker
125*abb65b4bSAndroid Build Coastguard Worker oapv_assert(bs);
126*abb65b4bSAndroid Build Coastguard Worker
127*abb65b4bSAndroid Build Coastguard Worker if(bs->is_bin_count) {
128*abb65b4bSAndroid Build Coastguard Worker bs->bin_count += len;
129*abb65b4bSAndroid Build Coastguard Worker return 0;
130*abb65b4bSAndroid Build Coastguard Worker }
131*abb65b4bSAndroid Build Coastguard Worker
132*abb65b4bSAndroid Build Coastguard Worker leftbits = bs->leftbits;
133*abb65b4bSAndroid Build Coastguard Worker val <<= (32 - len);
134*abb65b4bSAndroid Build Coastguard Worker bs->code |= (val >> (32 - leftbits));
135*abb65b4bSAndroid Build Coastguard Worker
136*abb65b4bSAndroid Build Coastguard Worker if(len < leftbits) {
137*abb65b4bSAndroid Build Coastguard Worker bs->leftbits -= len;
138*abb65b4bSAndroid Build Coastguard Worker }
139*abb65b4bSAndroid Build Coastguard Worker else {
140*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(bs->cur + 4 <= bs->end, -1);
141*abb65b4bSAndroid Build Coastguard Worker
142*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 0;
143*abb65b4bSAndroid Build Coastguard Worker bs->fn_flush(bs, 0);
144*abb65b4bSAndroid Build Coastguard Worker bs->code = (leftbits < 32 ? val << leftbits : 0);
145*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 32 - (len - leftbits);
146*abb65b4bSAndroid Build Coastguard Worker }
147*abb65b4bSAndroid Build Coastguard Worker
148*abb65b4bSAndroid Build Coastguard Worker return 0;
149*abb65b4bSAndroid Build Coastguard Worker }
150*abb65b4bSAndroid Build Coastguard Worker
151*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
152*abb65b4bSAndroid Build Coastguard Worker // end of encoder code
153*abb65b4bSAndroid Build Coastguard Worker #endif // ENABLE_ENCODER
154*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
155*abb65b4bSAndroid Build Coastguard Worker
156*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
157*abb65b4bSAndroid Build Coastguard Worker // start of decoder code
158*abb65b4bSAndroid Build Coastguard Worker #if ENABLE_DECODER
159*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
160*abb65b4bSAndroid Build Coastguard Worker
161*abb65b4bSAndroid Build Coastguard Worker /* Table of count of leading zero for 4 bit value */
162*abb65b4bSAndroid Build Coastguard Worker static const u8 tbl_zero_count4[16] = {
163*abb65b4bSAndroid Build Coastguard Worker 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
164*abb65b4bSAndroid Build Coastguard Worker };
165*abb65b4bSAndroid Build Coastguard Worker
166*abb65b4bSAndroid Build Coastguard Worker // skip code if lefbits are larger than skip bit count;
bsr_skip_code(oapv_bs_t * bs,int size)167*abb65b4bSAndroid Build Coastguard Worker static void inline bsr_skip_code(oapv_bs_t *bs, int size)
168*abb65b4bSAndroid Build Coastguard Worker {
169*abb65b4bSAndroid Build Coastguard Worker oapv_assert(size <= 32);
170*abb65b4bSAndroid Build Coastguard Worker oapv_assert(bs->leftbits >= size);
171*abb65b4bSAndroid Build Coastguard Worker if(size == 32) {
172*abb65b4bSAndroid Build Coastguard Worker bs->code = 0;
173*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 0;
174*abb65b4bSAndroid Build Coastguard Worker }
175*abb65b4bSAndroid Build Coastguard Worker else {
176*abb65b4bSAndroid Build Coastguard Worker bs->code <<= size;
177*abb65b4bSAndroid Build Coastguard Worker bs->leftbits -= size;
178*abb65b4bSAndroid Build Coastguard Worker }
179*abb65b4bSAndroid Build Coastguard Worker }
180*abb65b4bSAndroid Build Coastguard Worker
bsr_flush(oapv_bs_t * bs,int byte)181*abb65b4bSAndroid Build Coastguard Worker static int bsr_flush(oapv_bs_t *bs, int byte)
182*abb65b4bSAndroid Build Coastguard Worker {
183*abb65b4bSAndroid Build Coastguard Worker int shift = 24, remained;
184*abb65b4bSAndroid Build Coastguard Worker u32 code = 0;
185*abb65b4bSAndroid Build Coastguard Worker
186*abb65b4bSAndroid Build Coastguard Worker oapv_assert(byte);
187*abb65b4bSAndroid Build Coastguard Worker
188*abb65b4bSAndroid Build Coastguard Worker remained = (int)(bs->end - bs->cur) + 1;
189*abb65b4bSAndroid Build Coastguard Worker if(byte > remained)
190*abb65b4bSAndroid Build Coastguard Worker byte = remained;
191*abb65b4bSAndroid Build Coastguard Worker
192*abb65b4bSAndroid Build Coastguard Worker if(byte <= 0) {
193*abb65b4bSAndroid Build Coastguard Worker bs->code = 0;
194*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 0;
195*abb65b4bSAndroid Build Coastguard Worker return -1;
196*abb65b4bSAndroid Build Coastguard Worker }
197*abb65b4bSAndroid Build Coastguard Worker
198*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = byte << 3;
199*abb65b4bSAndroid Build Coastguard Worker
200*abb65b4bSAndroid Build Coastguard Worker bs->cur += byte;
201*abb65b4bSAndroid Build Coastguard Worker while(byte) {
202*abb65b4bSAndroid Build Coastguard Worker code |= *(bs->cur - byte) << shift;
203*abb65b4bSAndroid Build Coastguard Worker byte--;
204*abb65b4bSAndroid Build Coastguard Worker shift -= 8;
205*abb65b4bSAndroid Build Coastguard Worker }
206*abb65b4bSAndroid Build Coastguard Worker bs->code = code;
207*abb65b4bSAndroid Build Coastguard Worker return 0;
208*abb65b4bSAndroid Build Coastguard Worker }
209*abb65b4bSAndroid Build Coastguard Worker
oapv_bsr_init(oapv_bs_t * bs,u8 * buf,int size,oapv_bs_fn_flush_t fn_flush)210*abb65b4bSAndroid Build Coastguard Worker void oapv_bsr_init(oapv_bs_t *bs, u8 *buf, int size, oapv_bs_fn_flush_t fn_flush)
211*abb65b4bSAndroid Build Coastguard Worker {
212*abb65b4bSAndroid Build Coastguard Worker bs->size = size;
213*abb65b4bSAndroid Build Coastguard Worker bs->cur = buf;
214*abb65b4bSAndroid Build Coastguard Worker bs->beg = buf;
215*abb65b4bSAndroid Build Coastguard Worker bs->end = buf + size - 1;
216*abb65b4bSAndroid Build Coastguard Worker bs->code = 0;
217*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 0;
218*abb65b4bSAndroid Build Coastguard Worker bs->fn_flush = (fn_flush == NULL) ? bsr_flush : fn_flush;
219*abb65b4bSAndroid Build Coastguard Worker }
220*abb65b4bSAndroid Build Coastguard Worker
oapv_bsr_clz_in_code(u32 code)221*abb65b4bSAndroid Build Coastguard Worker int oapv_bsr_clz_in_code(u32 code)
222*abb65b4bSAndroid Build Coastguard Worker {
223*abb65b4bSAndroid Build Coastguard Worker int clz, bits4, shift;
224*abb65b4bSAndroid Build Coastguard Worker
225*abb65b4bSAndroid Build Coastguard Worker if(code == 0)
226*abb65b4bSAndroid Build Coastguard Worker return 32; /* to protect infinite loop */
227*abb65b4bSAndroid Build Coastguard Worker
228*abb65b4bSAndroid Build Coastguard Worker bits4 = 0;
229*abb65b4bSAndroid Build Coastguard Worker clz = 0;
230*abb65b4bSAndroid Build Coastguard Worker shift = 28;
231*abb65b4bSAndroid Build Coastguard Worker
232*abb65b4bSAndroid Build Coastguard Worker while(bits4 == 0 && shift >= 0) {
233*abb65b4bSAndroid Build Coastguard Worker bits4 = (code >> shift) & 0xf;
234*abb65b4bSAndroid Build Coastguard Worker clz += tbl_zero_count4[bits4];
235*abb65b4bSAndroid Build Coastguard Worker shift -= 4;
236*abb65b4bSAndroid Build Coastguard Worker }
237*abb65b4bSAndroid Build Coastguard Worker return clz;
238*abb65b4bSAndroid Build Coastguard Worker }
239*abb65b4bSAndroid Build Coastguard Worker
oapv_bsr_align8(oapv_bs_t * bs)240*abb65b4bSAndroid Build Coastguard Worker void oapv_bsr_align8(oapv_bs_t *bs)
241*abb65b4bSAndroid Build Coastguard Worker {
242*abb65b4bSAndroid Build Coastguard Worker /*
243*abb65b4bSAndroid Build Coastguard Worker while (!bsr_is_align8(bs)) {
244*abb65b4bSAndroid Build Coastguard Worker oapv_bsr_read1(bs);
245*abb65b4bSAndroid Build Coastguard Worker }
246*abb65b4bSAndroid Build Coastguard Worker */
247*abb65b4bSAndroid Build Coastguard Worker int size;
248*abb65b4bSAndroid Build Coastguard Worker
249*abb65b4bSAndroid Build Coastguard Worker size = bs->leftbits & 0x7;
250*abb65b4bSAndroid Build Coastguard Worker
251*abb65b4bSAndroid Build Coastguard Worker bs->code <<= size;
252*abb65b4bSAndroid Build Coastguard Worker bs->leftbits -= size;
253*abb65b4bSAndroid Build Coastguard Worker }
254*abb65b4bSAndroid Build Coastguard Worker
oapv_bsr_skip(oapv_bs_t * bs,int size)255*abb65b4bSAndroid Build Coastguard Worker void oapv_bsr_skip(oapv_bs_t *bs, int size)
256*abb65b4bSAndroid Build Coastguard Worker {
257*abb65b4bSAndroid Build Coastguard Worker oapv_assert(size > 0 && size <= 32);
258*abb65b4bSAndroid Build Coastguard Worker
259*abb65b4bSAndroid Build Coastguard Worker if(bs->leftbits < size) {
260*abb65b4bSAndroid Build Coastguard Worker size -= bs->leftbits;
261*abb65b4bSAndroid Build Coastguard Worker if(bs->fn_flush(bs, 4)) {
262*abb65b4bSAndroid Build Coastguard Worker // oapv_trace("already reached the end of bitstream\n"); /* should be updated */
263*abb65b4bSAndroid Build Coastguard Worker return;
264*abb65b4bSAndroid Build Coastguard Worker }
265*abb65b4bSAndroid Build Coastguard Worker }
266*abb65b4bSAndroid Build Coastguard Worker bsr_skip_code(bs, size);
267*abb65b4bSAndroid Build Coastguard Worker }
268*abb65b4bSAndroid Build Coastguard Worker
oapv_bsr_peek(oapv_bs_t * bs,u32 * val,int size)269*abb65b4bSAndroid Build Coastguard Worker void oapv_bsr_peek(oapv_bs_t *bs, u32 *val, int size)
270*abb65b4bSAndroid Build Coastguard Worker {
271*abb65b4bSAndroid Build Coastguard Worker int byte, leftbits;
272*abb65b4bSAndroid Build Coastguard Worker u32 code = 0;
273*abb65b4bSAndroid Build Coastguard Worker
274*abb65b4bSAndroid Build Coastguard Worker if(bs->leftbits < size) {
275*abb65b4bSAndroid Build Coastguard Worker byte = (32 - bs->leftbits) >> 3;
276*abb65b4bSAndroid Build Coastguard Worker
277*abb65b4bSAndroid Build Coastguard Worker /* We should not check the return value
278*abb65b4bSAndroid Build Coastguard Worker because this function could be failed at the EOB. */
279*abb65b4bSAndroid Build Coastguard Worker if(byte) {
280*abb65b4bSAndroid Build Coastguard Worker code = bs->code;
281*abb65b4bSAndroid Build Coastguard Worker leftbits = bs->leftbits;
282*abb65b4bSAndroid Build Coastguard Worker
283*abb65b4bSAndroid Build Coastguard Worker bs->fn_flush(bs, byte);
284*abb65b4bSAndroid Build Coastguard Worker
285*abb65b4bSAndroid Build Coastguard Worker bs->code >>= leftbits;
286*abb65b4bSAndroid Build Coastguard Worker bs->code |= code;
287*abb65b4bSAndroid Build Coastguard Worker bs->leftbits += leftbits;
288*abb65b4bSAndroid Build Coastguard Worker }
289*abb65b4bSAndroid Build Coastguard Worker }
290*abb65b4bSAndroid Build Coastguard Worker
291*abb65b4bSAndroid Build Coastguard Worker oapv_assert(bs->leftbits <= 32);
292*abb65b4bSAndroid Build Coastguard Worker
293*abb65b4bSAndroid Build Coastguard Worker code = bs->code >> (32 - size);
294*abb65b4bSAndroid Build Coastguard Worker size -= bs->leftbits;
295*abb65b4bSAndroid Build Coastguard Worker
296*abb65b4bSAndroid Build Coastguard Worker if(size > 0) {
297*abb65b4bSAndroid Build Coastguard Worker /* even though we update several bytes, the requested size would be
298*abb65b4bSAndroid Build Coastguard Worker larger than current bs->leftbits.
299*abb65b4bSAndroid Build Coastguard Worker In this case, we should read one more byte, but we could not store
300*abb65b4bSAndroid Build Coastguard Worker the read byte. */
301*abb65b4bSAndroid Build Coastguard Worker if(bs->cur <= bs->end) {
302*abb65b4bSAndroid Build Coastguard Worker code |= *(bs->cur) >> (8 - size);
303*abb65b4bSAndroid Build Coastguard Worker }
304*abb65b4bSAndroid Build Coastguard Worker }
305*abb65b4bSAndroid Build Coastguard Worker *val = code;
306*abb65b4bSAndroid Build Coastguard Worker }
307*abb65b4bSAndroid Build Coastguard Worker
oapv_bsr_sink(oapv_bs_t * bs)308*abb65b4bSAndroid Build Coastguard Worker void *oapv_bsr_sink(oapv_bs_t *bs)
309*abb65b4bSAndroid Build Coastguard Worker {
310*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv(bs->cur + BSW_GET_SINK_BYTE(bs) <= bs->end, NULL);
311*abb65b4bSAndroid Build Coastguard Worker oapv_assert_rv((bs->leftbits & 7) == 0, NULL);
312*abb65b4bSAndroid Build Coastguard Worker bs->cur = bs->cur - (bs->leftbits >> 3);
313*abb65b4bSAndroid Build Coastguard Worker bs->code = 0;
314*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 0;
315*abb65b4bSAndroid Build Coastguard Worker return (void *)bs->cur;
316*abb65b4bSAndroid Build Coastguard Worker }
317*abb65b4bSAndroid Build Coastguard Worker
oapv_bsr_move(oapv_bs_t * bs,u8 * pos)318*abb65b4bSAndroid Build Coastguard Worker void oapv_bsr_move(oapv_bs_t *bs, u8 *pos)
319*abb65b4bSAndroid Build Coastguard Worker {
320*abb65b4bSAndroid Build Coastguard Worker bs->code = 0;
321*abb65b4bSAndroid Build Coastguard Worker bs->leftbits = 0;
322*abb65b4bSAndroid Build Coastguard Worker bs->cur = pos;
323*abb65b4bSAndroid Build Coastguard Worker }
324*abb65b4bSAndroid Build Coastguard Worker
oapv_bsr_read(oapv_bs_t * bs,int size)325*abb65b4bSAndroid Build Coastguard Worker u32 oapv_bsr_read(oapv_bs_t *bs, int size)
326*abb65b4bSAndroid Build Coastguard Worker {
327*abb65b4bSAndroid Build Coastguard Worker u32 code = 0;
328*abb65b4bSAndroid Build Coastguard Worker
329*abb65b4bSAndroid Build Coastguard Worker oapv_assert(size > 0);
330*abb65b4bSAndroid Build Coastguard Worker
331*abb65b4bSAndroid Build Coastguard Worker if(bs->leftbits < size) {
332*abb65b4bSAndroid Build Coastguard Worker code = bs->code >> (32 - size);
333*abb65b4bSAndroid Build Coastguard Worker size -= bs->leftbits;
334*abb65b4bSAndroid Build Coastguard Worker if(bs->fn_flush(bs, 4)) {
335*abb65b4bSAndroid Build Coastguard Worker oapv_trace("already reached the end of bitstream\n"); /* should be updated */
336*abb65b4bSAndroid Build Coastguard Worker return (u32)(-1);
337*abb65b4bSAndroid Build Coastguard Worker }
338*abb65b4bSAndroid Build Coastguard Worker }
339*abb65b4bSAndroid Build Coastguard Worker code |= bs->code >> (32 - size);
340*abb65b4bSAndroid Build Coastguard Worker
341*abb65b4bSAndroid Build Coastguard Worker bsr_skip_code(bs, size);
342*abb65b4bSAndroid Build Coastguard Worker
343*abb65b4bSAndroid Build Coastguard Worker return code;
344*abb65b4bSAndroid Build Coastguard Worker }
345*abb65b4bSAndroid Build Coastguard Worker
oapv_bsr_read1(oapv_bs_t * bs)346*abb65b4bSAndroid Build Coastguard Worker int oapv_bsr_read1(oapv_bs_t *bs)
347*abb65b4bSAndroid Build Coastguard Worker {
348*abb65b4bSAndroid Build Coastguard Worker int code;
349*abb65b4bSAndroid Build Coastguard Worker if(bs->leftbits == 0) {
350*abb65b4bSAndroid Build Coastguard Worker if(bs->fn_flush(bs, 4)) {
351*abb65b4bSAndroid Build Coastguard Worker oapv_trace("already reached the end of bitstream\n"); /* should be updated */
352*abb65b4bSAndroid Build Coastguard Worker return -1;
353*abb65b4bSAndroid Build Coastguard Worker }
354*abb65b4bSAndroid Build Coastguard Worker }
355*abb65b4bSAndroid Build Coastguard Worker code = (int)(bs->code >> 31);
356*abb65b4bSAndroid Build Coastguard Worker
357*abb65b4bSAndroid Build Coastguard Worker bs->code <<= 1;
358*abb65b4bSAndroid Build Coastguard Worker bs->leftbits -= 1;
359*abb65b4bSAndroid Build Coastguard Worker
360*abb65b4bSAndroid Build Coastguard Worker return code;
361*abb65b4bSAndroid Build Coastguard Worker }
362*abb65b4bSAndroid Build Coastguard Worker
363*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
364*abb65b4bSAndroid Build Coastguard Worker // end of decoder code
365*abb65b4bSAndroid Build Coastguard Worker #endif // ENABLE_DECODER
366*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
367