之前 HEVC代码学习39:decodeCtu和xDecodeCU函数 中对HM中的CTU解码函数进行了学习,这里来学习一下JEM中的。

首先需要强调的是,这里只是用来解码flag、系数等,没有进行预测重构。

decodeCtu

该函数是解码CTU的入口函数,代码比较简单。

JEM中与HM主要区别:
在JEM中,会对帧内模式的亮度和色度分量分别编码,因此解码时会首先对帧内模式的亮度CTU解码,然后对色度CTU解码。

流程如下:
1.为亮度设置QP,调用xDecodeCU解码亮度CTU。
2.为色度设置QP,调用xDecodeCU解码色度CTU。

代码分析:

/** Parse a CTU.\param    pCtu                      [in/out] pointer to CTU data structure\param    isLastCtuOfSliceSegment   [out]    true, if last CTU of the slice segment*/
//解码CTU
Void TDecCu::decodeCtu( TComDataCU* pCtu, Bool& isLastCtuOfSliceSegment )
{//亮度
#if JVET_C0024_QTBTpCtu->getSlice()->setTextType(CHANNEL_TYPE_LUMA);
#endifif ( pCtu->getSlice()->getPPS()->getUseDQP() ){setdQPFlag(true);
#if JVET_C0024_DELTA_QP_FIX // init current quantization unit info.Char qp = pCtu->getCtuLastCodedQP();pCtu->setQuPartIdx(0); pCtu->setQuLastCodedQP( qp );pCtu->setCodedQP( qp );
#endif}if ( pCtu->getSlice()->getUseChromaQpAdj() ){setIsChromaQpAdjCoded(true);}// start from the top level CU
#if JVET_C0024_QTBTUInt uiCTUSize = pCtu->getSlice()->getSPS()->getCTUSize();pCtu->getPic()->setCodedAreaInCTU(0);pCtu->getPic()->setCodedBlkInCTU(false, 0, 0, uiCTUSize>>MIN_CU_LOG2, uiCTUSize>>MIN_CU_LOG2);  //only used for affine merge code or not//解码CUxDecodeCU( pCtu, 0, 0, uiCTUSize, uiCTUSize, isLastCtuOfSliceSegment);
#elsexDecodeCU( pCtu, 0, 0, isLastCtuOfSliceSegment);
#endif//如果是帧内模式,亮度和色度分开解码,上面解码的是亮度,下面解码色度
#if JVET_C0024_QTBTif (pCtu->getSlice()->isIntra()){pCtu->getSlice()->setTextType(CHANNEL_TYPE_CHROMA);pCtu->getPic()->setCodedAreaInCTU(0);
#if JVET_E0077_ENHANCED_LMpCtu->getPic()->setCodedBlkInCTU(false, 0, 0, uiCTUSize >> MIN_CU_LOG2, uiCTUSize >> MIN_CU_LOG2);
#endif
#if JVET_C0024_DELTA_QP_FIXif ( pCtu->getSlice()->getPPS()->getUseDQP() ){setdQPFlag(true);
#if JVET_C0024_DELTA_QP_FIX // init current quantization unit info.Char qp = pCtu->getCtuLastCodedQP();pCtu->setQuPartIdx(0); pCtu->setQuLastCodedQP( qp );pCtu->setCodedQP( qp );
#endif}
#endif
#if JVET_E0062_MULTI_DMSpCtu->getPic()->setCodedBlkInCTU(false, 0, 0, uiCTUSize>>MIN_CU_LOG2, uiCTUSize>>MIN_CU_LOG2);
#endif// start from the top level CU//解码CUxDecodeCU( pCtu, 0, 0, uiCTUSize, uiCTUSize, isLastCtuOfSliceSegment);}xFinishDecodeCU( pCtu, 0, 0, isLastCtuOfSliceSegment );
#endif
}

xDecodeCU

该函数通过递归完成一个CTU的所有CU的解码工作,主要是各种预测信息的解码,是xEncodeCU(详见
H.266代码学习:xEncodeCU函数)的逆处理。

JEM中与HM主要区别:
1.JEM中采用四叉树+二叉树划分,因此解码时增加了二叉树部分的划分。
2.在JEM中,帧间merge增加了很多模式,因此在skip解码中增加了FRUC Merge、Affine Merge解码,同时还增加了IC(光照补偿)解码。

流程如下:
一、初始化,获取当前CU的图像、SPS、PPS、最大CU宽度高度等信息。
二、计算CU边界坐标。
三、先进行四叉树解码,后进行二叉树接阿妈
1.四叉树划分:解码split flag,满足条件时对四个分块进行递归划分。当达到深度或边缘时,结束划分。
2.二叉树划分,解码二叉树划分flag和划分模式,BTSplitMode分为三种:0不划分,1水平划分,2垂直划分。当模式为1和2时,对两个分块进行递归划分。
四.解码当前CU的各种信息:
1.解码skip flag,如果skip flag为true,需要解码FRUC Merge、Affine Merge和普通Merge,并解码IC。这里没有看到Merge候选列表的构建,比较奇怪,留一个问题,之后看明白了再来补充。
2.解码预测模式,如果是帧内预测,解码PCM模式,看是否是PCM模式。
3.调用decodePredInfo解码帧内、帧间的模式。
4.解码系数

代码分析:

//! decode CU block recursively
//递归解码CU
#if JVET_C0024_QTBT
Void TDecCu::xDecodeCU( TComDataCU*const pcCU, const UInt uiAbsPartIdx, const UInt uiDepth, const UInt uiWidth, const UInt uiHeight, Bool &isLastCtuOfSliceSegment, UInt uiSplitConstrain)
#else
Void TDecCu::xDecodeCU( TComDataCU*const pcCU, const UInt uiAbsPartIdx, const UInt uiDepth, Bool &isLastCtuOfSliceSegment)
#endif
{//初始化TComPic* pcPic        = pcCU->getPic();const TComSPS &sps    = pcPic->getPicSym()->getSPS();const TComPPS &pps    = pcPic->getPicSym()->getPPS();
#if !JVET_C0024_QTBTconst UInt maxCuWidth = sps.getMaxCUWidth();const UInt maxCuHeight= sps.getMaxCUHeight();
#endifUInt uiCurNumParts    = pcPic->getNumPartitionsInCtu() >> (uiDepth<<1);UInt uiQNumParts      = uiCurNumParts>>2;//边界Bool bBoundary = false;UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
#if JVET_C0024_QTBTUInt uiRPelX   = uiLPelX + uiWidth  - 1;
#elseUInt uiRPelX   = uiLPelX + (maxCuWidth>>uiDepth)  - 1;
#endifUInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
#if JVET_C0024_QTBTUInt uiBPelY   = uiTPelY + uiHeight - 1;
#elseUInt uiBPelY   = uiTPelY + (maxCuHeight>>uiDepth) - 1;
#endif//解码split flag,先四叉树划分
#if JVET_C0024_BT_RMV_REDUNDANTpcCU->setSplitConstrain( uiSplitConstrain );Bool bQTreeValid = false;
#endif#if JVET_C0024_QTBT//是否强制四叉树划分Bool bForceQT = uiWidth > MAX_TU_SIZE;if( bForceQT )        //强制四叉树划分只能对方形块进行{assert(uiWidth == uiHeight);}UInt uiCTUSize = pcCU->getSlice()->getSPS()->getCTUSize();
#if JVET_C0024_DELTA_QP_FIXUInt uiQTWidth = uiCTUSize>>uiDepth;UInt uiQTHeight = uiCTUSize>>uiDepth;//最大深度const UInt uiQTBTDepth = (uiDepth << 1) + (g_aucConvertToBit[uiQTWidth]-g_aucConvertToBit[uiWidth] + g_aucConvertToBit[uiQTHeight]-g_aucConvertToBit[uiHeight]);const UInt uiMaxDQPDepthQTBT = pps.getMaxCuDQPDepth() << 1;
#endifif (uiCTUSize>>uiDepth == uiWidth && uiWidth==uiHeight){
#endifif( ( uiRPelX < sps.getPicWidthInLumaSamples() ) && ( uiBPelY < sps.getPicHeightInLumaSamples() ) ){
#if JVET_C0024_QTBTif( bForceQT ){pcCU->setDepthSubParts( uiDepth + 1, uiAbsPartIdx );}else
#endif//解码四叉树划分flagm_pcEntropyDecoder->decodeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );}else{bBoundary = true;}#if JVET_C0024_BT_RMV_REDUNDANTbQTreeValid = true;//最小四叉树划分尺寸UInt uiMinQTSize = sps.getMinQTSize(pcCU->getSlice()->getSliceType(), pcCU->getTextType());//尺寸小于等于uiMinQTSize时,停止四叉树划分if ((uiCTUSize>>uiDepth) <= uiMinQTSize )  {bQTreeValid = false;}
#endif//达到深度或边缘处,递归
#if JVET_C0024_QTBTif( ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) ) || bBoundary )
#elseif( ( ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) ) && ( uiDepth < sps.getLog2DiffMaxMinCodingBlockSize() ) ) || bBoundary )
#endif{UInt uiIdx = uiAbsPartIdx;
#if JVET_C0024_DELTA_QP_FIXif( uiQTBTDepth == uiMaxDQPDepthQTBT && pps.getUseDQP())
#elseif( uiDepth == pps.getMaxCuDQPDepth() && pps.getUseDQP())
#endif{setdQPFlag(true);
#if JVET_C0024_DELTA_QP_FIXpcCU->setQuPartIdx( uiAbsPartIdx );pcCU->setQuLastCodedQP( pcCU->getCodedQP() );
#endif
#if JVET_C0024_DELTA_QP_FIXpcCU->setQPSubParts( pcCU->getRefQP(uiAbsPartIdx), uiAbsPartIdx, uiWidth, uiHeight ); // set QP to default QP
#elsepcCU->setQPSubParts( pcCU->getRefQP(uiAbsPartIdx), uiAbsPartIdx, uiDepth ); // set QP to default QP
#endif}if( uiDepth == pps.getPpsRangeExtension().getDiffCuChromaQpOffsetDepth() && pcCU->getSlice()->getUseChromaQpAdj() ){setIsChromaQpAdjCoded(true);}//递归对四个分块进行划分for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ ){uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiIdx] ];uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiIdx] ];if ( !isLastCtuOfSliceSegment && ( uiLPelX < sps.getPicWidthInLumaSamples() ) && ( uiTPelY < sps.getPicHeightInLumaSamples() ) ){
#if JVET_C0024_QTBTxDecodeCU( pcCU, uiIdx, uiDepth+1, uiWidth>>1, uiHeight>>1, isLastCtuOfSliceSegment );
#elsexDecodeCU( pcCU, uiIdx, uiDepth+1, isLastCtuOfSliceSegment );
#endif}else{pcCU->setOutsideCUPart( uiIdx, uiDepth+1 );
#if JVET_C0024_QTBTpcCU->getPic()->addCodedAreaInCTU(uiWidth*uiHeight>>2);
#endif}uiIdx += uiQNumParts;}
#if JVET_C0024_DELTA_QP_FIXif( uiQTBTDepth == uiMaxDQPDepthQTBT && pps.getUseDQP())
#elseif( uiDepth == pps.getMaxCuDQPDepth() && pps.getUseDQP())
#endif{if ( getdQPFlag() ){UInt uiQPSrcPartIdx = uiAbsPartIdx;
#if JVET_C0024_DELTA_QP_FIXpcCU->setQPSubParts( pcCU->getRefQP( uiQPSrcPartIdx ), uiAbsPartIdx, uiWidth, uiHeight ); // set QP to default QP
#elsepcCU->setQPSubParts( pcCU->getRefQP( uiQPSrcPartIdx ), uiAbsPartIdx, uiDepth ); // set QP to default QP
#endif
#if JVET_C0024_DELTA_QP_FIXpcCU->setCodedQP( pcCU->getQP(uiQPSrcPartIdx) );
#endif}}return;}
#if JVET_C0024_QTBT}//二叉树划分
#if JVET_C0024_BT_RMV_REDUNDANT Bool bBTHorRmvEnable = false;Bool bBTVerRmvEnable = false;if (pcCU->getSlice()->getSliceType() != I_SLICE){bBTHorRmvEnable = true;bBTVerRmvEnable = bQTreeValid;}
#endif//初始化二叉树划分
#if JVET_C0024_SPS_MAX_BT_DEPTHUInt uiMaxBTD = pcCU->getSlice()->isIntra() ? (isLuma(pcCU->getTextType())?sps.getMaxBTDepthISliceL():sps.getMaxBTDepthISliceC()): sps.getMaxBTDepth();
#elseUInt uiMaxBTD = pcCU->getSlice()->isIntra() ? (isLuma(pcCU->getTextType())?MAX_BT_DEPTH:MAX_BT_DEPTH_C): MAX_BT_DEPTH_INTER;
#endif
#if JVET_C0024_SPS_MAX_BT_SIZEUInt uiMaxBTSize = pcCU->getSlice()->isIntra() ? (isLuma(pcCU->getTextType())?sps.getMaxBTSizeISliceL():sps.getMaxBTSizeISliceC()): sps.getMaxBTSize();
#elseUInt uiMaxBTSize = isLuma(pcCU->getTextType()) ? pcCU->getSlice()->getMaxBTSize(): MAX_BT_SIZE_C;
#endifUInt uiMinBTSize = pcCU->getSlice()->isIntra() ? (isLuma(pcCU->getTextType())?MIN_BT_SIZE:MIN_BT_SIZE_C): MIN_BT_SIZE_INTER;UInt uiBTDepth = pcCU->getBTDepth(uiAbsPartIdx, uiWidth, uiHeight);///满足条件进行解码二叉树划分模式flag,递归进行划分if ( (uiHeight>uiMinBTSize || uiWidth>uiMinBTSize) && uiWidth<=uiMaxBTSize && uiHeight<=uiMaxBTSize && uiBTDepth<uiMaxBTD) {UInt uiIdxBT = uiAbsPartIdx;m_pcEntropyDecoder->decodeBTSplitMode(pcCU, uiAbsPartIdx, uiWidth, uiHeight);
#if JVET_C0024_BT_RMV_REDUNDANTuiSplitConstrain = 0;
#endif//水平划分if (pcCU->getBTSplitModeForBTDepth(uiAbsPartIdx, uiBTDepth)==1){
#if JVET_C0024_DELTA_QP_FIXif( uiQTBTDepth == uiMaxDQPDepthQTBT && pps.getUseDQP()){setdQPFlag(true);
#if JVET_C0024_DELTA_QP_FIXpcCU->setQuPartIdx( uiAbsPartIdx );pcCU->setQuLastCodedQP( pcCU->getCodedQP() );
#endifpcCU->setQPSubParts( pcCU->getRefQP(uiAbsPartIdx), uiAbsPartIdx, uiWidth, uiHeight ); // set QP to default QP}
#endif//分别对两个分块进行递归划分for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 2; uiPartUnitIdx++ ){if (uiPartUnitIdx==1){uiIdxBT = g_auiRasterToZscan[g_auiZscanToRaster[uiIdxBT] + (uiHeight>>1)/pcCU->getPic()->getMinCUHeight()*pcCU->getPic()->getNumPartInCtuWidth()];}
#if JVET_C0024_BT_RMV_REDUNDANTxDecodeCU( pcCU, uiIdxBT, uiDepth, uiWidth, uiHeight>>1, isLastCtuOfSliceSegment, uiSplitConstrain );if (pcCU->getBTSplitModeForBTDepth(uiIdxBT, uiBTDepth+1) == 2 && bBTHorRmvEnable && uiPartUnitIdx==0){uiSplitConstrain = 2;}
#elsexDecodeCU( pcCU, uiIdxBT, uiDepth, uiWidth, uiHeight>>1, isLastCtuOfSliceSegment );
#endif}
#if JVET_C0024_DELTA_QP_FIXif( uiQTBTDepth == uiMaxDQPDepthQTBT && pps.getUseDQP()){if ( getdQPFlag() ){UInt uiQPSrcPartIdx = uiAbsPartIdx;pcCU->setQPSubParts( pcCU->getRefQP( uiQPSrcPartIdx ), uiAbsPartIdx, uiWidth, uiHeight ); // set QP to default QP
#if JVET_C0024_DELTA_QP_FIXpcCU->setCodedQP( pcCU->getQP(uiQPSrcPartIdx) );
#endif}}
#endifreturn;}//垂直划分else if (pcCU->getBTSplitModeForBTDepth(uiAbsPartIdx, uiBTDepth)==2){
#if JVET_C0024_DELTA_QP_FIXif( uiQTBTDepth == uiMaxDQPDepthQTBT && pps.getUseDQP()){setdQPFlag(true);
#if JVET_C0024_DELTA_QP_FIXpcCU->setQuPartIdx( uiAbsPartIdx );pcCU->setQuLastCodedQP( pcCU->getCodedQP() );
#endifpcCU->setQPSubParts( pcCU->getRefQP(uiAbsPartIdx), uiAbsPartIdx, uiWidth, uiHeight ); // set QP to default QP}
#endif//分别对两个分块进行递归划分for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 2; uiPartUnitIdx++ ){if (uiPartUnitIdx==1){uiIdxBT = g_auiRasterToZscan[g_auiZscanToRaster[uiIdxBT] + (uiWidth>>1)/pcCU->getPic()->getMinCUWidth()];}
#if JVET_C0024_BT_RMV_REDUNDANTxDecodeCU( pcCU, uiIdxBT, uiDepth, uiWidth>>1, uiHeight, isLastCtuOfSliceSegment, uiSplitConstrain );if (pcCU->getBTSplitModeForBTDepth(uiIdxBT, uiBTDepth+1) == 1 && bBTVerRmvEnable && uiPartUnitIdx==0){uiSplitConstrain = 1;}
#elsexDecodeCU( pcCU, uiIdxBT, uiDepth, uiWidth>>1, uiHeight, isLastCtuOfSliceSegment );
#endif}//delta QP
#if JVET_C0024_DELTA_QP_FIXif( uiQTBTDepth == uiMaxDQPDepthQTBT && pps.getUseDQP()){if ( getdQPFlag() ){UInt uiQPSrcPartIdx = uiAbsPartIdx;pcCU->setQPSubParts( pcCU->getRefQP( uiQPSrcPartIdx ), uiAbsPartIdx, uiWidth, uiHeight ); // set QP to default QP
#if JVET_C0024_DELTA_QP_FIXpcCU->setCodedQP( pcCU->getQP(uiQPSrcPartIdx) );
#endif}}
#endifreturn;}  }pcCU->setSizeSubParts( uiWidth, uiHeight, uiAbsPartIdx, uiDepth );UInt uiBlkX = g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ] >> MIN_CU_LOG2;UInt uiBlkY = g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ] >> MIN_CU_LOG2;pcCU->getPic()->setCodedBlkInCTU(true, uiBlkX, uiBlkY, uiWidth>> MIN_CU_LOG2, uiHeight>> MIN_CU_LOG2);pcCU->getPic()->addCodedAreaInCTU(uiWidth*uiHeight);UInt uiWidthIdx = g_aucConvertToBit[uiWidth];UInt uiHeightIdx = g_aucConvertToBit[uiHeight];assert(g_aucConvertToBit[uiWidth]>=0 && g_aucConvertToBit[uiHeight]>=0);
#endif#if JVET_C0024_DELTA_QP_FIXif( uiQTBTDepth <= uiMaxDQPDepthQTBT && pps.getUseDQP())
#elseif( uiDepth <= pps.getMaxCuDQPDepth() && pps.getUseDQP())
#endif{setdQPFlag(true);
#if JVET_C0024_DELTA_QP_FIXpcCU->setQuPartIdx( uiAbsPartIdx );pcCU->setQuLastCodedQP( pcCU->getCodedQP() );
#endif
#if JVET_C0024_DELTA_QP_FIXpcCU->setQPSubParts( pcCU->getRefQP(uiAbsPartIdx), uiAbsPartIdx, uiWidth, uiHeight ); // set QP to default QP
#elsepcCU->setQPSubParts( pcCU->getRefQP(uiAbsPartIdx), uiAbsPartIdx, uiDepth ); // set QP to default QP
#endif}if( uiDepth <= pps.getPpsRangeExtension().getDiffCuChromaQpOffsetDepth() && pcCU->getSlice()->getUseChromaQpAdj() ){setIsChromaQpAdjCoded(true);}if (pps.getTransquantBypassEnableFlag()){m_pcEntropyDecoder->decodeCUTransquantBypassFlag( pcCU, uiAbsPartIdx, uiDepth );}// decode CU mode and the partition size//解码CU模式和分块尺寸if( !pcCU->getSlice()->isIntra()) //非帧内模式,解码skip flag{m_pcEntropyDecoder->decodeSkipFlag( pcCU, uiAbsPartIdx, uiDepth );}
#if COM16_C806_OBMCpcCU->setOBMCFlagSubParts( true, uiAbsPartIdx, uiDepth );
#endif//解码skip模式信息if( pcCU->isSkipped(uiAbsPartIdx) ){
#if JVET_C0024_QTBTm_pppcCU[uiWidthIdx][uiHeightIdx]->copyInterPredInfoFrom( pcCU, uiAbsPartIdx, REF_PIC_LIST_0 );m_pppcCU[uiWidthIdx][uiHeightIdx]->copyInterPredInfoFrom( pcCU, uiAbsPartIdx, REF_PIC_LIST_1 );
#elsem_ppcCU[uiDepth]->copyInterPredInfoFrom( pcCU, uiAbsPartIdx, REF_PIC_LIST_0 );m_ppcCU[uiDepth]->copyInterPredInfoFrom( pcCU, uiAbsPartIdx, REF_PIC_LIST_1 );
#endif
#if VCEG_AZ07_FRUC_MERGE//解码FRUC Mrege模式m_pcEntropyDecoder->decodeFRUCMgrMode( pcCU , uiAbsPartIdx , uiDepth , 0 );if( !pcCU->getFRUCMgrMode( uiAbsPartIdx ) ){
#endif
#if !VCEG_AZ07_FRUC_MERGE && !JVET_C0024_QTBTTComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists
#if COM16_C1016_AFFINETComMvField cAffineMvField[2][3]; // double length for mv of both lists, 3 mv for affine
#endifUChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
#if COM16_C806_VCEG_AZ10_SUB_PU_TMVP UChar eMergeCandTypeNieghors[MRG_MAX_NUM_CANDS];memset ( eMergeCandTypeNieghors, MGR_TYPE_DEFAULT_N, sizeof(UChar)*MRG_MAX_NUM_CANDS );
#endif
#if VCEG_AZ06_ICBool abICFlag[MRG_MAX_NUM_CANDS];
#endifInt numValidMergeCand = 0;
#if JVET_C0024_QTBTfor( UInt ui = 0; ui < m_pppcCU[uiWidthIdx][uiHeightIdx]->getSlice()->getMaxNumMergeCand(); ++ui )
#elsefor( UInt ui = 0; ui < m_ppcCU[uiDepth]->getSlice()->getMaxNumMergeCand(); ++ui )
#endif{uhInterDirNeighbours[ui] = 0;}
#endif#if COM16_C1016_AFFINE//解码Affine Merge模式if ( pcCU->isAffineMrgFlagCoded(uiAbsPartIdx, 0) ){m_pcEntropyDecoder->decodeAffineFlag( pcCU, uiAbsPartIdx, uiDepth, 0 );}//解码普通Mergeif ( !pcCU->isAffine(uiAbsPartIdx) ){m_pcEntropyDecoder->decodeMergeIndex( pcCU, 0, uiAbsPartIdx, uiDepth );}
#elsem_pcEntropyDecoder->decodeMergeIndex( pcCU, 0, uiAbsPartIdx, uiDepth );
#endif#if !VCEG_AZ07_FRUC_MERGE && !JVET_C0024_QTBTUInt uiMergeIndex = pcCU->getMergeIndex(uiAbsPartIdx);#if COM16_C1016_AFFINEif ( pcCU->isAffine( uiAbsPartIdx ) ){
#if JVET_C0024_QTBTm_pppcCU[uiWidthIdx][uiHeightIdx]->getAffineMergeCandidates( 0, 0, cAffineMvField, uhInterDirNeighbours, numValidMergeCand );
#elsem_ppcCU[uiDepth]->getAffineMergeCandidates( 0, 0, cAffineMvField, uhInterDirNeighbours, numValidMergeCand );
#endifpcCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeIndex], uiAbsPartIdx, 0, uiDepth );TComMv cTmpMv( 0, 0 );for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ ){if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 ){TComMvField* pcMvField = cAffineMvField[ 2 * uiMergeIndex + uiRefListIdx ];pcCU->setMVPIdxSubParts( 0, RefPicList( uiRefListIdx ), uiAbsPartIdx, 0, uiDepth);pcCU->setMVPNumSubParts( 0, RefPicList( uiRefListIdx ), uiAbsPartIdx, 0, uiDepth);pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->setAllMvd( cTmpMv, SIZE_2Nx2N, uiAbsPartIdx, uiDepth );pcCU->setAllAffineMvField( uiAbsPartIdx, 0, pcMvField, RefPicList(uiRefListIdx), uiDepth );}}xFinishDecodeCU( pcCU, uiAbsPartIdx, uiDepth, isLastCtuOfSliceSegment );return;}
#endif
#if JVET_C0024_QTBTm_pppcCU[uiWidthIdx][uiHeightIdx]->getInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand
#elsem_ppcCU[uiDepth]->getInterMergeCandidates( 0, 0, cMvFieldNeighbours, uhInterDirNeighbours, numValidMergeCand
#endif
#if VCEG_AZ06_IC, abICFlag
#endif
#if COM16_C806_VCEG_AZ10_SUB_PU_TMVP, eMergeCandTypeNieghors, m_pMvFieldSP, m_phInterDirSP, uiAbsPartIdx, pcCU
#endif, uiMergeIndex );#if COM16_C806_VCEG_AZ10_SUB_PU_TMVPpcCU->setMergeTypeSubParts( eMergeCandTypeNieghors[uiMergeIndex] , uiAbsPartIdx, 0, uiDepth ); if( eMergeCandTypeNieghors[uiMergeIndex] == MGR_TYPE_DEFAULT_N )
#endifpcCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeIndex], uiAbsPartIdx, 0, uiDepth );
#if VCEG_AZ06_ICpcCU->setICFlagSubParts( pcCU->getSlice()->getApplyIC() ? abICFlag[uiMergeIndex] : 0, uiAbsPartIdx, uiDepth );
#endifTComMv cTmpMv( 0, 0 );for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ ){if ( pcCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 ){pcCU->setMVPIdxSubParts( 0, RefPicList( uiRefListIdx ), uiAbsPartIdx, 0, uiDepth);pcCU->setMVPNumSubParts( 0, RefPicList( uiRefListIdx ), uiAbsPartIdx, 0, uiDepth);pcCU->getCUMvField( RefPicList( uiRefListIdx ) )->setAllMvd( cTmpMv, SIZE_2Nx2N, uiAbsPartIdx, uiDepth );
#if COM16_C806_VCEG_AZ10_SUB_PU_TMVPif( eMergeCandTypeNieghors[uiMergeIndex] == MGR_TYPE_DEFAULT_N ){
#endifpcCU->getCUMvField( RefPicList( uiRefListIdx ) )->setAllMvField( cMvFieldNeighbours[ 2*uiMergeIndex + uiRefListIdx ], SIZE_2Nx2N, uiAbsPartIdx, uiDepth );
#if COM16_C806_VCEG_AZ10_SUB_PU_TMVP}
#endif}}
#endif
#if VCEG_AZ07_FRUC_MERGE}
#if VCEG_AZ06_IC//解码ICm_pcEntropyDecoder->decodeICFlag( pcCU, uiAbsPartIdx, uiDepth );
#endif
#endif
#if JVET_C0024_QTBTif(  pcCU->getSlice()->getPPS()->getUseDQP()){
#if JVET_C0024_DELTA_QP_FIXpcCU->setQPSubParts( getdQPFlag()?pcCU->getRefQP(uiAbsPartIdx):pcCU->getCodedQP(), uiAbsPartIdx, uiWidth, uiHeight ); // set QP
#elsepcCU->setQPSubParts( getdQPFlag()?pcCU->getRefQP(uiAbsPartIdx):pcCU->getCodedQP(), uiAbsPartIdx, uiDepth ); // set QP
#endif
#if JVET_C0024_DELTA_QP_FIXpcCU->setCodedQP( pcCU->getQP(uiAbsPartIdx) );
#endif}if (pcCU->getSlice()->getUseChromaQpAdj() && !getIsChromaQpAdjCoded()){pcCU->setChromaQpAdjSubParts( pcCU->getCodedChromaQpAdj(), uiAbsPartIdx, uiDepth ); // set QP}
#elsexFinishDecodeCU( pcCU, uiAbsPartIdx, uiDepth, isLastCtuOfSliceSegment );
#endifreturn;}m_pcEntropyDecoder->decodePredMode( pcCU, uiAbsPartIdx, uiDepth );
#if JVET_C0024_QTBT//帧内预测模式if (isLuma(pcCU->getTextType())){
#endif
#if VCEG_AZ05_INTRA_MPIm_pcEntropyDecoder->decodeMPIIdx(pcCU, uiAbsPartIdx, uiDepth);
#endif
#if COM16_C1046_PDPC_INTRA && !JVET_G0104_PLANAR_PDPCm_pcEntropyDecoder->decodePDPCIdx(pcCU, uiAbsPartIdx, uiDepth);
#endif
#if JVET_C0024_QTBT}
#elsem_pcEntropyDecoder->decodePartSize( pcCU, uiAbsPartIdx, uiDepth );
#endif#if JVET_C0024_QTBT//帧内模式if (pcCU->isIntra( uiAbsPartIdx ) )
#elseif (pcCU->isIntra( uiAbsPartIdx ) && pcCU->getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N )
#endif{//解码PCM模式m_pcEntropyDecoder->decodeIPCMInfo( pcCU, uiAbsPartIdx, uiDepth );if(pcCU->getIPCMFlag(uiAbsPartIdx)){
#if JVET_C0024_QTBTif(  pcCU->getSlice()->getPPS()->getUseDQP()){
#if JVET_C0024_DELTA_QP_FIXpcCU->setQPSubParts( getdQPFlag()?pcCU->getRefQP(uiAbsPartIdx):pcCU->getCodedQP(), uiAbsPartIdx, uiWidth, uiHeight ); // set QP
#elsepcCU->setQPSubParts( getdQPFlag()?pcCU->getRefQP(uiAbsPartIdx):pcCU->getCodedQP(), uiAbsPartIdx, uiDepth ); // set QP
#endif
#if JVET_C0024_DELTA_QP_FIXpcCU->setCodedQP( pcCU->getQP(uiAbsPartIdx) );
#endif}if (pcCU->getSlice()->getUseChromaQpAdj() && !getIsChromaQpAdjCoded()){pcCU->setChromaQpAdjSubParts( pcCU->getCodedChromaQpAdj(), uiAbsPartIdx, uiDepth ); // set QP}
#elsexFinishDecodeCU( pcCU, uiAbsPartIdx, uiDepth, isLastCtuOfSliceSegment );
#endifreturn;}}// prediction mode ( Intra : direction mode, Inter : Mv, reference idx )//解码预测模式(帧内:方向模式,帧间:MV和参考索引)
#if JVET_C0024_QTBTm_pcEntropyDecoder->decodePredInfo( pcCU, uiAbsPartIdx, uiDepth, m_pppcCU[uiWidthIdx][uiHeightIdx]);
#elsem_pcEntropyDecoder->decodePredInfo( pcCU, uiAbsPartIdx, uiDepth, m_ppcCU[uiDepth]);
#endif
#if COM16_C806_OBMCm_pcEntropyDecoder->decodeOBMCFlag( pcCU, uiAbsPartIdx, uiDepth );
#endif
#if VCEG_AZ06_ICm_pcEntropyDecoder->decodeICFlag( pcCU, uiAbsPartIdx, uiDepth );
#endif// Coefficient decoding//解码系数Bool bCodeDQP = getdQPFlag();Bool isChromaQpAdjCoded = getIsChromaQpAdjCoded();m_pcEntropyDecoder->decodeCoeff( pcCU, uiAbsPartIdx, uiDepth, bCodeDQP, isChromaQpAdjCoded );setIsChromaQpAdjCoded( isChromaQpAdjCoded );setdQPFlag( bCodeDQP );#if JVET_C0024_QTBTif(  pcCU->getSlice()->getPPS()->getUseDQP()){
#if JVET_C0024_DELTA_QP_FIXpcCU->setQPSubParts( getdQPFlag()?pcCU->getRefQP(uiAbsPartIdx):pcCU->getCodedQP(), uiAbsPartIdx, uiWidth, uiHeight ); // set QP
#elsepcCU->setQPSubParts( getdQPFlag()?pcCU->getRefQP(uiAbsPartIdx):pcCU->getCodedQP(), uiAbsPartIdx, uiDepth ); // set QP
#endif
#if JVET_C0024_DELTA_QP_FIXpcCU->setCodedQP( pcCU->getQP(uiAbsPartIdx) );
#endif}if (pcCU->getSlice()->getUseChromaQpAdj() && !getIsChromaQpAdjCoded()){pcCU->setChromaQpAdjSubParts( pcCU->getCodedChromaQpAdj(), uiAbsPartIdx, uiDepth ); // set QP}
#elsexFinishDecodeCU( pcCU, uiAbsPartIdx, uiDepth, isLastCtuOfSliceSegment );
#endif
}

H.266代码学习:decodeCtu和xDecodeCU函数相关推荐

  1. H.266代码学习:decompressCtu和xDecompressCU函数

    今天来学习一下JEM的decompressCtu和xDecompressCU函数.之前在 H.266代码学习:decodeCtu和xDecodeCU函数 学习了的学习中提到,decodeCtu和xDe ...

  2. H.266代码学习:xIntraCodingTUBlock函数

    今天来继续学习帧内编码的重要函数xIntraCodingTUBlock,上次 H.266代码学习:xRecurIntraCodingLumaQT函数 学习中提到,xIntraCodingTUBlock ...

  3. H.266代码学习:estIntraPredLumaQT函数

    之前 HEVC代码学习42:estIntraPredLumaQT函数 对HM中的estIntraPredLumaQT函数进行了学习,下面将对JEM中的该函数进行学习. estIntraPredLuma ...

  4. H.266代码学习:xEncodeCU函数

    之前在HEVC代码学习35:xEncodeCU函数中介绍过xEncodeCU函数,今天来看JEM中的xEncodeCU,其中难点在于QTBT编码结构. HM中使用compressCtu对每个CTU进行 ...

  5. H.266代码学习:JEM使用方法

    之前在HEVC代码学习0:HM使用+码流分析教程中详细介绍了HM使用方法,而H.266参考代码JEM已经成型,因此这里简单介绍下JEM的使用方法. 阅读建议: JEM使用方法与HM类似,使用中改动在于 ...

  6. HEVC代码学习39:decodeCtu和xDecodeCU函数

    在之前 HEVC代码学习38:decompressSlice函数 学习中提到,解码slice会遍历所有CTU,调用decodeCtu和decompressCtu解码每一个CTU.下面就来学习一下dec ...

  7. VVC/H.266代码阅读(VTM8.0)(三. Slice到CTU的处理 )

    本文是本系列的第三篇博客,内容是分析从Slice到CTU的处理代码. 该系列相关博客为: VVC/H.266代码阅读(VTM8.0)(一. NALU提取) VVC/H.266代码阅读(VTM8.0)( ...

  8. HEVC代码学习42:estIntraPredLumaQT函数

    在之前的 HEVC代码学习37:帧内预测代码整体学习 中已经提到,estIntraPredLumaQT是亮度帧内预测的入口函数,下面将对该函数进行详细学习. estIntraPredLumaQT中完成 ...

  9. HEVC代码学习13:predInterSearch函数

    在上一章的xCheckRDCostInter学习中,我们知道了,进行帧间搜索的入口实际是predInterSearch,今天我们就来对他进行学习. 推荐看大神博客 http://blog.csdn.n ...

最新文章

  1. bzero, memset ,setmem 区别
  2. JavaScript的正则表达式实现邮箱校验
  3. Sqlserver高版本还原到低版本方法(Sqlserver2012到SqlServer2008 R2)
  4. 云上更安全?亚马逊云科技宣布将持续加大在中国区域安全合规领域投入
  5. SpringBoot的编码问题
  6. mysql添加新用户 开放外网访问
  7. 【ElasticSearch 】ElasticSearch监控工具 cerebro
  8. [20180819]四校联考
  9. Phoca Gallery Images 去除 logo
  10. cglib动态代理实现及其原理浅析
  11. 单片机毕业设计 stm32智能温控风扇
  12. 美国大学计算机信息技术专业排名,新鲜出炉 2019年USNews美国大学信息技术管理专业排名榜单!...
  13. Windows XP下如何清理日志文件
  14. AutoVue使用教程:如何在64位Linux上安装AutoVue
  15. HTMLdiv标签滑条
  16. 为什么我们不应该使用微信或者 QQ 作为团队协作的 IM 工具?
  17. python如何切换windows窗口_selenium+python 切换窗口的几种方法
  18. 腾讯云搭建代理服务器全部内容
  19. 计算机如何连接发票打印机,惠普打印机怎么连接电脑详细步骤,发票打印机怎么添加-...
  20. python twisted安装_图文详解python之twisted模块安装

热门文章

  1. snap7使用说明中文版_Python官方入门教程_中文版_3.7.3
  2. 20182019电子设计竞赛---无线充电小车初探
  3. vue项目在IE浏览器和360兼容模式下页面不显示问题,亲测有效
  4. 收款鸿蒙系统手机,华为10月17日将会发布收款搭载鸿蒙系统的手机
  5. 爬虫:pyquery 解析库
  6. 安全之AAA服务器--路由器认证,授权,审计
  7. 全新UI众人帮/蚂蚁帮任务平台系统源码+修复版
  8. adb安装及简单操作
  9. 酷玩乐队的Yellow被翻唱了
  10. mysql数据库导入1062_myMySQL数据库 出现1062错误怎么办 MySQL数据库使用教程