转载于http://blog.csdn.net/mashiying2013/article/details/10068927

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相关推荐

  1. HEVC---CompressCU 函数解析

    看过好几次CompressCU函数,都是一知半解.这次要做的是把模式保留下来,可以减少熵编码的比特数.这样就必须彻底的弄清楚CU的递归的划分也就是xcompressCU这个函数.这样才知道什么时候保存 ...

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

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

  3. 【HEVC】1、HM-16.7编码器的基本结构

    编码器在整个HM解决方案中的工程名为TAppEncoder,入口点函数位于encmain.cpp文件中: 1 int main(int argc, char* argv[]) 2 { 3 TAppEn ...

  4. HEVC---xCompressCU()函数作用及位置

    xCompressCU( )作为HEVC编码器最重要的函数之一,主要是确定CU的分割深度.预测模式等参数. (一) xCompressCU( )位置 以HM16.5版本为例进行分析,在工程" ...

  5. HEVC: 整个编码流程以及相关的函数介绍

    本文转载自https://blog.csdn.net/qq_39348150/article/details/78422117 来自网上的文档,但是最初来源不知道是哪,谢谢这个作者! 整个流程可以从c ...

  6. HEVC里面CU与TU打印到屏幕及提取到txt文本

    测试模型为HM16.5 在解决方案资源管理器里面找到项目TlibEncoder,会看到里面有个源文件TencCU.cpp (1)打印到屏幕 (在TencCU.cpp的xCompressCU函数(237 ...

  7. HEVC中打印CU划分

    转载,原文地址:http://blog.csdn.net/minbiao880224/article/details/17685935,结合我的第一篇HM编码的使用,自己完全可以理解他的MATLAB代 ...

  8. 三、使用HM进行简单的视频隐写demo

    三.使用HM进行简单的视频隐写 前言 一.实验环境 二.实验思路 三.实验过程 3.1 提取原始载体 3.2 使用LSB隐写算法进行隐写 3.3 放回含密载体 3.4 提取含密载体 3.5 使用LSB ...

  9. HM编码器代码阅读(13)——帧间预测之AMVP模式(一)总体流程

    帧间预测的原理 AMVP的原理 帧间预测的实质就是为当前的PU在参考帧中寻找一块最相似块(相似度的判断准则有SAD等方法).但是参考图像通常都比较大,我们直接去搜索的话就太费时了,应该使用某种方法在参 ...

  10. VVC/VTM:代码学习——CIIP详细过程

    位于函数void EncCu::xCheckRDCostMerge2Nx2N()中 原理介绍:VVC/VTM:帧间预测--Combined inter and intra prediction (CI ...

最新文章

  1. java获取客户端硬件信息_java如何获取远程计算机的系统信息,cpu使用情况,磁盘使用情况等等...
  2. 专访Mycat核心开发成员王金剑 :借助Mycat轻松抵御海量并发
  3. Python之深入解析如何使用Python Kivy实现一个“乒乓球”游戏
  4. Java多线程知识小抄集(二)
  5. 使用ViewPager制作Android引导界面
  6. Qt工作笔记-列表的分页显示(Qt Widgets框架)
  7. SpringBoot-技术专区-详细打印启动时异常堆栈信息
  8. 工作分析文献综述_学术知识| 如何撰写文献综述
  9. android表格布局的属性,android:TableLayout表格布局详解
  10. 最小生成树(Prim算法和Kruskal算法)
  11. 软件工程——系统流程图符号及案例
  12. Linux_标准IO
  13. 项目在使用easyui时遇到的问题
  14. 人人都是系统装机高手,利用windows官方的工具,安装超简单
  15. 【大数据入门核心技术-HBase】(八)Phoenix简介
  16. 设计模式C++实现40讲(11)终生受益的观察者模式
  17. 来自2021秋招人的总结
  18. Verilog 多路选择器(MUX)
  19. html5画布星空,HTML5 Canvas星空|星域背景图生成器
  20. 陆奇看好的创业项目,16/22 个都由 AI 驱动

热门文章

  1. python最全画地图,可视化数据
  2. 如何读取书生sep文档内容
  3. 简单介绍Hadoop实操
  4. 英文期刊论文翻译格式要求和文献要求
  5. 文华财经期货买卖点指标源码,期货超短线指标公式源码
  6. React之网易云音乐(实现唱片滚动以及lrc歌词滚动效果)
  7. python网易云_python 网易云音乐
  8. R语言系统教程(一):向量及其相关操作
  9. 短信平台API接口集成指南
  10. tensorflow 中MNIST数据集下载