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