ih264e_cavlc.c revision 3a52efd36102c9a4cb8e8f23b6f9131b8b01eef5
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()
39*  - ih264e_write_pslice_mb()
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_structs.h"
69#include "ih264_defs.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 "irc_cntrl_param.h"
79#include "irc_frame_info_collector.h"
80#include "ih264e_rate_control.h"
81#include "ih264e_structs.h"
82#include "ih264e_encode_header.h"
83#include "ih264_cavlc_tables.h"
84#include "ih264e_cavlc.h"
85#include "ih264e_statistics.h"
86#include "ih264e_trace.h"
87
88/*****************************************************************************/
89/* Function Definitions                                                      */
90/*****************************************************************************/
91
92/**
93*******************************************************************************
94*
95* @brief
96*  This function computes run of zero, number of trailing ones and sign of
97*  trailing ones basing on the significant coeff map, residual block and
98*  total nnz.
99*
100* @param[in] pi2_res_block
101*  Pointer to residual block containing levels in scan order
102*
103* @param[in] u4_total_coeff
104*  Total non-zero coefficients in that sub block
105*
106* @param[in] pu1_zero_run
107*  Pointer to array to store run of zeros
108*
109* @param[in] u4_sig_coeff_map
110*  significant coefficient map
111*
112* @returns u4_totzero_sign_trailone
113*  Bits 0-8 contains number of trailing ones.
114*  Bits 8-16 contains bitwise sign information of trailing one
115*  Bits 16-24 contains total number of zeros.
116*
117* @remarks
118*  None
119*
120*******************************************************************************
121*/
122static UWORD32 ih264e_compute_zeroruns_and_trailingones(WORD16 *pi2_res_block,
123                                                        UWORD32 u4_total_coeff,
124                                                        UWORD8 *pu1_zero_run,
125                                                        UWORD32 u4_sig_coeff_map)
126{
127    UWORD32 i = 0;
128    UWORD32 u4_nnz_coeff = 0;
129    WORD32  i4_run = -1;
130    UWORD32 u4_sign = 0;
131    UWORD32 u4_tot_zero = 0;
132    UWORD32 u4_trailing1 = 0;
133    WORD32 i4_val;
134    UWORD32 u4_totzero_sign_trailone;
135    UWORD32 *pu4_zero_run;
136
137    pu4_zero_run = (void *)pu1_zero_run;
138    pu4_zero_run[0] = 0;
139    pu4_zero_run[1] = 0;
140    pu4_zero_run[2] = 0;
141    pu4_zero_run[3] = 0;
142
143    /* Compute Runs of zeros for all nnz coefficients except the last 3 */
144    if (u4_total_coeff > 3)
145    {
146        for (i = 0; u4_nnz_coeff < (u4_total_coeff-3); i++)
147        {
148            i4_run++;
149
150            i4_val = (u4_sig_coeff_map & 0x1);
151            u4_sig_coeff_map >>= 1;
152
153            if (i4_val != 0)
154            {
155                pu1_zero_run[u4_nnz_coeff++] = i4_run;
156                i4_run = -1;
157            }
158        }
159    }
160
161    /* Compute T1's, Signof(T1's) and Runs of zeros for the last 3 */
162    while (u4_nnz_coeff != u4_total_coeff)
163    {
164        i4_run++;
165
166        i4_val = (u4_sig_coeff_map & 0x1);
167        u4_sig_coeff_map >>= 1;
168
169        if (i4_val != 0)
170        {
171            if (pi2_res_block[u4_nnz_coeff] == 1)
172            {
173                pu1_zero_run[u4_nnz_coeff] = i4_run;
174                u4_trailing1++;
175            }
176            else
177            {
178                if (pi2_res_block[u4_nnz_coeff] == -1)
179                {
180                    pu1_zero_run[u4_nnz_coeff] = i4_run;
181                    u4_sign |= 1 << u4_trailing1;
182                    u4_trailing1++;
183                }
184                else
185                {
186                    pu1_zero_run[u4_nnz_coeff] = i4_run;
187                    u4_trailing1 = 0;
188                    u4_sign = 0;
189                }
190            }
191            i4_run = -1;
192            u4_nnz_coeff++;
193        }
194        i++;
195    }
196
197    u4_tot_zero = i - u4_total_coeff;
198    u4_totzero_sign_trailone = (u4_tot_zero << 16)|(u4_sign << 8)|u4_trailing1;
199
200    return (u4_totzero_sign_trailone);
201}
202
203/**
204*******************************************************************************
205*
206* @brief
207*  This function generates CAVLC coded bit stream for the given residual block
208*
209* @param[in] pi2_res_block
210*  Pointer to residual block containing levels in scan order
211*
212* @param[in] u4_total_coeff
213*  Total non-zero coefficients in the sub block
214*
215* @param[in] u4_block_type
216*  block type
217*
218* @param[in] pu1_zero_run
219*  Pointer to array to store run of zeros
220*
221* @param[in] u4_nc
222*  average of non zero coeff from top and left blocks (when available)
223*
224* @param[in, out] ps_bit_stream
225*  structure pointing to a buffer holding output bit stream
226*
227* @param[in] u4_sig_coeff_map
228*  significant coefficient map of the residual block
229*
230* @returns
231*  error code
232*
233* @remarks
234*  If the block type is CAVLC_CHROMA_4x4_DC, then u4_nc is non-significant
235*
236*******************************************************************************
237*/
238static IH264E_ERROR_T ih264e_write_coeff4x4_cavlc(WORD16 *pi2_res_block,
239                                                  UWORD32 u4_total_coeff,
240                                                  ENTROPY_BLK_TYPE u4_block_type,
241                                                  UWORD8 *pu1_zero_run,
242                                                  UWORD32 u4_nc,
243                                                  bitstrm_t *ps_bit_stream,
244                                                  UWORD32 u4_sig_coeff_map)
245{
246    IH264E_ERROR_T error_status = IH264E_SUCCESS;
247    UWORD32 u4_totzero_sign_trailone = 0;
248    UWORD32 u4_trailing_ones = 0;
249    UWORD32 u4_tot_zeros = 0;
250    UWORD32 u4_remaining_coeff = 0;
251    UWORD32 u4_sign1 = 0;
252    UWORD32 u4_max_num_coeff = 0;
253    const UWORD32 au4_max_num_nnz_coeff[] = {16, 15, 16, 4, 15};
254
255    /* validate inputs */
256    ASSERT(u4_block_type <= CAVLC_CHROMA_4x4_AC);
257
258    u4_max_num_coeff = au4_max_num_nnz_coeff[u4_block_type];
259
260    ASSERT(u4_total_coeff <= u4_max_num_coeff);
261
262    if (!u4_total_coeff)
263    {
264        UWORD32 u4_codeword = 15;
265        UWORD32 u4_codesize = 1;
266        if (u4_block_type == CAVLC_CHROMA_4x4_DC)
267        {
268            u4_codeword = 1;
269            u4_codesize = 2;
270            DEBUG("\n[%d numcoeff, %d numtrailing ones]",u4_total_coeff, 0);
271            ENTROPY_TRACE("\tnumber of non zero coeffs ",u4_total_coeff);
272            ENTROPY_TRACE("\tnumber of trailing ones ",0);
273        }
274        else
275        {
276            UWORD32 u4_vlcnum = u4_nc >> 1;
277
278            /* write coeff_token */
279            if (u4_vlcnum > 3)
280            {
281                /* Num-FLC */
282                u4_codeword = 3;
283                u4_codesize = 6;
284            }
285            else
286            {
287                /* Num-VLC 0, 1, 2 */
288                if (u4_vlcnum > 1)
289                {
290                    u4_vlcnum = 2;
291                }
292                u4_codesize <<= u4_vlcnum;
293                u4_codeword >>= (4 - u4_codesize);
294            }
295
296            DEBUG("\n[%d numcoeff, %d numtrailing ones, %d nnz]",u4_total_coeff, 0, u4_nc);
297            ENTROPY_TRACE("\tnumber of non zero coeffs ",u4_total_coeff);
298            ENTROPY_TRACE("\tnC ",u4_nc);
299        }
300
301
302        DEBUG("\nCOEFF TOKEN 0: %d u4_codeword, %d u4_codesize",u4_codeword, u4_codesize);
303        ENTROPY_TRACE("\tcodeword ",u4_codeword);
304        ENTROPY_TRACE("\tcodesize ",u4_codesize);
305
306        error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
307
308        return error_status;
309    }
310    else
311    {
312        /* Compute zero run, number of trailing ones and their sign. */
313        u4_totzero_sign_trailone =
314                ih264e_compute_zeroruns_and_trailingones(pi2_res_block,
315                        u4_total_coeff,
316                        pu1_zero_run,
317                        u4_sig_coeff_map);
318        u4_trailing_ones = u4_totzero_sign_trailone & 0xFF;
319        u4_sign1 = (u4_totzero_sign_trailone >> 8)& 0xFF;
320        u4_tot_zeros = (u4_totzero_sign_trailone >> 16) & 0xFF;
321        u4_remaining_coeff = u4_total_coeff - u4_trailing_ones;
322
323        /* write coeff_token */
324        {
325            UWORD32 u4_codeword;
326            UWORD32 u4_codesize;
327            if (u4_block_type == CAVLC_CHROMA_4x4_DC)
328            {
329                u4_codeword = gu1_code_coeff_token_table_chroma[u4_trailing_ones][u4_total_coeff-1];
330                u4_codesize = gu1_size_coeff_token_table_chroma[u4_trailing_ones][u4_total_coeff-1];
331
332                DEBUG("\n[%d numcoeff, %d numtrailing ones]",u4_total_coeff, u4_trailing_ones);
333                ENTROPY_TRACE("\tnumber of non zero coeffs ",u4_total_coeff);
334                ENTROPY_TRACE("\tnumber of trailing ones ",u4_trailing_ones);
335            }
336            else
337            {
338                UWORD32 u4_vlcnum = u4_nc >> 1;
339
340                if (u4_vlcnum > 3)
341                {
342                    /* Num-FLC */
343                    u4_codeword = ((u4_total_coeff-1) << 2 ) + u4_trailing_ones;
344                    u4_codesize = 6;
345                }
346                else
347                {
348                    /* Num-VLC 0, 1, 2 */
349                    if (u4_vlcnum > 1)
350                    {
351                        u4_vlcnum = 2;
352                    }
353                    u4_codeword = gu1_code_coeff_token_table[u4_vlcnum][u4_trailing_ones][u4_total_coeff-1];
354                    u4_codesize = gu1_size_coeff_token_table[u4_vlcnum][u4_trailing_ones][u4_total_coeff-1];
355                }
356
357                DEBUG("\n[%d numcoeff, %d numtrailing ones, %d nnz]",u4_total_coeff, u4_trailing_ones, u4_nc);
358                ENTROPY_TRACE("\tnumber of non zero coeffs ",u4_total_coeff);
359                ENTROPY_TRACE("\tnumber of trailing ones ",u4_trailing_ones);
360                ENTROPY_TRACE("\tnC ",u4_nc);
361            }
362
363            DEBUG("\nCOEFF TOKEN 0: %d u4_codeword, %d u4_codesize",u4_codeword, u4_codesize);
364            ENTROPY_TRACE("\tcodeword ",u4_codeword);
365            ENTROPY_TRACE("\tcodesize ",u4_codesize);
366
367            error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
368        }
369
370        /* write sign of trailing ones */
371        if (u4_trailing_ones)
372        {
373            DEBUG("\nT1's: %d u4_codeword, %d u4_codesize",u4_sign1, u4_trailing_ones);
374            error_status = ih264e_put_bits(ps_bit_stream, u4_sign1, u4_trailing_ones);
375            ENTROPY_TRACE("\tnumber of trailing ones ",u4_trailing_ones);
376            ENTROPY_TRACE("\tsign of trailing ones ",u4_sign1);
377        }
378
379        /* write level codes */
380        if (u4_remaining_coeff)
381        {
382            WORD32 i4_level = pi2_res_block[u4_remaining_coeff-1];
383            UWORD32 u4_escape;
384            UWORD32 u4_suffix_length = 0; // Level-VLC[N]
385            UWORD32 u4_abs_level, u4_abs_level_actual = 0;
386            WORD32 i4_sign;
387            const UWORD32 u4_rndfactor[] = {0, 0, 1, 3, 7, 15, 31};
388
389            DEBUG("\n \t%d coeff,",i4_level);
390            ENTROPY_TRACE("\tcoeff ",i4_level);
391
392            if (u4_trailing_ones < 3)
393            {
394                /* If there are less than 3 T1s, then the first non-T1 level is incremented if negative (decremented if positive)*/
395                if (i4_level < 0)
396                {
397                    i4_level += 1;
398                }
399                else
400                {
401                    i4_level -= 1;
402                }
403
404                u4_abs_level_actual = 1;
405
406                /* Initialize VLC table (Suffix Length) to encode the level */
407                if (u4_total_coeff > 10)
408                {
409                    u4_suffix_length = 1;
410                }
411            }
412
413            i4_sign = (i4_level >> (sizeof(WORD32) * CHAR_BIT - 1));
414            u4_abs_level = ((i4_level + i4_sign) ^ i4_sign);
415
416            u4_abs_level_actual += u4_abs_level;
417
418            u4_escape = (u4_abs_level + u4_rndfactor[u4_suffix_length]) >> u4_suffix_length;
419
420            while (1)
421            {
422                UWORD32 u4_codesize;
423                UWORD32 u4_codeword;
424                UWORD32 u4_codeval;
425
426                u4_remaining_coeff--;
427
428GATHER_CAVLC_STATS1();
429
430                {
431                    u4_codeval = u4_abs_level << 1;
432                    u4_codeval = u4_codeval - 2 - i4_sign;
433
434                    if ((!u4_suffix_length) && (u4_escape > 7) && (u4_abs_level < 16))
435                    {
436                        u4_codeword = (1 << 4) + (u4_codeval - 14);
437                        u4_codesize = 19;
438                    }
439                    else if (u4_escape > 7)
440                    {
441                        u4_codeword = (1 << 12) + (u4_codeval - (15 << u4_suffix_length));
442                        u4_codesize = 28;
443                        if (!u4_suffix_length)
444                        {
445                            u4_codeword -= 15;
446                        }
447                    }
448                    else
449                    {
450                        u4_codeword = (1 << u4_suffix_length) + (u4_codeval & ((1 << u4_suffix_length)-1));
451                        u4_codesize = (u4_codeval >> u4_suffix_length) + 1 + u4_suffix_length;
452                    }
453                }
454
455                /*put the level code in bitstream*/
456                DEBUG("\nLEVEL: %d u4_codeword, %d u4_codesize",u4_codeword, u4_codesize);
457                ENTROPY_TRACE("\tcodeword ",u4_codeword);
458                ENTROPY_TRACE("\tcodesize ",u4_codesize);
459                error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
460
461                if (u4_remaining_coeff == 0) break;
462
463                /*update suffix length for next level*/
464                if (u4_suffix_length == 0)
465                {
466                    u4_suffix_length++;
467                }
468                if (u4_suffix_length < 6)
469                {
470                    if (u4_abs_level_actual > gu1_threshold_vlc_level[u4_suffix_length])
471                    {
472                        u4_suffix_length++;
473                    }
474                }
475
476                /* next level */
477                i4_level      = pi2_res_block[u4_remaining_coeff-1];
478
479                DEBUG("\n \t%d coeff,",i4_level);
480                ENTROPY_TRACE("\tcoeff ",i4_level);
481
482                i4_sign = (i4_level >> (sizeof(WORD32) * CHAR_BIT - 1));
483                u4_abs_level = ((i4_level + i4_sign) ^ i4_sign);
484
485                u4_abs_level_actual = u4_abs_level;
486
487                u4_escape = (u4_abs_level + u4_rndfactor[u4_suffix_length]) >> u4_suffix_length;
488            }
489        }
490
491        DEBUG("\n \t %d totalzeros",u4_tot_zeros);
492        ENTROPY_TRACE("\ttotal zeros ",u4_tot_zeros);
493
494        /* Write Total Zeros */
495        if (u4_total_coeff < u4_max_num_coeff)
496        {
497            WORD32 index;
498            UWORD32 u4_codeword;
499            UWORD32 u4_codesize;
500
501            if (u4_block_type == CAVLC_CHROMA_4x4_DC)
502            {
503                UWORD8 gu1_index_zero_table_chroma[] = {0, 4, 7};
504                index = gu1_index_zero_table_chroma[u4_total_coeff-1] + u4_tot_zeros;
505                u4_codesize = gu1_size_zero_table_chroma[index];
506                u4_codeword = gu1_code_zero_table_chroma[index];
507            }
508            else
509            {
510                index = gu1_index_zero_table[u4_total_coeff-1] + u4_tot_zeros;
511                u4_codesize = gu1_size_zero_table[index];
512                u4_codeword = gu1_code_zero_table[index];
513            }
514
515            DEBUG("\nTOTAL ZEROS: %d u4_codeword, %d u4_codesize",u4_codeword, u4_codesize);
516            ENTROPY_TRACE("\tcodeword ",u4_codeword);
517            ENTROPY_TRACE("\tcodesize ",u4_codesize);
518            error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
519        }
520
521        /* Write Run Before */
522        if (u4_tot_zeros)
523        {
524            UWORD32 u4_max_num_coef = u4_total_coeff-1;
525            UWORD32 u4_codeword;
526            UWORD32 u4_codesize;
527            UWORD32 u4_zeros_left = u4_tot_zeros;
528
529            while (u4_max_num_coef)
530            {
531                UWORD32 u4_run_before = pu1_zero_run[u4_max_num_coef];
532                UWORD32 u4_index;
533
534                if (u4_zeros_left > MAX_ZERO_LEFT)
535                {
536                    u4_index = gu1_index_run_table[MAX_ZERO_LEFT];
537                }
538                else
539                {
540                    u4_index = gu1_index_run_table[u4_zeros_left - 1];
541                }
542
543                u4_codesize = gu1_size_run_table[u4_index + u4_run_before];
544                u4_codeword = gu1_code_run_table[u4_index + u4_run_before];
545
546                DEBUG("\nRUN BEFORE ZEROS: %d u4_codeword, %d u4_codesize",u4_codeword, u4_codesize);
547                ENTROPY_TRACE("\tcodeword ",u4_codeword);
548                ENTROPY_TRACE("\tcodesize ",u4_codesize);
549                error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
550
551                u4_zeros_left -= u4_run_before;
552                if (!u4_zeros_left)
553                {
554                    break;
555                }
556                u4_max_num_coef--;
557            }
558        }
559    }
560
561    return error_status;
562}
563
564/**
565*******************************************************************************
566*
567* @brief
568*  This function generates CAVLC coded bit stream for the given subblock
569*
570* @param[in] ps_ent_ctxt
571*  Pointer to entropy context
572*
573* @param[in] pi2_res_block
574*  Pointers to residual blocks of all the partitions for the current subblk
575*  (containing levels in scan order)
576*
577* @param[in] pu1_nnz
578*  Total non-zero coefficients of all the partitions for the current subblk
579*
580* @param[in] pu2_sig_coeff_map
581*  Significant coefficient map of all the partitions for the current subblk
582*
583* @param[in] u4_block_type
584*  entropy coding block type
585*
586* @param[in] u4_ngbr_avbl
587*  top and left availability of all the partitions for the current subblk
588*  (packed)
589*
590* @param[in] pu1_top_nnz
591*  pointer to the buffer containing nnz of all the subblks to the top
592*
593* @param[in] pu1_left_nnz
594*  pointer to the buffer containing nnz of all the subblks to the left
595*
596* @returns error status
597*
598* @remarks none
599*
600*******************************************************************************
601*/
602static IH264E_ERROR_T ih264e_write_coeff8x8_cavlc(entropy_ctxt_t *ps_ent_ctxt,
603                                                  WORD16 **pi2_res_block,
604                                                  UWORD8 *pu1_nnz,
605                                                  UWORD16 *pu2_sig_coeff_map,
606                                                  ENTROPY_BLK_TYPE u4_block_type,
607                                                  UWORD32 u4_ngbr_avlb,
608                                                  UWORD8 *pu1_top_nnz,
609                                                  UWORD8 *pu1_left_nnz)
610{
611    IH264E_ERROR_T error_status = IH264E_SUCCESS;
612    bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
613    UWORD8 *pu1_zero_run = ps_ent_ctxt->au1_zero_run, *pu1_ngbr_avbl;
614    UWORD32 u4_nC;
615    UWORD8 u1_mb_a, u1_mb_b;
616
617    pu1_ngbr_avbl = (void *)(&u4_ngbr_avlb);
618
619    /* encode ac block index 4x4 = 0*/
620    u1_mb_a = pu1_ngbr_avbl[0] & 0x0F;
621    u1_mb_b = pu1_ngbr_avbl[0] & 0xF0;
622    u4_nC = 0;
623    if (u1_mb_a)
624        u4_nC += pu1_left_nnz[0];
625    if (u1_mb_b)
626        u4_nC += pu1_top_nnz[0];
627    if (u1_mb_a && u1_mb_b)
628        u4_nC = (u4_nC + 1) >> 1;
629    pu1_left_nnz[0] = pu1_top_nnz[0] = pu1_nnz[0];
630    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]);
631
632    /* encode ac block index 4x4 = 1*/
633    u1_mb_a = pu1_ngbr_avbl[1] & 0x0F;
634    u1_mb_b = pu1_ngbr_avbl[1] & 0xF0;
635    u4_nC = 0;
636    if (u1_mb_a)
637        u4_nC += pu1_left_nnz[0];
638    if (u1_mb_b)
639        u4_nC += pu1_top_nnz[1];
640    if (u1_mb_a && u1_mb_b)
641        u4_nC = (u4_nC + 1) >> 1;
642    pu1_left_nnz[0] = pu1_top_nnz[1] = pu1_nnz[1];
643    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]);
644
645    /* encode ac block index 4x4 = 2*/
646    u1_mb_a = pu1_ngbr_avbl[2] & 0x0F;
647    u1_mb_b = pu1_ngbr_avbl[2] & 0xF0;
648    u4_nC = 0;
649    if (u1_mb_a)
650        u4_nC += pu1_left_nnz[1];
651    if (u1_mb_b)
652        u4_nC += pu1_top_nnz[0];
653    if (u1_mb_a && u1_mb_b)
654        u4_nC = (u4_nC + 1) >> 1;
655    pu1_left_nnz[1] = pu1_top_nnz[0] = pu1_nnz[2];
656    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]);
657
658    /* encode ac block index 4x4 = 0*/
659    u1_mb_a = pu1_ngbr_avbl[3] & 0x0F;
660    u1_mb_b = pu1_ngbr_avbl[3] & 0xF0;
661    u4_nC = 0;
662    if (u1_mb_a)
663        u4_nC += pu1_left_nnz[1];
664    if (u1_mb_b)
665        u4_nC += pu1_top_nnz[1];
666    if (u1_mb_a && u1_mb_b)
667        u4_nC = (u4_nC + 1) >> 1;
668    pu1_left_nnz[1] = pu1_top_nnz[1] = pu1_nnz[3];
669    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]);
670
671    return error_status;
672}
673
674/**
675*******************************************************************************
676*
677* @brief
678*  This function encodes luma and chroma residues of a macro block when
679*  the entropy coding mode chosen is cavlc.
680*
681* @param[in] ps_ent_ctxt
682*  Pointer to entropy context
683*
684* @param[in] u4_mb_type
685*  current mb type
686*
687* @param[in] u4_cbp
688*  coded block pattern for the current mb
689*
690* @returns error code
691*
692* @remarks none
693*
694*******************************************************************************
695*/
696static IH264E_ERROR_T ih264e_encode_residue(entropy_ctxt_t *ps_ent_ctxt,
697                                            UWORD32 u4_mb_type,
698                                            UWORD32 u4_cbp)
699{
700    /* error status */
701    IH264E_ERROR_T error_status = IH264E_SUCCESS;
702
703    /* packed residue */
704    void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data;
705
706    /* bit stream buffer */
707    bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
708
709    /* zero run */
710    UWORD8 *pu1_zero_run = ps_ent_ctxt->au1_zero_run;
711
712    /* temp var */
713    UWORD32 u4_nC, u4_ngbr_avlb;
714    UWORD8 au1_nnz[4], *pu1_ngbr_avlb, *pu1_top_nnz, *pu1_left_nnz;
715    UWORD16 au2_sig_coeff_map[4];
716    WORD16 *pi2_res_block[4];
717    UWORD8 *pu1_slice_idx = ps_ent_ctxt->pu1_slice_idx;
718    tu_sblk_coeff_data_t *ps_mb_coeff_data;
719    ENTROPY_BLK_TYPE e_entropy_blk_type = CAVLC_LUMA_4x4;
720
721    /* ngbr availability */
722    UWORD8 u1_mb_a, u1_mb_b;
723
724    /* cbp */
725    UWORD32 u4_cbp_luma = u4_cbp & 0xF, u4_cbp_chroma = u4_cbp >> 4;
726
727    /* mb indices */
728    WORD32 i4_mb_x, i4_mb_y;
729
730    /* derive neighbor availability */
731    i4_mb_x = ps_ent_ctxt->i4_mb_x;
732    i4_mb_y = ps_ent_ctxt->i4_mb_y;
733    pu1_slice_idx += (i4_mb_y * ps_ent_ctxt->i4_wd_mbs);
734    /* left macroblock availability */
735    u1_mb_a = (i4_mb_x == 0 ||
736                    (pu1_slice_idx[i4_mb_x - 1 ] != pu1_slice_idx[i4_mb_x]))? 0 : 1;
737    /* top macroblock availability */
738    u1_mb_b = (i4_mb_y == 0 ||
739                    (pu1_slice_idx[i4_mb_x-ps_ent_ctxt->i4_wd_mbs] != pu1_slice_idx[i4_mb_x]))? 0 : 1;
740
741    pu1_ngbr_avlb = (void *)(&u4_ngbr_avlb);
742    pu1_top_nnz = ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
743    pu1_left_nnz = (UWORD8 *)&ps_ent_ctxt->u4_left_nnz_luma;
744
745    /* encode luma residue */
746
747    /* mb type intra 16x16 */
748    if (u4_mb_type == I16x16)
749    {
750        /* parse packed coeff data structure for residual data */
751        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]);
752        /* estimate nnz for the current mb */
753        u4_nC = 0;
754        if (u1_mb_a)
755            u4_nC += pu1_left_nnz[0];
756        if (u1_mb_b)
757            u4_nC += pu1_top_nnz[0];
758        if (u1_mb_a && u1_mb_b)
759            u4_nC = (u4_nC + 1) >> 1;
760
761        /* encode dc block */
762        ENTROPY_TRACE("Luma DC blk idx %d",0);
763        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]);
764
765        e_entropy_blk_type = CAVLC_LUMA_4x4_AC;
766    }
767
768    if (u4_cbp_luma & 1)
769    {
770        /* encode ac block index 8x8 = 0*/
771        /* parse packed coeff data structure for residual data */
772        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]);
773        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]);
774        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]);
775        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]);
776        /* derive sub block neighbor availability */
777
778        pu1_ngbr_avlb[0] = (u1_mb_b << 4) | (u1_mb_a);
779        pu1_ngbr_avlb[1] = (u1_mb_b << 4) | 1;
780        pu1_ngbr_avlb[2] = (1 << 4) | (u1_mb_a);
781        pu1_ngbr_avlb[3] = 0x11;
782        /* encode sub blk */
783        ENTROPY_TRACE("Luma blk idx %d",0);
784        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);
785    }
786    else
787    {
788        pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
789        pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
790    }
791
792    if (u4_cbp_luma & 2)
793    {
794        /* encode ac block index 8x8 = 1*/
795        /* parse packed coeff data structure for residual data */
796        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]);
797        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]);
798        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]);
799        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]);
800
801        /* derive sub block neighbor availability */
802        pu1_ngbr_avlb[1] = pu1_ngbr_avlb[0] = (u1_mb_b << 4) | 1;
803        pu1_ngbr_avlb[3] = pu1_ngbr_avlb[2] = 0x11;
804        /* encode sub blk */
805        ENTROPY_TRACE("Luma blk idx %d",1);
806        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);
807    }
808    else
809    {
810        (pu1_top_nnz + 2)[0] = (pu1_top_nnz + 2)[1] = 0;
811        pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
812    }
813
814    if (u4_cbp_luma & 0x4)
815    {
816        /* encode ac block index 8x8 = 2*/
817        /* parse packed coeff data structure for residual data */
818        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]);
819        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]);
820        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]);
821        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]);
822
823        /* derive sub block neighbor availability */
824        pu1_ngbr_avlb[2] = pu1_ngbr_avlb[0] = (1 << 4) | u1_mb_a;
825        pu1_ngbr_avlb[1] = pu1_ngbr_avlb[3] = 0x11;
826        /* encode sub blk */
827        ENTROPY_TRACE("Luma blk idx %d",2);
828        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));
829    }
830    else
831    {
832        pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
833        (pu1_left_nnz + 2)[0] = (pu1_left_nnz + 2)[1] = 0;
834    }
835
836    if (u4_cbp_luma & 0x8)
837    {
838        /* encode ac block index 8x8 = 3*/
839        /* parse packed coeff data structure for residual data */
840        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]);
841        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]);
842        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]);
843        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]);
844
845        /* derive sub block neighbor availability */
846        u4_ngbr_avlb = 0x11111111;
847        /* encode sub blk */
848        ENTROPY_TRACE("Luma blk idx %d",3);
849        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);
850    }
851    else
852    {
853        (pu1_top_nnz + 2)[0] = (pu1_top_nnz + 2)[1] = 0;
854        (pu1_left_nnz + 2)[0] = (pu1_left_nnz + 2)[1] = 0;
855    }
856
857    /* encode chroma residue */
858    if (u4_cbp_chroma & 3)
859    {
860        /* parse packed coeff data structure for residual data */
861        /* cb, cr */
862        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]);
863        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]);
864
865        /* encode dc block */
866        /* cb, cr */
867        ENTROPY_TRACE("Chroma DC blk idx %d",0);
868        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]);
869        ENTROPY_TRACE("Chroma DC blk idx %d",1);
870        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]);
871    }
872
873    pu1_top_nnz = ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
874    pu1_left_nnz = (UWORD8 *) &ps_ent_ctxt->u4_left_nnz_cbcr;
875
876    /* encode sub blk */
877    if (u4_cbp_chroma & 0x2)
878    {
879        /* encode ac block index 8x8 = 0*/
880        /* derive sub block neighbor availability */
881        pu1_ngbr_avlb[0] = (u1_mb_b << 4) | (u1_mb_a);
882        pu1_ngbr_avlb[1] = (u1_mb_b << 4) | 1;
883        pu1_ngbr_avlb[2] = (1 << 4) | (u1_mb_a);
884        pu1_ngbr_avlb[3] = 0x11;
885
886        /* parse packed coeff data structure for residual data */
887        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]);
888        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]);
889        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]);
890        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]);
891
892        ENTROPY_TRACE("Chroma AC blk idx %d",0);
893        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);
894    }
895    else
896    {
897        pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
898        pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
899    }
900
901    pu1_top_nnz += 2;
902    pu1_left_nnz += 2;
903
904    /* encode sub blk */
905    if (u4_cbp_chroma & 0x2)
906    {
907        /* parse packed coeff data structure for residual data */
908        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]);
909        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]);
910        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]);
911        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]);
912
913        ENTROPY_TRACE("Chroma AC blk idx %d",1);
914        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);
915    }
916    else
917    {
918        pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
919        pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
920    }
921
922    /* store the index of the next mb coeff data */
923    ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data;
924
925    return error_status;
926}
927
928#define GET_NUM_BITS(ps_bitstream) ((ps_bitstream->u4_strm_buf_offset << 3) + 32 - ps_bitstream->i4_bits_left_in_cw)
929
930/**
931*******************************************************************************
932*
933* @brief
934*  This function generates CAVLC coded bit stream for an Intra Slice.
935*
936* @description
937*  The mb syntax layer for intra slices constitutes luma mb mode, luma sub modes
938*  (if present), mb qp delta, coded block pattern, chroma mb mode and
939*  luma/chroma residue. These syntax elements are written as directed by table
940*  7.3.5 of h264 specification.
941*
942* @param[in] ps_ent_ctxt
943*  pointer to entropy context
944*
945* @returns error code
946*
947* @remarks none
948*
949*******************************************************************************
950*/
951IH264E_ERROR_T ih264e_write_islice_mb(entropy_ctxt_t *ps_ent_ctxt)
952{
953    /* error status */
954    IH264E_ERROR_T error_status = IH264E_SUCCESS;
955
956    /* bit stream ptr */
957    bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
958
959    /* packed header data */
960    UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
961
962    /* mb header info */
963    /*
964     * mb_tpm : mb type plus mode
965     * mb_type : luma mb type and chroma mb type are packed
966     * cbp : coded block pattern
967     * mb_qp_delta : mb qp delta
968     * chroma_intra_mode : chroma intra mode
969     * luma_intra_mode : luma intra mode
970     */
971    WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
972    WORD8 mb_qp_delta;
973
974    /* temp var */
975    WORD32 i, mb_type_stream;
976
977    WORD32 bitstream_start_offset, bitstream_end_offset;
978
979    /* Starting bitstream offset for header in bits */
980    bitstream_start_offset = GET_NUM_BITS(ps_bitstream);
981
982
983    /********************************************************************/
984    /*                    BEGIN HEADER GENERATION                       */
985    /********************************************************************/
986
987    /* mb header info */
988    mb_tpm = *pu1_byte++;
989    cbp = *pu1_byte++;
990    mb_qp_delta = *pu1_byte++;
991
992    /* mb type */
993    mb_type = mb_tpm & 0xF;
994    /* is intra ? */
995    if (mb_type == I16x16)
996    {
997        UWORD32 u4_cbp_l, u4_cbp_c;
998
999        u4_cbp_c = (cbp >> 4);
1000        u4_cbp_l = (cbp & 0xF);
1001        luma_intra_mode = (mb_tpm >> 4) & 3;
1002        chroma_intra_mode = (mb_tpm >> 6);
1003
1004        mb_type_stream =  luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1005
1006        /* write mb type */
1007        PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1008
1009        /* intra_chroma_pred_mode */
1010        PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1011    }
1012    else if (mb_type == I4x4)
1013    {
1014        /* mb sub blk modes */
1015        WORD32 intra_pred_mode_flag, rem_intra_mode;
1016        WORD32 byte;
1017
1018        chroma_intra_mode = (mb_tpm >> 6);
1019
1020        /* write mb type */
1021        PUT_BITS_UEV(ps_bitstream, 0, error_status, "mb type");
1022
1023        for (i = 0; i < 16; i += 2)
1024        {
1025            /* sub blk idx 1 */
1026            byte = *pu1_byte++;
1027
1028            intra_pred_mode_flag = byte & 0x1;
1029
1030            /* prev_intra4x4_pred_mode_flag */
1031            PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1032
1033            /* rem_intra4x4_pred_mode */
1034            if (!intra_pred_mode_flag)
1035            {
1036                rem_intra_mode = (byte & 0xF) >> 1;
1037                PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1038            }
1039
1040            /* sub blk idx 2 */
1041            byte >>= 4;
1042
1043            intra_pred_mode_flag = byte & 0x1;
1044
1045            /* prev_intra4x4_pred_mode_flag */
1046            PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1047
1048            /* rem_intra4x4_pred_mode */
1049            if (!intra_pred_mode_flag)
1050            {
1051                rem_intra_mode = (byte & 0xF) >> 1;
1052                PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1053            }
1054        }
1055
1056        /* intra_chroma_pred_mode */
1057        PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1058    }
1059    else if (mb_type == I8x8)
1060    {
1061        /* transform 8x8 flag */
1062        UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1063
1064        /* mb sub blk modes */
1065        WORD32 intra_pred_mode_flag, rem_intra_mode;
1066        WORD32 byte;
1067
1068        chroma_intra_mode = (mb_tpm >> 6);
1069
1070        ASSERT(0);
1071
1072        /* write mb type */
1073        PUT_BITS_UEV(ps_bitstream, 0, error_status, "mb type");
1074
1075        /* u4_transform_size_8x8_flag */
1076        PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status, "u4_transform_size_8x8_flag");
1077
1078        /* write sub block modes */
1079        for (i = 0; i < 4; i++)
1080        {
1081            /* sub blk idx 1 */
1082            byte = *pu1_byte++;
1083
1084            intra_pred_mode_flag = byte & 0x1;
1085
1086            /* prev_intra4x4_pred_mode_flag */
1087            PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1088
1089            /* rem_intra4x4_pred_mode */
1090            if (!intra_pred_mode_flag)
1091            {
1092                rem_intra_mode = (byte & 0xF) >> 1;
1093                PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1094            }
1095
1096            /* sub blk idx 2 */
1097            byte >>= 4;
1098
1099            intra_pred_mode_flag = byte & 0x1;
1100
1101            /* prev_intra4x4_pred_mode_flag */
1102            PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1103
1104            /* rem_intra4x4_pred_mode */
1105            if (!intra_pred_mode_flag)
1106            {
1107                rem_intra_mode = (byte & 0xF) >> 1;
1108                PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1109            }
1110        }
1111
1112        /* intra_chroma_pred_mode */
1113        PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1114    }
1115    else
1116    {
1117    }
1118
1119    /* coded_block_pattern */
1120    if (mb_type != I16x16)
1121    {
1122        PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][0], error_status, "coded_block_pattern");
1123    }
1124
1125    if (cbp || mb_type == I16x16)
1126    {
1127        /* mb_qp_delta */
1128        PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
1129    }
1130
1131    /* Ending bitstream offset for header in bits */
1132    bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1133
1134    ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset - bitstream_start_offset;
1135
1136    /* Starting bitstream offset for residue */
1137    bitstream_start_offset = bitstream_end_offset;
1138
1139    /* residual */
1140    error_status = ih264e_encode_residue(ps_ent_ctxt, mb_type, cbp);
1141
1142    /* Ending bitstream offset for reside in bits */
1143    bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1144    ps_ent_ctxt->u4_residue_bits[0] += bitstream_end_offset - bitstream_start_offset;
1145
1146    /* store the index of the next mb syntax layer */
1147    ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1148
1149    return error_status;
1150}
1151
1152/**
1153*******************************************************************************
1154*
1155* @brief
1156*  This function generates CAVLC coded bit stream for Inter slices
1157*
1158* @description
1159*  The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
1160*  (if present), mb qp delta, coded block pattern, chroma mb mode and
1161*  luma/chroma residue. These syntax elements are written as directed by table
1162*  7.3.5 of h264 specification
1163*
1164* @param[in] ps_ent_ctxt
1165*  pointer to entropy context
1166*
1167* @returns error code
1168*
1169* @remarks none
1170*
1171*******************************************************************************
1172*/
1173IH264E_ERROR_T ih264e_write_pslice_mb(entropy_ctxt_t *ps_ent_ctxt)
1174{
1175    /* error status */
1176    IH264E_ERROR_T error_status = IH264E_SUCCESS;
1177
1178    /* bit stream ptr */
1179    bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
1180
1181    /* packed header data */
1182    UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
1183
1184    /* mb header info */
1185    /*
1186     * mb_tpm : mb type plus mode
1187     * mb_type : luma mb type and chroma mb type are packed
1188     * cbp : coded block pattern
1189     * mb_qp_delta : mb qp delta
1190     * chroma_intra_mode : chroma intra mode
1191     * luma_intra_mode : luma intra mode
1192     * ps_pu :  Pointer to the array of structures having motion vectors, size
1193     * and position of sub partitions
1194     */
1195    WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
1196    WORD8 mb_qp_delta;
1197
1198    /* temp var */
1199    WORD32 i, mb_type_stream, cbptable = 1;
1200
1201    WORD32 is_inter = 0;
1202
1203    WORD32 bitstream_start_offset, bitstream_end_offset;
1204
1205    /* Starting bitstream offset for header in bits */
1206    bitstream_start_offset = GET_NUM_BITS(ps_bitstream);
1207
1208    /********************************************************************/
1209    /*                    BEGIN HEADER GENERATION                       */
1210    /********************************************************************/
1211
1212    /* mb header info */
1213    mb_tpm = *pu1_byte++;
1214
1215    /* mb type */
1216    mb_type = mb_tpm & 0xF;
1217
1218    /* check for skip */
1219    if (mb_type == PSKIP)
1220    {
1221        UWORD32 *nnz;
1222
1223        is_inter = 1;
1224
1225        /* increment skip counter */
1226        (*ps_ent_ctxt->pi4_mb_skip_run)++;
1227
1228        /* store the index of the next mb syntax layer */
1229        ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1230
1231        /* set nnz to zero */
1232        ps_ent_ctxt->u4_left_nnz_luma = 0;
1233        nnz = (UWORD32 *)ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
1234        *nnz = 0;
1235        ps_ent_ctxt->u4_left_nnz_cbcr = 0;
1236        nnz = (UWORD32 *)ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
1237        *nnz = 0;
1238
1239        /* residual */
1240        error_status = ih264e_encode_residue(ps_ent_ctxt, P16x16, 0);
1241
1242        bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1243
1244        ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1245
1246        return error_status;
1247    }
1248
1249    /* remaining mb header info */
1250    cbp = *pu1_byte++;
1251    mb_qp_delta = *pu1_byte++;
1252
1253    /* mb skip run */
1254    PUT_BITS_UEV(ps_bitstream, *ps_ent_ctxt->pi4_mb_skip_run, error_status, "mb skip run");
1255
1256    /* reset skip counter */
1257    *ps_ent_ctxt->pi4_mb_skip_run = 0;
1258
1259    /* is intra ? */
1260    if (mb_type == I16x16)
1261    {
1262        UWORD32 u4_cbp_l, u4_cbp_c;
1263
1264        is_inter = 0;
1265
1266        u4_cbp_c = (cbp >> 4);
1267        u4_cbp_l = (cbp & 0xF);
1268        luma_intra_mode = (mb_tpm >> 4) & 3;
1269        chroma_intra_mode = (mb_tpm >> 6);
1270
1271        mb_type_stream =  luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1272
1273        mb_type_stream += 5;
1274
1275        /* write mb type */
1276        PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1277
1278        /* intra_chroma_pred_mode */
1279        PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1280    }
1281    else if (mb_type == I4x4)
1282    {
1283        /* mb sub blk modes */
1284        WORD32 intra_pred_mode_flag, rem_intra_mode;
1285        WORD32 byte;
1286
1287        is_inter = 0;
1288
1289        chroma_intra_mode = (mb_tpm >> 6);
1290        cbptable = 0;
1291
1292        /* write mb type */
1293        PUT_BITS_UEV(ps_bitstream, 5, error_status, "mb type");
1294
1295        for (i = 0; i < 16; i += 2)
1296        {
1297            /* sub blk idx 1 */
1298            byte = *pu1_byte++;
1299
1300            intra_pred_mode_flag = byte & 0x1;
1301
1302            /* prev_intra4x4_pred_mode_flag */
1303            PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1304
1305            /* rem_intra4x4_pred_mode */
1306            if (!intra_pred_mode_flag)
1307            {
1308                rem_intra_mode = (byte & 0xF) >> 1;
1309                PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1310            }
1311
1312            /* sub blk idx 2 */
1313            byte >>= 4;
1314
1315            intra_pred_mode_flag = byte & 0x1;
1316
1317            /* prev_intra4x4_pred_mode_flag */
1318            PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1319
1320            /* rem_intra4x4_pred_mode */
1321            if (!intra_pred_mode_flag)
1322            {
1323                rem_intra_mode = (byte & 0xF) >> 1;
1324                PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1325            }
1326        }
1327
1328        /* intra_chroma_pred_mode */
1329        PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1330    }
1331    else if (mb_type == I8x8)
1332    {
1333        /* transform 8x8 flag */
1334        UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1335
1336        /* mb sub blk modes */
1337        WORD32 intra_pred_mode_flag, rem_intra_mode;
1338        WORD32 byte;
1339
1340        is_inter = 0;
1341
1342        chroma_intra_mode = (mb_tpm >> 6);
1343        cbptable = 0;
1344
1345        ASSERT(0);
1346
1347        /* write mb type */
1348        PUT_BITS_UEV(ps_bitstream, 5, error_status, "mb type");
1349
1350        /* u4_transform_size_8x8_flag */
1351        PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status, "u4_transform_size_8x8_flag");
1352
1353        /* write sub block modes */
1354        for (i = 0; i < 4; i++)
1355        {
1356            /* sub blk idx 1 */
1357            byte = *pu1_byte++;
1358
1359            intra_pred_mode_flag = byte & 0x1;
1360
1361            /* prev_intra4x4_pred_mode_flag */
1362            PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1363
1364            /* rem_intra4x4_pred_mode */
1365            if (!intra_pred_mode_flag)
1366            {
1367                rem_intra_mode = (byte & 0xF) >> 1;
1368                PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1369            }
1370
1371            /* sub blk idx 2 */
1372            byte >>= 4;
1373
1374            intra_pred_mode_flag = byte & 0x1;
1375
1376            /* prev_intra4x4_pred_mode_flag */
1377            PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status, "prev_intra4x4_pred_mode_flag");
1378
1379            /* rem_intra4x4_pred_mode */
1380            if (!intra_pred_mode_flag)
1381            {
1382                rem_intra_mode = (byte & 0xF) >> 1;
1383                PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status, "rem_intra4x4_pred_mode");
1384            }
1385        }
1386
1387        /* intra_chroma_pred_mode */
1388        PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1389    }
1390    else
1391    {
1392        /* inter macro block partition cnt */
1393        const UWORD8 au1_part_cnt[] = { 1, 2, 2, 4 };
1394
1395        /* mv ptr */
1396        WORD16 *pi2_mv_ptr = (WORD16 *)pu1_byte;
1397
1398        /* number of partitions for the current mb */
1399        UWORD32 u4_part_cnt = au1_part_cnt[mb_type - 3];
1400
1401        is_inter = 1;
1402
1403        /* write mb type */
1404        PUT_BITS_UEV(ps_bitstream, mb_type - 3, error_status, "mb type");
1405
1406        for (i = 0; i < (WORD32)u4_part_cnt; i++)
1407        {
1408            PUT_BITS_SEV(ps_bitstream, *pi2_mv_ptr++, error_status, "mv x");
1409
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
1429    /* Ending bitstream offset for header in bits */
1430    bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1431
1432    ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1433
1434    /* start bitstream offset for residue in bits */
1435    bitstream_start_offset = bitstream_end_offset;
1436
1437    /* residual */
1438    error_status = ih264e_encode_residue(ps_ent_ctxt, mb_type, cbp);
1439
1440    /* Ending bitstream offset for residue in bits */
1441    bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
1442
1443    ps_ent_ctxt->u4_residue_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1444
1445    /* store the index of the next mb syntax layer */
1446    ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1447
1448    return error_status;
1449}
1450