| /****************************************************************************** |
| * |
| * 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.h |
| * |
| * @brief |
| * This file contains decoder cabac engine related structures and |
| * interface prototypes |
| * |
| * @author |
| * Ittiam |
| ****************************************************************************** |
| */ |
| |
| #ifndef _IHEVCD_CABAC_H_ |
| #define _IHEVCD_CABAC_H_ |
| |
| #include "ihevc_typedefs.h" |
| /*****************************************************************************/ |
| /* Constant Macros */ |
| /*****************************************************************************/ |
| /** |
| ******************************************************************************* |
| @brief |
| ******************************************************************************* |
| */ |
| #define CABAC_BITS 9 |
| |
| /** |
| * Following definitions control whether cabac functions are inlined as macros or |
| * are called as functions. Set these to 0 to debug cabac leaf level functions |
| * Note these macros assume FULLRANGE is 1. |
| */ |
| #define CABAC_DECODE_BIN 1 |
| #define CABAC_DECODE_BYPASS_BIN 1 |
| #define CABAC_DECODE_BYPASS_BINS 1 |
| |
| /*****************************************************************************/ |
| /* Function Macros */ |
| /*****************************************************************************/ |
| #if CABAC_DECODE_BIN |
| #define IHEVCD_CABAC_DECODE_BIN(u4_bin, ps_cabac, ps_bitstrm, ctxt_index) \ |
| { \ |
| UWORD32 u4_range = ps_cabac->u4_range; \ |
| UWORD32 u4_ofst = ps_cabac->u4_ofst; \ |
| UWORD32 u4_rlps; \ |
| UWORD8 *pu1_ctxt_model = &ps_cabac->au1_ctxt_models[ctxt_index]; \ |
| WORD32 state_mps = *pu1_ctxt_model; \ |
| WORD32 clz; \ |
| UWORD32 u4_qnt_range; \ |
| \ |
| /* Sanity checks */ \ |
| ASSERT(FULLRANGE == 1); \ |
| ASSERT(u4_range >= 256); \ |
| ASSERT((ctxt_index >= 0) && (ctxt_index < IHEVC_CAB_CTXT_END)); \ |
| ASSERT(state_mps < 128); \ |
| clz = CLZ(u4_range); \ |
| clz -= (32 - RANGE_NUMBITS); \ |
| u4_qnt_range = u4_range << clz; \ |
| u4_qnt_range = (u4_qnt_range >> (RANGE_SHIFT + 6)) & 0x3; \ |
| /* Get the lps range from LUT based on quantized range and state */ \ |
| u4_rlps = gau1_ihevc_cabac_rlps[state_mps >> 1][u4_qnt_range]; \ |
| u4_rlps = u4_rlps << (RANGE_SHIFT - clz); \ |
| 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); \ |
| 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; \ |
| \ |
| } |
| #else |
| #define IHEVCD_CABAC_DECODE_BIN(u4_bin, ps_cabac, ps_bitstrm, ctxt_index) \ |
| u4_bin = ihevcd_cabac_decode_bin(ps_cabac, ps_bitstrm, ctxt_index); |
| #endif |
| |
| #if CABAC_DECODE_BYPASS_BIN |
| #define IHEVCD_CABAC_DECODE_BYPASS_BIN(u4_bin, ps_cabac, ps_bitstrm) \ |
| { \ |
| \ |
| UWORD32 u4_range = ps_cabac->u4_range; \ |
| UWORD32 u4_ofst = ps_cabac->u4_ofst; \ |
| UWORD32 u4_bits; \ |
| \ |
| /* Sanity checks */ \ |
| ASSERT(FULLRANGE == 1); \ |
| 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; \ |
| } |
| #else |
| |
| #define IHEVCD_CABAC_DECODE_BYPASS_BIN(u4_bin, ps_cabac, ps_bitstrm) \ |
| u4_bin = ihevcd_cabac_decode_bypass_bin(ps_cabac, ps_bitstrm); |
| #endif |
| |
| #if CABAC_DECODE_BYPASS_BINS |
| #define IHEVCD_CABAC_DECODE_BYPASS_BINS(u4_bins, ps_cabac, ps_bitstrm, numbins) \ |
| { \ |
| UWORD32 u4_range = ps_cabac->u4_range; \ |
| UWORD32 u4_ofst = ps_cabac->u4_ofst; \ |
| UWORD32 u4_bits; \ |
| ASSERT(FULLRANGE == 1); \ |
| ASSERT(u4_range >= 256); \ |
| ASSERT(numbins > 0); \ |
| { \ |
| WORD32 numbins_tmp = numbins; \ |
| /* 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_tmp--; \ |
| u4_bit = (u4_bits >> numbins_tmp) & 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_tmp); \ |
| \ |
| /* Update the cabac context */ \ |
| ps_cabac->u4_ofst = u4_ofst; \ |
| } \ |
| } |
| |
| |
| #else |
| |
| #define IHEVCD_CABAC_DECODE_BYPASS_BINS(u4_bins, ps_cabac, ps_bitstrm, numbins) \ |
| u4_bins = ihevcd_cabac_decode_bypass_bins(ps_cabac, ps_bitstrm, numbins); |
| |
| #endif |
| /*****************************************************************************/ |
| /* Structures */ |
| /*****************************************************************************/ |
| |
| |
| |
| /*****************************************************************************/ |
| /* Extern Function Declarations */ |
| /*****************************************************************************/ |
| IHEVCD_ERROR_T ihevcd_cabac_init |
| ( |
| cab_ctxt_t *ps_cabac, |
| bitstrm_t *ps_bitstrm, |
| WORD32 slice_qp, |
| WORD32 cabac_init_idc, |
| const UWORD8 *pu1_init_ctxt |
| ); |
| |
| |
| |
| UWORD32 ihevcd_cabac_decode_bin |
| ( |
| cab_ctxt_t *ps_cabac, |
| bitstrm_t *ps_bitstrm, |
| WORD32 ctxt_index |
| ); |
| |
| UWORD32 ihevcd_cabac_decode_bypass_bin |
| ( |
| cab_ctxt_t *ps_cabac, |
| bitstrm_t *ps_bitstrm |
| ); |
| |
| UWORD32 ihevcd_cabac_decode_terminate |
| ( |
| cab_ctxt_t *ps_cabac, |
| bitstrm_t *ps_bitstrm |
| ); |
| |
| UWORD32 ihevcd_cabac_decode_bypass_bins |
| ( |
| cab_ctxt_t *ps_cabac, |
| bitstrm_t *ps_bitstrm, |
| WORD32 num_bins |
| ); |
| |
| 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 ihevcd_cabac_decode_bypass_bins_tunary |
| ( |
| cab_ctxt_t *ps_cabac, |
| bitstrm_t *ps_bitstrm, |
| WORD32 c_max |
| |
| ); |
| |
| UWORD32 ihevcd_cabac_decode_bypass_bins_egk |
| ( |
| cab_ctxt_t *ps_cabac, |
| bitstrm_t *ps_bitstrm, |
| WORD32 k |
| ); |
| |
| 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 |
| ); |
| |
| IHEVCD_ERROR_T ihevcd_cabac_flush(cab_ctxt_t *ps_cabac); |
| |
| IHEVCD_ERROR_T ihevcd_cabac_reset(cab_ctxt_t *ps_cabac, |
| bitstrm_t *ps_bitstrm); |
| |
| #endif /* _IHEVCD_CABAC_H_ */ |