参考:https://blog.csdn.net/nb_vol_1/article/details/51163625

1、源代码:

/** check RD costs for a CU block encoded with merge
* \param rpcBestCU
* \param rpcTempCU
* \returns Void
*/
Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU DEBUG_STRING_FN_DECLARE(sDebug), Bool *earlyDetectionSkipMode )
{
assert( rpcTempCU->getSlice()->getSliceType() != I_SLICE ); // 确定该片是P Slice或者B Slice
TComMvField cMvFieldNeighbours[ * MRG_MAX_NUM_CANDS]; // double length for mv of both lists
UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
Int numValidMergeCand = ;
const Bool bTransquantBypassFlag = rpcTempCU->getCUTransquantBypass(); for( UInt ui = ; ui < rpcTempCU->getSlice()->getMaxNumMergeCand(); ++ui )
{
uhInterDirNeighbours[ui] = ;
}
UChar uhDepth = rpcTempCU->getDepth( ); // 获取当前深度
// 给PU中相应的partition写入分割模式
rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, , uhDepth ); // interprets depth relative to LCU level
// 取出Merge候选列表
rpcTempCU->getInterMergeCandidates( , , cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );

// 构造候选列表
Int mergeCandBuffer[MRG_MAX_NUM_CANDS];
for( UInt ui = ; ui < numValidMergeCand; ++ui )
{
mergeCandBuffer[ui] = ;
} Bool bestIsSkip = false; UInt iteration;
// 默认为false,iteration = 2
if ( rpcTempCU->isLosslessCoded())
{
iteration = ;
}
else
{
iteration = ;
}
DEBUG_STRING_NEW(bestStr)

//代码结构分析

//第一次不理skip模式,bestIsSkip的初始值为false;

//第二次不处理mergeCandBuffer[uiMergeCand]为1的情况.

  // 遍历两次:第一次无残差编码,第二次对残差编码
for( UInt uiNoResidual = ; uiNoResidual < iteration; ++uiNoResidual )
{
// 遍历所有Merge候选成员
for( UInt uiMergeCand = ; uiMergeCand < numValidMergeCand; ++uiMergeCand )
{
if(!(uiNoResidual== && mergeCandBuffer[uiMergeCand]==))
{
if( !(bestIsSkip && uiNoResidual == ) )
{
DEBUG_STRING_NEW(tmpStr)
// set MC parameters 设置运动补偿参数
rpcTempCU->setPredModeSubParts( MODE_INTER, , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->setCUTransquantBypassSubParts( bTransquantBypassFlag, , uhDepth );
rpcTempCU->setChromaQpAdjSubParts( bTransquantBypassFlag ? : m_ChromaQpAdjIdc, , uhDepth );
rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->setMergeFlagSubParts( true, , , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->setMergeIndexSubParts( uiMergeCand, , , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeCand], , , uhDepth ); // interprets depth relative to LCU level
rpcTempCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMvFieldNeighbours[ + *uiMergeCand], SIZE_2Nx2N, , ); // interprets depth relative to rpcTempCU level
rpcTempCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMvFieldNeighbours[ + *uiMergeCand], SIZE_2Nx2N, , ); // interprets depth relative to rpcTempCU level // do MC 进行运动补偿
m_pcPredSearch->motionCompensation ( rpcTempCU, m_ppcPredYuvTemp[uhDepth] );
// estimate residual and encode everything 计算残差和RDCost,并进行编码
m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU,
m_ppcOrigYuv [uhDepth],
m_ppcPredYuvTemp[uhDepth],
m_ppcResiYuvTemp[uhDepth],
m_ppcResiYuvBest[uhDepth],
m_ppcRecoYuvTemp[uhDepth],
(uiNoResidual != ) DEBUG_STRING_PASS_INTO(tmpStr) ); #ifdef DEBUG_STRING
DebugInterPredResiReco(tmpStr, *(m_ppcPredYuvTemp[uhDepth]), *(m_ppcResiYuvBest[uhDepth]), *(m_ppcRecoYuvTemp[uhDepth]), DebugStringGetPredModeMask(rpcTempCU->getPredictionMode()));
#endif
// 第一次迭代时进行
if ((uiNoResidual == ) && (rpcTempCU->getQtRootCbf() == ))
{
// If no residual when allowing for one, then set mark to not try case where residual is forced to 0
mergeCandBuffer[uiMergeCand] = ;
} rpcTempCU->setSkipFlagSubParts( rpcTempCU->getQtRootCbf() == , , uhDepth );
Int orgQP = rpcTempCU->getQP( );
xCheckDQP( rpcTempCU );
// 更新最优模式
xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth DEBUG_STRING_PASS_INTO(bestStr) DEBUG_STRING_PASS_INTO(tmpStr));
// 重新初始化预测参数,为下一次预测做准备
rpcTempCU->initEstData( uhDepth, orgQP, bTransquantBypassFlag ); if( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip )
{
bestIsSkip = rpcBestCU->getQtRootCbf() == ;
}
}
}
}

// 如果开启earlyDetectionSkip时,第一次迭代执行
if(uiNoResidual == && m_pcEncCfg->getUseEarlySkipDetection())
{
if(rpcBestCU->getQtRootCbf( ) == )
{
if( rpcBestCU->getMergeFlag( ))
{
*earlyDetectionSkipMode = true;
}
else if(m_pcEncCfg->getFastSearch() != SELECTIVE)
{
Int absoulte_MV=;
for ( UInt uiRefListIdx = ; uiRefListIdx < ; uiRefListIdx++ )
{
if ( rpcBestCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > )
{
TComCUMvField* pcCUMvField = rpcBestCU->getCUMvField(RefPicList( uiRefListIdx ));
Int iHor = pcCUMvField->getMvd( ).getAbsHor();
Int iVer = pcCUMvField->getMvd( ).getAbsVer();
absoulte_MV+=iHor+iVer;
}
} if(absoulte_MV == )
{
*earlyDetectionSkipMode = true;
}
}
}
}
}
DEBUG_STRING_APPEND(sDebug, bestStr)
}

HM16.0之帧间Merge模式——xCheckRDCostMerge2Nx2N的更多相关文章

  1. HM16.0之帧间预测——xCheckRDCostInter()函数

    参考:https://blog.csdn.net/nb_vol_1/article/category/6179825/1? 1.源代码: #if AMP_MRG Void TEncCu::xCheck ...

  2. HM16.0之帧内模式——xCheckRDCostIntra()函数

    参考:https://blog.csdn.net/nb_vol_1/article/category/6179825/1? 1.源代码: Void TEncCu::xCheckRDCostIntra( ...

  3. HM16.0 TAppEncoder

    参考:  https://www.cnblogs.com/tiansha/p/6458573.html https://blog.csdn.net/liangjiubujiu/article/deta ...

  4. x264源代码简单分析:宏块分析(Analysis)部分-帧间宏块(Inter)

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  5. Paper | 帧间相关性 + 压缩视频质量增强(MFQE)

    目录 1. ABSTRACT 2. INTRODUCTION 3. RELATED WORKS 3.1. Quality Enhancement 3.2. Multi-frame Super-reso ...

  6. x264代码剖析(十三):核心算法之帧间预測函数x264_mb_analyse_inter_*()

    x264代码剖析(十三):核心算法之帧间预測函数x264_mb_analyse_inter_*() 帧间预測是指利用视频时间域相关性,使用临近已编码图像像素预測当前图像的像素,以达到有效去除视频时域冗 ...

  7. 【HEVC帧间预测论文】P1.7 Content Based Hierarchical Fast Coding Unit Decision Algorithm

    Content Based Hierarchical Fast Coding Unit Decision Algorithm For HEVC <HEVC标准介绍.HEVC帧间预测论文笔记> ...

  8. 【HEVC帧间预测论文】P1.4 Motion Vectors Merging: Low Complexity Prediction Unit Decision

    Motion Vectors Merging: Low Complexity Prediction Unit Decision Heuristic for the inter-Prediction o ...

  9. 【HEVC帧间预测论文】P1.3 Fast Inter-Frame Prediction Algorithm of HEVC Based on Graphic Information

    基于图形信息的HEVC帧间预测快速算法/Fast Inter-Frame Prediction Algorithm of HEVC Based on Graphic Information <H ...

随机推荐

  1. Java容器学习之ArrayList

    一.概述 ArrayList是java中十分常用的集合类,继承于AbstractList,并实现了List.RandomAccess.Cloneable和Serializable接口.ArrayLis ...

  2. adb常用命令大全

    1. 显示系统中全部Android平台:    android list targets2. 显示系统中全部AVD(模拟器):  启动制定模拟器:emulator -avd 模拟器名字    andr ...

  3. 线程_Process基础语法

    """ Process([group[,target[,name[,args[,kwargs]]]]]) group:大多数情况下用不到 target:表示这个进程实例所 ...

  4. SUM and COUNT -- SQLZOO

    SUM and COUNT 注意:where语句中对表示条件的需要用单引号, 下面的译文使用的是有道翻译如有不正确,请直接投诉有道 01.Show the total population of th ...

  5. CF R 635 div1 C Kaavi and Magic Spell 区间dp

    LINK:Kaavi and Magic Spell 一打CF才知道自己原来这么菜 这题完全没想到. 可以发现 如果dp f[i][j]表示前i个字符匹配T的前j个字符的方案数 此时转移变得异常麻烦 ...

  6. 开源后端数据校验插件Validate.Net,类似Validate.js

    介绍 Validate.Net将Validate.js移植到.Net平台,可以更方便.更快捷的校验实体内属性值是否合法.内置多种常规数据校验规则(校验必填.校验字符串长度区间.校验最大最小值.校验值区 ...

  7. python与pycharm的爱恨情仇

    首先大家应该区别 这两者是什么? python 是一门语言 pycharm 是工具 还得交待的是  可以编译python的工具 不止这一款 比如说--eclipse idea ... eclipse中 ...

  8. java交换两个参数值的四种方法

    第一种:添加中间变量,算是最经典最简易的一种了. //添加一个中间变量 int x = 1, y = 2; int z; z = x;x = y;y = z; System.out.println(x ...

  9. 如何解决java高并发详细讲解

    对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...

  10. 2020-04-23:假设一个订单的编号规则是AAAAOrder2020-0000001,AAAAOrder2020-0000002....后面的数字是自增长,如果订单号码达到AAAAOrder2020-1000000(100万),数据库中应该有100万条数据,此时我随机删除2条数据(物理删除,且不考虑日志和备份),请问怎么找到删掉的数据的编号?给出解题思路即可,答案需要在1秒内运行得到。

    福哥答案2020-04-23: 分批查询:分成500次count(),每次count()肯定小于等于2000条数据,经过测试,一次count()在.1ms左右,500次就是500ms.二分法(时间微超 ...