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