xref: /aosp_15_r20/external/libopenapv/src/oapv_vlc.c (revision abb65b4b03b69e1d508d4d9a44dcf199df16e7c3)
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 #include "oapv_metadata.h"
34*abb65b4bSAndroid Build Coastguard Worker 
35*abb65b4bSAndroid Build Coastguard Worker #define OAPV_FLUSH_SWAP(cur, code, lb) \
36*abb65b4bSAndroid Build Coastguard Worker     {                                  \
37*abb65b4bSAndroid Build Coastguard Worker         *cur++ = (code >> 24) & 0xFF;  \
38*abb65b4bSAndroid Build Coastguard Worker         *cur++ = (code >> 16) & 0xFF;  \
39*abb65b4bSAndroid Build Coastguard Worker         *cur++ = (code >> 8) & 0xFF;   \
40*abb65b4bSAndroid Build Coastguard Worker         *cur++ = (code) & 0xFF;        \
41*abb65b4bSAndroid Build Coastguard Worker         code = 0;                      \
42*abb65b4bSAndroid Build Coastguard Worker         lb = 32;                       \
43*abb65b4bSAndroid Build Coastguard Worker     }
44*abb65b4bSAndroid Build Coastguard Worker 
45*abb65b4bSAndroid Build Coastguard Worker #define OAPV_FLUSH(bs)                        \
46*abb65b4bSAndroid Build Coastguard Worker     {                                         \
47*abb65b4bSAndroid Build Coastguard Worker         *bs->cur++ = (bs->code >> 24) & 0xFF; \
48*abb65b4bSAndroid Build Coastguard Worker         *bs->cur++ = (bs->code >> 16) & 0xFF; \
49*abb65b4bSAndroid Build Coastguard Worker         *bs->cur++ = (bs->code >> 8) & 0xFF;  \
50*abb65b4bSAndroid Build Coastguard Worker         *bs->cur++ = (bs->code) & 0xFF;       \
51*abb65b4bSAndroid Build Coastguard Worker         bs->code = 0;                         \
52*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits = 32;                    \
53*abb65b4bSAndroid Build Coastguard Worker     }
54*abb65b4bSAndroid Build Coastguard Worker 
55*abb65b4bSAndroid Build Coastguard Worker #define OAPV_READ_FLUSH(bs, byte)       \
56*abb65b4bSAndroid Build Coastguard Worker     {                                   \
57*abb65b4bSAndroid Build Coastguard Worker         bs->code = 0;                   \
58*abb65b4bSAndroid Build Coastguard Worker         bs->code |= *(bs->cur++) << 24; \
59*abb65b4bSAndroid Build Coastguard Worker         bs->code |= *(bs->cur++) << 16; \
60*abb65b4bSAndroid Build Coastguard Worker         bs->code |= *(bs->cur++) << 8;  \
61*abb65b4bSAndroid Build Coastguard Worker         bs->code |= *(bs->cur++);       \
62*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits = 32;              \
63*abb65b4bSAndroid Build Coastguard Worker     }
64*abb65b4bSAndroid Build Coastguard Worker 
65*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
66*abb65b4bSAndroid Build Coastguard Worker // start of encoder code
67*abb65b4bSAndroid Build Coastguard Worker #if ENABLE_ENCODER
68*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
69*abb65b4bSAndroid Build Coastguard Worker 
enc_vlc_write(oapv_bs_t * bs,int coef,int k)70*abb65b4bSAndroid Build Coastguard Worker static inline void enc_vlc_write(oapv_bs_t *bs, int coef, int k)
71*abb65b4bSAndroid Build Coastguard Worker {
72*abb65b4bSAndroid Build Coastguard Worker     const s32 simple_vlc_table[3][2] = { {
73*abb65b4bSAndroid Build Coastguard Worker                                              1,
74*abb65b4bSAndroid Build Coastguard Worker                                          },
75*abb65b4bSAndroid Build Coastguard Worker                                          { 0, 0 },
76*abb65b4bSAndroid Build Coastguard Worker                                          { 0, 1 } };
77*abb65b4bSAndroid Build Coastguard Worker     u32       symbol = coef;
78*abb65b4bSAndroid Build Coastguard Worker     u32       simple_vlc_val = oapv_clip3(0, 2, symbol >> k);
79*abb65b4bSAndroid Build Coastguard Worker     int       bit_cnt = 0;
80*abb65b4bSAndroid Build Coastguard Worker     if(bs->is_bin_count) {
81*abb65b4bSAndroid Build Coastguard Worker         bs->bin_count += coef;
82*abb65b4bSAndroid Build Coastguard Worker         return;
83*abb65b4bSAndroid Build Coastguard Worker     }
84*abb65b4bSAndroid Build Coastguard Worker     if(symbol >= (u32)(1 << k)) {
85*abb65b4bSAndroid Build Coastguard Worker         symbol -= (1 << k);
86*abb65b4bSAndroid Build Coastguard Worker         int val = simple_vlc_table[simple_vlc_val][bit_cnt];
87*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits--;
88*abb65b4bSAndroid Build Coastguard Worker         bs->code |= ((val & 0x1) << bs->leftbits);
89*abb65b4bSAndroid Build Coastguard Worker         if(bs->leftbits == 0) {
90*abb65b4bSAndroid Build Coastguard Worker             OAPV_FLUSH(bs);
91*abb65b4bSAndroid Build Coastguard Worker         }
92*abb65b4bSAndroid Build Coastguard Worker         bit_cnt++;
93*abb65b4bSAndroid Build Coastguard Worker     }
94*abb65b4bSAndroid Build Coastguard Worker     if(symbol >= (u32)(1 << k) && simple_vlc_val > 0) {
95*abb65b4bSAndroid Build Coastguard Worker         symbol -= (1 << k);
96*abb65b4bSAndroid Build Coastguard Worker         int val = simple_vlc_table[simple_vlc_val][bit_cnt];
97*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits--;
98*abb65b4bSAndroid Build Coastguard Worker         bs->code |= ((val & 0x1) << bs->leftbits);
99*abb65b4bSAndroid Build Coastguard Worker         if(bs->leftbits == 0) {
100*abb65b4bSAndroid Build Coastguard Worker             OAPV_FLUSH(bs);
101*abb65b4bSAndroid Build Coastguard Worker         }
102*abb65b4bSAndroid Build Coastguard Worker         bit_cnt++;
103*abb65b4bSAndroid Build Coastguard Worker     }
104*abb65b4bSAndroid Build Coastguard Worker     while(symbol >= (u32)(1 << k)) {
105*abb65b4bSAndroid Build Coastguard Worker         symbol -= (1 << k);
106*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits--;
107*abb65b4bSAndroid Build Coastguard Worker         if(bs->leftbits == 0) {
108*abb65b4bSAndroid Build Coastguard Worker             OAPV_FLUSH(bs);
109*abb65b4bSAndroid Build Coastguard Worker         }
110*abb65b4bSAndroid Build Coastguard Worker         if(bit_cnt >= 2) {
111*abb65b4bSAndroid Build Coastguard Worker             k++;
112*abb65b4bSAndroid Build Coastguard Worker         }
113*abb65b4bSAndroid Build Coastguard Worker         bit_cnt++;
114*abb65b4bSAndroid Build Coastguard Worker     }
115*abb65b4bSAndroid Build Coastguard Worker     if(bit_cnt < 2) {
116*abb65b4bSAndroid Build Coastguard Worker         int val = simple_vlc_table[simple_vlc_val][bit_cnt];
117*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits--;
118*abb65b4bSAndroid Build Coastguard Worker         bs->code |= ((val & 0x1) << bs->leftbits);
119*abb65b4bSAndroid Build Coastguard Worker         if(bs->leftbits == 0) {
120*abb65b4bSAndroid Build Coastguard Worker             OAPV_FLUSH(bs);
121*abb65b4bSAndroid Build Coastguard Worker         }
122*abb65b4bSAndroid Build Coastguard Worker     }
123*abb65b4bSAndroid Build Coastguard Worker     else {
124*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits--;
125*abb65b4bSAndroid Build Coastguard Worker         bs->code |= ((1 & 0x1) << bs->leftbits);
126*abb65b4bSAndroid Build Coastguard Worker         if(bs->leftbits == 0) {
127*abb65b4bSAndroid Build Coastguard Worker             OAPV_FLUSH(bs);
128*abb65b4bSAndroid Build Coastguard Worker         }
129*abb65b4bSAndroid Build Coastguard Worker     }
130*abb65b4bSAndroid Build Coastguard Worker     if(k > 0) {
131*abb65b4bSAndroid Build Coastguard Worker         int leftbits;
132*abb65b4bSAndroid Build Coastguard Worker         leftbits = bs->leftbits;
133*abb65b4bSAndroid Build Coastguard Worker         symbol <<= (32 - k);
134*abb65b4bSAndroid Build Coastguard Worker         bs->code |= (symbol >> (32 - leftbits));
135*abb65b4bSAndroid Build Coastguard Worker         if(k < leftbits) {
136*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits -= k;
137*abb65b4bSAndroid Build Coastguard Worker         }
138*abb65b4bSAndroid Build Coastguard Worker         else {
139*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits = 0;
140*abb65b4bSAndroid Build Coastguard Worker             OAPV_FLUSH(bs);
141*abb65b4bSAndroid Build Coastguard Worker             bs->code = (leftbits < 32 ? symbol << leftbits : 0);
142*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits = 32 - (k - leftbits);
143*abb65b4bSAndroid Build Coastguard Worker         }
144*abb65b4bSAndroid Build Coastguard Worker     }
145*abb65b4bSAndroid Build Coastguard Worker }
146*abb65b4bSAndroid Build Coastguard Worker 
bsr_skip_code_opt(oapv_bs_t * bs,int size)147*abb65b4bSAndroid Build Coastguard Worker static void inline bsr_skip_code_opt(oapv_bs_t *bs, int size)
148*abb65b4bSAndroid Build Coastguard Worker {
149*abb65b4bSAndroid Build Coastguard Worker 
150*abb65b4bSAndroid Build Coastguard Worker     if(size == 32) {
151*abb65b4bSAndroid Build Coastguard Worker         bs->code = 0;
152*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits = 0;
153*abb65b4bSAndroid Build Coastguard Worker     }
154*abb65b4bSAndroid Build Coastguard Worker     else {
155*abb65b4bSAndroid Build Coastguard Worker         bs->code <<= size;
156*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits -= size;
157*abb65b4bSAndroid Build Coastguard Worker     }
158*abb65b4bSAndroid Build Coastguard Worker }
dec_vlc_read_1bit_read(oapv_bs_t * bs,int k)159*abb65b4bSAndroid Build Coastguard Worker static int dec_vlc_read_1bit_read(oapv_bs_t *bs, int k)
160*abb65b4bSAndroid Build Coastguard Worker {
161*abb65b4bSAndroid Build Coastguard Worker     u32 symbol = 0;
162*abb65b4bSAndroid Build Coastguard Worker     int t0 = -1;
163*abb65b4bSAndroid Build Coastguard Worker     int parse_exp_golomb = 1;
164*abb65b4bSAndroid Build Coastguard Worker     if(bs->leftbits == 0) {
165*abb65b4bSAndroid Build Coastguard Worker         OAPV_READ_FLUSH(bs, 4);
166*abb65b4bSAndroid Build Coastguard Worker     }
167*abb65b4bSAndroid Build Coastguard Worker     t0 = (u32)(bs->code >> 31);
168*abb65b4bSAndroid Build Coastguard Worker     bs->code <<= 1;
169*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits -= 1;
170*abb65b4bSAndroid Build Coastguard Worker     if(t0 == 0) {
171*abb65b4bSAndroid Build Coastguard Worker         symbol += (1 << k);
172*abb65b4bSAndroid Build Coastguard Worker         parse_exp_golomb = 0;
173*abb65b4bSAndroid Build Coastguard Worker     }
174*abb65b4bSAndroid Build Coastguard Worker     else {
175*abb65b4bSAndroid Build Coastguard Worker         symbol += (2 << k);
176*abb65b4bSAndroid Build Coastguard Worker         parse_exp_golomb = 1;
177*abb65b4bSAndroid Build Coastguard Worker     }
178*abb65b4bSAndroid Build Coastguard Worker     if(parse_exp_golomb) {
179*abb65b4bSAndroid Build Coastguard Worker         while(1) {
180*abb65b4bSAndroid Build Coastguard Worker             if(bs->leftbits == 0) {
181*abb65b4bSAndroid Build Coastguard Worker                 OAPV_READ_FLUSH(bs, 4);
182*abb65b4bSAndroid Build Coastguard Worker             }
183*abb65b4bSAndroid Build Coastguard Worker             t0 = (u32)(bs->code >> 31);
184*abb65b4bSAndroid Build Coastguard Worker             bs->code <<= 1;
185*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits -= 1;
186*abb65b4bSAndroid Build Coastguard Worker             if(t0 == 1) {
187*abb65b4bSAndroid Build Coastguard Worker                 break;
188*abb65b4bSAndroid Build Coastguard Worker             }
189*abb65b4bSAndroid Build Coastguard Worker             else {
190*abb65b4bSAndroid Build Coastguard Worker                 symbol += (1 << k);
191*abb65b4bSAndroid Build Coastguard Worker                 k++;
192*abb65b4bSAndroid Build Coastguard Worker             }
193*abb65b4bSAndroid Build Coastguard Worker         }
194*abb65b4bSAndroid Build Coastguard Worker     }
195*abb65b4bSAndroid Build Coastguard Worker     if(k > 0) {
196*abb65b4bSAndroid Build Coastguard Worker         u32 code = 0;
197*abb65b4bSAndroid Build Coastguard Worker         if(bs->leftbits < k) {
198*abb65b4bSAndroid Build Coastguard Worker             code = bs->code >> (32 - k);
199*abb65b4bSAndroid Build Coastguard Worker             k -= bs->leftbits;
200*abb65b4bSAndroid Build Coastguard Worker             OAPV_READ_FLUSH(bs, 4);
201*abb65b4bSAndroid Build Coastguard Worker         }
202*abb65b4bSAndroid Build Coastguard Worker         code |= bs->code >> (32 - k);
203*abb65b4bSAndroid Build Coastguard Worker         bsr_skip_code_opt(bs, k);
204*abb65b4bSAndroid Build Coastguard Worker         symbol += code;
205*abb65b4bSAndroid Build Coastguard Worker     }
206*abb65b4bSAndroid Build Coastguard Worker     return symbol;
207*abb65b4bSAndroid Build Coastguard Worker }
dec_vlc_read(oapv_bs_t * bs,int k)208*abb65b4bSAndroid Build Coastguard Worker static int dec_vlc_read(oapv_bs_t *bs, int k)
209*abb65b4bSAndroid Build Coastguard Worker {
210*abb65b4bSAndroid Build Coastguard Worker     u32 symbol = 0;
211*abb65b4bSAndroid Build Coastguard Worker     int t0 = -1;
212*abb65b4bSAndroid Build Coastguard Worker     int parse_exp_golomb = 1;
213*abb65b4bSAndroid Build Coastguard Worker     if(bs->leftbits == 0) {
214*abb65b4bSAndroid Build Coastguard Worker         OAPV_READ_FLUSH(bs, 4);
215*abb65b4bSAndroid Build Coastguard Worker     }
216*abb65b4bSAndroid Build Coastguard Worker     t0 = (u32)(bs->code >> 31);
217*abb65b4bSAndroid Build Coastguard Worker     bs->code <<= 1;
218*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits -= 1;
219*abb65b4bSAndroid Build Coastguard Worker     if(t0 == 1) {
220*abb65b4bSAndroid Build Coastguard Worker         parse_exp_golomb = 0;
221*abb65b4bSAndroid Build Coastguard Worker     }
222*abb65b4bSAndroid Build Coastguard Worker     else {
223*abb65b4bSAndroid Build Coastguard Worker         if(bs->leftbits == 0) {
224*abb65b4bSAndroid Build Coastguard Worker             OAPV_READ_FLUSH(bs, 4);
225*abb65b4bSAndroid Build Coastguard Worker         }
226*abb65b4bSAndroid Build Coastguard Worker         t0 = (u32)(bs->code >> 31);
227*abb65b4bSAndroid Build Coastguard Worker         bs->code <<= 1;
228*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits -= 1;
229*abb65b4bSAndroid Build Coastguard Worker         if(t0 == 0) {
230*abb65b4bSAndroid Build Coastguard Worker             symbol += (1 << k);
231*abb65b4bSAndroid Build Coastguard Worker             parse_exp_golomb = 0;
232*abb65b4bSAndroid Build Coastguard Worker         }
233*abb65b4bSAndroid Build Coastguard Worker         else {
234*abb65b4bSAndroid Build Coastguard Worker             symbol += (2 << k);
235*abb65b4bSAndroid Build Coastguard Worker             parse_exp_golomb = 1;
236*abb65b4bSAndroid Build Coastguard Worker         }
237*abb65b4bSAndroid Build Coastguard Worker     }
238*abb65b4bSAndroid Build Coastguard Worker     if(parse_exp_golomb) {
239*abb65b4bSAndroid Build Coastguard Worker         while(1) {
240*abb65b4bSAndroid Build Coastguard Worker             if(bs->leftbits == 0) {
241*abb65b4bSAndroid Build Coastguard Worker                 OAPV_READ_FLUSH(bs, 4);
242*abb65b4bSAndroid Build Coastguard Worker             }
243*abb65b4bSAndroid Build Coastguard Worker             t0 = (u32)(bs->code >> 31);
244*abb65b4bSAndroid Build Coastguard Worker             bs->code <<= 1;
245*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits -= 1;
246*abb65b4bSAndroid Build Coastguard Worker             if(t0 == 1) {
247*abb65b4bSAndroid Build Coastguard Worker                 break;
248*abb65b4bSAndroid Build Coastguard Worker             }
249*abb65b4bSAndroid Build Coastguard Worker             else {
250*abb65b4bSAndroid Build Coastguard Worker                 symbol += (1 << k);
251*abb65b4bSAndroid Build Coastguard Worker                 k++;
252*abb65b4bSAndroid Build Coastguard Worker             }
253*abb65b4bSAndroid Build Coastguard Worker         }
254*abb65b4bSAndroid Build Coastguard Worker     }
255*abb65b4bSAndroid Build Coastguard Worker     if(k > 0) {
256*abb65b4bSAndroid Build Coastguard Worker         u32 code = 0;
257*abb65b4bSAndroid Build Coastguard Worker         if(bs->leftbits < k) {
258*abb65b4bSAndroid Build Coastguard Worker             code = bs->code >> (32 - k);
259*abb65b4bSAndroid Build Coastguard Worker             k -= bs->leftbits;
260*abb65b4bSAndroid Build Coastguard Worker             OAPV_READ_FLUSH(bs, 4);
261*abb65b4bSAndroid Build Coastguard Worker         }
262*abb65b4bSAndroid Build Coastguard Worker         code |= bs->code >> (32 - k);
263*abb65b4bSAndroid Build Coastguard Worker         bsr_skip_code_opt(bs, k);
264*abb65b4bSAndroid Build Coastguard Worker         symbol += code;
265*abb65b4bSAndroid Build Coastguard Worker     }
266*abb65b4bSAndroid Build Coastguard Worker     return symbol;
267*abb65b4bSAndroid Build Coastguard Worker }
268*abb65b4bSAndroid Build Coastguard Worker 
oapve_set_frame_header(oapve_ctx_t * ctx,oapv_fh_t * fh)269*abb65b4bSAndroid Build Coastguard Worker void oapve_set_frame_header(oapve_ctx_t *ctx, oapv_fh_t *fh)
270*abb65b4bSAndroid Build Coastguard Worker {
271*abb65b4bSAndroid Build Coastguard Worker     oapv_mset(fh, 0, sizeof(oapv_fh_t));
272*abb65b4bSAndroid Build Coastguard Worker     fh->fi.profile_idc = ctx->param->profile_idc;
273*abb65b4bSAndroid Build Coastguard Worker     fh->fi.level_idc = ctx->param->level_idc;
274*abb65b4bSAndroid Build Coastguard Worker     fh->fi.band_idc = ctx->param->band_idc;
275*abb65b4bSAndroid Build Coastguard Worker     fh->fi.frame_width = ctx->param->w;
276*abb65b4bSAndroid Build Coastguard Worker     fh->fi.frame_height = ctx->param->h;
277*abb65b4bSAndroid Build Coastguard Worker     fh->fi.chroma_format_idc = ctx->cfi;
278*abb65b4bSAndroid Build Coastguard Worker     fh->fi.bit_depth = ctx->bit_depth;
279*abb65b4bSAndroid Build Coastguard Worker     fh->tile_width_in_mbs = ctx->param->tile_w_mb;
280*abb65b4bSAndroid Build Coastguard Worker     fh->tile_height_in_mbs = ctx->param->tile_h_mb;
281*abb65b4bSAndroid Build Coastguard Worker     if(fh->color_description_present_flag == 0) {
282*abb65b4bSAndroid Build Coastguard Worker         fh->color_primaries = 2;
283*abb65b4bSAndroid Build Coastguard Worker         fh->transfer_characteristics = 2;
284*abb65b4bSAndroid Build Coastguard Worker         fh->matrix_coefficients = 2;
285*abb65b4bSAndroid Build Coastguard Worker     }
286*abb65b4bSAndroid Build Coastguard Worker     fh->use_q_matrix = ctx->param->use_q_matrix;
287*abb65b4bSAndroid Build Coastguard Worker     if(fh->use_q_matrix == 0) {
288*abb65b4bSAndroid Build Coastguard Worker         for(int cidx = 0; cidx < ctx->num_comp; cidx++) {
289*abb65b4bSAndroid Build Coastguard Worker             for(int y = 0; y < OAPV_BLK_H; y++) {
290*abb65b4bSAndroid Build Coastguard Worker                 for(int x = 0; x < OAPV_BLK_W; x++) {
291*abb65b4bSAndroid Build Coastguard Worker                     fh->q_matrix[cidx][y][x] = 16;
292*abb65b4bSAndroid Build Coastguard Worker                 }
293*abb65b4bSAndroid Build Coastguard Worker             }
294*abb65b4bSAndroid Build Coastguard Worker         }
295*abb65b4bSAndroid Build Coastguard Worker     }
296*abb65b4bSAndroid Build Coastguard Worker     else {
297*abb65b4bSAndroid Build Coastguard Worker         int mod = (1 << OAPV_LOG2_BLK) - 1;
298*abb65b4bSAndroid Build Coastguard Worker         for(int i = 0; i < OAPV_BLK_D; i++) {
299*abb65b4bSAndroid Build Coastguard Worker             fh->q_matrix[Y_C][i >> OAPV_LOG2_BLK][i & mod] = ctx->param->q_matrix_y[i];
300*abb65b4bSAndroid Build Coastguard Worker             fh->q_matrix[U_C][i >> OAPV_LOG2_BLK][i & mod] = ctx->param->q_matrix_u[i];
301*abb65b4bSAndroid Build Coastguard Worker             fh->q_matrix[V_C][i >> OAPV_LOG2_BLK][i & mod] = ctx->param->q_matrix_v[i];
302*abb65b4bSAndroid Build Coastguard Worker             fh->q_matrix[X_C][i >> OAPV_LOG2_BLK][i & mod] = ctx->param->q_matrix_x[i];
303*abb65b4bSAndroid Build Coastguard Worker         }
304*abb65b4bSAndroid Build Coastguard Worker     }
305*abb65b4bSAndroid Build Coastguard Worker     fh->tile_size_present_in_fh_flag = 0;
306*abb65b4bSAndroid Build Coastguard Worker }
307*abb65b4bSAndroid Build Coastguard Worker 
enc_vlc_quantization_matrix(oapv_bs_t * bs,oapve_ctx_t * ctx,oapv_fh_t * fh)308*abb65b4bSAndroid Build Coastguard Worker static int enc_vlc_quantization_matrix(oapv_bs_t *bs, oapve_ctx_t *ctx, oapv_fh_t *fh)
309*abb65b4bSAndroid Build Coastguard Worker {
310*abb65b4bSAndroid Build Coastguard Worker     for(int cidx = 0; cidx < ctx->num_comp; cidx++) {
311*abb65b4bSAndroid Build Coastguard Worker         for(int y = 0; y < 8; y++) {
312*abb65b4bSAndroid Build Coastguard Worker             for(int x = 0; x < 8; x++) {
313*abb65b4bSAndroid Build Coastguard Worker                 oapv_bsw_write(bs, fh->q_matrix[cidx][y][x] - 1, 8);
314*abb65b4bSAndroid Build Coastguard Worker                 DUMP_HLS(fh->q_matrix, fh->q_matrix[cidx][y][x]);
315*abb65b4bSAndroid Build Coastguard Worker             }
316*abb65b4bSAndroid Build Coastguard Worker         }
317*abb65b4bSAndroid Build Coastguard Worker     }
318*abb65b4bSAndroid Build Coastguard Worker     return 0;
319*abb65b4bSAndroid Build Coastguard Worker }
320*abb65b4bSAndroid Build Coastguard Worker 
enc_vlc_tile_info(oapv_bs_t * bs,oapve_ctx_t * ctx,oapv_fh_t * fh)321*abb65b4bSAndroid Build Coastguard Worker static int enc_vlc_tile_info(oapv_bs_t *bs, oapve_ctx_t *ctx, oapv_fh_t *fh)
322*abb65b4bSAndroid Build Coastguard Worker {
323*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fh->tile_width_in_mbs - 1, 28);
324*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fh->tile_width_in_mbs, fh->tile_width_in_mbs);
325*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fh->tile_height_in_mbs - 1, 28);
326*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fh->tile_height_in_mbs, fh->tile_height_in_mbs);
327*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fh->tile_size_present_in_fh_flag, 1);
328*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fh->tile_size_present_in_fh_flag, fh->tile_size_present_in_fh_flag);
329*abb65b4bSAndroid Build Coastguard Worker     if(fh->tile_size_present_in_fh_flag) {
330*abb65b4bSAndroid Build Coastguard Worker         for(int i = 0; i < ctx->num_tiles; i++) {
331*abb65b4bSAndroid Build Coastguard Worker             oapv_bsw_write(bs, fh->tile_size[i] - 1, 32);
332*abb65b4bSAndroid Build Coastguard Worker             DUMP_HLS(fh->tile_size, fh->tile_size[i] - 1);
333*abb65b4bSAndroid Build Coastguard Worker         }
334*abb65b4bSAndroid Build Coastguard Worker     }
335*abb65b4bSAndroid Build Coastguard Worker 
336*abb65b4bSAndroid Build Coastguard Worker     return 0;
337*abb65b4bSAndroid Build Coastguard Worker }
338*abb65b4bSAndroid Build Coastguard Worker 
oapve_vlc_frame_info(oapv_bs_t * bs,oapv_fi_t * fi)339*abb65b4bSAndroid Build Coastguard Worker int oapve_vlc_frame_info(oapv_bs_t *bs, oapv_fi_t *fi)
340*abb65b4bSAndroid Build Coastguard Worker {
341*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fi->profile_idc, 8);
342*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->profile_idc, fi->profile_idc);
343*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fi->level_idc, 8);
344*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->level_idc, fi->level_idc);
345*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fi->band_idc, 3);
346*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->band_idc, fi->band_idc);
347*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, 0, 5); // reserved_zero_5bits
348*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero, 0);
349*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fi->frame_width - 1, 32);
350*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->frame_width, fi->frame_width - 1);
351*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fi->frame_height - 1, 32);
352*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->frame_height, fi->frame_height - 1);
353*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fi->chroma_format_idc, 4);
354*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->chroma_format_idc, fi->chroma_format_idc);
355*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fi->bit_depth - 8, 4);
356*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->bit_depth, fi->bit_depth - 8);
357*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fi->capture_time_distance, 8);
358*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->capture_time_distance, fi->capture_time_distance);
359*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, 0, 8); // reserved_zero_8bits
360*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero, 0);
361*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
362*abb65b4bSAndroid Build Coastguard Worker }
363*abb65b4bSAndroid Build Coastguard Worker 
oapve_vlc_frame_header(oapv_bs_t * bs,oapve_ctx_t * ctx,oapv_fh_t * fh)364*abb65b4bSAndroid Build Coastguard Worker int oapve_vlc_frame_header(oapv_bs_t *bs, oapve_ctx_t *ctx, oapv_fh_t *fh)
365*abb65b4bSAndroid Build Coastguard Worker {
366*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(bsw_is_align8(bs), OAPV_ERR_MALFORMED_BITSTREAM);
367*abb65b4bSAndroid Build Coastguard Worker 
368*abb65b4bSAndroid Build Coastguard Worker     oapve_vlc_frame_info(bs, &fh->fi);
369*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, 0, 8); // reserved_zero_8bits
370*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero, 0);
371*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fh->color_description_present_flag, 1);
372*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fh->color_description_present_flag, fh->color_description_present_flag);
373*abb65b4bSAndroid Build Coastguard Worker     if(fh->color_description_present_flag) {
374*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write(bs, fh->color_primaries, 8);
375*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(fh->color_primaries, fh->color_primaries);
376*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write(bs, fh->transfer_characteristics, 8);
377*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(fh->transfer_characteristics, fh->transfer_characteristics);
378*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write(bs, fh->matrix_coefficients, 8);
379*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(fh->matrix_coefficients, fh->matrix_coefficients);
380*abb65b4bSAndroid Build Coastguard Worker     }
381*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, fh->use_q_matrix, 1);
382*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fh->use_q_matrix, fh->use_q_matrix);
383*abb65b4bSAndroid Build Coastguard Worker     if(fh->use_q_matrix) {
384*abb65b4bSAndroid Build Coastguard Worker         enc_vlc_quantization_matrix(bs, ctx, fh);
385*abb65b4bSAndroid Build Coastguard Worker     }
386*abb65b4bSAndroid Build Coastguard Worker     enc_vlc_tile_info(bs, ctx, fh);
387*abb65b4bSAndroid Build Coastguard Worker 
388*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, 0, 8); // reserved_zero_8bits
389*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero, 0);
390*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
391*abb65b4bSAndroid Build Coastguard Worker }
392*abb65b4bSAndroid Build Coastguard Worker 
oapve_vlc_tile_size(oapv_bs_t * bs,int tile_size)393*abb65b4bSAndroid Build Coastguard Worker int oapve_vlc_tile_size(oapv_bs_t *bs, int tile_size)
394*abb65b4bSAndroid Build Coastguard Worker {
395*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(bsw_is_align8(bs), OAPV_ERR_MALFORMED_BITSTREAM);
396*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, tile_size - 1, 32);
397*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(tile_size, tile_size - 1);
398*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
399*abb65b4bSAndroid Build Coastguard Worker }
400*abb65b4bSAndroid Build Coastguard Worker 
oapve_set_tile_header(oapve_ctx_t * ctx,oapv_th_t * th,int tile_idx,int qp)401*abb65b4bSAndroid Build Coastguard Worker void oapve_set_tile_header(oapve_ctx_t *ctx, oapv_th_t *th, int tile_idx, int qp)
402*abb65b4bSAndroid Build Coastguard Worker {
403*abb65b4bSAndroid Build Coastguard Worker     oapv_mset(th, 0, sizeof(oapv_th_t));
404*abb65b4bSAndroid Build Coastguard Worker     for(int c = 0; c < ctx->num_comp; c++) {
405*abb65b4bSAndroid Build Coastguard Worker         th->tile_qp[c] = qp;
406*abb65b4bSAndroid Build Coastguard Worker         if(c == 1) {
407*abb65b4bSAndroid Build Coastguard Worker             th->tile_qp[c] += ctx->param->qp_cb_offset;
408*abb65b4bSAndroid Build Coastguard Worker         }
409*abb65b4bSAndroid Build Coastguard Worker         else if(c == 2) {
410*abb65b4bSAndroid Build Coastguard Worker             th->tile_qp[c] += ctx->param->qp_cr_offset;
411*abb65b4bSAndroid Build Coastguard Worker         }
412*abb65b4bSAndroid Build Coastguard Worker     }
413*abb65b4bSAndroid Build Coastguard Worker     th->tile_index = tile_idx;
414*abb65b4bSAndroid Build Coastguard Worker 
415*abb65b4bSAndroid Build Coastguard Worker     for(int i = 0; i < N_C; i++) {
416*abb65b4bSAndroid Build Coastguard Worker         // this setting is required to prevent underflow at dummy writing tile header due to '-1'.
417*abb65b4bSAndroid Build Coastguard Worker         th->tile_data_size[i] = 1;
418*abb65b4bSAndroid Build Coastguard Worker     }
419*abb65b4bSAndroid Build Coastguard Worker }
420*abb65b4bSAndroid Build Coastguard Worker 
oapve_vlc_tile_header(oapve_ctx_t * ctx,oapv_bs_t * bs,oapv_th_t * th)421*abb65b4bSAndroid Build Coastguard Worker int oapve_vlc_tile_header(oapve_ctx_t *ctx, oapv_bs_t *bs, oapv_th_t *th)
422*abb65b4bSAndroid Build Coastguard Worker {
423*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(bsw_is_align8(bs), OAPV_ERR_MALFORMED_BITSTREAM);
424*abb65b4bSAndroid Build Coastguard Worker     th->tile_header_size = 5;                    // tile_header_size + tile_index + reserved_zero_8bits
425*abb65b4bSAndroid Build Coastguard Worker     th->tile_header_size += (ctx->num_comp * 5); // tile_data_size + tile_qp
426*abb65b4bSAndroid Build Coastguard Worker 
427*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, th->tile_header_size, 16);
428*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(th->tile_header_size, th->tile_header_size);
429*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, th->tile_index, 16);
430*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(th->tile_index, th->tile_index);
431*abb65b4bSAndroid Build Coastguard Worker     for(int c = 0; c < ctx->num_comp; c++) {
432*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write(bs, th->tile_data_size[c] - 1, 32);
433*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(th->tile_data_size, th->tile_data_size[c] - 1);
434*abb65b4bSAndroid Build Coastguard Worker     }
435*abb65b4bSAndroid Build Coastguard Worker     for(int c = 0; c < ctx->num_comp; c++) {
436*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write(bs, th->tile_qp[c], 8);
437*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(th->tile_qp, th->tile_qp[c]);
438*abb65b4bSAndroid Build Coastguard Worker     }
439*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, th->reserved_zero_8bits, 8);
440*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(th->reserved_zero_8bits, th->reserved_zero_8bits);
441*abb65b4bSAndroid Build Coastguard Worker 
442*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
443*abb65b4bSAndroid Build Coastguard Worker }
444*abb65b4bSAndroid Build Coastguard Worker 
oapve_vlc_run_length_cc(oapve_ctx_t * ctx,oapve_core_t * core,oapv_bs_t * bs,s16 * coef,int log2_w,int log2_h,int num_sig,int ch_type)445*abb65b4bSAndroid Build Coastguard Worker void oapve_vlc_run_length_cc(oapve_ctx_t *ctx, oapve_core_t *core, oapv_bs_t *bs, s16 *coef, int log2_w, int log2_h, int num_sig, int ch_type)
446*abb65b4bSAndroid Build Coastguard Worker {
447*abb65b4bSAndroid Build Coastguard Worker     u32        num_coeff, scan_pos;
448*abb65b4bSAndroid Build Coastguard Worker     u32        sign, level, prev_level, run;
449*abb65b4bSAndroid Build Coastguard Worker     const u16 *scanp;
450*abb65b4bSAndroid Build Coastguard Worker     s16        coef_cur;
451*abb65b4bSAndroid Build Coastguard Worker 
452*abb65b4bSAndroid Build Coastguard Worker     scanp = oapv_tbl_scan;
453*abb65b4bSAndroid Build Coastguard Worker     num_coeff = 1 << (log2_w + log2_h);
454*abb65b4bSAndroid Build Coastguard Worker     run = 0;
455*abb65b4bSAndroid Build Coastguard Worker     int first_ac = 1;
456*abb65b4bSAndroid Build Coastguard Worker     prev_level = core->prev_1st_ac_ctx[ch_type];
457*abb65b4bSAndroid Build Coastguard Worker 
458*abb65b4bSAndroid Build Coastguard Worker     int prev_run = 0;
459*abb65b4bSAndroid Build Coastguard Worker 
460*abb65b4bSAndroid Build Coastguard Worker     int rice_level = 0;
461*abb65b4bSAndroid Build Coastguard Worker     scan_pos = 0;
462*abb65b4bSAndroid Build Coastguard Worker 
463*abb65b4bSAndroid Build Coastguard Worker     // for DC
464*abb65b4bSAndroid Build Coastguard Worker     {
465*abb65b4bSAndroid Build Coastguard Worker         coef_cur = coef[scanp[scan_pos]];
466*abb65b4bSAndroid Build Coastguard Worker         level = oapv_abs16(coef_cur);
467*abb65b4bSAndroid Build Coastguard Worker         sign = (coef_cur > 0) ? 0 : 1;
468*abb65b4bSAndroid Build Coastguard Worker 
469*abb65b4bSAndroid Build Coastguard Worker         rice_level = oapv_clip3(OAPV_MIN_DC_LEVEL_CTX, OAPV_MAX_DC_LEVEL_CTX, core->prev_dc_ctx[ch_type] >> 1);
470*abb65b4bSAndroid Build Coastguard Worker 
471*abb65b4bSAndroid Build Coastguard Worker         enc_vlc_write(bs, level, rice_level);
472*abb65b4bSAndroid Build Coastguard Worker 
473*abb65b4bSAndroid Build Coastguard Worker         if(level)
474*abb65b4bSAndroid Build Coastguard Worker             oapv_bsw_write1(bs, sign);
475*abb65b4bSAndroid Build Coastguard Worker 
476*abb65b4bSAndroid Build Coastguard Worker         core->prev_dc_ctx[ch_type] = level;
477*abb65b4bSAndroid Build Coastguard Worker     }
478*abb65b4bSAndroid Build Coastguard Worker 
479*abb65b4bSAndroid Build Coastguard Worker     for(scan_pos = 1; scan_pos < num_coeff; scan_pos++) {
480*abb65b4bSAndroid Build Coastguard Worker         coef_cur = coef[scanp[scan_pos]];
481*abb65b4bSAndroid Build Coastguard Worker 
482*abb65b4bSAndroid Build Coastguard Worker         if(coef_cur) {
483*abb65b4bSAndroid Build Coastguard Worker             level = oapv_abs16(coef_cur);
484*abb65b4bSAndroid Build Coastguard Worker             sign = (coef_cur > 0) ? 0 : 1;
485*abb65b4bSAndroid Build Coastguard Worker 
486*abb65b4bSAndroid Build Coastguard Worker             /* Run coding */
487*abb65b4bSAndroid Build Coastguard Worker             int rice_run = 0;
488*abb65b4bSAndroid Build Coastguard Worker             rice_run = prev_run / 4;
489*abb65b4bSAndroid Build Coastguard Worker             if(rice_run > 2)
490*abb65b4bSAndroid Build Coastguard Worker                 rice_run = 2;
491*abb65b4bSAndroid Build Coastguard Worker             enc_vlc_write(bs, run, rice_run);
492*abb65b4bSAndroid Build Coastguard Worker 
493*abb65b4bSAndroid Build Coastguard Worker             /* Level coding */
494*abb65b4bSAndroid Build Coastguard Worker             rice_level = oapv_clip3(OAPV_MIN_AC_LEVEL_CTX, OAPV_MAX_AC_LEVEL_CTX, prev_level >> 2);
495*abb65b4bSAndroid Build Coastguard Worker             enc_vlc_write(bs, level - 1, rice_level);
496*abb65b4bSAndroid Build Coastguard Worker 
497*abb65b4bSAndroid Build Coastguard Worker             /* Sign coding */
498*abb65b4bSAndroid Build Coastguard Worker             oapv_bsw_write1(bs, sign);
499*abb65b4bSAndroid Build Coastguard Worker 
500*abb65b4bSAndroid Build Coastguard Worker             if(first_ac) {
501*abb65b4bSAndroid Build Coastguard Worker                 first_ac = 0;
502*abb65b4bSAndroid Build Coastguard Worker                 core->prev_1st_ac_ctx[ch_type] = level;
503*abb65b4bSAndroid Build Coastguard Worker             }
504*abb65b4bSAndroid Build Coastguard Worker 
505*abb65b4bSAndroid Build Coastguard Worker             if(scan_pos == num_coeff - 1) {
506*abb65b4bSAndroid Build Coastguard Worker                 break;
507*abb65b4bSAndroid Build Coastguard Worker             }
508*abb65b4bSAndroid Build Coastguard Worker             prev_run = run;
509*abb65b4bSAndroid Build Coastguard Worker             run = 0;
510*abb65b4bSAndroid Build Coastguard Worker 
511*abb65b4bSAndroid Build Coastguard Worker             {
512*abb65b4bSAndroid Build Coastguard Worker                 prev_level = level;
513*abb65b4bSAndroid Build Coastguard Worker             }
514*abb65b4bSAndroid Build Coastguard Worker 
515*abb65b4bSAndroid Build Coastguard Worker             num_sig--;
516*abb65b4bSAndroid Build Coastguard Worker         }
517*abb65b4bSAndroid Build Coastguard Worker         else {
518*abb65b4bSAndroid Build Coastguard Worker             run++;
519*abb65b4bSAndroid Build Coastguard Worker         }
520*abb65b4bSAndroid Build Coastguard Worker     }
521*abb65b4bSAndroid Build Coastguard Worker 
522*abb65b4bSAndroid Build Coastguard Worker     if(coef[scanp[num_coeff - 1]] == 0) {
523*abb65b4bSAndroid Build Coastguard Worker         int rice_run = 0;
524*abb65b4bSAndroid Build Coastguard Worker         rice_run = prev_run / 4;
525*abb65b4bSAndroid Build Coastguard Worker         if(rice_run > 2)
526*abb65b4bSAndroid Build Coastguard Worker             rice_run = 2;
527*abb65b4bSAndroid Build Coastguard Worker         enc_vlc_write(bs, run, rice_run);
528*abb65b4bSAndroid Build Coastguard Worker     }
529*abb65b4bSAndroid Build Coastguard Worker }
530*abb65b4bSAndroid Build Coastguard Worker 
oapve_vlc_au_info(oapv_bs_t * bs,oapve_ctx_t * ctx,oapv_frms_t * frms,oapv_bs_t ** bs_fi_pos)531*abb65b4bSAndroid Build Coastguard Worker int oapve_vlc_au_info(oapv_bs_t *bs, oapve_ctx_t *ctx, oapv_frms_t *frms, oapv_bs_t **bs_fi_pos)
532*abb65b4bSAndroid Build Coastguard Worker {
533*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, frms->num_frms, 16);
534*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(num_frames, frms->num_frms);
535*abb65b4bSAndroid Build Coastguard Worker     for(int fidx = 0; fidx < frms->num_frms; fidx++) {
536*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write(bs, frms->frm[fidx].pbu_type, 8);
537*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(pbu_type, frms->frm[fidx].pbu_type);
538*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write(bs, frms->frm[fidx].group_id, 16);
539*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(group_id, frms->frm[fidx].group_id);
540*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write(bs, 0, 8);
541*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(reserved_zero_8bits, 0);
542*abb65b4bSAndroid Build Coastguard Worker         memcpy(*(bs_fi_pos + sizeof(oapv_bs_t) * fidx), bs, sizeof(oapv_bs_t)); /* store fi pos in au to re-write */
543*abb65b4bSAndroid Build Coastguard Worker         oapve_vlc_frame_info(bs, &ctx->fh.fi);
544*abb65b4bSAndroid Build Coastguard Worker     }
545*abb65b4bSAndroid Build Coastguard Worker 
546*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, 0, 8);
547*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero_8bits, 0);
548*abb65b4bSAndroid Build Coastguard Worker     while(!bsw_is_align8(bs)) {
549*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write1(bs, 0);
550*abb65b4bSAndroid Build Coastguard Worker     }
551*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
552*abb65b4bSAndroid Build Coastguard Worker }
553*abb65b4bSAndroid Build Coastguard Worker 
oapve_vlc_pbu_size(oapv_bs_t * bs,int pbu_size)554*abb65b4bSAndroid Build Coastguard Worker int oapve_vlc_pbu_size(oapv_bs_t *bs, int pbu_size)
555*abb65b4bSAndroid Build Coastguard Worker {
556*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(bsw_is_align8(bs), OAPV_ERR_MALFORMED_BITSTREAM);
557*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, pbu_size, 32);
558*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(pbu_size, pbu_size);
559*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
560*abb65b4bSAndroid Build Coastguard Worker }
561*abb65b4bSAndroid Build Coastguard Worker 
oapve_vlc_pbu_header(oapv_bs_t * bs,int pbu_type,int group_id)562*abb65b4bSAndroid Build Coastguard Worker int oapve_vlc_pbu_header(oapv_bs_t *bs, int pbu_type, int group_id)
563*abb65b4bSAndroid Build Coastguard Worker {
564*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, pbu_type, 8);
565*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(pbu_type, pbu_type);
566*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, group_id, 16);
567*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(group_id, group_id);
568*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, 0, 8); // reserved_zero_8bit
569*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero, 0);
570*abb65b4bSAndroid Build Coastguard Worker 
571*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
572*abb65b4bSAndroid Build Coastguard Worker }
573*abb65b4bSAndroid Build Coastguard Worker 
574*abb65b4bSAndroid Build Coastguard Worker /****** ENABLE_DECODER ******/
oapve_vlc_metadata(oapv_md_t * md,oapv_bs_t * bs)575*abb65b4bSAndroid Build Coastguard Worker int oapve_vlc_metadata(oapv_md_t *md, oapv_bs_t *bs)
576*abb65b4bSAndroid Build Coastguard Worker {
577*abb65b4bSAndroid Build Coastguard Worker     oapv_bsw_write(bs, md->md_size, 32);
578*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(metadata_size, md->md_size);
579*abb65b4bSAndroid Build Coastguard Worker     oapv_mdp_t *mdp = md->md_payload;
580*abb65b4bSAndroid Build Coastguard Worker 
581*abb65b4bSAndroid Build Coastguard Worker     while(mdp != NULL) {
582*abb65b4bSAndroid Build Coastguard Worker         u32 mdp_pltype = mdp->pld_type;
583*abb65b4bSAndroid Build Coastguard Worker         while(mdp_pltype >= 255) {
584*abb65b4bSAndroid Build Coastguard Worker             oapv_bsw_write(bs, 0xFF, 8);
585*abb65b4bSAndroid Build Coastguard Worker             DUMP_HLS(payload_type, 0xFF);
586*abb65b4bSAndroid Build Coastguard Worker             mdp_pltype -= 255;
587*abb65b4bSAndroid Build Coastguard Worker         }
588*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write(bs, mdp_pltype, 8);
589*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(payload_type, mdp_pltype);
590*abb65b4bSAndroid Build Coastguard Worker 
591*abb65b4bSAndroid Build Coastguard Worker         u32 mdp_size = mdp->pld_size;
592*abb65b4bSAndroid Build Coastguard Worker         while(mdp_size >= 255) {
593*abb65b4bSAndroid Build Coastguard Worker             oapv_bsw_write(bs, 0xFF, 8);
594*abb65b4bSAndroid Build Coastguard Worker             DUMP_HLS(payload_size, 0xFF);
595*abb65b4bSAndroid Build Coastguard Worker             mdp_size -= 255;
596*abb65b4bSAndroid Build Coastguard Worker         }
597*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write(bs, mdp_size, 8);
598*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(payload_size, mdp_size);
599*abb65b4bSAndroid Build Coastguard Worker 
600*abb65b4bSAndroid Build Coastguard Worker         for(u32 i = 0; i < mdp->pld_size; i++) {
601*abb65b4bSAndroid Build Coastguard Worker             u8 *payload_data = (u8 *)mdp->pld_data;
602*abb65b4bSAndroid Build Coastguard Worker             oapv_bsw_write(bs, payload_data[i], 8);
603*abb65b4bSAndroid Build Coastguard Worker             DUMP_HLS(payload_data, payload_data[i]);
604*abb65b4bSAndroid Build Coastguard Worker         }
605*abb65b4bSAndroid Build Coastguard Worker 
606*abb65b4bSAndroid Build Coastguard Worker         mdp = mdp->next;
607*abb65b4bSAndroid Build Coastguard Worker     }
608*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
609*abb65b4bSAndroid Build Coastguard Worker }
610*abb65b4bSAndroid Build Coastguard Worker 
611*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
612*abb65b4bSAndroid Build Coastguard Worker // end of encoder code
613*abb65b4bSAndroid Build Coastguard Worker #endif // ENABLE_ENCODER
614*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
615*abb65b4bSAndroid Build Coastguard Worker 
616*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
617*abb65b4bSAndroid Build Coastguard Worker // start of decoder code
618*abb65b4bSAndroid Build Coastguard Worker #if ENABLE_DECODER
619*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
oapvd_vlc_au_size(oapv_bs_t * bs,u32 * au_size)620*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_au_size(oapv_bs_t *bs, u32 *au_size)
621*abb65b4bSAndroid Build Coastguard Worker {
622*abb65b4bSAndroid Build Coastguard Worker     u32 size;
623*abb65b4bSAndroid Build Coastguard Worker     size = oapv_bsr_read(bs, 32);
624*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(size > 0 && size < 0xFFFFFFFF, OAPV_ERR_MALFORMED_BITSTREAM);
625*abb65b4bSAndroid Build Coastguard Worker     *au_size = size;
626*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
627*abb65b4bSAndroid Build Coastguard Worker }
628*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_pbu_size(oapv_bs_t * bs,u32 * pbu_size)629*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_pbu_size(oapv_bs_t *bs, u32 *pbu_size)
630*abb65b4bSAndroid Build Coastguard Worker {
631*abb65b4bSAndroid Build Coastguard Worker     u32 size;
632*abb65b4bSAndroid Build Coastguard Worker     size = oapv_bsr_read(bs, 32);
633*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(pbu_size, size);
634*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(size > 0 && size < 0xFFFFFFFF, OAPV_ERR_MALFORMED_BITSTREAM);
635*abb65b4bSAndroid Build Coastguard Worker     *pbu_size = size;
636*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
637*abb65b4bSAndroid Build Coastguard Worker }
638*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_pbu_header(oapv_bs_t * bs,oapv_pbuh_t * pbuh)639*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_pbu_header(oapv_bs_t *bs, oapv_pbuh_t *pbuh)
640*abb65b4bSAndroid Build Coastguard Worker {
641*abb65b4bSAndroid Build Coastguard Worker     int reserved_zero;
642*abb65b4bSAndroid Build Coastguard Worker     pbuh->pbu_type = oapv_bsr_read(bs, 8);
643*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(pbu_type, pbuh->pbu_type);
644*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(pbuh->pbu_type != 0, OAPV_ERR_MALFORMED_BITSTREAM);
645*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(!(pbuh->pbu_type >= 3 && pbuh->pbu_type <= 24), OAPV_ERR_MALFORMED_BITSTREAM);
646*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(!(pbuh->pbu_type >= 28 && pbuh->pbu_type <= 64), OAPV_ERR_MALFORMED_BITSTREAM);
647*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(!(pbuh->pbu_type >= 68), OAPV_ERR_MALFORMED_BITSTREAM);
648*abb65b4bSAndroid Build Coastguard Worker 
649*abb65b4bSAndroid Build Coastguard Worker     pbuh->group_id = oapv_bsr_read(bs, 16);
650*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(group_id, pbuh->group_id);
651*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(pbuh->group_id >= 0 && pbuh->group_id < 0xFFFF, OAPV_ERR_MALFORMED_BITSTREAM);
652*abb65b4bSAndroid Build Coastguard Worker 
653*abb65b4bSAndroid Build Coastguard Worker     reserved_zero = oapv_bsr_read(bs, 8);
654*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero, reserved_zero);
655*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(reserved_zero == 0, OAPV_ERR_MALFORMED_BITSTREAM);
656*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
657*abb65b4bSAndroid Build Coastguard Worker }
658*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_frame_info(oapv_bs_t * bs,oapv_fi_t * fi)659*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_frame_info(oapv_bs_t *bs, oapv_fi_t *fi)
660*abb65b4bSAndroid Build Coastguard Worker {
661*abb65b4bSAndroid Build Coastguard Worker     int reserved_zero;
662*abb65b4bSAndroid Build Coastguard Worker 
663*abb65b4bSAndroid Build Coastguard Worker     fi->profile_idc = oapv_bsr_read(bs, 8);
664*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->profile_idc, fi->profile_idc);
665*abb65b4bSAndroid Build Coastguard Worker 
666*abb65b4bSAndroid Build Coastguard Worker     fi->level_idc = oapv_bsr_read(bs, 8);
667*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->level_idc, fi->level_idc);
668*abb65b4bSAndroid Build Coastguard Worker 
669*abb65b4bSAndroid Build Coastguard Worker     fi->band_idc = oapv_bsr_read(bs, 3);
670*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->band_idc, fi->band_idc);
671*abb65b4bSAndroid Build Coastguard Worker 
672*abb65b4bSAndroid Build Coastguard Worker     reserved_zero = oapv_bsr_read(bs, 5);
673*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero, reserved_zero);
674*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(reserved_zero == 0, OAPV_ERR_MALFORMED_BITSTREAM);
675*abb65b4bSAndroid Build Coastguard Worker 
676*abb65b4bSAndroid Build Coastguard Worker     fi->frame_width = oapv_bsr_read(bs, 32);
677*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->frame_width, fi->frame_width);
678*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(fi->frame_width > 0 && fi->frame_width < 0xFFFFFFFF, OAPV_ERR_MALFORMED_BITSTREAM);
679*abb65b4bSAndroid Build Coastguard Worker     fi->frame_width += 1;
680*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(fi->frame_width <= INT_MAX, OAPV_ERR_UNSUPPORTED); // frame width greater than 2^31 is unsupported in the current implementation
681*abb65b4bSAndroid Build Coastguard Worker 
682*abb65b4bSAndroid Build Coastguard Worker     fi->frame_height = oapv_bsr_read(bs, 32);
683*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->frame_height, fi->frame_height);
684*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(fi->frame_height > 0 && fi->frame_height < 0xFFFFFFFF, OAPV_ERR_MALFORMED_BITSTREAM);
685*abb65b4bSAndroid Build Coastguard Worker     fi->frame_height += 1;
686*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(fi->frame_height <= INT_MAX, OAPV_ERR_UNSUPPORTED); // frame height greater than 2^31 is unsupported in the current implementation
687*abb65b4bSAndroid Build Coastguard Worker 
688*abb65b4bSAndroid Build Coastguard Worker     fi->chroma_format_idc = oapv_bsr_read(bs, 4);
689*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->chroma_format_idc, fi->chroma_format_idc);
690*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(fi->chroma_format_idc >= 0 && fi->chroma_format_idc <= 4, OAPV_ERR_MALFORMED_BITSTREAM);
691*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(fi->chroma_format_idc != 1, OAPV_ERR_MALFORMED_BITSTREAM);
692*abb65b4bSAndroid Build Coastguard Worker 
693*abb65b4bSAndroid Build Coastguard Worker     fi->bit_depth = oapv_bsr_read(bs, 4);
694*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->bit_depth, fi->bit_depth);
695*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(fi->bit_depth >= 2 && fi->bit_depth <= 8, OAPV_ERR_MALFORMED_BITSTREAM);
696*abb65b4bSAndroid Build Coastguard Worker     fi->bit_depth += 8;
697*abb65b4bSAndroid Build Coastguard Worker 
698*abb65b4bSAndroid Build Coastguard Worker     fi->capture_time_distance = oapv_bsr_read(bs, 8);
699*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fi->capture_time_distance, fi->capture_time_distance);
700*abb65b4bSAndroid Build Coastguard Worker 
701*abb65b4bSAndroid Build Coastguard Worker     reserved_zero = oapv_bsr_read(bs, 8);
702*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero, reserved_zero);
703*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(reserved_zero == 0, OAPV_ERR_MALFORMED_BITSTREAM);
704*abb65b4bSAndroid Build Coastguard Worker 
705*abb65b4bSAndroid Build Coastguard Worker     // check frame width in case of 422 format.
706*abb65b4bSAndroid Build Coastguard Worker     if(fi->chroma_format_idc == 2) {
707*abb65b4bSAndroid Build Coastguard Worker         // frame_width should be multiple of 2
708*abb65b4bSAndroid Build Coastguard Worker         oapv_assert_rv((fi->frame_width & 0x1) == 0, OAPV_ERR_MALFORMED_BITSTREAM);
709*abb65b4bSAndroid Build Coastguard Worker     }
710*abb65b4bSAndroid Build Coastguard Worker 
711*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
712*abb65b4bSAndroid Build Coastguard Worker }
713*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_au_info(oapv_bs_t * bs,oapv_aui_t * aui)714*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_au_info(oapv_bs_t *bs, oapv_aui_t *aui)
715*abb65b4bSAndroid Build Coastguard Worker {
716*abb65b4bSAndroid Build Coastguard Worker     int ret;
717*abb65b4bSAndroid Build Coastguard Worker     int reserved_zero_8bits;
718*abb65b4bSAndroid Build Coastguard Worker 
719*abb65b4bSAndroid Build Coastguard Worker     aui->num_frames = oapv_bsr_read(bs, 16);
720*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(num_frames, aui->num_frames);
721*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(aui->num_frames <= OAPV_MAX_NUM_FRAMES, OAPV_ERR_REACHED_MAX);
722*abb65b4bSAndroid Build Coastguard Worker     for(int fidx = 0; fidx < aui->num_frames; fidx++) {
723*abb65b4bSAndroid Build Coastguard Worker         aui->pbu_type[fidx] = oapv_bsr_read(bs, 8);
724*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(pbu_type, aui->pbu_type[fidx]);
725*abb65b4bSAndroid Build Coastguard Worker         aui->group_id[fidx] = oapv_bsr_read(bs, 16);
726*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(group_id, aui->group_id[fidx]);
727*abb65b4bSAndroid Build Coastguard Worker         reserved_zero_8bits = oapv_bsr_read(bs, 8);
728*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(reserved_zero_8bits, reserved_zero_8bits);
729*abb65b4bSAndroid Build Coastguard Worker         oapv_assert_rv(reserved_zero_8bits == 0, OAPV_ERR_MALFORMED_BITSTREAM);
730*abb65b4bSAndroid Build Coastguard Worker         ret = oapvd_vlc_frame_info(bs, &aui->frame_info[fidx]);
731*abb65b4bSAndroid Build Coastguard Worker         oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
732*abb65b4bSAndroid Build Coastguard Worker     }
733*abb65b4bSAndroid Build Coastguard Worker     reserved_zero_8bits = oapv_bsr_read(bs, 8);
734*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero_8bits, reserved_zero_8bits);
735*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(reserved_zero_8bits == 0, OAPV_ERR_MALFORMED_BITSTREAM);
736*abb65b4bSAndroid Build Coastguard Worker     /* byte align */
737*abb65b4bSAndroid Build Coastguard Worker     oapv_bsr_align8(bs);
738*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
739*abb65b4bSAndroid Build Coastguard Worker }
740*abb65b4bSAndroid Build Coastguard Worker 
dec_vlc_q_matrix(oapv_bs_t * bs,oapv_fh_t * fh)741*abb65b4bSAndroid Build Coastguard Worker static int dec_vlc_q_matrix(oapv_bs_t *bs, oapv_fh_t *fh)
742*abb65b4bSAndroid Build Coastguard Worker {
743*abb65b4bSAndroid Build Coastguard Worker     int num_comp = get_num_comp(fh->fi.chroma_format_idc);
744*abb65b4bSAndroid Build Coastguard Worker     for(int cidx = 0; cidx < num_comp; cidx++) {
745*abb65b4bSAndroid Build Coastguard Worker         for(int y = 0; y < OAPV_BLK_H; y++) {
746*abb65b4bSAndroid Build Coastguard Worker             for(int x = 0; x < OAPV_BLK_W; x++) {
747*abb65b4bSAndroid Build Coastguard Worker                 fh->q_matrix[cidx][y][x] = oapv_bsr_read(bs, 8) + 1;
748*abb65b4bSAndroid Build Coastguard Worker                 DUMP_HLS(fh->q_matrix, fh->q_matrix[cidx][y][x]);
749*abb65b4bSAndroid Build Coastguard Worker             }
750*abb65b4bSAndroid Build Coastguard Worker         }
751*abb65b4bSAndroid Build Coastguard Worker     }
752*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
753*abb65b4bSAndroid Build Coastguard Worker }
754*abb65b4bSAndroid Build Coastguard Worker 
dec_vlc_tile_info(oapv_bs_t * bs,oapv_fh_t * fh)755*abb65b4bSAndroid Build Coastguard Worker static int dec_vlc_tile_info(oapv_bs_t *bs, oapv_fh_t *fh)
756*abb65b4bSAndroid Build Coastguard Worker {
757*abb65b4bSAndroid Build Coastguard Worker     int pic_w, pic_h, tile_w, tile_h, tile_cols, tile_rows;
758*abb65b4bSAndroid Build Coastguard Worker 
759*abb65b4bSAndroid Build Coastguard Worker     fh->tile_width_in_mbs = oapv_bsr_read(bs, 28) + 1;
760*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fh->tile_width_in_mbs, fh->tile_width_in_mbs);
761*abb65b4bSAndroid Build Coastguard Worker 
762*abb65b4bSAndroid Build Coastguard Worker     fh->tile_height_in_mbs = oapv_bsr_read(bs, 28) + 1;
763*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fh->tile_height_in_mbs, fh->tile_height_in_mbs);
764*abb65b4bSAndroid Build Coastguard Worker 
765*abb65b4bSAndroid Build Coastguard Worker     /* set various value */
766*abb65b4bSAndroid Build Coastguard Worker     pic_w = ((fh->fi.frame_width + (OAPV_MB_W - 1)) >> OAPV_LOG2_MB_W) << OAPV_LOG2_MB_W;
767*abb65b4bSAndroid Build Coastguard Worker     pic_h = ((fh->fi.frame_height + (OAPV_MB_H - 1)) >> OAPV_LOG2_MB_H) << OAPV_LOG2_MB_H;
768*abb65b4bSAndroid Build Coastguard Worker 
769*abb65b4bSAndroid Build Coastguard Worker     tile_w = fh->tile_width_in_mbs * OAPV_MB_W;
770*abb65b4bSAndroid Build Coastguard Worker     tile_h = fh->tile_height_in_mbs * OAPV_MB_H;
771*abb65b4bSAndroid Build Coastguard Worker 
772*abb65b4bSAndroid Build Coastguard Worker     tile_cols = (pic_w + (tile_w - 1)) / tile_w;
773*abb65b4bSAndroid Build Coastguard Worker     tile_rows = (pic_h + (tile_h - 1)) / tile_h;
774*abb65b4bSAndroid Build Coastguard Worker 
775*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(tile_cols <= OAPV_MAX_TILE_COLS && tile_rows <= OAPV_MAX_TILE_ROWS, OAPV_ERR_MALFORMED_BITSTREAM)
776*abb65b4bSAndroid Build Coastguard Worker 
777*abb65b4bSAndroid Build Coastguard Worker     fh->tile_size_present_in_fh_flag = oapv_bsr_read1(bs);
778*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fh->tile_size_present_in_fh_flag, fh->tile_size_present_in_fh_flag);
779*abb65b4bSAndroid Build Coastguard Worker 
780*abb65b4bSAndroid Build Coastguard Worker     if(fh->tile_size_present_in_fh_flag) {
781*abb65b4bSAndroid Build Coastguard Worker         for(int i = 0; i < tile_cols * tile_rows; i++) {
782*abb65b4bSAndroid Build Coastguard Worker             fh->tile_size[i] = oapv_bsr_read(bs, 32);
783*abb65b4bSAndroid Build Coastguard Worker             DUMP_HLS(fh->tile_size, fh->tile_size[i]);
784*abb65b4bSAndroid Build Coastguard Worker             oapv_assert_rv(fh->tile_size[i] > 0 && fh->tile_size[i] < 0xFFFFFFFF, OAPV_ERR_MALFORMED_BITSTREAM);
785*abb65b4bSAndroid Build Coastguard Worker             fh->tile_size[i] += 1;
786*abb65b4bSAndroid Build Coastguard Worker         }
787*abb65b4bSAndroid Build Coastguard Worker     }
788*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
789*abb65b4bSAndroid Build Coastguard Worker }
790*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_frame_header(oapv_bs_t * bs,oapv_fh_t * fh)791*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_frame_header(oapv_bs_t *bs, oapv_fh_t *fh)
792*abb65b4bSAndroid Build Coastguard Worker {
793*abb65b4bSAndroid Build Coastguard Worker     int ret, reserved_zero;
794*abb65b4bSAndroid Build Coastguard Worker     ret = oapvd_vlc_frame_info(bs, &fh->fi);
795*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
796*abb65b4bSAndroid Build Coastguard Worker 
797*abb65b4bSAndroid Build Coastguard Worker     reserved_zero = oapv_bsr_read(bs, 8);
798*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero, reserved_zero);
799*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(reserved_zero == 0, OAPV_ERR_MALFORMED_BITSTREAM);
800*abb65b4bSAndroid Build Coastguard Worker 
801*abb65b4bSAndroid Build Coastguard Worker     fh->color_description_present_flag = oapv_bsr_read(bs, 1);
802*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fh->color_description_present_flag, fh->color_description_present_flag);
803*abb65b4bSAndroid Build Coastguard Worker     if(fh->color_description_present_flag) {
804*abb65b4bSAndroid Build Coastguard Worker         fh->color_primaries = oapv_bsr_read(bs, 8);
805*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(fh->color_primaries, fh->color_primaries);
806*abb65b4bSAndroid Build Coastguard Worker         fh->transfer_characteristics = oapv_bsr_read(bs, 8);
807*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(fh->transfer_characteristics, fh->transfer_characteristics);
808*abb65b4bSAndroid Build Coastguard Worker         fh->matrix_coefficients = oapv_bsr_read(bs, 8);
809*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(fh->matrix_coefficients, fh->matrix_coefficients);
810*abb65b4bSAndroid Build Coastguard Worker     }
811*abb65b4bSAndroid Build Coastguard Worker     else {
812*abb65b4bSAndroid Build Coastguard Worker         fh->color_primaries = 2;
813*abb65b4bSAndroid Build Coastguard Worker         fh->transfer_characteristics = 2;
814*abb65b4bSAndroid Build Coastguard Worker         fh->matrix_coefficients = 2;
815*abb65b4bSAndroid Build Coastguard Worker     }
816*abb65b4bSAndroid Build Coastguard Worker     fh->use_q_matrix = oapv_bsr_read(bs, 1);
817*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(fh->use_q_matrix, fh->use_q_matrix);
818*abb65b4bSAndroid Build Coastguard Worker     if(fh->use_q_matrix) {
819*abb65b4bSAndroid Build Coastguard Worker         ret = dec_vlc_q_matrix(bs, fh);
820*abb65b4bSAndroid Build Coastguard Worker         oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
821*abb65b4bSAndroid Build Coastguard Worker     }
822*abb65b4bSAndroid Build Coastguard Worker 
823*abb65b4bSAndroid Build Coastguard Worker     ret = dec_vlc_tile_info(bs, fh);
824*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(OAPV_SUCCEEDED(ret), ret);
825*abb65b4bSAndroid Build Coastguard Worker 
826*abb65b4bSAndroid Build Coastguard Worker     reserved_zero = oapv_bsr_read(bs, 8);
827*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(reserved_zero, reserved_zero);
828*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(reserved_zero == 0, OAPV_ERR_MALFORMED_BITSTREAM);
829*abb65b4bSAndroid Build Coastguard Worker 
830*abb65b4bSAndroid Build Coastguard Worker     /* byte align */
831*abb65b4bSAndroid Build Coastguard Worker     oapv_bsr_align8(bs);
832*abb65b4bSAndroid Build Coastguard Worker 
833*abb65b4bSAndroid Build Coastguard Worker     if(fh->use_q_matrix == 0) {
834*abb65b4bSAndroid Build Coastguard Worker         int num_comp = get_num_comp(fh->fi.chroma_format_idc);
835*abb65b4bSAndroid Build Coastguard Worker         for(int cidx = 0; cidx < num_comp; cidx++) {
836*abb65b4bSAndroid Build Coastguard Worker             for(int y = 0; y < OAPV_BLK_H; y++) {
837*abb65b4bSAndroid Build Coastguard Worker                 for(int x = 0; x < OAPV_BLK_W; x++) {
838*abb65b4bSAndroid Build Coastguard Worker                     fh->q_matrix[cidx][y][x] = 16;
839*abb65b4bSAndroid Build Coastguard Worker                 }
840*abb65b4bSAndroid Build Coastguard Worker             }
841*abb65b4bSAndroid Build Coastguard Worker         }
842*abb65b4bSAndroid Build Coastguard Worker     }
843*abb65b4bSAndroid Build Coastguard Worker 
844*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
845*abb65b4bSAndroid Build Coastguard Worker }
846*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_tile_size(oapv_bs_t * bs,u32 * tile_size)847*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_tile_size(oapv_bs_t *bs, u32 *tile_size)
848*abb65b4bSAndroid Build Coastguard Worker {
849*abb65b4bSAndroid Build Coastguard Worker     u32 size = oapv_bsr_read(bs, 32);
850*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(tile_size, size);
851*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(size > 0 && size < 0xFFFFFFFF, OAPV_ERR_MALFORMED_BITSTREAM);
852*abb65b4bSAndroid Build Coastguard Worker     *tile_size = size + 1;
853*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
854*abb65b4bSAndroid Build Coastguard Worker }
855*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_tile_header(oapv_bs_t * bs,oapvd_ctx_t * ctx,oapv_th_t * th)856*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_tile_header(oapv_bs_t *bs, oapvd_ctx_t *ctx, oapv_th_t *th)
857*abb65b4bSAndroid Build Coastguard Worker {
858*abb65b4bSAndroid Build Coastguard Worker     th->tile_header_size = oapv_bsr_read(bs, 16);
859*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(th->tile_header_size, th->tile_header_size);
860*abb65b4bSAndroid Build Coastguard Worker     th->tile_index = oapv_bsr_read(bs, 16);
861*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(th->tile_index, th->tile_index);
862*abb65b4bSAndroid Build Coastguard Worker     for(int c = 0; c < ctx->num_comp; c++) {
863*abb65b4bSAndroid Build Coastguard Worker         th->tile_data_size[c] = oapv_bsr_read(bs, 32);
864*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(th->tile_data_size, th->tile_data_size[c]);
865*abb65b4bSAndroid Build Coastguard Worker         oapv_assert_rv(th->tile_data_size[c] > 0 && th->tile_data_size[c] < 0xFFFFFFFF, OAPV_ERR_MALFORMED_BITSTREAM);
866*abb65b4bSAndroid Build Coastguard Worker         th->tile_data_size[c] += 1;
867*abb65b4bSAndroid Build Coastguard Worker     }
868*abb65b4bSAndroid Build Coastguard Worker     for(int c = 0; c < ctx->num_comp; c++) {
869*abb65b4bSAndroid Build Coastguard Worker         th->tile_qp[c] = oapv_bsr_read(bs, 8);
870*abb65b4bSAndroid Build Coastguard Worker         DUMP_HLS(th->tile_qp, th->tile_qp[c]);
871*abb65b4bSAndroid Build Coastguard Worker     }
872*abb65b4bSAndroid Build Coastguard Worker     th->reserved_zero_8bits = oapv_bsr_read(bs, 8);
873*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(th->reserved_zero_8bits, th->reserved_zero_8bits);
874*abb65b4bSAndroid Build Coastguard Worker     /* byte align */
875*abb65b4bSAndroid Build Coastguard Worker     oapv_bsr_align8(bs);
876*abb65b4bSAndroid Build Coastguard Worker 
877*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_rv(th->reserved_zero_8bits == 0, OAPV_ERR_MALFORMED_BITSTREAM);
878*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
879*abb65b4bSAndroid Build Coastguard Worker }
880*abb65b4bSAndroid Build Coastguard Worker 
oapve_vlc_dc_coeff(oapve_ctx_t * ctx,oapve_core_t * core,oapv_bs_t * bs,int dc_diff,int c)881*abb65b4bSAndroid Build Coastguard Worker int oapve_vlc_dc_coeff(oapve_ctx_t *ctx, oapve_core_t *core, oapv_bs_t *bs, int dc_diff, int c)
882*abb65b4bSAndroid Build Coastguard Worker {
883*abb65b4bSAndroid Build Coastguard Worker     int rice_level = 0;
884*abb65b4bSAndroid Build Coastguard Worker     int abs_dc_diff = oapv_abs32(dc_diff);
885*abb65b4bSAndroid Build Coastguard Worker     int sign_dc_diff = (dc_diff > 0) ? 0 : 1;
886*abb65b4bSAndroid Build Coastguard Worker 
887*abb65b4bSAndroid Build Coastguard Worker     rice_level = oapv_clip3(OAPV_MIN_DC_LEVEL_CTX, OAPV_MAX_DC_LEVEL_CTX, core->prev_dc_ctx[c] >> 1);
888*abb65b4bSAndroid Build Coastguard Worker     enc_vlc_write(bs, abs_dc_diff, rice_level);
889*abb65b4bSAndroid Build Coastguard Worker 
890*abb65b4bSAndroid Build Coastguard Worker     if(abs_dc_diff)
891*abb65b4bSAndroid Build Coastguard Worker         oapv_bsw_write1(bs, sign_dc_diff);
892*abb65b4bSAndroid Build Coastguard Worker 
893*abb65b4bSAndroid Build Coastguard Worker     core->prev_dc_ctx[c] = abs_dc_diff;
894*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
895*abb65b4bSAndroid Build Coastguard Worker }
oapve_vlc_ac_coeff(oapve_ctx_t * ctx,oapve_core_t * core,oapv_bs_t * bs,s16 * coef,int num_sig,int ch_type)896*abb65b4bSAndroid Build Coastguard Worker void oapve_vlc_ac_coeff(oapve_ctx_t *ctx, oapve_core_t *core, oapv_bs_t *bs, s16 *coef, int num_sig, int ch_type)
897*abb65b4bSAndroid Build Coastguard Worker {
898*abb65b4bSAndroid Build Coastguard Worker     ALIGNED_16(s16 coef_temp[64]);
899*abb65b4bSAndroid Build Coastguard Worker     u32        num_coeff, scan_pos;
900*abb65b4bSAndroid Build Coastguard Worker     u32        sign, level, prev_level, run;
901*abb65b4bSAndroid Build Coastguard Worker     const u16 *scanp;
902*abb65b4bSAndroid Build Coastguard Worker     s16        coef_cur;
903*abb65b4bSAndroid Build Coastguard Worker 
904*abb65b4bSAndroid Build Coastguard Worker     scanp = oapv_tbl_scan;
905*abb65b4bSAndroid Build Coastguard Worker     num_coeff = OAPV_BLK_D;
906*abb65b4bSAndroid Build Coastguard Worker     run = 0;
907*abb65b4bSAndroid Build Coastguard Worker     int first_ac = 1;
908*abb65b4bSAndroid Build Coastguard Worker     prev_level = core->prev_1st_ac_ctx[ch_type];
909*abb65b4bSAndroid Build Coastguard Worker     int prev_run = 0;
910*abb65b4bSAndroid Build Coastguard Worker     int rice_run = 0;
911*abb65b4bSAndroid Build Coastguard Worker     int rice_level = 0;
912*abb65b4bSAndroid Build Coastguard Worker     int lb = bs->leftbits;
913*abb65b4bSAndroid Build Coastguard Worker     u32 code = bs->code;
914*abb65b4bSAndroid Build Coastguard Worker     u8 *cur = bs->cur;
915*abb65b4bSAndroid Build Coastguard Worker 
916*abb65b4bSAndroid Build Coastguard Worker     for(scan_pos = 1; scan_pos < num_coeff; scan_pos++) {
917*abb65b4bSAndroid Build Coastguard Worker         coef_temp[scan_pos] = coef[scanp[scan_pos]];
918*abb65b4bSAndroid Build Coastguard Worker     }
919*abb65b4bSAndroid Build Coastguard Worker 
920*abb65b4bSAndroid Build Coastguard Worker     const s32 simple_vlc_table[3][2] = { {
921*abb65b4bSAndroid Build Coastguard Worker                                              1,
922*abb65b4bSAndroid Build Coastguard Worker                                          },
923*abb65b4bSAndroid Build Coastguard Worker                                          { 0, 0 },
924*abb65b4bSAndroid Build Coastguard Worker                                          { 0, 1 } };
925*abb65b4bSAndroid Build Coastguard Worker     for(scan_pos = 1; scan_pos < num_coeff - 1; scan_pos++) {
926*abb65b4bSAndroid Build Coastguard Worker         coef_cur = coef_temp[scan_pos];
927*abb65b4bSAndroid Build Coastguard Worker         if(coef_cur) {
928*abb65b4bSAndroid Build Coastguard Worker             level = oapv_abs16(coef_cur);
929*abb65b4bSAndroid Build Coastguard Worker             sign = (coef_cur > 0) ? 0 : 1;
930*abb65b4bSAndroid Build Coastguard Worker             rice_run = prev_run >> 2;
931*abb65b4bSAndroid Build Coastguard Worker             if(rice_run > 2)
932*abb65b4bSAndroid Build Coastguard Worker                 rice_run = 2;
933*abb65b4bSAndroid Build Coastguard Worker             if(run == 0 && rice_run == 0) {
934*abb65b4bSAndroid Build Coastguard Worker                 lb--; // bs->leftbits--;
935*abb65b4bSAndroid Build Coastguard Worker                 code |= (1 << lb);
936*abb65b4bSAndroid Build Coastguard Worker                 if(lb == 0) {
937*abb65b4bSAndroid Build Coastguard Worker                     OAPV_FLUSH_SWAP(cur, code, lb);
938*abb65b4bSAndroid Build Coastguard Worker                 }
939*abb65b4bSAndroid Build Coastguard Worker             }
940*abb65b4bSAndroid Build Coastguard Worker             else {
941*abb65b4bSAndroid Build Coastguard Worker                 int leftbits;
942*abb65b4bSAndroid Build Coastguard Worker                 leftbits = lb;
943*abb65b4bSAndroid Build Coastguard Worker                 u32 code_from_lut = CODE_LUT_100[run][rice_run][0];
944*abb65b4bSAndroid Build Coastguard Worker                 int len_from_lut = CODE_LUT_100[run][rice_run][1];
945*abb65b4bSAndroid Build Coastguard Worker                 code |= (code_from_lut >> (32 - leftbits));
946*abb65b4bSAndroid Build Coastguard Worker                 if(len_from_lut < leftbits) {
947*abb65b4bSAndroid Build Coastguard Worker                     lb -= len_from_lut;
948*abb65b4bSAndroid Build Coastguard Worker                 }
949*abb65b4bSAndroid Build Coastguard Worker                 else {
950*abb65b4bSAndroid Build Coastguard Worker                     lb = 0;
951*abb65b4bSAndroid Build Coastguard Worker                     OAPV_FLUSH_SWAP(cur, code, lb);
952*abb65b4bSAndroid Build Coastguard Worker                     code = (leftbits < 32 ? code_from_lut << leftbits : 0);
953*abb65b4bSAndroid Build Coastguard Worker                     lb = 32 - (len_from_lut - leftbits);
954*abb65b4bSAndroid Build Coastguard Worker                 }
955*abb65b4bSAndroid Build Coastguard Worker             }
956*abb65b4bSAndroid Build Coastguard Worker             rice_level = prev_level >> 2;
957*abb65b4bSAndroid Build Coastguard Worker             if(rice_level > 4)
958*abb65b4bSAndroid Build Coastguard Worker                 rice_level = OAPV_MAX_AC_LEVEL_CTX;
959*abb65b4bSAndroid Build Coastguard Worker             if(level - 1 == 0 && rice_level == 0) {
960*abb65b4bSAndroid Build Coastguard Worker                 lb--;
961*abb65b4bSAndroid Build Coastguard Worker                 code |= (1 << lb);
962*abb65b4bSAndroid Build Coastguard Worker                 if(lb == 0) {
963*abb65b4bSAndroid Build Coastguard Worker                     OAPV_FLUSH_SWAP(cur, code, lb);
964*abb65b4bSAndroid Build Coastguard Worker                 }
965*abb65b4bSAndroid Build Coastguard Worker             }
966*abb65b4bSAndroid Build Coastguard Worker             else {
967*abb65b4bSAndroid Build Coastguard Worker                 if(level - 1 > 98) {
968*abb65b4bSAndroid Build Coastguard Worker                     {
969*abb65b4bSAndroid Build Coastguard Worker                         int k = rice_level;
970*abb65b4bSAndroid Build Coastguard Worker                         u32 symbol = level - 1;
971*abb65b4bSAndroid Build Coastguard Worker                         u32 simple_vlc_val = oapv_clip3(0, 2, symbol >> k);
972*abb65b4bSAndroid Build Coastguard Worker                         int bit_cnt = 0;
973*abb65b4bSAndroid Build Coastguard Worker                         if(symbol >= (u32)(1 << k)) {
974*abb65b4bSAndroid Build Coastguard Worker                             symbol -= (1 << k);
975*abb65b4bSAndroid Build Coastguard Worker                             int val = simple_vlc_table[simple_vlc_val][bit_cnt];
976*abb65b4bSAndroid Build Coastguard Worker                             lb--;
977*abb65b4bSAndroid Build Coastguard Worker                             code |= ((val & 0x1) << lb);
978*abb65b4bSAndroid Build Coastguard Worker                             if(lb == 0) {
979*abb65b4bSAndroid Build Coastguard Worker                                 OAPV_FLUSH_SWAP(cur, code, lb);
980*abb65b4bSAndroid Build Coastguard Worker                             }
981*abb65b4bSAndroid Build Coastguard Worker                             bit_cnt++;
982*abb65b4bSAndroid Build Coastguard Worker                         }
983*abb65b4bSAndroid Build Coastguard Worker                         if(symbol >= (u32)(1 << k) && simple_vlc_val > 0) {
984*abb65b4bSAndroid Build Coastguard Worker                             symbol -= (1 << k);
985*abb65b4bSAndroid Build Coastguard Worker                             int val = simple_vlc_table[simple_vlc_val][bit_cnt];
986*abb65b4bSAndroid Build Coastguard Worker                             lb--;
987*abb65b4bSAndroid Build Coastguard Worker                             code |= ((val & 0x1) << lb);
988*abb65b4bSAndroid Build Coastguard Worker                             if(lb == 0) {
989*abb65b4bSAndroid Build Coastguard Worker                                 OAPV_FLUSH_SWAP(cur, code, lb);
990*abb65b4bSAndroid Build Coastguard Worker                             }
991*abb65b4bSAndroid Build Coastguard Worker                             bit_cnt++;
992*abb65b4bSAndroid Build Coastguard Worker                         }
993*abb65b4bSAndroid Build Coastguard Worker                         while(symbol >= (u32)(1 << k)) {
994*abb65b4bSAndroid Build Coastguard Worker                             symbol -= (1 << k);
995*abb65b4bSAndroid Build Coastguard Worker                             lb--;
996*abb65b4bSAndroid Build Coastguard Worker                             if(lb == 0) {
997*abb65b4bSAndroid Build Coastguard Worker                                 OAPV_FLUSH_SWAP(cur, code, lb);
998*abb65b4bSAndroid Build Coastguard Worker                             }
999*abb65b4bSAndroid Build Coastguard Worker                             if(bit_cnt >= 2) {
1000*abb65b4bSAndroid Build Coastguard Worker                                 k++;
1001*abb65b4bSAndroid Build Coastguard Worker                             }
1002*abb65b4bSAndroid Build Coastguard Worker                             bit_cnt++;
1003*abb65b4bSAndroid Build Coastguard Worker                         }
1004*abb65b4bSAndroid Build Coastguard Worker                         if(bit_cnt < 2) {
1005*abb65b4bSAndroid Build Coastguard Worker                             int val = simple_vlc_table[simple_vlc_val][bit_cnt];
1006*abb65b4bSAndroid Build Coastguard Worker                             lb--;
1007*abb65b4bSAndroid Build Coastguard Worker                             code |= ((val & 0x1) << lb);
1008*abb65b4bSAndroid Build Coastguard Worker                             if(lb == 0) {
1009*abb65b4bSAndroid Build Coastguard Worker                                 OAPV_FLUSH_SWAP(cur, code, lb);
1010*abb65b4bSAndroid Build Coastguard Worker                             }
1011*abb65b4bSAndroid Build Coastguard Worker                         }
1012*abb65b4bSAndroid Build Coastguard Worker                         else {
1013*abb65b4bSAndroid Build Coastguard Worker                             lb--;
1014*abb65b4bSAndroid Build Coastguard Worker                             code |= ((1 & 0x1) << lb);
1015*abb65b4bSAndroid Build Coastguard Worker                             if(lb == 0) {
1016*abb65b4bSAndroid Build Coastguard Worker                                 OAPV_FLUSH_SWAP(cur, code, lb);
1017*abb65b4bSAndroid Build Coastguard Worker                             }
1018*abb65b4bSAndroid Build Coastguard Worker                         }
1019*abb65b4bSAndroid Build Coastguard Worker                         if(k > 0) {
1020*abb65b4bSAndroid Build Coastguard Worker                             int leftbits;
1021*abb65b4bSAndroid Build Coastguard Worker                             leftbits = lb;
1022*abb65b4bSAndroid Build Coastguard Worker                             symbol <<= (32 - k);
1023*abb65b4bSAndroid Build Coastguard Worker                             code |= (symbol >> (32 - leftbits));
1024*abb65b4bSAndroid Build Coastguard Worker                             if(k < leftbits) {
1025*abb65b4bSAndroid Build Coastguard Worker                                 lb -= k;
1026*abb65b4bSAndroid Build Coastguard Worker                             }
1027*abb65b4bSAndroid Build Coastguard Worker                             else {
1028*abb65b4bSAndroid Build Coastguard Worker                                 lb = 0;
1029*abb65b4bSAndroid Build Coastguard Worker                                 OAPV_FLUSH_SWAP(cur, code, lb);
1030*abb65b4bSAndroid Build Coastguard Worker                                 code = (leftbits < 32 ? symbol << leftbits : 0);
1031*abb65b4bSAndroid Build Coastguard Worker                                 lb = 32 - (k - leftbits);
1032*abb65b4bSAndroid Build Coastguard Worker                             }
1033*abb65b4bSAndroid Build Coastguard Worker                         }
1034*abb65b4bSAndroid Build Coastguard Worker                     }
1035*abb65b4bSAndroid Build Coastguard Worker                 }
1036*abb65b4bSAndroid Build Coastguard Worker                 else {
1037*abb65b4bSAndroid Build Coastguard Worker                     int leftbits;
1038*abb65b4bSAndroid Build Coastguard Worker                     leftbits = lb;
1039*abb65b4bSAndroid Build Coastguard Worker                     u32 code_from_lut = CODE_LUT_100[level - 1][rice_level][0];
1040*abb65b4bSAndroid Build Coastguard Worker                     int len_from_lut = CODE_LUT_100[level - 1][rice_level][1];
1041*abb65b4bSAndroid Build Coastguard Worker                     code |= (code_from_lut >> (32 - leftbits));
1042*abb65b4bSAndroid Build Coastguard Worker                     if(len_from_lut < leftbits) {
1043*abb65b4bSAndroid Build Coastguard Worker                         lb -= len_from_lut;
1044*abb65b4bSAndroid Build Coastguard Worker                     }
1045*abb65b4bSAndroid Build Coastguard Worker                     else {
1046*abb65b4bSAndroid Build Coastguard Worker                         lb = 0;
1047*abb65b4bSAndroid Build Coastguard Worker                         OAPV_FLUSH_SWAP(cur, code, lb);
1048*abb65b4bSAndroid Build Coastguard Worker                         code = (leftbits < 32 ? code_from_lut << leftbits : 0);
1049*abb65b4bSAndroid Build Coastguard Worker                         lb = 32 - (len_from_lut - leftbits);
1050*abb65b4bSAndroid Build Coastguard Worker                     }
1051*abb65b4bSAndroid Build Coastguard Worker                 }
1052*abb65b4bSAndroid Build Coastguard Worker             }
1053*abb65b4bSAndroid Build Coastguard Worker             {
1054*abb65b4bSAndroid Build Coastguard Worker                 lb--;
1055*abb65b4bSAndroid Build Coastguard Worker                 code |= ((sign & 0x1) << lb);
1056*abb65b4bSAndroid Build Coastguard Worker                 if(lb == 0) {
1057*abb65b4bSAndroid Build Coastguard Worker                     OAPV_FLUSH_SWAP(cur, code, lb);
1058*abb65b4bSAndroid Build Coastguard Worker                 }
1059*abb65b4bSAndroid Build Coastguard Worker             }
1060*abb65b4bSAndroid Build Coastguard Worker             if(first_ac) {
1061*abb65b4bSAndroid Build Coastguard Worker                 first_ac = 0;
1062*abb65b4bSAndroid Build Coastguard Worker                 core->prev_1st_ac_ctx[ch_type] = level;
1063*abb65b4bSAndroid Build Coastguard Worker             }
1064*abb65b4bSAndroid Build Coastguard Worker             prev_run = run;
1065*abb65b4bSAndroid Build Coastguard Worker             run = 0;
1066*abb65b4bSAndroid Build Coastguard Worker             prev_level = level;
1067*abb65b4bSAndroid Build Coastguard Worker         }
1068*abb65b4bSAndroid Build Coastguard Worker         else {
1069*abb65b4bSAndroid Build Coastguard Worker             run++;
1070*abb65b4bSAndroid Build Coastguard Worker         }
1071*abb65b4bSAndroid Build Coastguard Worker     }
1072*abb65b4bSAndroid Build Coastguard Worker     bs->cur = cur;
1073*abb65b4bSAndroid Build Coastguard Worker     bs->code = code;
1074*abb65b4bSAndroid Build Coastguard Worker     bs->leftbits = lb;
1075*abb65b4bSAndroid Build Coastguard Worker     coef_cur = coef_temp[scan_pos];
1076*abb65b4bSAndroid Build Coastguard Worker     if(coef_cur) {
1077*abb65b4bSAndroid Build Coastguard Worker         level = oapv_abs16(coef_cur);
1078*abb65b4bSAndroid Build Coastguard Worker         sign = (coef_cur > 0) ? 0 : 1;
1079*abb65b4bSAndroid Build Coastguard Worker         /* Run coding */
1080*abb65b4bSAndroid Build Coastguard Worker         rice_run = prev_run >> 2;
1081*abb65b4bSAndroid Build Coastguard Worker         if(rice_run > 2)
1082*abb65b4bSAndroid Build Coastguard Worker             rice_run = 2;
1083*abb65b4bSAndroid Build Coastguard Worker         if(run == 0 && rice_run == 0) {
1084*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits--;
1085*abb65b4bSAndroid Build Coastguard Worker             bs->code |= (1 << bs->leftbits);
1086*abb65b4bSAndroid Build Coastguard Worker             if(bs->leftbits == 0) {
1087*abb65b4bSAndroid Build Coastguard Worker                 OAPV_FLUSH(bs);
1088*abb65b4bSAndroid Build Coastguard Worker             }
1089*abb65b4bSAndroid Build Coastguard Worker         }
1090*abb65b4bSAndroid Build Coastguard Worker         else {
1091*abb65b4bSAndroid Build Coastguard Worker             int leftbits;
1092*abb65b4bSAndroid Build Coastguard Worker             leftbits = bs->leftbits;
1093*abb65b4bSAndroid Build Coastguard Worker             u32 code_from_lut = CODE_LUT_100[run][rice_run][0];
1094*abb65b4bSAndroid Build Coastguard Worker             int len_from_lut = CODE_LUT_100[run][rice_run][1];
1095*abb65b4bSAndroid Build Coastguard Worker             bs->code |= (code_from_lut >> (32 - leftbits));
1096*abb65b4bSAndroid Build Coastguard Worker             if(len_from_lut < leftbits) {
1097*abb65b4bSAndroid Build Coastguard Worker                 bs->leftbits -= len_from_lut;
1098*abb65b4bSAndroid Build Coastguard Worker             }
1099*abb65b4bSAndroid Build Coastguard Worker             else {
1100*abb65b4bSAndroid Build Coastguard Worker                 bs->leftbits = 0;
1101*abb65b4bSAndroid Build Coastguard Worker                 OAPV_FLUSH(bs);
1102*abb65b4bSAndroid Build Coastguard Worker                 bs->code = (leftbits < 32 ? code_from_lut << leftbits : 0);
1103*abb65b4bSAndroid Build Coastguard Worker                 bs->leftbits = 32 - (len_from_lut - leftbits);
1104*abb65b4bSAndroid Build Coastguard Worker             }
1105*abb65b4bSAndroid Build Coastguard Worker         }
1106*abb65b4bSAndroid Build Coastguard Worker         /* Level coding */
1107*abb65b4bSAndroid Build Coastguard Worker         rice_level = prev_level >> 2;
1108*abb65b4bSAndroid Build Coastguard Worker         if(rice_level > 4)
1109*abb65b4bSAndroid Build Coastguard Worker             rice_level = OAPV_MAX_AC_LEVEL_CTX;
1110*abb65b4bSAndroid Build Coastguard Worker         if(level - 1 == 0 && rice_level == 0) {
1111*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits--;
1112*abb65b4bSAndroid Build Coastguard Worker             bs->code |= (1 << bs->leftbits);
1113*abb65b4bSAndroid Build Coastguard Worker             if(bs->leftbits == 0) {
1114*abb65b4bSAndroid Build Coastguard Worker                 OAPV_FLUSH(bs);
1115*abb65b4bSAndroid Build Coastguard Worker             }
1116*abb65b4bSAndroid Build Coastguard Worker         }
1117*abb65b4bSAndroid Build Coastguard Worker         else {
1118*abb65b4bSAndroid Build Coastguard Worker             if(level - 1 > 98) {
1119*abb65b4bSAndroid Build Coastguard Worker                 enc_vlc_write(bs, level - 1, rice_level);
1120*abb65b4bSAndroid Build Coastguard Worker             }
1121*abb65b4bSAndroid Build Coastguard Worker             else {
1122*abb65b4bSAndroid Build Coastguard Worker                 int leftbits;
1123*abb65b4bSAndroid Build Coastguard Worker                 leftbits = bs->leftbits;
1124*abb65b4bSAndroid Build Coastguard Worker                 u32 code_from_lut = CODE_LUT_100[level - 1][rice_level][0];
1125*abb65b4bSAndroid Build Coastguard Worker                 int len_from_lut = CODE_LUT_100[level - 1][rice_level][1];
1126*abb65b4bSAndroid Build Coastguard Worker                 bs->code |= (code_from_lut >> (32 - leftbits));
1127*abb65b4bSAndroid Build Coastguard Worker                 if(len_from_lut < leftbits) {
1128*abb65b4bSAndroid Build Coastguard Worker                     bs->leftbits -= len_from_lut;
1129*abb65b4bSAndroid Build Coastguard Worker                 }
1130*abb65b4bSAndroid Build Coastguard Worker                 else {
1131*abb65b4bSAndroid Build Coastguard Worker                     bs->leftbits = 0;
1132*abb65b4bSAndroid Build Coastguard Worker                     OAPV_FLUSH(bs);
1133*abb65b4bSAndroid Build Coastguard Worker                     bs->code = (leftbits < 32 ? code_from_lut << leftbits : 0);
1134*abb65b4bSAndroid Build Coastguard Worker                     bs->leftbits = 32 - (len_from_lut - leftbits);
1135*abb65b4bSAndroid Build Coastguard Worker                 }
1136*abb65b4bSAndroid Build Coastguard Worker             }
1137*abb65b4bSAndroid Build Coastguard Worker         }
1138*abb65b4bSAndroid Build Coastguard Worker         /* Sign coding */
1139*abb65b4bSAndroid Build Coastguard Worker         {
1140*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits--;
1141*abb65b4bSAndroid Build Coastguard Worker             bs->code |= ((sign & 0x1) << bs->leftbits);
1142*abb65b4bSAndroid Build Coastguard Worker             if(bs->leftbits == 0) {
1143*abb65b4bSAndroid Build Coastguard Worker                 OAPV_FLUSH(bs);
1144*abb65b4bSAndroid Build Coastguard Worker             }
1145*abb65b4bSAndroid Build Coastguard Worker         }
1146*abb65b4bSAndroid Build Coastguard Worker         if(first_ac) {
1147*abb65b4bSAndroid Build Coastguard Worker             first_ac = 0;
1148*abb65b4bSAndroid Build Coastguard Worker             core->prev_1st_ac_ctx[ch_type] = level;
1149*abb65b4bSAndroid Build Coastguard Worker         }
1150*abb65b4bSAndroid Build Coastguard Worker     }
1151*abb65b4bSAndroid Build Coastguard Worker     else {
1152*abb65b4bSAndroid Build Coastguard Worker         run++;
1153*abb65b4bSAndroid Build Coastguard Worker     }
1154*abb65b4bSAndroid Build Coastguard Worker     if(coef_temp[num_coeff - 1] == 0) {
1155*abb65b4bSAndroid Build Coastguard Worker         int rice_run = 0;
1156*abb65b4bSAndroid Build Coastguard Worker         rice_run = prev_run >> 2;
1157*abb65b4bSAndroid Build Coastguard Worker         if(rice_run > 2)
1158*abb65b4bSAndroid Build Coastguard Worker             rice_run = 2;
1159*abb65b4bSAndroid Build Coastguard Worker 
1160*abb65b4bSAndroid Build Coastguard Worker         if(run == 0 && rice_run == 0) {
1161*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits--;
1162*abb65b4bSAndroid Build Coastguard Worker             bs->code |= (1 << bs->leftbits);
1163*abb65b4bSAndroid Build Coastguard Worker             if(bs->leftbits == 0) {
1164*abb65b4bSAndroid Build Coastguard Worker                 OAPV_FLUSH(bs);
1165*abb65b4bSAndroid Build Coastguard Worker             }
1166*abb65b4bSAndroid Build Coastguard Worker         }
1167*abb65b4bSAndroid Build Coastguard Worker         else {
1168*abb65b4bSAndroid Build Coastguard Worker             int leftbits;
1169*abb65b4bSAndroid Build Coastguard Worker             leftbits = bs->leftbits;
1170*abb65b4bSAndroid Build Coastguard Worker             u32 code_from_lut = CODE_LUT_100[run][rice_run][0];
1171*abb65b4bSAndroid Build Coastguard Worker             int len_from_lut = CODE_LUT_100[run][rice_run][1];
1172*abb65b4bSAndroid Build Coastguard Worker             bs->code |= (code_from_lut >> (32 - leftbits));
1173*abb65b4bSAndroid Build Coastguard Worker             if(len_from_lut < leftbits) {
1174*abb65b4bSAndroid Build Coastguard Worker                 bs->leftbits -= len_from_lut;
1175*abb65b4bSAndroid Build Coastguard Worker             }
1176*abb65b4bSAndroid Build Coastguard Worker             else {
1177*abb65b4bSAndroid Build Coastguard Worker                 bs->leftbits = 0;
1178*abb65b4bSAndroid Build Coastguard Worker                 OAPV_FLUSH(bs);
1179*abb65b4bSAndroid Build Coastguard Worker                 bs->code = (leftbits < 32 ? code_from_lut << leftbits : 0);
1180*abb65b4bSAndroid Build Coastguard Worker                 bs->leftbits = 32 - (len_from_lut - leftbits);
1181*abb65b4bSAndroid Build Coastguard Worker             }
1182*abb65b4bSAndroid Build Coastguard Worker         }
1183*abb65b4bSAndroid Build Coastguard Worker     }
1184*abb65b4bSAndroid Build Coastguard Worker }
1185*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_dc_coeff(oapvd_ctx_t * ctx,oapvd_core_t * core,oapv_bs_t * bs,s16 * dc_diff,int c)1186*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_dc_coeff(oapvd_ctx_t *ctx, oapvd_core_t *core, oapv_bs_t *bs, s16 *dc_diff, int c)
1187*abb65b4bSAndroid Build Coastguard Worker {
1188*abb65b4bSAndroid Build Coastguard Worker     int rice_level = 0;
1189*abb65b4bSAndroid Build Coastguard Worker     int abs_dc_diff;
1190*abb65b4bSAndroid Build Coastguard Worker     int sign_dc_diff = 0;
1191*abb65b4bSAndroid Build Coastguard Worker 
1192*abb65b4bSAndroid Build Coastguard Worker     rice_level = oapv_clip3(OAPV_MIN_DC_LEVEL_CTX, OAPV_MAX_DC_LEVEL_CTX, core->prev_dc_ctx[c] >> 1);
1193*abb65b4bSAndroid Build Coastguard Worker     abs_dc_diff = dec_vlc_read(bs, rice_level);
1194*abb65b4bSAndroid Build Coastguard Worker     if(abs_dc_diff)
1195*abb65b4bSAndroid Build Coastguard Worker         sign_dc_diff = oapv_bsr_read1(bs);
1196*abb65b4bSAndroid Build Coastguard Worker 
1197*abb65b4bSAndroid Build Coastguard Worker     *dc_diff = sign_dc_diff ? -abs_dc_diff : abs_dc_diff;
1198*abb65b4bSAndroid Build Coastguard Worker     core->prev_dc_ctx[c] = abs_dc_diff;
1199*abb65b4bSAndroid Build Coastguard Worker 
1200*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
1201*abb65b4bSAndroid Build Coastguard Worker }
1202*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_ac_coeff(oapvd_ctx_t * ctx,oapvd_core_t * core,oapv_bs_t * bs,s16 * coef,int c)1203*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_ac_coeff(oapvd_ctx_t *ctx, oapvd_core_t *core, oapv_bs_t *bs, s16 *coef, int c)
1204*abb65b4bSAndroid Build Coastguard Worker {
1205*abb65b4bSAndroid Build Coastguard Worker     int        sign, level, prev_level, run;
1206*abb65b4bSAndroid Build Coastguard Worker     int        scan_pos_offset, num_coeff, i, coef_cnt = 0;
1207*abb65b4bSAndroid Build Coastguard Worker     const u16 *scanp;
1208*abb65b4bSAndroid Build Coastguard Worker 
1209*abb65b4bSAndroid Build Coastguard Worker     scanp = oapv_tbl_scan;
1210*abb65b4bSAndroid Build Coastguard Worker     num_coeff = OAPV_BLK_D;
1211*abb65b4bSAndroid Build Coastguard Worker     scan_pos_offset = 1;
1212*abb65b4bSAndroid Build Coastguard Worker     run = 0;
1213*abb65b4bSAndroid Build Coastguard Worker 
1214*abb65b4bSAndroid Build Coastguard Worker     int first_ac = 1;
1215*abb65b4bSAndroid Build Coastguard Worker     prev_level = core->prev_1st_ac_ctx[c];
1216*abb65b4bSAndroid Build Coastguard Worker     int prev_run = 0;
1217*abb65b4bSAndroid Build Coastguard Worker 
1218*abb65b4bSAndroid Build Coastguard Worker     do {
1219*abb65b4bSAndroid Build Coastguard Worker         int rice_run = 0;
1220*abb65b4bSAndroid Build Coastguard Worker         rice_run = prev_run / 4;
1221*abb65b4bSAndroid Build Coastguard Worker         if(rice_run > 2)
1222*abb65b4bSAndroid Build Coastguard Worker             rice_run = 2;
1223*abb65b4bSAndroid Build Coastguard Worker         if(rice_run == 0) {
1224*abb65b4bSAndroid Build Coastguard Worker             if(bs->leftbits == 0) {
1225*abb65b4bSAndroid Build Coastguard Worker                 OAPV_READ_FLUSH(bs, 4);
1226*abb65b4bSAndroid Build Coastguard Worker             }
1227*abb65b4bSAndroid Build Coastguard Worker             u32 t0 = (u32)(bs->code >> 31);
1228*abb65b4bSAndroid Build Coastguard Worker             bs->code <<= 1;
1229*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits -= 1;
1230*abb65b4bSAndroid Build Coastguard Worker             if(t0)
1231*abb65b4bSAndroid Build Coastguard Worker                 run = 0;
1232*abb65b4bSAndroid Build Coastguard Worker             else
1233*abb65b4bSAndroid Build Coastguard Worker                 run = dec_vlc_read_1bit_read(bs, rice_run);
1234*abb65b4bSAndroid Build Coastguard Worker         }
1235*abb65b4bSAndroid Build Coastguard Worker         else {
1236*abb65b4bSAndroid Build Coastguard Worker             run = dec_vlc_read(bs, rice_run);
1237*abb65b4bSAndroid Build Coastguard Worker         }
1238*abb65b4bSAndroid Build Coastguard Worker 
1239*abb65b4bSAndroid Build Coastguard Worker         oapv_assert_rv((scan_pos_offset + run) <= 64, OAPV_ERR_MALFORMED_BITSTREAM);
1240*abb65b4bSAndroid Build Coastguard Worker         for (i = scan_pos_offset; i < scan_pos_offset + run; i++){
1241*abb65b4bSAndroid Build Coastguard Worker             coef[scanp[i]] = 0;
1242*abb65b4bSAndroid Build Coastguard Worker         }
1243*abb65b4bSAndroid Build Coastguard Worker 
1244*abb65b4bSAndroid Build Coastguard Worker         if(scan_pos_offset + run == num_coeff) {
1245*abb65b4bSAndroid Build Coastguard Worker             break;
1246*abb65b4bSAndroid Build Coastguard Worker         }
1247*abb65b4bSAndroid Build Coastguard Worker 
1248*abb65b4bSAndroid Build Coastguard Worker         scan_pos_offset += run;
1249*abb65b4bSAndroid Build Coastguard Worker 
1250*abb65b4bSAndroid Build Coastguard Worker         /* Level parsing */
1251*abb65b4bSAndroid Build Coastguard Worker         int rice_level = 0;
1252*abb65b4bSAndroid Build Coastguard Worker         if(scan_pos_offset == 0) {
1253*abb65b4bSAndroid Build Coastguard Worker             rice_level = oapv_clip3(OAPV_MIN_DC_LEVEL_CTX, OAPV_MAX_DC_LEVEL_CTX, core->prev_dc_ctx[c] >> 1);
1254*abb65b4bSAndroid Build Coastguard Worker         }
1255*abb65b4bSAndroid Build Coastguard Worker         else {
1256*abb65b4bSAndroid Build Coastguard Worker             rice_level = oapv_clip3(OAPV_MIN_AC_LEVEL_CTX, OAPV_MAX_AC_LEVEL_CTX, prev_level >> 2);
1257*abb65b4bSAndroid Build Coastguard Worker         }
1258*abb65b4bSAndroid Build Coastguard Worker         if(rice_level == 0) {
1259*abb65b4bSAndroid Build Coastguard Worker             if(bs->leftbits == 0) {
1260*abb65b4bSAndroid Build Coastguard Worker                 OAPV_READ_FLUSH(bs, 4);
1261*abb65b4bSAndroid Build Coastguard Worker             }
1262*abb65b4bSAndroid Build Coastguard Worker             u32 t0 = (u32)(bs->code >> 31);
1263*abb65b4bSAndroid Build Coastguard Worker             bs->code <<= 1;
1264*abb65b4bSAndroid Build Coastguard Worker             bs->leftbits -= 1;
1265*abb65b4bSAndroid Build Coastguard Worker             if(t0)
1266*abb65b4bSAndroid Build Coastguard Worker                 level = 0;
1267*abb65b4bSAndroid Build Coastguard Worker             else
1268*abb65b4bSAndroid Build Coastguard Worker                 level = dec_vlc_read_1bit_read(bs, rice_level);
1269*abb65b4bSAndroid Build Coastguard Worker         }
1270*abb65b4bSAndroid Build Coastguard Worker         else {
1271*abb65b4bSAndroid Build Coastguard Worker             level = dec_vlc_read(bs, rice_level);
1272*abb65b4bSAndroid Build Coastguard Worker         }
1273*abb65b4bSAndroid Build Coastguard Worker         level++;
1274*abb65b4bSAndroid Build Coastguard Worker 
1275*abb65b4bSAndroid Build Coastguard Worker         if(scan_pos_offset != 0) {
1276*abb65b4bSAndroid Build Coastguard Worker             prev_level = level;
1277*abb65b4bSAndroid Build Coastguard Worker         }
1278*abb65b4bSAndroid Build Coastguard Worker         prev_run = run;
1279*abb65b4bSAndroid Build Coastguard Worker 
1280*abb65b4bSAndroid Build Coastguard Worker         if(scan_pos_offset == 0) {
1281*abb65b4bSAndroid Build Coastguard Worker             core->prev_dc_ctx[c] = level;
1282*abb65b4bSAndroid Build Coastguard Worker         }
1283*abb65b4bSAndroid Build Coastguard Worker         else if(first_ac) {
1284*abb65b4bSAndroid Build Coastguard Worker             first_ac = 0;
1285*abb65b4bSAndroid Build Coastguard Worker             core->prev_1st_ac_ctx[c] = level;
1286*abb65b4bSAndroid Build Coastguard Worker         }
1287*abb65b4bSAndroid Build Coastguard Worker 
1288*abb65b4bSAndroid Build Coastguard Worker         /* Sign parsing */
1289*abb65b4bSAndroid Build Coastguard Worker         if(bs->leftbits == 0) {
1290*abb65b4bSAndroid Build Coastguard Worker             OAPV_READ_FLUSH(bs, 4);
1291*abb65b4bSAndroid Build Coastguard Worker         }
1292*abb65b4bSAndroid Build Coastguard Worker         sign = (u32)(bs->code >> 31);
1293*abb65b4bSAndroid Build Coastguard Worker         bs->code <<= 1;
1294*abb65b4bSAndroid Build Coastguard Worker         bs->leftbits -= 1;
1295*abb65b4bSAndroid Build Coastguard Worker         coef[scanp[scan_pos_offset]] = sign ? -(s16)level : (s16)level;
1296*abb65b4bSAndroid Build Coastguard Worker 
1297*abb65b4bSAndroid Build Coastguard Worker         coef_cnt++;
1298*abb65b4bSAndroid Build Coastguard Worker 
1299*abb65b4bSAndroid Build Coastguard Worker         if(scan_pos_offset >= num_coeff - 1) {
1300*abb65b4bSAndroid Build Coastguard Worker             break;
1301*abb65b4bSAndroid Build Coastguard Worker         }
1302*abb65b4bSAndroid Build Coastguard Worker         scan_pos_offset++;
1303*abb65b4bSAndroid Build Coastguard Worker     } while(1);
1304*abb65b4bSAndroid Build Coastguard Worker 
1305*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
1306*abb65b4bSAndroid Build Coastguard Worker }
1307*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_tile_dummy_data(oapv_bs_t * bs)1308*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_tile_dummy_data(oapv_bs_t *bs)
1309*abb65b4bSAndroid Build Coastguard Worker {
1310*abb65b4bSAndroid Build Coastguard Worker     while(bs->cur <= bs->end) {
1311*abb65b4bSAndroid Build Coastguard Worker         oapv_bsr_read(bs, 8);
1312*abb65b4bSAndroid Build Coastguard Worker     }
1313*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
1314*abb65b4bSAndroid Build Coastguard Worker }
1315*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_metadata(oapv_bs_t * bs,u32 pbu_size,oapvm_t mid,int group_id)1316*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_metadata(oapv_bs_t *bs, u32 pbu_size, oapvm_t mid, int group_id)
1317*abb65b4bSAndroid Build Coastguard Worker {
1318*abb65b4bSAndroid Build Coastguard Worker     int ret;
1319*abb65b4bSAndroid Build Coastguard Worker     u32 t0;
1320*abb65b4bSAndroid Build Coastguard Worker     u32 metadata_size;
1321*abb65b4bSAndroid Build Coastguard Worker     metadata_size = oapv_bsr_read(bs, 32);
1322*abb65b4bSAndroid Build Coastguard Worker     DUMP_HLS(metadata_size, metadata_size);
1323*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_gv(metadata_size <= (pbu_size - 8), ret, OAPV_ERR_MALFORMED_BITSTREAM, ERR);
1324*abb65b4bSAndroid Build Coastguard Worker     u8 *bs_start_pos = bs->cur;
1325*abb65b4bSAndroid Build Coastguard Worker     u8 *payload_data = NULL;
1326*abb65b4bSAndroid Build Coastguard Worker 
1327*abb65b4bSAndroid Build Coastguard Worker     while(metadata_size > 0) {
1328*abb65b4bSAndroid Build Coastguard Worker         u32 payload_type = 0, payload_size = 0;
1329*abb65b4bSAndroid Build Coastguard Worker         t0 = 0;
1330*abb65b4bSAndroid Build Coastguard Worker         do {
1331*abb65b4bSAndroid Build Coastguard Worker             t0 = oapv_bsr_read(bs, 8);
1332*abb65b4bSAndroid Build Coastguard Worker             DUMP_HLS(payload_type, t0);
1333*abb65b4bSAndroid Build Coastguard Worker             metadata_size -= 1;
1334*abb65b4bSAndroid Build Coastguard Worker             if(t0 == 0xFF) {
1335*abb65b4bSAndroid Build Coastguard Worker                 payload_type += 255;
1336*abb65b4bSAndroid Build Coastguard Worker             }
1337*abb65b4bSAndroid Build Coastguard Worker         } while(t0 == 0xFF);
1338*abb65b4bSAndroid Build Coastguard Worker         payload_type += t0;
1339*abb65b4bSAndroid Build Coastguard Worker 
1340*abb65b4bSAndroid Build Coastguard Worker         t0 = 0;
1341*abb65b4bSAndroid Build Coastguard Worker         do {
1342*abb65b4bSAndroid Build Coastguard Worker             t0 = oapv_bsr_read(bs, 8);
1343*abb65b4bSAndroid Build Coastguard Worker             DUMP_HLS(payload_size, t0);
1344*abb65b4bSAndroid Build Coastguard Worker             metadata_size -= 1;
1345*abb65b4bSAndroid Build Coastguard Worker             if(t0 == 0xFF) {
1346*abb65b4bSAndroid Build Coastguard Worker                 payload_size += 255;
1347*abb65b4bSAndroid Build Coastguard Worker             }
1348*abb65b4bSAndroid Build Coastguard Worker         } while(t0 == 0xFF);
1349*abb65b4bSAndroid Build Coastguard Worker         payload_size += t0;
1350*abb65b4bSAndroid Build Coastguard Worker         oapv_assert_gv(payload_size <= metadata_size, ret, OAPV_ERR_MALFORMED_BITSTREAM, ERR);
1351*abb65b4bSAndroid Build Coastguard Worker 
1352*abb65b4bSAndroid Build Coastguard Worker         if(payload_size > 0) {
1353*abb65b4bSAndroid Build Coastguard Worker 
1354*abb65b4bSAndroid Build Coastguard Worker             payload_data = oapv_malloc(payload_size);
1355*abb65b4bSAndroid Build Coastguard Worker             oapv_assert_gv(payload_data != NULL, ret, OAPV_ERR_OUT_OF_MEMORY, ERR);
1356*abb65b4bSAndroid Build Coastguard Worker             if(payload_type == OAPV_METADATA_FILLER) {
1357*abb65b4bSAndroid Build Coastguard Worker                 for(u32 i = 0; i < payload_size; i++) {
1358*abb65b4bSAndroid Build Coastguard Worker                     t0 = oapv_bsr_read(bs, 8);
1359*abb65b4bSAndroid Build Coastguard Worker                     DUMP_HLS(payload_data, t0);
1360*abb65b4bSAndroid Build Coastguard Worker                     oapv_assert_gv(t0 == 0xFF, ret, OAPV_ERR_MALFORMED_BITSTREAM, ERR);
1361*abb65b4bSAndroid Build Coastguard Worker                     payload_data[i] = 0xFF;
1362*abb65b4bSAndroid Build Coastguard Worker                 }
1363*abb65b4bSAndroid Build Coastguard Worker             }
1364*abb65b4bSAndroid Build Coastguard Worker             else {
1365*abb65b4bSAndroid Build Coastguard Worker                 for(u32 i = 0; i < payload_size; i++) {
1366*abb65b4bSAndroid Build Coastguard Worker                     t0 = oapv_bsr_read(bs, 8);
1367*abb65b4bSAndroid Build Coastguard Worker                     DUMP_HLS(payload_data, t0);
1368*abb65b4bSAndroid Build Coastguard Worker                     payload_data[i] = t0;
1369*abb65b4bSAndroid Build Coastguard Worker                 }
1370*abb65b4bSAndroid Build Coastguard Worker             }
1371*abb65b4bSAndroid Build Coastguard Worker         }
1372*abb65b4bSAndroid Build Coastguard Worker         ret = oapvm_set(mid, group_id, payload_type, payload_data, payload_size,
1373*abb65b4bSAndroid Build Coastguard Worker                         payload_type == OAPV_METADATA_USER_DEFINED ? payload_data : NULL);
1374*abb65b4bSAndroid Build Coastguard Worker         oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1375*abb65b4bSAndroid Build Coastguard Worker         metadata_size -= payload_size;
1376*abb65b4bSAndroid Build Coastguard Worker     }
1377*abb65b4bSAndroid Build Coastguard Worker     const u32 target_read_size = (pbu_size - 8);
1378*abb65b4bSAndroid Build Coastguard Worker     ret = oapvd_vlc_filler(bs, target_read_size - (bs->cur - bs_start_pos));
1379*abb65b4bSAndroid Build Coastguard Worker     oapv_assert_g(OAPV_SUCCEEDED(ret), ERR);
1380*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
1381*abb65b4bSAndroid Build Coastguard Worker 
1382*abb65b4bSAndroid Build Coastguard Worker ERR:
1383*abb65b4bSAndroid Build Coastguard Worker     // TO-DO: free memory
1384*abb65b4bSAndroid Build Coastguard Worker     return ret;
1385*abb65b4bSAndroid Build Coastguard Worker }
1386*abb65b4bSAndroid Build Coastguard Worker 
oapvd_vlc_filler(oapv_bs_t * bs,u32 filler_size)1387*abb65b4bSAndroid Build Coastguard Worker int oapvd_vlc_filler(oapv_bs_t *bs, u32 filler_size)
1388*abb65b4bSAndroid Build Coastguard Worker {
1389*abb65b4bSAndroid Build Coastguard Worker     int val;
1390*abb65b4bSAndroid Build Coastguard Worker     while(filler_size > 0) {
1391*abb65b4bSAndroid Build Coastguard Worker         val = oapv_bsr_read(bs, 8);
1392*abb65b4bSAndroid Build Coastguard Worker         if(val != 0xFF) {
1393*abb65b4bSAndroid Build Coastguard Worker             return OAPV_ERR_MALFORMED_BITSTREAM;
1394*abb65b4bSAndroid Build Coastguard Worker         }
1395*abb65b4bSAndroid Build Coastguard Worker         filler_size--;
1396*abb65b4bSAndroid Build Coastguard Worker     }
1397*abb65b4bSAndroid Build Coastguard Worker     return OAPV_OK;
1398*abb65b4bSAndroid Build Coastguard Worker }
1399*abb65b4bSAndroid Build Coastguard Worker 
1400*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
1401*abb65b4bSAndroid Build Coastguard Worker // end of decoder code
1402*abb65b4bSAndroid Build Coastguard Worker #endif // ENABLE_DECODER
1403*abb65b4bSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
1404