HEVC帧间预测之三——TEncCu::xCheckRDCostMerge2Nx2N函数分析
本文将对实现merge模式的主函数xCheckRDCostMerge2Nx2N进行分析,方便理清merge模式的整个过程。之前的一篇分析了getInterMergeCandidates的具体实现,还有两个比较重要的函数motionCompensation和encodeResAndCalcRdInterCU,将留在后面陆续进行分析,但是根据它们的命名就不难猜出它们的作用,而且事实也是这样,因此对理解merge模式的整个过程没有影响,可以暂时不用去细究具体实现。下面仍然以贴代码及注释的方式来进行分析:[cpp]Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, Bool *earlyDetectionSkipMode )
{assert( rpcTempCU->getSlice()->getSliceType() != I_SLICE );TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both listsUChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];Int numValidMergeCand = 0;
for( UInt ui = 0; ui < rpcTempCU->getSlice()->getMaxNumMergeCand(); ++ui )
{uhInterDirNeighbours[ui] = 0;}UChar uhDepth = rpcTempCU->getDepth( 0 );rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU levelrpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );rpcTempCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );//! 创建一个merging candidates的列表Int mergeCandBuffer[MRG_MAX_NUM_CANDS];for( UInt ui = 0; ui < rpcTempCU->getSlice()->getMaxNumMergeCand(); ++ui ){mergeCandBuffer[ui] = 0;}
Bool bestIsSkip = false;
UInt iteration;
if ( rpcTempCU->isLosslessCoded(0)) //!< 默认为false{iteration = 1;}else{iteration = 2;}
for( UInt uiNoResidual = 0; uiNoResidual < iteration; ++uiNoResidual )
{for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand ) //!< 遍历所有merging candidates{{if(!(uiNoResidual==1 && mergeCandBuffer[uiMergeCand]==1)) //!< uiNoResidual等于0或者mergeCandBuffer[uiMergeCand]等于0时条件成立{
if( !(bestIsSkip && uiNoResidual == 0) ) //!< bestIsSkip等于false或者uiNoResidual等于1时条件成立
{// set MC parametersrpcTempCU->setPredModeSubParts( MODE_INTER, 0, uhDepth ); // interprets depth relative to LCU levelrpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU levelrpcTempCU->setMergeFlagSubParts( true, 0, 0, uhDepth ); // interprets depth relative to LCU levelrpcTempCU->setMergeIndexSubParts( uiMergeCand, 0, 0, uhDepth ); // interprets depth relative to LCU levelrpcTempCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeCand], 0, 0, uhDepth ); // interprets depth relative to LCU levelrpcTempCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 ); // interprets depth relative to rpcTempCU levelrpcTempCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 ); // interprets depth relative to rpcTempCU level
// do MC
m_pcPredSearch->motionCompensation ( rpcTempCU, m_ppcPredYuvTemp[uhDepth] ); //!< 运动补偿// estimate residual and encode everythingm_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU,m_ppcOrigYuv [uhDepth],m_ppcPredYuvTemp[uhDepth],m_ppcResiYuvTemp[uhDepth],m_ppcResiYuvBest[uhDepth],m_ppcRecoYuvTemp[uhDepth],(uiNoResidual? true:false)); //!< 对残差进行编码并计算RDCost
if(uiNoResidual==0){if(rpcTempCU->getQtRootCbf(0) == 0) //!< CBF为0,说明变换系数全为0{mergeCandBuffer[uiMergeCand] = 1;}}
rpcTempCU->setSkipFlagSubParts( rpcTempCU->getQtRootCbf(0) == 0, 0, uhDepth );
Int orgQP = rpcTempCU->getQP( 0 );xCheckDQP( rpcTempCU );xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth); //!< 更新最佳模式rpcTempCU->initEstData( uhDepth, orgQP ); //!< 重新初始化预测参数,为下一次预测做准备
if( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip ) //!< m_useFastDecisionForMerge默认为true{bestIsSkip = rpcBestCU->getQtRootCbf(0) == 0;}
}//!< if( !(bestIsSkip && uiNoResidual == 0) )
}//!< if(!(uiNoResidual==1 && mergeCandBuffer[uiMergeCand]==1))}//!<}//!< for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
if(uiNoResidual == 0 && m_pcEncCfg->getUseEarlySkipDetection()) //!< 第一次对merging candidates迭代后
{if(rpcBestCU->getQtRootCbf( 0 ) == 0) //!< earlyDetectionSkip 算法{if( rpcBestCU->getMergeFlag( 0 )){*earlyDetectionSkipMode = true;}else{ <补充:软件开发 , C++ ,
- 更多C/C++疑问解答:
- 关于c++的cout输出的问题。
- 在学校里学过C和C++,不过学的很一般,现在自学C#,会不会很难?
- 全国计算机二级C语言笔试题
- 已知某树有2个2度结点,3个3度结点,4个4度结点,问有几个叶子结点?
- c++数据结构内部排序问题,整数排序
- 2012九月计算机二级C语言全国题库,,急求急求
- 如果assert只有一个字符串作为参数,是什么意思呢?
- C语言中,哪些运算符具有左结合性,哪些具有右结合性,帮忙总结下,谢谢了!
- 为什么用结构体编写的程序输入是,0输不出来啊~~~
- 将IEEE—754的十六进制转化为十进制浮点类型,用C或C++都行,多谢各位大侠啊,非常感谢!
- 为什么这个程序求不出公式?
- 这个链表倒置的算法请大家分析下
- c语言函数库调用
- C语言unsigned int纠错
- C语言快排求解啊