1. 双向预测
一直谈了文献【1】那么久,并没有真正对双向预测进行学习,这里将要说明一下JMVC中的双向预测。这里就以16x16的模式进行说明,在xEstimateMb16x16()中,以下代码便开始了双向预测,
//===== BI PREDICTION =====
if( rcRefFrameList0.getActive() && rcRefFrameList1.getActive() )
除了一些设置的中间标志量,值得一提的就是cBSParams.pcAltRefPelData = &cYuvMbBuffer[1-uiDir]; 这里cYuvMbBuffer是IntYuvMbBuffer类的对象,存放了宏块yuv数据。pcAltRefPelData首次被赋值时,是list1的最佳匹配宏块的IntYuvMbBuffer值,然后在叠代搜索过程中,被最佳匹配的宏块数据所更新(在m_pcMotionEstimation->compensateBlock( &cYuvMbBuffer[uiDir],PART_16x16, MODE_16x16 ) 中)。这个pcAltRefPelData的作用是在加权预测中被用于计算当前宏块数据的双向加权预测值。
以上内容虽然复杂,但是还不是重点,重点是B宏块是怎么和前后两个块匹配的,又如何叠代?
对于BI PREDICTION由于uiSearchRange非零,代码将进入xPelBlockSearch()进行范围从-8到8的整像素搜索。看看XDistSearchStruct的对象m_cXDSS,这个对像将存储用于运动估计宏块的的YUV原始值和预测值,还存储使用的RDCost函数指针。estimateBlockWithStart()中在完成加权预测后,有一段代码如下:
m_pcXDistortion->getDistStruct( uiMode, m_cParams.getFullPelDFunc(), false, m_cXDSS ); ......语句1
m_cXDSS.pYOrg = pcWeightedYuvBuffer->getLumBlk();
m_cXDSS.pUOrg = pcWeightedYuvBuffer->getCbBlk ();
m_cXDSS.pVOrg = pcWeightedYuvBuffer->getCrBlk ();
这里的代码就是分别进行RDCost函数指针初始化和经过加权预测的当前宏块的的YUV原始值赋值,语句1中第4个参数是false,正是这个参数控制了是够使用双向预测,从这里的代码看,JMVC没有真正的使用双向预测。代码调试试验显示,在xPelBlockSearch()进行整像素搜索时,使用的计算SAD的函数为单向的。因为代码实际使用的SAD计算公式是xGetSAD16x而非xGetBiSAD16x,后者使用的是前后两个参考帧相关宏块的Y平均值和当前宏块比较。
那么当前进入比较是谁呢?是进入叠代的单一参考帧,他们的初始化在xPelBlockSearch()中
m_cXDSS.pYSearch = pucYSearch + x;
m_cXDSS.pUSearch = pucURef + (y>>1)*iCStride + (x>>1);
m_cXDSS.pVSearch = pucVRef + (y>>1)*iCStride + (x>>1);
从调试试验,可以以比较下面的数据:
===================pYOrg ====================================
85 85 83 92 91 89 86 88 88 84 81 78 79 83 83 80
86 83 81 86 83 83 86 88 84 83 78 73 74 74 78 82
87 90 86 91 86 86 83 85 77 80 81 78 75 79 83 85
83 86 86 85 82 84 87 83 77 77 77 74 73 83 83 81
80 83 85 84 83 87 88 82 80 77 76 73 76 83 81 83
78 83 89 86 85 85 84 82 82 77 76 75 78 79 77 81
74 80 94 91 86 84 81 83 83 80 79 79 76 73 69 74
77 83 89 88 85 85 85 83 81 81 80 77 77 80 76 82
83 87 91 92 93 89 83 79 81 83 81 71 69 72 72 78
86 90 90 82 87 87 85 79 83 83 82 76 71 74 78 78
85 90 90 78 83 87 83 81 87 85 81 80 78 77 77 77
85 87 88 82 83 81 81 81 89 87 82 82 85 83 79 77
85 85 81 84 84 88 90 90 82 84 80 82 85 79 75 79
81 81 83 85 88 92 96 96 80 80 84 82 81 71 67 71
85 85 89 89 92 90 92 90 76 76 84 83 78 72 72 76
85 89 93 91 94 90 88 90 80 80 84 83 78 72 74 80
===================pYSearch =================================
76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76
79 79 79 79 79 79 79 79 79 79 79 79 79 79 78 78
80 80 80 80 80 80 80 80 80 80 80 80 80 80 79 79
83 83 83 83 83 83 83 83 83 83 83 83 83 83 81 80
84 84 84 84 84 84 84 84 84 84 84 84 84 84 82 81
87 87 87 87 87 87 87 87 87 87 87 87 87 87 84 83
87 87 87 87 87 87 87 87 87 87 87 87 87 87 84 83
87 87 87 87 87 87 87 87 87 87 87 87 87 87 84 83
87 87 87 87 87 87 87 87 87 87 87 87 87 87 84 83
87 87 87 87 87 87 87 87 87 87 87 87 87 87 85 84
87 87 87 87 87 87 87 87 87 87 87 87 87 87 85 84
87 87 87 87 87 87 87 87 87 87 87 87 87 87 85 84
87 87 87 87 87 87 87 87 87 87 87 87 87 87 86 85
87 87 87 87 87 87 87 87 87 87 87 87 87 87 86 85
87 87 87 87 87 87 87 87 87 87 87 87 87 87 86 85
87 87 87 87 87 87 87 87 87 87 87 87 87 87 86 85
76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76
79 79 79 79 79 79 79 79 79 79 79 79 79 78 78 76
80 80 80 80 80 80 80 80 80 80 80 80 80 79 79 76
83 83 83 83 83 83 83 83 83 83 83 83 83 81 80 80
84 84 84 84 84 84 84 84 84 84 84 84 84 82 81 80
87 87 87 87 87 87 87 87 87 87 87 87 87 84 83 80
87 87 87 87 87 87 87 87 87 87 87 87 87 84 83 80
87 87 87 87 87 87 87 87 87 87 87 87 87 84 83 80
87 87 87 87 87 87 87 87 87 87 87 87 87 84 83 81
87 87 87 87 87 87 87 87 87 87 87 87 87 85 84 81
87 87 87 87 87 87 87 87 87 87 87 87 87 85 84 82
87 87 87 87 87 87 87 87 87 87 87 87 87 85 84 83
87 87 87 87 87 87 87 87 87 87 87 87 87 86 85 83
87 87 87 87 87 87 87 87 87 87 87 87 87 86 85 84
87 87 87 87 87 87 87 87 87 87 87 87 87 86 85 84
87 87 87 87 87 87 87 87 87 87 87 87 87 86 85 84
76 76 76 76 76 76 76 76 76 76 76 76 76 76 76 76
79 79 79 79 79 79 79 79 79 79 79 79 78 78 76 76
80 80 80 80 80 80 80 80 80 80 80 80 79 79 76 76
83 83 83 83 83 83 83 83 83 83 83 83 81 80 80 79
84 84 84 84 84 84 84 84 84 84 84 84 82 81 80 79
87 87 87 87 87 87 87 87 87 87 87 87 84 83 80 79
87 87 87 87 87 87 87 87 87 87 87 87 84 83 80 79
87 87 87 87 87 87 87 87 87 87 87 87 84 83 80 79
87 87 87 87 87 87 87 87 87 87 87 87 84 83 81 80
87 87 87 87 87 87 87 87 87 87 87 87 85 84 81 80
87 87 87 87 87 87 87 87 87 87 87 87 85 84 82 81
87 87 87 87 87 87 87 87 87 87 87 87 85 84 83 82
87 87 87 87 87 87 87 87 87 87 87 87 86 85 83 82
87 87 87 87 87 87 87 87 87 87 87 87 86 85 84 83
87 87 87 87 87 87 87 87 87 87 87 87 86 85 84 83
87 87 87 87 87 87 87 87 87 87 87 87 86 85 84 83
它们分别是当前宏块的Y值和list0的预测块的Y值,可以看见预测块在做全像素搜索的水平偏移关系。这些预测块的值来自estimateBlockWithStart()函数
pcRefPelData[0] = const_cast<IntFrame&>(rcRefFrame).getFullPelYuvBuffer();
叠代搜索是以单一参考帧的最优预测值为起点,进行范围为8的全像素搜索的,它的可以在RDCost得不到持续减小时提前终止(用bChanged控制),否则完成配置定义的搜索次数。
完成代码的查看,来讨论一下当前代码的叠代搜索增益,为什么在叠代搜索中不用快速搜索算法呢?我认为,对list0,list1的估计过程中使用快速搜索,例如xTZSearch,叠代搜索的增益来自其对最优点附近的(小范围)全像素搜索。如果对之前估计过程已经使用全像素搜索,当前代码的叠代搜索将没有增益。从我的一组实验中可以看看如果在叠代搜索中使用xTZSearch会取得怎样的效果。下图展示了叠代预测中把JMVC代码默认的xPelBlockSearch替换成xTZSearch的比较效果,帧是取自ballroom2.yuv的前9帧,GOPSize=8,统计图中是GOP中的6个B帧按编码顺序排列。如图所示,在使用快速搜索后,每帧编码时间下降了1/4,编码质量下降在0.015DB之内。
***************************实验数据*************************
xPelBlockSearch: 9 frames encoded: Y 32.3391 dB U 37.8961 dB V 37.7462 dB
xTZSearch: 9 frames encoded: Y 32.3356 dB U 37.8913 dB V 37.7326 dB
******************************************************************************
可以考虑修改代码实现xGetBiSAD16x来进行双向搜索,并优化实现双向搜索。(todo:留着作学生毕设课题 )
2.亚像素搜索
在完成了整像素搜索后,MotionEstimationQuarterPel::xSubPelSearch()将被调用作亚像素搜索。如同代码的其他部分,bQPelOnly被设置为不起作用,可以跳过所有bQPelOnly的作用区域。亚像素是先围绕最佳整像素点进行1/2像素搜索,然后在最佳点周围再进行1/4,逐步求精。如下图:
再来分析一下具体程序,rcMv传进来整数搜索的最佳点,函数MotionEstimationQuarterPel::xCompensateBlocksHalf()的作用就是从具体的内存单元中取得1/2像素的Y值信息,辗转找了半天,这些1/2像素点值是在QuarterPelFilter::filterFrame()被设进来的,而1/4像素点则在这里的m_pcQuarterPelFilter->filterBlock()里具体计算。这些点采用不同的插值滤波器由整像素点生成,具体的数学过程可以参考文献【2】。
陆续花了四周时间,总算把运动估计部分弄清楚了,具体的视差估计还没有在代码中实现,这应该是立体视频最精彩的部分,参考模型给我们预留了很多空间,等以后计算机视觉的学习有一些积累后再进行探讨。下周(2009.6.22-2009.6.28)将探讨一些参考帧管理和数据IO之类的琐事,为以后的继续深入学习打好基础。
【参考文献】
1. Siu-Wai Wu and Allen Gersho, "Joint Estimation of Forward and Backward Motion
Vectors for Interpolative Prediction of Video"
2. 毕厚杰, “新一代视频压缩编码标准:H.264/AVC”
(jacky) |