/* The copyright in this software is being made available under the BSD * License, included below. This software may be subject to other third party * and contributor rights, including patent rights, and no such rights are * granted under this license. * * Copyright (c) 2010-2011, ISO/IEC * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the ISO/IEC nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ /** \file TEncSbac.cpp \brief SBAC encoder class */ #include "TEncTop.h" #include "TEncSbac.h" #include extern UChar stateMappingTable[113]; extern Int entropyBits[128]; // ==================================================================================================================== // Constructor / destructor / create / destroy // ==================================================================================================================== TEncSbac::TEncSbac() // new structure here : m_pcBitIf ( NULL ) , m_pcSlice ( NULL ) , m_pcBinIf ( NULL ) , m_bAlfCtrl ( false ) , m_uiCoeffCost ( 0 ) , m_uiMaxAlfCtrlDepth ( 0 ) , m_cCUSplitFlagSCModel ( 1, 1, NUM_SPLIT_FLAG_CTX ) , m_cCUSkipFlagSCModel ( 1, 1, NUM_SKIP_FLAG_CTX ) , m_cCUMergeFlagExtSCModel ( 1, 1, NUM_MERGE_FLAG_EXT_CTX ) , m_cCUMergeIdxExtSCModel ( 1, 1, NUM_MERGE_IDX_EXT_CTX ) , m_cCUMVMergeIdxExtSCModel ( 1, 1, NUM_MV_MERGE_IDX_EXT_CTX ) , m_cResPredFlagSCModel ( 1, 1, NUM_RES_PRED_FLAG_CTX ) , m_cCUPartSizeSCModel ( 1, 1, NUM_PART_SIZE_CTX ) , m_cCUPredModeSCModel ( 1, 1, NUM_PRED_MODE_CTX ) , m_cCUAlfCtrlFlagSCModel ( 1, 1, NUM_ALF_CTRL_FLAG_CTX ) , m_cCUIntraPredSCModel ( 1, 1, NUM_ADI_CTX ) #if ADD_PLANAR_MODE , m_cPlanarFlagSCModel ( 1, 1, NUM_PLANARFLAG_CTX ) #endif , m_cCUChromaPredSCModel ( 1, 1, NUM_CHROMA_PRED_CTX ) , m_cCUDeltaQpSCModel ( 1, 1, NUM_DELTA_QP_CTX ) , m_cCUInterDirSCModel ( 1, 1, NUM_INTER_DIR_CTX ) , m_cCURefPicSCModel ( 1, 1, NUM_REF_NO_CTX ) , m_cCUMvdSCModel ( 1, 2, NUM_MV_RES_CTX ) , m_cCUQtCbfSCModel ( 1, 3, NUM_QT_CBF_CTX ) , m_cCUTransSubdivFlagSCModel ( 1, 1, NUM_TRANS_SUBDIV_FLAG_CTX ) , m_cCUQtRootCbfSCModel ( 1, 1, NUM_QT_ROOT_CBF_CTX ) #if SIMPLE_CONTEXT_SIG , m_cCUSigSCModel ( 4, 2, NUM_SIG_FLAG_CTX ) #else , m_cCUSigSCModel ( MAX_CU_DEPTH, 2, NUM_SIG_FLAG_CTX ) #endif #if PCP_SIGMAP_SIMPLE_LAST , m_cCuCtxLastX ( 1, 2, NUM_CTX_LAST_FLAG_XY ) , m_cCuCtxLastY ( 1, 2, NUM_CTX_LAST_FLAG_XY ) #else , m_cCULastSCModel ( MAX_CU_DEPTH, 2, NUM_LAST_FLAG_CTX ) #endif , m_cCUOneSCModel ( 1, 2, NUM_ONE_FLAG_CTX ) , m_cCUAbsSCModel ( 1, 2, NUM_ABS_FLAG_CTX ) , m_cMVPIdxSCModel ( 1, 1, NUM_MVP_IDX_CTX ) , m_cALFFlagSCModel ( 1, 1, NUM_ALF_FLAG_CTX ) , m_cALFUvlcSCModel ( 1, 1, NUM_ALF_UVLC_CTX ) , m_cALFSvlcSCModel ( 1, 1, NUM_ALF_SVLC_CTX ) #if MTK_SAO , m_cAOFlagSCModel ( 1, 1, NUM_AO_FLAG_CTX ) , m_cAOUvlcSCModel ( 1, 1, NUM_AO_UVLC_CTX ) , m_cAOSvlcSCModel ( 1, 1, NUM_AO_SVLC_CTX ) #endif , m_cViewIdxSCModel ( 1, 1, NUM_VIEW_IDX_CTX ) #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX , m_cIntraDMMSCModel ( 1, 1, NUM_DMM_CTX ) , m_cIntraWedgeSCModel ( 1, 1, NUM_WEDGE_CTX ) #endif { } TEncSbac::~TEncSbac() { } // ==================================================================================================================== // Public member functions // ==================================================================================================================== Void TEncSbac::resetEntropy () { Int iQp = m_pcSlice->getSliceQp(); SliceType eSliceType = m_pcSlice->getSliceType(); m_cCUSplitFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_SPLIT_FLAG ); m_cCUSkipFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_SKIP_FLAG ); m_cCUAlfCtrlFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_ALF_CTRL_FLAG ); m_cCUMergeFlagExtSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_MERGE_FLAG_EXT); m_cCUMergeIdxExtSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_MERGE_IDX_EXT); m_cCUMVMergeIdxExtSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_MV_MERGE_IDX_EXT ); m_cResPredFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_RES_PRED_FLAG ); m_cCUPartSizeSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_PART_SIZE ); m_cCUPredModeSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_PRED_MODE ); m_cCUIntraPredSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_INTRA_PRED_MODE ); #if ADD_PLANAR_MODE m_cPlanarFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_PLANARFLAG ); #endif m_cCUChromaPredSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_CHROMA_PRED_MODE ); m_cCUInterDirSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_INTER_DIR ); m_cCUMvdSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_MVD ); m_cCURefPicSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_REF_PIC ); m_cCUDeltaQpSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_DQP ); m_cCUQtCbfSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_QT_CBF ); m_cCUQtRootCbfSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_QT_ROOT_CBF ); m_cCUSigSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_SIG_FLAG ); #if PCP_SIGMAP_SIMPLE_LAST m_cCuCtxLastX.initBuffer ( eSliceType, iQp, (Short*)INIT_LAST_X ); m_cCuCtxLastY.initBuffer ( eSliceType, iQp, (Short*)INIT_LAST_Y ); #else m_cCULastSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_LAST_FLAG ); #endif m_cCUOneSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_ONE_FLAG ); m_cCUAbsSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_ABS_FLAG ); m_cMVPIdxSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_MVP_IDX ); m_cALFFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_ALF_FLAG ); m_cALFUvlcSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_ALF_UVLC ); m_cALFSvlcSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_ALF_SVLC ); m_cCUTransSubdivFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_TRANS_SUBDIV_FLAG ); #if MTK_SAO m_cAOFlagSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_AO_FLAG ); m_cAOUvlcSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_AO_UVLC ); m_cAOSvlcSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_AO_SVLC ); #endif m_cViewIdxSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_VIEW_IDX ); #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX m_cIntraDMMSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_INTRA_DMM ); m_cIntraWedgeSCModel.initBuffer ( eSliceType, iQp, (Short*)INIT_INTRA_WEDGELET ); #endif // new structure m_uiLastQp = iQp; m_pcBinIf->start(); return; } #if BITSTREAM_EXTRACTION Void TEncSbac::codeNALUnitHeader( NalUnitType eNalUnitType, NalRefIdc eNalRefIdc, UInt TemporalId, UInt uiLayerId ) #else Void TEncSbac::codeNALUnitHeader( NalUnitType eNalUnitType, NalRefIdc eNalRefIdc, UInt TemporalId, Bool bOutputFlag ) #endif { assert (0); return; } void TEncSbac::codeSEI(const SEI&) { assert(0); } Void TEncSbac::codeSPS( TComSPS* pcSPS ) { assert (0); return; } Void TEncSbac::codePPS( TComPPS* pcPPS ) { assert (0); return; } Void TEncSbac::codeSliceHeader( TComSlice* pcSlice ) { assert (0); return; } Void TEncSbac::codeTerminatingBit( UInt uilsLast ) { m_pcBinIf->encodeBinTrm( uilsLast ); } Void TEncSbac::codeSliceFinish() { m_pcBinIf->finish(); } Void TEncSbac::xWriteUnarySymbol( UInt uiSymbol, ContextModel* pcSCModel, Int iOffset ) { m_pcBinIf->encodeBin( uiSymbol ? 1 : 0, pcSCModel[0] ); if( 0 == uiSymbol) { return; } while( uiSymbol-- ) { m_pcBinIf->encodeBin( uiSymbol ? 1 : 0, pcSCModel[ iOffset ] ); } return; } Void TEncSbac::xWriteUnaryMaxSymbol( UInt uiSymbol, ContextModel* pcSCModel, Int iOffset, UInt uiMaxSymbol ) { if (uiMaxSymbol == 0) { return; } m_pcBinIf->encodeBin( uiSymbol ? 1 : 0, pcSCModel[ 0 ] ); if ( uiSymbol == 0 ) { return; } Bool bCodeLast = ( uiMaxSymbol > uiSymbol ); while( --uiSymbol ) { m_pcBinIf->encodeBin( 1, pcSCModel[ iOffset ] ); } if( bCodeLast ) { m_pcBinIf->encodeBin( 0, pcSCModel[ iOffset ] ); } return; } Void TEncSbac::xWriteEpExGolomb( UInt uiSymbol, UInt uiCount ) { while( uiSymbol >= (UInt)(1<encodeBinEP( 1 ); uiSymbol -= 1<encodeBinEP( 0 ); while( uiCount-- ) { m_pcBinIf->encodeBinEP( (uiSymbol>>uiCount) & 1 ); } return; } #if E253 /** Coding of coeff_abs_level_minus3 * \param uiSymbol value of coeff_abs_level_minus3 * \param ruiGoRiceParam reference to Rice parameter * \returns Void */ Void TEncSbac::xWriteGoRiceExGolomb( UInt uiSymbol, UInt &ruiGoRiceParam ) { UInt uiCount = 0; UInt uiMaxVlc = g_auiGoRiceRange[ ruiGoRiceParam ]; Bool bExGolomb = ( uiSymbol > uiMaxVlc ); UInt uiCodeWord = min( uiSymbol, ( uiMaxVlc + 1 ) ); UInt uiQuotient = uiCodeWord >> ruiGoRiceParam; UInt uiUnaryPart = uiQuotient; UInt uiRemainder = 1; UInt uiMaxPreLen = g_auiGoRicePrefixLen[ ruiGoRiceParam ]; if( uiUnaryPart ) { m_pcBinIf->encodeBinEP( 1 ); uiCount++; while( --uiUnaryPart && uiCount < uiMaxPreLen ) { m_pcBinIf->encodeBinEP( 1 ); uiCount++; } if( uiCount < uiMaxPreLen ) { m_pcBinIf->encodeBinEP( uiUnaryPart ? 1 : 0 ); } } else { m_pcBinIf->encodeBinEP( 0 ); } for( UInt ui = 0; ui < ruiGoRiceParam; ui++ ) { m_pcBinIf->encodeBinEP( ( uiRemainder & uiCodeWord ) ? 1 : 0 ); uiRemainder = uiRemainder << 1; } ruiGoRiceParam = g_aauiGoRiceUpdate[ ruiGoRiceParam ][ min( uiSymbol, 15 ) ]; if( bExGolomb ) { uiSymbol -= uiMaxVlc + 1; xWriteEpExGolomb( uiSymbol, 0 ); } return; } #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX Void TEncSbac::xWriteExGolombLevel( UInt uiSymbol, ContextModel& rcSCModel ) { if( uiSymbol ) { m_pcBinIf->encodeBin( 1, rcSCModel ); UInt uiCount = 0; Bool bNoExGo = (uiSymbol < 13); while( --uiSymbol && ++uiCount < 13 ) { m_pcBinIf->encodeBin( 1, rcSCModel ); } if( bNoExGo ) { m_pcBinIf->encodeBin( 0, rcSCModel ); } else { xWriteEpExGolomb( uiSymbol, 0 ); } } else { m_pcBinIf->encodeBin( 0, rcSCModel ); } return; } #endif #else Void TEncSbac::xWriteExGolombLevel( UInt uiSymbol, ContextModel& rcSCModel ) { if( uiSymbol ) { m_pcBinIf->encodeBin( 1, rcSCModel ); UInt uiCount = 0; Bool bNoExGo = (uiSymbol < 13); while( --uiSymbol && ++uiCount < 13 ) { m_pcBinIf->encodeBin( 1, rcSCModel ); } if( bNoExGo ) { m_pcBinIf->encodeBin( 0, rcSCModel ); } else { xWriteEpExGolomb( uiSymbol, 0 ); } } else { m_pcBinIf->encodeBin( 0, rcSCModel ); } return; } #endif // SBAC RD Void TEncSbac::load ( TEncSbac* pScr) { this->xCopyFrom(pScr); } Void TEncSbac::store( TEncSbac* pDest) { pDest->xCopyFrom( this ); } Void TEncSbac::xCopyFrom( TEncSbac* pSrc ) { m_pcBinIf->copyState( pSrc->m_pcBinIf ); this->m_uiCoeffCost = pSrc->m_uiCoeffCost; this->m_uiLastQp = pSrc->m_uiLastQp; this->m_cCUSplitFlagSCModel .copyFrom( &pSrc->m_cCUSplitFlagSCModel ); this->m_cCUSkipFlagSCModel .copyFrom( &pSrc->m_cCUSkipFlagSCModel ); this->m_cCUMergeFlagExtSCModel .copyFrom( &pSrc->m_cCUMergeFlagExtSCModel); this->m_cCUMergeIdxExtSCModel .copyFrom( &pSrc->m_cCUMergeIdxExtSCModel); this->m_cCUMVMergeIdxExtSCModel .copyFrom( &pSrc->m_cCUMVMergeIdxExtSCModel ); this->m_cResPredFlagSCModel .copyFrom( &pSrc->m_cResPredFlagSCModel ); this->m_cCUPartSizeSCModel .copyFrom( &pSrc->m_cCUPartSizeSCModel ); this->m_cCUPredModeSCModel .copyFrom( &pSrc->m_cCUPredModeSCModel ); this->m_cCUIntraPredSCModel .copyFrom( &pSrc->m_cCUIntraPredSCModel ); #if ADD_PLANAR_MODE this->m_cPlanarFlagSCModel .copyFrom( &pSrc->m_cPlanarFlagSCModel ); #endif this->m_cCUChromaPredSCModel .copyFrom( &pSrc->m_cCUChromaPredSCModel ); this->m_cCUDeltaQpSCModel .copyFrom( &pSrc->m_cCUDeltaQpSCModel ); this->m_cCUInterDirSCModel .copyFrom( &pSrc->m_cCUInterDirSCModel ); this->m_cCURefPicSCModel .copyFrom( &pSrc->m_cCURefPicSCModel ); this->m_cCUMvdSCModel .copyFrom( &pSrc->m_cCUMvdSCModel ); this->m_cCUQtCbfSCModel .copyFrom( &pSrc->m_cCUQtCbfSCModel ); this->m_cCUTransSubdivFlagSCModel.copyFrom( &pSrc->m_cCUTransSubdivFlagSCModel ); this->m_cCUQtRootCbfSCModel .copyFrom( &pSrc->m_cCUQtRootCbfSCModel ); this->m_cCUSigSCModel .copyFrom( &pSrc->m_cCUSigSCModel ); #if PCP_SIGMAP_SIMPLE_LAST this->m_cCuCtxLastX .copyFrom( &pSrc->m_cCuCtxLastX ); this->m_cCuCtxLastY .copyFrom( &pSrc->m_cCuCtxLastY ); #else this->m_cCULastSCModel .copyFrom( &pSrc->m_cCULastSCModel ); #endif this->m_cCUOneSCModel .copyFrom( &pSrc->m_cCUOneSCModel ); this->m_cCUAbsSCModel .copyFrom( &pSrc->m_cCUAbsSCModel ); this->m_cMVPIdxSCModel .copyFrom( &pSrc->m_cMVPIdxSCModel ); this->m_cViewIdxSCModel .copyFrom( &pSrc->m_cViewIdxSCModel ); #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX this->m_cIntraDMMSCModel .copyFrom( &pSrc->m_cIntraDMMSCModel ); this->m_cIntraWedgeSCModel .copyFrom( &pSrc->m_cIntraWedgeSCModel ); #endif } Void TEncSbac::codeMVPIdx ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList ) { Int iSymbol = pcCU->getMVPIdx(eRefList, uiAbsPartIdx); Int iNum = pcCU->getMVPNum(eRefList, uiAbsPartIdx); xWriteUnaryMaxSymbol(iSymbol, m_cMVPIdxSCModel.get(0), 1, iNum-1); } Void TEncSbac::codePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { PartSize eSize = pcCU->getPartitionSize( uiAbsPartIdx ); if ( pcCU->getSlice()->isInterB() && pcCU->isIntra( uiAbsPartIdx ) ) { m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 0) ); #if HHI_RMP_SWITCH if( pcCU->getSlice()->getSPS()->getUseRMP() ) #endif { m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 1) ); m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 2) ); } #if HHI_DISABLE_INTER_NxN_SPLIT if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth ) #endif { m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 3) ); } #if MTK_DISABLE_INTRA_NxN_SPLIT if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth ) #endif { m_pcBinIf->encodeBin( (eSize == SIZE_2Nx2N? 0 : 1), m_cCUPartSizeSCModel.get( 0, 0, 4) ); } return; } if ( pcCU->isIntra( uiAbsPartIdx ) ) { #if MTK_DISABLE_INTRA_NxN_SPLIT if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth ) #endif { m_pcBinIf->encodeBin( eSize == SIZE_2Nx2N? 1 : 0, m_cCUPartSizeSCModel.get( 0, 0, 0 ) ); } return; } switch(eSize) { case SIZE_2Nx2N: { m_pcBinIf->encodeBin( 1, m_cCUPartSizeSCModel.get( 0, 0, 0) ); break; } case SIZE_2NxN: { m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 0) ); m_pcBinIf->encodeBin( 1, m_cCUPartSizeSCModel.get( 0, 0, 1) ); break; } case SIZE_Nx2N: { m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 0) ); m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 1) ); m_pcBinIf->encodeBin( 1, m_cCUPartSizeSCModel.get( 0, 0, 2) ); break; } case SIZE_NxN: { #if HHI_DISABLE_INTER_NxN_SPLIT if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth ) #endif { m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 0) ); #if HHI_RMP_SWITCH if( pcCU->getSlice()->getSPS()->getUseRMP() ) #endif { m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 1) ); m_pcBinIf->encodeBin( 0, m_cCUPartSizeSCModel.get( 0, 0, 2) ); } if (pcCU->getSlice()->isInterB()) { m_pcBinIf->encodeBin( 1, m_cCUPartSizeSCModel.get( 0, 0, 3) ); } } break; } default: { assert(0); } } } /** code prediction mode * \param pcCU * \param uiAbsPartIdx * \returns Void */ Void TEncSbac::codePredMode( TComDataCU* pcCU, UInt uiAbsPartIdx ) { // get context function is here Int iPredMode = pcCU->getPredictionMode( uiAbsPartIdx ); if (pcCU->getSlice()->isInterB() ) { return; } m_pcBinIf->encodeBin( iPredMode == MODE_INTER ? 0 : 1, m_cCUPredModeSCModel.get( 0, 0, 1 ) ); } Void TEncSbac::codeAlfCtrlFlag( TComDataCU* pcCU, UInt uiAbsPartIdx ) { if (!m_bAlfCtrl) return; if( pcCU->getDepth(uiAbsPartIdx) > m_uiMaxAlfCtrlDepth && !pcCU->isFirstAbsZorderIdxInDepth(uiAbsPartIdx, m_uiMaxAlfCtrlDepth)) { return; } // get context function is here UInt uiSymbol = pcCU->getAlfCtrlFlag( uiAbsPartIdx ) ? 1 : 0; m_pcBinIf->encodeBin( uiSymbol, m_cCUAlfCtrlFlagSCModel.get( 0, 0, pcCU->getCtxAlfCtrlFlag( uiAbsPartIdx) ) ); } Void TEncSbac::codeAlfCtrlDepth() { if (!m_bAlfCtrl) return; UInt uiDepth = m_uiMaxAlfCtrlDepth; xWriteUnaryMaxSymbol(uiDepth, m_cALFUvlcSCModel.get(0), 1, g_uiMaxCUDepth-1); } /** code skip flag * \param pcCU * \param uiAbsPartIdx * \returns Void */ Void TEncSbac::codeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx ) { // get context function is here UInt uiSymbol = pcCU->isSkipped( uiAbsPartIdx ) ? 1 : 0; UInt uiCtxSkip = pcCU->getCtxSkipFlag( uiAbsPartIdx ) ; m_pcBinIf->encodeBin( uiSymbol, m_cCUSkipFlagSCModel.get( 0, 0, uiCtxSkip ) ); DTRACE_CABAC_V( g_nSymbolCounter++ ); DTRACE_CABAC_T( "\tSkipFlag" ); DTRACE_CABAC_T( "\tuiCtxSkip: "); DTRACE_CABAC_V( uiCtxSkip ); DTRACE_CABAC_T( "\tuiSymbol: "); DTRACE_CABAC_V( uiSymbol ); DTRACE_CABAC_T( "\n"); } /** code merge flag * \param pcCU * \param uiAbsPartIdx * \returns Void */ Void TEncSbac::codeMergeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx ) { UInt uiCtx = 0; #if CHANGE_MERGE_CONTEXT uiCtx = pcCU->getCtxMergeFlag( uiAbsPartIdx ); #else for(UInt uiIter = 0; uiIter < MRG_MAX_NUM_CANDS; uiIter++ ) { if( pcCU->getNeighbourCandIdx( uiIter, uiAbsPartIdx ) == uiIter + 1 ) { if( uiIter == 0 ) { uiCtx++; } else if( uiIter == 1 ) { uiCtx++; } } } #endif UInt uiSymbol = pcCU->getMergeFlag( uiAbsPartIdx ) ? 1 : 0; m_pcBinIf->encodeBin( uiSymbol, m_cCUMergeFlagExtSCModel.get( 0, 0, uiCtx ) ); DTRACE_CABAC_V( g_nSymbolCounter++ ); DTRACE_CABAC_T( "\tMergeFlag: " ); DTRACE_CABAC_V( uiSymbol ); DTRACE_CABAC_T( "\tAddress: " ); DTRACE_CABAC_V( pcCU->getAddr() ); DTRACE_CABAC_T( "\tuiAbsPartIdx: " ); DTRACE_CABAC_V( uiAbsPartIdx ); for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ ) { DTRACE_CABAC_T( "\tNumMrgCand: " ); DTRACE_CABAC_V( ui ); DTRACE_CABAC_T( "\t==\t" ); DTRACE_CABAC_V( UInt( pcCU->getNeighbourCandIdx( ui, uiAbsPartIdx ) ) ); } DTRACE_CABAC_T( "\n" ); } #if HHI_INTER_VIEW_MOTION_PRED || HHI_MPI Void TEncSbac::codeMergeIndexMV( TComDataCU* pcCU, UInt uiAbsPartIdx ) { //--- set number of candidates and availability --- Bool abAvailable[ MRG_MAX_NUM_CANDS ]; UInt uiNumCand = 0; #if HHI_MPI const Bool bMVIAvailable = pcCU->getSlice()->getSPS()->getUseMVI() && pcCU->getSlice()->getSliceType() != I_SLICE; const UInt uiMviMergePos = bMVIAvailable ? HHI_MPI_MERGE_POS : MRG_MAX_NUM_CANDS; #endif for( UInt uiIdx = 0; uiIdx < MRG_MAX_NUM_CANDS; uiIdx++ ) { #if HHI_MPI if( uiIdx == uiMviMergePos ) { abAvailable[ uiIdx ] = true; uiNumCand++; } else if( uiIdx > uiMviMergePos ) { if( ( abAvailable[ uiIdx ] = ( pcCU->getNeighbourCandIdx( uiIdx - 1, uiAbsPartIdx ) == uiIdx ) ) ) { uiNumCand++; } } else #endif if( ( abAvailable[ uiIdx ] = ( pcCU->getNeighbourCandIdx( uiIdx, uiAbsPartIdx ) == uiIdx + 1 ) ) ) { uiNumCand++; } } AOF( uiNumCand > 1 ); //--- determine contexts --- AOF( NUM_MV_MERGE_IDX_EXT_CTX >= MRG_MAX_NUM_CANDS - 1 ); UInt auiCtx[ MRG_MAX_NUM_CANDS - 1 ]; for( UInt uiIdx = 0; uiIdx < MRG_MAX_NUM_CANDS - 1; uiIdx++ ) { auiCtx[ uiIdx ] = MRG_MAX_NUM_CANDS; if( uiNumCand > uiIdx + 1 ) { Bool bAvComb = false; for( UInt uiCId = uiIdx; uiCId < MRG_MAX_NUM_CANDS - 1; uiCId++ ) { bAvComb = ( bAvComb || abAvailable[ uiCId ] ); if( abAvailable[ uiCId + 1 ] && bAvComb ) { auiCtx[ uiIdx ] = uiCId; break; } } AOT( auiCtx[ uiIdx ] == MRG_MAX_NUM_CANDS ); } } //--- determine unary index --- UInt uiMergeIdx = pcCU->getMergeIndex( uiAbsPartIdx ); #if HHI_MPI if( bMVIAvailable ) { const Bool bUseMVI = pcCU->getTextureModeDepth( uiAbsPartIdx ) != -1; if( bUseMVI ) { uiMergeIdx = HHI_MPI_MERGE_POS; } else if( uiMergeIdx >= HHI_MPI_MERGE_POS ) { uiMergeIdx++; } } #endif UInt uiUnaryIdx = uiMergeIdx; for( UInt uiIdx = 0; uiIdx < uiMergeIdx; uiIdx++ ) { if( ! abAvailable[ uiIdx ] ) { uiUnaryIdx--; } } //--- code unary index --- for( UInt ui = 0; ui < uiNumCand - 1; ui++ ) { const UInt uiSymbol = ( ui == uiUnaryIdx ? 0 : 1 ); m_pcBinIf->encodeBin( uiSymbol, m_cCUMVMergeIdxExtSCModel.get( 0, 0, auiCtx[ui] ) ); if( uiSymbol == 0 ) { break; } } //--- trace --- DTRACE_CABAC_V( g_nSymbolCounter++ ); DTRACE_CABAC_T( "\tparseMergeIndex():" ); DTRACE_CABAC_T( " MRGIdx = " ); DTRACE_CABAC_V( uiMergeIdx ); DTRACE_CABAC_T( " UnaryIdx = " ); DTRACE_CABAC_V( uiUnaryIdx ); DTRACE_CABAC_T( " NumCand = " ); DTRACE_CABAC_V( uiNumCand ); DTRACE_CABAC_T( " Availibility = " ); for( UInt uiIdx = 0; uiIdx < MRG_MAX_NUM_CANDS; uiIdx++ ) { DTRACE_CABAC_V( abAvailable[ uiIdx ] ? 1 : 0 ); } DTRACE_CABAC_T( " Contexts = " ); for( UInt uiIdx = 0; uiIdx < MRG_MAX_NUM_CANDS - 1; uiIdx++ ) { DTRACE_CABAC_V( auiCtx[ uiIdx ] ); } DTRACE_CABAC_T( "\n" ); } #endif /** code merge index * \param pcCU * \param uiAbsPartIdx * \returns Void */ Void TEncSbac::codeMergeIndex( TComDataCU* pcCU, UInt uiAbsPartIdx ) { #if HHI_INTER_VIEW_MOTION_PRED || HHI_MPI #if HHI_INTER_VIEW_MOTION_PRED && HHI_MPI if( ( pcCU->getSlice()->getSPS()->getViewId() > 0 && ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() & PDM_USE_FOR_MERGE ) == PDM_USE_FOR_MERGE ) || ( pcCU->getSlice()->getSPS()->getUseMVI() && pcCU->getSlice()->getSliceType() != I_SLICE && pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N ) ) #elif HHI_MPI if( pcCU->getSlice()->getSPS()->getUseMVI() && pcCU->getSlice()->getSliceType() != I_SLICE && pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N ) #else if( pcCU->getSlice()->getSPS()->getViewId() > 0 && ( pcCU->getSlice()->getSPS()->getMultiviewMvPredMode() & PDM_USE_FOR_MERGE ) == PDM_USE_FOR_MERGE ) #endif { codeMergeIndexMV( pcCU, uiAbsPartIdx ); return; } #endif Bool bLeftInvolved = false; Bool bAboveInvolved = false; Bool bCollocatedInvolved = false; Bool bCornerInvolved = false; Bool bCornerBLInvolved = false; UInt uiNumCand = 0; for( UInt uiIter = 0; uiIter < MRG_MAX_NUM_CANDS; ++uiIter ) { if( pcCU->getNeighbourCandIdx( uiIter, uiAbsPartIdx ) == uiIter + 1 ) { uiNumCand++; if( uiIter == 0 ) { bLeftInvolved = true; } else if( uiIter == 1 ) { bAboveInvolved = true; } else if( uiIter == 2 ) { bCollocatedInvolved = true; } else if( uiIter == 3 ) { bCornerInvolved = true; } else if( uiIter == 4 ) { bCornerBLInvolved = true; } } } assert( uiNumCand > 1 ); UInt auiCtx[4] = { 0, 0, 0, 3 }; if( bLeftInvolved && bAboveInvolved ) { auiCtx[0] = 0; } else if( bLeftInvolved || bAboveInvolved ) { auiCtx[0] = bCollocatedInvolved ? 1 : 2; } else { auiCtx[0] = bCollocatedInvolved ? 2 : 3; } if( uiNumCand >= 3 ) { if( bAboveInvolved ) { auiCtx[1] = bCollocatedInvolved ? 1 : 2; } else { auiCtx[1] = bCollocatedInvolved ? 2 : 3; } } if( uiNumCand >= 4 ) { auiCtx[2] = bCollocatedInvolved ? 2 : 3; } UInt uiUnaryIdx = pcCU->getMergeIndex( uiAbsPartIdx ); if( !bCornerInvolved && uiUnaryIdx > 3 ) { --uiUnaryIdx; } if( !bCollocatedInvolved && uiUnaryIdx > 2 ) { --uiUnaryIdx; } if( !bAboveInvolved && uiUnaryIdx > 1 ) { --uiUnaryIdx; } if( !bLeftInvolved && uiUnaryIdx > 0 ) { --uiUnaryIdx; } for( UInt ui = 0; ui < uiNumCand - 1; ++ui ) { const UInt uiSymbol = ui == uiUnaryIdx ? 0 : 1; m_pcBinIf->encodeBin( uiSymbol, m_cCUMergeIdxExtSCModel.get( 0, 0, auiCtx[ui] ) ); if( uiSymbol == 0 ) { break; } } DTRACE_CABAC_V( g_nSymbolCounter++ ); DTRACE_CABAC_T( "\tparseMergeIndex()" ); DTRACE_CABAC_T( "\tuiMRGIdx= " ); DTRACE_CABAC_V( pcCU->getMergeIndex( uiAbsPartIdx ) ); DTRACE_CABAC_T( "\tuiNumCand= " ); DTRACE_CABAC_V( uiNumCand ); DTRACE_CABAC_T( "\tbLeftInvolved= " ); DTRACE_CABAC_V( bLeftInvolved ); DTRACE_CABAC_T( "\tbAboveInvolved= " ); DTRACE_CABAC_V( bAboveInvolved ); DTRACE_CABAC_T( "\tbCollocatedInvolved= " ); DTRACE_CABAC_V( bCollocatedInvolved ); DTRACE_CABAC_T( "\tbCornerRTInvolved= " ); DTRACE_CABAC_V( bCornerInvolved ); DTRACE_CABAC_T( "\tbCornerBLInvolved= " ); DTRACE_CABAC_V( bCornerBLInvolved ); DTRACE_CABAC_T( "\n" ); } #if HHI_INTER_VIEW_RESIDUAL_PRED Void TEncSbac::codeResPredFlag( TComDataCU* pcCU, UInt uiAbsPartIdx ) { UInt uiCtx = 0; UInt uiSymbol = ( pcCU->getResPredFlag( uiAbsPartIdx ) ? 1 : 0 ); m_pcBinIf->encodeBin( uiSymbol, m_cResPredFlagSCModel.get( 0, 0, uiCtx ) ); } #endif Void TEncSbac::codeSplitFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { if( uiDepth == g_uiMaxCUDepth - g_uiAddCUDepth ) return; UInt uiCtx = pcCU->getCtxSplitFlag( uiAbsPartIdx, uiDepth ); UInt uiCurrSplitFlag = ( pcCU->getDepth( uiAbsPartIdx ) > uiDepth ) ? 1 : 0; assert( uiCtx < 3 ); m_pcBinIf->encodeBin( uiCurrSplitFlag, m_cCUSplitFlagSCModel.get( 0, 0, uiCtx ) ); DTRACE_CABAC_V( g_nSymbolCounter++ ) DTRACE_CABAC_T( "\tSplitFlag\n" ) return; } Void TEncSbac::codeTransformSubdivFlag( UInt uiSymbol, UInt uiCtx ) { m_pcBinIf->encodeBin( uiSymbol, m_cCUTransSubdivFlagSCModel.get( 0, 0, uiCtx ) ); DTRACE_CABAC_V( g_nSymbolCounter++ ) DTRACE_CABAC_T( "\tparseTransformSubdivFlag()" ) DTRACE_CABAC_T( "\tsymbol=" ) DTRACE_CABAC_V( uiSymbol ) DTRACE_CABAC_T( "\tctx=" ) DTRACE_CABAC_V( uiCtx ) DTRACE_CABAC_T( "\n" ) } #if HHI_DMM_WEDGE_INTRA Void TEncSbac::xCodeWedgeFullInfo( TComDataCU* pcCU, UInt uiAbsPartIdx ) { Int iIntraIdx = pcCU->getIntraSizeIdx(uiAbsPartIdx); Int iBits = g_aucWedgeFullBitsListIdx[iIntraIdx]; UInt uiTabIdx = pcCU->getWedgeFullTabIdx( uiAbsPartIdx ); for ( Int i = 0; i < iBits; i++ ) { m_pcBinIf->encodeBin( ( uiTabIdx >> i ) & 1, m_cIntraWedgeSCModel.get(0, 0, 0) ); } } Void TEncSbac::xCodeWedgeFullDeltaInfo( TComDataCU* pcCU, UInt uiAbsPartIdx ) { Int iIntraIdx = pcCU->getIntraSizeIdx(uiAbsPartIdx); Int iBits = g_aucWedgeFullBitsListIdx[iIntraIdx]; UInt uiTabIdx = pcCU->getWedgeFullTabIdx( uiAbsPartIdx ); for ( Int i = 0; i < iBits; i++ ) { m_pcBinIf->encodeBin( ( uiTabIdx >> i ) & 1, m_cIntraWedgeSCModel.get(0, 0, 0) ); } Int iDeltaDC1 = pcCU->getWedgeFullDeltaDC1( uiAbsPartIdx ); Int iDeltaDC2 = pcCU->getWedgeFullDeltaDC2( uiAbsPartIdx ); xWriteExGolombLevel( UInt( abs( iDeltaDC1 ) ), m_cIntraWedgeSCModel.get(0, 0, 1) ); if ( iDeltaDC1 != 0 ) { UInt uiSign = iDeltaDC1 > 0 ? 0 : 1; m_pcBinIf->encodeBinEP( uiSign ); } xWriteExGolombLevel( UInt( abs( iDeltaDC2 ) ), m_cIntraWedgeSCModel.get(0, 0, 1) ); if ( iDeltaDC2 != 0 ) { UInt uiSign = iDeltaDC2 > 0 ? 0 : 1; m_pcBinIf->encodeBinEP( uiSign ); } } Void TEncSbac::xCodeWedgePredDirInfo( TComDataCU* pcCU, UInt uiAbsPartIdx ) { if( DMM_WEDGE_PREDDIR_DELTAEND_MAX > 0 ) { Int iDeltaEnd = pcCU->getWedgePredDirDeltaEnd( uiAbsPartIdx ); m_pcBinIf->encodeBin( (iDeltaEnd!=0), m_cIntraWedgeSCModel.get(0, 0, 3) ); if( iDeltaEnd != 0 ) { UInt uiAbsValMinus1 = abs(iDeltaEnd)-1; m_pcBinIf->encodeBin( (uiAbsValMinus1 & 0x01), m_cIntraWedgeSCModel.get(0, 0, 3) ); m_pcBinIf->encodeBin( (uiAbsValMinus1 & 0x02) >> 1, m_cIntraWedgeSCModel.get(0, 0, 3) ); UInt uiSign = iDeltaEnd > 0 ? 0 : 1; m_pcBinIf->encodeBinEP( uiSign ); } } } Void TEncSbac::xCodeWedgePredDirDeltaInfo( TComDataCU* pcCU, UInt uiAbsPartIdx ) { if( DMM_WEDGE_PREDDIR_DELTAEND_MAX > 0 ) { Int iDeltaEnd = pcCU->getWedgePredDirDeltaEnd( uiAbsPartIdx ); m_pcBinIf->encodeBin( (iDeltaEnd!=0), m_cIntraWedgeSCModel.get(0, 0, 3) ); if( iDeltaEnd != 0 ) { UInt uiAbsValMinus1 = abs(iDeltaEnd)-1; m_pcBinIf->encodeBin( (uiAbsValMinus1 & 0x01), m_cIntraWedgeSCModel.get(0, 0, 3) ); m_pcBinIf->encodeBin( (uiAbsValMinus1 & 0x02) >> 1, m_cIntraWedgeSCModel.get(0, 0, 3) ); UInt uiSign = iDeltaEnd > 0 ? 0 : 1; m_pcBinIf->encodeBinEP( uiSign ); } } Int iDeltaDC1 = pcCU->getWedgePredDirDeltaDC1( uiAbsPartIdx ); Int iDeltaDC2 = pcCU->getWedgePredDirDeltaDC2( uiAbsPartIdx ); xWriteExGolombLevel( UInt( abs( iDeltaDC1 ) ), m_cIntraWedgeSCModel.get(0, 0, 1) ); if ( iDeltaDC1 != 0 ) { UInt uiSign = iDeltaDC1 > 0 ? 0 : 1; m_pcBinIf->encodeBinEP( uiSign ); } xWriteExGolombLevel( UInt( abs( iDeltaDC2 ) ), m_cIntraWedgeSCModel.get(0, 0, 1) ); if ( iDeltaDC2 != 0 ) { UInt uiSign = iDeltaDC2 > 0 ? 0 : 1; m_pcBinIf->encodeBinEP( uiSign ); } } #endif #if HHI_DMM_PRED_TEX Void TEncSbac::xCodeWedgePredTexDeltaInfo( TComDataCU* pcCU, UInt uiAbsPartIdx ) { Int iDeltaDC1 = pcCU->getWedgePredTexDeltaDC1( uiAbsPartIdx ); Int iDeltaDC2 = pcCU->getWedgePredTexDeltaDC2( uiAbsPartIdx ); xWriteExGolombLevel( UInt( abs( iDeltaDC1 ) ), m_cIntraWedgeSCModel.get(0, 0, 1) ); if ( iDeltaDC1 != 0 ) { UInt uiSign = iDeltaDC1 > 0 ? 0 : 1; m_pcBinIf->encodeBinEP( uiSign ); } xWriteExGolombLevel( UInt( abs( iDeltaDC2 ) ), m_cIntraWedgeSCModel.get(0, 0, 1) ); if ( iDeltaDC2 != 0 ) { UInt uiSign = iDeltaDC2 > 0 ? 0 : 1; m_pcBinIf->encodeBinEP( uiSign ); } } Void TEncSbac::xCodeContourPredTexDeltaInfo( TComDataCU* pcCU, UInt uiAbsPartIdx ) { Int iDeltaDC1 = pcCU->getContourPredTexDeltaDC1( uiAbsPartIdx ); Int iDeltaDC2 = pcCU->getContourPredTexDeltaDC2( uiAbsPartIdx ); xWriteExGolombLevel( UInt( abs( iDeltaDC1 ) ), m_cIntraWedgeSCModel.get(0, 0, 1) ); if ( iDeltaDC1 != 0 ) { UInt uiSign = iDeltaDC1 > 0 ? 0 : 1; m_pcBinIf->encodeBinEP( uiSign ); } xWriteExGolombLevel( UInt( abs( iDeltaDC2 ) ), m_cIntraWedgeSCModel.get(0, 0, 1) ); if ( iDeltaDC2 != 0 ) { UInt uiSign = iDeltaDC2 > 0 ? 0 : 1; m_pcBinIf->encodeBinEP( uiSign ); } } #endif #if MTK_DCM_MPM Void TEncSbac::codeIntraDirLumaAng( TComDataCU* pcCU, UInt uiAbsPartIdx ) { UInt uiDir = pcCU->getLumaIntraDir( uiAbsPartIdx ); #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX if ( pcCU->getSlice()->getSPS()->isDepth() && pcCU->getSlice()->getSPS()->getUseDMM() && pcCU->getWidth( uiAbsPartIdx ) < 64 ) { m_pcBinIf->encodeBin( uiDir > MAX_MODE_ID_INTRA_DIR, m_cIntraDMMSCModel.get(0, 0, 0) ); } if( uiDir > MAX_MODE_ID_INTRA_DIR ) { assert( pcCU->getWidth( uiAbsPartIdx ) < 64 ); UInt uiDMMode = uiDir - (MAX_MODE_ID_INTRA_DIR+1); #if HHI_DMM_WEDGE_INTRA && HHI_DMM_PRED_TEX m_pcBinIf->encodeBin( (uiDMMode & 0x01), m_cIntraDMMSCModel.get(0, 0, 1) ); m_pcBinIf->encodeBin( (uiDMMode & 0x02) >> 1, m_cIntraDMMSCModel.get(0, 0, 1) ); if ( pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_NxN && pcCU->getWidth( uiAbsPartIdx ) > 4 ) { m_pcBinIf->encodeBin( (uiDMMode & 0x04) >> 2, m_cIntraDMMSCModel.get(0, 0, 1) ); } #else m_pcBinIf->encodeBin( (uiDMMode & 0x01), m_cIntraDMMSCModel.get(0, 0, 1) ); if ( pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_NxN && pcCU->getWidth( uiAbsPartIdx ) > 4 ) { m_pcBinIf->encodeBin( (uiDMMode & 0x02) >> 1, m_cIntraDMMSCModel.get(0, 0, 1) ); } #endif #if HHI_DMM_WEDGE_INTRA if( uiDir == DMM_WEDGE_FULL_IDX ) { xCodeWedgeFullInfo ( pcCU, uiAbsPartIdx ); } if( uiDir == DMM_WEDGE_FULL_D_IDX ) { xCodeWedgeFullDeltaInfo ( pcCU, uiAbsPartIdx ); } if( uiDir == DMM_WEDGE_PREDDIR_IDX ) { xCodeWedgePredDirInfo ( pcCU, uiAbsPartIdx ); } if( uiDir == DMM_WEDGE_PREDDIR_D_IDX ) { xCodeWedgePredDirDeltaInfo ( pcCU, uiAbsPartIdx ); } #endif #if HHI_DMM_PRED_TEX #if FLEX_CODING_ORDER if ( !pcCU->getSlice()->getSPS()->getUseDMM34() ) { assert( uiDir != DMM_WEDGE_PREDTEX_D_IDX ); assert( uiDir != DMM_CONTOUR_PREDTEX_D_IDX ); } #endif if( uiDir == DMM_WEDGE_PREDTEX_D_IDX ) { xCodeWedgePredTexDeltaInfo ( pcCU, uiAbsPartIdx ); } if( uiDir == DMM_CONTOUR_PREDTEX_D_IDX ) { xCodeContourPredTexDeltaInfo( pcCU, uiAbsPartIdx ); } #endif } else #endif { Int iIntraIdx = pcCU->getIntraSizeIdx(uiAbsPartIdx); #if ADD_PLANAR_MODE UInt planarFlag = 0; if (uiDir == PLANAR_IDX) { uiDir = 2; planarFlag = 1; } #endif Int uiPreds[2] = {-1, -1}; Int uiPredNum = pcCU->getIntraDirLumaPredictor(uiAbsPartIdx, uiPreds); Int uiPredIdx = -1; for(UInt i = 0; i < uiPredNum; i++) { if(uiDir == uiPreds[i]) { uiPredIdx = i; } } if(uiPredIdx != -1) { m_pcBinIf->encodeBin( 1, m_cCUIntraPredSCModel.get( 0, 0, 0 ) ); if(uiPredNum == 2) { m_pcBinIf->encodeBin( uiPredIdx, m_cCUIntraPredSCModel.get( 0, 0, 2 ) ); } } else { m_pcBinIf->encodeBin( 0, m_cCUIntraPredSCModel.get( 0, 0, 0 ) ); for(Int i = (uiPredNum - 1); i >= 0; i--) { uiDir = uiDir > uiPreds[i] ? uiDir - 1 : uiDir; } if ( g_aucIntraModeBitsAng[iIntraIdx] < 6 ) { m_pcBinIf->encodeBin((uiDir & 0x01), m_cCUIntraPredSCModel.get(0, 0, 1)); if ( g_aucIntraModeBitsAng[iIntraIdx] > 2 ) { m_pcBinIf->encodeBin((uiDir & 0x02) >> 1, m_cCUIntraPredSCModel.get(0, 0, 1));} if ( g_aucIntraModeBitsAng[iIntraIdx] > 3 ) { m_pcBinIf->encodeBin((uiDir & 0x04) >> 2, m_cCUIntraPredSCModel.get(0, 0, 1));} if ( g_aucIntraModeBitsAng[iIntraIdx] > 4 ) { m_pcBinIf->encodeBin((uiDir & 0x08) >> 3, m_cCUIntraPredSCModel.get(0, 0, 1));} } else { if (uiDir < 31){ // uiDir is here 0...32, 5 bits for uiDir 0...30, 31 is an escape code for coding one more bit for 31 and 32 m_pcBinIf->encodeBin((uiDir & 0x01), m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin((uiDir & 0x02) >> 1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin((uiDir & 0x04) >> 2, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin((uiDir & 0x08) >> 3, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin((uiDir & 0x10) >> 4, m_cCUIntraPredSCModel.get(0, 0, 1)); } else{ m_pcBinIf->encodeBin(1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin(1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin(1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin(1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin(1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin((uiDir == 32) ? 1 : 0, m_cCUIntraPredSCModel.get(0, 0, 1)); } } } #if ADD_PLANAR_MODE uiDir = pcCU->getLumaIntraDir( uiAbsPartIdx ); if ( (uiDir == PLANAR_IDX) || (uiDir == 2) ) { m_pcBinIf->encodeBin( planarFlag, m_cPlanarFlagSCModel.get(0,0,0) ); } #endif } return; } #else Void TEncSbac::codeIntraDirLumaAng( TComDataCU* pcCU, UInt uiAbsPartIdx ) { UInt uiDir = pcCU->getLumaIntraDir( uiAbsPartIdx ); #if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX if ( pcCU->getSlice()->getSPS()->isDepth() && pcCU->getSlice()->getSPS()->getUseDMM() && pcCU->getWidth( uiAbsPartIdx ) < 64 ) { m_pcBinIf->encodeBin( uiDir > MAX_MODE_ID_INTRA_DIR, m_cIntraDMMSCModel.get(0, 0, 0) ); } if( uiDir > MAX_MODE_ID_INTRA_DIR ) { assert( pcCU->getWidth( uiAbsPartIdx ) < 64 ); UInt uiDMMode = uiDir - (MAX_MODE_ID_INTRA_DIR+1); #if HHI_DMM_WEDGE_INTRA && HHI_DMM_PRED_TEX m_pcBinIf->encodeBin( (uiDMMode & 0x01), m_cIntraDMMSCModel.get(0, 0, 1) ); m_pcBinIf->encodeBin( (uiDMMode & 0x02) >> 1, m_cIntraDMMSCModel.get(0, 0, 1) ); if ( pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_NxN && pcCU->getWidth( uiAbsPartIdx ) > 4 ) { m_pcBinIf->encodeBin( (uiDMMode & 0x04) >> 2, m_cIntraDMMSCModel.get(0, 0, 1) ); } #else m_pcBinIf->encodeBin( (uiDMMode & 0x01), m_cIntraDMMSCModel.get(0, 0, 1) ); if ( pcCU->getPartitionSize( uiAbsPartIdx ) != SIZE_NxN && pcCU->getWidth( uiAbsPartIdx ) > 4 ) { m_pcBinIf->encodeBin( (uiDMMode & 0x02) >> 1, m_cIntraDMMSCModel.get(0, 0, 1) ); } #endif #if HHI_DMM_WEDGE_INTRA if( uiDir == DMM_WEDGE_FULL_IDX ) { xCodeWedgeFullInfo ( pcCU, uiAbsPartIdx ); } if( uiDir == DMM_WEDGE_FULL_D_IDX ) { xCodeWedgeFullDeltaInfo ( pcCU, uiAbsPartIdx ); } if( uiDir == DMM_WEDGE_PREDDIR_IDX ) { xCodeWedgePredDirInfo ( pcCU, uiAbsPartIdx ); } if( uiDir == DMM_WEDGE_PREDDIR_D_IDX ) { xCodeWedgePredDirDeltaInfo ( pcCU, uiAbsPartIdx ); } #endif #if HHI_DMM_PRED_TEX if( uiDir == DMM_WEDGE_PREDTEX_D_IDX ) { xCodeWedgePredTexDeltaInfo ( pcCU, uiAbsPartIdx ); } if( uiDir == DMM_CONTOUR_PREDTEX_D_IDX ) { xCodeContourPredTexDeltaInfo( pcCU, uiAbsPartIdx ); } #endif } else #endif { Int iMostProbable = pcCU->getMostProbableIntraDirLuma( uiAbsPartIdx ); #if ADD_PLANAR_MODE UInt planarFlag = 0; if (uiDir == PLANAR_IDX) { uiDir = 2; planarFlag = 1; } #endif if (uiDir == iMostProbable) m_pcBinIf->encodeBin( 1, m_cCUIntraPredSCModel.get( 0, 0, 0 ) ); else { m_pcBinIf->encodeBin( 0, m_cCUIntraPredSCModel.get( 0, 0, 0 ) ); uiDir = uiDir > iMostProbable ? uiDir - 1 : uiDir; Int iIntraIdx = pcCU->getIntraSizeIdx(uiAbsPartIdx); if ( g_aucIntraModeBitsAng[iIntraIdx] < 6 ) { m_pcBinIf->encodeBin((uiDir & 0x01), m_cCUIntraPredSCModel.get(0, 0, 1)); if ( g_aucIntraModeBitsAng[iIntraIdx] > 2 ) m_pcBinIf->encodeBin((uiDir & 0x02) >> 1, m_cCUIntraPredSCModel.get(0, 0, 1)); if ( g_aucIntraModeBitsAng[iIntraIdx] > 3 ) m_pcBinIf->encodeBin((uiDir & 0x04) >> 2, m_cCUIntraPredSCModel.get(0, 0, 1)); if ( g_aucIntraModeBitsAng[iIntraIdx] > 4 ) m_pcBinIf->encodeBin((uiDir & 0x08) >> 3, m_cCUIntraPredSCModel.get(0, 0, 1)); } else { if (uiDir < 31) { // uiDir is here 0...32, 5 bits for uiDir 0...30, 31 is an escape code for coding one more bit for 31 and 32 m_pcBinIf->encodeBin((uiDir & 0x01), m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin((uiDir & 0x02) >> 1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin((uiDir & 0x04) >> 2, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin((uiDir & 0x08) >> 3, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin((uiDir & 0x10) >> 4, m_cCUIntraPredSCModel.get(0, 0, 1)); } else { m_pcBinIf->encodeBin(1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin(1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin(1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin(1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin(1, m_cCUIntraPredSCModel.get(0, 0, 1)); m_pcBinIf->encodeBin((uiDir == 32) ? 1 : 0, m_cCUIntraPredSCModel.get(0, 0, 1)); } } } #if ADD_PLANAR_MODE uiDir = pcCU->getLumaIntraDir( uiAbsPartIdx ); if ( (uiDir == PLANAR_IDX) || (uiDir == 2) ) { m_pcBinIf->encodeBin( planarFlag, m_cPlanarFlagSCModel.get(0,0,0) ); } #endif } return; } #endif Void TEncSbac::codeIntraDirChroma( TComDataCU* pcCU, UInt uiAbsPartIdx ) { UInt uiCtx = pcCU->getCtxIntraDirChroma( uiAbsPartIdx ); UInt uiIntraDirChroma = pcCU->getChromaIntraDir ( uiAbsPartIdx ); #if ADD_PLANAR_MODE UInt planarFlag = 0; if (uiIntraDirChroma == PLANAR_IDX) { uiIntraDirChroma = 2; planarFlag = 1; } #endif #if CHROMA_CODEWORD UInt uiMode = pcCU->getLumaIntraDir(uiAbsPartIdx); #if ADD_PLANAR_MODE if ( (uiMode == 2 ) || (uiMode == PLANAR_IDX) ) { uiMode = 4; } #endif #if LM_CHROMA Bool bUseLMFlag = pcCU->getSlice()->getSPS()->getUseLMChroma(); Int iMaxMode = bUseLMFlag ? 3 : 4; Int iMax = uiMode < iMaxMode ? 2 : 3; //switch codeword if (uiIntraDirChroma == 4) { uiIntraDirChroma = 0; } else if (uiIntraDirChroma == 3 && bUseLMFlag ) { uiIntraDirChroma = 1; } else { if (uiIntraDirChroma < uiMode) uiIntraDirChroma++; if (bUseLMFlag) uiIntraDirChroma++; #if CHROMA_CODEWORD_SWITCH uiIntraDirChroma = ChromaMapping[iMax-2][uiIntraDirChroma]; #endif } #else // <-- LM_CHROMA Int iMax = uiMode < 4 ? 2 : 3; //switch codeword if (uiIntraDirChroma == 4) { uiIntraDirChroma = 0; } #if CHROMA_CODEWORD_SWITCH else { if (uiIntraDirChroma < uiMode) { uiIntraDirChroma++; } uiIntraDirChroma = ChromaMapping[iMax-2][uiIntraDirChroma]; } #else else if (uiIntraDirChroma < uiMode) { uiIntraDirChroma++; } #endif #endif // <-- LM_CHROMA if ( 0 == uiIntraDirChroma ) { m_pcBinIf->encodeBin( 0, m_cCUChromaPredSCModel.get( 0, 0, uiCtx ) ); } else { m_pcBinIf->encodeBin( 1, m_cCUChromaPredSCModel.get( 0, 0, uiCtx ) ); xWriteUnaryMaxSymbol( uiIntraDirChroma - 1, m_cCUChromaPredSCModel.get( 0, 0 ) + 3, 0, iMax ); } #else // CHROMA_CODEWORD if ( 0 == uiIntraDirChroma ) { m_pcBinIf->encodeBin( 0, m_cCUChromaPredSCModel.get( 0, 0, uiCtx ) ); } else { m_pcBinIf->encodeBin( 1, m_cCUChromaPredSCModel.get( 0, 0, uiCtx ) ); xWriteUnaryMaxSymbol( uiIntraDirChroma - 1, m_cCUChromaPredSCModel.get( 0, 0 ) + 3, 0, 3 ); } #endif #if ADD_PLANAR_MODE uiIntraDirChroma = pcCU->getChromaIntraDir( uiAbsPartIdx ); #if CHROMA_CODEWORD uiMode = pcCU->getLumaIntraDir(uiAbsPartIdx); mapPlanartoDC( uiIntraDirChroma ); mapPlanartoDC( uiMode ); if ( (uiIntraDirChroma == 2) && (uiMode != 2) ) #else if ( (uiIntraDirChroma == PLANAR_IDX) || (uiIntraDirChroma == 2) ) #endif { m_pcBinIf->encodeBin( planarFlag, m_cPlanarFlagSCModel.get(0,0,1) ); } #endif return; } Void TEncSbac::codeInterDir( TComDataCU* pcCU, UInt uiAbsPartIdx ) { UInt uiInterDir = pcCU->getInterDir ( uiAbsPartIdx ); UInt uiCtx = pcCU->getCtxInterDir( uiAbsPartIdx ); uiInterDir--; m_pcBinIf->encodeBin( ( uiInterDir == 2 ? 1 : 0 ), m_cCUInterDirSCModel.get( 0, 0, uiCtx ) ); if ( pcCU->getSlice()->getNoBackPredFlag() ) { assert( uiInterDir != 1 ); return; } #if DCM_COMB_LIST if ( uiInterDir < 2 && pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) <= 0) #else if ( uiInterDir < 2 ) #endif { m_pcBinIf->encodeBin( uiInterDir, m_cCUInterDirSCModel.get( 0, 0, 3 ) ); } return; } Void TEncSbac::codeRefFrmIdx( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList ) { #if DCM_COMB_LIST if ( pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getInterDir( uiAbsPartIdx ) != 3) { Int iRefFrame = pcCU->getSlice()->getRefIdxOfLC(eRefList, pcCU->getCUMvField( eRefList )->getRefIdx( uiAbsPartIdx )); UInt uiCtx; uiCtx = pcCU->getCtxRefIdx( uiAbsPartIdx, RefPicList(pcCU->getSlice()->getListIdFromIdxOfLC(0)) ); m_pcBinIf->encodeBin( ( iRefFrame == 0 ? 0 : 1 ), m_cCURefPicSCModel.get( 0, 0, uiCtx ) ); if ( iRefFrame > 0 ) { xWriteUnaryMaxSymbol( iRefFrame - 1, &m_cCURefPicSCModel.get( 0, 0, 4 ), 1, pcCU->getSlice()->getNumRefIdx( REF_PIC_LIST_C )-2 ); } } else { #endif Int iRefFrame = pcCU->getCUMvField( eRefList )->getRefIdx( uiAbsPartIdx ); UInt uiCtx = pcCU->getCtxRefIdx( uiAbsPartIdx, eRefList ); m_pcBinIf->encodeBin( ( iRefFrame == 0 ? 0 : 1 ), m_cCURefPicSCModel.get( 0, 0, uiCtx ) ); if ( iRefFrame > 0 ) { xWriteUnaryMaxSymbol( iRefFrame - 1, &m_cCURefPicSCModel.get( 0, 0, 4 ), 1, pcCU->getSlice()->getNumRefIdx( eRefList )-2 ); } #if DCM_COMB_LIST } #endif return; } Void TEncSbac::codeViewIdx(Int iViewIdx) { assert(0) ; // not implemented yet xWriteUnaryMaxSymbol(iViewIdx, &m_cViewIdxSCModel.get( 0, 0, 4),1, MAX_NUMBER_VIEWS ); } Void TEncSbac::codeMvd( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList ) { TComCUMvField* pcCUMvField = pcCU->getCUMvField( eRefList ); Int iHor = pcCUMvField->getMvd( uiAbsPartIdx ).getHor(); Int iVer = pcCUMvField->getMvd( uiAbsPartIdx ).getVer(); UInt uiAbsPartIdxL, uiAbsPartIdxA; #if MVD_CTX Int iHorPredL, iVerPredL; Int iHorPredA, iVerPredA; #else Int iHorPred, iVerPred; #endif TComDataCU* pcCUL = pcCU->getPULeft ( uiAbsPartIdxL, pcCU->getZorderIdxInCU() + uiAbsPartIdx ); TComDataCU* pcCUA = pcCU->getPUAbove( uiAbsPartIdxA, pcCU->getZorderIdxInCU() + uiAbsPartIdx ); TComCUMvField* pcCUMvFieldL = ( pcCUL == NULL || pcCUL->isIntra( uiAbsPartIdxL ) ) ? NULL : pcCUL->getCUMvField( eRefList ); TComCUMvField* pcCUMvFieldA = ( pcCUA == NULL || pcCUA->isIntra( uiAbsPartIdxA ) ) ? NULL : pcCUA->getCUMvField( eRefList ); #if MVD_CTX iHorPredA = ( (pcCUMvFieldA == NULL) ? 0 : pcCUMvFieldA->getMvd( uiAbsPartIdxA ).getAbsHor() ); iVerPredA = ( (pcCUMvFieldA == NULL) ? 0 : pcCUMvFieldA->getMvd( uiAbsPartIdxA ).getAbsVer() ); iHorPredL = ( (pcCUMvFieldL == NULL) ? 0 : pcCUMvFieldL->getMvd( uiAbsPartIdxL ).getAbsHor() ); iVerPredL = ( (pcCUMvFieldL == NULL) ? 0 : pcCUMvFieldL->getMvd( uiAbsPartIdxL ).getAbsVer() ); xWriteMvd( iHor, iHorPredL, iHorPredA, 0 ); xWriteMvd( iVer, iVerPredL, iVerPredA, 1 ); #else iHorPred = ( (pcCUMvFieldL == NULL) ? 0 : pcCUMvFieldL->getMvd( uiAbsPartIdxL ).getAbsHor() ) + ( (pcCUMvFieldA == NULL) ? 0 : pcCUMvFieldA->getMvd( uiAbsPartIdxA ).getAbsHor() ); iVerPred = ( (pcCUMvFieldL == NULL) ? 0 : pcCUMvFieldL->getMvd( uiAbsPartIdxL ).getAbsVer() ) + ( (pcCUMvFieldA == NULL) ? 0 : pcCUMvFieldA->getMvd( uiAbsPartIdxA ).getAbsVer() ); xWriteMvd( iHor, iHorPred, 0 ); xWriteMvd( iVer, iVerPred, 1 ); #endif return; } Void TEncSbac::codeDeltaQP( TComDataCU* pcCU, UInt uiAbsPartIdx ) { Int iDQp = pcCU->getQP( uiAbsPartIdx ) - pcCU->getSlice()->getSliceQp(); if ( iDQp == 0 ) { m_pcBinIf->encodeBin( 0, m_cCUDeltaQpSCModel.get( 0, 0, 0 ) ); } else { m_pcBinIf->encodeBin( 1, m_cCUDeltaQpSCModel.get( 0, 0, 0 ) ); UInt uiDQp = (UInt)( iDQp > 0 ? ( 2 * iDQp - 2 ) : ( -2 * iDQp - 1 ) ); xWriteUnarySymbol( uiDQp, &m_cCUDeltaQpSCModel.get( 0, 0, 2 ), 1 ); } return; } Void TEncSbac::codeQtCbf( TComDataCU* pcCU, UInt uiAbsPartIdx, TextType eType, UInt uiTrDepth ) { UInt uiCbf = pcCU->getCbf ( uiAbsPartIdx, eType, uiTrDepth ); UInt uiCtx = pcCU->getCtxQtCbf( uiAbsPartIdx, eType, uiTrDepth ); m_pcBinIf->encodeBin( uiCbf , m_cCUQtCbfSCModel.get( 0, eType ? eType - 1 : eType, uiCtx ) ); DTRACE_CABAC_V( g_nSymbolCounter++ ) DTRACE_CABAC_T( "\tparseQtCbf()" ) DTRACE_CABAC_T( "\tsymbol=" ) DTRACE_CABAC_V( uiCbf ) DTRACE_CABAC_T( "\tctx=" ) DTRACE_CABAC_V( uiCtx ) DTRACE_CABAC_T( "\tetype=" ) DTRACE_CABAC_V( eType ) DTRACE_CABAC_T( "\tuiAbsPartIdx=" ) DTRACE_CABAC_V( uiAbsPartIdx ) DTRACE_CABAC_T( "\n" ) } UInt xCheckCoeffPlainCNoRecur( const TCoeff* pcCoef, UInt uiSize, UInt uiDepth ) { UInt uiNumofCoeff = 0; UInt ui = uiSize>>uiDepth; { UInt x, y; const TCoeff* pCeoff = pcCoef; for( y=0 ; ygetQtRootCbf( uiAbsPartIdx ); UInt uiCtx = pcCU->getCtxQtRootCbf( uiAbsPartIdx ); m_pcBinIf->encodeBin( uiCbf , m_cCUQtRootCbfSCModel.get( 0, 0, uiCtx ) ); DTRACE_CABAC_V( g_nSymbolCounter++ ) DTRACE_CABAC_T( "\tparseQtRootCbf()" ) DTRACE_CABAC_T( "\tsymbol=" ) DTRACE_CABAC_V( uiCbf ) DTRACE_CABAC_T( "\tctx=" ) DTRACE_CABAC_V( uiCtx ) DTRACE_CABAC_T( "\tuiAbsPartIdx=" ) DTRACE_CABAC_V( uiAbsPartIdx ) DTRACE_CABAC_T( "\n" ) } Void TEncSbac::xCheckCoeff( TCoeff* pcCoef, UInt uiSize, UInt uiDepth, UInt& uiNumofCoeff, UInt& uiPart ) { UInt ui = uiSize>>uiDepth; if( uiPart == 0 ) { if( ui <= 4 ) { UInt x, y; TCoeff* pCeoff = pcCoef; for( y=0 ; y>1), uiSize, uiDepth+1, uiNumofCoeff, uiPart ); uiPart++; //2nd Part xCheckCoeff( pcCoef + (ui>>1)*uiSize, uiSize, uiDepth+1, uiNumofCoeff, uiPart ); uiPart++; //3rd Part xCheckCoeff( pcCoef + (ui>>1)*uiSize + (ui>>1), uiSize, uiDepth+1, uiNumofCoeff, uiPart ); //4th Part } } else { UInt x, y; TCoeff* pCeoff = pcCoef; for( y=0 ; yencodeBin( 0, m_cCuCtxLastX.get( 0, eTType, uiCtxOffset + g_uiCtxXY[uiCtxLast] ) ); } if(uiPosX < uiWidth - 1) { m_pcBinIf->encodeBin( 1, m_cCuCtxLastX.get( 0, eTType, uiCtxOffset + g_uiCtxXY[uiCtxLast] ) ); } for(uiCtxLast=0; uiCtxLastencodeBin( 0, m_cCuCtxLastY.get( 0, eTType, uiCtxOffset + g_uiCtxXY[uiCtxLast] ) ); } if(uiPosY < uiWidth - 1) { m_pcBinIf->encodeBin( 1, m_cCuCtxLastY.get( 0, eTType, uiCtxOffset + g_uiCtxXY[uiCtxLast] ) ); } } #endif Void TEncSbac::codeCoeffNxN( TComDataCU* pcCU, TCoeff* pcCoef, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, UInt uiDepth, TextType eTType, Bool bRD ) { DTRACE_CABAC_V( g_nSymbolCounter++ ) DTRACE_CABAC_T( "\tparseCoeffNxN()\teType=" ) DTRACE_CABAC_V( eTType ) DTRACE_CABAC_T( "\twidth=" ) DTRACE_CABAC_V( uiWidth ) DTRACE_CABAC_T( "\theight=" ) DTRACE_CABAC_V( uiHeight ) DTRACE_CABAC_T( "\tdepth=" ) DTRACE_CABAC_V( uiDepth ) DTRACE_CABAC_T( "\tabspartidx=" ) DTRACE_CABAC_V( uiAbsPartIdx ) DTRACE_CABAC_T( "\ttoCU-X=" ) DTRACE_CABAC_V( pcCU->getCUPelX() ) DTRACE_CABAC_T( "\ttoCU-Y=" ) DTRACE_CABAC_V( pcCU->getCUPelY() ) DTRACE_CABAC_T( "\tCU-addr=" ) DTRACE_CABAC_V( pcCU->getAddr() ) DTRACE_CABAC_T( "\tinCU-X=" ) DTRACE_CABAC_V( g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ] ) DTRACE_CABAC_T( "\tinCU-Y=" ) DTRACE_CABAC_V( g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ] ) DTRACE_CABAC_T( "\tpredmode=" ) DTRACE_CABAC_V( pcCU->getPredictionMode( uiAbsPartIdx ) ) DTRACE_CABAC_T( "\n" ) if( uiWidth > m_pcSlice->getSPS()->getMaxTrSize() ) { uiWidth = m_pcSlice->getSPS()->getMaxTrSize(); uiHeight = m_pcSlice->getSPS()->getMaxTrSize(); } UInt uiNumSig = 0; UInt uiCTXIdx = 0; switch( uiWidth ) { case 2: uiCTXIdx = 6; break; case 4: uiCTXIdx = 5; break; case 8: uiCTXIdx = 4; break; case 16: uiCTXIdx = 3; break; case 32: uiCTXIdx = 2; break; case 64: uiCTXIdx = 1; break; default: uiCTXIdx = 0; break; } // compute number of significant coefficients UInt uiPart = 0; xCheckCoeff(pcCoef, uiWidth, 0, uiNumSig, uiPart ); if ( bRD ) { UInt uiTempDepth = uiDepth - pcCU->getDepth( uiAbsPartIdx ); pcCU->setCbfSubParts( ( uiNumSig ? 1 : 0 ) << uiTempDepth, eTType, uiAbsPartIdx, uiDepth ); } if ( uiNumSig == 0 ) return; eTType = eTType == TEXT_LUMA ? TEXT_LUMA : ( eTType == TEXT_NONE ? TEXT_NONE : TEXT_CHROMA ); //----- encode significance map ----- const UInt uiLog2BlockSize = g_aucConvertToBit[ uiWidth ] + 2; const UInt uiMaxNumCoeff = 1 << ( uiLog2BlockSize << 1 ); #if !PCP_SIGMAP_SIMPLE_LAST const UInt uiMaxNumCoeffM1 = uiMaxNumCoeff - 1; #endif const UInt uiNum4x4Blk = max( 1, uiMaxNumCoeff >> 4 ); #if QC_MDCS const UInt uiScanIdx = pcCU->getCoefScanIdx(uiAbsPartIdx, uiWidth, eTType==TEXT_LUMA, pcCU->isIntra(uiAbsPartIdx)); #endif //QC_MDCS #if PCP_SIGMAP_SIMPLE_LAST //===== code last coeff ===== UInt uiScanPosLast = 0, uiPosLastX, uiPosLastY; for( UInt uiScanPos = 0; uiScanPos < uiMaxNumCoeff; uiScanPos++ ) { #if QC_MDCS UInt uiBlkPos = g_auiSigLastScan[uiScanIdx][uiLog2BlockSize-1][uiScanPos]; #else UInt uiBlkPos = g_auiFrameScanXY[ uiLog2BlockSize-1 ][ uiScanPos ]; #endif //QC_MDCS uiPosLastY = uiBlkPos >> uiLog2BlockSize; uiPosLastX = uiBlkPos - ( uiPosLastY << uiLog2BlockSize ); if( pcCoef[ uiBlkPos ] != 0 ) { uiNumSig--; if( uiNumSig == 0 ) { codeLastSignificantXY(uiPosLastX, uiPosLastY, uiWidth, eTType, uiCTXIdx, uiScanIdx); uiScanPosLast = uiScanPos; break; } } } //===== code significance flag ===== { for( UInt uiScanPos = 0; uiScanPos < uiScanPosLast; uiScanPos++ ) { #if QC_MDCS UInt uiBlkPos = g_auiSigLastScan[uiScanIdx][uiLog2BlockSize-1][uiScanPos]; #else UInt uiBlkPos = g_auiFrameScanXY[ uiLog2BlockSize-1 ][ uiScanPos ]; #endif //QC_MDCS UInt uiPosY = uiBlkPos >> uiLog2BlockSize; UInt uiPosX = uiBlkPos - ( uiPosY << uiLog2BlockSize ); UInt uiSig = pcCoef[ uiBlkPos ] != 0 ? 1 : 0; UInt uiCtxSig = TComTrQuant::getSigCtxInc( pcCoef, uiPosX, uiPosY, uiLog2BlockSize, uiWidth ); #if SIMPLE_CONTEXT_SIG if( uiCtxSig < 4 || eTType) { m_pcBinIf->encodeBin( uiSig, m_cCUSigSCModel.get( uiCTXIdx-2, eTType, uiCtxSig ) ); } else { m_pcBinIf->encodeBin( uiSig, m_cCUSigSCModel.get( uiCTXIdx-2 ? uiCTXIdx-2 : 1, eTType, uiCtxSig ) ); } #else m_pcBinIf->encodeBin( uiSig, m_cCUSigSCModel.get( uiCTXIdx, eTType, uiCtxSig ) ); #endif } } #else for( UInt uiScanPos = 0; uiScanPos < uiMaxNumCoeffM1; uiScanPos++ ) { #if QC_MDCS UInt uiBlkPos = g_auiSigLastScan[uiScanIdx][uiLog2BlockSize-1][uiScanPos]; #else UInt uiBlkPos = g_auiFrameScanXY[ uiLog2BlockSize-1 ][ uiScanPos ]; #endif //QC_MDCS UInt uiPosY = uiBlkPos >> uiLog2BlockSize; UInt uiPosX = uiBlkPos - ( uiPosY << uiLog2BlockSize ); //===== code significance flag ===== UInt uiSig = pcCoef[ uiBlkPos ] != 0 ? 1 : 0; UInt uiCtxSig = TComTrQuant::getSigCtxInc( pcCoef, uiPosX, uiPosY, uiLog2BlockSize, uiWidth ); #if SIMPLE_CONTEXT_SIG if( uiCtxSig < 4 || eTType) { m_pcBinIf->encodeBin( uiSig, m_cCUSigSCModel.get( uiCTXIdx-2, eTType, uiCtxSig ) ); } else { m_pcBinIf->encodeBin( uiSig, m_cCUSigSCModel.get( uiCTXIdx-2 ? uiCTXIdx-2 : 1, eTType, uiCtxSig ) ); } #else m_pcBinIf->encodeBin( uiSig, m_cCUSigSCModel.get( uiCTXIdx, eTType, uiCtxSig ) ); #endif if( uiSig ) { uiNumSig--; //===== code last flag ===== UInt uiLast = ( uiNumSig == 0 ) ? 1 : 0; UInt uiCtxLast = TComTrQuant::getLastCtxInc( uiPosX, uiPosY, uiLog2BlockSize ); m_pcBinIf->encodeBin( uiLast, m_cCULastSCModel.get( uiCTXIdx, eTType, uiCtxLast ) ); if( uiLast ) { break; } } } #endif /* * Sign and bin0 PCP (Section 3.2 and 3.3 of JCTVC-B088) */ Int c1, c2; UInt uiSign; UInt uiAbs; #if E253 UInt uiGoRiceParam = 0; #endif if( uiNum4x4Blk > 1 ) { Bool b1stBlk = true; UInt uiNumOne = 0; for( UInt uiSubBlk = 0; uiSubBlk < uiNum4x4Blk; uiSubBlk++ ) { UInt uiCtxSet = 0; UInt uiSubNumSig = 0; UInt uiSubPosX = 0; UInt uiSubPosY = 0; #if E253 uiGoRiceParam = 0; #endif uiSubPosX = g_auiFrameScanX[ g_aucConvertToBit[ uiWidth ] - 1 ][ uiSubBlk ] << 2; uiSubPosY = g_auiFrameScanY[ g_aucConvertToBit[ uiWidth ] - 1 ][ uiSubBlk ] << 2; TCoeff* piCurr = &pcCoef[ uiSubPosX + uiSubPosY * uiWidth ]; for( UInt uiY = 0; uiY < 4; uiY++ ) { for( UInt uiX = 0; uiX < 4; uiX++ ) { if( piCurr[ uiX ] ) { uiSubNumSig++; } } piCurr += uiWidth; } if( uiSubNumSig > 0 ) { c1 = 1; c2 = 0; if( b1stBlk ) { b1stBlk = false; uiCtxSet = 5; } else { uiCtxSet = ( uiNumOne >> 2 ) + 1; uiNumOne = 0; } for( UInt uiScanPos = 0; uiScanPos < 16; uiScanPos++ ) { UInt uiBlkPos = g_auiFrameScanXY[ 1 ][ 15 - uiScanPos ]; UInt uiPosY = uiBlkPos >> 2; UInt uiPosX = uiBlkPos - ( uiPosY << 2 ); UInt uiIndex = ( ( uiSubPosY + uiPosY ) << uiLog2BlockSize ) + uiSubPosX + uiPosX; if( pcCoef[ uiIndex ] ) { if( pcCoef[ uiIndex ] > 0) { uiAbs = static_cast( pcCoef[ uiIndex ]); uiSign = 0; } else { uiAbs = static_cast(-pcCoef[ uiIndex ]); uiSign = 1; } UInt uiCtx = min(c1, 4); UInt uiSymbol = uiAbs > 1 ? 1 : 0; m_pcBinIf->encodeBin( uiSymbol, m_cCUOneSCModel.get( 0, eTType, ( uiCtxSet << 2 ) + uiCtxSet + uiCtx ) ); if( uiSymbol ) { c1 = 0; } else if( c1 ) { c1++; } } } for( UInt uiScanPos = 0; uiScanPos < 16; uiScanPos++ ) { UInt uiBlkPos = g_auiFrameScanXY[ 1 ][ 15 - uiScanPos ]; UInt uiPosY = uiBlkPos >> 2; UInt uiPosX = uiBlkPos - ( uiPosY << 2 ); UInt uiIndex = ( ( uiSubPosY + uiPosY ) << uiLog2BlockSize ) + uiSubPosX + uiPosX; if( pcCoef[ uiIndex ] ) { if( pcCoef[ uiIndex ] > 0) { uiAbs = static_cast( pcCoef[ uiIndex ]); uiSign = 0; } else { uiAbs = static_cast(-pcCoef[ uiIndex ]); uiSign = 1; } UInt uiSymbol = uiAbs > 1 ? 1 : 0; if( uiSymbol ) { UInt uiCtx = min(c2, 4); uiAbs -= 2; c2++; uiNumOne++; #if E253 uiSymbol = uiAbs > 0 ? 1 : 0; m_pcBinIf->encodeBin( uiSymbol, m_cCUAbsSCModel.get( 0, eTType, ( uiCtxSet << 2 ) + uiCtxSet + uiCtx ) ); if( uiSymbol ) { uiAbs -= 1; xWriteGoRiceExGolomb( uiAbs, uiGoRiceParam ); } #else xWriteExGolombLevel( uiAbs, m_cCUAbsSCModel.get( 0, eTType, ( uiCtxSet << 2 ) + uiCtxSet + uiCtx ) ); #endif } } } for( UInt uiScanPos = 0; uiScanPos < 16; uiScanPos++ ) { UInt uiBlkPos = g_auiFrameScanXY[ 1 ][ 15 - uiScanPos ]; UInt uiPosY = uiBlkPos >> 2; UInt uiPosX = uiBlkPos - ( uiPosY << 2 ); UInt uiIndex = ( ( uiSubPosY + uiPosY ) << uiLog2BlockSize ) + uiSubPosX + uiPosX; if( pcCoef[ uiIndex ] ) { if( pcCoef[ uiIndex ] > 0) { uiAbs = static_cast( pcCoef[ uiIndex ]); uiSign = 0; } else { uiAbs = static_cast(-pcCoef[ uiIndex ]); uiSign = 1; } m_pcBinIf->encodeBinEP( uiSign ); } } } } } else { c1 = 1; c2 = 0; for( UInt uiScanPos = 0; uiScanPos < 16; uiScanPos++ ) { UInt uiIndex = g_auiFrameScanXY[ 1 ][ 15 - uiScanPos ]; if( pcCoef[ uiIndex ] ) { if( pcCoef[ uiIndex ] > 0) { uiAbs = static_cast( pcCoef[ uiIndex ]); uiSign = 0; } else { uiAbs = static_cast(-pcCoef[ uiIndex ]); uiSign = 1; } UInt uiCtx = min(c1, 4); UInt uiSymbol = uiAbs > 1 ? 1 : 0; m_pcBinIf->encodeBin( uiSymbol, m_cCUOneSCModel.get( 0, eTType, uiCtx ) ); if( uiSymbol ) { c1 = 0; } else if( c1 ) { c1++; } } } for( UInt uiScanPos = 0; uiScanPos < 16; uiScanPos++ ) { UInt uiIndex = g_auiFrameScanXY[ 1 ][ 15 - uiScanPos ]; if( pcCoef[ uiIndex ] ) { if( pcCoef[ uiIndex ] > 0) { uiAbs = static_cast( pcCoef[ uiIndex ]); uiSign = 0; } else { uiAbs = static_cast(-pcCoef[ uiIndex ]); uiSign = 1; } UInt uiSymbol = uiAbs > 1 ? 1 : 0; if( uiSymbol ) { UInt uiCtx = min(c2, 4); uiAbs -= 2; c2++; #if E253 uiSymbol = uiAbs > 0 ? 1 : 0; m_pcBinIf->encodeBin( uiSymbol, m_cCUAbsSCModel.get( 0, eTType, uiCtx ) ); if( uiSymbol ) { uiAbs -= 1; xWriteGoRiceExGolomb( uiAbs, uiGoRiceParam ); } #else xWriteExGolombLevel( uiAbs, m_cCUAbsSCModel.get( 0, eTType, uiCtx ) ); #endif } } } for( UInt uiScanPos = 0; uiScanPos < 16; uiScanPos++ ) { UInt uiIndex = g_auiFrameScanXY[ 1 ][ 15 - uiScanPos ]; if( pcCoef[ uiIndex ] ) { if( pcCoef[ uiIndex ] > 0) { uiAbs = static_cast( pcCoef[ uiIndex ]); uiSign = 0; } else { uiAbs = static_cast(-pcCoef[ uiIndex ]); uiSign = 1; } m_pcBinIf->encodeBinEP( uiSign ); } } } return; } #if MVD_CTX /** Encode a motion vector difference * \param iMvd motion vector difference * \param uiAbsSumL motion vector difference of left PU * \param uiAbsSumA motion vector difference of above PU * \param uiCtx index for context set based on vertical or horizontal component */ Void TEncSbac::xWriteMvd( Int iMvd, UInt uiAbsSumL, UInt uiAbsSumA, UInt uiCtx ) #else Void TEncSbac::xWriteMvd( Int iMvd, UInt uiAbsSum, UInt uiCtx ) #endif { UInt uiLocalCtx = 0; #if MVD_CTX uiLocalCtx += (uiAbsSumA>16) ? 1 : 0; uiLocalCtx += (uiAbsSumL>16) ? 1 : 0; #else if ( uiAbsSum >= 3 ) { uiLocalCtx += ( uiAbsSum > 32 ) ? 2 : 1; } #endif UInt uiSymbol = ( 0 == iMvd ) ? 0 : 1; m_pcBinIf->encodeBin( uiSymbol, m_cCUMvdSCModel.get( 0, uiCtx, uiLocalCtx ) ); if ( 0 == uiSymbol ) { return; } UInt uiSign = 0; if ( 0 > iMvd ) { uiSign = 1; iMvd = -iMvd; } xWriteExGolombMvd( iMvd-1, &m_cCUMvdSCModel.get( 0, uiCtx, 3 ), 3 ); m_pcBinIf->encodeBinEP( uiSign ); return; } Void TEncSbac::xWriteExGolombMvd( UInt uiSymbol, ContextModel* pcSCModel, UInt uiMaxBin ) { if ( ! uiSymbol ) { m_pcBinIf->encodeBin( 0, *pcSCModel ); return; } m_pcBinIf->encodeBin( 1, *pcSCModel ); Bool bNoExGo = ( uiSymbol < 8 ); UInt uiCount = 1; pcSCModel++; while ( --uiSymbol && ++uiCount <= 8 ) { m_pcBinIf->encodeBin( 1, *pcSCModel ); if ( uiCount == 2 ) { pcSCModel++; } if ( uiCount == uiMaxBin ) { pcSCModel++; } } if ( bNoExGo ) { m_pcBinIf->encodeBin( 0, *pcSCModel ); } else { xWriteEpExGolomb( uiSymbol, 3 ); } return; } Void TEncSbac::codeAlfFlag ( UInt uiCode ) { UInt uiSymbol = ( ( uiCode == 0 ) ? 0 : 1 ); m_pcBinIf->encodeBin( uiSymbol, m_cALFFlagSCModel.get( 0, 0, 0 ) ); } #if TSB_ALF_HEADER Void TEncSbac::codeAlfFlagNum( UInt uiCode, UInt minValue ) { UInt uiLength = 0; UInt maxValue = (minValue << (this->getMaxAlfCtrlDepth()*2)); assert((uiCode>=minValue)&&(uiCode<=maxValue)); UInt temp = maxValue - minValue; for(UInt i=0; i<32; i++) { if(temp&0x1) { uiLength = i+1; } temp = (temp >> 1); } UInt uiSymbol = uiCode - minValue; if(uiLength) { while( uiLength-- ) { m_pcBinIf->encodeBinEP( (uiSymbol>>uiLength) & 0x1 ); } } } Void TEncSbac::codeAlfCtrlFlag( UInt uiSymbol ) { m_pcBinIf->encodeBin( uiSymbol, m_cCUAlfCtrlFlagSCModel.get( 0, 0, 0) ); } #endif Void TEncSbac::codeAlfUvlc ( UInt uiCode ) { Int i; if ( uiCode == 0 ) { m_pcBinIf->encodeBin( 0, m_cALFUvlcSCModel.get( 0, 0, 0 ) ); } else { m_pcBinIf->encodeBin( 1, m_cALFUvlcSCModel.get( 0, 0, 0 ) ); for ( i=0; iencodeBin( 1, m_cALFUvlcSCModel.get( 0, 0, 1 ) ); } m_pcBinIf->encodeBin( 0, m_cALFUvlcSCModel.get( 0, 0, 1 ) ); } } Void TEncSbac::codeAlfSvlc ( Int iCode ) { Int i; if ( iCode == 0 ) { m_pcBinIf->encodeBin( 0, m_cALFSvlcSCModel.get( 0, 0, 0 ) ); } else { m_pcBinIf->encodeBin( 1, m_cALFSvlcSCModel.get( 0, 0, 0 ) ); // write sign if ( iCode > 0 ) { m_pcBinIf->encodeBin( 0, m_cALFSvlcSCModel.get( 0, 0, 1 ) ); } else { m_pcBinIf->encodeBin( 1, m_cALFSvlcSCModel.get( 0, 0, 1 ) ); iCode = -iCode; } // write magnitude for ( i=0; iencodeBin( 1, m_cALFSvlcSCModel.get( 0, 0, 2 ) ); } m_pcBinIf->encodeBin( 0, m_cALFSvlcSCModel.get( 0, 0, 2 ) ); } } #if MTK_SAO Void TEncSbac::codeAoFlag ( UInt uiCode ) { UInt uiSymbol = ( ( uiCode == 0 ) ? 0 : 1 ); m_pcBinIf->encodeBin( uiSymbol, m_cAOFlagSCModel.get( 0, 0, 0 ) ); } Void TEncSbac::codeAoUvlc ( UInt uiCode ) { Int i; if ( uiCode == 0 ) { m_pcBinIf->encodeBin( 0, m_cAOUvlcSCModel.get( 0, 0, 0 ) ); } else { m_pcBinIf->encodeBin( 1, m_cAOUvlcSCModel.get( 0, 0, 0 ) ); for ( i=0; iencodeBin( 1, m_cAOUvlcSCModel.get( 0, 0, 1 ) ); } m_pcBinIf->encodeBin( 0, m_cAOUvlcSCModel.get( 0, 0, 1 ) ); } } Void TEncSbac::codeAoSvlc ( Int iCode ) { Int i; if ( iCode == 0 ) { m_pcBinIf->encodeBin( 0, m_cAOSvlcSCModel.get( 0, 0, 0 ) ); } else { m_pcBinIf->encodeBin( 1, m_cAOSvlcSCModel.get( 0, 0, 0 ) ); // write sign if ( iCode > 0 ) { m_pcBinIf->encodeBin( 0, m_cAOSvlcSCModel.get( 0, 0, 1 ) ); } else { m_pcBinIf->encodeBin( 1, m_cAOSvlcSCModel.get( 0, 0, 1 ) ); iCode = -iCode; } // write magnitude for ( i=0; iencodeBin( 1, m_cAOSvlcSCModel.get( 0, 0, 2 ) ); } m_pcBinIf->encodeBin( 0, m_cAOSvlcSCModel.get( 0, 0, 2 ) ); } } #endif /*! **************************************************************************** * \brief * estimate bit cost for CBP, significant map and significant coefficients **************************************************************************** */ Void TEncSbac::estBit( estBitsSbacStruct* pcEstBitsSbac, UInt uiCTXIdx, TextType eTType ) { estCBFBit( pcEstBitsSbac, 0, eTType ); // encode significance map estSignificantMapBit( pcEstBitsSbac, uiCTXIdx, eTType ); // encode significant coefficients estSignificantCoefficientsBit( pcEstBitsSbac, uiCTXIdx, eTType ); } /*! **************************************************************************** * \brief * estimate bit cost for each CBP bit **************************************************************************** */ Void TEncSbac::estCBFBit( estBitsSbacStruct* pcEstBitsSbac, UInt uiCTXIdx, TextType eTType ) { ContextModel *pCtx = m_cCUQtCbfSCModel.get( 0 ); for( UInt uiCtxInc = 0; uiCtxInc < 45; uiCtxInc++ ) { pcEstBitsSbac->blockCbpBits[ uiCtxInc ][ 0 ] = biari_no_bits( 0, pCtx[ uiCtxInc ] ); pcEstBitsSbac->blockCbpBits[ uiCtxInc ][ 1 ] = biari_no_bits( 1, pCtx[ uiCtxInc ] ); } for( UInt uiCtxInc = 0; uiCtxInc < 4; uiCtxInc++ ) { pcEstBitsSbac->blockRootCbpBits[ uiCtxInc ][ 0 ] = biari_no_bits( 0, m_cCUQtRootCbfSCModel.get( 0, 0, uiCtxInc ) ); pcEstBitsSbac->blockRootCbpBits[ uiCtxInc ][ 1 ] = biari_no_bits( 1, m_cCUQtRootCbfSCModel.get( 0, 0, uiCtxInc ) ); } } /*! **************************************************************************** * \brief * estimate SAMBAC bit cost for significant coefficient map **************************************************************************** */ Void TEncSbac::estSignificantMapBit( estBitsSbacStruct* pcEstBitsSbac, UInt uiCTXIdx, TextType eTType ) { for ( UInt uiCtx = 0; uiCtx < 16; uiCtx++ ) { for( UInt uiBin = 0; uiBin < 2; uiBin++ ) { #if SIMPLE_CONTEXT_SIG if( uiCtx < 4 || eTType ) { pcEstBitsSbac->significantBits[ uiCtx ][ uiBin ] = biari_no_bits ( uiBin, m_cCUSigSCModel.get( uiCTXIdx-2, eTType, uiCtx ) ); } else { pcEstBitsSbac->significantBits[ uiCtx ][ uiBin ] = biari_no_bits ( uiBin, m_cCUSigSCModel.get( uiCTXIdx-2 ? uiCTXIdx-2 : 1, eTType, uiCtx ) ); } #else pcEstBitsSbac->significantBits[ uiCtx ][ uiBin ] = biari_no_bits ( uiBin, m_cCUSigSCModel.get( uiCTXIdx, eTType, uiCtx ) ); #endif #if !PCP_SIGMAP_SIMPLE_LAST pcEstBitsSbac->lastBits[ uiCtx ][ uiBin ] = biari_no_bits ( uiBin, m_cCULastSCModel.get( uiCTXIdx, eTType, uiCtx ) ); #endif } } #if PCP_SIGMAP_SIMPLE_LAST Int iBitsX = 0, iBitsY = 0; const UInt uiCtxOffset = g_uiCtxXYOffset[uiCTXIdx]; const UInt uiWidthM1 = (1 << (7-uiCTXIdx)) - 1; for ( UInt uiCtx = 0; uiCtx < uiWidthM1; uiCtx++ ) { pcEstBitsSbac->lastXBits[uiCtx] = iBitsX + biari_no_bits (1, m_cCuCtxLastX.get( 0, eTType, uiCtxOffset + g_uiCtxXY[uiCtx] )); pcEstBitsSbac->lastYBits[uiCtx] = iBitsY + biari_no_bits (1, m_cCuCtxLastY.get( 0, eTType, uiCtxOffset + g_uiCtxXY[uiCtx] )); iBitsX += biari_no_bits (0, m_cCuCtxLastX.get( 0, eTType, uiCtxOffset + g_uiCtxXY[uiCtx] )); iBitsY += biari_no_bits (0, m_cCuCtxLastY.get( 0, eTType, uiCtxOffset + g_uiCtxXY[uiCtx] )); } pcEstBitsSbac->lastXBits[uiWidthM1] = iBitsX; pcEstBitsSbac->lastYBits[uiWidthM1] = iBitsY; #endif } /*! **************************************************************************** * \brief * estimate bit cost of significant coefficient **************************************************************************** */ Void TEncSbac::estSignificantCoefficientsBit( estBitsSbacStruct* pcEstBitsSbac, UInt uiCTXIdx, TextType eTType ) { for( UInt uiSet = 0; uiSet < 6; uiSet++ ) { for( UInt uiCtx = 0; uiCtx < 5; uiCtx++ ) { pcEstBitsSbac->greaterOneBits[ uiSet ][ 0 ][ uiCtx ][ 0 ] = biari_no_bits( 0, m_cCUOneSCModel.get( 0, eTType, ( uiSet << 2 ) + uiSet + uiCtx ) ); pcEstBitsSbac->greaterOneBits[ uiSet ][ 0 ][ uiCtx ][ 1 ] = biari_no_bits( 1, m_cCUOneSCModel.get( 0, eTType, ( uiSet << 2 ) + uiSet + uiCtx ) ); pcEstBitsSbac->greaterOneBits[ uiSet ][ 1 ][ uiCtx ][ 0 ] = biari_no_bits( 0, m_cCUAbsSCModel.get( 0, eTType, ( uiSet << 2 ) + uiSet + uiCtx ) ); pcEstBitsSbac->greaterOneBits[ uiSet ][ 1 ][ uiCtx ][ 1 ] = biari_no_bits( 1, m_cCUAbsSCModel.get( 0, eTType, ( uiSet << 2 ) + uiSet + uiCtx ) ); } } } Int TEncSbac::biari_no_bits( Short symbol, ContextModel& rcSCModel ) { UInt uiEstBits; Short ui16State; symbol = (Short)( symbol != 0 ); ui16State = symbol == rcSCModel.getMps() ? 64 + rcSCModel.getState() : 63 - rcSCModel.getState(); uiEstBits = entropyBits[ 127 - ui16State ]; return uiEstBits; }