Home | History | Annotate | Download | only in encoder
      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 */
    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 */
    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 */
    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 */
    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 */
    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 */
   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 */
   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