/****************************************************************************** * * 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 ih264d_parse_mb_header.c * * \brief * This file contains context identifier encoding routines. * * \date * 04/02/2003 * * \author NS *************************************************************************** */ #include <string.h> #include "ih264d_structs.h" #include "ih264d_bitstrm.h" #include "ih264d_cabac.h" #include "ih264_typedefs.h" #include "ih264_macros.h" #include "ih264_platform_macros.h" #include "ih264d_defs.h" #include "ih264d_error_handler.h" #include "ih264d_tables.h" #include "ih264d_debug.h" #include "ih264d_defs.h" #include "ih264d_defs.h" #include "ih264d_mb_utils.h" #include "ih264d_parse_mb_header.h" #include "ih264d_defs.h" /*! < CtxtInc index 0 - CtxMbTypeI, CtxMbTypeSISuffix index 1 - CtxMbTypePSuffix, CtxMbTypeBSuffix */ /*! ************************************************************************** * \if Function name : ih264d_parse_mb_type_intra_cabac \endif * * \brief * This function decodes MB type using CABAC entropy coding mode. * * \return * MBType. * ************************************************************************** */ UWORD8 ih264d_parse_mb_type_intra_cabac(UWORD8 u1_inter, struct _DecStruct * ps_dec) { decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; ctxt_inc_mb_info_t * ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; ctxt_inc_mb_info_t * ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; bin_ctxt_model_t *ps_mb_bin_ctxt = ps_dec->p_mb_type_t; WORD8 u1_mb_type, u1_bin; UWORD32 u4_cxt_inc; u4_cxt_inc = 0; if(!u1_inter) { if(ps_left_ctxt != ps_dec->ps_def_ctxt_mb_info) u4_cxt_inc += ((ps_left_ctxt->u1_mb_type != CAB_I4x4) ? 1 : 0); if(ps_top_ctxt != ps_dec->ps_def_ctxt_mb_info) u4_cxt_inc += ((ps_top_ctxt->u1_mb_type != CAB_I4x4) ? 1 : 0); } else { ps_mb_bin_ctxt = ps_mb_bin_ctxt + 3 + (ps_dec->u1_B << 1); } /* b0 */ u1_mb_type = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); if(u1_mb_type) { /* I16x16 or I_PCM mode */ /* b1 */ u1_bin = ih264d_decode_terminate(ps_cab_env, ps_bitstrm); if(u1_bin == 0) { /* I16x16 mode */ /* Read b2 and b3 */ u4_cxt_inc = (u1_inter) ? 0x021 : 0x043; u1_bin = ih264d_decode_bins(2, u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); if(u1_bin & 0x01) u1_mb_type += 4; if(u1_bin & 0x02) u1_mb_type += 12; if(u1_bin & 0x01) { /* since b3=1, Read three bins */ u4_cxt_inc = (u1_inter) ? 0x0332 : 0x0765; u1_bin = (UWORD8)ih264d_decode_bins(3, u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); } else { /* Read two bins */ u4_cxt_inc = (u1_inter) ? 0x033 : 0x076; u1_bin = (UWORD8)ih264d_decode_bins(2, u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); } u1_mb_type += u1_bin; } else { /* I_PCM mode */ /* b1=1 */ u1_mb_type = 25; } } return (u1_mb_type); } /*! ************************************************************************** * \if Function name : ih264d_parse_mb_type_cabac \endif * * \brief * This function decodes MB type using CABAC entropy coding mode. * * \return * MBType. * ************************************************************************** */ UWORD32 ih264d_parse_mb_type_cabac(struct _DecStruct * ps_dec) { const UWORD8 uc_slice_type = ps_dec->ps_cur_slice->u1_slice_type; decoding_envirnoment_t *ps_cab_env = &ps_dec->s_cab_dec_env; dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm; ctxt_inc_mb_info_t *ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; ctxt_inc_mb_info_t *ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; WORD8 c_ctxt_inc; bin_ctxt_model_t *ps_mb_bin_ctxt = ps_dec->p_mb_type_t; WORD8 u1_mb_type = 0, u1_bin; UWORD32 u4_cxt_inc; INC_SYM_COUNT(ps_cab_env); c_ctxt_inc = 0; if(uc_slice_type == SI_SLICE) { /* b0 */ if(ps_left_ctxt != ps_dec->ps_def_ctxt_mb_info) c_ctxt_inc += ((ps_left_ctxt->u1_mb_type != CAB_SI4x4) ? 1 : 0); if(ps_top_ctxt != ps_dec->ps_def_ctxt_mb_info) c_ctxt_inc += ((ps_top_ctxt->u1_mb_type != CAB_SI4x4) ? 1 : 0); u4_cxt_inc = c_ctxt_inc; u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); if(u1_bin == 0) { /* SI MB */ u1_mb_type = 0; } else { u1_mb_type = 1 + ih264d_parse_mb_type_intra_cabac(0, ps_dec); } } else if(uc_slice_type == P_SLICE) { /* P Slice */ /* b0 */ u4_cxt_inc = 0; u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); if(!u1_bin) { /* Inter MB types */ /* b1 */ u4_cxt_inc = 0x01; u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); /* b2 */ u4_cxt_inc = u1_bin + 2; u1_mb_type = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); u1_mb_type = (u1_bin << 1) + u1_mb_type; if(u1_mb_type) u1_mb_type = 4 - u1_mb_type; } else { /* Intra Prefix 1 found */ /* Intra MB type */ u1_mb_type = 5 + ih264d_parse_mb_type_intra_cabac(1, ps_dec); } } else if(uc_slice_type == B_SLICE) { WORD8 a, b; /* B Slice */ /* b0 */ /* a = b = 0, if B slice and MB is a SKIP or B_DIRECT16x16 */ a = 0; b = 0; u1_mb_type = 0; if(ps_left_ctxt != ps_dec->ps_def_ctxt_mb_info) a = ((ps_left_ctxt->u1_mb_type & CAB_BD16x16_MASK) != CAB_BD16x16); if(ps_top_ctxt != ps_dec->ps_def_ctxt_mb_info) b = ((ps_top_ctxt->u1_mb_type & CAB_BD16x16_MASK) != CAB_BD16x16); u4_cxt_inc = a + b; u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); if(u1_bin) { /* b1 */ u4_cxt_inc = 0x03; u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); if(!u1_bin) { /* b2 */ u4_cxt_inc = 0x05; u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); u1_mb_type = u1_bin + 1; } else { u1_mb_type = 3; /* b2 */ u4_cxt_inc = 0x04; u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); if(u1_bin) { u1_mb_type += 8; /* b3 */ u4_cxt_inc = 0x05; u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); if(!u1_bin) { u1_mb_type++; /* b4, b5, b6 */ u4_cxt_inc = 0x0555; u1_bin = (UWORD8)ih264d_decode_bins(3, u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); u1_mb_type += u1_bin; } else { /* b4 */ u4_cxt_inc = 0x05; u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); if(u1_bin) { /* b5 */ u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); u1_mb_type += (u1_bin ? 11 : 0); } else { u1_mb_type = 20; /* b5 */ u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); if(!u1_bin) { /* b6 */ u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); u1_mb_type += u1_bin; } else { /* Intra Prefix 111101 found */ /* Intra MB type */ u1_mb_type = 23 + ih264d_parse_mb_type_intra_cabac( 1, ps_dec); } } } } else { /* b3, b4, b5 */ u4_cxt_inc = 0x0555; u1_bin = (UWORD8)ih264d_decode_bins(3, u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, ps_cab_env); u1_mb_type += u1_bin; } } } } return ((UWORD32)u1_mb_type); } /*! ************************************************************************** * \if Function name : DecSubMBType \endif * * \brief * This function decodes MB type using CABAC entropy coding mode. * * \return * MBType. * ************************************************************************** */ UWORD32 ih264d_parse_submb_type_cabac(const UWORD8 u1_slc_type_b, decoding_envirnoment_t * ps_cab_env, dec_bit_stream_t * ps_bitstrm, bin_ctxt_model_t * ps_sub_mb_cxt) { WORD8 u1_sub_mb_type, u1_bin; INC_SYM_COUNT(ps_cab_env); u1_sub_mb_type = 0; u1_bin = (UWORD8)ih264d_decode_bin(0, ps_sub_mb_cxt, ps_bitstrm, ps_cab_env); if(u1_slc_type_b ^ u1_bin) return 0; if(!u1_slc_type_b) { /* P Slice */ u1_sub_mb_type = 1; u1_bin = (UWORD8)ih264d_decode_bin(1, ps_sub_mb_cxt, ps_bitstrm, ps_cab_env); if(u1_bin == 1) { u1_bin = (UWORD8)ih264d_decode_bin(2, ps_sub_mb_cxt, ps_bitstrm, ps_cab_env); u1_sub_mb_type = (2 + (!u1_bin)); } return u1_sub_mb_type; } else { /* B Slice */ /* b1 */ u1_bin = (UWORD8)ih264d_decode_bin(1, ps_sub_mb_cxt, ps_bitstrm, ps_cab_env); if(u1_bin) { /* b2 */ u1_bin = (UWORD8)ih264d_decode_bin(2, ps_sub_mb_cxt, ps_bitstrm, ps_cab_env); if(u1_bin) { /* b3 */ u1_sub_mb_type = 7; u1_bin = (UWORD8)ih264d_decode_bin(3, ps_sub_mb_cxt, ps_bitstrm, ps_cab_env); u1_sub_mb_type += u1_bin << 2; u1_bin = !u1_bin; /* b4 */ if(u1_bin == 0) { u1_bin = ih264d_decode_bin(3, ps_sub_mb_cxt, ps_bitstrm, ps_cab_env); } else { u1_bin = (UWORD8)ih264d_decode_bins(2, 0x33, ps_sub_mb_cxt, ps_bitstrm, ps_cab_env); } return (u1_sub_mb_type + u1_bin); } else { /* b3 */ u1_bin = (UWORD8)ih264d_decode_bins(2, 0x33, ps_sub_mb_cxt, ps_bitstrm, ps_cab_env); return (3 + u1_bin); } } else { /* b2 */ u1_bin = (UWORD8)ih264d_decode_bin(3, ps_sub_mb_cxt, ps_bitstrm, ps_cab_env); return (1 + u1_bin); } } } /*! ************************************************************************** * \if Function name : ih264d_parse_ref_idx_cabac \endif * * \brief * This function decodes Reference Index using CABAC entropy coding mode. * * \return * None * ************************************************************************** */ WORD32 ih264d_parse_ref_idx_cabac(const UWORD8 u1_num_part, const UWORD8 u1_b2, const UWORD8 u1_max_ref_minus1, const UWORD8 u1_mb_mode, WORD8 * pi1_ref_idx, WORD8 * const pi1_lft_cxt, WORD8 * const pi1_top_cxt, decoding_envirnoment_t * const ps_cab_env, dec_bit_stream_t * const ps_bitstrm, bin_ctxt_model_t * const ps_ref_cxt) { UWORD8 u1_a, u1_b; UWORD32 u4_cxt_inc; UWORD8 u1_blk_no, u1_i, u1_idx_lft, u1_idx_top; WORD8 i1_ref_idx; for(u1_blk_no = 0, u1_i = 0; u1_i < u1_num_part; u1_i++, pi1_ref_idx++) { u1_idx_lft = ((u1_blk_no & 0x02) >> 1) + u1_b2; u1_idx_top = (u1_blk_no & 0x01) + u1_b2; i1_ref_idx = *pi1_ref_idx; if(i1_ref_idx > 0) { u1_a = pi1_lft_cxt[u1_idx_lft] > 0; u1_b = pi1_top_cxt[u1_idx_top] > 0; u4_cxt_inc = u1_a + (u1_b << 1); u4_cxt_inc = (u4_cxt_inc | 0x55540); i1_ref_idx = (WORD8)ih264d_decode_bins_unary(32, u4_cxt_inc, ps_ref_cxt, ps_bitstrm, ps_cab_env); if((i1_ref_idx > u1_max_ref_minus1) || (i1_ref_idx < 0)) { return ERROR_REF_IDX; } *pi1_ref_idx = i1_ref_idx; INC_SYM_COUNT(ps_cab_env); } /* Storing Reference Idx Information */ pi1_lft_cxt[u1_idx_lft] = i1_ref_idx; pi1_top_cxt[u1_idx_top] = i1_ref_idx; u1_blk_no = u1_blk_no + 1 + (u1_mb_mode & 0x01); } /* if(!u1_sub_mb) */ if(u1_num_part != 4) { pi1_lft_cxt[(!(u1_mb_mode & 0x1)) + u1_b2] = pi1_lft_cxt[u1_b2]; pi1_top_cxt[(!(u1_mb_mode & 0x2)) + u1_b2] = pi1_top_cxt[u1_b2]; } return OK; } /*! ************************************************************************** * \if Function name : ih264d_parse_mb_qp_delta_cabac \endif * * \brief * This function decodes MB Qp delta using CABAC entropy coding mode. * * \return * None * ************************************************************************** */ WORD32 ih264d_parse_mb_qp_delta_cabac(struct _DecStruct * ps_dec, WORD8 *pi1_mb_qp_delta) { decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; UWORD8 u1_code_num; bin_ctxt_model_t *ps_mb_qp_delta_ctxt = ps_dec->p_mb_qp_delta_t; UWORD32 u4_cxt_inc; INC_SYM_COUNT(ps_cab_env); u4_cxt_inc = (!(!(ps_dec->i1_prev_mb_qp_delta))); u1_code_num = 0; u4_cxt_inc = (u4_cxt_inc | 0x33320); /* max number of bins = 53, since Range for MbQpDelta= -26 to +25 inclusive, UNARY code */ u1_code_num = ih264d_decode_bins_unary(32, u4_cxt_inc, ps_mb_qp_delta_ctxt, ps_bitstrm, ps_cab_env); if(u1_code_num == 32) { /* Read remaining 21 bins */ UWORD8 uc_codeNumX; u4_cxt_inc = 0x33333; uc_codeNumX = ih264d_decode_bins_unary(21, u4_cxt_inc, ps_mb_qp_delta_ctxt, ps_bitstrm, ps_cab_env); u1_code_num = u1_code_num + uc_codeNumX; } *pi1_mb_qp_delta = (u1_code_num + 1) >> 1; /* Table 9.3: If code_num is even Syntax Element has -ve value */ if(!(u1_code_num & 0x01)) *pi1_mb_qp_delta = -(*pi1_mb_qp_delta); /* Range of MbQpDelta= -26 to +25 inclusive */ if((*pi1_mb_qp_delta < -26) || (*pi1_mb_qp_delta > 25)) return ERROR_INV_RANGE_QP_T; ps_dec->i1_prev_mb_qp_delta = *pi1_mb_qp_delta; return OK; } /*! ************************************************************************** * \if Function name : ih264d_parse_chroma_pred_mode_cabac \endif * * \brief * This function decodes Chroma Pred mode using CABAC entropy coding mode. * * \return * None * ************************************************************************** */ WORD8 ih264d_parse_chroma_pred_mode_cabac(struct _DecStruct * ps_dec) { decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; ctxt_inc_mb_info_t * ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; ctxt_inc_mb_info_t * ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; WORD8 i1_chroma_pred_mode, a, b; UWORD32 u4_cxt_inc; INC_SYM_COUNT(ps_cab_env); /* Binarization is TU and Cmax=3 */ i1_chroma_pred_mode = 0; a = 0; b = 0; a = ((ps_left_ctxt->u1_intra_chroma_pred_mode != 0) ? 1 : 0); b = ((ps_top_ctxt->u1_intra_chroma_pred_mode != 0) ? 1 : 0); u4_cxt_inc = a + b; u4_cxt_inc = (u4_cxt_inc | 0x330); i1_chroma_pred_mode = ih264d_decode_bins_tunary( 3, u4_cxt_inc, ps_dec->p_intra_chroma_pred_mode_t, ps_bitstrm, ps_cab_env); return (i1_chroma_pred_mode); } /*****************************************************************************/ /* */ /* Function Name : ih264d_parse_transform8x8flag_cabac */ /* */ /* Description : */ /* Inputs : */ /* */ /* */ /* Returns : */ /* */ /* Revision History: */ /* */ /* DD MM YYYY Author(s) Changes (Describe the changes made) */ /* Rajasekhar Creation */ /* */ /*****************************************************************************/ UWORD8 ih264d_parse_transform8x8flag_cabac(struct _DecStruct * ps_dec, dec_mb_info_t * ps_cur_mb_info) { decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; ctxt_inc_mb_info_t * ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; ctxt_inc_mb_info_t * ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; UWORD8 u1_transform_8x8flag; UWORD8 u1_mb_ngbr_avail = ps_cur_mb_info->u1_mb_ngbr_availablity; WORD8 a, b; UWORD32 u4_cxt_inc; /* for calculating the context increment for transform8x8 u4_flag */ /* it reads transform8x8 u4_flag of the neighbors through */ /* Binarization is FLC */ a = 0; b = 0; if(u1_mb_ngbr_avail & LEFT_MB_AVAILABLE_MASK) { a = ps_left_ctxt->u1_transform8x8_ctxt; } if(u1_mb_ngbr_avail & TOP_MB_AVAILABLE_MASK) { b = ps_top_ctxt->u1_transform8x8_ctxt; } u4_cxt_inc = a + b; u1_transform_8x8flag = ih264d_decode_bin( u4_cxt_inc, ps_dec->s_high_profile.ps_transform8x8_flag, ps_bitstrm, ps_cab_env); return (u1_transform_8x8flag); } /*! ************************************************************************** * \if Function name : ih264d_read_intra_pred_modes_cabac \endif * * \brief * Reads the intra pred mode related values of I4x4 MB from bitstream. * * This function will read the prev intra pred mode flags and * stores it in pu1_prev_intra4x4_pred_mode_flag. If the u4_flag * indicates that most probable mode is not intra pred mode, then * the rem_intra4x4_pred_mode is read and stored in * pu1_rem_intra4x4_pred_mode array. * * * \return * 0 on success and Error code otherwise * ************************************************************************** */ WORD32 ih264d_read_intra_pred_modes_cabac(dec_struct_t * ps_dec, UWORD8 * pu1_prev_intra4x4_pred_mode_flag, UWORD8 * pu1_rem_intra4x4_pred_mode, UWORD8 u1_tran_form8x8) { WORD32 i4x4_luma_blk_idx = 0; dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; bin_ctxt_model_t *ps_ctxt_ipred_luma_mpm, *ps_ctx_ipred_luma_rm; WORD32 i4_rem_intra4x4_pred_mode; UWORD32 u4_prev_intra4x4_pred_mode_flag; UWORD32 u4_code_int_range, u4_code_int_val_ofst; const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; ps_ctxt_ipred_luma_mpm = ps_dec->p_prev_intra4x4_pred_mode_flag_t; ps_ctx_ipred_luma_rm = ps_dec->p_rem_intra4x4_pred_mode_t; SWITCHOFFTRACE; i4x4_luma_blk_idx = (0 == u1_tran_form8x8) ? 16 : 4; u4_code_int_range = ps_cab_env->u4_code_int_range; u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; do { DECODE_ONE_BIN_MACRO(ps_ctxt_ipred_luma_mpm, u4_code_int_range, u4_code_int_val_ofst, pu4_table, ps_bitstrm, u4_prev_intra4x4_pred_mode_flag) *pu1_prev_intra4x4_pred_mode_flag = u4_prev_intra4x4_pred_mode_flag; i4_rem_intra4x4_pred_mode = -1; if(!u4_prev_intra4x4_pred_mode_flag) { /*inlining DecodeDecisionBins_FLC*/ { UWORD8 u1_max_bins = 3; UWORD32 u4_value; UWORD32 u4_symbol, i; i = 0; u4_value = 0; do { DECODE_ONE_BIN_MACRO(ps_ctx_ipred_luma_rm, u4_code_int_range, u4_code_int_val_ofst, pu4_table, ps_bitstrm, u4_symbol) INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); u4_value = u4_value | (u4_symbol << i); i++; } while(i < u1_max_bins); i4_rem_intra4x4_pred_mode = (u4_value); } } (*pu1_rem_intra4x4_pred_mode) = i4_rem_intra4x4_pred_mode; COPYTHECONTEXT("intra4x4_pred_mode", i4_rem_intra4x4_pred_mode); pu1_prev_intra4x4_pred_mode_flag++; pu1_rem_intra4x4_pred_mode++; i4x4_luma_blk_idx--; } while(i4x4_luma_blk_idx); ps_cab_env->u4_code_int_range = u4_code_int_range; ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; return (0); } /*! ************************************************************************** * \if Function name : ih264d_parse_ctx_cbp_cabac \endif * * \brief * This function decodes CtxCbpLuma and CtxCbpChroma (CBP of a Macroblock). * using CABAC entropy coding mode. * * \return * CBP of a MB. * ************************************************************************** */ UWORD32 ih264d_parse_ctx_cbp_cabac(struct _DecStruct * ps_dec) { UWORD32 u4_cxt_inc; decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; ctxt_inc_mb_info_t * ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; ctxt_inc_mb_info_t * ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; bin_ctxt_model_t *ps_ctxt_cbp_luma = ps_dec->p_cbp_luma_t, *ps_bin_ctxt; WORD8 c_Cbp; //,i,j; UWORD32 u4_code_int_range, u4_code_int_val_ofst; UWORD32 u4_offset, *pu4_buffer; const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; INC_SYM_COUNT(ps_cab_env); /* CBP Luma, FL, Cmax = 15, L = 4 */ u4_cxt_inc = (!((ps_top_ctxt->u1_cbp >> 2) & 0x01)) << 1; u4_cxt_inc += !((ps_left_ctxt->u1_cbp >> 1) & 0x01); u4_offset = ps_bitstrm->u4_ofst; pu4_buffer = ps_bitstrm->pu4_buffer; u4_code_int_range = ps_cab_env->u4_code_int_range; u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; /*renormalize to ensure there 23 bits more in the u4_code_int_val_ofst*/ { UWORD32 u4_clz, read_bits; u4_clz = CLZ(u4_code_int_range); FLUSHBITS(u4_offset, u4_clz) NEXTBITS(read_bits, u4_offset, pu4_buffer, 23) u4_code_int_range = u4_code_int_range << u4_clz; u4_code_int_val_ofst = (u4_code_int_val_ofst << u4_clz) | read_bits; } ps_bin_ctxt = ps_ctxt_cbp_luma + u4_cxt_inc; /*inlining DecodeDecision_onebin without renorm*/ { UWORD32 u4_qnt_int_range, u4_int_range_lps; UWORD32 u4_symbol, u1_mps_state; UWORD32 table_lookup; UWORD32 u4_clz; u1_mps_state = (ps_bin_ctxt->u1_mps_state); u4_clz = CLZ(u4_code_int_range); u4_qnt_int_range = u4_code_int_range << u4_clz; u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; table_lookup = pu4_table[(u1_mps_state << 2) + u4_qnt_int_range]; u4_int_range_lps = table_lookup & 0xff; u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); u4_code_int_range = u4_code_int_range - u4_int_range_lps; u4_symbol = ((u1_mps_state >> 6) & 0x1); /*if mps*/ u1_mps_state = (table_lookup >> 8) & 0x7F; CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, u4_int_range_lps, u1_mps_state, table_lookup) INC_BIN_COUNT(ps_cab_env); ps_bin_ctxt->u1_mps_state = u1_mps_state; c_Cbp = u4_symbol; } u4_cxt_inc = (!((ps_top_ctxt->u1_cbp >> 3) & 0x01)) << 1; u4_cxt_inc += !(c_Cbp & 0x01); ps_bin_ctxt = ps_ctxt_cbp_luma + u4_cxt_inc; /*inlining DecodeDecision_onebin without renorm*/ { UWORD32 u4_qnt_int_range, u4_int_range_lps; UWORD32 u4_symbol, u1_mps_state; UWORD32 table_lookup; UWORD32 u4_clz; u1_mps_state = (ps_bin_ctxt->u1_mps_state); u4_clz = CLZ(u4_code_int_range); u4_qnt_int_range = u4_code_int_range << u4_clz; u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; table_lookup = pu4_table[(u1_mps_state << 2) + u4_qnt_int_range]; u4_int_range_lps = table_lookup & 0xff; u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); u4_code_int_range = u4_code_int_range - u4_int_range_lps; u4_symbol = ((u1_mps_state >> 6) & 0x1); /*if mps*/ u1_mps_state = (table_lookup >> 8) & 0x7F; CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, u4_int_range_lps, u1_mps_state, table_lookup) INC_BIN_COUNT(ps_cab_env); ps_bin_ctxt->u1_mps_state = u1_mps_state; c_Cbp |= u4_symbol << 1; } u4_cxt_inc = (!(c_Cbp & 0x01)) << 1; u4_cxt_inc += !((ps_left_ctxt->u1_cbp >> 3) & 0x01); ps_bin_ctxt = ps_ctxt_cbp_luma + u4_cxt_inc; /*inlining DecodeDecision_onebin without renorm*/ { UWORD32 u4_qnt_int_range, u4_int_range_lps; UWORD32 u4_symbol, u1_mps_state; UWORD32 table_lookup; UWORD32 u4_clz; u1_mps_state = (ps_bin_ctxt->u1_mps_state); u4_clz = CLZ(u4_code_int_range); u4_qnt_int_range = u4_code_int_range << u4_clz; u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; table_lookup = pu4_table[(u1_mps_state << 2) + u4_qnt_int_range]; u4_int_range_lps = table_lookup & 0xff; u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); u4_code_int_range = u4_code_int_range - u4_int_range_lps; u4_symbol = ((u1_mps_state >> 6) & 0x1); /*if mps*/ u1_mps_state = (table_lookup >> 8) & 0x7F; CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, u4_int_range_lps, u1_mps_state, table_lookup) INC_BIN_COUNT(ps_cab_env); ps_bin_ctxt->u1_mps_state = u1_mps_state; c_Cbp |= u4_symbol << 2; } u4_cxt_inc = (!((c_Cbp >> 1) & 0x01)) << 1; u4_cxt_inc += !((c_Cbp >> 2) & 0x01); ps_bin_ctxt = ps_ctxt_cbp_luma + u4_cxt_inc; /*inlining DecodeDecision_onebin without renorm*/ { UWORD32 u4_qnt_int_range, u4_int_range_lps; UWORD32 u4_symbol, u1_mps_state; UWORD32 table_lookup; UWORD32 u4_clz; u1_mps_state = (ps_bin_ctxt->u1_mps_state); u4_clz = CLZ(u4_code_int_range); u4_qnt_int_range = u4_code_int_range << u4_clz; u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; table_lookup = pu4_table[(u1_mps_state << 2) + u4_qnt_int_range]; u4_int_range_lps = table_lookup & 0xff; u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); u4_code_int_range = u4_code_int_range - u4_int_range_lps; u4_symbol = ((u1_mps_state >> 6) & 0x1); /*if mps*/ u1_mps_state = (table_lookup >> 8) & 0x7F; CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, u4_int_range_lps, u1_mps_state, table_lookup) INC_BIN_COUNT(ps_cab_env); ps_bin_ctxt->u1_mps_state = u1_mps_state; c_Cbp |= u4_symbol << 3; } if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_8) { RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, u4_offset, pu4_buffer) } { UWORD32 u4_cxt_inc; WORD8 a, b, c, d; bin_ctxt_model_t *p_CtxtCbpChroma = ps_dec->p_cbp_chroma_t; /* CBP Chroma, TU, Cmax = 2 */ a = 0; b = 0; c = 0; d = 0; { a = (ps_top_ctxt->u1_cbp > 15) ? 2 : 0; c = (ps_top_ctxt->u1_cbp > 31) ? 2 : 0; } { b = (ps_left_ctxt->u1_cbp > 15) ? 1 : 0; d = (ps_left_ctxt->u1_cbp > 31) ? 1 : 0; } u4_cxt_inc = a + b; u4_cxt_inc = (u4_cxt_inc | ((4 + c + d) << 4)); /*inlining ih264d_decode_bins_tunary */ { UWORD8 u1_max_bins = 2; UWORD32 u4_ctx_inc = u4_cxt_inc; UWORD32 u4_value; UWORD32 u4_symbol; UWORD8 u4_ctx_Inc; bin_ctxt_model_t *ps_bin_ctxt; u4_value = 0; do { u4_ctx_Inc = u4_ctx_inc & 0xF; u4_ctx_inc = u4_ctx_inc >> 4; ps_bin_ctxt = p_CtxtCbpChroma + u4_ctx_Inc; /*inlining DecodeDecision_onebin*/ { UWORD32 u4_qnt_int_range, u4_int_range_lps; UWORD32 u1_mps_state; UWORD32 table_lookup; UWORD32 u4_clz; u1_mps_state = (ps_bin_ctxt->u1_mps_state); u4_clz = CLZ(u4_code_int_range); u4_qnt_int_range = u4_code_int_range << u4_clz; u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; table_lookup = pu4_table[(u1_mps_state << 2) + u4_qnt_int_range]; u4_int_range_lps = table_lookup & 0xff; u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); u4_code_int_range = u4_code_int_range - u4_int_range_lps; u4_symbol = ((u1_mps_state >> 6) & 0x1); /*if mps*/ u1_mps_state = (table_lookup >> 8) & 0x7F; CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, u4_int_range_lps, u1_mps_state, table_lookup) if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_8) { RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, u4_offset, pu4_buffer) } ps_bin_ctxt->u1_mps_state = u1_mps_state; } INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS( ps_cab_env); u4_value++; } while((u4_value < u1_max_bins) & (u4_symbol)); u4_value = u4_value - 1 + u4_symbol; a = (u4_value); } c_Cbp = (c_Cbp | (a << 4)); } ps_bitstrm->u4_ofst = u4_offset; ps_cab_env->u4_code_int_range = u4_code_int_range; ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; return (c_Cbp); } /*! ************************************************************************** * \if Function name : ih264d_get_mvd_cabac \endif * * \brief * This function decodes Horz and Vert mvd_l0 and mvd_l1 using CABAC entropy * coding mode as defined in 9.3.2.3. * * \return * None * ************************************************************************** */ void ih264d_get_mvd_cabac(UWORD8 u1_sub_mb, UWORD8 u1_b2, UWORD8 u1_part_wd, UWORD8 u1_part_ht, UWORD8 u1_dec_mvd, dec_struct_t *ps_dec, mv_pred_t *ps_mv) { UWORD8 u1_abs_mvd_x = 0, u1_abs_mvd_y = 0; UWORD8 u1_sub_mb_x, u1_sub_mb_y; UWORD8 *pu1_top_mv_ctxt, *pu1_lft_mv_ctxt; WORD16 *pi2_mv; u1_sub_mb_x = (UWORD8)(u1_sub_mb & 0x03); u1_sub_mb_y = (UWORD8)(u1_sub_mb >> 2); pu1_top_mv_ctxt = &ps_dec->ps_curr_ctxt_mb_info->u1_mv[u1_sub_mb_x][u1_b2]; pu1_lft_mv_ctxt = &ps_dec->pu1_left_mv_ctxt_inc[u1_sub_mb_y][u1_b2]; pi2_mv = &ps_mv->i2_mv[u1_b2]; if(u1_dec_mvd) { WORD16 i2_mv_x, i2_mv_y; WORD32 i2_temp; { decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; 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]; i2_temp = u2_abs_mvd_x_a + u2_abs_mvd_x_b; i2_mv_x = ih264d_parse_mvd_cabac(ps_bitstrm, ps_cab_env, ps_dec->p_mvd_x_t, i2_temp); i2_temp = u2_abs_mvd_y_a + u2_abs_mvd_y_b; i2_mv_y = ih264d_parse_mvd_cabac(ps_bitstrm, ps_cab_env, ps_dec->p_mvd_y_t, i2_temp); } /***********************************************************************/ /* Store the abs_mvd_values in cabac contexts */ /* The follownig code can be easily optimzed if mvX, mvY clip values */ /* are packed in 16 bits follwed by memcpy */ /***********************************************************************/ u1_abs_mvd_x = CLIP3(0, 127, ABS(i2_mv_x)); u1_abs_mvd_y = CLIP3(0, 127, ABS(i2_mv_y)); COPYTHECONTEXT("MVD", i2_mv_x);COPYTHECONTEXT("MVD", i2_mv_y); /* Storing Mv residuals */ pi2_mv[0] = i2_mv_x; pi2_mv[1] = i2_mv_y; } /***************************************************************/ /* Store abs_mvd_values cabac contexts */ /***************************************************************/ #ifndef ARM { UWORD8 u1_i; for(u1_i = 0; u1_i < u1_part_wd; u1_i++, pu1_top_mv_ctxt += 4) { pu1_top_mv_ctxt[0] = u1_abs_mvd_x; pu1_top_mv_ctxt[1] = u1_abs_mvd_y; } for(u1_i = 0; u1_i < u1_part_ht; u1_i++, pu1_lft_mv_ctxt += 4) { pu1_lft_mv_ctxt[0] = u1_abs_mvd_x; pu1_lft_mv_ctxt[1] = u1_abs_mvd_y; } } #else /* Optimising the loop, with Little-Endian Assumption */ { UWORD16 *pu2_top_cxt = (UWORD16 *)pu1_top_mv_ctxt; UWORD16 *pu2_lft_cxt = (UWORD16 *)pu1_lft_mv_ctxt; UWORD16 u2_pack_mvd = (UWORD16)((u1_abs_mvd_y << 8) | u1_abs_mvd_x); UWORD8 u1_wd = u1_part_wd, u1_ht = u1_part_ht; u1_wd--; *pu2_top_cxt = u2_pack_mvd; pu2_top_cxt += 2; if(u1_wd) { u1_wd--; *pu2_top_cxt = u2_pack_mvd; pu2_top_cxt += 2; } if(u1_wd) { *pu2_top_cxt = u2_pack_mvd; pu2_top_cxt += 2; *pu2_top_cxt = u2_pack_mvd; } u1_ht--; *pu2_lft_cxt = u2_pack_mvd; pu2_lft_cxt += 2; if(u1_ht) { u1_ht--; *pu2_lft_cxt = u2_pack_mvd; pu2_lft_cxt += 2; } if(u1_ht) { *pu2_lft_cxt = u2_pack_mvd; pu2_lft_cxt += 2; *pu2_lft_cxt = u2_pack_mvd; } } #endif } /*****************************************************************************/ /* */ /* Function Name : ih264d_parse_mvd_cabac */ /* */ /* Description : This cabac function decodes the mvd in a given direction */ /* direction ( x or y ) as defined in 9.3.2.3. */ /* */ /* Inputs : 1. pointer to Bitstream */ /* 2. pointer to cabac decoding environmnet */ /* 3. pointer to Mvd context */ /* 4. abs(Top mvd) = u2_abs_mvd_b */ /* 5. abs(left mvd)= u2_abs_mvd_a */ /* */ /* Processing : see section 9.3.2.3 of the standard */ /* */ /* Outputs : i2_mvd */ /* Returns : i2_mvd */ /* */ /* Issues : none */ /* */ /* Revision History: */ /* */ /* DD MM YYYY Author(s) Changes (Describe the changes made) */ /* 16 06 2005 Jay Draft */ /* */ /*****************************************************************************/ WORD16 ih264d_parse_mvd_cabac(dec_bit_stream_t * ps_bitstrm, decoding_envirnoment_t * ps_cab_env, bin_ctxt_model_t * p_ctxt_mvd, UWORD32 i4_temp) { WORD8 k; WORD16 i2_suf; WORD16 i2_mvd; UWORD16 u2_abs_mvd; UWORD32 u4_ctx_inc; UWORD32 u4_prefix; const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; UWORD32 u4_code_int_range, u4_code_int_val_ofst; /* if mvd < 9 */ /* mvd = Prefix */ /* else */ /* mvd = Prefix + Suffix */ /* decode sign bit */ /* Prefix TU decoding Cmax =Ucoff and Suffix 3rd order Exp-Golomb */ u2_abs_mvd = (UWORD16)i4_temp; u4_ctx_inc = 1; if(u2_abs_mvd < 3) u4_ctx_inc = 0; else if(u2_abs_mvd > 32) u4_ctx_inc = 2; u4_ctx_inc = (u4_ctx_inc | 0x65430); /*inlining modified version of ih264d_decode_bins_unary*/ { UWORD8 u1_max_bins = 9; UWORD32 u4_value; UWORD32 u4_symbol; bin_ctxt_model_t *ps_bin_ctxt; UWORD32 u4_ctx_Inc; u4_value = 0; u4_code_int_range = ps_cab_env->u4_code_int_range; u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; do { u4_ctx_Inc = u4_ctx_inc & 0xf; u4_ctx_inc = u4_ctx_inc >> 4; ps_bin_ctxt = p_ctxt_mvd + u4_ctx_Inc; DECODE_ONE_BIN_MACRO(ps_bin_ctxt, u4_code_int_range, u4_code_int_val_ofst, pu4_table, ps_bitstrm, u4_symbol) INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); u4_value++; } while(u4_symbol && u4_value < 5); ps_bin_ctxt = p_ctxt_mvd + 6; if(u4_symbol && (u4_value < u1_max_bins)) { do { DECODE_ONE_BIN_MACRO(ps_bin_ctxt, u4_code_int_range, u4_code_int_val_ofst, pu4_table, ps_bitstrm, u4_symbol) INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); u4_value++; } while(u4_symbol && (u4_value < u1_max_bins)); } ps_cab_env->u4_code_int_range = u4_code_int_range; ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; u4_value = u4_value - 1 + u4_symbol; u4_prefix = (u4_value); } i2_mvd = u4_prefix; if(i2_mvd == 9) { /* Read Suffix */ k = ih264d_decode_bypass_bins_unary(ps_cab_env, ps_bitstrm); i2_suf = (1 << k) - 1; k = k + 3; i2_suf = (i2_suf << 3); i2_mvd += i2_suf; i2_suf = ih264d_decode_bypass_bins(ps_cab_env, k, ps_bitstrm); i2_mvd += i2_suf; } /* Read Sign bit */ if(!i2_mvd) return (i2_mvd); else { UWORD32 u4_code_int_val_ofst, u4_code_int_range; u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; u4_code_int_range = ps_cab_env->u4_code_int_range; if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_9) { UWORD32 *pu4_buffer, u4_offset; pu4_buffer = ps_bitstrm->pu4_buffer; u4_offset = ps_bitstrm->u4_ofst; RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, u4_offset, pu4_buffer) ps_bitstrm->u4_ofst = u4_offset; } u4_code_int_range = u4_code_int_range >> 1; if(u4_code_int_val_ofst >= u4_code_int_range) { /* S=1 */ u4_code_int_val_ofst -= u4_code_int_range; i2_mvd = (-i2_mvd); } ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; ps_cab_env->u4_code_int_range = u4_code_int_range; return (i2_mvd); } }