/* 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-2012, ITU/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 ITU/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 TDecEntropy.cpp \brief entropy decoder class */ #include "TDecEntropy.h" //! \ingroup TLibDecoder //! \{ Void TDecEntropy::setEntropyDecoder ( TDecEntropyIf* p ) { m_pcEntropyDecoderIf = p; } #include "TLibCommon/TComAdaptiveLoopFilter.h" #include "TLibCommon/TComSampleAdaptiveOffset.h" Void TDecEntropy::decodeSkipFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { m_pcEntropyDecoderIf->parseSkipFlag( pcCU, uiAbsPartIdx, uiDepth ); } /** decode merge flag * \param pcSubCU * \param uiAbsPartIdx * \param uiDepth * \param uiPUIdx * \returns Void */ Void TDecEntropy::decodeMergeFlag( TComDataCU* pcSubCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPUIdx ) { // at least one merge candidate exists m_pcEntropyDecoderIf->parseMergeFlag( pcSubCU, uiAbsPartIdx, uiDepth, uiPUIdx ); } #if LGE_ILLUCOMP_B0045 Void TDecEntropy::decodeICFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { pcCU->setICFlagSubParts( false , uiAbsPartIdx, 0, uiDepth ); if (pcCU->isIntra(uiAbsPartIdx) || (pcCU->getSlice()->getViewId() == 0) || pcCU->getSlice()->getSPS()->isDepth()) { return; } if(!pcCU->getSlice()->getApplyIC()) return; if(pcCU->isICFlagRequired(uiAbsPartIdx)) m_pcEntropyDecoderIf->parseICFlag( pcCU, uiAbsPartIdx, uiDepth ); } #endif /** decode merge index * \param pcCU * \param uiPartIdx * \param uiAbsPartIdx * \param puhInterDirNeighbours pointer to list of inter direction from the casual neighbours * \param pcMvFieldNeighbours pointer to list of motion vector field from the casual neighbours * \param uiDepth * \returns Void */ Void TDecEntropy::decodeMergeIndex( TComDataCU* pcCU, UInt uiPartIdx, UInt uiAbsPartIdx, PartSize eCUMode, UChar* puhInterDirNeighbours, TComMvField* pcMvFieldNeighbours, UInt uiDepth ) { UInt uiMergeIndex = 0; m_pcEntropyDecoderIf->parseMergeIndex( pcCU, uiMergeIndex, uiAbsPartIdx, uiDepth ); pcCU->setMergeIndexSubParts( uiMergeIndex, uiAbsPartIdx, uiPartIdx, uiDepth ); } #if HHI_INTER_VIEW_RESIDUAL_PRED Void TDecEntropy::decodeResPredFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, TComDataCU* pcSubCU, UInt uiPUIdx ) { Bool bResPredAvailable = false; Bool bResPredFlag = false; Bool bResPredAllowed = (!pcCU->getSlice()->getSPS()->isDepth () ); bResPredAllowed = bResPredAllowed && ( pcCU->getSlice()->getSPS()->getViewId () ); bResPredAllowed = bResPredAllowed && ( pcCU->getSlice()->getSPS()->getMultiviewResPredMode() ); bResPredAllowed = bResPredAllowed && (!pcCU->isIntra ( uiAbsPartIdx ) ); // check if supported if( bResPredAllowed ) { bResPredAvailable = pcSubCU->getResidualSamples( uiPUIdx #if QC_SIMPLIFIEDIVRP_M24938 , false #endif ); } // read from bitstream if( bResPredAvailable ) { #if LG_RESTRICTEDRESPRED_M24766 Int iPUResiPredShift[4]; pcCU->getPUResiPredShift(iPUResiPredShift, uiAbsPartIdx); if(iPUResiPredShift[0] >= 0 || iPUResiPredShift[1] >= 0 || iPUResiPredShift[2] >= 0 || iPUResiPredShift[3] >= 0 ) #endif m_pcEntropyDecoderIf->parseResPredFlag( pcCU, bResPredFlag, uiAbsPartIdx, uiDepth ); } // set data pcCU->setResPredAvailSubParts ( bResPredAvailable, uiAbsPartIdx, uiPUIdx, uiDepth ); pcCU->setResPredFlagSubParts ( bResPredFlag, uiAbsPartIdx, uiPUIdx, uiDepth ); } #endif Void TDecEntropy::decodeSplitFlag ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { m_pcEntropyDecoderIf->parseSplitFlag( pcCU, uiAbsPartIdx, uiDepth ); } Void TDecEntropy::decodePredMode( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { m_pcEntropyDecoderIf->parsePredMode( pcCU, uiAbsPartIdx, uiDepth ); #if RWTH_SDC_DLT_B0036 // if B-Slice, code SDC flag later if( !pcCU->getSlice()->isInterB() && pcCU->isIntra(uiAbsPartIdx) && pcCU->getSlice()->getSPS()->isDepth() ) { // decode SDC flag decodeSDCFlag(pcCU, uiAbsPartIdx, uiDepth); } #endif } Void TDecEntropy::decodePartSize( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { #if RWTH_SDC_DLT_B0036 if( !pcCU->getSlice()->isInterB() && pcCU->isIntra(uiAbsPartIdx) && pcCU->getSDCFlag(uiAbsPartIdx) ) { pcCU->setPartSizeSubParts( SIZE_2Nx2N, uiAbsPartIdx, uiDepth ); pcCU->setSizeSubParts( g_uiMaxCUWidth>>uiDepth, g_uiMaxCUHeight>>uiDepth, uiAbsPartIdx, uiDepth ); return; } #endif m_pcEntropyDecoderIf->parsePartSize( pcCU, uiAbsPartIdx, uiDepth ); #if RWTH_SDC_DLT_B0036 if( pcCU->getSlice()->isInterB() && pcCU->getSlice()->getSPS()->isDepth() && pcCU->isIntra(uiAbsPartIdx) ) { // decode SDC flag decodeSDCFlag(pcCU, uiAbsPartIdx, uiDepth); if( pcCU->getSDCFlag(uiAbsPartIdx) ) { // part size is also known for SDC intra pcCU->setPartSizeSubParts( SIZE_2Nx2N, uiAbsPartIdx, uiDepth ); pcCU->setSizeSubParts( g_uiMaxCUWidth>>uiDepth, g_uiMaxCUHeight>>uiDepth, uiAbsPartIdx, uiDepth ); } } #endif } Void TDecEntropy::decodePredInfo ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, TComDataCU* pcSubCU ) { #if RWTH_SDC_DLT_B0036 if( pcCU->getSDCFlag(uiAbsPartIdx) ) { decodeSDCPredMode(pcCU, uiAbsPartIdx, uiDepth); return; } #endif PartSize eMode = pcCU->getPartitionSize( uiAbsPartIdx ); if( pcCU->isIntra( uiAbsPartIdx ) ) // If it is Intra mode, encode intra prediction mode. { if( eMode == SIZE_NxN ) // if it is NxN size, encode 4 intra directions. { UInt uiPartOffset = ( pcCU->getPic()->getNumPartInCU() >> ( pcCU->getDepth(uiAbsPartIdx) << 1 ) ) >> 2; // if it is NxN size, this size might be the smallest partition size. // if it is NxN size, this size might be the smallest partition size. decodeIntraDirModeLuma( pcCU, uiAbsPartIdx, uiDepth+1 ); decodeIntraDirModeLuma( pcCU, uiAbsPartIdx + uiPartOffset, uiDepth+1 ); decodeIntraDirModeLuma( pcCU, uiAbsPartIdx + uiPartOffset*2, uiDepth+1 ); decodeIntraDirModeLuma( pcCU, uiAbsPartIdx + uiPartOffset*3, uiDepth+1 ); decodeIntraDirModeChroma( pcCU, uiAbsPartIdx, uiDepth ); } else // if it is not NxN size, encode 1 intra directions { decodeIntraDirModeLuma ( pcCU, uiAbsPartIdx, uiDepth ); decodeIntraDirModeChroma( pcCU, uiAbsPartIdx, uiDepth ); } } else // if it is Inter mode, encode motion vector and reference index { decodePUWise( pcCU, uiAbsPartIdx, uiDepth, pcSubCU ); } } /** Parse I_PCM information. * \param pcCU pointer to CUpointer to CU * \param uiAbsPartIdx CU index * \param uiDepth CU depth * \returns Void */ Void TDecEntropy::decodeIPCMInfo( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { if(!pcCU->getSlice()->getSPS()->getUsePCM() || pcCU->getWidth(uiAbsPartIdx) > (1<getSlice()->getSPS()->getPCMLog2MaxSize()) || pcCU->getWidth(uiAbsPartIdx) < (1<getSlice()->getSPS()->getPCMLog2MinSize()) ) { return; } #if RWTH_SDC_DLT_B0036 if( pcCU->getSDCFlag(uiAbsPartIdx) ) { return; } #endif m_pcEntropyDecoderIf->parseIPCMInfo( pcCU, uiAbsPartIdx, uiDepth ); } Void TDecEntropy::decodeIntraDirModeLuma ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { m_pcEntropyDecoderIf->parseIntraDirLumaAng( pcCU, uiAbsPartIdx, uiDepth ); } Void TDecEntropy::decodeIntraDirModeChroma( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { m_pcEntropyDecoderIf->parseIntraDirChroma( pcCU, uiAbsPartIdx, uiDepth ); } /** decode motion information for every PU block. * \param pcCU * \param uiAbsPartIdx * \param uiDepth * \param pcSubCU * \returns Void */ Void TDecEntropy::decodePUWise( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, TComDataCU* pcSubCU ) { PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx ); UInt uiNumPU = ( ePartSize == SIZE_2Nx2N ? 1 : ( ePartSize == SIZE_NxN ? 4 : 2 ) ); UInt uiPUOffset = ( g_auiPUOffset[UInt( ePartSize )] << ( ( pcCU->getSlice()->getSPS()->getMaxCUDepth() - uiDepth ) << 1 ) ) >> 4; #if CU_BASED_MRG_CAND_LIST #if HHI_INTER_VIEW_MOTION_PRED TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS_MEM << 1]; // double length for mv of both lists UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS_MEM]; for ( UInt ui = 0; ui < MRG_MAX_NUM_CANDS_MEM; ui++ ) #else TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS]; for ( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ui++ ) #endif { uhInterDirNeighbours[ui] = 0; } Int numValidMergeCand = 0; bool isMerged = false; #endif pcSubCU->copyInterPredInfoFrom( pcCU, uiAbsPartIdx, REF_PIC_LIST_0 ); pcSubCU->copyInterPredInfoFrom( pcCU, uiAbsPartIdx, REF_PIC_LIST_1 ); for ( UInt uiPartIdx = 0, uiSubPartIdx = uiAbsPartIdx; uiPartIdx < uiNumPU; uiPartIdx++, uiSubPartIdx += uiPUOffset ) { #if !CU_BASED_MRG_CAND_LIST #if HHI_INTER_VIEW_MOTION_PRED TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS_MEM << 1]; // double length for mv of both lists UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS_MEM]; Int numValidMergeCand = 0; for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS_MEM; ++ui ) #else TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS]; Int numValidMergeCand = 0; for( UInt ui = 0; ui < MRG_MAX_NUM_CANDS; ++ui ) #endif { uhInterDirNeighbours[ui] = 0; } #endif decodeMergeFlag( pcCU, uiSubPartIdx, uiDepth, uiPartIdx ); if ( pcCU->getMergeFlag( uiSubPartIdx ) ) { decodeMergeIndex( pcCU, uiPartIdx, uiSubPartIdx, ePartSize, uhInterDirNeighbours, cMvFieldNeighbours, uiDepth ); #if CU_BASED_MRG_CAND_LIST UInt uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); if ( pcCU->getSlice()->getPPS()->getLog2ParallelMergeLevelMinus2() && ePartSize != SIZE_2Nx2N && pcSubCU->getWidth( 0 ) <= 8 ) { pcSubCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth ); if ( !isMerged ) { pcSubCU->getInterMergeCandidates( 0, 0, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand ); isMerged = true; } pcSubCU->setPartSizeSubParts( ePartSize, 0, uiDepth ); } else { #if SIMP_MRG_PRUN uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex ); #else pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand ); uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); #endif } #else #if SIMP_MRG_PRUN UInt uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand, uiMergeIndex ); #else pcSubCU->getInterMergeCandidates( uiSubPartIdx-uiAbsPartIdx, uiPartIdx, uiDepth, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand ); UInt uiMergeIndex = pcCU->getMergeIndex(uiSubPartIdx); #endif #endif pcCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeIndex], uiSubPartIdx, uiPartIdx, uiDepth ); TComMv cTmpMv( 0, 0 ); for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ ) { if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 ) { pcCU->setMVPIdxSubParts( 0, RefPicList( uiRefListIdx ), uiSubPartIdx, uiPartIdx, uiDepth); pcCU->setMVPNumSubParts( 0, RefPicList( uiRefListIdx ), uiSubPartIdx, uiPartIdx, uiDepth); pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->setAllMvd( cTmpMv, ePartSize, uiSubPartIdx, uiDepth, uiPartIdx ); pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->setAllMvField( cMvFieldNeighbours[ 2*uiMergeIndex + uiRefListIdx ], ePartSize, uiSubPartIdx, uiDepth, uiPartIdx ); } } } else { decodeInterDirPU( pcCU, uiSubPartIdx, uiDepth, uiPartIdx ); for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ ) { if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 ) { decodeRefFrmIdxPU( pcCU, uiSubPartIdx, uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) ); decodeMvdPU ( pcCU, uiSubPartIdx, uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) ); decodeMVPIdxPU ( pcSubCU, uiSubPartIdx-uiAbsPartIdx, uiDepth, uiPartIdx, RefPicList( uiRefListIdx ) ); } } } } return; } /** decode inter direction for a PU block * \param pcCU * \param uiAbsPartIdx * \param uiDepth * \param uiPartIdx * \returns Void */ Void TDecEntropy::decodeInterDirPU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx ) { UInt uiInterDir; if ( pcCU->getSlice()->isInterP() ) { uiInterDir = 1; } else { m_pcEntropyDecoderIf->parseInterDir( pcCU, uiInterDir, uiAbsPartIdx, uiDepth ); } pcCU->setInterDirSubParts( uiInterDir, uiAbsPartIdx, uiPartIdx, uiDepth ); } Void TDecEntropy::decodeRefFrmIdxPU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList ) { if(pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_C) > 0 && pcCU->getInterDir( uiAbsPartIdx ) != 3) { if(eRefList == REF_PIC_LIST_1) { return; } Int iRefFrmIdx = 0; Int iRefFrmIdxTemp; UInt uiInterDir; RefPicList eRefListTemp; PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx ); if ( pcCU->getSlice()->getNumRefIdx ( REF_PIC_LIST_C ) > 1 ) { m_pcEntropyDecoderIf->parseRefFrmIdx( pcCU, iRefFrmIdx, uiAbsPartIdx, uiDepth, REF_PIC_LIST_C ); } else { iRefFrmIdx=0; } uiInterDir = pcCU->getSlice()->getListIdFromIdxOfLC(iRefFrmIdx) + 1; iRefFrmIdxTemp = pcCU->getSlice()->getRefIdxFromIdxOfLC(iRefFrmIdx); eRefListTemp = (RefPicList)pcCU->getSlice()->getListIdFromIdxOfLC(iRefFrmIdx); pcCU->getCUMvField( eRefListTemp )->setAllRefIdx( iRefFrmIdxTemp, ePartSize, uiAbsPartIdx, uiDepth, uiPartIdx ); pcCU->setInterDirSubParts( uiInterDir, uiAbsPartIdx, uiPartIdx, uiDepth ); } else { Int iRefFrmIdx = 0; Int iParseRefFrmIdx = pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ); if ( pcCU->getSlice()->getNumRefIdx( eRefList ) > 1 && iParseRefFrmIdx ) { m_pcEntropyDecoderIf->parseRefFrmIdx( pcCU, iRefFrmIdx, uiAbsPartIdx, uiDepth, eRefList ); } else if ( !iParseRefFrmIdx ) { iRefFrmIdx = NOT_VALID; } else { iRefFrmIdx = 0; } PartSize ePartSize = pcCU->getPartitionSize( uiAbsPartIdx ); pcCU->getCUMvField( eRefList )->setAllRefIdx( iRefFrmIdx, ePartSize, uiAbsPartIdx, uiDepth, uiPartIdx ); } } /** decode motion vector difference for a PU block * \param pcCU * \param uiAbsPartIdx * \param uiDepth * \param uiPartIdx * \param eRefList * \returns Void */ Void TDecEntropy::decodeMvdPU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList ) { if ( pcCU->getInterDir( uiAbsPartIdx ) & ( 1 << eRefList ) ) { m_pcEntropyDecoderIf->parseMvd( pcCU, uiAbsPartIdx, uiPartIdx, uiDepth, eRefList ); } } Void TDecEntropy::decodeMVPIdxPU( TComDataCU* pcSubCU, UInt uiPartAddr, UInt uiDepth, UInt uiPartIdx, RefPicList eRefList ) { Int iMVPIdx = -1; TComMv cZeroMv( 0, 0 ); TComMv cMv = cZeroMv; Int iRefIdx = -1; TComCUMvField* pcSubCUMvField = pcSubCU->getCUMvField( eRefList ); AMVPInfo* pAMVPInfo = pcSubCUMvField->getAMVPInfo(); iRefIdx = pcSubCUMvField->getRefIdx(uiPartAddr); cMv = cZeroMv; if ( (pcSubCU->getInterDir(uiPartAddr) & ( 1 << eRefList )) && (pcSubCU->getAMVPMode(uiPartAddr) == AM_EXPL) ) { #if HHI_INTER_VIEW_MOTION_PRED const Int iNumAMVPCands = AMVP_MAX_NUM_CANDS + ( pcSubCU->getSlice()->getSPS()->getMultiviewMvPredMode() ? 1 : 0 ); m_pcEntropyDecoderIf->parseMVPIdx( iMVPIdx, iNumAMVPCands ); #else m_pcEntropyDecoderIf->parseMVPIdx( iMVPIdx ); #endif } #if SHARP_INTERVIEW_DECOUPLE_B0111 pcSubCU->fillMvpCand(uiPartIdx, uiPartAddr, eRefList, iRefIdx, pAMVPInfo, iMVPIdx); #else pcSubCU->fillMvpCand(uiPartIdx, uiPartAddr, eRefList, iRefIdx, pAMVPInfo); #endif pcSubCU->setMVPNumSubParts(pAMVPInfo->iN, eRefList, uiPartAddr, uiPartIdx, uiDepth); pcSubCU->setMVPIdxSubParts( iMVPIdx, eRefList, uiPartAddr, uiPartIdx, uiDepth ); if ( iRefIdx >= 0 ) { m_pcPrediction->getMvPredAMVP( pcSubCU, uiPartIdx, uiPartAddr, eRefList, iRefIdx, cMv); cMv += pcSubCUMvField->getMvd( uiPartAddr ); } PartSize ePartSize = pcSubCU->getPartitionSize( uiPartAddr ); pcSubCU->getCUMvField( eRefList )->setAllMv(cMv, ePartSize, uiPartAddr, 0, uiPartIdx); } #if UNIFIED_TRANSFORM_TREE Void TDecEntropy::xDecodeTransform( TComDataCU* pcCU, UInt offsetLuma, UInt offsetChroma, UInt uiAbsPartIdx, UInt absTUPartIdx, UInt uiDepth, UInt width, UInt height, UInt uiTrIdx, UInt uiInnerQuadIdx, UInt& uiYCbfFront3, UInt& uiUCbfFront3, UInt& uiVCbfFront3, Bool& bCodeDQP ) #else Void TDecEntropy::xDecodeTransformSubdiv( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt absTUPartIdx, UInt uiDepth, UInt uiInnerQuadIdx, UInt& uiYCbfFront3, UInt& uiUCbfFront3, UInt& uiVCbfFront3 ) #endif { UInt uiSubdiv; const UInt uiLog2TrafoSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()]+2 - uiDepth; #if UNIFIED_TRANSFORM_TREE if(uiTrIdx==0) { m_bakAbsPartIdxCU = uiAbsPartIdx; } if( uiLog2TrafoSize == 2 ) { UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 ); if( ( uiAbsPartIdx % partNum ) == 0 ) { m_uiBakAbsPartIdx = uiAbsPartIdx; m_uiBakChromaOffset = offsetChroma; } } #endif // UNIFIED_TRANSFORM_TREE if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTRA && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_NxN && uiDepth == pcCU->getDepth(uiAbsPartIdx) ) { uiSubdiv = 1; } #if G519_TU_AMP_NSQT_HARMONIZATION else if( (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) && (pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER) && ( pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N ) && (uiDepth == pcCU->getDepth(uiAbsPartIdx)) ) #else else if( (pcCU->getSlice()->getSPS()->getQuadtreeTUMaxDepthInter() == 1) && (pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER) && ( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2NxN || pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_Nx2N) && (uiDepth == pcCU->getDepth(uiAbsPartIdx)) ) #endif { uiSubdiv = (uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx)); } else if( uiLog2TrafoSize > pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() ) { uiSubdiv = 1; } else if( uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MinSize() ) { uiSubdiv = 0; } else if( uiLog2TrafoSize == pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ) { uiSubdiv = 0; } else { assert( uiLog2TrafoSize > pcCU->getQuadtreeTULog2MinSizeInCU(uiAbsPartIdx) ); m_pcEntropyDecoderIf->parseTransformSubdivFlag( uiSubdiv, uiDepth ); } const UInt uiTrDepth = uiDepth - pcCU->getDepth( uiAbsPartIdx ); if( uiLog2TrafoSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() ) { const Bool bFirstCbfOfCU = uiLog2TrafoSize == pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() || uiTrDepth == 0; if( bFirstCbfOfCU ) { pcCU->setCbfSubParts( 0, TEXT_CHROMA_U, uiAbsPartIdx, uiDepth ); pcCU->setCbfSubParts( 0, TEXT_CHROMA_V, uiAbsPartIdx, uiDepth ); } if( bFirstCbfOfCU || uiLog2TrafoSize > 2 ) { if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth - 1 ) ) { if ( uiInnerQuadIdx == 3 && uiUCbfFront3 == 0 && uiLog2TrafoSize < pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() ) { uiUCbfFront3++; pcCU->setCbfSubParts( 1 << uiTrDepth, TEXT_CHROMA_U, uiAbsPartIdx, uiDepth ); //printf( " \nsave bits, U Cbf"); } else { m_pcEntropyDecoderIf->parseQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth, uiDepth ); uiUCbfFront3 += pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth ); } } if( bFirstCbfOfCU || pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth - 1 ) ) { if ( uiInnerQuadIdx == 3 && uiVCbfFront3 == 0 && uiLog2TrafoSize < pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() ) { uiVCbfFront3++; pcCU->setCbfSubParts( 1 << uiTrDepth, TEXT_CHROMA_V, uiAbsPartIdx, uiDepth ); //printf( " \nsave bits, V Cbf"); } else { m_pcEntropyDecoderIf->parseQtCbf( pcCU, uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth, uiDepth ); uiVCbfFront3 += pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth ); } } } else { pcCU->setCbfSubParts( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth - 1 ) << uiTrDepth, TEXT_CHROMA_U, uiAbsPartIdx, uiDepth ); pcCU->setCbfSubParts( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth - 1 ) << uiTrDepth, TEXT_CHROMA_V, uiAbsPartIdx, uiDepth ); if ( uiLog2TrafoSize == 2 ) { uiUCbfFront3 += pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrDepth ); uiVCbfFront3 += pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrDepth ); } } } if( uiSubdiv ) { #if UNIFIED_TRANSFORM_TREE UInt size; width >>= 1; height >>= 1; size = width*height; uiTrIdx++; #endif ++uiDepth; const UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1); const UInt uiStartAbsPartIdx = uiAbsPartIdx; UInt uiLumaTrMode, uiChromaTrMode; pcCU->convertTransIdx( uiStartAbsPartIdx, uiTrDepth+1, uiLumaTrMode, uiChromaTrMode ); UInt uiYCbf = 0; UInt uiUCbf = 0; UInt uiVCbf = 0; UInt uiCurrentCbfY = 0; UInt uiCurrentCbfU = 0; UInt uiCurrentCbfV = 0; for( Int i = 0; i < 4; i++ ) { #if UNIFIED_TRANSFORM_TREE UInt nsAddr = 0; nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrafoSize-1, uiAbsPartIdx, absTUPartIdx, i, uiTrDepth+1 ); xDecodeTransform( pcCU, offsetLuma, offsetChroma, uiAbsPartIdx, nsAddr, uiDepth, width, height, uiTrIdx, i, uiCurrentCbfY, uiCurrentCbfU, uiCurrentCbfV, bCodeDQP ); #else UInt nsAddr = 0; nsAddr = pcCU->getNSAbsPartIdx( uiLog2TrafoSize-1, uiAbsPartIdx, absTUPartIdx, i, uiTrDepth+1 ); xDecodeTransformSubdiv( pcCU, uiAbsPartIdx, nsAddr, uiDepth, i, uiCurrentCbfY, uiCurrentCbfU, uiCurrentCbfV ); #endif uiYCbf |= pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiLumaTrMode ); uiUCbf |= pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiChromaTrMode ); uiVCbf |= pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiChromaTrMode ); uiAbsPartIdx += uiQPartNum; #if UNIFIED_TRANSFORM_TREE offsetLuma += size; offsetChroma += (size>>2); #endif } uiYCbfFront3 += uiCurrentCbfY; uiUCbfFront3 += uiCurrentCbfU; uiVCbfFront3 += uiCurrentCbfV; pcCU->convertTransIdx( uiStartAbsPartIdx, uiTrDepth, uiLumaTrMode, uiChromaTrMode ); for( UInt ui = 0; ui < 4 * uiQPartNum; ++ui ) { pcCU->getCbf( TEXT_LUMA )[uiStartAbsPartIdx + ui] |= uiYCbf << uiLumaTrMode; pcCU->getCbf( TEXT_CHROMA_U )[uiStartAbsPartIdx + ui] |= uiUCbf << uiChromaTrMode; pcCU->getCbf( TEXT_CHROMA_V )[uiStartAbsPartIdx + ui] |= uiVCbf << uiChromaTrMode; } } else { assert( uiDepth >= pcCU->getDepth( uiAbsPartIdx ) ); pcCU->setTrIdxSubParts( uiTrDepth, uiAbsPartIdx, uiDepth ); { DTRACE_CABAC_VL( g_nSymbolCounter++ ); DTRACE_CABAC_T( "\tTrIdx: abspart=" ); DTRACE_CABAC_V( uiAbsPartIdx ); DTRACE_CABAC_T( "\tdepth=" ); DTRACE_CABAC_V( uiDepth ); DTRACE_CABAC_T( "\ttrdepth=" ); DTRACE_CABAC_V( uiTrDepth ); DTRACE_CABAC_T( "\n" ); } UInt uiLumaTrMode, uiChromaTrMode; pcCU->convertTransIdx( uiAbsPartIdx, uiTrDepth, uiLumaTrMode, uiChromaTrMode ); if(pcCU->getPredictionMode( uiAbsPartIdx ) == MODE_INTER && pcCU->useNonSquarePU( uiAbsPartIdx ) ) { pcCU->setNSQTIdxSubParts( uiLog2TrafoSize, uiAbsPartIdx, absTUPartIdx, uiLumaTrMode ); } pcCU->setCbfSubParts ( 0, TEXT_LUMA, uiAbsPartIdx, uiDepth ); if( pcCU->getPredictionMode(uiAbsPartIdx) != MODE_INTRA && uiDepth == pcCU->getDepth( uiAbsPartIdx ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, 0 ) && !pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, 0 ) ) { pcCU->setCbfSubParts( 1 << uiLumaTrMode, TEXT_LUMA, uiAbsPartIdx, uiDepth ); } else { const UInt uiLog2CUSize = g_aucConvertToBit[pcCU->getSlice()->getSPS()->getMaxCUWidth()] + 2 - pcCU->getDepth( uiAbsPartIdx ); if ( pcCU->getPredictionMode( uiAbsPartIdx ) != MODE_INTRA && uiInnerQuadIdx == 3 && uiYCbfFront3 == 0 && uiUCbfFront3 == 0 && uiVCbfFront3 == 0 && ( uiLog2CUSize <= pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() + 1 || uiLog2TrafoSize < pcCU->getSlice()->getSPS()->getQuadtreeTULog2MaxSize() ) ) { pcCU->setCbfSubParts( 1 << uiLumaTrMode, TEXT_LUMA, uiAbsPartIdx, uiDepth ); //printf( " \nsave bits, Y Cbf"); uiYCbfFront3++; } else { m_pcEntropyDecoderIf->parseQtCbf( pcCU, uiAbsPartIdx, TEXT_LUMA, uiLumaTrMode, uiDepth ); uiYCbfFront3 += pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiLumaTrMode ); } } #if UNIFIED_TRANSFORM_TREE // transform_unit begin UInt cbfY = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA , uiTrIdx ); UInt cbfU = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrIdx ); UInt cbfV = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrIdx ); if( uiLog2TrafoSize == 2 ) { UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 ); if( ( uiAbsPartIdx % partNum ) == (partNum - 1) ) { cbfU = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_U, uiTrIdx ); cbfV = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_V, uiTrIdx ); } } if ( cbfY || cbfU || cbfV ) { // dQP: only for LCU if ( pcCU->getSlice()->getPPS()->getUseDQP() ) { if ( bCodeDQP ) { decodeQP( pcCU, m_bakAbsPartIdxCU); bCodeDQP = false; } } } if( cbfY ) { Int trWidth = width; Int trHeight = height; pcCU->getNSQTSize( uiTrIdx, uiAbsPartIdx, trWidth, trHeight ); m_pcEntropyDecoderIf->parseCoeffNxN( pcCU, (pcCU->getCoeffY()+offsetLuma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_LUMA ); } if( uiLog2TrafoSize > 2 ) { Int trWidth = width >> 1; Int trHeight = height >> 1; pcCU->getNSQTSize( uiTrIdx, uiAbsPartIdx, trWidth, trHeight ); if( cbfU ) { m_pcEntropyDecoderIf->parseCoeffNxN( pcCU, (pcCU->getCoeffCb()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U ); } if( cbfV ) { m_pcEntropyDecoderIf->parseCoeffNxN( pcCU, (pcCU->getCoeffCr()+offsetChroma), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V ); } } else { UInt partNum = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 ); if( ( uiAbsPartIdx % partNum ) == (partNum - 1) ) { Int trWidth = width; Int trHeight = height; pcCU->getNSQTSize( uiTrIdx - 1, uiAbsPartIdx, trWidth, trHeight ); if( cbfU ) { m_pcEntropyDecoderIf->parseCoeffNxN( pcCU, (pcCU->getCoeffCb()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U ); } if( cbfV ) { m_pcEntropyDecoderIf->parseCoeffNxN( pcCU, (pcCU->getCoeffCr()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V ); } } } // transform_unit end #endif // UNIFIED_TRANSFORM_TREE } } #if !UNIFIED_TRANSFORM_TREE Void TDecEntropy::decodeTransformIdx( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { DTRACE_CABAC_VL( g_nSymbolCounter++ ) DTRACE_CABAC_T( "\tdecodeTransformIdx()\tCUDepth=" ) DTRACE_CABAC_V( uiDepth ) DTRACE_CABAC_T( "\n" ) UInt temp = 0; UInt temp1 = 0; UInt temp2 = 0; xDecodeTransformSubdiv( pcCU, uiAbsPartIdx, uiAbsPartIdx, uiDepth, 0, temp, temp1, temp2 ); } #endif // UNIFIED_TRANSFORM_TREE #if UNIFIED_TRANSFORM_TREE Void TDecEntropy::decodeQP ( TComDataCU* pcCU, UInt uiAbsPartIdx ) { if ( pcCU->getSlice()->getPPS()->getUseDQP() ) { m_pcEntropyDecoderIf->parseDeltaQP( pcCU, uiAbsPartIdx, pcCU->getDepth( uiAbsPartIdx ) ); } } #else Void TDecEntropy::decodeQP ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { if ( pcCU->getSlice()->getPPS()->getUseDQP() ) { m_pcEntropyDecoderIf->parseDeltaQP( pcCU, uiAbsPartIdx, uiDepth ); } } #endif #if !UNIFIED_TRANSFORM_TREE Void TDecEntropy::xDecodeCoeff( TComDataCU* pcCU, UInt uiLumaOffset, UInt uiChromaOffset, UInt uiAbsPartIdx, UInt uiDepth, UInt uiWidth, UInt uiHeight, UInt uiTrIdx, UInt uiCurrTrIdx, Bool& bCodeDQP ) { UInt uiLog2TrSize = g_aucConvertToBit[ pcCU->getSlice()->getSPS()->getMaxCUWidth() >> uiDepth ] + 2; UInt uiCbfY = pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiTrIdx ); UInt uiCbfU = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrIdx ); UInt uiCbfV = pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrIdx ); if( uiLog2TrSize == 2 ) { UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 ); if( ( uiAbsPartIdx % uiQPDiv ) == 0 ) { m_uiBakAbsPartIdx = uiAbsPartIdx; m_uiBakChromaOffset = uiChromaOffset; } else if( ( uiAbsPartIdx % uiQPDiv ) == (uiQPDiv - 1) ) { uiCbfU = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_U, uiTrIdx ); uiCbfV = pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_V, uiTrIdx ); } } if ( uiCbfY || uiCbfU || uiCbfV ) { // dQP: only for LCU if ( pcCU->getSlice()->getPPS()->getUseDQP() ) { if ( bCodeDQP ) { decodeQP( pcCU, uiAbsPartIdx, uiDepth); bCodeDQP = false; } } UInt uiLumaTrMode, uiChromaTrMode; pcCU->convertTransIdx( uiAbsPartIdx, pcCU->getTransformIdx( uiAbsPartIdx ), uiLumaTrMode, uiChromaTrMode ); const UInt uiStopTrMode = uiLumaTrMode; if( uiTrIdx == uiStopTrMode ) { if( pcCU->getCbf( uiAbsPartIdx, TEXT_LUMA, uiTrIdx ) ) { Int trWidth = uiWidth; Int trHeight = uiHeight; pcCU->getNSQTSize( uiTrIdx, uiAbsPartIdx, trWidth, trHeight ); m_pcEntropyDecoderIf->parseCoeffNxN( pcCU, (pcCU->getCoeffY()+uiLumaOffset), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_LUMA ); } uiWidth >>= 1; uiHeight >>= 1; if( uiLog2TrSize == 2 ) { UInt uiQPDiv = pcCU->getPic()->getNumPartInCU() >> ( ( uiDepth - 1 ) << 1 ); if( ( uiAbsPartIdx % uiQPDiv ) == (uiQPDiv - 1) ) { uiWidth <<= 1; uiHeight <<= 1; Int trWidth = uiWidth; Int trHeight = uiHeight; pcCU->getNSQTSize( uiTrIdx-1, uiAbsPartIdx, trWidth, trHeight ); if( pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_U, uiTrIdx ) ) { m_pcEntropyDecoderIf->parseCoeffNxN( pcCU, (pcCU->getCoeffCb()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U ); } if( pcCU->getCbf( m_uiBakAbsPartIdx, TEXT_CHROMA_V, uiTrIdx ) ) { m_pcEntropyDecoderIf->parseCoeffNxN( pcCU, (pcCU->getCoeffCr()+m_uiBakChromaOffset), m_uiBakAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V ); } } } else { Int trWidth = uiWidth; Int trHeight = uiHeight; pcCU->getNSQTSize( uiTrIdx, uiAbsPartIdx, trWidth, trHeight ); if( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_U, uiTrIdx ) ) { m_pcEntropyDecoderIf->parseCoeffNxN( pcCU, (pcCU->getCoeffCb()+uiChromaOffset), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_U ); } if( pcCU->getCbf( uiAbsPartIdx, TEXT_CHROMA_V, uiTrIdx ) ) { m_pcEntropyDecoderIf->parseCoeffNxN( pcCU, (pcCU->getCoeffCr()+uiChromaOffset), uiAbsPartIdx, trWidth, trHeight, uiDepth, TEXT_CHROMA_V ); } } } else { { DTRACE_CABAC_VL( g_nSymbolCounter++ ); DTRACE_CABAC_T( "\tgoing down\tdepth=" ); DTRACE_CABAC_V( uiDepth ); DTRACE_CABAC_T( "\ttridx=" ); DTRACE_CABAC_V( uiTrIdx ); DTRACE_CABAC_T( "\n" ); } if( uiCurrTrIdx <= uiTrIdx ) { assert(1); } UInt uiSize; uiWidth >>= 1; uiHeight >>= 1; uiSize = uiWidth*uiHeight; uiDepth++; uiTrIdx++; UInt uiQPartNum = pcCU->getPic()->getNumPartInCU() >> (uiDepth << 1); UInt uiIdx = uiAbsPartIdx; xDecodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiIdx, uiDepth, uiWidth, uiHeight, uiTrIdx, uiCurrTrIdx, bCodeDQP ); uiLumaOffset += uiSize; uiChromaOffset += (uiSize>>2); uiIdx += uiQPartNum; xDecodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiIdx, uiDepth, uiWidth, uiHeight, uiTrIdx, uiCurrTrIdx, bCodeDQP ); uiLumaOffset += uiSize; uiChromaOffset += (uiSize>>2); uiIdx += uiQPartNum; xDecodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiIdx, uiDepth, uiWidth, uiHeight, uiTrIdx, uiCurrTrIdx, bCodeDQP ); uiLumaOffset += uiSize; uiChromaOffset += (uiSize>>2); uiIdx += uiQPartNum; xDecodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiIdx, uiDepth, uiWidth, uiHeight, uiTrIdx, uiCurrTrIdx, bCodeDQP ); { DTRACE_CABAC_VL( g_nSymbolCounter++ ); DTRACE_CABAC_T( "\tgoing up\n" ); } } } } #endif // !UNIFIED_TRANSFORM_TREE /** decode coefficients * \param pcCU * \param uiAbsPartIdx * \param uiDepth * \param uiWidth * \param uiHeight * \returns Void */ Void TDecEntropy::decodeCoeff( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiWidth, UInt uiHeight, Bool& bCodeDQP ) { UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight(); UInt uiLumaOffset = uiMinCoeffSize*uiAbsPartIdx; UInt uiChromaOffset = uiLumaOffset>>2; #if UNIFIED_TRANSFORM_TREE UInt temp = 0; UInt temp1 = 0; UInt temp2 = 0; #else UInt uiLumaTrMode, uiChromaTrMode; #endif #if RWTH_SDC_DLT_B0036 if( pcCU->getSDCAvailable(uiAbsPartIdx) && pcCU->getSDCFlag( uiAbsPartIdx ) ) { assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ); assert( pcCU->getTransformIdx(uiAbsPartIdx) == 0 ); assert( pcCU->getCbf(uiAbsPartIdx, TEXT_LUMA) == 1 ); assert( pcCU->getCbf(uiAbsPartIdx, TEXT_CHROMA_U) == 1 ); assert( pcCU->getCbf(uiAbsPartIdx, TEXT_CHROMA_V) == 1 ); decodeSDCResidualData(pcCU, uiAbsPartIdx, uiDepth); return; } #endif if( pcCU->isIntra(uiAbsPartIdx) ) { #if !UNIFIED_TRANSFORM_TREE decodeTransformIdx( pcCU, uiAbsPartIdx, pcCU->getDepth(uiAbsPartIdx) ); pcCU->convertTransIdx( uiAbsPartIdx, pcCU->getTransformIdx(uiAbsPartIdx), uiLumaTrMode, uiChromaTrMode ); #endif // !UNIFIED_TRANSFORM_TREE } else { UInt uiQtRootCbf = 1; #if HHI_MPI if( !(pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N && ( pcCU->getTextureModeDepth( uiAbsPartIdx ) == -1 || uiDepth == pcCU->getTextureModeDepth( uiAbsPartIdx ) ) ) ) #else if( !( pcCU->getPartitionSize( uiAbsPartIdx) == SIZE_2Nx2N && pcCU->getMergeFlag( uiAbsPartIdx ) ) ) #endif { m_pcEntropyDecoderIf->parseQtRootCbf( pcCU, uiAbsPartIdx, uiDepth, uiQtRootCbf ); } if ( !uiQtRootCbf ) { pcCU->setCbfSubParts( 0, 0, 0, uiAbsPartIdx, uiDepth ); pcCU->setTrIdxSubParts( 0 , uiAbsPartIdx, uiDepth ); pcCU->setNSQTIdxSubParts( uiAbsPartIdx, uiDepth ); return; } #if !UNIFIED_TRANSFORM_TREE decodeTransformIdx( pcCU, uiAbsPartIdx, pcCU->getDepth(uiAbsPartIdx) ); pcCU->convertTransIdx( uiAbsPartIdx, pcCU->getTransformIdx(uiAbsPartIdx), uiLumaTrMode, uiChromaTrMode ); #endif // !UNIFIED_TRANSFORM_TREE } #if FIX_MPI_B0065 if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getMergeIndex( uiAbsPartIdx ) == 0 && pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N && pcCU->getTextureModeDepth( uiAbsPartIdx ) != -1 ) { TComDataCU *pcTextureCU = pcCU->getSlice()->getTexturePic()->getCU( pcCU->getAddr() ); if( uiDepth == pcTextureCU->getDepth(uiAbsPartIdx)) { PartSize partSize = pcTextureCU->getPartitionSize(uiAbsPartIdx); pcCU->setPartSizeSubParts( partSize, uiAbsPartIdx, uiDepth ); } else { pcCU->setPartSizeSubParts( SIZE_NxN, uiAbsPartIdx, uiDepth ); } } #endif #if UNIFIED_TRANSFORM_TREE xDecodeTransform( pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, 0, temp, temp1, temp2, bCodeDQP ); #else // UNIFIED_TRANSFORM_TREE xDecodeCoeff( pcCU, uiLumaOffset, uiChromaOffset, uiAbsPartIdx, uiDepth, uiWidth, uiHeight, 0, uiLumaTrMode, bCodeDQP ); #endif // UNIFIED_TRANSFORM_TREE #if FIX_MPI_B0065 if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTER && pcCU->getMergeFlag( uiAbsPartIdx ) && pcCU->getMergeIndex( uiAbsPartIdx ) == 0 && pcCU->getPartitionSize(uiAbsPartIdx) != SIZE_2Nx2N && pcCU->getTextureModeDepth( uiAbsPartIdx ) != -1 ) { pcCU->setPartSizeSubParts( SIZE_2Nx2N, uiAbsPartIdx, uiDepth ); } #endif } #if RWTH_SDC_DLT_B0036 Void TDecEntropy::decodeSDCPredMode( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { assert( pcCU->getSlice()->getSPS()->isDepth() ); assert( pcCU->getPartitionSize(uiAbsPartIdx) == SIZE_2Nx2N ); m_pcEntropyDecoderIf->parseSDCPredMode(pcCU, uiAbsPartIdx, uiDepth ); } Void TDecEntropy::decodeSDCFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { assert( pcCU->getSlice()->getSPS()->isDepth() ); m_pcEntropyDecoderIf->parseSDCFlag(pcCU, uiAbsPartIdx, uiDepth ); } Void TDecEntropy::decodeSDCResidualData( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) { assert( pcCU->getSlice()->getSPS()->isDepth() ); assert( pcCU->getSDCFlag(uiAbsPartIdx) ); // number of segments depends on prediction mode for INTRA UInt uiNumSegments = 2; UInt uiLumaPredMode = pcCU->getLumaIntraDir( uiAbsPartIdx ); if( pcCU->getPredictionMode(uiAbsPartIdx) == MODE_INTRA && (uiLumaPredMode == DC_IDX || uiLumaPredMode == PLANAR_IDX) ) uiNumSegments = 1; // decode residual data for each segment for( UInt uiSeg = 0; uiSeg < uiNumSegments; uiSeg++ ) m_pcEntropyDecoderIf->parseSDCResidualData(pcCU, uiAbsPartIdx, uiDepth, uiSeg); } #endif //! \}