TEncCu::xCheckRDCostMerge2Nx2N
来源:互联网 发布:稻叶浩志 知乎 编辑:程序博客网 时间:2024/05/29 03:10
VoidTEncCu::xCheckRDCostMerge2Nx2N(TComDataCU*&rpcBestCU,TComDataCU*&rpcTempCU,Bool *earlyDetectionSkipMode )
{
assert(rpcTempCU->getSlice()->getSliceType() !=I_SLICE ); //确定该片是P Slice或者 B Slice
//#define MRG_MAX_NUM_CANDS 5
//由于是两个列表所以这里要左移一位
TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; //double length for mv of both lists
//
UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
Int numValidMergeCand = 0;
//初始化,rpcTempCU->getSlice()->getMaxNumMergeCand()== 5
for(UInt ui = 0; ui <rpcTempCU->getSlice()->getMaxNumMergeCand();++ui ){
uhInterDirNeighbours[ui] = 0;
}
//计算该CU所在的深度
UChar uhDepth =rpcTempCU->getDepth( 0 );
//根据当前CU的深度,做相应的初始化,以4x4块为单位
//memset( m_pePartSize +uiAbsPartIdx, eMode, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );
// Char* m_pePartSize; ///< array of partition sizes
//给 PU中相应的partition写入分割模式
rpcTempCU->setPartSizeSubParts(SIZE_2Nx2N, 0, uhDepth );// interprets depth relative toLCU level
//memset( m_CUTransquantBypass +uiAbsPartIdx, flag, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );
//m_CUTransquantBypass : array ofcu_transquant_bypass flags
//
rpcTempCU->setCUTransquantBypassSubParts(m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );
//设置cMvFieldNeighbours,uhInterDirNeighbours,numValidMergeCand等
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;
//!<默认为false
if (rpcTempCU->isLosslessCoded(0)) {
iteration = 1;
} else {
iteration = 2;
}
//代码结构分析
//第一次不理skip模式,bestIsSkip 初始值为 false;
//第二次不处理mergeCandBuffer[uiMergeCand]==1的情况
//遍历两次:第一次是对残差不编码;第二次对残差编码.
for(UInt uiNoResidual = 0; uiNoResidual <iteration; ++uiNoResidual ){
//!<遍历所有merging candidates
for(UInt uiMergeCand = 0; uiMergeCand <numValidMergeCand; ++uiMergeCand ) {
{
//!((uiNoResidual==1 &&mergeCandBuffer[uiMergeCand]==1) || (bestIsSkip && uiNoResidual == 0))
//!< uiNoResidual等于0或者mergeCandBuffer[uiMergeCand]等于0时条件成立
if(!(uiNoResidual==1 &&mergeCandBuffer[uiMergeCand]==1)){
//!< bestIsSkip等于false或者uiNoResidual等于1时条件成立
if( !(bestIsSkip &&uiNoResidual == 0) ){
// set MC parameters
// interprets depth relative to LCUlevel设置变量 m_pePredMode
//memset( m_pePredMode +uiAbsPartIdx(0), eMode, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ));
rpcTempCU->setPredModeSubParts(MODE_INTER, 0, uhDepth );
//设置变量 m_CUTransquantBypass
// memset( m_CUTransquantBypass +uiAbsPartIdx, flag, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );
rpcTempCU->setCUTransquantBypassSubParts(m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );
// interprets depth relative to LCUlevel设置变量 m_pePartSize
//memset( m_pePartSize +uiAbsPartIdx, eMode, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );
rpcTempCU->setPartSizeSubParts(SIZE_2Nx2N, 0, uhDepth );
// interprets depth relative to LCUlevel
rpcTempCU->setMergeFlagSubParts(true, 0, 0, uhDepth );
// interprets depth relative to LCUlevel
rpcTempCU->setMergeIndexSubParts(uiMergeCand, 0, 0, uhDepth );
// interprets depth relative to LCUlevel
rpcTempCU->setInterDirSubParts(uhInterDirNeighbours[uiMergeCand], 0, 0, uhDepth );
// interprets depth relative torpcTempCU level
rpcTempCU->getCUMvField(REF_PIC_LIST_0 )->setAllMvField(cMvFieldNeighbours[0 + 2*uiMergeCand],SIZE_2Nx2N, 0, 0 );
// interprets depth relative torpcTempCU level
rpcTempCU->getCUMvField(REF_PIC_LIST_1 )->setAllMvField(cMvFieldNeighbours[1 + 2*uiMergeCand],SIZE_2Nx2N, 0, 0 );
//运动补偿
m_pcPredSearch->motionCompensation (rpcTempCU, m_ppcPredYuvTemp[uhDepth] );
// estimate residual and encodeeverything
m_pcPredSearch->encodeResAndCalcRdInterCU(
rpcTempCU,
m_ppcOrigYuv [uhDepth],
m_ppcPredYuvTemp[uhDepth],
m_ppcResiYuvTemp[uhDepth],
m_ppcResiYuvBest[uhDepth],
m_ppcRecoYuvTemp[uhDepth],
//!< 对残差进行编码并计算RDCost
(uiNoResidual? true:false));
//第一次修改,
if(uiNoResidual==0){
//!< CBF为0,说明变换系数全为0
if(rpcTempCU->getQtRootCbf(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);
//!< m_useFastDecisionForMerge默认为true
if(m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip ) {
bestIsSkip = rpcBestCU->getQtRootCbf(0) == 0;
}
}
}
}
}
// 不处理
if(uiNoResidual == 0 &&m_pcEncCfg->getUseEarlySkipDetection())
{
if(rpcBestCU->getQtRootCbf( 0 ) == 0) //!< earlyDetectionSkip算法
{
if(rpcBestCU->getMergeFlag( 0 ))
{
*earlyDetectionSkipMode =true;
}
else
{
Int absoulte_MV=0;
for (UInt uiRefListIdx = 0; uiRefListIdx <2; uiRefListIdx++ )
{
if (rpcBestCU->getSlice()->getNumRefIdx(RefPicList( uiRefListIdx ) ) > 0 )
{
TComCUMvField* pcCUMvField =rpcBestCU->getCUMvField(RefPicList( uiRefListIdx ));
Int iHor = pcCUMvField->getMvd(0 ).getAbsHor();
Int iVer = pcCUMvField->getMvd(0 ).getAbsVer();
absoulte_MV+=iHor+iVer;
}
}
if(absoulte_MV == 0)
{
*earlyDetectionSkipMode =true;
}
}
}
assert(0);
}
}
}
- TEncCu::xCheckRDCostMerge2Nx2N
- TEncCu::xCheckRDCostMerge2Nx2N
- TEncCu::xCheckRDCostMerge2Nx2N
- HEVC帧间预测之三——TEncCu::xCheckRDCostMerge2Nx2N函数分析
- HM TEncCu相关说明
- HEVC代码学习31:xCheckRDCostMerge2Nx2N函数
- HEVC学习之琐事(三):TEncCu::compressCU
- 10个步骤引导你开发出畅销的移动应用
- linux I/O和oracle的关系(二)
- 安装Homebrew
- 微信小黄鸡 微信公众平台娱乐助手 聊天机器人 娱乐小助手
- 嵌入式系统中的大端模式和小端模式
- TEncCu::xCheckRDCostMerge2Nx2N
- 博弈问题及SG函数
- proc文件系统详解
- 几种location.href的区别 js实现网页防止被iframe框架嵌套功能 .
- 对android的android:taskAffinity初识
- 分页存储过程
- JSU 2013 Summer Individual Ranking Contest - 6
- mac lion下的emacs使用
- 数据结构--插入排序