You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
760 lines
22 KiB
760 lines
22 KiB
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
|
|
*
|
|
* 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.
|
|
*
|
|
******************************************************************************/
|
|
/**
|
|
******************************************************************************
|
|
* @file ihevcd_cabac.c
|
|
*
|
|
* @brief
|
|
* This file contains function definitions related to CABAC parsing
|
|
*
|
|
* @author
|
|
* Ittiam
|
|
*
|
|
*
|
|
* List of Functions
|
|
*
|
|
* ihevcd_cabac_init()
|
|
* ihevcd_cabac_decode_bin()
|
|
* ihevcd_cabac_decode_bypass_bin()
|
|
* ihevcd_cabac_decode_bypass_bins_tunary()
|
|
* ihevcd_cabac_decode_terminate()
|
|
* ihevcd_cabac_decode_bin_tunary()
|
|
* ihevcd_cabac_decode_bypass_bins()
|
|
* ihevcd_cabac_decode_bypass_bins_egk()
|
|
* ihevcd_cabac_decode_trunc_rice()
|
|
* ihevcd_cabac_flush()
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*****************************************************************************/
|
|
/* File Includes */
|
|
/*****************************************************************************/
|
|
#include <stdio.h>
|
|
#include <stddef.h>
|
|
#include <assert.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "ihevc_typedefs.h"
|
|
#include "iv.h"
|
|
#include "ivd.h"
|
|
#include "ihevcd_cxa.h"
|
|
|
|
|
|
#include "ihevc_debug.h"
|
|
#include "ihevc_macros.h"
|
|
#include "ihevc_platform_macros.h"
|
|
#include "ihevc_cabac_tables.h"
|
|
#include "ihevc_defs.h"
|
|
#include "ihevc_structs.h"
|
|
#include "ihevc_cabac_tables.h"
|
|
|
|
|
|
#include "ihevcd_defs.h"
|
|
#include "ihevcd_function_selector.h"
|
|
#include "ihevcd_structs.h"
|
|
#include "ihevcd_error.h"
|
|
#include "ihevcd_bitstream.h"
|
|
#include "ihevcd_cabac.h"
|
|
#include "ihevcd_trace.h"
|
|
|
|
#ifdef TRACE
|
|
extern trace_t g_trace;
|
|
#endif
|
|
#if DEBUG_CABAC_RANGE_OFST
|
|
#if FULLRANGE
|
|
#define DEBUG_RANGE_OFST(str, m_range, m_ofst ) \
|
|
{\
|
|
UWORD32 m_clz, m_range_shift, m_ofst_shift; \
|
|
m_clz = CLZ(m_range); \
|
|
m_clz -= (32 - RANGE_NUMBITS); \
|
|
m_range_shift = m_range << m_clz; \
|
|
m_range_shift = m_range_shift >> RANGE_SHIFT; \
|
|
m_ofst_shift = m_ofst << m_clz; \
|
|
m_ofst_shift = m_ofst_shift >> RANGE_SHIFT; \
|
|
fprintf( g_trace.fp, "%-40s R: %3d O: %3d\n", str, m_range_shift, m_ofst_shift); \
|
|
}
|
|
|
|
#else
|
|
#define DEBUG_RANGE_OFST(str, m_range, m_ofst) \
|
|
fprintf( g_trace.fp, "%-40s R: %3d O: %3d\n", str, m_range, m_ofst);
|
|
#endif
|
|
#else
|
|
#define DEBUG_RANGE_OFST(str, m_range, m_ofst )
|
|
#endif
|
|
/*****************************************************************************/
|
|
/* Function Definitions */
|
|
/*****************************************************************************/
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief Initializes the decoder cabac engine
|
|
*
|
|
* @par Description
|
|
* This routine needs to be called at start of slice/frame decode
|
|
*
|
|
* @param[in,out] ps_cabac_ctxt
|
|
* pointer to cabac context (handle)
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* pointer to bitstream context (handle)
|
|
*
|
|
* @param[in] qp
|
|
* current slice Qp
|
|
*
|
|
* @param[in] cabac_init_idc
|
|
* current slice init idc (range [0 - 2])
|
|
*
|
|
* @param[in] pu1_init_ctxt
|
|
* Init cabac context to be used (range [0 - 2])
|
|
*
|
|
* @return success or failure error code
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
IHEVCD_ERROR_T ihevcd_cabac_init(cab_ctxt_t *ps_cabac,
|
|
bitstrm_t *ps_bitstrm,
|
|
WORD32 qp,
|
|
WORD32 cabac_init_idc,
|
|
const UWORD8 *pu1_init_ctxt)
|
|
{
|
|
/* Sanity checks */
|
|
ASSERT(ps_cabac != NULL);
|
|
ASSERT(ps_bitstrm != NULL);
|
|
ASSERT((qp >= 0) && (qp < 52));
|
|
ASSERT((cabac_init_idc >= 0) && (cabac_init_idc < 3));
|
|
UNUSED(qp);
|
|
UNUSED(cabac_init_idc);
|
|
/* CABAC engine uses 32 bit range instead of 9 bits as specified by
|
|
* the spec. This is done to reduce number of renormalizations
|
|
*/
|
|
/* cabac engine initialization */
|
|
#if FULLRANGE
|
|
ps_cabac->u4_range = (UWORD32)510 << RANGE_SHIFT;
|
|
BITS_GET(ps_cabac->u4_ofst, ps_bitstrm->pu4_buf, ps_bitstrm->u4_bit_ofst,
|
|
ps_bitstrm->u4_cur_word, ps_bitstrm->u4_nxt_word, (9 + RANGE_SHIFT));
|
|
|
|
#else
|
|
ps_cabac->u4_range = (UWORD32)510;
|
|
BITS_GET(ps_cabac->u4_ofst, ps_bitstrm->pu4_buf, ps_bitstrm->u4_bit_ofst,
|
|
ps_bitstrm->u4_cur_word, ps_bitstrm->u4_nxt_word, 9);
|
|
|
|
#endif
|
|
|
|
/* cabac context initialization based on init idc and slice qp */
|
|
memcpy(ps_cabac->au1_ctxt_models,
|
|
pu1_init_ctxt,
|
|
IHEVC_CAB_CTXT_END);
|
|
DEBUG_RANGE_OFST("init", ps_cabac->u4_range, ps_cabac->u4_ofst);
|
|
|
|
/*
|
|
* If the offset is greater than or equal to range, return fail.
|
|
*/
|
|
if(ps_cabac->u4_ofst >= ps_cabac->u4_range)
|
|
{
|
|
return ((IHEVCD_ERROR_T)IHEVCD_FAIL);
|
|
}
|
|
|
|
return ((IHEVCD_ERROR_T)IHEVCD_SUCCESS);
|
|
}
|
|
|
|
IHEVCD_ERROR_T ihevcd_cabac_reset(cab_ctxt_t *ps_cabac,
|
|
bitstrm_t *ps_bitstrm)
|
|
{
|
|
/* Sanity checks */
|
|
ASSERT(ps_cabac != NULL);
|
|
ASSERT(ps_bitstrm != NULL);
|
|
|
|
/* CABAC engine uses 32 bit range instead of 9 bits as specified by
|
|
* the spec. This is done to reduce number of renormalizations
|
|
*/
|
|
/* cabac engine initialization */
|
|
#if FULLRANGE
|
|
ps_cabac->u4_range = (UWORD32)510 << RANGE_SHIFT;
|
|
BITS_GET(ps_cabac->u4_ofst, ps_bitstrm->pu4_buf, ps_bitstrm->u4_bit_ofst,
|
|
ps_bitstrm->u4_cur_word, ps_bitstrm->u4_nxt_word, (9 + RANGE_SHIFT));
|
|
|
|
#else
|
|
ps_cabac->u4_range = (UWORD32)510;
|
|
BITS_GET(ps_cabac->u4_ofst, ps_bitstrm->pu4_buf, ps_bitstrm->u4_bit_ofst,
|
|
ps_bitstrm->u4_cur_word, ps_bitstrm->u4_nxt_word, 9);
|
|
|
|
#endif
|
|
|
|
return ((IHEVCD_ERROR_T)IHEVCD_SUCCESS);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief Decodes a bin based on probablilty and mps packed context model
|
|
*
|
|
* @par Description
|
|
* Decodes a bin as per Section : 9.3.3.2.1 and calls renormalization if required
|
|
* as per section 9.3.3.2.2
|
|
* 1. Apart from decoding bin, context model is updated as per state transition
|
|
* 2. Range and Low renormalization is done based on bin and original state
|
|
* 3. After renorm bistream is updated (if required)
|
|
*
|
|
* @param[in,out] ps_cabac
|
|
* pointer to cabac context (handle)
|
|
*
|
|
* @param[in] ctxt_index
|
|
* index of cabac context model containing pState[bits6-1] | MPS[bit0]
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* Bitstream context
|
|
*
|
|
* @return bin(boolean) to be decoded
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
UWORD32 ihevcd_cabac_decode_bin(cab_ctxt_t *ps_cabac,
|
|
bitstrm_t *ps_bitstrm,
|
|
WORD32 ctxt_index
|
|
|
|
)
|
|
{
|
|
UWORD32 u4_range = ps_cabac->u4_range;
|
|
UWORD32 u4_ofst = ps_cabac->u4_ofst;
|
|
UWORD32 u4_rlps;
|
|
UWORD32 u4_bin;
|
|
UWORD8 *pu1_ctxt_model = &ps_cabac->au1_ctxt_models[ctxt_index];
|
|
WORD32 state_mps = *pu1_ctxt_model;
|
|
#if FULLRANGE
|
|
WORD32 clz;
|
|
#endif
|
|
UWORD32 u4_qnt_range;
|
|
|
|
/* Sanity checks */
|
|
ASSERT(u4_range >= 256);
|
|
ASSERT((ctxt_index >= 0) && (ctxt_index < IHEVC_CAB_CTXT_END));
|
|
ASSERT(state_mps < 128);
|
|
#if FULLRANGE
|
|
clz = CLZ(u4_range);
|
|
clz -= (32 - RANGE_NUMBITS);
|
|
u4_qnt_range = u4_range << clz;
|
|
u4_qnt_range = (u4_qnt_range >> (RANGE_SHIFT + 6)) & 0x3;
|
|
#else
|
|
u4_qnt_range = (u4_range >> 6) & 0x3;
|
|
#endif
|
|
/* Get the lps range from LUT based on quantized range and state */
|
|
u4_rlps = gau1_ihevc_cabac_rlps[state_mps >> 1][u4_qnt_range];
|
|
#if FULLRANGE
|
|
u4_rlps = u4_rlps << (RANGE_SHIFT - clz);
|
|
#endif
|
|
u4_range -= u4_rlps;
|
|
|
|
u4_bin = state_mps & 1;
|
|
|
|
if(u4_ofst >= u4_range)
|
|
{
|
|
u4_bin = 1 - u4_bin;
|
|
u4_ofst -= u4_range;
|
|
u4_range = u4_rlps;
|
|
}
|
|
|
|
*pu1_ctxt_model = gau1_ihevc_next_state[(state_mps << 1) | u4_bin];
|
|
|
|
/*****************************************************************/
|
|
/* Re-normalization; calculate bits generated based on range(R) */
|
|
/*****************************************************************/
|
|
if(u4_range < (1 << 8))
|
|
{
|
|
UWORD32 u4_bits;
|
|
WORD32 numbits;
|
|
numbits = CLZ(u4_range);
|
|
numbits -= (32 - RANGE_NUMBITS);
|
|
#if !FULLRANGE
|
|
numbits -= RANGE_SHIFT;
|
|
#endif
|
|
BITS_GET(u4_bits, ps_bitstrm->pu4_buf, ps_bitstrm->u4_bit_ofst,
|
|
ps_bitstrm->u4_cur_word, ps_bitstrm->u4_nxt_word, numbits);
|
|
|
|
u4_ofst <<= numbits;
|
|
u4_ofst |= u4_bits;
|
|
u4_range <<= numbits;
|
|
|
|
}
|
|
/* Update the cabac context */
|
|
ps_cabac->u4_range = u4_range;
|
|
ps_cabac->u4_ofst = u4_ofst;
|
|
DEBUG_RANGE_OFST("bin", ps_cabac->u4_range, ps_cabac->u4_ofst);
|
|
|
|
return (u4_bin);
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief Decodes a bypass bin (equi-probable 0 / 1)
|
|
*
|
|
* @par Description
|
|
* Decodes a bypss bin as per Section : 9.3.3.2.3
|
|
*
|
|
* @param[in,out] ps_cabac
|
|
* pointer to cabac context (handle)
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* Bitstream context
|
|
*
|
|
* @return Decoded bypass bin
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
UWORD32 ihevcd_cabac_decode_bypass_bin(cab_ctxt_t *ps_cabac,
|
|
bitstrm_t *ps_bitstrm)
|
|
{
|
|
|
|
UWORD32 u4_bin;
|
|
UWORD32 u4_range = ps_cabac->u4_range;
|
|
UWORD32 u4_ofst = ps_cabac->u4_ofst;
|
|
UWORD32 u4_bits;
|
|
|
|
/* Sanity checks */
|
|
ASSERT(u4_range >= 256);
|
|
|
|
BIT_GET(u4_bits, ps_bitstrm->pu4_buf, ps_bitstrm->u4_bit_ofst,
|
|
ps_bitstrm->u4_cur_word, ps_bitstrm->u4_nxt_word);
|
|
|
|
u4_ofst <<= 1;
|
|
u4_ofst |= u4_bits;
|
|
|
|
u4_bin = 0;
|
|
if(u4_ofst >= u4_range)
|
|
{
|
|
u4_bin = 1;
|
|
u4_ofst -= u4_range;
|
|
}
|
|
|
|
/* Update the cabac context */
|
|
ps_cabac->u4_ofst = u4_ofst;
|
|
DEBUG_RANGE_OFST("bypass end", ps_cabac->u4_range, ps_cabac->u4_ofst);
|
|
return (u4_bin);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief Decodes a terminate bin (1:terminate 0:do not terminate)
|
|
*
|
|
* @par Description
|
|
* Decodes a terminate bin to be called for end_of_slice_flag and pcm_flag
|
|
* as per Section : 9.3.3.2.4
|
|
*
|
|
* @param[in,out] ps_cabac
|
|
* pointer to cabac context (handle)
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* Bitstream context
|
|
*
|
|
* @return Decoded Bin to indicate whether to terminate or not
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
UWORD32 ihevcd_cabac_decode_terminate(cab_ctxt_t *ps_cabac,
|
|
bitstrm_t *ps_bitstrm)
|
|
{
|
|
UWORD32 u4_range = ps_cabac->u4_range;
|
|
UWORD32 u4_ofst = ps_cabac->u4_ofst;
|
|
UWORD32 u4_bin;
|
|
#if FULLRANGE
|
|
WORD32 clz;
|
|
#endif
|
|
/* Sanity checks */
|
|
ASSERT(u4_range >= 256);
|
|
#if FULLRANGE
|
|
clz = CLZ(u4_range);
|
|
clz -= (32 - RANGE_NUMBITS);
|
|
u4_range -= 2 << (RANGE_SHIFT - clz);
|
|
#else
|
|
u4_range -= 2;
|
|
#endif
|
|
|
|
if(u4_ofst >= u4_range)
|
|
{
|
|
u4_bin = 1;
|
|
|
|
#if FULLRANGE
|
|
/* In case of FULLRANGE extra bits read earlier need to pushed back to the bitstream */
|
|
{
|
|
WORD32 clz;
|
|
WORD32 numbits;
|
|
clz = CLZ(ps_cabac->u4_range);
|
|
|
|
numbits = (32 - clz);
|
|
numbits -= 9;
|
|
|
|
ihevcd_bits_seek(ps_bitstrm, -numbits);
|
|
}
|
|
#endif
|
|
|
|
}
|
|
else
|
|
{
|
|
u4_bin = 0;
|
|
}
|
|
if(0 == u4_bin)
|
|
{
|
|
UWORD32 u4_bits;
|
|
WORD32 numbits;
|
|
numbits = CLZ(u4_range);
|
|
numbits -= (32 - RANGE_NUMBITS);
|
|
#if !FULLRANGE
|
|
numbits -= RANGE_SHIFT;
|
|
#endif
|
|
/* Renormalize if required */
|
|
if(numbits)
|
|
{
|
|
BITS_GET(u4_bits, ps_bitstrm->pu4_buf, ps_bitstrm->u4_bit_ofst,
|
|
ps_bitstrm->u4_cur_word, ps_bitstrm->u4_nxt_word, numbits);
|
|
|
|
u4_ofst <<= numbits;
|
|
u4_ofst |= u4_bits;
|
|
u4_range <<= numbits;
|
|
}
|
|
}
|
|
/* bits to be inserted in the bitstream */
|
|
ps_cabac->u4_range = u4_range;
|
|
ps_cabac->u4_ofst = u4_ofst;
|
|
DEBUG_RANGE_OFST("term", ps_cabac->u4_range, ps_cabac->u4_ofst);
|
|
|
|
return (u4_bin);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief Decodes a bypass bin (equi-probable 0 / 1)
|
|
*
|
|
* @par Description
|
|
* Decodes a bypss bin as per Section : 9.3.3.2.3
|
|
*
|
|
* @param[in,out] ps_cabac
|
|
* pointer to cabac context (handle)
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* Bitstream context
|
|
*
|
|
* @param[in] numbins
|
|
* Number of bins to decoded
|
|
*
|
|
* @return Decoded bypass bin
|
|
*
|
|
* @remarks Tested only for numbins less than 17
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
UWORD32 ihevcd_cabac_decode_bypass_bins(cab_ctxt_t *ps_cabac,
|
|
bitstrm_t *ps_bitstrm,
|
|
WORD32 numbins)
|
|
{
|
|
UWORD32 u4_bins;
|
|
|
|
|
|
UWORD32 u4_range = ps_cabac->u4_range;
|
|
UWORD32 u4_ofst = ps_cabac->u4_ofst;
|
|
UWORD32 u4_bits;
|
|
ASSERT(u4_range >= 256);
|
|
ASSERT(numbins > 0);
|
|
|
|
/* Sanity checks */
|
|
ASSERT(numbins < 17);
|
|
|
|
u4_bins = 0;
|
|
|
|
BITS_GET(u4_bits, ps_bitstrm->pu4_buf, ps_bitstrm->u4_bit_ofst,
|
|
ps_bitstrm->u4_cur_word, ps_bitstrm->u4_nxt_word, numbins);
|
|
|
|
do
|
|
{
|
|
UWORD32 u4_bit;
|
|
numbins--;
|
|
u4_bit = (u4_bits >> numbins) & 1;
|
|
u4_ofst <<= 1;
|
|
u4_ofst |= u4_bit;
|
|
|
|
u4_bins <<= 1;
|
|
if(u4_ofst >= u4_range)
|
|
{
|
|
u4_bins += 1;
|
|
u4_ofst -= u4_range;
|
|
}
|
|
}while(numbins);
|
|
|
|
/* Update the cabac context */
|
|
ps_cabac->u4_ofst = u4_ofst;
|
|
DEBUG_RANGE_OFST("bypass", ps_cabac->u4_range, ps_cabac->u4_ofst);
|
|
return (u4_bins);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief Decodes a truncated unary symbol associated with context model(s)
|
|
*
|
|
* @par Description
|
|
* Decodes symbols coded with TUnary binarization as per sec 9.3.2.2
|
|
* This is used for computing symbols like qp_delta,
|
|
* last_sig_coeff_prefix_x, last_sig_coeff_prefix_y.
|
|
*
|
|
* The context models associated with each bin is computed as :
|
|
* current bin context = "base context idx" + (bin_idx >> shift)
|
|
* where
|
|
* 1. "base context idx" is the base index for the syntax element
|
|
* 2. "bin_idx" is the current bin index of the unary code
|
|
* 3. "shift" is the shift factor associated with this syntax element
|
|
*
|
|
* @param[in,out] ps_cabac
|
|
* pointer to cabac context (handle)
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* Bitstream context
|
|
*
|
|
* @param[in] c_max
|
|
* maximum value of sym (required for tunary binarization)
|
|
*
|
|
* @param[in] ctxt_index
|
|
* base context model index for this syntax element
|
|
*
|
|
* @param[in] ctxt_shift
|
|
* shift factor for context increments associated with this syntax element
|
|
*
|
|
* @param[in] ctxt_inc_max
|
|
* max value of context increment beyond which all bins will use same ctxt
|
|
*
|
|
* @return syntax element decoded
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
UWORD32 ihevcd_cabac_decode_bins_tunary(cab_ctxt_t *ps_cabac,
|
|
bitstrm_t *ps_bitstrm,
|
|
WORD32 c_max,
|
|
WORD32 ctxt_index,
|
|
WORD32 ctxt_shift,
|
|
WORD32 ctxt_inc_max)
|
|
{
|
|
UWORD32 u4_sym;
|
|
WORD32 bin;
|
|
|
|
/* Sanity checks */
|
|
ASSERT(c_max > 0);
|
|
ASSERT((ctxt_index >= 0) && (ctxt_index < IHEVC_CAB_CTXT_END));
|
|
ASSERT((ctxt_index + (c_max >> ctxt_shift)) < IHEVC_CAB_CTXT_END);
|
|
|
|
u4_sym = 0;
|
|
do
|
|
{
|
|
WORD32 bin_index;
|
|
bin_index = ctxt_index + MIN((u4_sym >> ctxt_shift), (UWORD32)ctxt_inc_max);
|
|
IHEVCD_CABAC_DECODE_BIN(bin, ps_cabac, ps_bitstrm, bin_index);
|
|
u4_sym++;
|
|
}while(((WORD32)u4_sym < c_max) && bin);
|
|
|
|
u4_sym = u4_sym - 1 + bin;
|
|
|
|
return (u4_sym);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief Decodes a syntax element as truncated unary bypass bins
|
|
*
|
|
* @par Description
|
|
* Decodes symbols coded with TUnary binarization as per sec 9.3.2.2
|
|
* These symbols are coded as bypass bins
|
|
* This is used for computing symbols like merge_idx,
|
|
* mpm_idx etc
|
|
*
|
|
* @param[in,out]ps_cabac
|
|
* pointer to cabac context (handle)
|
|
*
|
|
* @param[in] ps_bitstrm
|
|
* Bitstream context
|
|
*
|
|
* @param[in] c_max
|
|
* maximum value of sym (required for tunary binarization)
|
|
*
|
|
* @return syntax element decoded
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
UWORD32 ihevcd_cabac_decode_bypass_bins_tunary(cab_ctxt_t *ps_cabac,
|
|
bitstrm_t *ps_bitstrm,
|
|
WORD32 c_max)
|
|
{
|
|
|
|
UWORD32 u4_sym;
|
|
WORD32 bin;
|
|
UWORD32 u4_ofst = ps_cabac->u4_ofst;
|
|
UWORD32 u4_range = ps_cabac->u4_range;
|
|
UWORD32 u4_bits;
|
|
/* Sanity checks */
|
|
ASSERT(c_max > 0);
|
|
ASSERT(u4_range >= 256);
|
|
u4_sym = 0;
|
|
BITS_NXT(u4_bits, ps_bitstrm->pu4_buf, ps_bitstrm->u4_bit_ofst,
|
|
ps_bitstrm->u4_cur_word, ps_bitstrm->u4_nxt_word, (UWORD32)c_max);
|
|
u4_bits <<= (32 - c_max);
|
|
do
|
|
{
|
|
u4_ofst <<= 1;
|
|
u4_ofst |= (u4_bits >> 31);
|
|
u4_bits <<= 1;
|
|
|
|
bin = 0;
|
|
if(u4_ofst >= u4_range)
|
|
{
|
|
bin = 1;
|
|
u4_ofst -= u4_range;
|
|
}
|
|
u4_sym++;
|
|
}while(((WORD32)u4_sym < c_max) && bin);
|
|
BITS_FLUSH(ps_bitstrm->pu4_buf, ps_bitstrm->u4_bit_ofst,
|
|
ps_bitstrm->u4_cur_word, ps_bitstrm->u4_nxt_word, u4_sym);
|
|
|
|
u4_sym = u4_sym - 1 + bin;
|
|
/* Update the cabac context */
|
|
ps_cabac->u4_ofst = u4_ofst;
|
|
|
|
return (u4_sym);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief Decodes a syntax element as kth order Exp-Golomb code (EGK)
|
|
*
|
|
* @par Description
|
|
* Decodes a syntax element binarized as kth order Exp-Golomb code (EGK)
|
|
* Elements are coded as bypass bins
|
|
*
|
|
* @param[in,out] ps_cabac
|
|
* pointer to cabac context (handle)
|
|
*
|
|
* @param[in] u4_sym
|
|
* syntax element to be coded as EGK
|
|
*
|
|
* @param[in] k
|
|
* order of EGk
|
|
*
|
|
* @return success or failure error code
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
UWORD32 ihevcd_cabac_decode_bypass_bins_egk(cab_ctxt_t *ps_cabac,
|
|
bitstrm_t *ps_bitstrm,
|
|
WORD32 k)
|
|
{
|
|
|
|
UWORD32 u4_sym;
|
|
WORD32 numones;
|
|
WORD32 bin;
|
|
|
|
/* Sanity checks */
|
|
ASSERT((k >= 0));
|
|
|
|
numones = k;
|
|
bin = 1;
|
|
u4_sym = 0;
|
|
while(bin && (numones <= 16))
|
|
{
|
|
IHEVCD_CABAC_DECODE_BYPASS_BIN(bin, ps_cabac, ps_bitstrm);
|
|
u4_sym += bin << numones++;
|
|
}
|
|
|
|
numones -= 1;
|
|
|
|
if(numones)
|
|
{
|
|
UWORD32 u4_suffix;
|
|
|
|
IHEVCD_CABAC_DECODE_BYPASS_BINS(u4_suffix, ps_cabac, ps_bitstrm, numones);
|
|
u4_sym += u4_suffix;
|
|
}
|
|
return (u4_sym);
|
|
}
|
|
|
|
/**
|
|
******************************************************************************
|
|
*
|
|
* @brief Decodes a syntax element as truncated rice code (TR)
|
|
*
|
|
* @par Description
|
|
* Decodes a syntax element as truncated rice code (TR)
|
|
* Elements are coded as bypass bins
|
|
* This function ise used for coeff_abs_level_remaining coding when
|
|
* level is less than c_rice_max
|
|
*
|
|
* @param[in,out] ps_cabac
|
|
* pointer to cabac context (handle)
|
|
*
|
|
* @param[in] u4_sym
|
|
* syntax element to be coded as truncated rice code
|
|
*
|
|
* @param[in] c_rice_param
|
|
* shift factor for truncated unary prefix coding of (u4_sym >> c_rice_param)
|
|
*
|
|
* @param[in] c_rice_max
|
|
* max symbol val below which a suffix is coded as (u4_sym%(1<<c_rice_param))
|
|
* This is currently (4 << c_rice_param) for coeff_abs_level_remaining
|
|
*
|
|
* @return success or failure error code
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
UWORD32 ihevcd_cabac_decode_bypass_bins_trunc_rice(cab_ctxt_t *ps_cabac,
|
|
bitstrm_t *ps_bitstrm,
|
|
WORD32 c_rice_param,
|
|
WORD32 c_rice_max)
|
|
{
|
|
UWORD32 u4_sym;
|
|
WORD32 bin;
|
|
WORD32 c_max;
|
|
UWORD32 u4_suffix;
|
|
/* Sanity checks */
|
|
ASSERT((c_rice_param >= 0));
|
|
|
|
|
|
/* Decode prefix coded as TUnary */
|
|
c_max = c_rice_max >> c_rice_param;
|
|
u4_sym = 0;
|
|
do
|
|
{
|
|
IHEVCD_CABAC_DECODE_BYPASS_BIN(bin, ps_cabac, ps_bitstrm);
|
|
u4_sym++;
|
|
|
|
}while(((WORD32)u4_sym < c_max) && bin);
|
|
u4_sym = u4_sym - 1 + bin;
|
|
|
|
/* If suffix is present, then decode c_rice_param number of bins */
|
|
if(c_rice_param)
|
|
{
|
|
IHEVCD_CABAC_DECODE_BYPASS_BINS(u4_suffix, ps_cabac, ps_bitstrm, c_rice_param);
|
|
|
|
u4_sym = (u4_sym << c_rice_param) | u4_suffix;
|
|
}
|
|
return (u4_sym);
|
|
}
|