|
|
/******************************************************************************
|
|
|
*
|
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
|
*
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
* You may obtain a copy of the License at:
|
|
|
*
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
*
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
* See the License for the specific language governing permissions and
|
|
|
* limitations under the License.
|
|
|
*
|
|
|
*****************************************************************************
|
|
|
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
* @file
|
|
|
* ih264e_cabac.c
|
|
|
*
|
|
|
* @brief
|
|
|
* Contains all functions to encode in CABAC entropy mode
|
|
|
*
|
|
|
*
|
|
|
* @author
|
|
|
* Doney Alex
|
|
|
*
|
|
|
* @par List of Functions:
|
|
|
*
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
/* File Includes */
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
/* System include files */
|
|
|
#include <stdio.h>
|
|
|
#include <assert.h>
|
|
|
#include <limits.h>
|
|
|
#include <string.h>
|
|
|
|
|
|
/* User include files */
|
|
|
#include "ih264e_config.h"
|
|
|
#include "ih264_typedefs.h"
|
|
|
#include "iv2.h"
|
|
|
#include "ive2.h"
|
|
|
#include "ih264_debug.h"
|
|
|
#include "ih264_defs.h"
|
|
|
#include "ih264e_defs.h"
|
|
|
#include "ih264_macros.h"
|
|
|
#include "ih264e_error.h"
|
|
|
#include "ih264e_bitstream.h"
|
|
|
#include "ime_distortion_metrics.h"
|
|
|
#include "ime_defs.h"
|
|
|
#include "ime_structs.h"
|
|
|
#include "ih264_error.h"
|
|
|
#include "ih264_structs.h"
|
|
|
#include "ih264_trans_quant_itrans_iquant.h"
|
|
|
#include "ih264_inter_pred_filters.h"
|
|
|
#include "ih264_mem_fns.h"
|
|
|
#include "ih264_padding.h"
|
|
|
#include "ih264_platform_macros.h"
|
|
|
#include "ih264_intra_pred_filters.h"
|
|
|
#include "ih264_deblk_edge_filters.h"
|
|
|
#include "ih264_cabac_tables.h"
|
|
|
#include "irc_cntrl_param.h"
|
|
|
#include "irc_frame_info_collector.h"
|
|
|
#include "ih264e_rate_control.h"
|
|
|
#include "ih264e_cabac_structs.h"
|
|
|
#include "ih264e_structs.h"
|
|
|
#include "ih264e_cabac.h"
|
|
|
#include "ih264e_encode_header.h"
|
|
|
#include "ih264_cavlc_tables.h"
|
|
|
#include "ih264e_cavlc.h"
|
|
|
#include "ih264e_statistics.h"
|
|
|
#include "ih264e_trace.h"
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
/* Function Definitions */
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
*
|
|
|
* @brief
|
|
|
* Encodes mb_skip_flag using CABAC entropy coding mode.
|
|
|
*
|
|
|
* @param[in] u1_mb_skip_flag
|
|
|
* mb_skip_flag
|
|
|
*
|
|
|
* @param[in] ps_cabac_ctxt
|
|
|
* Pointer to cabac context structure
|
|
|
*
|
|
|
* @param[in] u4_ctxidx_offset
|
|
|
* ctxIdxOffset for mb_skip_flag context
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_enc_mb_skip(UWORD8 u1_mb_skip_flag,
|
|
|
cabac_ctxt_t *ps_cabac_ctxt,
|
|
|
UWORD32 u4_ctxidx_offset)
|
|
|
{
|
|
|
|
|
|
UWORD8 u4_ctx_inc;
|
|
|
WORD8 a, b;
|
|
|
a = ((ps_cabac_ctxt->ps_left_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK) ?
|
|
|
0 : 1);
|
|
|
b = ((ps_cabac_ctxt->ps_top_ctxt_mb_info->u1_mb_type & CAB_SKIP_MASK) ?
|
|
|
0 : 1);
|
|
|
|
|
|
u4_ctx_inc = a + b;
|
|
|
/* Encode the bin */
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt,
|
|
|
(UWORD32) u1_mb_skip_flag,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctxidx_offset
|
|
|
+ u4_ctx_inc);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
/* ! < Table 9-36 <20> Binarization for macroblock types in I slices in ITU_T_H264-201402
|
|
|
* Bits 0-7 : binarised value
|
|
|
* Bits 8-15: length of binary sequence
|
|
|
*/
|
|
|
static const UWORD32 u4_mb_type_intra[26] =
|
|
|
{ 0x0100, 0x0620, 0x0621, 0x0622, 0x0623, 0x0748, 0x0749, 0x074a, 0x074b,
|
|
|
0x074c, 0x074d, 0x074e, 0x074f, 0x0628, 0x0629, 0x062a, 0x062b, 0x0758,
|
|
|
0x0759, 0x075a, 0x075b, 0x075c, 0x075d, 0x075e, 0x075f, 0x0203 };
|
|
|
|
|
|
|
|
|
/* CtxInc for mb types */
|
|
|
static const UWORD32 u4_mb_ctxinc[2][26] =
|
|
|
{
|
|
|
/* Intra CtxInc's */
|
|
|
{ 0x00,
|
|
|
0x03467, 0x03467, 0x03467, 0x03467, 0x034567, 0x034567, 0x034567,
|
|
|
0x034567, 0x034567, 0x034567, 0x034567, 0x034567, 0x03467, 0x03467,
|
|
|
0x03467, 0x03467, 0x034567, 0x034567, 0x034567, 0x034567, 0x034567,
|
|
|
0x034567, 0x034567, 0x034567, 0x00},
|
|
|
/* Inter CtxInc's */
|
|
|
{ 0x00,
|
|
|
0x001233, 0x001233, 0x001233, 0x001233, 0x0012233, 0x0012233, 0x0012233,
|
|
|
0x0012233, 0x0012233, 0x0012233, 0x0012233, 0x0012233, 0x001233, 0x001233,
|
|
|
0x001233, 0x001233, 0x0012233, 0x0012233, 0x0012233, 0x0012233, 0x0012233,
|
|
|
0x0012233, 0x0012233, 0x0012233, 0x00}
|
|
|
};
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
*
|
|
|
* @brief
|
|
|
* Encodes mb_type for an intra MB.
|
|
|
*
|
|
|
* @param[in] u4_slice_type
|
|
|
* slice type
|
|
|
*
|
|
|
* @param[in] u4_intra_mb_type
|
|
|
* MB type (Table 7-11)
|
|
|
*
|
|
|
* @param[in] ps_cabac_ctxt
|
|
|
* Pointer to cabac context structure
|
|
|
*
|
|
|
** @param[in] u4_ctxidx_offset
|
|
|
* ctxIdxOffset for mb_type context
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
|
|
|
static void ih264e_cabac_enc_intra_mb_type(UWORD32 u4_slice_type,
|
|
|
UWORD32 u4_intra_mb_type,
|
|
|
cabac_ctxt_t *ps_cabac_ctxt,
|
|
|
UWORD32 u4_ctx_idx_offset)
|
|
|
{
|
|
|
|
|
|
encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env);
|
|
|
bin_ctxt_model *pu1_mb_bin_ctxt, *pu1_bin_ctxt;
|
|
|
UWORD8 u1_bin;
|
|
|
mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info;
|
|
|
mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
|
|
|
UWORD32 u4_bins;
|
|
|
UWORD32 u4_ctx_inc;
|
|
|
WORD8 i1_bins_len;
|
|
|
UWORD32 u4_code_int_range;
|
|
|
UWORD32 u4_code_int_low;
|
|
|
UWORD16 u2_quant_code_int_range;
|
|
|
UWORD16 u4_code_int_range_lps;
|
|
|
WORD8 i;
|
|
|
UWORD8 u1_ctx_inc;
|
|
|
UWORD32 u4_table_val;
|
|
|
|
|
|
pu1_mb_bin_ctxt = ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctx_idx_offset;
|
|
|
|
|
|
u4_bins = u4_mb_type_intra[u4_intra_mb_type];
|
|
|
i1_bins_len = (WORD8) ((u4_bins >> 8) & 0x0f);
|
|
|
u4_ctx_inc = u4_mb_ctxinc[(u4_slice_type != ISLICE)][u4_intra_mb_type];
|
|
|
u1_ctx_inc = 0;
|
|
|
if (u4_slice_type == ISLICE)
|
|
|
{
|
|
|
if (ps_left_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
|
|
|
u1_ctx_inc += ((ps_left_ctxt->u1_mb_type != CAB_I4x4) ? 1 : 0);
|
|
|
if (ps_top_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
|
|
|
u1_ctx_inc += ((ps_top_ctxt->u1_mb_type != CAB_I4x4) ? 1 : 0);
|
|
|
|
|
|
u4_ctx_inc = (u4_ctx_inc | (u1_ctx_inc << ((i1_bins_len - 1) << 2)));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
pu1_mb_bin_ctxt += 3;
|
|
|
if (u4_slice_type == BSLICE)
|
|
|
pu1_mb_bin_ctxt += 2;
|
|
|
|
|
|
}
|
|
|
|
|
|
u4_code_int_range = ps_cab_enc_env->u4_code_int_range;
|
|
|
u4_code_int_low = ps_cab_enc_env->u4_code_int_low;
|
|
|
|
|
|
for (i = (i1_bins_len - 1); i >= 0; i--)
|
|
|
{
|
|
|
WORD32 shift;
|
|
|
|
|
|
u1_ctx_inc = ((u4_ctx_inc >> (i << 2)) & 0x0f);
|
|
|
u1_bin = ((u4_bins >> i) & 0x01);
|
|
|
/* Encode the bin */
|
|
|
pu1_bin_ctxt = pu1_mb_bin_ctxt + u1_ctx_inc;
|
|
|
if (i != (i1_bins_len - 2))
|
|
|
{
|
|
|
WORD8 i1_mps = !!((*pu1_bin_ctxt) & (0x40));
|
|
|
WORD8 i1_state = (*pu1_bin_ctxt) & 0x3F;
|
|
|
|
|
|
u2_quant_code_int_range = ((u4_code_int_range >> 6) & 0x03);
|
|
|
u4_table_val =
|
|
|
gau4_ih264_cabac_table[i1_state][u2_quant_code_int_range];
|
|
|
u4_code_int_range_lps = u4_table_val & 0xFF;
|
|
|
|
|
|
u4_code_int_range -= u4_code_int_range_lps;
|
|
|
if (u1_bin != i1_mps)
|
|
|
{
|
|
|
u4_code_int_low += u4_code_int_range;
|
|
|
u4_code_int_range = u4_code_int_range_lps;
|
|
|
if (i1_state == 0)
|
|
|
{
|
|
|
/* MPS(CtxIdx) = 1 - MPS(CtxIdx) */
|
|
|
i1_mps = 1 - i1_mps;
|
|
|
}
|
|
|
|
|
|
i1_state = (u4_table_val >> 15) & 0x3F;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
i1_state = (u4_table_val >> 8) & 0x3F;
|
|
|
|
|
|
}
|
|
|
|
|
|
(*pu1_bin_ctxt) = (i1_mps << 6) | i1_state;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
u4_code_int_range -= 2;
|
|
|
}
|
|
|
|
|
|
/* Renormalize */
|
|
|
/*****************************************************************/
|
|
|
/* Renormalization; calculate bits generated based on range(R) */
|
|
|
/* Note : 6 <= R < 512; R is 2 only for terminating encode */
|
|
|
/*****************************************************************/
|
|
|
GETRANGE(shift, u4_code_int_range);
|
|
|
shift = 9 - shift;
|
|
|
u4_code_int_low <<= shift;
|
|
|
u4_code_int_range <<= shift;
|
|
|
|
|
|
/* bits to be inserted in the bitstream */
|
|
|
ps_cab_enc_env->u4_bits_gen += shift;
|
|
|
ps_cab_enc_env->u4_code_int_range = u4_code_int_range;
|
|
|
ps_cab_enc_env->u4_code_int_low = u4_code_int_low;
|
|
|
|
|
|
/* generate stream when a byte is ready */
|
|
|
if (ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
|
|
|
{
|
|
|
ih264e_cabac_put_byte(ps_cabac_ctxt);
|
|
|
u4_code_int_range = ps_cab_enc_env->u4_code_int_range;
|
|
|
u4_code_int_low = ps_cab_enc_env->u4_code_int_low;
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
*
|
|
|
* @brief
|
|
|
* Encodes prev_intra4x4_pred_mode_flag and
|
|
|
* rem_intra4x4_pred_mode using CABAC entropy coding mode
|
|
|
*
|
|
|
* @param[in] ps_cabac_ctxt
|
|
|
* Pointer to cabac context structure
|
|
|
*
|
|
|
* @param[in] pu1_intra_4x4_modes
|
|
|
* Pointer to array containing prev_intra4x4_pred_mode_flag and
|
|
|
* rem_intra4x4_pred_mode
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_enc_4x4mb_modes(cabac_ctxt_t *ps_cabac_ctxt,
|
|
|
UWORD8 *pu1_intra_4x4_modes)
|
|
|
{
|
|
|
WORD32 i;
|
|
|
WORD8 byte;
|
|
|
for (i = 0; i < 16; i += 2)
|
|
|
{
|
|
|
/* sub blk idx 1 */
|
|
|
byte = pu1_intra_4x4_modes[i >> 1];
|
|
|
if (byte & 0x1)
|
|
|
{
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt,
|
|
|
1,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ PREV_INTRA4X4_PRED_MODE_FLAG);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* Binarization is FL and Cmax=7 */
|
|
|
ih264e_encode_decision_bins(byte & 0xF,
|
|
|
4,
|
|
|
0x05554,
|
|
|
4,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ REM_INTRA4X4_PRED_MODE - 5,
|
|
|
ps_cabac_ctxt);
|
|
|
}
|
|
|
/* sub blk idx 2 */
|
|
|
byte >>= 4;
|
|
|
if (byte & 0x1)
|
|
|
{
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt,
|
|
|
1,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ PREV_INTRA4X4_PRED_MODE_FLAG);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ih264e_encode_decision_bins(byte & 0xF,
|
|
|
4,
|
|
|
0x05554,
|
|
|
4,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ REM_INTRA4X4_PRED_MODE - 5,
|
|
|
ps_cabac_ctxt);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
*
|
|
|
* @brief
|
|
|
* Encodes chroma intrapred mode for the MB.
|
|
|
*
|
|
|
* @param[in] u1_chroma_pred_mode
|
|
|
* Chroma intr prediction mode
|
|
|
*
|
|
|
* @param[in] ps_cabac_ctxt
|
|
|
* Pointer to cabac context structure
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_enc_chroma_predmode(UWORD8 u1_chroma_pred_mode,
|
|
|
cabac_ctxt_t *ps_cabac_ctxt)
|
|
|
{
|
|
|
|
|
|
WORD8 i1_temp;
|
|
|
mb_info_ctxt_t *ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
|
|
|
mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info;
|
|
|
mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
|
|
|
UWORD32 u4_bins = 0;
|
|
|
WORD8 i1_bins_len = 1;
|
|
|
UWORD32 u4_ctx_inc = 0;
|
|
|
UWORD8 a, b;
|
|
|
a = ((ps_left_ctxt->u1_intrapred_chroma_mode != 0) ? 1 : 0);
|
|
|
b = ((ps_top_ctxt->u1_intrapred_chroma_mode != 0) ? 1 : 0);
|
|
|
|
|
|
/* Binarization is TU and Cmax=3 */
|
|
|
ps_curr_ctxt->u1_intrapred_chroma_mode = u1_chroma_pred_mode;
|
|
|
|
|
|
u4_ctx_inc = a + b;
|
|
|
u4_ctx_inc = (u4_ctx_inc | 0x330);
|
|
|
if (u1_chroma_pred_mode)
|
|
|
{
|
|
|
u4_bins = 1;
|
|
|
i1_temp = u1_chroma_pred_mode;
|
|
|
i1_temp--;
|
|
|
/* Put a stream of 1's of length Chromaps_pred_mode_ctxt value */
|
|
|
while (i1_temp)
|
|
|
{
|
|
|
u4_bins = (u4_bins | (1 << i1_bins_len));
|
|
|
i1_bins_len++;
|
|
|
i1_temp--;
|
|
|
}
|
|
|
/* If Chromaps_pred_mode_ctxt < Cmax i.e 3. Terminate put a zero */
|
|
|
if (u1_chroma_pred_mode < 3)
|
|
|
{
|
|
|
i1_bins_len++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
ih264e_encode_decision_bins(u4_bins,
|
|
|
i1_bins_len,
|
|
|
u4_ctx_inc,
|
|
|
3,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ INTRA_CHROMA_PRED_MODE,
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
*
|
|
|
* @brief
|
|
|
* Encodes CBP for the MB.
|
|
|
*
|
|
|
* @param[in] u1_cbp
|
|
|
* CBP for the MB
|
|
|
*
|
|
|
* @param[in] ps_cabac_ctxt
|
|
|
* Pointer to cabac context structure
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_enc_cbp(UWORD32 u4_cbp, cabac_ctxt_t *ps_cabac_ctxt)
|
|
|
{
|
|
|
mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info;
|
|
|
mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
|
|
|
WORD8 i2_cbp_chroma, i, j;
|
|
|
UWORD8 u1_ctxt_inc, u1_bin;
|
|
|
UWORD8 a, b;
|
|
|
UWORD32 u4_ctx_inc;
|
|
|
UWORD32 u4_bins;
|
|
|
WORD8 i1_bins_len;
|
|
|
|
|
|
/* CBP Luma, FL, Cmax = 15, L = 4 */
|
|
|
u4_ctx_inc = 0;
|
|
|
u4_bins = 0;
|
|
|
i1_bins_len = 5;
|
|
|
for (i = 0; i < 4; i++)
|
|
|
{
|
|
|
/* calulate ctxtInc, depending on neighbour availability */
|
|
|
/* u1_ctxt_inc = CondTerm(A) + 2 * CondTerm(B);
|
|
|
A: Left block and B: Top block */
|
|
|
|
|
|
/* Check for Top availability */
|
|
|
if (i >> 1)
|
|
|
{
|
|
|
j = i - 2;
|
|
|
/* Top is available always and it's current MB */
|
|
|
b = (((u4_cbp >> j) & 0x01) != 0 ? 0 : 1);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* for blocks whose top reference is in another MB */
|
|
|
{
|
|
|
j = i + 2;
|
|
|
b = ((ps_top_ctxt->u1_cbp >> j) & 0x01) ? 0 : 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Check for Left availability */
|
|
|
if (i & 0x01)
|
|
|
{
|
|
|
/* Left is available always and it's current MB */
|
|
|
j = i - 1;
|
|
|
a = (((u4_cbp >> j) & 0x01) != 0 ? 0 : 1);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
{
|
|
|
j = i + 1;
|
|
|
a = ((ps_left_ctxt->u1_cbp >> j) & 0x01) ? 0 : 1;
|
|
|
}
|
|
|
}
|
|
|
u1_ctxt_inc = a + 2 * b;
|
|
|
u1_bin = ((u4_cbp >> i) & 0x01);
|
|
|
u4_ctx_inc = (u4_ctx_inc | (u1_ctxt_inc << (i << 2)));
|
|
|
u4_bins = (u4_bins | (u1_bin << i));
|
|
|
}
|
|
|
|
|
|
/* CBP Chroma, TU, Cmax = 2 */
|
|
|
i2_cbp_chroma = u4_cbp >> 4;
|
|
|
/* calulate ctxtInc, depending on neighbour availability */
|
|
|
a = (ps_left_ctxt->u1_cbp > 15) ? 1 : 0;
|
|
|
b = (ps_top_ctxt->u1_cbp > 15) ? 1 : 0;
|
|
|
|
|
|
u1_ctxt_inc = a + 2 * b;
|
|
|
if (i2_cbp_chroma)
|
|
|
{
|
|
|
u4_ctx_inc = u4_ctx_inc | ((4 + u1_ctxt_inc) << 16);
|
|
|
u4_bins = (u4_bins | 0x10);
|
|
|
/* calulate ctxtInc, depending on neighbour availability */
|
|
|
a = (ps_left_ctxt->u1_cbp > 31) ? 1 : 0;
|
|
|
b = (ps_top_ctxt->u1_cbp > 31) ? 1 : 0;
|
|
|
u1_ctxt_inc = a + 2 * b;
|
|
|
u4_ctx_inc = u4_ctx_inc | ((8 + u1_ctxt_inc) << 20);
|
|
|
u4_bins = (u4_bins | (((i2_cbp_chroma >> 1) & 0x01) << i1_bins_len));
|
|
|
i1_bins_len++;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
u4_ctx_inc = (u4_ctx_inc | ((4 + u1_ctxt_inc) << 16));
|
|
|
}
|
|
|
ih264e_encode_decision_bins(u4_bins, i1_bins_len, u4_ctx_inc, 8,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table + CBP_LUMA,
|
|
|
ps_cabac_ctxt);
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
*
|
|
|
* @brief
|
|
|
* Encodes mb_qp_delta for the MB.
|
|
|
*
|
|
|
* @param[in] i1_mb_qp_delta
|
|
|
* mb_qp_delta
|
|
|
*
|
|
|
* @param[in] ps_cabac_ctxt
|
|
|
* Pointer to cabac context structure
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_enc_mb_qp_delta(WORD8 i1_mb_qp_delta,
|
|
|
cabac_ctxt_t *ps_cabac_ctxt)
|
|
|
{
|
|
|
UWORD8 u1_code_num;
|
|
|
UWORD8 u1_ctxt_inc;
|
|
|
|
|
|
UWORD32 u4_ctx_inc;
|
|
|
UWORD32 u4_bins;
|
|
|
WORD8 i1_bins_len;
|
|
|
UWORD8 u1_ctx_inc, u1_bin;
|
|
|
/* Range of ps_mb_qp_delta_ctxt= -26 to +25 inclusive */
|
|
|
ASSERT((i1_mb_qp_delta < 26) && (i1_mb_qp_delta > -27));
|
|
|
/* if ps_mb_qp_delta_ctxt=0, then codeNum=0 */
|
|
|
u1_code_num = 0;
|
|
|
if (i1_mb_qp_delta > 0)
|
|
|
u1_code_num = (i1_mb_qp_delta << 1) - 1;
|
|
|
else if (i1_mb_qp_delta < 0)
|
|
|
u1_code_num = (ABS(i1_mb_qp_delta)) << 1;
|
|
|
|
|
|
u4_ctx_inc = 0;
|
|
|
u4_bins = 0;
|
|
|
i1_bins_len = 1;
|
|
|
/* calculate ctxtInc, depending on neighbour availability */
|
|
|
u1_ctxt_inc = (!(!(ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt)));
|
|
|
ps_cabac_ctxt->i1_prevps_mb_qp_delta_ctxt = i1_mb_qp_delta;
|
|
|
|
|
|
if (u1_code_num == 0)
|
|
|
{
|
|
|
/* b0 */
|
|
|
u1_bin = (UWORD8) (u4_bins);
|
|
|
u1_ctx_inc = u1_ctxt_inc & 0x0f;
|
|
|
/* Encode the bin */
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt,
|
|
|
u1_bin,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table + MB_QP_DELTA
|
|
|
+ u1_ctx_inc);
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* b0 */
|
|
|
u4_ctx_inc = u1_ctxt_inc;
|
|
|
u4_bins = 1;
|
|
|
u1_code_num--;
|
|
|
if (u1_code_num == 0)
|
|
|
{
|
|
|
/* b1 */
|
|
|
u4_ctx_inc = (u4_ctx_inc | 0x20);
|
|
|
i1_bins_len++;
|
|
|
ih264e_encode_decision_bins(u4_bins, i1_bins_len, u4_ctx_inc, 3,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table + MB_QP_DELTA,
|
|
|
ps_cabac_ctxt);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* b1 */
|
|
|
u4_ctx_inc = (u4_ctx_inc | 0x20);
|
|
|
u4_bins = (u4_bins | (1 << i1_bins_len));
|
|
|
i1_bins_len++;
|
|
|
u1_code_num--;
|
|
|
/* BinIdx from b2 onwards */
|
|
|
if (u1_code_num < 30)
|
|
|
{ /* maximum i1_bins_len = 31 */
|
|
|
while (u1_code_num)
|
|
|
{
|
|
|
u4_bins = (u4_bins | (1 << i1_bins_len));
|
|
|
i1_bins_len++;
|
|
|
u1_code_num--;
|
|
|
};
|
|
|
u4_ctx_inc = (u4_ctx_inc | 0x300);
|
|
|
i1_bins_len++;
|
|
|
ih264e_encode_decision_bins(u4_bins,
|
|
|
i1_bins_len,
|
|
|
u4_ctx_inc,
|
|
|
2,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ MB_QP_DELTA,
|
|
|
ps_cabac_ctxt);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* maximum i1_bins_len = 53 */
|
|
|
u4_bins = 0xffffffff;
|
|
|
i1_bins_len = 32;
|
|
|
u4_ctx_inc = (u4_ctx_inc | 0x300);
|
|
|
u1_code_num -= 30;
|
|
|
ih264e_encode_decision_bins(u4_bins,
|
|
|
i1_bins_len,
|
|
|
u4_ctx_inc,
|
|
|
2,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ MB_QP_DELTA,
|
|
|
ps_cabac_ctxt);
|
|
|
u4_bins = 0;
|
|
|
i1_bins_len = 0;
|
|
|
u4_ctx_inc = 0x033;
|
|
|
while (u1_code_num)
|
|
|
{
|
|
|
u4_bins = (u4_bins | (1 << i1_bins_len));
|
|
|
i1_bins_len++;
|
|
|
u1_code_num--;
|
|
|
};
|
|
|
|
|
|
u4_ctx_inc = (u4_ctx_inc | 0x300);
|
|
|
i1_bins_len++;
|
|
|
ih264e_encode_decision_bins(u4_bins,
|
|
|
i1_bins_len,
|
|
|
u4_ctx_inc,
|
|
|
1,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ MB_QP_DELTA,
|
|
|
ps_cabac_ctxt);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
* @brief
|
|
|
* Encodes 4residual_block_cabac as defined in 7.3.5.3.3.
|
|
|
*
|
|
|
* @param[in] pi2_res_block
|
|
|
* pointer to the array of residues
|
|
|
*
|
|
|
* @param[in] u1_nnz
|
|
|
* Number of non zero coeffs in the block
|
|
|
*
|
|
|
* @param[in] u1_max_num_coeffs
|
|
|
* Max number of coeffs that can be there in the block
|
|
|
*
|
|
|
* @param[in] u2_sig_coeff_map
|
|
|
* Significant coeff map
|
|
|
*
|
|
|
* @param[in] u4_ctx_cat_offset
|
|
|
* ctxIdxOffset for absolute value contexts
|
|
|
*
|
|
|
* @param[in] pu1_ctxt_sig_coeff
|
|
|
* Pointer to residual state variables
|
|
|
*
|
|
|
* @param[in] ps_cabac_ctxt
|
|
|
* Pointer to cabac context structure
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_write_coeff4x4(WORD16 *pi2_res_block, UWORD8 u1_nnz,
|
|
|
UWORD8 u1_max_num_coeffs,
|
|
|
UWORD16 u2_sig_coeff_map,
|
|
|
UWORD32 u4_ctx_cat_offset,
|
|
|
bin_ctxt_model *pu1_ctxt_sig_coeff,
|
|
|
cabac_ctxt_t *ps_cabac_ctxt)
|
|
|
{
|
|
|
|
|
|
WORD8 i;
|
|
|
WORD16 *pi16_coeffs;
|
|
|
UWORD32 u4_sig_coeff, u4_bins;
|
|
|
UWORD32 u4_ctx_inc;
|
|
|
UWORD8 u1_last_sig_coef_index = (31 - CLZ(u2_sig_coeff_map));
|
|
|
|
|
|
/* Always put Coded Block Flag as 1 */
|
|
|
|
|
|
pi16_coeffs = pi2_res_block;
|
|
|
{
|
|
|
bin_ctxt_model *pu1_bin_ctxt;
|
|
|
UWORD8 u1_bin, uc_last;
|
|
|
|
|
|
i = 0;
|
|
|
pu1_bin_ctxt = pu1_ctxt_sig_coeff;
|
|
|
u4_sig_coeff = 0;
|
|
|
u1_bin = 1;
|
|
|
if ((u1_last_sig_coef_index))
|
|
|
{
|
|
|
u1_bin = !!(u2_sig_coeff_map & 01);
|
|
|
}
|
|
|
uc_last = 1;
|
|
|
|
|
|
do
|
|
|
{
|
|
|
/* Encode Decision */
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt, u1_bin, pu1_bin_ctxt);
|
|
|
|
|
|
if (u1_bin & uc_last)
|
|
|
{
|
|
|
u4_sig_coeff = (u4_sig_coeff | (1 << i));
|
|
|
pu1_bin_ctxt = pu1_ctxt_sig_coeff + i
|
|
|
+ LAST_SIGNIFICANT_COEFF_FLAG_FRAME
|
|
|
- SIGNIFICANT_COEFF_FLAG_FRAME;
|
|
|
u1_bin = (i == u1_last_sig_coef_index);
|
|
|
uc_last = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
i = i + 1;
|
|
|
pu1_bin_ctxt = pu1_ctxt_sig_coeff + i;
|
|
|
u1_bin = (i == u1_last_sig_coef_index);
|
|
|
uc_last = 1;
|
|
|
if ((i != u1_last_sig_coef_index))
|
|
|
{
|
|
|
u1_bin = !!((u2_sig_coeff_map >> i) & 01);
|
|
|
}
|
|
|
}
|
|
|
}while (!((i > u1_last_sig_coef_index)
|
|
|
|| (i > (u1_max_num_coeffs - 1))));
|
|
|
}
|
|
|
|
|
|
/* Encode coeff_abs_level_minus1 and coeff_sign_flag */
|
|
|
{
|
|
|
UWORD8 u1_sign;
|
|
|
UWORD16 u2_abs_level;
|
|
|
UWORD8 u1_abs_level_equal1 = 1, u1_abs_level_gt1 = 0;
|
|
|
UWORD8 u1_ctx_inc;
|
|
|
UWORD8 u1_coff;
|
|
|
WORD16 i2_sufs;
|
|
|
WORD8 i1_bins_len;
|
|
|
i = u1_last_sig_coef_index;
|
|
|
pi16_coeffs = pi2_res_block + u1_nnz - 1;
|
|
|
do
|
|
|
{
|
|
|
{
|
|
|
u4_sig_coeff = u4_sig_coeff & ((1 << i) - 1);
|
|
|
u4_bins = 0;
|
|
|
u4_ctx_inc = 0;
|
|
|
i1_bins_len = 1;
|
|
|
/* Encode the AbsLevelMinus1 */
|
|
|
u2_abs_level = ABS(*(pi16_coeffs)) - 1;
|
|
|
/* CtxInc for bin0 */
|
|
|
u4_ctx_inc = MIN(u1_abs_level_equal1, 4);
|
|
|
/* CtxInc for remaining */
|
|
|
u1_ctx_inc = 5 + MIN(u1_abs_level_gt1, 4);
|
|
|
u4_ctx_inc = u4_ctx_inc + (u1_ctx_inc << 4);
|
|
|
if (u2_abs_level)
|
|
|
{
|
|
|
u1_abs_level_gt1++;
|
|
|
u1_abs_level_equal1 = 0;
|
|
|
}
|
|
|
if (!u1_abs_level_gt1)
|
|
|
u1_abs_level_equal1++;
|
|
|
|
|
|
u1_coff = 14;
|
|
|
if (u2_abs_level >= u1_coff)
|
|
|
{
|
|
|
/* Prefix TU i.e string of 14 1's */
|
|
|
u4_bins = 0x3fff;
|
|
|
i1_bins_len = 14;
|
|
|
ih264e_encode_decision_bins(u4_bins, i1_bins_len,
|
|
|
u4_ctx_inc, 1, ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ u4_ctx_cat_offset,
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
/* Suffix, uses EncodeBypass */
|
|
|
i2_sufs = u2_abs_level - u1_coff;
|
|
|
|
|
|
u4_bins = ih264e_cabac_UEGk0_binarization(i2_sufs,
|
|
|
&i1_bins_len);
|
|
|
|
|
|
ih264e_cabac_encode_bypass_bins(ps_cabac_ctxt, u4_bins,
|
|
|
i1_bins_len);
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* Prefix only */
|
|
|
u4_bins = (1 << u2_abs_level) - 1;
|
|
|
i1_bins_len = u2_abs_level + 1;
|
|
|
/* Encode Terminating bit */
|
|
|
ih264e_encode_decision_bins(u4_bins, i1_bins_len,
|
|
|
u4_ctx_inc, 1, ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ u4_ctx_cat_offset,
|
|
|
ps_cabac_ctxt);
|
|
|
}
|
|
|
}
|
|
|
/* encode coeff_sign_flag[i] */
|
|
|
u1_sign = ((*pi16_coeffs) < 0) ? 1 : 0;
|
|
|
ih264e_cabac_encode_bypass_bin(ps_cabac_ctxt, u1_sign);
|
|
|
i = CLZ(u4_sig_coeff);
|
|
|
i = 31 - i;
|
|
|
pi16_coeffs--;
|
|
|
}while (u4_sig_coeff);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
* @brief
|
|
|
* Write DC coeffs for intra predicted luma block
|
|
|
*
|
|
|
* @param[in] ps_ent_ctxt
|
|
|
* Pointer to entropy context structure
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_encode_residue_luma_dc(entropy_ctxt_t *ps_ent_ctxt)
|
|
|
{
|
|
|
|
|
|
/* CABAC context */
|
|
|
cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
|
|
|
tu_sblk_coeff_data_t *ps_mb_coeff_data;
|
|
|
|
|
|
/* packed residue */
|
|
|
void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data;
|
|
|
UWORD16 u2_sig_coeff_map;
|
|
|
WORD16 *pi2_res_block;
|
|
|
UWORD8 u1_nnz;
|
|
|
UWORD8 u1_cbf;
|
|
|
mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
|
|
|
mb_info_ctxt_t *p_CurCtxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
|
|
|
|
|
|
PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, u1_nnz,
|
|
|
u2_sig_coeff_map, pi2_res_block);
|
|
|
|
|
|
u1_cbf = !!(u1_nnz);
|
|
|
|
|
|
{
|
|
|
UWORD32 u4_ctx_inc;
|
|
|
UWORD8 u1_a, u1_b;
|
|
|
|
|
|
u1_a = ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] & 0x1;
|
|
|
u1_b = ps_top_ctxt->u1_yuv_dc_csbp & 0x1;
|
|
|
u4_ctx_inc = u1_a + (u1_b << 1);
|
|
|
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt,
|
|
|
u1_cbf,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table + CBF
|
|
|
+ (LUMA_DC_CTXCAT << 2) + u4_ctx_inc);
|
|
|
}
|
|
|
|
|
|
/* Write coded_block_flag */
|
|
|
if (u1_cbf)
|
|
|
{
|
|
|
ih264e_cabac_write_coeff4x4(pi2_res_block,
|
|
|
u1_nnz,
|
|
|
15,
|
|
|
u2_sig_coeff_map,
|
|
|
COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_0_OFFSET,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ SIGNIFICANT_COEFF_FLAG_FRAME
|
|
|
+ SIG_COEFF_CTXT_CAT_0_OFFSET,
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] |= 0x1;
|
|
|
p_CurCtxt->u1_yuv_dc_csbp |= 0x1;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
|
|
|
p_CurCtxt->u1_yuv_dc_csbp &= 0x6;
|
|
|
}
|
|
|
|
|
|
ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
* @brief
|
|
|
* Write chroma residues to the bitstream
|
|
|
*
|
|
|
* @param[in] ps_ent_ctxt
|
|
|
* Pointer to entropy context structure
|
|
|
*
|
|
|
* @param[in] u1_chroma_cbp
|
|
|
* coded block pattern, chroma
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_write_chroma_residue(entropy_ctxt_t *ps_ent_ctxt,
|
|
|
UWORD8 u1_chroma_cbp)
|
|
|
{
|
|
|
/* CABAC context */
|
|
|
cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
|
|
|
tu_sblk_coeff_data_t *ps_mb_coeff_data;
|
|
|
/* packed residue */
|
|
|
void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data;
|
|
|
UWORD16 u2_sig_coeff_map;
|
|
|
UWORD8 u1_nnz;
|
|
|
mb_info_ctxt_t *ps_top_ctxt_mb_info, *ps_curr_ctxt;
|
|
|
|
|
|
ps_top_ctxt_mb_info = ps_cabac_ctxt->ps_top_ctxt_mb_info;
|
|
|
ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
|
|
|
|
|
|
/********************/
|
|
|
/* Write Chroma DC */
|
|
|
/********************/
|
|
|
{
|
|
|
WORD16 *pi2_res_block;
|
|
|
UWORD8 u1_left_dc_csbp, u1_top_dc_csbp, u1_uv, u1_cbf;
|
|
|
|
|
|
u1_left_dc_csbp = (ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0]) >> 1;
|
|
|
u1_top_dc_csbp = (ps_top_ctxt_mb_info->u1_yuv_dc_csbp) >> 1;
|
|
|
|
|
|
for (u1_uv = 0; u1_uv < 2; u1_uv++)
|
|
|
{
|
|
|
PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data,
|
|
|
u1_nnz, u2_sig_coeff_map, pi2_res_block);
|
|
|
u1_cbf = !!(u1_nnz);
|
|
|
{
|
|
|
UWORD8 u1_a, u1_b;
|
|
|
UWORD32 u4_ctx_inc;
|
|
|
u1_a = (u1_left_dc_csbp >> u1_uv) & 0x01;
|
|
|
u1_b = (u1_top_dc_csbp >> u1_uv) & 0x01;
|
|
|
u4_ctx_inc = (u1_a + (u1_b << 1));
|
|
|
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt,
|
|
|
u1_cbf,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table + CBF
|
|
|
+ (CHROMA_DC_CTXCAT << 2)
|
|
|
+ u4_ctx_inc);
|
|
|
}
|
|
|
|
|
|
if (u1_cbf)
|
|
|
{
|
|
|
ih264e_cabac_write_coeff4x4(pi2_res_block,
|
|
|
u1_nnz,
|
|
|
3,
|
|
|
u2_sig_coeff_map,
|
|
|
COEFF_ABS_LEVEL_MINUS1
|
|
|
+ COEFF_ABS_LEVEL_CAT_3_OFFSET,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ SIGNIFICANT_COEFF_FLAG_FRAME
|
|
|
+ SIG_COEFF_CTXT_CAT_3_OFFSET,
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
SETBIT(u1_top_dc_csbp, u1_uv);
|
|
|
SETBIT(u1_left_dc_csbp, u1_uv);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CLEARBIT(u1_top_dc_csbp, u1_uv);
|
|
|
CLEARBIT(u1_left_dc_csbp, u1_uv);
|
|
|
}
|
|
|
}
|
|
|
/*************************************************************/
|
|
|
/* Update the DC csbp */
|
|
|
/*************************************************************/
|
|
|
ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x1;
|
|
|
ps_curr_ctxt->u1_yuv_dc_csbp &= 0x1;
|
|
|
ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] |= (u1_left_dc_csbp << 1);
|
|
|
ps_curr_ctxt->u1_yuv_dc_csbp |= (u1_top_dc_csbp << 1);
|
|
|
}
|
|
|
/*******************/
|
|
|
/* Write Chroma AC */
|
|
|
/*******************/
|
|
|
{
|
|
|
if (u1_chroma_cbp == 2)
|
|
|
{
|
|
|
UWORD8 u1_uv_blkno, u1_left_ac_csbp, u1_top_ac_csbp;
|
|
|
WORD16 *pi2_res_block;
|
|
|
u1_left_ac_csbp = ps_cabac_ctxt->pu1_left_uv_ac_csbp[0];
|
|
|
u1_top_ac_csbp = ps_top_ctxt_mb_info->u1_yuv_ac_csbp >> 4;
|
|
|
|
|
|
for (u1_uv_blkno = 0; u1_uv_blkno < 8; u1_uv_blkno++)
|
|
|
{
|
|
|
UWORD8 u1_cbf;
|
|
|
UWORD8 u1_b2b0, u1_b2b1;
|
|
|
PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data,
|
|
|
u1_nnz, u2_sig_coeff_map,
|
|
|
pi2_res_block);
|
|
|
|
|
|
u1_cbf = !!(u1_nnz);
|
|
|
u1_b2b0 = ((u1_uv_blkno & 0x4) >> 1) | (u1_uv_blkno & 0x1);
|
|
|
u1_b2b1 = ((u1_uv_blkno & 0x4) >> 1)
|
|
|
| ((u1_uv_blkno & 0x2) >> 1);
|
|
|
|
|
|
{
|
|
|
UWORD8 u1_a, u1_b;
|
|
|
UWORD32 u4_ctx_inc;
|
|
|
/* write coded_block_flag */
|
|
|
u1_a = (u1_left_ac_csbp >> u1_b2b1) & 0x1;
|
|
|
u1_b = (u1_top_ac_csbp >> u1_b2b0) & 0x1;
|
|
|
u4_ctx_inc = u1_a + (u1_b << 1);
|
|
|
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt,
|
|
|
u1_cbf,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table + CBF
|
|
|
+ (CHROMA_AC_CTXCAT << 2)
|
|
|
+ u4_ctx_inc);
|
|
|
|
|
|
}
|
|
|
if (u1_cbf)
|
|
|
{
|
|
|
ih264e_cabac_write_coeff4x4(pi2_res_block,
|
|
|
u1_nnz,
|
|
|
14,
|
|
|
u2_sig_coeff_map,
|
|
|
COEFF_ABS_LEVEL_MINUS1
|
|
|
+ COEFF_ABS_LEVEL_CAT_4_OFFSET,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ +SIGNIFICANT_COEFF_FLAG_FRAME
|
|
|
+ SIG_COEFF_CTXT_CAT_4_OFFSET,
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
SETBIT(u1_left_ac_csbp, u1_b2b1);
|
|
|
SETBIT(u1_top_ac_csbp, u1_b2b0);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CLEARBIT(u1_left_ac_csbp, u1_b2b1);
|
|
|
CLEARBIT(u1_top_ac_csbp, u1_b2b0);
|
|
|
|
|
|
}
|
|
|
}
|
|
|
/*************************************************************/
|
|
|
/* Update the AC csbp */
|
|
|
/*************************************************************/
|
|
|
ps_cabac_ctxt->pu1_left_uv_ac_csbp[0] = u1_left_ac_csbp;
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp &= 0x0f;
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp |= (u1_top_ac_csbp << 4);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_cabac_ctxt->pu1_left_uv_ac_csbp[0] = 0;
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp &= 0xf;
|
|
|
}
|
|
|
}
|
|
|
ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
* @brief
|
|
|
* Encodes Residues for the MB as defined in 7.3.5.3
|
|
|
*
|
|
|
* @param[in] ps_ent_ctxt
|
|
|
* Pointer to entropy context structure
|
|
|
*
|
|
|
* @param[in] u1_cbp
|
|
|
* coded block pattern
|
|
|
*
|
|
|
* @param[in] u1_ctx_cat
|
|
|
* Context category, LUMA_AC_CTXCAT or LUMA_4x4_CTXCAT
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_encode_residue(entropy_ctxt_t *ps_ent_ctxt,
|
|
|
UWORD32 u4_cbp, UWORD8 u1_ctx_cat)
|
|
|
{
|
|
|
/* CABAC context */
|
|
|
cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
|
|
|
|
|
|
tu_sblk_coeff_data_t *ps_mb_coeff_data;
|
|
|
/* packed residue */
|
|
|
void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data;
|
|
|
UWORD16 u2_sig_coeff_map;
|
|
|
UWORD8 u1_nnz;
|
|
|
mb_info_ctxt_t *ps_curr_ctxt;
|
|
|
mb_info_ctxt_t *ps_top_ctxt;
|
|
|
UWORD8 u1_left_ac_csbp;
|
|
|
UWORD8 u1_top_ac_csbp;
|
|
|
UWORD32 u4_ctx_idx_offset_sig_coef, u4_ctx_idx_offset_abs_lvl;
|
|
|
ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
|
|
|
ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
|
|
|
u1_left_ac_csbp = ps_cabac_ctxt->pu1_left_y_ac_csbp[0];
|
|
|
u1_top_ac_csbp = ps_top_ctxt->u1_yuv_ac_csbp;
|
|
|
|
|
|
if (u4_cbp & 0xf)
|
|
|
{
|
|
|
/* Write luma residue */
|
|
|
UWORD8 u1_offset;
|
|
|
WORD16 *pi2_res_block;
|
|
|
UWORD8 u1_subblk_num;
|
|
|
if (u1_ctx_cat == LUMA_AC_CTXCAT)
|
|
|
{
|
|
|
u1_offset = 1;
|
|
|
u4_ctx_idx_offset_sig_coef = SIG_COEFF_CTXT_CAT_1_OFFSET;
|
|
|
u4_ctx_idx_offset_abs_lvl = COEFF_ABS_LEVEL_MINUS1
|
|
|
+ COEFF_ABS_LEVEL_CAT_1_OFFSET;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
u1_offset = 0;
|
|
|
u4_ctx_idx_offset_sig_coef = SIG_COEFF_CTXT_CAT_2_OFFSET;
|
|
|
u4_ctx_idx_offset_abs_lvl = COEFF_ABS_LEVEL_MINUS1
|
|
|
+ COEFF_ABS_LEVEL_CAT_2_OFFSET;
|
|
|
}
|
|
|
|
|
|
for (u1_subblk_num = 0; u1_subblk_num < 16; u1_subblk_num++)
|
|
|
{
|
|
|
UWORD8 u1_b0, u1_b1, u1_b2, u1_b3, u1_b2b0, u1_b3b1, u1_b3b2;
|
|
|
u1_b0 = (u1_subblk_num & 0x1);
|
|
|
u1_b1 = (u1_subblk_num & 0x2) >> 1;
|
|
|
u1_b2 = (u1_subblk_num & 0x4) >> 2;
|
|
|
u1_b3 = (u1_subblk_num & 0x8) >> 3;
|
|
|
u1_b2b0 = (u1_b2 << 1) | (u1_b0);
|
|
|
u1_b3b1 = (u1_b3 << 1) | (u1_b1);
|
|
|
u1_b3b2 = (u1_b3 << 1) | (u1_b2);
|
|
|
|
|
|
if (!((u4_cbp >> u1_b3b2) & 0x1))
|
|
|
{
|
|
|
/* ---------------------------------------------------------- */
|
|
|
/* The current block is not coded so skip all the sub block */
|
|
|
/* and set the pointer of scan level, csbp accrodingly */
|
|
|
/* ---------------------------------------------------------- */
|
|
|
CLEARBIT(u1_top_ac_csbp, u1_b2b0);
|
|
|
CLEARBIT(u1_top_ac_csbp, (u1_b2b0 + 1));
|
|
|
CLEARBIT(u1_left_ac_csbp, u1_b3b1);
|
|
|
CLEARBIT(u1_left_ac_csbp, (u1_b3b1 + 1));
|
|
|
|
|
|
u1_subblk_num += 3;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
UWORD8 u1_csbf;
|
|
|
|
|
|
PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data,
|
|
|
u1_nnz, u2_sig_coeff_map,
|
|
|
pi2_res_block);
|
|
|
|
|
|
u1_csbf = !!(u1_nnz);
|
|
|
{
|
|
|
UWORD8 u1_a, u1_b;
|
|
|
UWORD32 u4_ctx_inc;
|
|
|
u1_b = (u1_top_ac_csbp >> u1_b2b0) & 0x01;
|
|
|
u1_a = (u1_left_ac_csbp >> u1_b3b1) & 0x01;
|
|
|
u4_ctx_inc = u1_a + (u1_b << 1);
|
|
|
|
|
|
/* Encode the bin */
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt,
|
|
|
u1_csbf,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table + CBF
|
|
|
+ (u1_ctx_cat << 2) + u4_ctx_inc);
|
|
|
|
|
|
}
|
|
|
/**************************/
|
|
|
/* Write coded_block_flag */
|
|
|
/**************************/
|
|
|
if (u1_csbf)
|
|
|
{
|
|
|
ih264e_cabac_write_coeff4x4(pi2_res_block,
|
|
|
u1_nnz,
|
|
|
(UWORD8) (15 - u1_offset),
|
|
|
u2_sig_coeff_map,
|
|
|
u4_ctx_idx_offset_abs_lvl,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ SIGNIFICANT_COEFF_FLAG_FRAME
|
|
|
+ u4_ctx_idx_offset_sig_coef,
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
SETBIT(u1_top_ac_csbp, u1_b2b0);
|
|
|
SETBIT(u1_left_ac_csbp, u1_b3b1);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CLEARBIT(u1_top_ac_csbp, u1_b2b0);
|
|
|
CLEARBIT(u1_left_ac_csbp, u1_b3b1);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
/**************************************************************************/
|
|
|
/* Update the AC csbp */
|
|
|
/**************************************************************************/
|
|
|
ps_cabac_ctxt->pu1_left_y_ac_csbp[0] = u1_left_ac_csbp & 0xf;
|
|
|
u1_top_ac_csbp &= 0x0f;
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp &= 0xf0;
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp |= u1_top_ac_csbp;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_cabac_ctxt->pu1_left_y_ac_csbp[0] = 0;
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp &= 0xf0;
|
|
|
}
|
|
|
|
|
|
/* Write chroma residue */
|
|
|
|
|
|
ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data;
|
|
|
{
|
|
|
UWORD8 u1_cbp_chroma;
|
|
|
u1_cbp_chroma = u4_cbp >> 4;
|
|
|
if (u1_cbp_chroma)
|
|
|
{
|
|
|
ih264e_cabac_write_chroma_residue(ps_ent_ctxt, u1_cbp_chroma);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x1;
|
|
|
ps_curr_ctxt->u1_yuv_dc_csbp &= 0x1;
|
|
|
ps_cabac_ctxt->pu1_left_uv_ac_csbp[0] = 0;
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp &= 0xf;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
* @brief
|
|
|
* Encodes a Motion vector (9.3.3.1.1.7 )
|
|
|
*
|
|
|
* @param[in] u1_mvd
|
|
|
* Motion vector to be encoded
|
|
|
*
|
|
|
* @param[in] u4_ctx_idx_offset
|
|
|
* * ctxIdxOffset for MV_X or MV_Ycontext
|
|
|
*
|
|
|
* @param[in] ui2_abs_mvd
|
|
|
* sum of absolute value of corresponding neighboring motion vectors
|
|
|
*
|
|
|
* @param[in] ps_cabac_ctxt
|
|
|
* Pointer to cabac context structure
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_enc_ctx_mvd(WORD16 u1_mvd, UWORD32 u4_ctx_idx_offset,
|
|
|
UWORD16 ui2_abs_mvd,
|
|
|
cabac_ctxt_t *ps_cabac_ctxt)
|
|
|
{
|
|
|
|
|
|
UWORD8 u1_bin, u1_ctxt_inc;
|
|
|
WORD8 k = 3, u1_coff = 9;
|
|
|
WORD16 i2_abs_mvd, i2_sufs;
|
|
|
UWORD32 u4_ctx_inc;
|
|
|
UWORD32 u4_bins;
|
|
|
WORD8 i1_bins_len;
|
|
|
|
|
|
/* if mvd < u1_coff
|
|
|
only Prefix
|
|
|
else
|
|
|
Prefix + Suffix
|
|
|
|
|
|
encode sign bit
|
|
|
|
|
|
Prefix TU encoding Cmax =u1_coff and Suffix 3rd order Exp-Golomb
|
|
|
*/
|
|
|
|
|
|
if (ui2_abs_mvd < 3)
|
|
|
u4_ctx_inc = 0;
|
|
|
else if (ui2_abs_mvd > 32)
|
|
|
u4_ctx_inc = 2;
|
|
|
else
|
|
|
u4_ctx_inc = 1;
|
|
|
|
|
|
u4_bins = 0;
|
|
|
i1_bins_len = 1;
|
|
|
|
|
|
if (u1_mvd == 0)
|
|
|
{
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt,
|
|
|
0,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table + u4_ctx_idx_offset
|
|
|
+ u4_ctx_inc);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
i2_abs_mvd = ABS(u1_mvd);
|
|
|
if (i2_abs_mvd >= u1_coff)
|
|
|
{
|
|
|
/* Prefix TU i.e string of 9 1's */
|
|
|
u4_bins = 0x1ff;
|
|
|
i1_bins_len = 9;
|
|
|
u4_ctx_inc = (u4_ctx_inc | 0x065430);
|
|
|
|
|
|
ih264e_encode_decision_bins(u4_bins,
|
|
|
i1_bins_len,
|
|
|
u4_ctx_inc,
|
|
|
4,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ u4_ctx_idx_offset,
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
/* Suffix, uses EncodeBypass */
|
|
|
u4_bins = 0;
|
|
|
i1_bins_len = 0;
|
|
|
i2_sufs = i2_abs_mvd - u1_coff;
|
|
|
while (1)
|
|
|
{
|
|
|
if (i2_sufs >= (1 << k))
|
|
|
{
|
|
|
u4_bins = (u4_bins | (1 << (31 - i1_bins_len)));
|
|
|
i1_bins_len++;
|
|
|
i2_sufs = i2_sufs - (1 << k);
|
|
|
k++;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
i1_bins_len++;
|
|
|
while (k--)
|
|
|
{
|
|
|
u1_bin = ((i2_sufs >> k) & 0x01);
|
|
|
u4_bins = (u4_bins | (u1_bin << (31 - i1_bins_len)));
|
|
|
i1_bins_len++;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
u4_bins >>= (32 - i1_bins_len);
|
|
|
ih264e_cabac_encode_bypass_bins(ps_cabac_ctxt, u4_bins,
|
|
|
i1_bins_len);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* Prefix only */
|
|
|
/* b0 */
|
|
|
u4_bins = 1;
|
|
|
i2_abs_mvd--;
|
|
|
u1_ctxt_inc = 3;
|
|
|
while (i2_abs_mvd)
|
|
|
{
|
|
|
i2_abs_mvd--;
|
|
|
u4_bins = (u4_bins | (1 << i1_bins_len));
|
|
|
if (u1_ctxt_inc <= 6)
|
|
|
{
|
|
|
u4_ctx_inc = (u4_ctx_inc
|
|
|
| (u1_ctxt_inc << (i1_bins_len << 2)));
|
|
|
u1_ctxt_inc++;
|
|
|
}
|
|
|
i1_bins_len++;
|
|
|
}
|
|
|
/* Encode Terminating bit */
|
|
|
if (i1_bins_len <= 4)
|
|
|
u4_ctx_inc = (u4_ctx_inc | (u1_ctxt_inc << (i1_bins_len << 2)));
|
|
|
i1_bins_len++;
|
|
|
ih264e_encode_decision_bins(u4_bins,
|
|
|
i1_bins_len,
|
|
|
u4_ctx_inc,
|
|
|
4,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ u4_ctx_idx_offset,
|
|
|
ps_cabac_ctxt);
|
|
|
}
|
|
|
/* sign bit, uses EncodeBypass */
|
|
|
if (u1_mvd > 0)
|
|
|
ih264e_cabac_encode_bypass_bin(ps_cabac_ctxt, 0);
|
|
|
else
|
|
|
ih264e_cabac_encode_bypass_bin(ps_cabac_ctxt, 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
* @brief
|
|
|
* Encodes all motion vectors for a P16x16 MB
|
|
|
*
|
|
|
* @param[in] ps_cabac_ctxt
|
|
|
* Pointer to cabac context structure
|
|
|
*
|
|
|
* @param[in] pi2_mv_ptr
|
|
|
* Pointer to array of motion vectors
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_enc_mvds_p16x16(cabac_ctxt_t *ps_cabac_ctxt,
|
|
|
WORD16 *pi2_mv_ptr)
|
|
|
{
|
|
|
|
|
|
|
|
|
/* Encode the differential component of the motion vectors */
|
|
|
|
|
|
{
|
|
|
UWORD8 u1_abs_mvd_x, u1_abs_mvd_y;
|
|
|
UWORD8 *pu1_top_mv_ctxt, *pu1_lft_mv_ctxt;
|
|
|
WORD16 u2_mv;
|
|
|
u1_abs_mvd_x = 0;
|
|
|
u1_abs_mvd_y = 0;
|
|
|
pu1_top_mv_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_mv[0];
|
|
|
pu1_lft_mv_ctxt = ps_cabac_ctxt->pu1_left_mv_ctxt_inc[0];
|
|
|
{
|
|
|
UWORD16 u2_abs_mvd_x_a, u2_abs_mvd_x_b, u2_abs_mvd_y_a,
|
|
|
u2_abs_mvd_y_b;
|
|
|
u2_abs_mvd_x_b = (UWORD16) pu1_top_mv_ctxt[0];
|
|
|
u2_abs_mvd_y_b = (UWORD16) pu1_top_mv_ctxt[1];
|
|
|
u2_abs_mvd_x_a = (UWORD16) pu1_lft_mv_ctxt[0];
|
|
|
u2_abs_mvd_y_a = (UWORD16) pu1_lft_mv_ctxt[1];
|
|
|
u2_mv = *(pi2_mv_ptr++);
|
|
|
|
|
|
ih264e_cabac_enc_ctx_mvd(u2_mv, MVD_X,
|
|
|
(UWORD16) (u2_abs_mvd_x_a + u2_abs_mvd_x_b),
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
u1_abs_mvd_x = CLIP3(0, 127, ABS(u2_mv));
|
|
|
u2_mv = *(pi2_mv_ptr++);
|
|
|
|
|
|
ih264e_cabac_enc_ctx_mvd(u2_mv, MVD_Y,
|
|
|
(UWORD16) (u2_abs_mvd_y_a + u2_abs_mvd_y_b),
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
u1_abs_mvd_y = CLIP3(0, 127, ABS(u2_mv));
|
|
|
}
|
|
|
/***************************************************************/
|
|
|
/* Store abs_mvd_values cabac contexts */
|
|
|
/***************************************************************/
|
|
|
pu1_top_mv_ctxt[0] = pu1_lft_mv_ctxt[0] = u1_abs_mvd_x;
|
|
|
pu1_top_mv_ctxt[1] = pu1_lft_mv_ctxt[1] = u1_abs_mvd_y;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
* @brief
|
|
|
* Encodes all motion vectors for a B MB (Assues that mbype is B_L0_16x16, B_L1_16x16 or B_Bi_16x16
|
|
|
*
|
|
|
* @param[in] ps_cabac_ctxt
|
|
|
* Pointer to cabac context structure
|
|
|
*
|
|
|
* @param[in] pi2_mv_ptr
|
|
|
* Pointer to array of motion vectors
|
|
|
*
|
|
|
* @returns
|
|
|
*
|
|
|
* @remarks
|
|
|
* None
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
static void ih264e_cabac_enc_mvds_b16x16(cabac_ctxt_t *ps_cabac_ctxt,
|
|
|
WORD16 *pi2_mv_ptr,
|
|
|
WORD32 i4_mb_part_pred_mode )
|
|
|
{
|
|
|
|
|
|
/* Encode the differential component of the motion vectors */
|
|
|
|
|
|
{
|
|
|
UWORD8 u1_abs_mvd_x, u1_abs_mvd_y;
|
|
|
UWORD8 *pu1_top_mv_ctxt, *pu1_lft_mv_ctxt;
|
|
|
WORD16 u2_mv;
|
|
|
u1_abs_mvd_x = 0;
|
|
|
u1_abs_mvd_y = 0;
|
|
|
pu1_top_mv_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_mv[0];
|
|
|
pu1_lft_mv_ctxt = ps_cabac_ctxt->pu1_left_mv_ctxt_inc[0];
|
|
|
if (i4_mb_part_pred_mode != PRED_L1)/* || PRED_BI */
|
|
|
{
|
|
|
UWORD16 u2_abs_mvd_x_a, u2_abs_mvd_x_b, u2_abs_mvd_y_a,
|
|
|
u2_abs_mvd_y_b;
|
|
|
u2_abs_mvd_x_b = (UWORD16) pu1_top_mv_ctxt[0];
|
|
|
u2_abs_mvd_y_b = (UWORD16) pu1_top_mv_ctxt[1];
|
|
|
u2_abs_mvd_x_a = (UWORD16) pu1_lft_mv_ctxt[0];
|
|
|
u2_abs_mvd_y_a = (UWORD16) pu1_lft_mv_ctxt[1];
|
|
|
u2_mv = pi2_mv_ptr[0];
|
|
|
|
|
|
ih264e_cabac_enc_ctx_mvd(u2_mv, MVD_X,
|
|
|
(UWORD16) (u2_abs_mvd_x_a + u2_abs_mvd_x_b),
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
u1_abs_mvd_x = CLIP3(0, 127, ABS(u2_mv));
|
|
|
u2_mv = pi2_mv_ptr[1];
|
|
|
|
|
|
ih264e_cabac_enc_ctx_mvd(u2_mv, MVD_Y,
|
|
|
(UWORD16) (u2_abs_mvd_y_a + u2_abs_mvd_y_b),
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
u1_abs_mvd_y = CLIP3(0, 127, ABS(u2_mv));
|
|
|
}
|
|
|
|
|
|
/***************************************************************/
|
|
|
/* Store abs_mvd_values cabac contexts */
|
|
|
/***************************************************************/
|
|
|
pu1_top_mv_ctxt[0] = pu1_lft_mv_ctxt[0] = u1_abs_mvd_x;
|
|
|
pu1_top_mv_ctxt[1] = pu1_lft_mv_ctxt[1] = u1_abs_mvd_y;
|
|
|
|
|
|
u1_abs_mvd_x = 0;
|
|
|
u1_abs_mvd_y = 0;
|
|
|
if (i4_mb_part_pred_mode != PRED_L0)/* || PRED_BI */
|
|
|
{
|
|
|
UWORD16 u2_abs_mvd_x_a, u2_abs_mvd_x_b, u2_abs_mvd_y_a,
|
|
|
u2_abs_mvd_y_b;
|
|
|
u2_abs_mvd_x_b = (UWORD16) pu1_top_mv_ctxt[2];
|
|
|
u2_abs_mvd_y_b = (UWORD16) pu1_top_mv_ctxt[3];
|
|
|
u2_abs_mvd_x_a = (UWORD16) pu1_lft_mv_ctxt[2];
|
|
|
u2_abs_mvd_y_a = (UWORD16) pu1_lft_mv_ctxt[3];
|
|
|
u2_mv = pi2_mv_ptr[2];
|
|
|
|
|
|
ih264e_cabac_enc_ctx_mvd(u2_mv, MVD_X,
|
|
|
(UWORD16) (u2_abs_mvd_x_a + u2_abs_mvd_x_b),
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
u1_abs_mvd_x = CLIP3(0, 127, ABS(u2_mv));
|
|
|
u2_mv = pi2_mv_ptr[3];
|
|
|
|
|
|
ih264e_cabac_enc_ctx_mvd(u2_mv, MVD_Y,
|
|
|
(UWORD16) (u2_abs_mvd_y_a + u2_abs_mvd_y_b),
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
u1_abs_mvd_y = CLIP3(0, 127, ABS(u2_mv));
|
|
|
}
|
|
|
/***************************************************************/
|
|
|
/* Store abs_mvd_values cabac contexts */
|
|
|
/***************************************************************/
|
|
|
pu1_top_mv_ctxt[2] = pu1_lft_mv_ctxt[2] = u1_abs_mvd_x;
|
|
|
pu1_top_mv_ctxt[3] = pu1_lft_mv_ctxt[3] = u1_abs_mvd_y;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
*
|
|
|
* @brief
|
|
|
* This function generates CABAC coded bit stream for an Intra Slice.
|
|
|
*
|
|
|
* @description
|
|
|
* The mb syntax layer for intra slices constitutes luma mb mode, mb qp delta, coded block pattern, chroma mb mode and
|
|
|
* luma/chroma residue. These syntax elements are written as directed by table
|
|
|
* 7.3.5 of h264 specification.
|
|
|
*
|
|
|
* @param[in] ps_ent_ctxt
|
|
|
* pointer to entropy context
|
|
|
*
|
|
|
* @returns error code
|
|
|
*
|
|
|
* @remarks none
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
IH264E_ERROR_T ih264e_write_islice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt)
|
|
|
{
|
|
|
/* bit stream ptr */
|
|
|
bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
|
|
|
/* CABAC context */
|
|
|
cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
|
|
|
/* packed header data */
|
|
|
UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
|
|
|
mb_hdr_common_t *ps_mb_hdr = (mb_hdr_common_t *)ps_ent_ctxt->pv_mb_header_data;
|
|
|
mb_info_ctxt_t *ps_curr_ctxt;
|
|
|
WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
|
|
|
WORD8 mb_qp_delta;
|
|
|
UWORD32 u4_cbp_l, u4_cbp_c;
|
|
|
WORD32 bitstream_start_offset, bitstream_end_offset;
|
|
|
|
|
|
if ((ps_bitstream->u4_strm_buf_offset + MIN_STREAM_SIZE_MB)
|
|
|
>= ps_bitstream->u4_max_strm_size)
|
|
|
{
|
|
|
/* return without corrupting the buffer beyond its size */
|
|
|
return (IH264E_BITSTREAM_BUFFER_OVERFLOW);
|
|
|
}
|
|
|
/* mb header info */
|
|
|
mb_tpm = ps_mb_hdr->u1_mb_type_mode;
|
|
|
cbp = ps_mb_hdr->u1_cbp;
|
|
|
mb_qp_delta = ps_mb_hdr->u1_mb_qp_delta;
|
|
|
|
|
|
/* mb type */
|
|
|
mb_type = mb_tpm & 0xF;
|
|
|
|
|
|
ih264e_get_cabac_context(ps_ent_ctxt, mb_type);
|
|
|
ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
|
|
|
|
|
|
/* Starting bitstream offset for header in bits */
|
|
|
bitstream_start_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
u4_cbp_c = (cbp >> 4);
|
|
|
u4_cbp_l = (cbp & 0xF);
|
|
|
if (mb_type == I16x16)
|
|
|
{
|
|
|
luma_intra_mode = ((mb_tpm >> 4) & 3) + 1 + (u4_cbp_c << 2)
|
|
|
+ (u4_cbp_l == 15) * 12;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
luma_intra_mode = 0;
|
|
|
}
|
|
|
|
|
|
chroma_intra_mode = (mb_tpm >> 6);
|
|
|
|
|
|
/* Encode Intra pred mode, Luma */
|
|
|
ih264e_cabac_enc_intra_mb_type(ISLICE, luma_intra_mode, ps_cabac_ctxt,
|
|
|
MB_TYPE_I_SLICE);
|
|
|
|
|
|
if (mb_type == I4x4)
|
|
|
{
|
|
|
/* Encode 4x4 MB modes */
|
|
|
mb_hdr_i4x4_t *ps_mb_hdr_i4x4 = (mb_hdr_i4x4_t *)ps_ent_ctxt->pv_mb_header_data;
|
|
|
ih264e_cabac_enc_4x4mb_modes(ps_cabac_ctxt, ps_mb_hdr_i4x4->au1_sub_blk_modes);
|
|
|
}
|
|
|
/* Encode chroma mode */
|
|
|
ih264e_cabac_enc_chroma_predmode(chroma_intra_mode, ps_cabac_ctxt);
|
|
|
|
|
|
if (mb_type != I16x16)
|
|
|
{ /* Encode MB cbp */
|
|
|
ih264e_cabac_enc_cbp(cbp, ps_cabac_ctxt);
|
|
|
}
|
|
|
|
|
|
if ((cbp > 0) || (mb_type == I16x16))
|
|
|
{
|
|
|
/* Encode mb_qp_delta */
|
|
|
ih264e_cabac_enc_mb_qp_delta(mb_qp_delta, ps_cabac_ctxt);
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
/* Starting bitstream offset for residue */
|
|
|
bitstream_start_offset = bitstream_end_offset;
|
|
|
if (mb_type == I16x16)
|
|
|
{
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I16x16;
|
|
|
ps_curr_ctxt->u1_cbp = cbp;
|
|
|
ih264e_cabac_encode_residue_luma_dc(ps_ent_ctxt);
|
|
|
ih264e_cabac_encode_residue(ps_ent_ctxt, cbp, LUMA_AC_CTXCAT);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_cbp = cbp;
|
|
|
ps_curr_ctxt->u1_mb_type = I4x4;
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I4x4;
|
|
|
ih264e_cabac_encode_residue(ps_ent_ctxt, cbp, LUMA_4X4_CTXCAT);
|
|
|
ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
|
|
|
ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
|
|
|
}
|
|
|
/* Ending bitstream offset for reside in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_residue_bits[0] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp = 0;
|
|
|
ps_curr_ctxt->u1_yuv_dc_csbp = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_y_ac_csbp) = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = 0;
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
|
|
|
/* Computing the number of used used for encoding the MB syntax */
|
|
|
}
|
|
|
memset(ps_curr_ctxt->u1_mv, 0, 16);
|
|
|
memset(ps_cabac_ctxt->pu1_left_mv_ctxt_inc, 0, 16);
|
|
|
ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_cbp = cbp;
|
|
|
|
|
|
if (mb_type == I16x16)
|
|
|
{
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I16x16;
|
|
|
pu1_byte += sizeof(mb_hdr_i16x16_t);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I4x4;
|
|
|
pu1_byte += sizeof(mb_hdr_i4x4_t);
|
|
|
}
|
|
|
ps_ent_ctxt->pv_mb_header_data = pu1_byte;
|
|
|
return IH264E_SUCCESS;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
*
|
|
|
* @brief
|
|
|
* This function generates CABAC coded bit stream for Inter slices
|
|
|
*
|
|
|
* @description
|
|
|
* The mb syntax layer for inter slices constitutes luma mb mode, mb qp delta, coded block pattern, chroma mb mode and
|
|
|
* luma/chroma residue. These syntax elements are written as directed by table
|
|
|
* 7.3.5 of h264 specification
|
|
|
*
|
|
|
* @param[in] ps_ent_ctxt
|
|
|
* pointer to entropy context
|
|
|
*
|
|
|
* @returns error code
|
|
|
*
|
|
|
* @remarks none
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
IH264E_ERROR_T ih264e_write_pslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt)
|
|
|
{
|
|
|
/* bit stream ptr */
|
|
|
bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
|
|
|
/* CABAC context */
|
|
|
cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
|
|
|
|
|
|
mb_info_ctxt_t *ps_curr_ctxt;
|
|
|
|
|
|
WORD32 bitstream_start_offset, bitstream_end_offset;
|
|
|
WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
|
|
|
WORD8 mb_qp_delta;
|
|
|
UWORD32 u4_cbp_l, u4_cbp_c;
|
|
|
UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
|
|
|
mb_hdr_common_t *ps_mb_hdr = (mb_hdr_common_t *)ps_ent_ctxt->pv_mb_header_data;
|
|
|
|
|
|
if ((ps_bitstream->u4_strm_buf_offset + MIN_STREAM_SIZE_MB)
|
|
|
>= ps_bitstream->u4_max_strm_size)
|
|
|
{
|
|
|
/* return without corrupting the buffer beyond its size */
|
|
|
return (IH264E_BITSTREAM_BUFFER_OVERFLOW);
|
|
|
}
|
|
|
/* mb header info */
|
|
|
mb_tpm = ps_mb_hdr->u1_mb_type_mode;
|
|
|
|
|
|
/* mb type */
|
|
|
mb_type = mb_tpm & 0xF;
|
|
|
/* CABAC contexts for the MB */
|
|
|
ih264e_get_cabac_context(ps_ent_ctxt, mb_type);
|
|
|
ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
|
|
|
|
|
|
/* if Intra MB */
|
|
|
if (mb_type == I16x16 || mb_type == I4x4)
|
|
|
{
|
|
|
cbp = ps_mb_hdr->u1_cbp;
|
|
|
mb_qp_delta = ps_mb_hdr->u1_mb_qp_delta;
|
|
|
|
|
|
/* Starting bitstream offset for header in bits */
|
|
|
bitstream_start_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
|
|
|
/* Encode mb_skip_flag */
|
|
|
ih264e_cabac_enc_mb_skip(0, ps_cabac_ctxt, MB_SKIP_FLAG_P_SLICE);
|
|
|
u4_cbp_c = (cbp >> 4);
|
|
|
u4_cbp_l = (cbp & 0xF);
|
|
|
if (mb_type == I16x16)
|
|
|
{
|
|
|
luma_intra_mode = ((mb_tpm >> 4) & 3) + 1 + (u4_cbp_c << 2)
|
|
|
+ (u4_cbp_l == 15) * 12;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
luma_intra_mode = 0;
|
|
|
}
|
|
|
/* Encode intra mb type */
|
|
|
{
|
|
|
ih264e_cabac_encode_bin(ps_cabac_ctxt,
|
|
|
1,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ MB_TYPE_P_SLICE);
|
|
|
|
|
|
ih264e_cabac_enc_intra_mb_type(PSLICE, (UWORD8) luma_intra_mode,
|
|
|
ps_cabac_ctxt, MB_TYPE_P_SLICE);
|
|
|
}
|
|
|
|
|
|
if (mb_type == I4x4)
|
|
|
{
|
|
|
/* Intra 4x4 modes */
|
|
|
mb_hdr_i4x4_t *ps_mb_hdr_i4x4 = (mb_hdr_i4x4_t *)ps_ent_ctxt->pv_mb_header_data;
|
|
|
ih264e_cabac_enc_4x4mb_modes(ps_cabac_ctxt, ps_mb_hdr_i4x4->au1_sub_blk_modes);
|
|
|
}
|
|
|
chroma_intra_mode = (mb_tpm >> 6);
|
|
|
|
|
|
ih264e_cabac_enc_chroma_predmode(chroma_intra_mode, ps_cabac_ctxt);
|
|
|
|
|
|
if (mb_type != I16x16)
|
|
|
{
|
|
|
/* encode CBP */
|
|
|
ih264e_cabac_enc_cbp(cbp, ps_cabac_ctxt);
|
|
|
}
|
|
|
|
|
|
if ((cbp > 0) || (mb_type == I16x16))
|
|
|
{
|
|
|
ih264e_cabac_enc_mb_qp_delta(mb_qp_delta, ps_cabac_ctxt);
|
|
|
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
/* Starting bitstream offset for residue */
|
|
|
bitstream_start_offset = bitstream_end_offset;
|
|
|
|
|
|
/* Encoding Residue */
|
|
|
if (mb_type == I16x16)
|
|
|
{
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I16x16;
|
|
|
ps_curr_ctxt->u1_cbp = (UWORD8) cbp;
|
|
|
ih264e_cabac_encode_residue_luma_dc(ps_ent_ctxt);
|
|
|
ih264e_cabac_encode_residue(ps_ent_ctxt, cbp, LUMA_AC_CTXCAT);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_cbp = (UWORD8) cbp;
|
|
|
ps_curr_ctxt->u1_mb_type = I4x4;
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I4x4;
|
|
|
ih264e_cabac_encode_residue(ps_ent_ctxt, cbp, LUMA_4X4_CTXCAT);
|
|
|
ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
|
|
|
ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
|
|
|
}
|
|
|
|
|
|
/* Ending bitstream offset for reside in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_residue_bits[0] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp = 0;
|
|
|
ps_curr_ctxt->u1_yuv_dc_csbp = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_y_ac_csbp) = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = 0;
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
}
|
|
|
|
|
|
memset(ps_curr_ctxt->u1_mv, 0, 16);
|
|
|
memset(ps_cabac_ctxt->pu1_left_mv_ctxt_inc, 0, 16);
|
|
|
ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_cbp = (UWORD8) cbp;
|
|
|
|
|
|
if (mb_type == I16x16)
|
|
|
{
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I16x16;
|
|
|
pu1_byte += sizeof(mb_hdr_i16x16_t);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I4x4;
|
|
|
pu1_byte += sizeof(mb_hdr_i4x4_t);
|
|
|
}
|
|
|
|
|
|
ps_ent_ctxt->pv_mb_header_data = pu1_byte;
|
|
|
|
|
|
return IH264E_SUCCESS;
|
|
|
}
|
|
|
else /* Inter MB */
|
|
|
{
|
|
|
/* Starting bitstream offset for header in bits */
|
|
|
bitstream_start_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
/* Encoding P16x16 */
|
|
|
if (mb_type != PSKIP)
|
|
|
{
|
|
|
mb_hdr_p16x16_t *ps_mb_hdr_p16x16 = (mb_hdr_p16x16_t *)ps_ent_ctxt->pv_mb_header_data;
|
|
|
cbp = ps_mb_hdr->u1_cbp;
|
|
|
mb_qp_delta = ps_mb_hdr->u1_mb_qp_delta;
|
|
|
|
|
|
/* Encoding mb_skip */
|
|
|
ih264e_cabac_enc_mb_skip(0, ps_cabac_ctxt, MB_SKIP_FLAG_P_SLICE);
|
|
|
|
|
|
/* Encoding mb_type as P16x16 */
|
|
|
{
|
|
|
UWORD32 u4_ctx_inc_p;
|
|
|
u4_ctx_inc_p = (0x010 + ((2) << 8));
|
|
|
|
|
|
ih264e_encode_decision_bins(0, 3, u4_ctx_inc_p, 3,
|
|
|
&(ps_cabac_ctxt->au1_cabac_ctxt_table[MB_TYPE_P_SLICE]),
|
|
|
ps_cabac_ctxt);
|
|
|
}
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_P;
|
|
|
{
|
|
|
WORD16 *pi2_mv_ptr = (WORD16 *) ps_mb_hdr_p16x16->ai2_mv;
|
|
|
|
|
|
ps_curr_ctxt->u1_mb_type = (ps_curr_ctxt->u1_mb_type
|
|
|
| CAB_NON_BD16x16);
|
|
|
/* Encoding motion vector for P16x16 */
|
|
|
ih264e_cabac_enc_mvds_p16x16(ps_cabac_ctxt, pi2_mv_ptr);
|
|
|
}
|
|
|
/* Encode CBP */
|
|
|
ih264e_cabac_enc_cbp(cbp, ps_cabac_ctxt);
|
|
|
|
|
|
if (cbp)
|
|
|
{
|
|
|
/* encode mb_qp_delta */
|
|
|
ih264e_cabac_enc_mb_qp_delta(mb_qp_delta, ps_cabac_ctxt);
|
|
|
}
|
|
|
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[1] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
/* Starting bitstream offset for residue */
|
|
|
bitstream_start_offset = bitstream_end_offset;
|
|
|
|
|
|
pu1_byte += sizeof(mb_hdr_p16x16_t);
|
|
|
|
|
|
}
|
|
|
else/* MB = PSKIP */
|
|
|
{
|
|
|
ih264e_cabac_enc_mb_skip(1, ps_cabac_ctxt, MB_SKIP_FLAG_P_SLICE);
|
|
|
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_P_SKIP;
|
|
|
(*ps_ent_ctxt->pi4_mb_skip_run)++;
|
|
|
|
|
|
memset(ps_curr_ctxt->u1_mv, 0, 16);
|
|
|
memset(ps_cabac_ctxt->pu1_left_mv_ctxt_inc, 0, 16);
|
|
|
cbp = 0;
|
|
|
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[1] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
/* Starting bitstream offset for residue */
|
|
|
|
|
|
pu1_byte += sizeof(mb_hdr_pskip_t);
|
|
|
}
|
|
|
|
|
|
if (cbp > 0)
|
|
|
{
|
|
|
/* Encode residue */
|
|
|
ih264e_cabac_encode_residue(ps_ent_ctxt, cbp, LUMA_4X4_CTXCAT);
|
|
|
/* Ending bitstream offset for reside in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_residue_bits[1] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
|
|
|
ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
|
|
|
ps_curr_ctxt->u1_yuv_dc_csbp &= 0x6;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp = 0;
|
|
|
ps_curr_ctxt->u1_yuv_dc_csbp = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_y_ac_csbp) = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = 0;
|
|
|
}
|
|
|
ps_curr_ctxt->u1_intrapred_chroma_mode = 0;
|
|
|
ps_curr_ctxt->u1_cbp = cbp;
|
|
|
ps_ent_ctxt->pv_mb_header_data = pu1_byte;
|
|
|
|
|
|
return IH264E_SUCCESS;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
/* ! < Table 9-37 <20> Binarization for macroblock types in B slices in ITU_T_H264-201402
|
|
|
* Bits 0-7 : binarised value
|
|
|
* Bits 8-15: length of binary sequence */
|
|
|
|
|
|
|
|
|
static const UWORD32 u4_b_mb_type[27] = { 0x0100, 0x0301, 0x0305, 0x0603,
|
|
|
0x0623, 0x0613, 0x0633, 0x060b,
|
|
|
0x062b, 0x061b, 0x063b, 0x061f,
|
|
|
0x0707, 0x0747, 0x0727, 0x0767,
|
|
|
0x0717, 0x0757, 0x0737, 0x0777,
|
|
|
0x070f, 0x074f, 0x063f };
|
|
|
/* CtxInc for mb types in B slices */
|
|
|
static const UWORD32 ui_b_mb_type_ctx_inc[27] = { 0x00, 0x0530, 0x0530,
|
|
|
0x0555430, 0x0555430,
|
|
|
0x0555430, 0x0555430,
|
|
|
0x0555430, 0x0555430,
|
|
|
0x0555430, 0x0555430,
|
|
|
0x0555430, 0x05555430,
|
|
|
0x05555430, 0x05555430,
|
|
|
0x05555430, 0x05555430,
|
|
|
0x05555430, 0x05555430,
|
|
|
0x05555430, 0x05555430,
|
|
|
0x05555430, 0x0555430 };
|
|
|
|
|
|
/**
|
|
|
*******************************************************************************
|
|
|
*
|
|
|
* @brief
|
|
|
* This function generates CABAC coded bit stream for B slices
|
|
|
*
|
|
|
* @description
|
|
|
* The mb syntax layer for inter slices constitutes luma mb mode,
|
|
|
* mb qp delta, coded block pattern, chroma mb mode and
|
|
|
* luma/chroma residue. These syntax elements are written as directed by table
|
|
|
* 7.3.5 of h264 specification
|
|
|
*
|
|
|
* @param[in] ps_ent_ctxt
|
|
|
* pointer to entropy context
|
|
|
*
|
|
|
* @returns error code
|
|
|
*
|
|
|
* @remarks none
|
|
|
*
|
|
|
*******************************************************************************
|
|
|
*/
|
|
|
IH264E_ERROR_T ih264e_write_bslice_mb_cabac(entropy_ctxt_t *ps_ent_ctxt)
|
|
|
{
|
|
|
/* bit stream ptr */
|
|
|
bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
|
|
|
/* CABAC context */
|
|
|
cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
|
|
|
|
|
|
mb_info_ctxt_t *ps_curr_ctxt;
|
|
|
|
|
|
WORD32 bitstream_start_offset, bitstream_end_offset;
|
|
|
WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
|
|
|
WORD8 mb_qp_delta;
|
|
|
UWORD32 u4_cbp_l, u4_cbp_c;
|
|
|
UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
|
|
|
mb_hdr_common_t *ps_mb_hdr = (mb_hdr_common_t *)ps_ent_ctxt->pv_mb_header_data;
|
|
|
|
|
|
if ((ps_bitstream->u4_strm_buf_offset + MIN_STREAM_SIZE_MB)
|
|
|
>= ps_bitstream->u4_max_strm_size)
|
|
|
{
|
|
|
/* return without corrupting the buffer beyond its size */
|
|
|
return (IH264E_BITSTREAM_BUFFER_OVERFLOW);
|
|
|
}
|
|
|
/* mb header info */
|
|
|
mb_tpm = ps_mb_hdr->u1_mb_type_mode;
|
|
|
|
|
|
/* mb type */
|
|
|
mb_type = mb_tpm & 0xF;
|
|
|
/* CABAC contexts for the MB */
|
|
|
ih264e_get_cabac_context(ps_ent_ctxt, mb_type);
|
|
|
ps_curr_ctxt = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
|
|
|
|
|
|
/* if Intra MB */
|
|
|
if (mb_type == I16x16 || mb_type == I4x4)
|
|
|
{
|
|
|
cbp = ps_mb_hdr->u1_cbp;
|
|
|
mb_qp_delta = ps_mb_hdr->u1_mb_qp_delta;
|
|
|
|
|
|
/* Starting bitstream offset for header in bits */
|
|
|
bitstream_start_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
|
|
|
/* Encode mb_skip_flag */
|
|
|
ih264e_cabac_enc_mb_skip(0, ps_cabac_ctxt, MB_SKIP_FLAG_B_SLICE);
|
|
|
u4_cbp_c = (cbp >> 4);
|
|
|
u4_cbp_l = (cbp & 0xF);
|
|
|
if (mb_type == I16x16)
|
|
|
{
|
|
|
luma_intra_mode = ((mb_tpm >> 4) & 3) + 1 + (u4_cbp_c << 2)
|
|
|
+ (u4_cbp_l == 15) * 12;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
luma_intra_mode = 0;
|
|
|
}
|
|
|
/* Encode intra mb type */
|
|
|
{
|
|
|
mb_info_ctxt_t *ps_left_ctxt = ps_cabac_ctxt->ps_left_ctxt_mb_info;
|
|
|
mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
|
|
|
UWORD32 u4_ctx_inc = 0;
|
|
|
|
|
|
if (ps_left_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
|
|
|
u4_ctx_inc += ((ps_left_ctxt->u1_mb_type & CAB_BD16x16_MASK)
|
|
|
!= CAB_BD16x16) ? 1 : 0;
|
|
|
if (ps_top_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
|
|
|
u4_ctx_inc += ((ps_top_ctxt->u1_mb_type & CAB_BD16x16_MASK)
|
|
|
!= CAB_BD16x16) ? 1 : 0;
|
|
|
|
|
|
/* Intra Prefix Only "111101" */
|
|
|
u4_ctx_inc = (u4_ctx_inc | 0x05555430);
|
|
|
ih264e_encode_decision_bins(0x2f,
|
|
|
6,
|
|
|
u4_ctx_inc,
|
|
|
3,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ MB_TYPE_B_SLICE,
|
|
|
ps_cabac_ctxt);
|
|
|
|
|
|
ih264e_cabac_enc_intra_mb_type(BSLICE, (UWORD8) luma_intra_mode,
|
|
|
ps_cabac_ctxt, MB_TYPE_B_SLICE);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (mb_type == I4x4)
|
|
|
{
|
|
|
/* Intra 4x4 modes */
|
|
|
mb_hdr_i4x4_t *ps_mb_hdr_i4x4 = (mb_hdr_i4x4_t *)ps_ent_ctxt->pv_mb_header_data;
|
|
|
ih264e_cabac_enc_4x4mb_modes(ps_cabac_ctxt, ps_mb_hdr_i4x4->au1_sub_blk_modes);
|
|
|
}
|
|
|
chroma_intra_mode = (mb_tpm >> 6);
|
|
|
|
|
|
ih264e_cabac_enc_chroma_predmode(chroma_intra_mode, ps_cabac_ctxt);
|
|
|
|
|
|
if (mb_type != I16x16)
|
|
|
{
|
|
|
/* encode CBP */
|
|
|
ih264e_cabac_enc_cbp(cbp, ps_cabac_ctxt);
|
|
|
}
|
|
|
|
|
|
if ((cbp > 0) || (mb_type == I16x16))
|
|
|
{
|
|
|
ih264e_cabac_enc_mb_qp_delta(mb_qp_delta, ps_cabac_ctxt);
|
|
|
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
/* Starting bitstream offset for residue */
|
|
|
bitstream_start_offset = bitstream_end_offset;
|
|
|
|
|
|
/* Encoding Residue */
|
|
|
if (mb_type == I16x16)
|
|
|
{
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I16x16;
|
|
|
ps_curr_ctxt->u1_cbp = (UWORD8) cbp;
|
|
|
ih264e_cabac_encode_residue_luma_dc(ps_ent_ctxt);
|
|
|
ih264e_cabac_encode_residue(ps_ent_ctxt, cbp, LUMA_AC_CTXCAT);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_cbp = (UWORD8) cbp;
|
|
|
ps_curr_ctxt->u1_mb_type = I4x4;
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I4x4;
|
|
|
ih264e_cabac_encode_residue(ps_ent_ctxt, cbp, LUMA_4X4_CTXCAT);
|
|
|
ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
|
|
|
ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_yuv_dc_csbp &= 0x6;
|
|
|
}
|
|
|
|
|
|
/* Ending bitstream offset for reside in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_residue_bits[0] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp = 0;
|
|
|
ps_curr_ctxt->u1_yuv_dc_csbp = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_y_ac_csbp) = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = 0;
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
}
|
|
|
|
|
|
memset(ps_curr_ctxt->u1_mv, 0, 16);
|
|
|
memset(ps_cabac_ctxt->pu1_left_mv_ctxt_inc, 0, 16);
|
|
|
ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_cbp = (UWORD8) cbp;
|
|
|
|
|
|
if (mb_type == I16x16)
|
|
|
{
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I16x16;
|
|
|
pu1_byte += sizeof(mb_hdr_i16x16_t);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_I4x4;
|
|
|
pu1_byte += sizeof(mb_hdr_i4x4_t);
|
|
|
}
|
|
|
|
|
|
ps_ent_ctxt->pv_mb_header_data = pu1_byte;
|
|
|
|
|
|
return IH264E_SUCCESS;
|
|
|
}
|
|
|
|
|
|
else /* Inter MB */
|
|
|
{
|
|
|
/* Starting bitstream offset for header in bits */
|
|
|
bitstream_start_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
/* Encoding B_Direct_16x16 */
|
|
|
if (mb_type == BDIRECT)
|
|
|
{
|
|
|
cbp = ps_mb_hdr->u1_cbp;
|
|
|
mb_qp_delta = ps_mb_hdr->u1_mb_qp_delta;
|
|
|
|
|
|
|
|
|
/* Encoding mb_skip */
|
|
|
ih264e_cabac_enc_mb_skip(0, ps_cabac_ctxt, MB_SKIP_FLAG_B_SLICE);
|
|
|
|
|
|
/* Encoding mb_type as B_Direct_16x16 */
|
|
|
{
|
|
|
|
|
|
mb_info_ctxt_t *ps_left_ctxt =
|
|
|
ps_cabac_ctxt->ps_left_ctxt_mb_info;
|
|
|
mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
|
|
|
UWORD32 u4_ctx_inc = 0;
|
|
|
|
|
|
if (ps_left_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
|
|
|
u4_ctx_inc += ((ps_left_ctxt->u1_mb_type & CAB_BD16x16_MASK)
|
|
|
!= CAB_BD16x16) ? 1 : 0;
|
|
|
if (ps_top_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
|
|
|
u4_ctx_inc += ((ps_top_ctxt->u1_mb_type & CAB_BD16x16_MASK)
|
|
|
!= CAB_BD16x16) ? 1 : 0;
|
|
|
/* Encode the bin */
|
|
|
ih264e_cabac_encode_bin(
|
|
|
ps_cabac_ctxt,
|
|
|
0,
|
|
|
ps_cabac_ctxt->au1_cabac_ctxt_table
|
|
|
+ MB_TYPE_B_SLICE + u4_ctx_inc);
|
|
|
|
|
|
}
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_BD16x16;
|
|
|
memset(ps_curr_ctxt->u1_mv, 0, 16);
|
|
|
memset(ps_cabac_ctxt->pu1_left_mv_ctxt_inc, 0, 16);
|
|
|
|
|
|
/* Encode CBP */
|
|
|
ih264e_cabac_enc_cbp(cbp, ps_cabac_ctxt);
|
|
|
|
|
|
if (cbp)
|
|
|
{
|
|
|
/* encode mb_qp_delta */
|
|
|
ih264e_cabac_enc_mb_qp_delta(mb_qp_delta, ps_cabac_ctxt);
|
|
|
}
|
|
|
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[1] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
/* Starting bitstream offset for residue */
|
|
|
bitstream_start_offset = bitstream_end_offset;
|
|
|
/* Starting bitstream offset for residue */
|
|
|
|
|
|
pu1_byte += sizeof(mb_hdr_bdirect_t);
|
|
|
}
|
|
|
|
|
|
else if (mb_type == BSKIP)/* MB = BSKIP */
|
|
|
{
|
|
|
ih264e_cabac_enc_mb_skip(1, ps_cabac_ctxt, MB_SKIP_FLAG_B_SLICE);
|
|
|
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_B_SKIP;
|
|
|
|
|
|
memset(ps_curr_ctxt->u1_mv, 0, 16);
|
|
|
memset(ps_cabac_ctxt->pu1_left_mv_ctxt_inc, 0, 16);
|
|
|
cbp = 0;
|
|
|
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[1] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
/* Starting bitstream offset for residue */
|
|
|
|
|
|
pu1_byte += sizeof(mb_hdr_bskip_t);
|
|
|
}
|
|
|
|
|
|
else /* mbype is B_L0_16x16, B_L1_16x16 or B_Bi_16x16 */
|
|
|
{
|
|
|
mb_hdr_b16x16_t *ps_mb_hdr_b16x16 = (mb_hdr_b16x16_t *)ps_ent_ctxt->pv_mb_header_data;
|
|
|
|
|
|
WORD32 i4_mb_part_pred_mode = (mb_tpm >> 4);
|
|
|
UWORD32 u4_mb_type = mb_type - B16x16 + B_L0_16x16
|
|
|
+ i4_mb_part_pred_mode;
|
|
|
cbp = ps_mb_hdr->u1_cbp;
|
|
|
mb_qp_delta = ps_mb_hdr->u1_mb_qp_delta;
|
|
|
|
|
|
/* Encoding mb_skip */
|
|
|
ih264e_cabac_enc_mb_skip(0, ps_cabac_ctxt, MB_SKIP_FLAG_B_SLICE);
|
|
|
|
|
|
/* Encoding mb_type as B16x16 */
|
|
|
{
|
|
|
mb_info_ctxt_t *ps_left_ctxt =
|
|
|
ps_cabac_ctxt->ps_left_ctxt_mb_info;
|
|
|
mb_info_ctxt_t *ps_top_ctxt = ps_cabac_ctxt->ps_top_ctxt_mb_info;
|
|
|
UWORD32 u4_ctx_inc = 0;
|
|
|
|
|
|
UWORD32 u4_mb_type_bins = u4_b_mb_type[u4_mb_type];
|
|
|
UWORD32 u4_bin_len = (u4_mb_type_bins >> 8) & 0x0F;
|
|
|
u4_mb_type_bins = u4_mb_type_bins & 0xFF;
|
|
|
|
|
|
if (ps_left_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
|
|
|
u4_ctx_inc += ((ps_left_ctxt->u1_mb_type & CAB_BD16x16_MASK)
|
|
|
!= CAB_BD16x16) ? 1 : 0;
|
|
|
if (ps_top_ctxt != ps_cabac_ctxt->ps_def_ctxt_mb_info)
|
|
|
u4_ctx_inc += ((ps_top_ctxt->u1_mb_type & CAB_BD16x16_MASK)
|
|
|
!= CAB_BD16x16) ? 1 : 0;
|
|
|
|
|
|
u4_ctx_inc = u4_ctx_inc | ui_b_mb_type_ctx_inc[u4_mb_type];
|
|
|
|
|
|
ih264e_encode_decision_bins(u4_mb_type_bins,
|
|
|
u4_bin_len,
|
|
|
u4_ctx_inc,
|
|
|
u4_bin_len,
|
|
|
&(ps_cabac_ctxt->au1_cabac_ctxt_table[MB_TYPE_B_SLICE]),
|
|
|
ps_cabac_ctxt);
|
|
|
}
|
|
|
|
|
|
ps_curr_ctxt->u1_mb_type = CAB_NON_BD16x16;
|
|
|
{
|
|
|
WORD16 *pi2_mv_ptr = (WORD16 *) ps_mb_hdr_b16x16->ai2_mv;
|
|
|
|
|
|
/* Get the pred modes */
|
|
|
ps_curr_ctxt->u1_mb_type = (ps_curr_ctxt->u1_mb_type
|
|
|
| CAB_NON_BD16x16);
|
|
|
/* Encoding motion vector for B16x16 */
|
|
|
ih264e_cabac_enc_mvds_b16x16(ps_cabac_ctxt, pi2_mv_ptr,
|
|
|
i4_mb_part_pred_mode);
|
|
|
}
|
|
|
/* Encode CBP */
|
|
|
ih264e_cabac_enc_cbp(cbp, ps_cabac_ctxt);
|
|
|
|
|
|
if (cbp)
|
|
|
{
|
|
|
/* encode mb_qp_delta */
|
|
|
ih264e_cabac_enc_mb_qp_delta(mb_qp_delta, ps_cabac_ctxt);
|
|
|
}
|
|
|
|
|
|
/* Ending bitstream offset for header in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_header_bits[1] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
/* Starting bitstream offset for residue */
|
|
|
bitstream_start_offset = bitstream_end_offset;
|
|
|
|
|
|
pu1_byte += sizeof(mb_hdr_b16x16_t);
|
|
|
}
|
|
|
|
|
|
if (cbp > 0)
|
|
|
{
|
|
|
/* Encode residue */
|
|
|
ih264e_cabac_encode_residue(ps_ent_ctxt, cbp, LUMA_4X4_CTXCAT);
|
|
|
/* Ending bitstream offset for reside in bits */
|
|
|
bitstream_end_offset = GET_NUM_BITS(ps_bitstream);
|
|
|
ps_ent_ctxt->u4_residue_bits[1] += bitstream_end_offset
|
|
|
- bitstream_start_offset;
|
|
|
|
|
|
ps_cabac_ctxt->pu1_left_yuv_dc_csbp[0] &= 0x6;
|
|
|
ps_curr_ctxt->u1_yuv_dc_csbp &= 0x6;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ps_curr_ctxt->u1_yuv_ac_csbp = 0;
|
|
|
ps_curr_ctxt->u1_yuv_dc_csbp = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_y_ac_csbp) = 0;
|
|
|
*(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = 0;
|
|
|
}
|
|
|
ps_curr_ctxt->u1_intrapred_chroma_mode = 0;
|
|
|
ps_curr_ctxt->u1_cbp = cbp;
|
|
|
ps_ent_ctxt->pv_mb_header_data = pu1_byte;
|
|
|
return IH264E_SUCCESS;
|
|
|
}
|
|
|
}
|