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