xref: /aosp_15_r20/external/libavc/encoder/svc/isvce_cavlc.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1*495ae853SAndroid Build Coastguard Worker /******************************************************************************
2*495ae853SAndroid Build Coastguard Worker  *
3*495ae853SAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
4*495ae853SAndroid Build Coastguard Worker  *
5*495ae853SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*495ae853SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*495ae853SAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*495ae853SAndroid Build Coastguard Worker  *
9*495ae853SAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*495ae853SAndroid Build Coastguard Worker  *
11*495ae853SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*495ae853SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*495ae853SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*495ae853SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*495ae853SAndroid Build Coastguard Worker  * limitations under the License.
16*495ae853SAndroid Build Coastguard Worker  *
17*495ae853SAndroid Build Coastguard Worker  *****************************************************************************
18*495ae853SAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*495ae853SAndroid Build Coastguard Worker  */
20*495ae853SAndroid Build Coastguard Worker 
21*495ae853SAndroid Build Coastguard Worker /**
22*495ae853SAndroid Build Coastguard Worker *******************************************************************************
23*495ae853SAndroid Build Coastguard Worker * @file
24*495ae853SAndroid Build Coastguard Worker *  isvce_cavlc.c
25*495ae853SAndroid Build Coastguard Worker *
26*495ae853SAndroid Build Coastguard Worker * @brief
27*495ae853SAndroid Build Coastguard Worker *  Contains all the routines to code syntax elements and residuals when entropy
28*495ae853SAndroid Build Coastguard Worker *  coding chosen is CAVLC
29*495ae853SAndroid Build Coastguard Worker *
30*495ae853SAndroid Build Coastguard Worker * @author
31*495ae853SAndroid Build Coastguard Worker *  ittiam
32*495ae853SAndroid Build Coastguard Worker *
33*495ae853SAndroid Build Coastguard Worker * @par List of Functions:
34*495ae853SAndroid Build Coastguard Worker *  - isvce_compute_zeroruns_and_trailingones()
35*495ae853SAndroid Build Coastguard Worker *  - isvce_write_coeff4x4_cavlc()
36*495ae853SAndroid Build Coastguard Worker *  - isvce_write_coeff8x8_cavlc()
37*495ae853SAndroid Build Coastguard Worker *  - isvce_encode_residue()
38*495ae853SAndroid Build Coastguard Worker *  - isvce_write_islice_mb_cavlc()
39*495ae853SAndroid Build Coastguard Worker *  - isvce_write_pslice_mb_cavlc()
40*495ae853SAndroid Build Coastguard Worker *
41*495ae853SAndroid Build Coastguard Worker * @remarks
42*495ae853SAndroid Build Coastguard Worker *  None
43*495ae853SAndroid Build Coastguard Worker *
44*495ae853SAndroid Build Coastguard Worker *******************************************************************************
45*495ae853SAndroid Build Coastguard Worker */
46*495ae853SAndroid Build Coastguard Worker 
47*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
48*495ae853SAndroid Build Coastguard Worker /* File Includes                                                             */
49*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
50*495ae853SAndroid Build Coastguard Worker 
51*495ae853SAndroid Build Coastguard Worker /* System include files */
52*495ae853SAndroid Build Coastguard Worker #include <stdio.h>
53*495ae853SAndroid Build Coastguard Worker #include <assert.h>
54*495ae853SAndroid Build Coastguard Worker #include <limits.h>
55*495ae853SAndroid Build Coastguard Worker 
56*495ae853SAndroid Build Coastguard Worker /* User include files */
57*495ae853SAndroid Build Coastguard Worker #include "ih264e_config.h"
58*495ae853SAndroid Build Coastguard Worker #include "ih264_typedefs.h"
59*495ae853SAndroid Build Coastguard Worker #include "iv2.h"
60*495ae853SAndroid Build Coastguard Worker #include "ive2.h"
61*495ae853SAndroid Build Coastguard Worker #include "ih264_debug.h"
62*495ae853SAndroid Build Coastguard Worker #include "isvc_macros.h"
63*495ae853SAndroid Build Coastguard Worker #include "isvc_defs.h"
64*495ae853SAndroid Build Coastguard Worker #include "isvce_defs.h"
65*495ae853SAndroid Build Coastguard Worker #include "ih264e_error.h"
66*495ae853SAndroid Build Coastguard Worker #include "ih264e_bitstream.h"
67*495ae853SAndroid Build Coastguard Worker #include "ime_distortion_metrics.h"
68*495ae853SAndroid Build Coastguard Worker #include "ime_defs.h"
69*495ae853SAndroid Build Coastguard Worker #include "ime_structs.h"
70*495ae853SAndroid Build Coastguard Worker #include "ih264_error.h"
71*495ae853SAndroid Build Coastguard Worker #include "isvc_structs.h"
72*495ae853SAndroid Build Coastguard Worker #include "isvc_trans_quant_itrans_iquant.h"
73*495ae853SAndroid Build Coastguard Worker #include "isvc_inter_pred_filters.h"
74*495ae853SAndroid Build Coastguard Worker #include "isvc_mem_fns.h"
75*495ae853SAndroid Build Coastguard Worker #include "ih264_padding.h"
76*495ae853SAndroid Build Coastguard Worker #include "ih264_intra_pred_filters.h"
77*495ae853SAndroid Build Coastguard Worker #include "ih264_deblk_edge_filters.h"
78*495ae853SAndroid Build Coastguard Worker #include "isvc_cabac_tables.h"
79*495ae853SAndroid Build Coastguard Worker #include "irc_cntrl_param.h"
80*495ae853SAndroid Build Coastguard Worker #include "irc_frame_info_collector.h"
81*495ae853SAndroid Build Coastguard Worker #include "isvce_rate_control.h"
82*495ae853SAndroid Build Coastguard Worker #include "isvce_cabac_structs.h"
83*495ae853SAndroid Build Coastguard Worker #include "isvce_structs.h"
84*495ae853SAndroid Build Coastguard Worker #include "isvce_encode_header.h"
85*495ae853SAndroid Build Coastguard Worker #include "ih264_cavlc_tables.h"
86*495ae853SAndroid Build Coastguard Worker #include "isvce_cavlc.h"
87*495ae853SAndroid Build Coastguard Worker #include "ih264e_statistics.h"
88*495ae853SAndroid Build Coastguard Worker #include "ih264e_trace.h"
89*495ae853SAndroid Build Coastguard Worker #include "isvce_encode_header.h"
90*495ae853SAndroid Build Coastguard Worker #include "isvce_utils.h"
91*495ae853SAndroid Build Coastguard Worker 
92*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
93*495ae853SAndroid Build Coastguard Worker /* Function Definitions                                                      */
94*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
95*495ae853SAndroid Build Coastguard Worker 
96*495ae853SAndroid Build Coastguard Worker /**
97*495ae853SAndroid Build Coastguard Worker *******************************************************************************
98*495ae853SAndroid Build Coastguard Worker *
99*495ae853SAndroid Build Coastguard Worker * @brief
100*495ae853SAndroid Build Coastguard Worker *  This function computes run of zero, number of trailing ones and sign of
101*495ae853SAndroid Build Coastguard Worker *  trailing ones basing on the significant coeff map, residual block and
102*495ae853SAndroid Build Coastguard Worker *  total nnz.
103*495ae853SAndroid Build Coastguard Worker *
104*495ae853SAndroid Build Coastguard Worker * @param[in] pi2_res_block
105*495ae853SAndroid Build Coastguard Worker *  Pointer to residual block containing levels in scan order
106*495ae853SAndroid Build Coastguard Worker *
107*495ae853SAndroid Build Coastguard Worker * @param[in] u4_total_coeff
108*495ae853SAndroid Build Coastguard Worker *  Total non-zero coefficients in that sub block
109*495ae853SAndroid Build Coastguard Worker *
110*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_zero_run
111*495ae853SAndroid Build Coastguard Worker *  Pointer to array to store run of zeros
112*495ae853SAndroid Build Coastguard Worker *
113*495ae853SAndroid Build Coastguard Worker * @param[in] u4_sig_coeff_map
114*495ae853SAndroid Build Coastguard Worker *  significant coefficient map
115*495ae853SAndroid Build Coastguard Worker *
116*495ae853SAndroid Build Coastguard Worker * @returns u4_totzero_sign_trailone
117*495ae853SAndroid Build Coastguard Worker *  Bits 0-8 contains number of trailing ones.
118*495ae853SAndroid Build Coastguard Worker *  Bits 8-16 contains bitwise sign information of trailing one
119*495ae853SAndroid Build Coastguard Worker *  Bits 16-24 contains total number of zeros.
120*495ae853SAndroid Build Coastguard Worker *
121*495ae853SAndroid Build Coastguard Worker * @remarks
122*495ae853SAndroid Build Coastguard Worker *  None
123*495ae853SAndroid Build Coastguard Worker *
124*495ae853SAndroid Build Coastguard Worker *******************************************************************************
125*495ae853SAndroid Build Coastguard Worker */
isvce_compute_zeroruns_and_trailingones(WORD16 * pi2_res_block,UWORD32 u4_total_coeff,UWORD8 * pu1_zero_run,UWORD32 u4_sig_coeff_map)126*495ae853SAndroid Build Coastguard Worker static UWORD32 isvce_compute_zeroruns_and_trailingones(WORD16 *pi2_res_block,
127*495ae853SAndroid Build Coastguard Worker                                                        UWORD32 u4_total_coeff, UWORD8 *pu1_zero_run,
128*495ae853SAndroid Build Coastguard Worker                                                        UWORD32 u4_sig_coeff_map)
129*495ae853SAndroid Build Coastguard Worker {
130*495ae853SAndroid Build Coastguard Worker     UWORD32 i = 0;
131*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_nnz_coeff = 0;
132*495ae853SAndroid Build Coastguard Worker     WORD32 i4_run = -1;
133*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_sign = 0;
134*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_tot_zero = 0;
135*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_trailing1 = 0;
136*495ae853SAndroid Build Coastguard Worker     WORD32 i4_val;
137*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_totzero_sign_trailone;
138*495ae853SAndroid Build Coastguard Worker     UWORD32 *pu4_zero_run;
139*495ae853SAndroid Build Coastguard Worker 
140*495ae853SAndroid Build Coastguard Worker     pu4_zero_run = (void *) pu1_zero_run;
141*495ae853SAndroid Build Coastguard Worker     pu4_zero_run[0] = 0;
142*495ae853SAndroid Build Coastguard Worker     pu4_zero_run[1] = 0;
143*495ae853SAndroid Build Coastguard Worker     pu4_zero_run[2] = 0;
144*495ae853SAndroid Build Coastguard Worker     pu4_zero_run[3] = 0;
145*495ae853SAndroid Build Coastguard Worker 
146*495ae853SAndroid Build Coastguard Worker     /* Compute Runs of zeros for all nnz coefficients except the last 3 */
147*495ae853SAndroid Build Coastguard Worker     if(u4_total_coeff > 3)
148*495ae853SAndroid Build Coastguard Worker     {
149*495ae853SAndroid Build Coastguard Worker         for(i = 0; u4_nnz_coeff < (u4_total_coeff - 3); i++)
150*495ae853SAndroid Build Coastguard Worker         {
151*495ae853SAndroid Build Coastguard Worker             i4_run++;
152*495ae853SAndroid Build Coastguard Worker 
153*495ae853SAndroid Build Coastguard Worker             i4_val = (u4_sig_coeff_map & 0x1);
154*495ae853SAndroid Build Coastguard Worker             u4_sig_coeff_map >>= 1;
155*495ae853SAndroid Build Coastguard Worker 
156*495ae853SAndroid Build Coastguard Worker             if(i4_val != 0)
157*495ae853SAndroid Build Coastguard Worker             {
158*495ae853SAndroid Build Coastguard Worker                 pu1_zero_run[u4_nnz_coeff++] = i4_run;
159*495ae853SAndroid Build Coastguard Worker                 i4_run = -1;
160*495ae853SAndroid Build Coastguard Worker             }
161*495ae853SAndroid Build Coastguard Worker         }
162*495ae853SAndroid Build Coastguard Worker     }
163*495ae853SAndroid Build Coastguard Worker 
164*495ae853SAndroid Build Coastguard Worker     /* Compute T1's, Signof(T1's) and Runs of zeros for the last 3 */
165*495ae853SAndroid Build Coastguard Worker     while(u4_nnz_coeff != u4_total_coeff)
166*495ae853SAndroid Build Coastguard Worker     {
167*495ae853SAndroid Build Coastguard Worker         i4_run++;
168*495ae853SAndroid Build Coastguard Worker 
169*495ae853SAndroid Build Coastguard Worker         i4_val = (u4_sig_coeff_map & 0x1);
170*495ae853SAndroid Build Coastguard Worker         u4_sig_coeff_map >>= 1;
171*495ae853SAndroid Build Coastguard Worker 
172*495ae853SAndroid Build Coastguard Worker         if(i4_val != 0)
173*495ae853SAndroid Build Coastguard Worker         {
174*495ae853SAndroid Build Coastguard Worker             if(pi2_res_block[u4_nnz_coeff] == 1)
175*495ae853SAndroid Build Coastguard Worker             {
176*495ae853SAndroid Build Coastguard Worker                 pu1_zero_run[u4_nnz_coeff] = i4_run;
177*495ae853SAndroid Build Coastguard Worker                 u4_trailing1++;
178*495ae853SAndroid Build Coastguard Worker             }
179*495ae853SAndroid Build Coastguard Worker             else
180*495ae853SAndroid Build Coastguard Worker             {
181*495ae853SAndroid Build Coastguard Worker                 if(pi2_res_block[u4_nnz_coeff] == -1)
182*495ae853SAndroid Build Coastguard Worker                 {
183*495ae853SAndroid Build Coastguard Worker                     pu1_zero_run[u4_nnz_coeff] = i4_run;
184*495ae853SAndroid Build Coastguard Worker                     u4_sign |= 1 << u4_trailing1;
185*495ae853SAndroid Build Coastguard Worker                     u4_trailing1++;
186*495ae853SAndroid Build Coastguard Worker                 }
187*495ae853SAndroid Build Coastguard Worker                 else
188*495ae853SAndroid Build Coastguard Worker                 {
189*495ae853SAndroid Build Coastguard Worker                     pu1_zero_run[u4_nnz_coeff] = i4_run;
190*495ae853SAndroid Build Coastguard Worker                     u4_trailing1 = 0;
191*495ae853SAndroid Build Coastguard Worker                     u4_sign = 0;
192*495ae853SAndroid Build Coastguard Worker                 }
193*495ae853SAndroid Build Coastguard Worker             }
194*495ae853SAndroid Build Coastguard Worker             i4_run = -1;
195*495ae853SAndroid Build Coastguard Worker             u4_nnz_coeff++;
196*495ae853SAndroid Build Coastguard Worker         }
197*495ae853SAndroid Build Coastguard Worker         i++;
198*495ae853SAndroid Build Coastguard Worker     }
199*495ae853SAndroid Build Coastguard Worker 
200*495ae853SAndroid Build Coastguard Worker     u4_tot_zero = i - u4_total_coeff;
201*495ae853SAndroid Build Coastguard Worker     u4_totzero_sign_trailone = (u4_tot_zero << 16) | (u4_sign << 8) | u4_trailing1;
202*495ae853SAndroid Build Coastguard Worker 
203*495ae853SAndroid Build Coastguard Worker     return (u4_totzero_sign_trailone);
204*495ae853SAndroid Build Coastguard Worker }
205*495ae853SAndroid Build Coastguard Worker 
206*495ae853SAndroid Build Coastguard Worker /**
207*495ae853SAndroid Build Coastguard Worker *******************************************************************************
208*495ae853SAndroid Build Coastguard Worker *
209*495ae853SAndroid Build Coastguard Worker * @brief
210*495ae853SAndroid Build Coastguard Worker *  This function generates CAVLC coded bit stream for the given residual block
211*495ae853SAndroid Build Coastguard Worker *
212*495ae853SAndroid Build Coastguard Worker * @param[in] pi2_res_block
213*495ae853SAndroid Build Coastguard Worker *  Pointer to residual block containing levels in scan order
214*495ae853SAndroid Build Coastguard Worker *
215*495ae853SAndroid Build Coastguard Worker * @param[in] u4_total_coeff
216*495ae853SAndroid Build Coastguard Worker *  Total non-zero coefficients in the sub block
217*495ae853SAndroid Build Coastguard Worker *
218*495ae853SAndroid Build Coastguard Worker * @param[in] u4_block_type
219*495ae853SAndroid Build Coastguard Worker *  block type
220*495ae853SAndroid Build Coastguard Worker *
221*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_zero_run
222*495ae853SAndroid Build Coastguard Worker *  Pointer to array to store run of zeros
223*495ae853SAndroid Build Coastguard Worker *
224*495ae853SAndroid Build Coastguard Worker * @param[in] u4_nc
225*495ae853SAndroid Build Coastguard Worker *  average of non zero coeff from top and left blocks (when available)
226*495ae853SAndroid Build Coastguard Worker *
227*495ae853SAndroid Build Coastguard Worker * @param[in, out] ps_bit_stream
228*495ae853SAndroid Build Coastguard Worker *  structure pointing to a buffer holding output bit stream
229*495ae853SAndroid Build Coastguard Worker *
230*495ae853SAndroid Build Coastguard Worker * @param[in] u4_sig_coeff_map
231*495ae853SAndroid Build Coastguard Worker *  significant coefficient map of the residual block
232*495ae853SAndroid Build Coastguard Worker *
233*495ae853SAndroid Build Coastguard Worker * @returns
234*495ae853SAndroid Build Coastguard Worker *  error code
235*495ae853SAndroid Build Coastguard Worker *
236*495ae853SAndroid Build Coastguard Worker * @remarks
237*495ae853SAndroid Build Coastguard Worker *  If the block type is CAVLC_CHROMA_4x4_DC, then u4_nc is non-significant
238*495ae853SAndroid Build Coastguard Worker *
239*495ae853SAndroid Build Coastguard Worker *******************************************************************************
240*495ae853SAndroid Build Coastguard Worker */
isvce_write_coeff4x4_cavlc(WORD16 * pi2_res_block,UWORD32 u4_total_coeff,ENTROPY_BLK_TYPE u4_block_type,UWORD8 * pu1_zero_run,UWORD32 u4_nc,bitstrm_t * ps_bit_stream,UWORD32 u4_sig_coeff_map)241*495ae853SAndroid Build Coastguard Worker static IH264E_ERROR_T isvce_write_coeff4x4_cavlc(WORD16 *pi2_res_block, UWORD32 u4_total_coeff,
242*495ae853SAndroid Build Coastguard Worker                                                  ENTROPY_BLK_TYPE u4_block_type,
243*495ae853SAndroid Build Coastguard Worker                                                  UWORD8 *pu1_zero_run, UWORD32 u4_nc,
244*495ae853SAndroid Build Coastguard Worker                                                  bitstrm_t *ps_bit_stream, UWORD32 u4_sig_coeff_map)
245*495ae853SAndroid Build Coastguard Worker {
246*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T error_status = IH264E_SUCCESS;
247*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_totzero_sign_trailone = 0;
248*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_trailing_ones = 0;
249*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_tot_zeros = 0;
250*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_remaining_coeff = 0;
251*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_sign1 = 0;
252*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_max_num_coeff = 0;
253*495ae853SAndroid Build Coastguard Worker     const UWORD32 au4_max_num_nnz_coeff[] = {16, 15, 16, 4, 15};
254*495ae853SAndroid Build Coastguard Worker 
255*495ae853SAndroid Build Coastguard Worker     /* validate inputs */
256*495ae853SAndroid Build Coastguard Worker     ASSERT(u4_block_type <= CAVLC_CHROMA_4x4_AC);
257*495ae853SAndroid Build Coastguard Worker 
258*495ae853SAndroid Build Coastguard Worker     u4_max_num_coeff = au4_max_num_nnz_coeff[u4_block_type];
259*495ae853SAndroid Build Coastguard Worker 
260*495ae853SAndroid Build Coastguard Worker     ASSERT(u4_total_coeff <= u4_max_num_coeff);
261*495ae853SAndroid Build Coastguard Worker 
262*495ae853SAndroid Build Coastguard Worker     if(!u4_total_coeff)
263*495ae853SAndroid Build Coastguard Worker     {
264*495ae853SAndroid Build Coastguard Worker         UWORD32 u4_codeword = 15;
265*495ae853SAndroid Build Coastguard Worker         UWORD32 u4_codesize = 1;
266*495ae853SAndroid Build Coastguard Worker         if(u4_block_type == CAVLC_CHROMA_4x4_DC)
267*495ae853SAndroid Build Coastguard Worker         {
268*495ae853SAndroid Build Coastguard Worker             u4_codeword = 1;
269*495ae853SAndroid Build Coastguard Worker             u4_codesize = 2;
270*495ae853SAndroid Build Coastguard Worker             DEBUG("\n[%d numcoeff, %d numtrailing ones]", u4_total_coeff, 0);
271*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
272*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tnumber of trailing ones ", 0);
273*495ae853SAndroid Build Coastguard Worker         }
274*495ae853SAndroid Build Coastguard Worker         else
275*495ae853SAndroid Build Coastguard Worker         {
276*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_vlcnum = u4_nc >> 1;
277*495ae853SAndroid Build Coastguard Worker 
278*495ae853SAndroid Build Coastguard Worker             /* write coeff_token */
279*495ae853SAndroid Build Coastguard Worker             if(u4_vlcnum > 3)
280*495ae853SAndroid Build Coastguard Worker             {
281*495ae853SAndroid Build Coastguard Worker                 /* Num-FLC */
282*495ae853SAndroid Build Coastguard Worker                 u4_codeword = 3;
283*495ae853SAndroid Build Coastguard Worker                 u4_codesize = 6;
284*495ae853SAndroid Build Coastguard Worker             }
285*495ae853SAndroid Build Coastguard Worker             else
286*495ae853SAndroid Build Coastguard Worker             {
287*495ae853SAndroid Build Coastguard Worker                 /* Num-VLC 0, 1, 2 */
288*495ae853SAndroid Build Coastguard Worker                 if(u4_vlcnum > 1)
289*495ae853SAndroid Build Coastguard Worker                 {
290*495ae853SAndroid Build Coastguard Worker                     u4_vlcnum = 2;
291*495ae853SAndroid Build Coastguard Worker                 }
292*495ae853SAndroid Build Coastguard Worker                 u4_codesize <<= u4_vlcnum;
293*495ae853SAndroid Build Coastguard Worker                 u4_codeword >>= (4 - u4_codesize);
294*495ae853SAndroid Build Coastguard Worker             }
295*495ae853SAndroid Build Coastguard Worker 
296*495ae853SAndroid Build Coastguard Worker             DEBUG("\n[%d numcoeff, %d numtrailing ones, %d nnz]", u4_total_coeff, 0, u4_nc);
297*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
298*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tnC ", u4_nc);
299*495ae853SAndroid Build Coastguard Worker         }
300*495ae853SAndroid Build Coastguard Worker 
301*495ae853SAndroid Build Coastguard Worker         DEBUG("\nCOEFF TOKEN 0: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
302*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("\tcodeword ", u4_codeword);
303*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("\tcodesize ", u4_codesize);
304*495ae853SAndroid Build Coastguard Worker 
305*495ae853SAndroid Build Coastguard Worker         error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
306*495ae853SAndroid Build Coastguard Worker 
307*495ae853SAndroid Build Coastguard Worker         return error_status;
308*495ae853SAndroid Build Coastguard Worker     }
309*495ae853SAndroid Build Coastguard Worker     else
310*495ae853SAndroid Build Coastguard Worker     {
311*495ae853SAndroid Build Coastguard Worker         /* Compute zero run, number of trailing ones and their sign. */
312*495ae853SAndroid Build Coastguard Worker         u4_totzero_sign_trailone = isvce_compute_zeroruns_and_trailingones(
313*495ae853SAndroid Build Coastguard Worker             pi2_res_block, u4_total_coeff, pu1_zero_run, u4_sig_coeff_map);
314*495ae853SAndroid Build Coastguard Worker         u4_trailing_ones = u4_totzero_sign_trailone & 0xFF;
315*495ae853SAndroid Build Coastguard Worker         u4_sign1 = (u4_totzero_sign_trailone >> 8) & 0xFF;
316*495ae853SAndroid Build Coastguard Worker         u4_tot_zeros = (u4_totzero_sign_trailone >> 16) & 0xFF;
317*495ae853SAndroid Build Coastguard Worker         u4_remaining_coeff = u4_total_coeff - u4_trailing_ones;
318*495ae853SAndroid Build Coastguard Worker 
319*495ae853SAndroid Build Coastguard Worker         /* write coeff_token */
320*495ae853SAndroid Build Coastguard Worker         {
321*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_codeword;
322*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_codesize;
323*495ae853SAndroid Build Coastguard Worker             if(u4_block_type == CAVLC_CHROMA_4x4_DC)
324*495ae853SAndroid Build Coastguard Worker             {
325*495ae853SAndroid Build Coastguard Worker                 u4_codeword =
326*495ae853SAndroid Build Coastguard Worker                     gu1_code_coeff_token_table_chroma[u4_trailing_ones][u4_total_coeff - 1];
327*495ae853SAndroid Build Coastguard Worker                 u4_codesize =
328*495ae853SAndroid Build Coastguard Worker                     gu1_size_coeff_token_table_chroma[u4_trailing_ones][u4_total_coeff - 1];
329*495ae853SAndroid Build Coastguard Worker 
330*495ae853SAndroid Build Coastguard Worker                 DEBUG("\n[%d numcoeff, %d numtrailing ones]", u4_total_coeff, u4_trailing_ones);
331*495ae853SAndroid Build Coastguard Worker                 ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
332*495ae853SAndroid Build Coastguard Worker                 ENTROPY_TRACE("\tnumber of trailing ones ", u4_trailing_ones);
333*495ae853SAndroid Build Coastguard Worker             }
334*495ae853SAndroid Build Coastguard Worker             else
335*495ae853SAndroid Build Coastguard Worker             {
336*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_vlcnum = u4_nc >> 1;
337*495ae853SAndroid Build Coastguard Worker 
338*495ae853SAndroid Build Coastguard Worker                 if(u4_vlcnum > 3)
339*495ae853SAndroid Build Coastguard Worker                 {
340*495ae853SAndroid Build Coastguard Worker                     /* Num-FLC */
341*495ae853SAndroid Build Coastguard Worker                     u4_codeword = ((u4_total_coeff - 1) << 2) + u4_trailing_ones;
342*495ae853SAndroid Build Coastguard Worker                     u4_codesize = 6;
343*495ae853SAndroid Build Coastguard Worker                 }
344*495ae853SAndroid Build Coastguard Worker                 else
345*495ae853SAndroid Build Coastguard Worker                 {
346*495ae853SAndroid Build Coastguard Worker                     /* Num-VLC 0, 1, 2 */
347*495ae853SAndroid Build Coastguard Worker                     if(u4_vlcnum > 1)
348*495ae853SAndroid Build Coastguard Worker                     {
349*495ae853SAndroid Build Coastguard Worker                         u4_vlcnum = 2;
350*495ae853SAndroid Build Coastguard Worker                     }
351*495ae853SAndroid Build Coastguard Worker                     u4_codeword =
352*495ae853SAndroid Build Coastguard Worker                         gu1_code_coeff_token_table[u4_vlcnum][u4_trailing_ones][u4_total_coeff - 1];
353*495ae853SAndroid Build Coastguard Worker                     u4_codesize =
354*495ae853SAndroid Build Coastguard Worker                         gu1_size_coeff_token_table[u4_vlcnum][u4_trailing_ones][u4_total_coeff - 1];
355*495ae853SAndroid Build Coastguard Worker                 }
356*495ae853SAndroid Build Coastguard Worker 
357*495ae853SAndroid Build Coastguard Worker                 DEBUG("\n[%d numcoeff, %d numtrailing ones, %d nnz]", u4_total_coeff,
358*495ae853SAndroid Build Coastguard Worker                       u4_trailing_ones, u4_nc);
359*495ae853SAndroid Build Coastguard Worker                 ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
360*495ae853SAndroid Build Coastguard Worker                 ENTROPY_TRACE("\tnumber of trailing ones ", u4_trailing_ones);
361*495ae853SAndroid Build Coastguard Worker                 ENTROPY_TRACE("\tnC ", u4_nc);
362*495ae853SAndroid Build Coastguard Worker             }
363*495ae853SAndroid Build Coastguard Worker 
364*495ae853SAndroid Build Coastguard Worker             DEBUG("\nCOEFF TOKEN 0: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
365*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tcodeword ", u4_codeword);
366*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tcodesize ", u4_codesize);
367*495ae853SAndroid Build Coastguard Worker 
368*495ae853SAndroid Build Coastguard Worker             error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
369*495ae853SAndroid Build Coastguard Worker         }
370*495ae853SAndroid Build Coastguard Worker 
371*495ae853SAndroid Build Coastguard Worker         /* write sign of trailing ones */
372*495ae853SAndroid Build Coastguard Worker         if(u4_trailing_ones)
373*495ae853SAndroid Build Coastguard Worker         {
374*495ae853SAndroid Build Coastguard Worker             DEBUG("\nT1's: %d u4_codeword, %d u4_codesize", u4_sign1, u4_trailing_ones);
375*495ae853SAndroid Build Coastguard Worker             error_status = ih264e_put_bits(ps_bit_stream, u4_sign1, u4_trailing_ones);
376*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tnumber of trailing ones ", u4_trailing_ones);
377*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tsign of trailing ones ", u4_sign1);
378*495ae853SAndroid Build Coastguard Worker         }
379*495ae853SAndroid Build Coastguard Worker 
380*495ae853SAndroid Build Coastguard Worker         /* write level codes */
381*495ae853SAndroid Build Coastguard Worker         if(u4_remaining_coeff)
382*495ae853SAndroid Build Coastguard Worker         {
383*495ae853SAndroid Build Coastguard Worker             WORD32 i4_level = pi2_res_block[u4_remaining_coeff - 1];
384*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_escape;
385*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_suffix_length = 0;  // Level-VLC[N]
386*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_abs_level, u4_abs_level_actual = 0;
387*495ae853SAndroid Build Coastguard Worker             WORD32 i4_sign;
388*495ae853SAndroid Build Coastguard Worker             const UWORD32 u4_rndfactor[] = {0, 0, 1, 3, 7, 15, 31};
389*495ae853SAndroid Build Coastguard Worker 
390*495ae853SAndroid Build Coastguard Worker             DEBUG("\n \t%d coeff,", i4_level);
391*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tcoeff ", i4_level);
392*495ae853SAndroid Build Coastguard Worker 
393*495ae853SAndroid Build Coastguard Worker             if(u4_trailing_ones < 3)
394*495ae853SAndroid Build Coastguard Worker             {
395*495ae853SAndroid Build Coastguard Worker                 /* If there are less than 3 T1s, then the first non-T1 level is
396*495ae853SAndroid Build Coastguard Worker                  * incremented if negative (decremented if positive)*/
397*495ae853SAndroid Build Coastguard Worker                 if(i4_level < 0)
398*495ae853SAndroid Build Coastguard Worker                 {
399*495ae853SAndroid Build Coastguard Worker                     i4_level += 1;
400*495ae853SAndroid Build Coastguard Worker                 }
401*495ae853SAndroid Build Coastguard Worker                 else
402*495ae853SAndroid Build Coastguard Worker                 {
403*495ae853SAndroid Build Coastguard Worker                     i4_level -= 1;
404*495ae853SAndroid Build Coastguard Worker                 }
405*495ae853SAndroid Build Coastguard Worker 
406*495ae853SAndroid Build Coastguard Worker                 u4_abs_level_actual = 1;
407*495ae853SAndroid Build Coastguard Worker 
408*495ae853SAndroid Build Coastguard Worker                 /* Initialize VLC table (Suffix Length) to encode the level */
409*495ae853SAndroid Build Coastguard Worker                 if(u4_total_coeff > 10)
410*495ae853SAndroid Build Coastguard Worker                 {
411*495ae853SAndroid Build Coastguard Worker                     u4_suffix_length = 1;
412*495ae853SAndroid Build Coastguard Worker                 }
413*495ae853SAndroid Build Coastguard Worker             }
414*495ae853SAndroid Build Coastguard Worker 
415*495ae853SAndroid Build Coastguard Worker             i4_sign = (i4_level >> (sizeof(WORD32) * CHAR_BIT - 1));
416*495ae853SAndroid Build Coastguard Worker             u4_abs_level = ((i4_level + i4_sign) ^ i4_sign);
417*495ae853SAndroid Build Coastguard Worker 
418*495ae853SAndroid Build Coastguard Worker             u4_abs_level_actual += u4_abs_level;
419*495ae853SAndroid Build Coastguard Worker 
420*495ae853SAndroid Build Coastguard Worker             u4_escape = (u4_abs_level + u4_rndfactor[u4_suffix_length]) >> u4_suffix_length;
421*495ae853SAndroid Build Coastguard Worker 
422*495ae853SAndroid Build Coastguard Worker             while(1)
423*495ae853SAndroid Build Coastguard Worker             {
424*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_codesize;
425*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_codeword;
426*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_codeval;
427*495ae853SAndroid Build Coastguard Worker 
428*495ae853SAndroid Build Coastguard Worker                 u4_remaining_coeff--;
429*495ae853SAndroid Build Coastguard Worker 
430*495ae853SAndroid Build Coastguard Worker                 GATHER_CAVLC_STATS1();
431*495ae853SAndroid Build Coastguard Worker 
432*495ae853SAndroid Build Coastguard Worker                 {
433*495ae853SAndroid Build Coastguard Worker                     u4_codeval = u4_abs_level << 1;
434*495ae853SAndroid Build Coastguard Worker                     u4_codeval = u4_codeval - 2 - i4_sign;
435*495ae853SAndroid Build Coastguard Worker 
436*495ae853SAndroid Build Coastguard Worker                     if((!u4_suffix_length) && (u4_escape > 7) && (u4_abs_level < 16))
437*495ae853SAndroid Build Coastguard Worker                     {
438*495ae853SAndroid Build Coastguard Worker                         u4_codeword = (1 << 4) + (u4_codeval - 14);
439*495ae853SAndroid Build Coastguard Worker                         u4_codesize = 19;
440*495ae853SAndroid Build Coastguard Worker                     }
441*495ae853SAndroid Build Coastguard Worker                     else if(u4_escape > 7)
442*495ae853SAndroid Build Coastguard Worker                     {
443*495ae853SAndroid Build Coastguard Worker                         u4_codeword = (1 << 12) + (u4_codeval - (15 << u4_suffix_length));
444*495ae853SAndroid Build Coastguard Worker                         u4_codesize = 28;
445*495ae853SAndroid Build Coastguard Worker                         if(!u4_suffix_length)
446*495ae853SAndroid Build Coastguard Worker                         {
447*495ae853SAndroid Build Coastguard Worker                             u4_codeword -= 15;
448*495ae853SAndroid Build Coastguard Worker                         }
449*495ae853SAndroid Build Coastguard Worker                     }
450*495ae853SAndroid Build Coastguard Worker                     else
451*495ae853SAndroid Build Coastguard Worker                     {
452*495ae853SAndroid Build Coastguard Worker                         u4_codeword =
453*495ae853SAndroid Build Coastguard Worker                             (1 << u4_suffix_length) + (u4_codeval & ((1 << u4_suffix_length) - 1));
454*495ae853SAndroid Build Coastguard Worker                         u4_codesize = (u4_codeval >> u4_suffix_length) + 1 + u4_suffix_length;
455*495ae853SAndroid Build Coastguard Worker                     }
456*495ae853SAndroid Build Coastguard Worker                 }
457*495ae853SAndroid Build Coastguard Worker 
458*495ae853SAndroid Build Coastguard Worker                 /*put the level code in bitstream*/
459*495ae853SAndroid Build Coastguard Worker                 DEBUG("\nLEVEL: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
460*495ae853SAndroid Build Coastguard Worker                 ENTROPY_TRACE("\tcodeword ", u4_codeword);
461*495ae853SAndroid Build Coastguard Worker                 ENTROPY_TRACE("\tcodesize ", u4_codesize);
462*495ae853SAndroid Build Coastguard Worker                 error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
463*495ae853SAndroid Build Coastguard Worker 
464*495ae853SAndroid Build Coastguard Worker                 if(u4_remaining_coeff == 0) break;
465*495ae853SAndroid Build Coastguard Worker 
466*495ae853SAndroid Build Coastguard Worker                 /*update suffix length for next level*/
467*495ae853SAndroid Build Coastguard Worker                 if(u4_suffix_length == 0)
468*495ae853SAndroid Build Coastguard Worker                 {
469*495ae853SAndroid Build Coastguard Worker                     u4_suffix_length++;
470*495ae853SAndroid Build Coastguard Worker                 }
471*495ae853SAndroid Build Coastguard Worker                 if(u4_suffix_length < 6)
472*495ae853SAndroid Build Coastguard Worker                 {
473*495ae853SAndroid Build Coastguard Worker                     if(u4_abs_level_actual > gu1_threshold_vlc_level[u4_suffix_length])
474*495ae853SAndroid Build Coastguard Worker                     {
475*495ae853SAndroid Build Coastguard Worker                         u4_suffix_length++;
476*495ae853SAndroid Build Coastguard Worker                     }
477*495ae853SAndroid Build Coastguard Worker                 }
478*495ae853SAndroid Build Coastguard Worker 
479*495ae853SAndroid Build Coastguard Worker                 /* next level */
480*495ae853SAndroid Build Coastguard Worker                 i4_level = pi2_res_block[u4_remaining_coeff - 1];
481*495ae853SAndroid Build Coastguard Worker 
482*495ae853SAndroid Build Coastguard Worker                 DEBUG("\n \t%d coeff,", i4_level);
483*495ae853SAndroid Build Coastguard Worker                 ENTROPY_TRACE("\tcoeff ", i4_level);
484*495ae853SAndroid Build Coastguard Worker 
485*495ae853SAndroid Build Coastguard Worker                 i4_sign = (i4_level >> (sizeof(WORD32) * CHAR_BIT - 1));
486*495ae853SAndroid Build Coastguard Worker                 u4_abs_level = ((i4_level + i4_sign) ^ i4_sign);
487*495ae853SAndroid Build Coastguard Worker 
488*495ae853SAndroid Build Coastguard Worker                 u4_abs_level_actual = u4_abs_level;
489*495ae853SAndroid Build Coastguard Worker 
490*495ae853SAndroid Build Coastguard Worker                 u4_escape = (u4_abs_level + u4_rndfactor[u4_suffix_length]) >> u4_suffix_length;
491*495ae853SAndroid Build Coastguard Worker             }
492*495ae853SAndroid Build Coastguard Worker         }
493*495ae853SAndroid Build Coastguard Worker 
494*495ae853SAndroid Build Coastguard Worker         DEBUG("\n \t %d totalzeros", u4_tot_zeros);
495*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("\ttotal zeros ", u4_tot_zeros);
496*495ae853SAndroid Build Coastguard Worker 
497*495ae853SAndroid Build Coastguard Worker         /* Write Total Zeros */
498*495ae853SAndroid Build Coastguard Worker         if(u4_total_coeff < u4_max_num_coeff)
499*495ae853SAndroid Build Coastguard Worker         {
500*495ae853SAndroid Build Coastguard Worker             WORD32 index;
501*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_codeword;
502*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_codesize;
503*495ae853SAndroid Build Coastguard Worker 
504*495ae853SAndroid Build Coastguard Worker             if(u4_block_type == CAVLC_CHROMA_4x4_DC)
505*495ae853SAndroid Build Coastguard Worker             {
506*495ae853SAndroid Build Coastguard Worker                 UWORD8 gu1_index_zero_table_chroma[] = {0, 4, 7};
507*495ae853SAndroid Build Coastguard Worker                 index = gu1_index_zero_table_chroma[u4_total_coeff - 1] + u4_tot_zeros;
508*495ae853SAndroid Build Coastguard Worker                 u4_codesize = gu1_size_zero_table_chroma[index];
509*495ae853SAndroid Build Coastguard Worker                 u4_codeword = gu1_code_zero_table_chroma[index];
510*495ae853SAndroid Build Coastguard Worker             }
511*495ae853SAndroid Build Coastguard Worker             else
512*495ae853SAndroid Build Coastguard Worker             {
513*495ae853SAndroid Build Coastguard Worker                 index = gu1_index_zero_table[u4_total_coeff - 1] + u4_tot_zeros;
514*495ae853SAndroid Build Coastguard Worker                 u4_codesize = gu1_size_zero_table[index];
515*495ae853SAndroid Build Coastguard Worker                 u4_codeword = gu1_code_zero_table[index];
516*495ae853SAndroid Build Coastguard Worker             }
517*495ae853SAndroid Build Coastguard Worker 
518*495ae853SAndroid Build Coastguard Worker             DEBUG("\nTOTAL ZEROS: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
519*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tcodeword ", u4_codeword);
520*495ae853SAndroid Build Coastguard Worker             ENTROPY_TRACE("\tcodesize ", u4_codesize);
521*495ae853SAndroid Build Coastguard Worker             error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
522*495ae853SAndroid Build Coastguard Worker         }
523*495ae853SAndroid Build Coastguard Worker 
524*495ae853SAndroid Build Coastguard Worker         /* Write Run Before */
525*495ae853SAndroid Build Coastguard Worker         if(u4_tot_zeros)
526*495ae853SAndroid Build Coastguard Worker         {
527*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_max_num_coef = u4_total_coeff - 1;
528*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_codeword;
529*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_codesize;
530*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_zeros_left = u4_tot_zeros;
531*495ae853SAndroid Build Coastguard Worker 
532*495ae853SAndroid Build Coastguard Worker             while(u4_max_num_coef)
533*495ae853SAndroid Build Coastguard Worker             {
534*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_run_before = pu1_zero_run[u4_max_num_coef];
535*495ae853SAndroid Build Coastguard Worker                 UWORD32 u4_index;
536*495ae853SAndroid Build Coastguard Worker 
537*495ae853SAndroid Build Coastguard Worker                 if(u4_zeros_left > MAX_ZERO_LEFT)
538*495ae853SAndroid Build Coastguard Worker                 {
539*495ae853SAndroid Build Coastguard Worker                     u4_index = gu1_index_run_table[MAX_ZERO_LEFT];
540*495ae853SAndroid Build Coastguard Worker                 }
541*495ae853SAndroid Build Coastguard Worker                 else
542*495ae853SAndroid Build Coastguard Worker                 {
543*495ae853SAndroid Build Coastguard Worker                     u4_index = gu1_index_run_table[u4_zeros_left - 1];
544*495ae853SAndroid Build Coastguard Worker                 }
545*495ae853SAndroid Build Coastguard Worker 
546*495ae853SAndroid Build Coastguard Worker                 u4_codesize = gu1_size_run_table[u4_index + u4_run_before];
547*495ae853SAndroid Build Coastguard Worker                 u4_codeword = gu1_code_run_table[u4_index + u4_run_before];
548*495ae853SAndroid Build Coastguard Worker 
549*495ae853SAndroid Build Coastguard Worker                 DEBUG("\nRUN BEFORE ZEROS: %d u4_codeword, %d u4_codesize", u4_codeword,
550*495ae853SAndroid Build Coastguard Worker                       u4_codesize);
551*495ae853SAndroid Build Coastguard Worker                 ENTROPY_TRACE("\tcodeword ", u4_codeword);
552*495ae853SAndroid Build Coastguard Worker                 ENTROPY_TRACE("\tcodesize ", u4_codesize);
553*495ae853SAndroid Build Coastguard Worker                 error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
554*495ae853SAndroid Build Coastguard Worker 
555*495ae853SAndroid Build Coastguard Worker                 u4_zeros_left -= u4_run_before;
556*495ae853SAndroid Build Coastguard Worker                 if(!u4_zeros_left)
557*495ae853SAndroid Build Coastguard Worker                 {
558*495ae853SAndroid Build Coastguard Worker                     break;
559*495ae853SAndroid Build Coastguard Worker                 }
560*495ae853SAndroid Build Coastguard Worker                 u4_max_num_coef--;
561*495ae853SAndroid Build Coastguard Worker             }
562*495ae853SAndroid Build Coastguard Worker         }
563*495ae853SAndroid Build Coastguard Worker     }
564*495ae853SAndroid Build Coastguard Worker 
565*495ae853SAndroid Build Coastguard Worker     return error_status;
566*495ae853SAndroid Build Coastguard Worker }
567*495ae853SAndroid Build Coastguard Worker 
568*495ae853SAndroid Build Coastguard Worker /**
569*495ae853SAndroid Build Coastguard Worker *******************************************************************************
570*495ae853SAndroid Build Coastguard Worker *
571*495ae853SAndroid Build Coastguard Worker * @brief
572*495ae853SAndroid Build Coastguard Worker *  This function generates CAVLC coded bit stream for the given subblock
573*495ae853SAndroid Build Coastguard Worker *
574*495ae853SAndroid Build Coastguard Worker * @param[in] ps_ent_ctxt
575*495ae853SAndroid Build Coastguard Worker *  Pointer to entropy context
576*495ae853SAndroid Build Coastguard Worker *
577*495ae853SAndroid Build Coastguard Worker * @param[in] pi2_res_block
578*495ae853SAndroid Build Coastguard Worker *  Pointers to residual blocks of all the partitions for the current subblk
579*495ae853SAndroid Build Coastguard Worker *  (containing levels in scan order)
580*495ae853SAndroid Build Coastguard Worker *
581*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_nnz
582*495ae853SAndroid Build Coastguard Worker *  Total non-zero coefficients of all the partitions for the current subblk
583*495ae853SAndroid Build Coastguard Worker *
584*495ae853SAndroid Build Coastguard Worker * @param[in] pu2_sig_coeff_map
585*495ae853SAndroid Build Coastguard Worker *  Significant coefficient map of all the partitions for the current subblk
586*495ae853SAndroid Build Coastguard Worker *
587*495ae853SAndroid Build Coastguard Worker * @param[in] u4_block_type
588*495ae853SAndroid Build Coastguard Worker *  entropy coding block type
589*495ae853SAndroid Build Coastguard Worker *
590*495ae853SAndroid Build Coastguard Worker * @param[in] u4_ngbr_avbl
591*495ae853SAndroid Build Coastguard Worker *  top and left availability of all the partitions for the current subblk
592*495ae853SAndroid Build Coastguard Worker *  (packed)
593*495ae853SAndroid Build Coastguard Worker *
594*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_top_nnz
595*495ae853SAndroid Build Coastguard Worker *  pointer to the buffer containing nnz of all the subblks to the top
596*495ae853SAndroid Build Coastguard Worker *
597*495ae853SAndroid Build Coastguard Worker * @param[in] pu1_left_nnz
598*495ae853SAndroid Build Coastguard Worker *  pointer to the buffer containing nnz of all the subblks to the left
599*495ae853SAndroid Build Coastguard Worker *
600*495ae853SAndroid Build Coastguard Worker * @returns error status
601*495ae853SAndroid Build Coastguard Worker *
602*495ae853SAndroid Build Coastguard Worker * @remarks none
603*495ae853SAndroid Build Coastguard Worker *
604*495ae853SAndroid Build Coastguard Worker *******************************************************************************
605*495ae853SAndroid Build Coastguard Worker */
isvce_write_coeff8x8_cavlc(isvce_entropy_ctxt_t * ps_ent_ctxt,WORD16 ** pi2_res_block,UWORD8 * pu1_nnz,UWORD16 * pu2_sig_coeff_map,ENTROPY_BLK_TYPE u4_block_type,UWORD32 u4_ngbr_avlb,UWORD8 * pu1_top_nnz,UWORD8 * pu1_left_nnz)606*495ae853SAndroid Build Coastguard Worker static IH264E_ERROR_T isvce_write_coeff8x8_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt,
607*495ae853SAndroid Build Coastguard Worker                                                  WORD16 **pi2_res_block, UWORD8 *pu1_nnz,
608*495ae853SAndroid Build Coastguard Worker                                                  UWORD16 *pu2_sig_coeff_map,
609*495ae853SAndroid Build Coastguard Worker                                                  ENTROPY_BLK_TYPE u4_block_type,
610*495ae853SAndroid Build Coastguard Worker                                                  UWORD32 u4_ngbr_avlb, UWORD8 *pu1_top_nnz,
611*495ae853SAndroid Build Coastguard Worker                                                  UWORD8 *pu1_left_nnz)
612*495ae853SAndroid Build Coastguard Worker {
613*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T error_status = IH264E_SUCCESS;
614*495ae853SAndroid Build Coastguard Worker     bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
615*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_zero_run = ps_ent_ctxt->au1_zero_run, *pu1_ngbr_avbl;
616*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_nC;
617*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_mb_a, u1_mb_b;
618*495ae853SAndroid Build Coastguard Worker 
619*495ae853SAndroid Build Coastguard Worker     pu1_ngbr_avbl = (void *) (&u4_ngbr_avlb);
620*495ae853SAndroid Build Coastguard Worker 
621*495ae853SAndroid Build Coastguard Worker     /* encode ac block index 4x4 = 0*/
622*495ae853SAndroid Build Coastguard Worker     u1_mb_a = pu1_ngbr_avbl[0] & 0x0F;
623*495ae853SAndroid Build Coastguard Worker     u1_mb_b = pu1_ngbr_avbl[0] & 0xF0;
624*495ae853SAndroid Build Coastguard Worker     u4_nC = 0;
625*495ae853SAndroid Build Coastguard Worker     if(u1_mb_a) u4_nC += pu1_left_nnz[0];
626*495ae853SAndroid Build Coastguard Worker     if(u1_mb_b) u4_nC += pu1_top_nnz[0];
627*495ae853SAndroid Build Coastguard Worker     if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
628*495ae853SAndroid Build Coastguard Worker     pu1_left_nnz[0] = pu1_top_nnz[0] = pu1_nnz[0];
629*495ae853SAndroid Build Coastguard Worker     error_status =
630*495ae853SAndroid Build Coastguard Worker         isvce_write_coeff4x4_cavlc(pi2_res_block[0], pu1_nnz[0], u4_block_type, pu1_zero_run, u4_nC,
631*495ae853SAndroid Build Coastguard Worker                                    ps_bitstream, pu2_sig_coeff_map[0]);
632*495ae853SAndroid Build Coastguard Worker 
633*495ae853SAndroid Build Coastguard Worker     /* encode ac block index 4x4 = 1*/
634*495ae853SAndroid Build Coastguard Worker     u1_mb_a = pu1_ngbr_avbl[1] & 0x0F;
635*495ae853SAndroid Build Coastguard Worker     u1_mb_b = pu1_ngbr_avbl[1] & 0xF0;
636*495ae853SAndroid Build Coastguard Worker     u4_nC = 0;
637*495ae853SAndroid Build Coastguard Worker     if(u1_mb_a) u4_nC += pu1_left_nnz[0];
638*495ae853SAndroid Build Coastguard Worker     if(u1_mb_b) u4_nC += pu1_top_nnz[1];
639*495ae853SAndroid Build Coastguard Worker     if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
640*495ae853SAndroid Build Coastguard Worker     pu1_left_nnz[0] = pu1_top_nnz[1] = pu1_nnz[1];
641*495ae853SAndroid Build Coastguard Worker     error_status =
642*495ae853SAndroid Build Coastguard Worker         isvce_write_coeff4x4_cavlc(pi2_res_block[1], pu1_nnz[1], u4_block_type, pu1_zero_run, u4_nC,
643*495ae853SAndroid Build Coastguard Worker                                    ps_bitstream, pu2_sig_coeff_map[1]);
644*495ae853SAndroid Build Coastguard Worker 
645*495ae853SAndroid Build Coastguard Worker     /* encode ac block index 4x4 = 2*/
646*495ae853SAndroid Build Coastguard Worker     u1_mb_a = pu1_ngbr_avbl[2] & 0x0F;
647*495ae853SAndroid Build Coastguard Worker     u1_mb_b = pu1_ngbr_avbl[2] & 0xF0;
648*495ae853SAndroid Build Coastguard Worker     u4_nC = 0;
649*495ae853SAndroid Build Coastguard Worker     if(u1_mb_a) u4_nC += pu1_left_nnz[1];
650*495ae853SAndroid Build Coastguard Worker     if(u1_mb_b) u4_nC += pu1_top_nnz[0];
651*495ae853SAndroid Build Coastguard Worker     if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
652*495ae853SAndroid Build Coastguard Worker     pu1_left_nnz[1] = pu1_top_nnz[0] = pu1_nnz[2];
653*495ae853SAndroid Build Coastguard Worker     error_status =
654*495ae853SAndroid Build Coastguard Worker         isvce_write_coeff4x4_cavlc(pi2_res_block[2], pu1_nnz[2], u4_block_type, pu1_zero_run, u4_nC,
655*495ae853SAndroid Build Coastguard Worker                                    ps_bitstream, pu2_sig_coeff_map[2]);
656*495ae853SAndroid Build Coastguard Worker 
657*495ae853SAndroid Build Coastguard Worker     /* encode ac block index 4x4 = 0*/
658*495ae853SAndroid Build Coastguard Worker     u1_mb_a = pu1_ngbr_avbl[3] & 0x0F;
659*495ae853SAndroid Build Coastguard Worker     u1_mb_b = pu1_ngbr_avbl[3] & 0xF0;
660*495ae853SAndroid Build Coastguard Worker     u4_nC = 0;
661*495ae853SAndroid Build Coastguard Worker     if(u1_mb_a) u4_nC += pu1_left_nnz[1];
662*495ae853SAndroid Build Coastguard Worker     if(u1_mb_b) u4_nC += pu1_top_nnz[1];
663*495ae853SAndroid Build Coastguard Worker     if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
664*495ae853SAndroid Build Coastguard Worker     pu1_left_nnz[1] = pu1_top_nnz[1] = pu1_nnz[3];
665*495ae853SAndroid Build Coastguard Worker     error_status =
666*495ae853SAndroid Build Coastguard Worker         isvce_write_coeff4x4_cavlc(pi2_res_block[3], pu1_nnz[3], u4_block_type, pu1_zero_run, u4_nC,
667*495ae853SAndroid Build Coastguard Worker                                    ps_bitstream, pu2_sig_coeff_map[3]);
668*495ae853SAndroid Build Coastguard Worker 
669*495ae853SAndroid Build Coastguard Worker     return error_status;
670*495ae853SAndroid Build Coastguard Worker }
671*495ae853SAndroid Build Coastguard Worker 
672*495ae853SAndroid Build Coastguard Worker /**
673*495ae853SAndroid Build Coastguard Worker *******************************************************************************
674*495ae853SAndroid Build Coastguard Worker *
675*495ae853SAndroid Build Coastguard Worker * @brief
676*495ae853SAndroid Build Coastguard Worker *  This function encodes luma and chroma residues of a macro block when
677*495ae853SAndroid Build Coastguard Worker *  the entropy coding mode chosen is cavlc.
678*495ae853SAndroid Build Coastguard Worker *
679*495ae853SAndroid Build Coastguard Worker * @param[in] ps_ent_ctxt
680*495ae853SAndroid Build Coastguard Worker *  Pointer to entropy context
681*495ae853SAndroid Build Coastguard Worker *
682*495ae853SAndroid Build Coastguard Worker * @param[in] u4_mb_type
683*495ae853SAndroid Build Coastguard Worker *  current mb type
684*495ae853SAndroid Build Coastguard Worker *
685*495ae853SAndroid Build Coastguard Worker * @param[in] u4_cbp
686*495ae853SAndroid Build Coastguard Worker *  coded block pattern for the current mb
687*495ae853SAndroid Build Coastguard Worker *
688*495ae853SAndroid Build Coastguard Worker * @returns error code
689*495ae853SAndroid Build Coastguard Worker *
690*495ae853SAndroid Build Coastguard Worker * @remarks none
691*495ae853SAndroid Build Coastguard Worker *
692*495ae853SAndroid Build Coastguard Worker *******************************************************************************
693*495ae853SAndroid Build Coastguard Worker */
isvce_encode_residue(isvce_entropy_ctxt_t * ps_ent_ctxt,UWORD32 u4_mb_type,UWORD32 u4_cbp)694*495ae853SAndroid Build Coastguard Worker static IH264E_ERROR_T isvce_encode_residue(isvce_entropy_ctxt_t *ps_ent_ctxt, UWORD32 u4_mb_type,
695*495ae853SAndroid Build Coastguard Worker                                            UWORD32 u4_cbp)
696*495ae853SAndroid Build Coastguard Worker {
697*495ae853SAndroid Build Coastguard Worker     /* error status */
698*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T error_status = IH264E_SUCCESS;
699*495ae853SAndroid Build Coastguard Worker 
700*495ae853SAndroid Build Coastguard Worker     /* packed residue */
701*495ae853SAndroid Build Coastguard Worker     void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data;
702*495ae853SAndroid Build Coastguard Worker 
703*495ae853SAndroid Build Coastguard Worker     /* bit stream buffer */
704*495ae853SAndroid Build Coastguard Worker     bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
705*495ae853SAndroid Build Coastguard Worker 
706*495ae853SAndroid Build Coastguard Worker     /* zero run */
707*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_zero_run = ps_ent_ctxt->au1_zero_run;
708*495ae853SAndroid Build Coastguard Worker 
709*495ae853SAndroid Build Coastguard Worker     /* temp var */
710*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_nC, u4_ngbr_avlb;
711*495ae853SAndroid Build Coastguard Worker     UWORD8 au1_nnz[4], *pu1_ngbr_avlb, *pu1_top_nnz, *pu1_left_nnz;
712*495ae853SAndroid Build Coastguard Worker     UWORD16 au2_sig_coeff_map[4] = {0};
713*495ae853SAndroid Build Coastguard Worker     WORD16 *pi2_res_block[4] = {NULL};
714*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_slice_idx = ps_ent_ctxt->pu1_slice_idx;
715*495ae853SAndroid Build Coastguard Worker     tu_sblk_coeff_data_t *ps_mb_coeff_data;
716*495ae853SAndroid Build Coastguard Worker     ENTROPY_BLK_TYPE e_entropy_blk_type = CAVLC_LUMA_4x4;
717*495ae853SAndroid Build Coastguard Worker 
718*495ae853SAndroid Build Coastguard Worker     /* ngbr availability */
719*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_mb_a, u1_mb_b;
720*495ae853SAndroid Build Coastguard Worker 
721*495ae853SAndroid Build Coastguard Worker     /* cbp */
722*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_cbp_luma = u4_cbp & 0xF, u4_cbp_chroma = u4_cbp >> 4;
723*495ae853SAndroid Build Coastguard Worker 
724*495ae853SAndroid Build Coastguard Worker     /* mb indices */
725*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_x, i4_mb_y;
726*495ae853SAndroid Build Coastguard Worker 
727*495ae853SAndroid Build Coastguard Worker     /* derive neighbor availability */
728*495ae853SAndroid Build Coastguard Worker     i4_mb_x = ps_ent_ctxt->i4_mb_x;
729*495ae853SAndroid Build Coastguard Worker     i4_mb_y = ps_ent_ctxt->i4_mb_y;
730*495ae853SAndroid Build Coastguard Worker     pu1_slice_idx += (i4_mb_y * ps_ent_ctxt->i4_wd_mbs);
731*495ae853SAndroid Build Coastguard Worker     /* left macroblock availability */
732*495ae853SAndroid Build Coastguard Worker     u1_mb_a = (i4_mb_x == 0 || (pu1_slice_idx[i4_mb_x - 1] != pu1_slice_idx[i4_mb_x])) ? 0 : 1;
733*495ae853SAndroid Build Coastguard Worker     /* top macroblock availability */
734*495ae853SAndroid Build Coastguard Worker     u1_mb_b = (i4_mb_y == 0 ||
735*495ae853SAndroid Build Coastguard Worker                (pu1_slice_idx[i4_mb_x - ps_ent_ctxt->i4_wd_mbs] != pu1_slice_idx[i4_mb_x]))
736*495ae853SAndroid Build Coastguard Worker                   ? 0
737*495ae853SAndroid Build Coastguard Worker                   : 1;
738*495ae853SAndroid Build Coastguard Worker 
739*495ae853SAndroid Build Coastguard Worker     pu1_ngbr_avlb = (void *) (&u4_ngbr_avlb);
740*495ae853SAndroid Build Coastguard Worker     pu1_top_nnz = ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
741*495ae853SAndroid Build Coastguard Worker     pu1_left_nnz = (UWORD8 *) &ps_ent_ctxt->u4_left_nnz_luma;
742*495ae853SAndroid Build Coastguard Worker 
743*495ae853SAndroid Build Coastguard Worker     /* encode luma residue */
744*495ae853SAndroid Build Coastguard Worker 
745*495ae853SAndroid Build Coastguard Worker     /* mb type intra 16x16 */
746*495ae853SAndroid Build Coastguard Worker     if(u4_mb_type == I16x16)
747*495ae853SAndroid Build Coastguard Worker     {
748*495ae853SAndroid Build Coastguard Worker         /* parse packed coeff data structure for residual data */
749*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
750*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[0], pi2_res_block[0]);
751*495ae853SAndroid Build Coastguard Worker         /* estimate nnz for the current mb */
752*495ae853SAndroid Build Coastguard Worker         u4_nC = 0;
753*495ae853SAndroid Build Coastguard Worker         if(u1_mb_a) u4_nC += pu1_left_nnz[0];
754*495ae853SAndroid Build Coastguard Worker         if(u1_mb_b) u4_nC += pu1_top_nnz[0];
755*495ae853SAndroid Build Coastguard Worker         if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
756*495ae853SAndroid Build Coastguard Worker 
757*495ae853SAndroid Build Coastguard Worker         /* encode dc block */
758*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("Luma DC blk idx %d", 0);
759*495ae853SAndroid Build Coastguard Worker         error_status =
760*495ae853SAndroid Build Coastguard Worker             isvce_write_coeff4x4_cavlc(pi2_res_block[0], au1_nnz[0], CAVLC_LUMA_4x4_DC,
761*495ae853SAndroid Build Coastguard Worker                                        pu1_zero_run, u4_nC, ps_bitstream, au2_sig_coeff_map[0]);
762*495ae853SAndroid Build Coastguard Worker 
763*495ae853SAndroid Build Coastguard Worker         e_entropy_blk_type = CAVLC_LUMA_4x4_AC;
764*495ae853SAndroid Build Coastguard Worker     }
765*495ae853SAndroid Build Coastguard Worker 
766*495ae853SAndroid Build Coastguard Worker     if(u4_cbp_luma & 1)
767*495ae853SAndroid Build Coastguard Worker     {
768*495ae853SAndroid Build Coastguard Worker         /* encode ac block index 8x8 = 0*/
769*495ae853SAndroid Build Coastguard Worker         /* parse packed coeff data structure for residual data */
770*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
771*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[0], pi2_res_block[0]);
772*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
773*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[1], pi2_res_block[1]);
774*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
775*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[2], pi2_res_block[2]);
776*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
777*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[3], pi2_res_block[3]);
778*495ae853SAndroid Build Coastguard Worker         /* derive sub block neighbor availability */
779*495ae853SAndroid Build Coastguard Worker 
780*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[0] = (u1_mb_b << 4) | (u1_mb_a);
781*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[1] = (u1_mb_b << 4) | 1;
782*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[2] = (1 << 4) | (u1_mb_a);
783*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[3] = 0x11;
784*495ae853SAndroid Build Coastguard Worker         /* encode sub blk */
785*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("Luma blk idx %d", 0);
786*495ae853SAndroid Build Coastguard Worker         error_status =
787*495ae853SAndroid Build Coastguard Worker             isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz, au2_sig_coeff_map,
788*495ae853SAndroid Build Coastguard Worker                                        e_entropy_blk_type, u4_ngbr_avlb, pu1_top_nnz, pu1_left_nnz);
789*495ae853SAndroid Build Coastguard Worker     }
790*495ae853SAndroid Build Coastguard Worker     else
791*495ae853SAndroid Build Coastguard Worker     {
792*495ae853SAndroid Build Coastguard Worker         pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
793*495ae853SAndroid Build Coastguard Worker         pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
794*495ae853SAndroid Build Coastguard Worker     }
795*495ae853SAndroid Build Coastguard Worker 
796*495ae853SAndroid Build Coastguard Worker     if(u4_cbp_luma & 2)
797*495ae853SAndroid Build Coastguard Worker     {
798*495ae853SAndroid Build Coastguard Worker         /* encode ac block index 8x8 = 1*/
799*495ae853SAndroid Build Coastguard Worker         /* parse packed coeff data structure for residual data */
800*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
801*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[0], pi2_res_block[0]);
802*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
803*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[1], pi2_res_block[1]);
804*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
805*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[2], pi2_res_block[2]);
806*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
807*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[3], pi2_res_block[3]);
808*495ae853SAndroid Build Coastguard Worker 
809*495ae853SAndroid Build Coastguard Worker         /* derive sub block neighbor availability */
810*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[1] = pu1_ngbr_avlb[0] = (u1_mb_b << 4) | 1;
811*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[3] = pu1_ngbr_avlb[2] = 0x11;
812*495ae853SAndroid Build Coastguard Worker         /* encode sub blk */
813*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("Luma blk idx %d", 1);
814*495ae853SAndroid Build Coastguard Worker         error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
815*495ae853SAndroid Build Coastguard Worker                                                   au2_sig_coeff_map, e_entropy_blk_type,
816*495ae853SAndroid Build Coastguard Worker                                                   u4_ngbr_avlb, pu1_top_nnz + 2, pu1_left_nnz);
817*495ae853SAndroid Build Coastguard Worker     }
818*495ae853SAndroid Build Coastguard Worker     else
819*495ae853SAndroid Build Coastguard Worker     {
820*495ae853SAndroid Build Coastguard Worker         (pu1_top_nnz + 2)[0] = (pu1_top_nnz + 2)[1] = 0;
821*495ae853SAndroid Build Coastguard Worker         pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
822*495ae853SAndroid Build Coastguard Worker     }
823*495ae853SAndroid Build Coastguard Worker 
824*495ae853SAndroid Build Coastguard Worker     if(u4_cbp_luma & 0x4)
825*495ae853SAndroid Build Coastguard Worker     {
826*495ae853SAndroid Build Coastguard Worker         /* encode ac block index 8x8 = 2*/
827*495ae853SAndroid Build Coastguard Worker         /* parse packed coeff data structure for residual data */
828*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
829*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[0], pi2_res_block[0]);
830*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
831*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[1], pi2_res_block[1]);
832*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
833*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[2], pi2_res_block[2]);
834*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
835*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[3], pi2_res_block[3]);
836*495ae853SAndroid Build Coastguard Worker 
837*495ae853SAndroid Build Coastguard Worker         /* derive sub block neighbor availability */
838*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[2] = pu1_ngbr_avlb[0] = (1 << 4) | u1_mb_a;
839*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[1] = pu1_ngbr_avlb[3] = 0x11;
840*495ae853SAndroid Build Coastguard Worker         /* encode sub blk */
841*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("Luma blk idx %d", 2);
842*495ae853SAndroid Build Coastguard Worker         error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
843*495ae853SAndroid Build Coastguard Worker                                                   au2_sig_coeff_map, e_entropy_blk_type,
844*495ae853SAndroid Build Coastguard Worker                                                   u4_ngbr_avlb, pu1_top_nnz, (pu1_left_nnz + 2));
845*495ae853SAndroid Build Coastguard Worker     }
846*495ae853SAndroid Build Coastguard Worker     else
847*495ae853SAndroid Build Coastguard Worker     {
848*495ae853SAndroid Build Coastguard Worker         pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
849*495ae853SAndroid Build Coastguard Worker         (pu1_left_nnz + 2)[0] = (pu1_left_nnz + 2)[1] = 0;
850*495ae853SAndroid Build Coastguard Worker     }
851*495ae853SAndroid Build Coastguard Worker 
852*495ae853SAndroid Build Coastguard Worker     if(u4_cbp_luma & 0x8)
853*495ae853SAndroid Build Coastguard Worker     {
854*495ae853SAndroid Build Coastguard Worker         /* encode ac block index 8x8 = 3*/
855*495ae853SAndroid Build Coastguard Worker         /* parse packed coeff data structure for residual data */
856*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
857*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[0], pi2_res_block[0]);
858*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
859*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[1], pi2_res_block[1]);
860*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
861*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[2], pi2_res_block[2]);
862*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
863*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[3], pi2_res_block[3]);
864*495ae853SAndroid Build Coastguard Worker 
865*495ae853SAndroid Build Coastguard Worker         /* derive sub block neighbor availability */
866*495ae853SAndroid Build Coastguard Worker         u4_ngbr_avlb = 0x11111111;
867*495ae853SAndroid Build Coastguard Worker         /* encode sub blk */
868*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("Luma blk idx %d", 3);
869*495ae853SAndroid Build Coastguard Worker         error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
870*495ae853SAndroid Build Coastguard Worker                                                   au2_sig_coeff_map, e_entropy_blk_type,
871*495ae853SAndroid Build Coastguard Worker                                                   u4_ngbr_avlb, pu1_top_nnz + 2, pu1_left_nnz + 2);
872*495ae853SAndroid Build Coastguard Worker     }
873*495ae853SAndroid Build Coastguard Worker     else
874*495ae853SAndroid Build Coastguard Worker     {
875*495ae853SAndroid Build Coastguard Worker         (pu1_top_nnz + 2)[0] = (pu1_top_nnz + 2)[1] = 0;
876*495ae853SAndroid Build Coastguard Worker         (pu1_left_nnz + 2)[0] = (pu1_left_nnz + 2)[1] = 0;
877*495ae853SAndroid Build Coastguard Worker     }
878*495ae853SAndroid Build Coastguard Worker 
879*495ae853SAndroid Build Coastguard Worker     /* encode chroma residue */
880*495ae853SAndroid Build Coastguard Worker     if(u4_cbp_chroma & 3)
881*495ae853SAndroid Build Coastguard Worker     {
882*495ae853SAndroid Build Coastguard Worker         /* parse packed coeff data structure for residual data */
883*495ae853SAndroid Build Coastguard Worker         /* cb, cr */
884*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
885*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[0], pi2_res_block[0]);
886*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
887*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[1], pi2_res_block[1]);
888*495ae853SAndroid Build Coastguard Worker 
889*495ae853SAndroid Build Coastguard Worker         /* encode dc block */
890*495ae853SAndroid Build Coastguard Worker         /* cb, cr */
891*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("Chroma DC blk idx %d", 0);
892*495ae853SAndroid Build Coastguard Worker         error_status =
893*495ae853SAndroid Build Coastguard Worker             isvce_write_coeff4x4_cavlc(pi2_res_block[0], au1_nnz[0], CAVLC_CHROMA_4x4_DC,
894*495ae853SAndroid Build Coastguard Worker                                        pu1_zero_run, 0, ps_bitstream, au2_sig_coeff_map[0]);
895*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("Chroma DC blk idx %d", 1);
896*495ae853SAndroid Build Coastguard Worker         error_status =
897*495ae853SAndroid Build Coastguard Worker             isvce_write_coeff4x4_cavlc(pi2_res_block[1], au1_nnz[1], CAVLC_CHROMA_4x4_DC,
898*495ae853SAndroid Build Coastguard Worker                                        pu1_zero_run, 0, ps_bitstream, au2_sig_coeff_map[1]);
899*495ae853SAndroid Build Coastguard Worker     }
900*495ae853SAndroid Build Coastguard Worker 
901*495ae853SAndroid Build Coastguard Worker     pu1_top_nnz = ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
902*495ae853SAndroid Build Coastguard Worker     pu1_left_nnz = (UWORD8 *) &ps_ent_ctxt->u4_left_nnz_cbcr;
903*495ae853SAndroid Build Coastguard Worker 
904*495ae853SAndroid Build Coastguard Worker     /* encode sub blk */
905*495ae853SAndroid Build Coastguard Worker     if(u4_cbp_chroma & 0x2)
906*495ae853SAndroid Build Coastguard Worker     {
907*495ae853SAndroid Build Coastguard Worker         /* encode ac block index 8x8 = 0*/
908*495ae853SAndroid Build Coastguard Worker         /* derive sub block neighbor availability */
909*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[0] = (u1_mb_b << 4) | (u1_mb_a);
910*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[1] = (u1_mb_b << 4) | 1;
911*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[2] = (1 << 4) | (u1_mb_a);
912*495ae853SAndroid Build Coastguard Worker         pu1_ngbr_avlb[3] = 0x11;
913*495ae853SAndroid Build Coastguard Worker 
914*495ae853SAndroid Build Coastguard Worker         /* parse packed coeff data structure for residual data */
915*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
916*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[0], pi2_res_block[0]);
917*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
918*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[1], pi2_res_block[1]);
919*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
920*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[2], pi2_res_block[2]);
921*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
922*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[3], pi2_res_block[3]);
923*495ae853SAndroid Build Coastguard Worker 
924*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("Chroma AC blk idx %d", 0);
925*495ae853SAndroid Build Coastguard Worker         error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
926*495ae853SAndroid Build Coastguard Worker                                                   au2_sig_coeff_map, CAVLC_CHROMA_4x4_AC,
927*495ae853SAndroid Build Coastguard Worker                                                   u4_ngbr_avlb, pu1_top_nnz, pu1_left_nnz);
928*495ae853SAndroid Build Coastguard Worker     }
929*495ae853SAndroid Build Coastguard Worker     else
930*495ae853SAndroid Build Coastguard Worker     {
931*495ae853SAndroid Build Coastguard Worker         pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
932*495ae853SAndroid Build Coastguard Worker         pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
933*495ae853SAndroid Build Coastguard Worker     }
934*495ae853SAndroid Build Coastguard Worker 
935*495ae853SAndroid Build Coastguard Worker     pu1_top_nnz += 2;
936*495ae853SAndroid Build Coastguard Worker     pu1_left_nnz += 2;
937*495ae853SAndroid Build Coastguard Worker 
938*495ae853SAndroid Build Coastguard Worker     /* encode sub blk */
939*495ae853SAndroid Build Coastguard Worker     if(u4_cbp_chroma & 0x2)
940*495ae853SAndroid Build Coastguard Worker     {
941*495ae853SAndroid Build Coastguard Worker         /* parse packed coeff data structure for residual data */
942*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
943*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[0], pi2_res_block[0]);
944*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
945*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[1], pi2_res_block[1]);
946*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
947*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[2], pi2_res_block[2]);
948*495ae853SAndroid Build Coastguard Worker         PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
949*495ae853SAndroid Build Coastguard Worker                                    au2_sig_coeff_map[3], pi2_res_block[3]);
950*495ae853SAndroid Build Coastguard Worker 
951*495ae853SAndroid Build Coastguard Worker         ENTROPY_TRACE("Chroma AC blk idx %d", 1);
952*495ae853SAndroid Build Coastguard Worker         error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
953*495ae853SAndroid Build Coastguard Worker                                                   au2_sig_coeff_map, CAVLC_CHROMA_4x4_AC,
954*495ae853SAndroid Build Coastguard Worker                                                   u4_ngbr_avlb, pu1_top_nnz, pu1_left_nnz);
955*495ae853SAndroid Build Coastguard Worker     }
956*495ae853SAndroid Build Coastguard Worker     else
957*495ae853SAndroid Build Coastguard Worker     {
958*495ae853SAndroid Build Coastguard Worker         pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
959*495ae853SAndroid Build Coastguard Worker         pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
960*495ae853SAndroid Build Coastguard Worker     }
961*495ae853SAndroid Build Coastguard Worker 
962*495ae853SAndroid Build Coastguard Worker     /* store the index of the next mb coeff data */
963*495ae853SAndroid Build Coastguard Worker     ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data;
964*495ae853SAndroid Build Coastguard Worker 
965*495ae853SAndroid Build Coastguard Worker     return error_status;
966*495ae853SAndroid Build Coastguard Worker }
967*495ae853SAndroid Build Coastguard Worker 
968*495ae853SAndroid Build Coastguard Worker /**
969*495ae853SAndroid Build Coastguard Worker *******************************************************************************
970*495ae853SAndroid Build Coastguard Worker *
971*495ae853SAndroid Build Coastguard Worker * @brief
972*495ae853SAndroid Build Coastguard Worker *  This function generates CAVLC coded bit stream for an Intra Slice.
973*495ae853SAndroid Build Coastguard Worker *
974*495ae853SAndroid Build Coastguard Worker * @description
975*495ae853SAndroid Build Coastguard Worker *  The mb syntax layer for intra slices constitutes luma mb mode, luma sub modes
976*495ae853SAndroid Build Coastguard Worker *  (if present), mb qp delta, coded block pattern, chroma mb mode and
977*495ae853SAndroid Build Coastguard Worker *  luma/chroma residue. These syntax elements are written as directed by table
978*495ae853SAndroid Build Coastguard Worker *  7.3.5 of h264 specification.
979*495ae853SAndroid Build Coastguard Worker *
980*495ae853SAndroid Build Coastguard Worker * @param[in] ps_ent_ctxt
981*495ae853SAndroid Build Coastguard Worker *  pointer to entropy context
982*495ae853SAndroid Build Coastguard Worker *
983*495ae853SAndroid Build Coastguard Worker * @returns error code
984*495ae853SAndroid Build Coastguard Worker *
985*495ae853SAndroid Build Coastguard Worker * @remarks none
986*495ae853SAndroid Build Coastguard Worker *
987*495ae853SAndroid Build Coastguard Worker *******************************************************************************
988*495ae853SAndroid Build Coastguard Worker */
isvce_write_islice_mb_cavlc(isvce_entropy_ctxt_t * ps_ent_ctxt)989*495ae853SAndroid Build Coastguard Worker IH264E_ERROR_T isvce_write_islice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt)
990*495ae853SAndroid Build Coastguard Worker {
991*495ae853SAndroid Build Coastguard Worker     /* error status */
992*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T error_status = IH264E_SUCCESS;
993*495ae853SAndroid Build Coastguard Worker 
994*495ae853SAndroid Build Coastguard Worker     /* bit stream ptr */
995*495ae853SAndroid Build Coastguard Worker     bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
996*495ae853SAndroid Build Coastguard Worker 
997*495ae853SAndroid Build Coastguard Worker     /* packed header data */
998*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
999*495ae853SAndroid Build Coastguard Worker     isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
1000*495ae853SAndroid Build Coastguard Worker 
1001*495ae853SAndroid Build Coastguard Worker     /* mb header info */
1002*495ae853SAndroid Build Coastguard Worker     /*
1003*495ae853SAndroid Build Coastguard Worker      * mb_tpm : mb type plus mode
1004*495ae853SAndroid Build Coastguard Worker      * mb_type : luma mb type and chroma mb type are packed
1005*495ae853SAndroid Build Coastguard Worker      * cbp : coded block pattern
1006*495ae853SAndroid Build Coastguard Worker      * mb_qp_delta : mb qp delta
1007*495ae853SAndroid Build Coastguard Worker      * chroma_intra_mode : chroma intra mode
1008*495ae853SAndroid Build Coastguard Worker      * luma_intra_mode : luma intra mode
1009*495ae853SAndroid Build Coastguard Worker      */
1010*495ae853SAndroid Build Coastguard Worker     WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
1011*495ae853SAndroid Build Coastguard Worker     WORD8 mb_qp_delta;
1012*495ae853SAndroid Build Coastguard Worker 
1013*495ae853SAndroid Build Coastguard Worker     /* temp var */
1014*495ae853SAndroid Build Coastguard Worker     WORD32 i, mb_type_stream;
1015*495ae853SAndroid Build Coastguard Worker 
1016*495ae853SAndroid Build Coastguard Worker     WORD32 bitstream_start_offset, bitstream_end_offset;
1017*495ae853SAndroid Build Coastguard Worker 
1018*495ae853SAndroid Build Coastguard Worker     svc_slice_header_t *ps_svc_slice_header =
1019*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->ps_svc_slice_hdr_base +
1020*495ae853SAndroid Build Coastguard Worker         (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
1021*495ae853SAndroid Build Coastguard Worker 
1022*495ae853SAndroid Build Coastguard Worker     /* Starting bitstream offset for header in bits */
1023*495ae853SAndroid Build Coastguard Worker     bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
1024*495ae853SAndroid Build Coastguard Worker 
1025*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1026*495ae853SAndroid Build Coastguard Worker     /*                    BEGIN HEADER GENERATION                       */
1027*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1028*495ae853SAndroid Build Coastguard Worker 
1029*495ae853SAndroid Build Coastguard Worker     if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
1030*495ae853SAndroid Build Coastguard Worker     {
1031*495ae853SAndroid Build Coastguard Worker         /* write base_mode_flag */
1032*495ae853SAndroid Build Coastguard Worker         PUT_BITS(ps_bitstream, ps_mb_hdr->u1_base_mode_flag, 1, error_status, "base_mode_flag");
1033*495ae853SAndroid Build Coastguard Worker     }
1034*495ae853SAndroid Build Coastguard Worker     else
1035*495ae853SAndroid Build Coastguard Worker     {
1036*495ae853SAndroid Build Coastguard Worker         ps_mb_hdr->u1_base_mode_flag = 0;
1037*495ae853SAndroid Build Coastguard Worker     }
1038*495ae853SAndroid Build Coastguard Worker 
1039*495ae853SAndroid Build Coastguard Worker     /* mb header info */
1040*495ae853SAndroid Build Coastguard Worker     mb_tpm = ps_mb_hdr->u1_mb_type_mode;
1041*495ae853SAndroid Build Coastguard Worker     cbp = ps_mb_hdr->u1_cbp;
1042*495ae853SAndroid Build Coastguard Worker     mb_qp_delta =
1043*495ae853SAndroid Build Coastguard Worker         ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
1044*495ae853SAndroid Build Coastguard Worker 
1045*495ae853SAndroid Build Coastguard Worker     /* mb type */
1046*495ae853SAndroid Build Coastguard Worker     mb_type = mb_tpm & 0xF;
1047*495ae853SAndroid Build Coastguard Worker     /* is intra ? */
1048*495ae853SAndroid Build Coastguard Worker     if(!ps_mb_hdr->u1_base_mode_flag)
1049*495ae853SAndroid Build Coastguard Worker     {
1050*495ae853SAndroid Build Coastguard Worker         if(mb_type == I16x16)
1051*495ae853SAndroid Build Coastguard Worker         {
1052*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_cbp_l, u4_cbp_c;
1053*495ae853SAndroid Build Coastguard Worker 
1054*495ae853SAndroid Build Coastguard Worker             u4_cbp_c = (cbp >> 4);
1055*495ae853SAndroid Build Coastguard Worker             u4_cbp_l = (cbp & 0xF);
1056*495ae853SAndroid Build Coastguard Worker             luma_intra_mode = (mb_tpm >> 4) & 3;
1057*495ae853SAndroid Build Coastguard Worker             chroma_intra_mode = (mb_tpm >> 6);
1058*495ae853SAndroid Build Coastguard Worker 
1059*495ae853SAndroid Build Coastguard Worker             mb_type_stream = luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1060*495ae853SAndroid Build Coastguard Worker 
1061*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1062*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1063*495ae853SAndroid Build Coastguard Worker 
1064*495ae853SAndroid Build Coastguard Worker             /* intra_chroma_pred_mode */
1065*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1066*495ae853SAndroid Build Coastguard Worker 
1067*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
1068*495ae853SAndroid Build Coastguard Worker         }
1069*495ae853SAndroid Build Coastguard Worker         else if(mb_type == I4x4)
1070*495ae853SAndroid Build Coastguard Worker         {
1071*495ae853SAndroid Build Coastguard Worker             isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
1072*495ae853SAndroid Build Coastguard Worker                 (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
1073*495ae853SAndroid Build Coastguard Worker 
1074*495ae853SAndroid Build Coastguard Worker             /* mb sub blk modes */
1075*495ae853SAndroid Build Coastguard Worker             WORD32 intra_pred_mode_flag, rem_intra_mode;
1076*495ae853SAndroid Build Coastguard Worker             WORD32 byte;
1077*495ae853SAndroid Build Coastguard Worker 
1078*495ae853SAndroid Build Coastguard Worker             chroma_intra_mode = (mb_tpm >> 6);
1079*495ae853SAndroid Build Coastguard Worker 
1080*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1081*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, 0, error_status, "mb type");
1082*495ae853SAndroid Build Coastguard Worker 
1083*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < 16; i += 2)
1084*495ae853SAndroid Build Coastguard Worker             {
1085*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 1 */
1086*495ae853SAndroid Build Coastguard Worker                 byte = ps_mb_hdr_i4x4->au1_sub_blk_modes[i >> 1];
1087*495ae853SAndroid Build Coastguard Worker 
1088*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1089*495ae853SAndroid Build Coastguard Worker 
1090*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1091*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1092*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1093*495ae853SAndroid Build Coastguard Worker 
1094*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1095*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1096*495ae853SAndroid Build Coastguard Worker                 {
1097*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1098*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1099*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1100*495ae853SAndroid Build Coastguard Worker                 }
1101*495ae853SAndroid Build Coastguard Worker 
1102*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 2 */
1103*495ae853SAndroid Build Coastguard Worker                 byte >>= 4;
1104*495ae853SAndroid Build Coastguard Worker 
1105*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1106*495ae853SAndroid Build Coastguard Worker 
1107*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1108*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1109*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1110*495ae853SAndroid Build Coastguard Worker 
1111*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1112*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1113*495ae853SAndroid Build Coastguard Worker                 {
1114*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1115*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1116*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1117*495ae853SAndroid Build Coastguard Worker                 }
1118*495ae853SAndroid Build Coastguard Worker             }
1119*495ae853SAndroid Build Coastguard Worker 
1120*495ae853SAndroid Build Coastguard Worker             /* intra_chroma_pred_mode */
1121*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1122*495ae853SAndroid Build Coastguard Worker 
1123*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
1124*495ae853SAndroid Build Coastguard Worker         }
1125*495ae853SAndroid Build Coastguard Worker         else if(mb_type == I8x8)
1126*495ae853SAndroid Build Coastguard Worker         {
1127*495ae853SAndroid Build Coastguard Worker             /* transform 8x8 flag */
1128*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1129*495ae853SAndroid Build Coastguard Worker             isvce_mb_hdr_i8x8_t *ps_mb_hdr_i8x8 =
1130*495ae853SAndroid Build Coastguard Worker                 (isvce_mb_hdr_i8x8_t *) ps_ent_ctxt->pv_mb_header_data;
1131*495ae853SAndroid Build Coastguard Worker 
1132*495ae853SAndroid Build Coastguard Worker             /* mb sub blk modes */
1133*495ae853SAndroid Build Coastguard Worker             WORD32 intra_pred_mode_flag, rem_intra_mode;
1134*495ae853SAndroid Build Coastguard Worker             WORD32 byte;
1135*495ae853SAndroid Build Coastguard Worker 
1136*495ae853SAndroid Build Coastguard Worker             chroma_intra_mode = (mb_tpm >> 6);
1137*495ae853SAndroid Build Coastguard Worker 
1138*495ae853SAndroid Build Coastguard Worker             ASSERT(0);
1139*495ae853SAndroid Build Coastguard Worker 
1140*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1141*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, 0, error_status, "mb type");
1142*495ae853SAndroid Build Coastguard Worker 
1143*495ae853SAndroid Build Coastguard Worker             /* u4_transform_size_8x8_flag */
1144*495ae853SAndroid Build Coastguard Worker             PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status,
1145*495ae853SAndroid Build Coastguard Worker                      "u4_transform_size_8x8_flag");
1146*495ae853SAndroid Build Coastguard Worker 
1147*495ae853SAndroid Build Coastguard Worker             /* write sub block modes */
1148*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < 4; i++)
1149*495ae853SAndroid Build Coastguard Worker             {
1150*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 1 */
1151*495ae853SAndroid Build Coastguard Worker                 byte = ps_mb_hdr_i8x8->au1_sub_blk_modes[i >> 1];
1152*495ae853SAndroid Build Coastguard Worker 
1153*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1154*495ae853SAndroid Build Coastguard Worker 
1155*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1156*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1157*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1158*495ae853SAndroid Build Coastguard Worker 
1159*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1160*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1161*495ae853SAndroid Build Coastguard Worker                 {
1162*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1163*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1164*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1165*495ae853SAndroid Build Coastguard Worker                 }
1166*495ae853SAndroid Build Coastguard Worker 
1167*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 2 */
1168*495ae853SAndroid Build Coastguard Worker                 byte >>= 4;
1169*495ae853SAndroid Build Coastguard Worker 
1170*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1171*495ae853SAndroid Build Coastguard Worker 
1172*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1173*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1174*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1175*495ae853SAndroid Build Coastguard Worker 
1176*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1177*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1178*495ae853SAndroid Build Coastguard Worker                 {
1179*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1180*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1181*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1182*495ae853SAndroid Build Coastguard Worker                 }
1183*495ae853SAndroid Build Coastguard Worker             }
1184*495ae853SAndroid Build Coastguard Worker 
1185*495ae853SAndroid Build Coastguard Worker             /* intra_chroma_pred_mode */
1186*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1187*495ae853SAndroid Build Coastguard Worker 
1188*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_i8x8_t);
1189*495ae853SAndroid Build Coastguard Worker         }
1190*495ae853SAndroid Build Coastguard Worker     }
1191*495ae853SAndroid Build Coastguard Worker     else
1192*495ae853SAndroid Build Coastguard Worker     {
1193*495ae853SAndroid Build Coastguard Worker         pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
1194*495ae853SAndroid Build Coastguard Worker     }
1195*495ae853SAndroid Build Coastguard Worker 
1196*495ae853SAndroid Build Coastguard Worker     /* coded_block_pattern */
1197*495ae853SAndroid Build Coastguard Worker     if(ps_mb_hdr->u1_base_mode_flag || mb_type != I16x16)
1198*495ae853SAndroid Build Coastguard Worker     {
1199*495ae853SAndroid Build Coastguard Worker         PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][ps_mb_hdr->u1_base_mode_flag],
1200*495ae853SAndroid Build Coastguard Worker                      error_status, "coded_block_pattern");
1201*495ae853SAndroid Build Coastguard Worker 
1202*495ae853SAndroid Build Coastguard Worker         if(cbp % 16 > 0 && ps_ent_ctxt->i1_transform_8x8_mode_flag &&
1203*495ae853SAndroid Build Coastguard Worker            (ps_mb_hdr->u1_base_mode_flag || (mb_type == I8x8 || mb_type == I4x4)))
1204*495ae853SAndroid Build Coastguard Worker         {
1205*495ae853SAndroid Build Coastguard Worker             PUT_BITS(ps_bitstream, ps_ent_ctxt->i1_transform_8x8_mode_flag, 1, error_status,
1206*495ae853SAndroid Build Coastguard Worker                      "u4_transform_size_8x8_flag");
1207*495ae853SAndroid Build Coastguard Worker         }
1208*495ae853SAndroid Build Coastguard Worker     }
1209*495ae853SAndroid Build Coastguard Worker 
1210*495ae853SAndroid Build Coastguard Worker     if((cbp > 0) || (mb_type == I16x16))
1211*495ae853SAndroid Build Coastguard Worker     {
1212*495ae853SAndroid Build Coastguard Worker         /* mb_qp_delta */
1213*495ae853SAndroid Build Coastguard Worker         PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
1214*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
1215*495ae853SAndroid Build Coastguard Worker     }
1216*495ae853SAndroid Build Coastguard Worker 
1217*495ae853SAndroid Build Coastguard Worker     /* Ending bitstream offset for header in bits */
1218*495ae853SAndroid Build Coastguard Worker     bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1219*495ae853SAndroid Build Coastguard Worker 
1220*495ae853SAndroid Build Coastguard Worker     ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset - bitstream_start_offset;
1221*495ae853SAndroid Build Coastguard Worker 
1222*495ae853SAndroid Build Coastguard Worker     /* Starting bitstream offset for residue */
1223*495ae853SAndroid Build Coastguard Worker     bitstream_start_offset = bitstream_end_offset;
1224*495ae853SAndroid Build Coastguard Worker 
1225*495ae853SAndroid Build Coastguard Worker     /* residual */
1226*495ae853SAndroid Build Coastguard Worker     error_status = isvce_encode_residue(ps_ent_ctxt, mb_type, cbp);
1227*495ae853SAndroid Build Coastguard Worker 
1228*495ae853SAndroid Build Coastguard Worker     /* Ending bitstream offset for reside in bits */
1229*495ae853SAndroid Build Coastguard Worker     bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1230*495ae853SAndroid Build Coastguard Worker     ps_ent_ctxt->u4_residue_bits[0] += bitstream_end_offset - bitstream_start_offset;
1231*495ae853SAndroid Build Coastguard Worker 
1232*495ae853SAndroid Build Coastguard Worker     /* store the index of the next mb syntax layer */
1233*495ae853SAndroid Build Coastguard Worker     ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1234*495ae853SAndroid Build Coastguard Worker 
1235*495ae853SAndroid Build Coastguard Worker     return error_status;
1236*495ae853SAndroid Build Coastguard Worker }
1237*495ae853SAndroid Build Coastguard Worker 
1238*495ae853SAndroid Build Coastguard Worker /**
1239*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1240*495ae853SAndroid Build Coastguard Worker *
1241*495ae853SAndroid Build Coastguard Worker * @brief
1242*495ae853SAndroid Build Coastguard Worker *  This function generates CAVLC coded bit stream for Inter slices
1243*495ae853SAndroid Build Coastguard Worker *
1244*495ae853SAndroid Build Coastguard Worker * @description
1245*495ae853SAndroid Build Coastguard Worker *  The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
1246*495ae853SAndroid Build Coastguard Worker *  (if present), mb qp delta, coded block pattern, chroma mb mode and
1247*495ae853SAndroid Build Coastguard Worker *  luma/chroma residue. These syntax elements are written as directed by table
1248*495ae853SAndroid Build Coastguard Worker *  7.3.5 of h264 specification
1249*495ae853SAndroid Build Coastguard Worker *
1250*495ae853SAndroid Build Coastguard Worker * @param[in] ps_ent_ctxt
1251*495ae853SAndroid Build Coastguard Worker *  pointer to entropy context
1252*495ae853SAndroid Build Coastguard Worker *
1253*495ae853SAndroid Build Coastguard Worker * @returns error code
1254*495ae853SAndroid Build Coastguard Worker *
1255*495ae853SAndroid Build Coastguard Worker * @remarks none
1256*495ae853SAndroid Build Coastguard Worker *
1257*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1258*495ae853SAndroid Build Coastguard Worker */
isvce_write_pslice_mb_cavlc(isvce_entropy_ctxt_t * ps_ent_ctxt)1259*495ae853SAndroid Build Coastguard Worker IH264E_ERROR_T isvce_write_pslice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt)
1260*495ae853SAndroid Build Coastguard Worker {
1261*495ae853SAndroid Build Coastguard Worker     /* mb header info */
1262*495ae853SAndroid Build Coastguard Worker     /*
1263*495ae853SAndroid Build Coastguard Worker      * mb_tpm : mb type plus mode
1264*495ae853SAndroid Build Coastguard Worker      * mb_type : luma mb type and chroma mb type are packed
1265*495ae853SAndroid Build Coastguard Worker      * cbp : coded block pattern
1266*495ae853SAndroid Build Coastguard Worker      * mb_qp_delta : mb qp delta
1267*495ae853SAndroid Build Coastguard Worker      * chroma_intra_mode : chroma intra mode
1268*495ae853SAndroid Build Coastguard Worker      * luma_intra_mode : luma intra mode
1269*495ae853SAndroid Build Coastguard Worker      * ps_pu :  Pointer to the array of structures having motion vectors, size
1270*495ae853SAndroid Build Coastguard Worker      * and position of sub partitions
1271*495ae853SAndroid Build Coastguard Worker      */
1272*495ae853SAndroid Build Coastguard Worker     WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
1273*495ae853SAndroid Build Coastguard Worker     WORD8 mb_qp_delta;
1274*495ae853SAndroid Build Coastguard Worker     WORD32 i, mb_type_stream;
1275*495ae853SAndroid Build Coastguard Worker     WORD32 bitstream_start_offset, bitstream_end_offset;
1276*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_is_intra_mb;
1277*495ae853SAndroid Build Coastguard Worker 
1278*495ae853SAndroid Build Coastguard Worker     bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
1279*495ae853SAndroid Build Coastguard Worker     isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
1280*495ae853SAndroid Build Coastguard Worker     svc_slice_header_t *ps_svc_slice_header =
1281*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->ps_svc_slice_hdr_base +
1282*495ae853SAndroid Build Coastguard Worker         (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
1283*495ae853SAndroid Build Coastguard Worker 
1284*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T error_status = IH264E_SUCCESS;
1285*495ae853SAndroid Build Coastguard Worker 
1286*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
1287*495ae853SAndroid Build Coastguard Worker     WORD32 cbptable = 1;
1288*495ae853SAndroid Build Coastguard Worker     WORD32 is_inter = 0;
1289*495ae853SAndroid Build Coastguard Worker 
1290*495ae853SAndroid Build Coastguard Worker     /* Starting bitstream offset for header in bits */
1291*495ae853SAndroid Build Coastguard Worker     bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
1292*495ae853SAndroid Build Coastguard Worker 
1293*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1294*495ae853SAndroid Build Coastguard Worker     /*                    BEGIN HEADER GENERATION                       */
1295*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1296*495ae853SAndroid Build Coastguard Worker 
1297*495ae853SAndroid Build Coastguard Worker     /* mb header info */
1298*495ae853SAndroid Build Coastguard Worker     mb_tpm = ps_mb_hdr->u1_mb_type_mode;
1299*495ae853SAndroid Build Coastguard Worker 
1300*495ae853SAndroid Build Coastguard Worker     /* mb type */
1301*495ae853SAndroid Build Coastguard Worker     mb_type = mb_tpm & 0xF;
1302*495ae853SAndroid Build Coastguard Worker     u1_is_intra_mb = (mb_type == I16x16) || (mb_type == I8x8) || (mb_type == I4x4);
1303*495ae853SAndroid Build Coastguard Worker 
1304*495ae853SAndroid Build Coastguard Worker     /* check for skip */
1305*495ae853SAndroid Build Coastguard Worker     if(mb_type == PSKIP)
1306*495ae853SAndroid Build Coastguard Worker     {
1307*495ae853SAndroid Build Coastguard Worker         UWORD32 *nnz;
1308*495ae853SAndroid Build Coastguard Worker 
1309*495ae853SAndroid Build Coastguard Worker         is_inter = 1;
1310*495ae853SAndroid Build Coastguard Worker 
1311*495ae853SAndroid Build Coastguard Worker         /* increment skip counter */
1312*495ae853SAndroid Build Coastguard Worker         (*ps_ent_ctxt->pi4_mb_skip_run)++;
1313*495ae853SAndroid Build Coastguard Worker 
1314*495ae853SAndroid Build Coastguard Worker         /* store the index of the next mb syntax layer */
1315*495ae853SAndroid Build Coastguard Worker         pu1_byte += sizeof(isvce_mb_hdr_pskip_t);
1316*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1317*495ae853SAndroid Build Coastguard Worker 
1318*495ae853SAndroid Build Coastguard Worker         /* set nnz to zero */
1319*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->u4_left_nnz_luma = 0;
1320*495ae853SAndroid Build Coastguard Worker         nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
1321*495ae853SAndroid Build Coastguard Worker         *nnz = 0;
1322*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->u4_left_nnz_cbcr = 0;
1323*495ae853SAndroid Build Coastguard Worker         nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
1324*495ae853SAndroid Build Coastguard Worker         *nnz = 0;
1325*495ae853SAndroid Build Coastguard Worker 
1326*495ae853SAndroid Build Coastguard Worker         /* residual */
1327*495ae853SAndroid Build Coastguard Worker         error_status = isvce_encode_residue(ps_ent_ctxt, P16x16, 0);
1328*495ae853SAndroid Build Coastguard Worker 
1329*495ae853SAndroid Build Coastguard Worker         bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1330*495ae853SAndroid Build Coastguard Worker 
1331*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1332*495ae853SAndroid Build Coastguard Worker 
1333*495ae853SAndroid Build Coastguard Worker         return error_status;
1334*495ae853SAndroid Build Coastguard Worker     }
1335*495ae853SAndroid Build Coastguard Worker 
1336*495ae853SAndroid Build Coastguard Worker     /* remaining mb header info */
1337*495ae853SAndroid Build Coastguard Worker     cbp = ps_mb_hdr->u1_cbp;
1338*495ae853SAndroid Build Coastguard Worker     mb_qp_delta =
1339*495ae853SAndroid Build Coastguard Worker         ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
1340*495ae853SAndroid Build Coastguard Worker 
1341*495ae853SAndroid Build Coastguard Worker     /* mb skip run */
1342*495ae853SAndroid Build Coastguard Worker     PUT_BITS_UEV(ps_bitstream, *ps_ent_ctxt->pi4_mb_skip_run, error_status, "mb skip run");
1343*495ae853SAndroid Build Coastguard Worker 
1344*495ae853SAndroid Build Coastguard Worker     /* reset skip counter */
1345*495ae853SAndroid Build Coastguard Worker     *ps_ent_ctxt->pi4_mb_skip_run = 0;
1346*495ae853SAndroid Build Coastguard Worker 
1347*495ae853SAndroid Build Coastguard Worker     if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
1348*495ae853SAndroid Build Coastguard Worker     {
1349*495ae853SAndroid Build Coastguard Worker         /* write base_mode_flag */
1350*495ae853SAndroid Build Coastguard Worker         PUT_BITS(ps_bitstream, ps_mb_hdr->u1_base_mode_flag, 1, error_status, "base_mode_flag");
1351*495ae853SAndroid Build Coastguard Worker     }
1352*495ae853SAndroid Build Coastguard Worker     else
1353*495ae853SAndroid Build Coastguard Worker     {
1354*495ae853SAndroid Build Coastguard Worker         ps_mb_hdr->u1_base_mode_flag = 0;
1355*495ae853SAndroid Build Coastguard Worker     }
1356*495ae853SAndroid Build Coastguard Worker 
1357*495ae853SAndroid Build Coastguard Worker     if(!ps_mb_hdr->u1_base_mode_flag)
1358*495ae853SAndroid Build Coastguard Worker     {
1359*495ae853SAndroid Build Coastguard Worker         /* is intra ? */
1360*495ae853SAndroid Build Coastguard Worker         if(mb_type == I16x16)
1361*495ae853SAndroid Build Coastguard Worker         {
1362*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_cbp_l, u4_cbp_c;
1363*495ae853SAndroid Build Coastguard Worker 
1364*495ae853SAndroid Build Coastguard Worker             is_inter = 0;
1365*495ae853SAndroid Build Coastguard Worker 
1366*495ae853SAndroid Build Coastguard Worker             u4_cbp_c = (cbp >> 4);
1367*495ae853SAndroid Build Coastguard Worker             u4_cbp_l = (cbp & 0xF);
1368*495ae853SAndroid Build Coastguard Worker             luma_intra_mode = (mb_tpm >> 4) & 3;
1369*495ae853SAndroid Build Coastguard Worker             chroma_intra_mode = (mb_tpm >> 6);
1370*495ae853SAndroid Build Coastguard Worker 
1371*495ae853SAndroid Build Coastguard Worker             mb_type_stream = luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1372*495ae853SAndroid Build Coastguard Worker 
1373*495ae853SAndroid Build Coastguard Worker             mb_type_stream += 5;
1374*495ae853SAndroid Build Coastguard Worker 
1375*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1376*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1377*495ae853SAndroid Build Coastguard Worker 
1378*495ae853SAndroid Build Coastguard Worker             /* intra_chroma_pred_mode */
1379*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1380*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
1381*495ae853SAndroid Build Coastguard Worker         }
1382*495ae853SAndroid Build Coastguard Worker         else if(mb_type == I4x4)
1383*495ae853SAndroid Build Coastguard Worker         {
1384*495ae853SAndroid Build Coastguard Worker             isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
1385*495ae853SAndroid Build Coastguard Worker                 (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
1386*495ae853SAndroid Build Coastguard Worker 
1387*495ae853SAndroid Build Coastguard Worker             /* mb sub blk modes */
1388*495ae853SAndroid Build Coastguard Worker             WORD32 intra_pred_mode_flag, rem_intra_mode;
1389*495ae853SAndroid Build Coastguard Worker             WORD32 byte;
1390*495ae853SAndroid Build Coastguard Worker 
1391*495ae853SAndroid Build Coastguard Worker             is_inter = 0;
1392*495ae853SAndroid Build Coastguard Worker 
1393*495ae853SAndroid Build Coastguard Worker             chroma_intra_mode = (mb_tpm >> 6);
1394*495ae853SAndroid Build Coastguard Worker             cbptable = 0;
1395*495ae853SAndroid Build Coastguard Worker 
1396*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1397*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, 5, error_status, "mb type");
1398*495ae853SAndroid Build Coastguard Worker 
1399*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < 16; i += 2)
1400*495ae853SAndroid Build Coastguard Worker             {
1401*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 1 */
1402*495ae853SAndroid Build Coastguard Worker                 byte = ps_mb_hdr_i4x4->au1_sub_blk_modes[i >> 1];
1403*495ae853SAndroid Build Coastguard Worker 
1404*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1405*495ae853SAndroid Build Coastguard Worker 
1406*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1407*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1408*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1409*495ae853SAndroid Build Coastguard Worker 
1410*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1411*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1412*495ae853SAndroid Build Coastguard Worker                 {
1413*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1414*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1415*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1416*495ae853SAndroid Build Coastguard Worker                 }
1417*495ae853SAndroid Build Coastguard Worker 
1418*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 2 */
1419*495ae853SAndroid Build Coastguard Worker                 byte >>= 4;
1420*495ae853SAndroid Build Coastguard Worker 
1421*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1422*495ae853SAndroid Build Coastguard Worker 
1423*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1424*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1425*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1426*495ae853SAndroid Build Coastguard Worker 
1427*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1428*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1429*495ae853SAndroid Build Coastguard Worker                 {
1430*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1431*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1432*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1433*495ae853SAndroid Build Coastguard Worker                 }
1434*495ae853SAndroid Build Coastguard Worker             }
1435*495ae853SAndroid Build Coastguard Worker 
1436*495ae853SAndroid Build Coastguard Worker             /* intra_chroma_pred_mode */
1437*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1438*495ae853SAndroid Build Coastguard Worker 
1439*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
1440*495ae853SAndroid Build Coastguard Worker         }
1441*495ae853SAndroid Build Coastguard Worker         else if(mb_type == I8x8)
1442*495ae853SAndroid Build Coastguard Worker         {
1443*495ae853SAndroid Build Coastguard Worker             isvce_mb_hdr_i8x8_t *ps_mb_hdr_i8x8 =
1444*495ae853SAndroid Build Coastguard Worker                 (isvce_mb_hdr_i8x8_t *) ps_ent_ctxt->pv_mb_header_data;
1445*495ae853SAndroid Build Coastguard Worker 
1446*495ae853SAndroid Build Coastguard Worker             /* transform 8x8 flag */
1447*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1448*495ae853SAndroid Build Coastguard Worker 
1449*495ae853SAndroid Build Coastguard Worker             /* mb sub blk modes */
1450*495ae853SAndroid Build Coastguard Worker             WORD32 intra_pred_mode_flag, rem_intra_mode;
1451*495ae853SAndroid Build Coastguard Worker             WORD32 byte;
1452*495ae853SAndroid Build Coastguard Worker 
1453*495ae853SAndroid Build Coastguard Worker             is_inter = 0;
1454*495ae853SAndroid Build Coastguard Worker 
1455*495ae853SAndroid Build Coastguard Worker             chroma_intra_mode = (mb_tpm >> 6);
1456*495ae853SAndroid Build Coastguard Worker             cbptable = 0;
1457*495ae853SAndroid Build Coastguard Worker 
1458*495ae853SAndroid Build Coastguard Worker             ASSERT(0);
1459*495ae853SAndroid Build Coastguard Worker 
1460*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1461*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, 5, error_status, "mb type");
1462*495ae853SAndroid Build Coastguard Worker 
1463*495ae853SAndroid Build Coastguard Worker             /* u4_transform_size_8x8_flag */
1464*495ae853SAndroid Build Coastguard Worker             PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status,
1465*495ae853SAndroid Build Coastguard Worker                      "u4_transform_size_8x8_flag");
1466*495ae853SAndroid Build Coastguard Worker 
1467*495ae853SAndroid Build Coastguard Worker             /* write sub block modes */
1468*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < 4; i++)
1469*495ae853SAndroid Build Coastguard Worker             {
1470*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 1 */
1471*495ae853SAndroid Build Coastguard Worker                 byte = ps_mb_hdr_i8x8->au1_sub_blk_modes[i >> 1];
1472*495ae853SAndroid Build Coastguard Worker 
1473*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1474*495ae853SAndroid Build Coastguard Worker 
1475*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1476*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1477*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1478*495ae853SAndroid Build Coastguard Worker 
1479*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1480*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1481*495ae853SAndroid Build Coastguard Worker                 {
1482*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1483*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1484*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1485*495ae853SAndroid Build Coastguard Worker                 }
1486*495ae853SAndroid Build Coastguard Worker 
1487*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 2 */
1488*495ae853SAndroid Build Coastguard Worker                 byte >>= 4;
1489*495ae853SAndroid Build Coastguard Worker 
1490*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1491*495ae853SAndroid Build Coastguard Worker 
1492*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1493*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1494*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1495*495ae853SAndroid Build Coastguard Worker 
1496*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1497*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1498*495ae853SAndroid Build Coastguard Worker                 {
1499*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1500*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1501*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1502*495ae853SAndroid Build Coastguard Worker                 }
1503*495ae853SAndroid Build Coastguard Worker             }
1504*495ae853SAndroid Build Coastguard Worker 
1505*495ae853SAndroid Build Coastguard Worker             /* intra_chroma_pred_mode */
1506*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1507*495ae853SAndroid Build Coastguard Worker 
1508*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_i8x8_t);
1509*495ae853SAndroid Build Coastguard Worker         }
1510*495ae853SAndroid Build Coastguard Worker         else
1511*495ae853SAndroid Build Coastguard Worker         {
1512*495ae853SAndroid Build Coastguard Worker             isvce_mb_hdr_p16x16_t *ps_mb_hdr_p16x16 =
1513*495ae853SAndroid Build Coastguard Worker                 (isvce_mb_hdr_p16x16_t *) ps_ent_ctxt->pv_mb_header_data;
1514*495ae853SAndroid Build Coastguard Worker 
1515*495ae853SAndroid Build Coastguard Worker             /* inter macro block partition cnt */
1516*495ae853SAndroid Build Coastguard Worker             const UWORD8 au1_part_cnt[] = {1, 2, 2, 4};
1517*495ae853SAndroid Build Coastguard Worker 
1518*495ae853SAndroid Build Coastguard Worker             /* mv ptr */
1519*495ae853SAndroid Build Coastguard Worker             WORD16 *pi2_mv_ptr = (WORD16 *) ps_mb_hdr_p16x16->ai2_mvd;
1520*495ae853SAndroid Build Coastguard Worker 
1521*495ae853SAndroid Build Coastguard Worker             /* number of partitions for the current mb */
1522*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_part_cnt = au1_part_cnt[mb_type - 3];
1523*495ae853SAndroid Build Coastguard Worker 
1524*495ae853SAndroid Build Coastguard Worker             is_inter = 1;
1525*495ae853SAndroid Build Coastguard Worker 
1526*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1527*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, mb_type - 3, error_status, "mb type");
1528*495ae853SAndroid Build Coastguard Worker 
1529*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < (WORD32) u4_part_cnt; i++)
1530*495ae853SAndroid Build Coastguard Worker             {
1531*495ae853SAndroid Build Coastguard Worker                 if(ps_ent_ctxt->u1_spatial_layer_id &&
1532*495ae853SAndroid Build Coastguard Worker                    ps_svc_slice_header->i1_adaptive_motion_prediction_flag)
1533*495ae853SAndroid Build Coastguard Worker                 {
1534*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, ps_mb_hdr_p16x16->u1_mvp_idx, 1, error_status,
1535*495ae853SAndroid Build Coastguard Worker                              "motion_prediction_flag_l0");
1536*495ae853SAndroid Build Coastguard Worker                 }
1537*495ae853SAndroid Build Coastguard Worker             }
1538*495ae853SAndroid Build Coastguard Worker 
1539*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < (WORD32) u4_part_cnt; i++)
1540*495ae853SAndroid Build Coastguard Worker             {
1541*495ae853SAndroid Build Coastguard Worker                 PUT_BITS_SEV(ps_bitstream, pi2_mv_ptr[i], error_status, "mv x");
1542*495ae853SAndroid Build Coastguard Worker                 PUT_BITS_SEV(ps_bitstream, pi2_mv_ptr[i + 1], error_status, "mv y");
1543*495ae853SAndroid Build Coastguard Worker             }
1544*495ae853SAndroid Build Coastguard Worker 
1545*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_p16x16_t);
1546*495ae853SAndroid Build Coastguard Worker         }
1547*495ae853SAndroid Build Coastguard Worker     }
1548*495ae853SAndroid Build Coastguard Worker     else
1549*495ae853SAndroid Build Coastguard Worker     {
1550*495ae853SAndroid Build Coastguard Worker         pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
1551*495ae853SAndroid Build Coastguard Worker     }
1552*495ae853SAndroid Build Coastguard Worker 
1553*495ae853SAndroid Build Coastguard Worker     if(ps_ent_ctxt->u1_spatial_layer_id &&
1554*495ae853SAndroid Build Coastguard Worker        ps_svc_slice_header->i1_adaptive_residual_prediction_flag &&
1555*495ae853SAndroid Build Coastguard Worker        !ps_ent_ctxt
1556*495ae853SAndroid Build Coastguard Worker             ->ps_svc_nalu_ext_base[1 + (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT)]
1557*495ae853SAndroid Build Coastguard Worker             .u1_idr_flag &&
1558*495ae853SAndroid Build Coastguard Worker        (ps_mb_hdr->u1_base_mode_flag || !u1_is_intra_mb))
1559*495ae853SAndroid Build Coastguard Worker     {
1560*495ae853SAndroid Build Coastguard Worker         PUT_BITS(ps_bitstream, ps_mb_hdr->u1_residual_prediction_flag, 1, error_status,
1561*495ae853SAndroid Build Coastguard Worker                  "residual_prediction_flag");
1562*495ae853SAndroid Build Coastguard Worker     }
1563*495ae853SAndroid Build Coastguard Worker 
1564*495ae853SAndroid Build Coastguard Worker     /* coded_block_pattern */
1565*495ae853SAndroid Build Coastguard Worker     if(ps_mb_hdr->u1_base_mode_flag || (mb_type != I16x16))
1566*495ae853SAndroid Build Coastguard Worker     {
1567*495ae853SAndroid Build Coastguard Worker         PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][cbptable], error_status,
1568*495ae853SAndroid Build Coastguard Worker                      "coded_block_pattern");
1569*495ae853SAndroid Build Coastguard Worker     }
1570*495ae853SAndroid Build Coastguard Worker 
1571*495ae853SAndroid Build Coastguard Worker     if((cbp > 0) || (mb_type == I16x16))
1572*495ae853SAndroid Build Coastguard Worker     {
1573*495ae853SAndroid Build Coastguard Worker         /* mb_qp_delta */
1574*495ae853SAndroid Build Coastguard Worker         PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
1575*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
1576*495ae853SAndroid Build Coastguard Worker     }
1577*495ae853SAndroid Build Coastguard Worker 
1578*495ae853SAndroid Build Coastguard Worker     /* Ending bitstream offset for header in bits */
1579*495ae853SAndroid Build Coastguard Worker     bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1580*495ae853SAndroid Build Coastguard Worker 
1581*495ae853SAndroid Build Coastguard Worker     ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1582*495ae853SAndroid Build Coastguard Worker 
1583*495ae853SAndroid Build Coastguard Worker     /* start bitstream offset for residue in bits */
1584*495ae853SAndroid Build Coastguard Worker     bitstream_start_offset = bitstream_end_offset;
1585*495ae853SAndroid Build Coastguard Worker 
1586*495ae853SAndroid Build Coastguard Worker     /* residual */
1587*495ae853SAndroid Build Coastguard Worker     error_status = isvce_encode_residue(ps_ent_ctxt, mb_type, cbp);
1588*495ae853SAndroid Build Coastguard Worker 
1589*495ae853SAndroid Build Coastguard Worker     /* Ending bitstream offset for residue in bits */
1590*495ae853SAndroid Build Coastguard Worker     bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1591*495ae853SAndroid Build Coastguard Worker 
1592*495ae853SAndroid Build Coastguard Worker     ps_ent_ctxt->u4_residue_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1593*495ae853SAndroid Build Coastguard Worker 
1594*495ae853SAndroid Build Coastguard Worker     /* store the index of the next mb syntax layer */
1595*495ae853SAndroid Build Coastguard Worker     ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1596*495ae853SAndroid Build Coastguard Worker 
1597*495ae853SAndroid Build Coastguard Worker     return error_status;
1598*495ae853SAndroid Build Coastguard Worker }
1599*495ae853SAndroid Build Coastguard Worker 
1600*495ae853SAndroid Build Coastguard Worker /**
1601*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1602*495ae853SAndroid Build Coastguard Worker *
1603*495ae853SAndroid Build Coastguard Worker * @brief
1604*495ae853SAndroid Build Coastguard Worker *  This function generates CAVLC coded bit stream for B slices
1605*495ae853SAndroid Build Coastguard Worker *
1606*495ae853SAndroid Build Coastguard Worker * @description
1607*495ae853SAndroid Build Coastguard Worker *  The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
1608*495ae853SAndroid Build Coastguard Worker *  (if present), mb qp delta, coded block pattern, chroma mb mode and
1609*495ae853SAndroid Build Coastguard Worker *  luma/chroma residue. These syntax elements are written as directed by table
1610*495ae853SAndroid Build Coastguard Worker *  7.3.5 of h264 specification
1611*495ae853SAndroid Build Coastguard Worker *
1612*495ae853SAndroid Build Coastguard Worker * @param[in] ps_ent_ctxt
1613*495ae853SAndroid Build Coastguard Worker *  pointer to entropy context
1614*495ae853SAndroid Build Coastguard Worker *
1615*495ae853SAndroid Build Coastguard Worker * @returns error code
1616*495ae853SAndroid Build Coastguard Worker *
1617*495ae853SAndroid Build Coastguard Worker * @remarks none
1618*495ae853SAndroid Build Coastguard Worker *
1619*495ae853SAndroid Build Coastguard Worker *******************************************************************************
1620*495ae853SAndroid Build Coastguard Worker */
isvce_write_bslice_mb_cavlc(isvce_entropy_ctxt_t * ps_ent_ctxt)1621*495ae853SAndroid Build Coastguard Worker IH264E_ERROR_T isvce_write_bslice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt)
1622*495ae853SAndroid Build Coastguard Worker {
1623*495ae853SAndroid Build Coastguard Worker     /* mb header info */
1624*495ae853SAndroid Build Coastguard Worker     /*
1625*495ae853SAndroid Build Coastguard Worker      * mb_tpm : mb type plus mode
1626*495ae853SAndroid Build Coastguard Worker      * mb_type : luma mb type and chroma mb type are packed
1627*495ae853SAndroid Build Coastguard Worker      * cbp : coded block pattern
1628*495ae853SAndroid Build Coastguard Worker      * mb_qp_delta : mb qp delta
1629*495ae853SAndroid Build Coastguard Worker      * chroma_intra_mode : chroma intra mode
1630*495ae853SAndroid Build Coastguard Worker      * luma_intra_mode : luma intra mode
1631*495ae853SAndroid Build Coastguard Worker      * ps_pu :  Pointer to the array of structures having motion vectors, size
1632*495ae853SAndroid Build Coastguard Worker      * and position of sub partitions
1633*495ae853SAndroid Build Coastguard Worker      */
1634*495ae853SAndroid Build Coastguard Worker     WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
1635*495ae853SAndroid Build Coastguard Worker     WORD8 mb_qp_delta;
1636*495ae853SAndroid Build Coastguard Worker     WORD32 i, j;
1637*495ae853SAndroid Build Coastguard Worker     WORD32 mb_type_stream;
1638*495ae853SAndroid Build Coastguard Worker     WORD32 bitstream_start_offset, bitstream_end_offset;
1639*495ae853SAndroid Build Coastguard Worker     UWORD8 u1_is_intra_mb;
1640*495ae853SAndroid Build Coastguard Worker 
1641*495ae853SAndroid Build Coastguard Worker     bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
1642*495ae853SAndroid Build Coastguard Worker     isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
1643*495ae853SAndroid Build Coastguard Worker     svc_slice_header_t *ps_svc_slice_header =
1644*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->ps_svc_slice_hdr_base +
1645*495ae853SAndroid Build Coastguard Worker         (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
1646*495ae853SAndroid Build Coastguard Worker 
1647*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T error_status = IH264E_SUCCESS;
1648*495ae853SAndroid Build Coastguard Worker 
1649*495ae853SAndroid Build Coastguard Worker     UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
1650*495ae853SAndroid Build Coastguard Worker     WORD32 cbptable = 1;
1651*495ae853SAndroid Build Coastguard Worker     WORD32 is_inter = 0;
1652*495ae853SAndroid Build Coastguard Worker 
1653*495ae853SAndroid Build Coastguard Worker     /* Starting bitstream offset for header in bits */
1654*495ae853SAndroid Build Coastguard Worker     bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
1655*495ae853SAndroid Build Coastguard Worker 
1656*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1657*495ae853SAndroid Build Coastguard Worker     /*                    BEGIN HEADER GENERATION                       */
1658*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
1659*495ae853SAndroid Build Coastguard Worker 
1660*495ae853SAndroid Build Coastguard Worker     mb_tpm = ps_mb_hdr->u1_mb_type_mode;
1661*495ae853SAndroid Build Coastguard Worker 
1662*495ae853SAndroid Build Coastguard Worker     /* mb type */
1663*495ae853SAndroid Build Coastguard Worker     mb_type = mb_tpm & 0xF;
1664*495ae853SAndroid Build Coastguard Worker     u1_is_intra_mb = (mb_type == I16x16) || (mb_type == I8x8) || (mb_type == I4x4);
1665*495ae853SAndroid Build Coastguard Worker 
1666*495ae853SAndroid Build Coastguard Worker     /* check for skip */
1667*495ae853SAndroid Build Coastguard Worker     if(mb_type == BSKIP)
1668*495ae853SAndroid Build Coastguard Worker     {
1669*495ae853SAndroid Build Coastguard Worker         UWORD32 *nnz;
1670*495ae853SAndroid Build Coastguard Worker 
1671*495ae853SAndroid Build Coastguard Worker         is_inter = 1;
1672*495ae853SAndroid Build Coastguard Worker 
1673*495ae853SAndroid Build Coastguard Worker         /* increment skip counter */
1674*495ae853SAndroid Build Coastguard Worker         (*ps_ent_ctxt->pi4_mb_skip_run)++;
1675*495ae853SAndroid Build Coastguard Worker 
1676*495ae853SAndroid Build Coastguard Worker         /* store the index of the next mb syntax layer */
1677*495ae853SAndroid Build Coastguard Worker         pu1_byte += sizeof(isvce_mb_hdr_bskip_t);
1678*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1679*495ae853SAndroid Build Coastguard Worker 
1680*495ae853SAndroid Build Coastguard Worker         /* set nnz to zero */
1681*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->u4_left_nnz_luma = 0;
1682*495ae853SAndroid Build Coastguard Worker         nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
1683*495ae853SAndroid Build Coastguard Worker         *nnz = 0;
1684*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->u4_left_nnz_cbcr = 0;
1685*495ae853SAndroid Build Coastguard Worker         nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
1686*495ae853SAndroid Build Coastguard Worker         *nnz = 0;
1687*495ae853SAndroid Build Coastguard Worker 
1688*495ae853SAndroid Build Coastguard Worker         /* residual */
1689*495ae853SAndroid Build Coastguard Worker         error_status = isvce_encode_residue(ps_ent_ctxt, B16x16, 0);
1690*495ae853SAndroid Build Coastguard Worker 
1691*495ae853SAndroid Build Coastguard Worker         bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1692*495ae853SAndroid Build Coastguard Worker 
1693*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1694*495ae853SAndroid Build Coastguard Worker 
1695*495ae853SAndroid Build Coastguard Worker         return error_status;
1696*495ae853SAndroid Build Coastguard Worker     }
1697*495ae853SAndroid Build Coastguard Worker 
1698*495ae853SAndroid Build Coastguard Worker     /* remaining mb header info */
1699*495ae853SAndroid Build Coastguard Worker     cbp = ps_mb_hdr->u1_cbp;
1700*495ae853SAndroid Build Coastguard Worker     mb_qp_delta =
1701*495ae853SAndroid Build Coastguard Worker         ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
1702*495ae853SAndroid Build Coastguard Worker 
1703*495ae853SAndroid Build Coastguard Worker     /* mb skip run */
1704*495ae853SAndroid Build Coastguard Worker     PUT_BITS_UEV(ps_bitstream, *ps_ent_ctxt->pi4_mb_skip_run, error_status, "mb skip run");
1705*495ae853SAndroid Build Coastguard Worker 
1706*495ae853SAndroid Build Coastguard Worker     /* reset skip counter */
1707*495ae853SAndroid Build Coastguard Worker     *ps_ent_ctxt->pi4_mb_skip_run = 0;
1708*495ae853SAndroid Build Coastguard Worker 
1709*495ae853SAndroid Build Coastguard Worker     if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
1710*495ae853SAndroid Build Coastguard Worker     {
1711*495ae853SAndroid Build Coastguard Worker         /* write base_mode_flag */
1712*495ae853SAndroid Build Coastguard Worker         PUT_BITS(ps_bitstream, ps_mb_hdr->u1_base_mode_flag, 1, error_status, "base_mode_flag");
1713*495ae853SAndroid Build Coastguard Worker     }
1714*495ae853SAndroid Build Coastguard Worker     else
1715*495ae853SAndroid Build Coastguard Worker     {
1716*495ae853SAndroid Build Coastguard Worker         ps_mb_hdr->u1_base_mode_flag = 0;
1717*495ae853SAndroid Build Coastguard Worker     }
1718*495ae853SAndroid Build Coastguard Worker 
1719*495ae853SAndroid Build Coastguard Worker     if(!ps_mb_hdr->u1_base_mode_flag)
1720*495ae853SAndroid Build Coastguard Worker     {
1721*495ae853SAndroid Build Coastguard Worker         /* is intra ? */
1722*495ae853SAndroid Build Coastguard Worker         if(mb_type == I16x16)
1723*495ae853SAndroid Build Coastguard Worker         {
1724*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_cbp_l, u4_cbp_c;
1725*495ae853SAndroid Build Coastguard Worker 
1726*495ae853SAndroid Build Coastguard Worker             is_inter = 0;
1727*495ae853SAndroid Build Coastguard Worker 
1728*495ae853SAndroid Build Coastguard Worker             u4_cbp_c = (cbp >> 4);
1729*495ae853SAndroid Build Coastguard Worker             u4_cbp_l = (cbp & 0xF);
1730*495ae853SAndroid Build Coastguard Worker             luma_intra_mode = (mb_tpm >> 4) & 3;
1731*495ae853SAndroid Build Coastguard Worker             chroma_intra_mode = (mb_tpm >> 6);
1732*495ae853SAndroid Build Coastguard Worker 
1733*495ae853SAndroid Build Coastguard Worker             mb_type_stream = luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1734*495ae853SAndroid Build Coastguard Worker 
1735*495ae853SAndroid Build Coastguard Worker             mb_type_stream += 23;
1736*495ae853SAndroid Build Coastguard Worker 
1737*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1738*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1739*495ae853SAndroid Build Coastguard Worker 
1740*495ae853SAndroid Build Coastguard Worker             /* intra_chroma_pred_mode */
1741*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1742*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
1743*495ae853SAndroid Build Coastguard Worker         }
1744*495ae853SAndroid Build Coastguard Worker         else if(mb_type == I4x4)
1745*495ae853SAndroid Build Coastguard Worker         {
1746*495ae853SAndroid Build Coastguard Worker             isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
1747*495ae853SAndroid Build Coastguard Worker                 (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
1748*495ae853SAndroid Build Coastguard Worker 
1749*495ae853SAndroid Build Coastguard Worker             /* mb sub blk modes */
1750*495ae853SAndroid Build Coastguard Worker             WORD32 intra_pred_mode_flag, rem_intra_mode;
1751*495ae853SAndroid Build Coastguard Worker             WORD32 byte;
1752*495ae853SAndroid Build Coastguard Worker 
1753*495ae853SAndroid Build Coastguard Worker             is_inter = 0;
1754*495ae853SAndroid Build Coastguard Worker 
1755*495ae853SAndroid Build Coastguard Worker             chroma_intra_mode = (mb_tpm >> 6);
1756*495ae853SAndroid Build Coastguard Worker             cbptable = 0;
1757*495ae853SAndroid Build Coastguard Worker 
1758*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1759*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, 23, error_status, "mb type");
1760*495ae853SAndroid Build Coastguard Worker 
1761*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < 16; i += 2)
1762*495ae853SAndroid Build Coastguard Worker             {
1763*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 1 */
1764*495ae853SAndroid Build Coastguard Worker                 byte = ps_mb_hdr_i4x4->au1_sub_blk_modes[i >> 1];
1765*495ae853SAndroid Build Coastguard Worker 
1766*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1767*495ae853SAndroid Build Coastguard Worker 
1768*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1769*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1770*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1771*495ae853SAndroid Build Coastguard Worker 
1772*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1773*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1774*495ae853SAndroid Build Coastguard Worker                 {
1775*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1776*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1777*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1778*495ae853SAndroid Build Coastguard Worker                 }
1779*495ae853SAndroid Build Coastguard Worker 
1780*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 2 */
1781*495ae853SAndroid Build Coastguard Worker                 byte >>= 4;
1782*495ae853SAndroid Build Coastguard Worker 
1783*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1784*495ae853SAndroid Build Coastguard Worker 
1785*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1786*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1787*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1788*495ae853SAndroid Build Coastguard Worker 
1789*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1790*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1791*495ae853SAndroid Build Coastguard Worker                 {
1792*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1793*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1794*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1795*495ae853SAndroid Build Coastguard Worker                 }
1796*495ae853SAndroid Build Coastguard Worker             }
1797*495ae853SAndroid Build Coastguard Worker 
1798*495ae853SAndroid Build Coastguard Worker             /* intra_chroma_pred_mode */
1799*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1800*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
1801*495ae853SAndroid Build Coastguard Worker         }
1802*495ae853SAndroid Build Coastguard Worker         else if(mb_type == I8x8)
1803*495ae853SAndroid Build Coastguard Worker         {
1804*495ae853SAndroid Build Coastguard Worker             isvce_mb_hdr_i8x8_t *ps_mb_hdr_i8x8 =
1805*495ae853SAndroid Build Coastguard Worker                 (isvce_mb_hdr_i8x8_t *) ps_ent_ctxt->pv_mb_header_data;
1806*495ae853SAndroid Build Coastguard Worker 
1807*495ae853SAndroid Build Coastguard Worker             /* transform 8x8 flag */
1808*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1809*495ae853SAndroid Build Coastguard Worker 
1810*495ae853SAndroid Build Coastguard Worker             /* mb sub blk modes */
1811*495ae853SAndroid Build Coastguard Worker             WORD32 intra_pred_mode_flag, rem_intra_mode;
1812*495ae853SAndroid Build Coastguard Worker             WORD32 byte;
1813*495ae853SAndroid Build Coastguard Worker 
1814*495ae853SAndroid Build Coastguard Worker             is_inter = 0;
1815*495ae853SAndroid Build Coastguard Worker 
1816*495ae853SAndroid Build Coastguard Worker             chroma_intra_mode = (mb_tpm >> 6);
1817*495ae853SAndroid Build Coastguard Worker             cbptable = 0;
1818*495ae853SAndroid Build Coastguard Worker 
1819*495ae853SAndroid Build Coastguard Worker             ASSERT(0);
1820*495ae853SAndroid Build Coastguard Worker 
1821*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1822*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, 23, error_status, "mb type");
1823*495ae853SAndroid Build Coastguard Worker 
1824*495ae853SAndroid Build Coastguard Worker             /* u4_transform_size_8x8_flag */
1825*495ae853SAndroid Build Coastguard Worker             PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status,
1826*495ae853SAndroid Build Coastguard Worker                      "u4_transform_size_8x8_flag");
1827*495ae853SAndroid Build Coastguard Worker 
1828*495ae853SAndroid Build Coastguard Worker             /* write sub block modes */
1829*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < 4; i++)
1830*495ae853SAndroid Build Coastguard Worker             {
1831*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 1 */
1832*495ae853SAndroid Build Coastguard Worker                 byte = ps_mb_hdr_i8x8->au1_sub_blk_modes[i >> 1];
1833*495ae853SAndroid Build Coastguard Worker 
1834*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1835*495ae853SAndroid Build Coastguard Worker 
1836*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1837*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1838*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1839*495ae853SAndroid Build Coastguard Worker 
1840*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1841*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1842*495ae853SAndroid Build Coastguard Worker                 {
1843*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1844*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1845*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1846*495ae853SAndroid Build Coastguard Worker                 }
1847*495ae853SAndroid Build Coastguard Worker 
1848*495ae853SAndroid Build Coastguard Worker                 /* sub blk idx 2 */
1849*495ae853SAndroid Build Coastguard Worker                 byte >>= 4;
1850*495ae853SAndroid Build Coastguard Worker 
1851*495ae853SAndroid Build Coastguard Worker                 intra_pred_mode_flag = byte & 0x1;
1852*495ae853SAndroid Build Coastguard Worker 
1853*495ae853SAndroid Build Coastguard Worker                 /* prev_intra4x4_pred_mode_flag */
1854*495ae853SAndroid Build Coastguard Worker                 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1855*495ae853SAndroid Build Coastguard Worker                          "prev_intra4x4_pred_mode_flag");
1856*495ae853SAndroid Build Coastguard Worker 
1857*495ae853SAndroid Build Coastguard Worker                 /* rem_intra4x4_pred_mode */
1858*495ae853SAndroid Build Coastguard Worker                 if(!intra_pred_mode_flag)
1859*495ae853SAndroid Build Coastguard Worker                 {
1860*495ae853SAndroid Build Coastguard Worker                     rem_intra_mode = (byte & 0xF) >> 1;
1861*495ae853SAndroid Build Coastguard Worker                     PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1862*495ae853SAndroid Build Coastguard Worker                              "rem_intra4x4_pred_mode");
1863*495ae853SAndroid Build Coastguard Worker                 }
1864*495ae853SAndroid Build Coastguard Worker             }
1865*495ae853SAndroid Build Coastguard Worker 
1866*495ae853SAndroid Build Coastguard Worker             /* intra_chroma_pred_mode */
1867*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1868*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_i8x8_t);
1869*495ae853SAndroid Build Coastguard Worker         }
1870*495ae853SAndroid Build Coastguard Worker         else if(mb_type == BDIRECT)
1871*495ae853SAndroid Build Coastguard Worker         {
1872*495ae853SAndroid Build Coastguard Worker             is_inter = 1;
1873*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1874*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, B_DIRECT_16x16, error_status, "mb type");
1875*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_bdirect_t);
1876*495ae853SAndroid Build Coastguard Worker         }
1877*495ae853SAndroid Build Coastguard Worker         else
1878*495ae853SAndroid Build Coastguard Worker         {
1879*495ae853SAndroid Build Coastguard Worker             isvce_mb_hdr_b16x16_t *ps_mb_hdr_b16x16 =
1880*495ae853SAndroid Build Coastguard Worker                 (isvce_mb_hdr_b16x16_t *) ps_ent_ctxt->pv_mb_header_data;
1881*495ae853SAndroid Build Coastguard Worker 
1882*495ae853SAndroid Build Coastguard Worker             /* inter macro block partition cnt for 16x16 16x8 8x16 8x8 */
1883*495ae853SAndroid Build Coastguard Worker             const UWORD8 au1_part_cnt[] = {1, 2, 2, 4};
1884*495ae853SAndroid Build Coastguard Worker 
1885*495ae853SAndroid Build Coastguard Worker             /* number of partitions for the current mb */
1886*495ae853SAndroid Build Coastguard Worker             UWORD32 u4_part_cnt = au1_part_cnt[mb_type - B16x16];
1887*495ae853SAndroid Build Coastguard Worker 
1888*495ae853SAndroid Build Coastguard Worker             /* Get the pred modes */
1889*495ae853SAndroid Build Coastguard Worker             WORD32 i4_mb_part_pred_mode = (mb_tpm >> 4);
1890*495ae853SAndroid Build Coastguard Worker 
1891*495ae853SAndroid Build Coastguard Worker             ASSERT(mb_type == B16x16);
1892*495ae853SAndroid Build Coastguard Worker 
1893*495ae853SAndroid Build Coastguard Worker             is_inter = 1;
1894*495ae853SAndroid Build Coastguard Worker 
1895*495ae853SAndroid Build Coastguard Worker             mb_type_stream = mb_type - B16x16 + B_L0_16x16 + i4_mb_part_pred_mode;
1896*495ae853SAndroid Build Coastguard Worker 
1897*495ae853SAndroid Build Coastguard Worker             /* write mb type */
1898*495ae853SAndroid Build Coastguard Worker             PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1899*495ae853SAndroid Build Coastguard Worker 
1900*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < (WORD32) u4_part_cnt; i++)
1901*495ae853SAndroid Build Coastguard Worker             {
1902*495ae853SAndroid Build Coastguard Worker                 for(j = 0; j < NUM_PRED_DIRS; j++)
1903*495ae853SAndroid Build Coastguard Worker                 {
1904*495ae853SAndroid Build Coastguard Worker                     PRED_MODE_T e_pred_mode = (PRED_MODE_T) j;
1905*495ae853SAndroid Build Coastguard Worker                     PRED_MODE_T e_cmpl_pred_mode = (e_pred_mode == L0) ? L1 : L0;
1906*495ae853SAndroid Build Coastguard Worker 
1907*495ae853SAndroid Build Coastguard Worker                     if(((PRED_MODE_T) i4_mb_part_pred_mode) != e_pred_mode)
1908*495ae853SAndroid Build Coastguard Worker                     {
1909*495ae853SAndroid Build Coastguard Worker                         if(ps_svc_slice_header->i1_adaptive_motion_prediction_flag &&
1910*495ae853SAndroid Build Coastguard Worker                            ps_ent_ctxt->u1_spatial_layer_id)
1911*495ae853SAndroid Build Coastguard Worker                         {
1912*495ae853SAndroid Build Coastguard Worker                             PUT_BITS(ps_bitstream, ps_mb_hdr_b16x16->au1_mvp_idx[e_cmpl_pred_mode],
1913*495ae853SAndroid Build Coastguard Worker                                      1, error_status, "motion_prediction_flag_l0");
1914*495ae853SAndroid Build Coastguard Worker                         }
1915*495ae853SAndroid Build Coastguard Worker                     }
1916*495ae853SAndroid Build Coastguard Worker                 }
1917*495ae853SAndroid Build Coastguard Worker             }
1918*495ae853SAndroid Build Coastguard Worker 
1919*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < (WORD32) u4_part_cnt; i++)
1920*495ae853SAndroid Build Coastguard Worker             {
1921*495ae853SAndroid Build Coastguard Worker                 if(i4_mb_part_pred_mode != L1)
1922*495ae853SAndroid Build Coastguard Worker                 {
1923*495ae853SAndroid Build Coastguard Worker                     PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[0][0], error_status,
1924*495ae853SAndroid Build Coastguard Worker                                  "mv l0 x");
1925*495ae853SAndroid Build Coastguard Worker                     PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[0][1], error_status,
1926*495ae853SAndroid Build Coastguard Worker                                  "mv l0 y");
1927*495ae853SAndroid Build Coastguard Worker                 }
1928*495ae853SAndroid Build Coastguard Worker                 if(i4_mb_part_pred_mode != L0)
1929*495ae853SAndroid Build Coastguard Worker                 {
1930*495ae853SAndroid Build Coastguard Worker                     PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[1][0], error_status,
1931*495ae853SAndroid Build Coastguard Worker                                  "mv l1 x");
1932*495ae853SAndroid Build Coastguard Worker                     PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[1][1], error_status,
1933*495ae853SAndroid Build Coastguard Worker                                  "mv l1 y");
1934*495ae853SAndroid Build Coastguard Worker                 }
1935*495ae853SAndroid Build Coastguard Worker             }
1936*495ae853SAndroid Build Coastguard Worker 
1937*495ae853SAndroid Build Coastguard Worker             pu1_byte += sizeof(isvce_mb_hdr_b16x16_t);
1938*495ae853SAndroid Build Coastguard Worker         }
1939*495ae853SAndroid Build Coastguard Worker     }
1940*495ae853SAndroid Build Coastguard Worker 
1941*495ae853SAndroid Build Coastguard Worker     if(ps_svc_slice_header->i1_adaptive_residual_prediction_flag &&
1942*495ae853SAndroid Build Coastguard Worker        ps_ent_ctxt->u1_spatial_layer_id && (ps_mb_hdr->u1_base_mode_flag || !u1_is_intra_mb))
1943*495ae853SAndroid Build Coastguard Worker     {
1944*495ae853SAndroid Build Coastguard Worker         PUT_BITS(ps_bitstream, ps_mb_hdr->u1_residual_prediction_flag, 1, error_status,
1945*495ae853SAndroid Build Coastguard Worker                  "residual_prediction_flag");
1946*495ae853SAndroid Build Coastguard Worker     }
1947*495ae853SAndroid Build Coastguard Worker 
1948*495ae853SAndroid Build Coastguard Worker     /* coded_block_pattern */
1949*495ae853SAndroid Build Coastguard Worker     if(ps_mb_hdr->u1_base_mode_flag || mb_type != I16x16)
1950*495ae853SAndroid Build Coastguard Worker     {
1951*495ae853SAndroid Build Coastguard Worker         PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][cbptable], error_status,
1952*495ae853SAndroid Build Coastguard Worker                      "coded_block_pattern");
1953*495ae853SAndroid Build Coastguard Worker     }
1954*495ae853SAndroid Build Coastguard Worker 
1955*495ae853SAndroid Build Coastguard Worker     if((cbp > 0) || (mb_type == I16x16))
1956*495ae853SAndroid Build Coastguard Worker     {
1957*495ae853SAndroid Build Coastguard Worker         /* mb_qp_delta */
1958*495ae853SAndroid Build Coastguard Worker         PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
1959*495ae853SAndroid Build Coastguard Worker         ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
1960*495ae853SAndroid Build Coastguard Worker     }
1961*495ae853SAndroid Build Coastguard Worker 
1962*495ae853SAndroid Build Coastguard Worker     /* Ending bitstream offset for header in bits */
1963*495ae853SAndroid Build Coastguard Worker     bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1964*495ae853SAndroid Build Coastguard Worker 
1965*495ae853SAndroid Build Coastguard Worker     ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1966*495ae853SAndroid Build Coastguard Worker 
1967*495ae853SAndroid Build Coastguard Worker     /* start bitstream offset for residue in bits */
1968*495ae853SAndroid Build Coastguard Worker     bitstream_start_offset = bitstream_end_offset;
1969*495ae853SAndroid Build Coastguard Worker 
1970*495ae853SAndroid Build Coastguard Worker     /* residual */
1971*495ae853SAndroid Build Coastguard Worker     error_status = isvce_encode_residue(ps_ent_ctxt, mb_type, cbp);
1972*495ae853SAndroid Build Coastguard Worker 
1973*495ae853SAndroid Build Coastguard Worker     /* Ending bitstream offset for residue in bits */
1974*495ae853SAndroid Build Coastguard Worker     bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1975*495ae853SAndroid Build Coastguard Worker 
1976*495ae853SAndroid Build Coastguard Worker     ps_ent_ctxt->u4_residue_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1977*495ae853SAndroid Build Coastguard Worker 
1978*495ae853SAndroid Build Coastguard Worker     /* store the index of the next mb syntax layer */
1979*495ae853SAndroid Build Coastguard Worker     ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1980*495ae853SAndroid Build Coastguard Worker 
1981*495ae853SAndroid Build Coastguard Worker     return error_status;
1982*495ae853SAndroid Build Coastguard Worker }
1983*495ae853SAndroid Build Coastguard Worker 
1984*495ae853SAndroid Build Coastguard Worker #if ENABLE_RE_ENC_AS_SKIP
1985*495ae853SAndroid Build Coastguard Worker /**
1986*495ae853SAndroid Build Coastguard Worker ******************************************************************************
1987*495ae853SAndroid Build Coastguard Worker *
1988*495ae853SAndroid Build Coastguard Worker *  @brief re-encode frame as all skip MBs
1989*495ae853SAndroid Build Coastguard Worker *
1990*495ae853SAndroid Build Coastguard Worker *  @par   Description
1991*495ae853SAndroid Build Coastguard Worker *  The frame is encoded as all skip MBs to comply with VBV restrictions
1992*495ae853SAndroid Build Coastguard Worker *
1993*495ae853SAndroid Build Coastguard Worker *  @param[in]    ps_entropy
1994*495ae853SAndroid Build Coastguard Worker *  pointer to entropy context (handle)
1995*495ae853SAndroid Build Coastguard Worker *
1996*495ae853SAndroid Build Coastguard Worker *  @return      success or failure error code
1997*495ae853SAndroid Build Coastguard Worker *
1998*495ae853SAndroid Build Coastguard Worker ******************************************************************************
1999*495ae853SAndroid Build Coastguard Worker */
isvce_reencode_as_skip_frame_cavlc(isvce_entropy_ctxt_t * ps_entropy)2000*495ae853SAndroid Build Coastguard Worker IH264E_ERROR_T isvce_reencode_as_skip_frame_cavlc(isvce_entropy_ctxt_t *ps_entropy)
2001*495ae853SAndroid Build Coastguard Worker {
2002*495ae853SAndroid Build Coastguard Worker     WORD32 i4_mb_skip_run;
2003*495ae853SAndroid Build Coastguard Worker 
2004*495ae853SAndroid Build Coastguard Worker     bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
2005*495ae853SAndroid Build Coastguard Worker     bitstrm_t *ps_bitstrm_after_slice_hdr = ps_entropy->ps_bitstrm_after_slice_hdr;
2006*495ae853SAndroid Build Coastguard Worker 
2007*495ae853SAndroid Build Coastguard Worker     ps_bitstrm->i4_bits_left_in_cw = ps_bitstrm_after_slice_hdr->i4_bits_left_in_cw;
2008*495ae853SAndroid Build Coastguard Worker     ps_bitstrm->u4_cur_word = ps_bitstrm_after_slice_hdr->u4_cur_word;
2009*495ae853SAndroid Build Coastguard Worker     ps_bitstrm->u4_strm_buf_offset = ps_bitstrm_after_slice_hdr->u4_strm_buf_offset;
2010*495ae853SAndroid Build Coastguard Worker     ps_bitstrm->i4_zero_bytes_run = ps_bitstrm_after_slice_hdr->i4_zero_bytes_run;
2011*495ae853SAndroid Build Coastguard Worker 
2012*495ae853SAndroid Build Coastguard Worker     /* mb skip run */
2013*495ae853SAndroid Build Coastguard Worker     i4_mb_skip_run = ps_entropy->i4_wd_mbs * ps_entropy->i4_ht_mbs;
2014*495ae853SAndroid Build Coastguard Worker     PUT_BITS_UEV(ps_bitstrm, i4_mb_skip_run, ps_entropy->i4_error_code, "mb skip run");
2015*495ae853SAndroid Build Coastguard Worker 
2016*495ae853SAndroid Build Coastguard Worker     /* put rbsp trailing bits */
2017*495ae853SAndroid Build Coastguard Worker     ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
2018*495ae853SAndroid Build Coastguard Worker 
2019*495ae853SAndroid Build Coastguard Worker     return ps_entropy->i4_error_code;
2020*495ae853SAndroid Build Coastguard Worker }
2021*495ae853SAndroid Build Coastguard Worker #endif
2022