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 
963     /* mb header info */
964     /*
965      * mb_tpm : mb type plus mode
966      * mb_type : luma mb type and chroma mb type are packed
967      * cbp : coded block pattern
968      * mb_qp_delta : mb qp delta
969      * chroma_intra_mode : chroma intra mode
970      * luma_intra_mode : luma intra mode
971      */
972     WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
973     WORD8 mb_qp_delta;
974 
975     /* temp var */
976     WORD32 i, mb_type_stream;
977 
978     WORD32 bitstream_start_offset, bitstream_end_offset;
979 
980     /* Starting bitstream offset for header in bits */
981     bitstream_start_offset = GET_NUM_BITS(ps_bitstream);
982 
983 
984     /********************************************************************/
985     /*                    BEGIN HEADER GENERATION                       */
986     /********************************************************************/
987 
988     /* mb header info */
989     mb_tpm = *pu1_byte++;
990     cbp = *pu1_byte++;
991     mb_qp_delta = *pu1_byte++;
992 
993     /* mb type */
994     mb_type = mb_tpm & 0xF;
995     /* is intra ? */
996     if (mb_type == I16x16)
997     {
998         UWORD32 u4_cbp_l, u4_cbp_c;
999 
1000         u4_cbp_c = (cbp >> 4);
1001         u4_cbp_l = (cbp & 0xF);
1002         luma_intra_mode = (mb_tpm >> 4) & 3;
1003         chroma_intra_mode = (mb_tpm >> 6);
1004 
1005         mb_type_stream =  luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1006 
1007         /* write mb type */
1008         PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1009 
1010         /* intra_chroma_pred_mode */
1011         PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1012     }
1013     else if (mb_type == I4x4)
1014     {
1015         /* mb sub blk modes */
1016         WORD32 intra_pred_mode_flag, rem_intra_mode;
1017         WORD32 byte;
1018 
1019         chroma_intra_mode = (mb_tpm >> 6);
1020 
1021         /* write mb type */
1022         PUT_BITS_UEV(ps_bitstream, 0, error_status, "mb type");
1023 
1024         for (i = 0; i < 16; i += 2)
1025         {
1026             /* sub blk idx 1 */
1027             byte = *pu1_byte++;
1028 
1029             intra_pred_mode_flag = byte & 0x1;
1030 
1031             /* prev_intra4x4_pred_mode_flag */
1032             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1033 
1034             /* rem_intra4x4_pred_mode */
1035             if (!intra_pred_mode_flag)
1036             {
1037                 rem_intra_mode = (byte & 0xF) >> 1;
1038                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1039             }
1040 
1041             /* sub blk idx 2 */
1042             byte >>= 4;
1043 
1044             intra_pred_mode_flag = byte & 0x1;
1045 
1046             /* prev_intra4x4_pred_mode_flag */
1047             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1048 
1049             /* rem_intra4x4_pred_mode */
1050             if (!intra_pred_mode_flag)
1051             {
1052                 rem_intra_mode = (byte & 0xF) >> 1;
1053                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1054             }
1055         }
1056 
1057         /* intra_chroma_pred_mode */
1058         PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1059     }
1060     else if (mb_type == I8x8)
1061     {
1062         /* transform 8x8 flag */
1063         UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1064 
1065         /* mb sub blk modes */
1066         WORD32 intra_pred_mode_flag, rem_intra_mode;
1067         WORD32 byte;
1068 
1069         chroma_intra_mode = (mb_tpm >> 6);
1070 
1071         ASSERT(0);
1072 
1073         /* write mb type */
1074         PUT_BITS_UEV(ps_bitstream, 0, error_status, "mb type");
1075 
1076         /* u4_transform_size_8x8_flag */
1077         PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status, "u4_transform_size_8x8_flag");
1078 
1079         /* write sub block modes */
1080         for (i = 0; i < 4; i++)
1081         {
1082             /* sub blk idx 1 */
1083             byte = *pu1_byte++;
1084 
1085             intra_pred_mode_flag = byte & 0x1;
1086 
1087             /* prev_intra4x4_pred_mode_flag */
1088             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1089 
1090             /* rem_intra4x4_pred_mode */
1091             if (!intra_pred_mode_flag)
1092             {
1093                 rem_intra_mode = (byte & 0xF) >> 1;
1094                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1095             }
1096 
1097             /* sub blk idx 2 */
1098             byte >>= 4;
1099 
1100             intra_pred_mode_flag = byte & 0x1;
1101 
1102             /* prev_intra4x4_pred_mode_flag */
1103             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1104 
1105             /* rem_intra4x4_pred_mode */
1106             if (!intra_pred_mode_flag)
1107             {
1108                 rem_intra_mode = (byte & 0xF) >> 1;
1109                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1110             }
1111         }
1112 
1113         /* intra_chroma_pred_mode */
1114         PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1115     }
1116     else
1117     {
1118     }
1119 
1120     /* coded_block_pattern */
1121     if (mb_type != I16x16)
1122     {
1123         PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][0], error_status, "coded_block_pattern");
1124     }
1125 
1126     if (cbp || mb_type == I16x16)
1127     {
1128         /* mb_qp_delta */
1129         PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
1130     }
1131 
1132     /* Ending bitstream offset for header in bits */
1133     bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1134 
1135     ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset - bitstream_start_offset;
1136 
1137     /* Starting bitstream offset for residue */
1138     bitstream_start_offset = bitstream_end_offset;
1139 
1140     /* residual */
1141     error_status = ih264e_encode_residue(ps_ent_ctxt, mb_type, cbp);
1142 
1143     /* Ending bitstream offset for reside in bits */
1144     bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1145     ps_ent_ctxt->u4_residue_bits[0] += bitstream_end_offset - bitstream_start_offset;
1146 
1147     /* store the index of the next mb syntax layer */
1148     ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1149 
1150     return error_status;
1151 }
1152 
1153 /**
1154 *******************************************************************************
1155 *
1156 * @brief
1157 *  This function generates CAVLC coded bit stream for Inter slices
1158 *
1159 * @description
1160 *  The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
1161 *  (if present), mb qp delta, coded block pattern, chroma mb mode and
1162 *  luma/chroma residue. These syntax elements are written as directed by table
1163 *  7.3.5 of h264 specification
1164 *
1165 * @param[in] ps_ent_ctxt
1166 *  pointer to entropy context
1167 *
1168 * @returns error code
1169 *
1170 * @remarks none
1171 *
1172 *******************************************************************************
1173 */
ih264e_write_pslice_mb_cavlc(entropy_ctxt_t * ps_ent_ctxt)1174 IH264E_ERROR_T ih264e_write_pslice_mb_cavlc(entropy_ctxt_t *ps_ent_ctxt)
1175 {
1176     /* error status */
1177     IH264E_ERROR_T error_status = IH264E_SUCCESS;
1178 
1179     /* bit stream ptr */
1180     bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
1181 
1182     /* packed header data */
1183     UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
1184 
1185     /* mb header info */
1186     /*
1187      * mb_tpm : mb type plus mode
1188      * mb_type : luma mb type and chroma mb type are packed
1189      * cbp : coded block pattern
1190      * mb_qp_delta : mb qp delta
1191      * chroma_intra_mode : chroma intra mode
1192      * luma_intra_mode : luma intra mode
1193      * ps_pu :  Pointer to the array of structures having motion vectors, size
1194      * and position of sub partitions
1195      */
1196     WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
1197     WORD8 mb_qp_delta;
1198 
1199     /* temp var */
1200     WORD32 i, mb_type_stream, cbptable = 1;
1201 
1202     WORD32 is_inter = 0;
1203 
1204     WORD32 bitstream_start_offset, bitstream_end_offset;
1205 
1206     /* Starting bitstream offset for header in bits */
1207     bitstream_start_offset = GET_NUM_BITS(ps_bitstream);
1208 
1209     /********************************************************************/
1210     /*                    BEGIN HEADER GENERATION                       */
1211     /********************************************************************/
1212 
1213     /* mb header info */
1214     mb_tpm = *pu1_byte++;
1215 
1216     /* mb type */
1217     mb_type = mb_tpm & 0xF;
1218 
1219     /* check for skip */
1220     if (mb_type == PSKIP)
1221     {
1222         UWORD32 *nnz;
1223 
1224         is_inter = 1;
1225 
1226         /* increment skip counter */
1227         (*ps_ent_ctxt->pi4_mb_skip_run)++;
1228 
1229         /* store the index of the next mb syntax layer */
1230         ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1231 
1232         /* set nnz to zero */
1233         ps_ent_ctxt->u4_left_nnz_luma = 0;
1234         nnz = (UWORD32 *)ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
1235         *nnz = 0;
1236         ps_ent_ctxt->u4_left_nnz_cbcr = 0;
1237         nnz = (UWORD32 *)ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
1238         *nnz = 0;
1239 
1240         /* residual */
1241         error_status = ih264e_encode_residue(ps_ent_ctxt, P16x16, 0);
1242 
1243         bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1244 
1245         ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1246 
1247         return error_status;
1248     }
1249 
1250     /* remaining mb header info */
1251     cbp = *pu1_byte++;
1252     mb_qp_delta = *pu1_byte++;
1253 
1254     /* mb skip run */
1255     PUT_BITS_UEV(ps_bitstream, *ps_ent_ctxt->pi4_mb_skip_run, error_status, "mb skip run");
1256 
1257     /* reset skip counter */
1258     *ps_ent_ctxt->pi4_mb_skip_run = 0;
1259 
1260     /* is intra ? */
1261     if (mb_type == I16x16)
1262     {
1263         UWORD32 u4_cbp_l, u4_cbp_c;
1264 
1265         is_inter = 0;
1266 
1267         u4_cbp_c = (cbp >> 4);
1268         u4_cbp_l = (cbp & 0xF);
1269         luma_intra_mode = (mb_tpm >> 4) & 3;
1270         chroma_intra_mode = (mb_tpm >> 6);
1271 
1272         mb_type_stream =  luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1273 
1274         mb_type_stream += 5;
1275 
1276         /* write mb type */
1277         PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1278 
1279         /* intra_chroma_pred_mode */
1280         PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1281     }
1282     else if (mb_type == I4x4)
1283     {
1284         /* mb sub blk modes */
1285         WORD32 intra_pred_mode_flag, rem_intra_mode;
1286         WORD32 byte;
1287 
1288         is_inter = 0;
1289 
1290         chroma_intra_mode = (mb_tpm >> 6);
1291         cbptable = 0;
1292 
1293         /* write mb type */
1294         PUT_BITS_UEV(ps_bitstream, 5, error_status, "mb type");
1295 
1296         for (i = 0; i < 16; i += 2)
1297         {
1298             /* sub blk idx 1 */
1299             byte = *pu1_byte++;
1300 
1301             intra_pred_mode_flag = byte & 0x1;
1302 
1303             /* prev_intra4x4_pred_mode_flag */
1304             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1305 
1306             /* rem_intra4x4_pred_mode */
1307             if (!intra_pred_mode_flag)
1308             {
1309                 rem_intra_mode = (byte & 0xF) >> 1;
1310                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1311             }
1312 
1313             /* sub blk idx 2 */
1314             byte >>= 4;
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 
1329         /* intra_chroma_pred_mode */
1330         PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1331     }
1332     else if (mb_type == I8x8)
1333     {
1334         /* transform 8x8 flag */
1335         UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1336 
1337         /* mb sub blk modes */
1338         WORD32 intra_pred_mode_flag, rem_intra_mode;
1339         WORD32 byte;
1340 
1341         is_inter = 0;
1342 
1343         chroma_intra_mode = (mb_tpm >> 6);
1344         cbptable = 0;
1345 
1346         ASSERT(0);
1347 
1348         /* write mb type */
1349         PUT_BITS_UEV(ps_bitstream, 5, error_status, "mb type");
1350 
1351         /* u4_transform_size_8x8_flag */
1352         PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status, "u4_transform_size_8x8_flag");
1353 
1354         /* write sub block modes */
1355         for (i = 0; i < 4; i++)
1356         {
1357             /* sub blk idx 1 */
1358             byte = *pu1_byte++;
1359 
1360             intra_pred_mode_flag = byte & 0x1;
1361 
1362             /* prev_intra4x4_pred_mode_flag */
1363             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1364 
1365             /* rem_intra4x4_pred_mode */
1366             if (!intra_pred_mode_flag)
1367             {
1368                 rem_intra_mode = (byte & 0xF) >> 1;
1369                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1370             }
1371 
1372             /* sub blk idx 2 */
1373             byte >>= 4;
1374 
1375             intra_pred_mode_flag = byte & 0x1;
1376 
1377             /* prev_intra4x4_pred_mode_flag */
1378             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1379 
1380             /* rem_intra4x4_pred_mode */
1381             if (!intra_pred_mode_flag)
1382             {
1383                 rem_intra_mode = (byte & 0xF) >> 1;
1384                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1385             }
1386         }
1387 
1388         /* intra_chroma_pred_mode */
1389         PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1390     }
1391     else
1392     {
1393         /* inter macro block partition cnt */
1394         const UWORD8 au1_part_cnt[] = { 1, 2, 2, 4 };
1395 
1396         /* mv ptr */
1397         WORD16 *pi2_mv_ptr = (WORD16 *)pu1_byte;
1398 
1399         /* number of partitions for the current mb */
1400         UWORD32 u4_part_cnt = au1_part_cnt[mb_type - 3];
1401 
1402         is_inter = 1;
1403 
1404         /* write mb type */
1405         PUT_BITS_UEV(ps_bitstream, mb_type - 3, error_status, "mb type");
1406 
1407         for (i = 0; i < (WORD32)u4_part_cnt; i++)
1408         {
1409             PUT_BITS_SEV(ps_bitstream, *pi2_mv_ptr++, error_status, "mv x");
1410             PUT_BITS_SEV(ps_bitstream, *pi2_mv_ptr++, error_status, "mv y");
1411         }
1412 
1413         pu1_byte = (UWORD8 *)pi2_mv_ptr;
1414     }
1415 
1416     /* coded_block_pattern */
1417     if (mb_type != I16x16)
1418     {
1419         PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][cbptable], error_status, "coded_block_pattern");
1420     }
1421 
1422     if (cbp || mb_type == I16x16)
1423     {
1424         /* mb_qp_delta */
1425         PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
1426     }
1427 
1428     /* Ending bitstream offset for header in bits */
1429     bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1430 
1431     ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1432 
1433     /* start bitstream offset for residue in bits */
1434     bitstream_start_offset = bitstream_end_offset;
1435 
1436     /* residual */
1437     error_status = ih264e_encode_residue(ps_ent_ctxt, mb_type, cbp);
1438 
1439     /* Ending bitstream offset for residue in bits */
1440     bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1441 
1442     ps_ent_ctxt->u4_residue_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1443 
1444     /* store the index of the next mb syntax layer */
1445     ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1446 
1447     return error_status;
1448 }
1449 
1450 
1451 /**
1452 *******************************************************************************
1453 *
1454 * @brief
1455 *  This function generates CAVLC coded bit stream for B slices
1456 *
1457 * @description
1458 *  The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
1459 *  (if present), mb qp delta, coded block pattern, chroma mb mode and
1460 *  luma/chroma residue. These syntax elements are written as directed by table
1461 *  7.3.5 of h264 specification
1462 *
1463 * @param[in] ps_ent_ctxt
1464 *  pointer to entropy context
1465 *
1466 * @returns error code
1467 *
1468 * @remarks none
1469 *
1470 *******************************************************************************
1471 */
ih264e_write_bslice_mb_cavlc(entropy_ctxt_t * ps_ent_ctxt)1472 IH264E_ERROR_T ih264e_write_bslice_mb_cavlc(entropy_ctxt_t *ps_ent_ctxt)
1473 {
1474     /* error status */
1475     IH264E_ERROR_T error_status = IH264E_SUCCESS;
1476 
1477     /* bit stream ptr */
1478     bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
1479 
1480     /* packed header data */
1481     UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
1482 
1483     /* mb header info */
1484     /*
1485      * mb_tpm : mb type plus mode
1486      * mb_type : luma mb type and chroma mb type are packed
1487      * cbp : coded block pattern
1488      * mb_qp_delta : mb qp delta
1489      * chroma_intra_mode : chroma intra mode
1490      * luma_intra_mode : luma intra mode
1491      * ps_pu :  Pointer to the array of structures having motion vectors, size
1492      * and position of sub partitions
1493      */
1494     WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
1495     WORD8 mb_qp_delta;
1496 
1497     /* temp var */
1498     WORD32 i, mb_type_stream, cbptable = 1;
1499 
1500     WORD32 is_inter = 0;
1501 
1502     WORD32 bitstream_start_offset, bitstream_end_offset;
1503 
1504     /* Starting bitstream offset for header in bits */
1505     bitstream_start_offset = GET_NUM_BITS(ps_bitstream);
1506 
1507     /********************************************************************/
1508     /*                    BEGIN HEADER GENERATION                       */
1509     /********************************************************************/
1510 
1511     mb_tpm = *pu1_byte++;
1512 
1513     /* mb type */
1514     mb_type = mb_tpm & 0xF;
1515 
1516     /* check for skip */
1517     if (mb_type == BSKIP)
1518     {
1519         UWORD32 *nnz;
1520 
1521         is_inter = 1;
1522 
1523         /* increment skip counter */
1524         (*ps_ent_ctxt->pi4_mb_skip_run)++;
1525 
1526         /* store the index of the next mb syntax layer */
1527         ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1528 
1529         /* set nnz to zero */
1530         ps_ent_ctxt->u4_left_nnz_luma = 0;
1531         nnz = (UWORD32 *)ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
1532         *nnz = 0;
1533         ps_ent_ctxt->u4_left_nnz_cbcr = 0;
1534         nnz = (UWORD32 *)ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
1535         *nnz = 0;
1536 
1537         /* residual */
1538         error_status = ih264e_encode_residue(ps_ent_ctxt, B16x16, 0);
1539 
1540         bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1541 
1542         ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset
1543                         - bitstream_start_offset;
1544 
1545         return error_status;
1546     }
1547 
1548 
1549     /* remaining mb header info */
1550     cbp = *pu1_byte++;
1551     mb_qp_delta = *pu1_byte++;
1552 
1553     /* mb skip run */
1554     PUT_BITS_UEV(ps_bitstream, *ps_ent_ctxt->pi4_mb_skip_run, error_status, "mb skip run");
1555 
1556     /* reset skip counter */
1557     *ps_ent_ctxt->pi4_mb_skip_run = 0;
1558 
1559     /* is intra ? */
1560     if (mb_type == I16x16)
1561     {
1562         UWORD32 u4_cbp_l, u4_cbp_c;
1563 
1564         is_inter = 0;
1565 
1566         u4_cbp_c = (cbp >> 4);
1567         u4_cbp_l = (cbp & 0xF);
1568         luma_intra_mode = (mb_tpm >> 4) & 3;
1569         chroma_intra_mode = (mb_tpm >> 6);
1570 
1571         mb_type_stream =  luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1572 
1573         mb_type_stream += 23;
1574 
1575         /* write mb type */
1576         PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1577 
1578         /* intra_chroma_pred_mode */
1579         PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1580     }
1581     else if (mb_type == I4x4)
1582     {
1583         /* mb sub blk modes */
1584         WORD32 intra_pred_mode_flag, rem_intra_mode;
1585         WORD32 byte;
1586 
1587         is_inter = 0;
1588 
1589         chroma_intra_mode = (mb_tpm >> 6);
1590         cbptable = 0;
1591 
1592         /* write mb type */
1593         PUT_BITS_UEV(ps_bitstream, 23, error_status, "mb type");
1594 
1595         for (i = 0; i < 16; i += 2)
1596         {
1597             /* sub blk idx 1 */
1598             byte = *pu1_byte++;
1599 
1600             intra_pred_mode_flag = byte & 0x1;
1601 
1602             /* prev_intra4x4_pred_mode_flag */
1603             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1604 
1605             /* rem_intra4x4_pred_mode */
1606             if (!intra_pred_mode_flag)
1607             {
1608                 rem_intra_mode = (byte & 0xF) >> 1;
1609                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1610             }
1611 
1612             /* sub blk idx 2 */
1613             byte >>= 4;
1614 
1615             intra_pred_mode_flag = byte & 0x1;
1616 
1617             /* prev_intra4x4_pred_mode_flag */
1618             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1619 
1620             /* rem_intra4x4_pred_mode */
1621             if (!intra_pred_mode_flag)
1622             {
1623                 rem_intra_mode = (byte & 0xF) >> 1;
1624                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1625             }
1626         }
1627 
1628         /* intra_chroma_pred_mode */
1629         PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1630     }
1631     else if (mb_type == I8x8)
1632     {
1633         /* transform 8x8 flag */
1634         UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1635 
1636         /* mb sub blk modes */
1637         WORD32 intra_pred_mode_flag, rem_intra_mode;
1638         WORD32 byte;
1639 
1640         is_inter = 0;
1641 
1642         chroma_intra_mode = (mb_tpm >> 6);
1643         cbptable = 0;
1644 
1645         ASSERT(0);
1646 
1647         /* write mb type */
1648         PUT_BITS_UEV(ps_bitstream, 23, error_status, "mb type");
1649 
1650         /* u4_transform_size_8x8_flag */
1651         PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status, "u4_transform_size_8x8_flag");
1652 
1653         /* write sub block modes */
1654         for (i = 0; i < 4; i++)
1655         {
1656             /* sub blk idx 1 */
1657             byte = *pu1_byte++;
1658 
1659             intra_pred_mode_flag = byte & 0x1;
1660 
1661             /* prev_intra4x4_pred_mode_flag */
1662             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1663 
1664             /* rem_intra4x4_pred_mode */
1665             if (!intra_pred_mode_flag)
1666             {
1667                 rem_intra_mode = (byte & 0xF) >> 1;
1668                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1669             }
1670 
1671             /* sub blk idx 2 */
1672             byte >>= 4;
1673 
1674             intra_pred_mode_flag = byte & 0x1;
1675 
1676             /* prev_intra4x4_pred_mode_flag */
1677             PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1678 
1679             /* rem_intra4x4_pred_mode */
1680             if (!intra_pred_mode_flag)
1681             {
1682                 rem_intra_mode = (byte & 0xF) >> 1;
1683                 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1684             }
1685         }
1686 
1687         /* intra_chroma_pred_mode */
1688         PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1689     }
1690     else if(mb_type == BDIRECT)
1691     {
1692         is_inter = 1;
1693         /* write mb type */
1694         PUT_BITS_UEV(ps_bitstream, B_DIRECT_16x16, error_status, "mb type");
1695     }
1696     else /* if mb_type == B16x16 */
1697     {
1698         /* inter macro block partition cnt for 16x16 16x8 8x16 8x8 */
1699         const UWORD8 au1_part_cnt[] = { 1, 2, 2, 4 };
1700 
1701         /* mv ptr */
1702         WORD16 *pi2_mvd_ptr = (WORD16 *)pu1_byte;
1703 
1704         /* number of partitions for the current mb */
1705         UWORD32 u4_part_cnt = au1_part_cnt[mb_type - B16x16];
1706 
1707         /* Get the pred modes */
1708         WORD32 i4_mb_part_pred_mode = (mb_tpm >> 4);
1709 
1710         is_inter = 1;
1711 
1712         mb_type_stream = mb_type - B16x16 + B_L0_16x16 + i4_mb_part_pred_mode;
1713 
1714         /* write mb type */
1715         PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1716 
1717         for (i = 0; i < (WORD32)u4_part_cnt; i++)
1718         {
1719             if (i4_mb_part_pred_mode != PRED_L1)/* || PRED_BI */
1720             {
1721                 PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr, error_status, "mv l0 x");
1722                 pi2_mvd_ptr++;
1723                 PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr, error_status, "mv l0 y");
1724                 pi2_mvd_ptr++;
1725             }
1726             if (i4_mb_part_pred_mode != PRED_L0)/* || PRED_BI */
1727             {
1728                 PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr, error_status, "mv l1 x");
1729                 pi2_mvd_ptr++;
1730                 PUT_BITS_SEV(ps_bitstream, *pi2_mvd_ptr, error_status, "mv l1 y");
1731                 pi2_mvd_ptr++;
1732             }
1733         }
1734 
1735         pu1_byte = (UWORD8 *)pi2_mvd_ptr;
1736     }
1737 
1738     /* coded_block_pattern */
1739     if (mb_type != I16x16)
1740     {
1741         PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][cbptable], error_status, "coded_block_pattern");
1742     }
1743 
1744     if (cbp || mb_type == I16x16)
1745     {
1746         /* mb_qp_delta */
1747         PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
1748     }
1749 
1750     /* Ending bitstream offset for header in bits */
1751     bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1752 
1753     ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1754 
1755     /* start bitstream offset for residue in bits */
1756     bitstream_start_offset = bitstream_end_offset;
1757 
1758     /* residual */
1759     error_status = ih264e_encode_residue(ps_ent_ctxt, mb_type, cbp);
1760 
1761     /* Ending bitstream offset for residue in bits */
1762     bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1763 
1764     ps_ent_ctxt->u4_residue_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1765 
1766     /* store the index of the next mb syntax layer */
1767     ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1768 
1769     return error_status;
1770 }
1771