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