mirror of
https://github.com/ittiam-systems/libhevc.git
synced 2026-10-18 23:06:17 +07:00
When the offset was greater than range, the bitstream was read more than the valid range in leaf-level cabac parsing modules. Error check was added to cabac init to fix this issue. Additionally end of slice and slice error were signalled to suppress further parsing of current slice. Bug: 34897036 Change-Id: I1263f1d1219684ffa6e952c76e5a08e9a933c9d2 (cherry picked from commit 3b175da88a1807d19cdd248b74bce60e57f05c6a)
759 lines
22 KiB
C
759 lines
22 KiB
C
/******************************************************************************
|
|
*
|
|
* 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);
|
|
}
|