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*/
124static 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*/
240static 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
430GATHER_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*/
604static 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*/
698static 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*/
952IH264E_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*/
1174IH264E_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*/
1472IH264E_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