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