HEVC代码学习8:xMotionEstimation函数
来源:互联网 发布:客单价方面的优化 编辑:程序博客网 时间:2024/05/21 04:24
之前学习了xPatternSearchFracDIF函数,今天来学习其上层的xMotionEstimation函数,从字面就可以理解,功能是进行运动估计。
xMotionEstimation是运动估计的入口函数,通过调用xPatternSearch、xPatternSearchFast、xPatternSearchFracDIF进行运动搜索。主要工作流程是:进行一些初始化,设置搜索范围,然后通过整像素搜索得到一个最优点,将这个最优点作为起点进行亚像素搜索,最终得到以1/4精度为单位的MV。
Void TEncSearch::xMotionEstimation( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, RefPicList eRefPicList, TComMv* pcMvPred, Int iRefIdxPred, TComMv& rcMv, UInt& ruiBits, Distortion& ruiCost, Bool bBi ){ UInt uiPartAddr; Int iRoiWidth; Int iRoiHeight; TComMv cMvHalf, cMvQter; //定义1/2和1/4精度MV TComMv cMvSrchRngLT; TComMv cMvSrchRngRB; TComYuv* pcYuv = pcYuvOrg; //图像首地址 assert(eRefPicList < MAX_NUM_REF_LIST_ADAPT_SR && iRefIdxPred<Int(MAX_IDX_ADAPT_SR)); m_iSearchRange = m_aaiAdaptSR[eRefPicList][iRefIdxPred]; //根据参考帧列表类型、参考帧序号自适应设置搜索范围 Int iSrchRng = ( bBi ? m_bipredSearchRange : m_iSearchRange ); //根据是否是双向预测设置搜索范围 TComPattern tmpPattern; TComPattern* pcPatternKey = &tmpPattern; // TComPattern是用于访问相邻块/像素的一个工具类,用于获取neighbor的信息 Double fWeight = 1.0; pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight ); //获取PU的地址,宽度和高度 if ( bBi ) //B帧 { TComYuv* pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList]; pcYuv = &m_cYuvPredTemp; pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight ); pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight, pcCU->getSlice()->getSPS()->getBitDepths().recon, m_pcEncCfg->getClipForBiPredMeEnabled() ); fWeight = 0.5; } // Search key pattern initialization 初始化待搜索的PU的首地址,宽度,高度,跨度,比特深度 pcPatternKey->initPattern( pcYuv->getAddr ( COMPONENT_Y, uiPartAddr ), iRoiWidth, iRoiHeight, pcYuv->getStride(COMPONENT_Y), pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA) ); //获取参考图像首地址和跨度 Pel* piRefY = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getAddr( COMPONENT_Y, pcCU->getCtuRsAddr(), pcCU->getZorderIdxInCtu() + uiPartAddr ); Int iRefStride = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getPicYuvRec()->getStride(COMPONENT_Y); TComMv cMvPred = *pcMvPred; //设置运动估计的搜索范围,LeftTop & RightBottom if ( bBi ) { xSetSearchRange ( pcCU, rcMv , iSrchRng, cMvSrchRngLT, cMvSrchRngRB ); } else { xSetSearchRange ( pcCU, cMvPred, iSrchRng, cMvSrchRngLT, cMvSrchRngRB ); } m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) ); //计算率失真代价 m_pcRdCost->setPredictor ( *pcMvPred ); //设置预测得到的MV m_pcRdCost->setCostScale ( 2 ); setWpScalingDistParam( pcCU, iRefIdxPred, eRefPicList ); //设置跟weighted prediction相关的参数 // Do integer search 整像素搜索 if ( !m_iFastSearch || bBi ) { // 如果是B帧或者不是快速搜索模式,进行常规搜索 xPatternSearch ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost ); } else { // 进行快速搜索 rcMv = *pcMvPred; const TComMv *pIntegerMv2Nx2NPred=0; if (pcCU->getPartitionSize(0) != SIZE_2Nx2N || pcCU->getDepth(0) != 0) { pIntegerMv2Nx2NPred = &(m_integerMv2Nx2N[eRefPicList][iRefIdxPred]); } xPatternSearchFast ( pcCU, pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost, pIntegerMv2Nx2NPred ); if (pcCU->getPartitionSize(0) == SIZE_2Nx2N) { m_integerMv2Nx2N[eRefPicList][iRefIdxPred] = rcMv; } } m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) ); m_pcRdCost->setCostScale ( 1 ); const Bool bIsLosslessCoded = pcCU->getCUTransquantBypass(uiPartAddr) != 0; xPatternSearchFracDIF( bIsLosslessCoded, pcPatternKey, piRefY, iRefStride, &rcMv, cMvHalf, cMvQter, ruiCost ); //分像素搜索 m_pcRdCost->setCostScale( 0 ); rcMv <<= 2; //整像素 rcMv += (cMvHalf <<= 1); //1/2像素 rcMv += cMvQter; //1/4像素,最终MV单位为1/4精度 UInt uiMvBits = m_pcRdCost->getBits( rcMv.getHor(), rcMv.getVer() ); ruiBits += uiMvBits; ruiCost = (Distortion)( floor( fWeight * ( (Double)ruiCost - (Double)m_pcRdCost->getCost( uiMvBits ) ) ) + (Double)m_pcRdCost->getCost( ruiBits ) );}
1 0
- HEVC代码学习8:xMotionEstimation函数
- HEVC代码追踪(十一。三):运动估计/补偿之xMotionEstimation
- HEVC代码学习2:TAppEncTop::encode函数
- HEVC代码学习3:TEncTop::encode函数
- HEVC代码学习7:xPatternSearchFracDIF函数
- HEVC代码学习9:getInterMergeCandidates函数
- HEVC代码学习11:xCompressCU函数
- HEVC代码学习12:xCheckRDCostInter函数
- HEVC代码学习13:predInterSearch函数
- HEVC代码学习14:motionCompensation函数
- HEVC代码学习15:AMVP相关函数
- HEVC代码学习20:xPatternSearchFast函数
- HEVC代码学习21:xTZSearch函数
- HEVC代码学习22:xTZSearchHelp函数
- HEVC代码学习23:xTZ8PointDiamondSearch函数
- HEVC代码学习24:encodeResAndCalcRdInterCU函数
- HEVC代码学习25:xDecompressCU函数
- HEVC代码学习27:calcRdCost函数
- SpringMVC简单实现国际化/多语言
- 最近二维点对
- idea新建maven项目
- 在css让图片自适应容器(div)大小
- C#中多态性的理解
- HEVC代码学习8:xMotionEstimation函数
- 选择排序,冒泡排序,归并排序,快速排序,堆排序等等
- PHP统计在线用户数
- Python学习笔记
- 如何在本地打开远程服务端口
- Shiro系列教程ShiroFilter源码分析
- spring容器启动事件和关闭事件
- NWBC连接配置及使用
- LIUNX inode 空间饱和,耗尽 的 排查,解决方法