最近看x264代码,看到帧内模式选择部分,对其中的模式代价计算一头雾水,其实对帧内模式选择一直没有深入底层研究,停留在概念上,“纸上得来终觉浅,要想深入需看代码”。但是要想看懂代码还是要对理论东西有个大体认识。废话少说!
下面是从网上摘过来的:
第一篇:H.264帧内编码的模式选择
H.264中4X4亮度预测依据预测方向的不同共有9种预测模式。在亮度4x4帧内预测时,其中DC预测(模式2)、垂直预测(模式0)和水平预测(模式2总是被认为有效的,即使在编码块上面像素或左边像素不可用的情况下(这时候上面像素或左边像素的值就使用128这个值来代替),而其它模式仅当所有需要利用的预测象素点都可用的情况下才可以使用(如果E, F, G,H不可用,可以用D的值来代替)。这儿所说的像素点可用(available)是指此像素所在的子块存在并且与当前编码的子块属于同一个slice。
模式选择
在H.264帧内编码中,每个宏块亮度信号都要完成9种4x4预测模式和4种16x16预测模式,然后通过预测模式选择,得出一种最佳预测模式使得编码后的图像在码流和图像质量两者权衡后的获得一个最佳。H.264中模式选择方法有两种:
1、使用率失真优化(RDO)模式选择。
使用这种RDO方式的模式选择过程如下:
1)在给定最后解码的帧及宏块的量化因子QP后,计算拉格朗日因子:
X=0.85*QP2 (1)
2)在帧内亮度4x4预测的9种预测模式中,通过计算下面的函数使得其值最小,从中选择最佳的帧内亮度4x4预测模式。
J(s, c, m I QP, Xm )=SSD(s, c, m I QP)+X*R(s, c, m I QP) (2)
式中QP是宏块的量化参数,X是(1)中的拉格朗日因子,SSD是原始的亮度块s与预测模式为m的重建块的平方差的和,R表示与选择模式m相关联的比特数,包括模式编帧内模式及DCT系数所需的比特数。
3)在帧内16x16预测模式中,通过计算4种16x16宏块的SATD(绝对变换差和)使得其值最小来确定最佳16x16亮度帧内预测模式。
4)通过比较一个宏块使用4x4预测模式时计算的RD代价值与使用16x16帧内预测模式时计算得到的最小代价值,选取代价最小的作为最佳预测模式。
2、基于SAD(或SATD)和速率估计的模式选择方法。对于这种模式选择方法,其亮度4x4预测模式的代价函数的计算方法如下所示:
Cost=SAD+4R*λ(QP) (3)
式中λ(QP)是QP的指数函数,4R是对使用某种预测模式后比特数的估计,R根据当前模式是否为最有可能的模式取值为0或1。式中SAD (绝对差值和)计算的差值是预测值与图像像素值的差值,为了更准确的比较每种模式的Cost值,H.264还对这些差值进行Hadamard变换,将差值(这些值最后要变换到频域进行编码)变换到频域求绝对差值和,这样计算得到的值叫作绝对变换差和(SATD)。这里使用Hadamard变换而不是使用DCT变换主要考虑到Hadamard变换比较简单,而又比较接近DCT变换。在计算4x4块的每一种模式的Cost值后,将Cost值最小的模式判决为最佳亮度4x4预测模式。对于亮度信号的16x16模式选择,其开销计算函数如下所示:
Cost =SATD (4)
式中的SATD也是绝对变换差和,其计算时也是将预测值与图像像素值的差值通过使用Hadamard变换,变换到频率域后求和。最后比较一个宏块做一次16xl6预测后的开销值Cost和做16次4x4预测后Cost值相加得到的总的开销值Cost的大小,选取Cost最小的作为最后宏块的预测模式。如果Cost值相同4x4预测模式将被优先选取,而如果9种4x4预测模式或4种4x4预测模式中出现相同Cost值时,序号较小的预测模式将被选为最佳预测模式。
比较两种模式选择方法可以看出,在RDO模式中,R值被精确地计算出,从而使得其模式选择的准确度大大提高,但为了计算R值需要非常复杂的计算,从而使得其运算复杂度很高,而基于SAD的模式选择由于R值是一个估计值避免了复杂的计算,所以速度大大提高,但选择的准确度也会下降。使用RDO模式选择的方法与使用基于SAD的模式选择方法相比,基于SAD的模式选择计算复杂度平均为RDO模式选择的7%,但与使用RDO模式选择相比基于SAD的模式选择方法PSNR平均降低。
一个宏块组合模式选择过程:
a) 对于4x4帧内预测模式建立相应的帧内预测块
b) 计算预测4x4块和原始块4x4块之间的SAD,以及相应的编码比特率
c) 计算该模式的率失真开销Rdcost
d) 重复以上a~c步,遍历所有的9种4x4帧内预测模式
e) 选取具有最小率失真开销的模式作为最佳预测模式
f) 对宏块中16个4x4块重复以上a~e,获得每一个4x4块的最佳模式和相应的Rdcost,进而获得该宏块的总Rdcost
g) 按类似的方法遍历4种16x16宏块的帧内预测模式并计算相应的宏块Rdcost,选取最小的模式为最佳16x16模式
h) 根据f和g中最小的宏块Rdcost,判断亮度宏块采用4x4或16x16帧内预测模式
i) 对每一种8x8色度宏块的帧内预测模式(两个色度宏块使用相同的模式)计算相应的Rdcost,并重复以上a~h,获得相应的宏块组合Rdcost作为该宏块组合的最佳帧内预测模式。
第二篇:
Q:如果不用率失真最优化,为什么选择SATD+delta×r(mv,mode)作为模式选择的依据?为什么运动估计中,整象素搜索用SAD,而亚象素用SATD?为什么帧内模式选择要用SATD?
A:
SAD即绝对误差和,仅反映残差时域差异,影响PSNR值,不能有效反映码流的大小。SATD即将残差经哈德曼变换的4×4块的预测残差绝对值总和,可以将其看作简单的时频变换,其值在一定程度上可以反映生成码流的大小。因此,不用率失真最优化时,可将其作为模式选择的依据。
一般帧内要对所有的模式进行检测,帧内预测选用SATD的原因同上。
在做运动估计时,一般而言,离最优匹配点越远,匹配误差值SAD越大,这就是有名的单一平面假设,现有的运动估计快速算法大都利用该特性。但是,转换后SATD值并不满足该条件,如果在整象素中运用SATD搜索,容易陷入局部最优点。而在亚象素中,待搜索点不多,各点处的SAD差异相对不大,可以用SATD选择码流较少的匹配位置。
·几种常见的算术名词缩写。
SAD(Sum of Absolute Difference)=SAE(Sum of Absolute Error)即绝对误差和
SATD(Sum of Absolute Transformed Difference)即hadamard变换后再绝对值求和
SSD(Sum of Squared Difference)=SSE(Sum of Squared Error)即差值的平方和
MAD(Mean Absolute Difference)=MAE(Mean Absolute Error)即平均绝对差值
MSD(Mean Squared Difference)=MSE(Mean Squared Error)即平均平方误差
众所周知,评价编码效率的有两大指标:码率和PSNR。码流越小,则压缩率越大;PSNR越大,重建图像越好。在模式选择的时候,判别公式实质上也就是对二者的综合评价。
首先以RDO为例,模式对应的代价:J(mode)=SSD+λ*R(ref,mode,mv,residual)
这里,SSD是指重建块与源图像的差值均方和;λ是拉格朗日乘子,就当是权值吧^_^;R就是该模式下宏块编码的实际码流,包括对参考帧、模式、运动矢量、残差等的比特总和。当然如果是帧内模式,就只有R(mode,residual)。
很多人迷惑的是,改宏块还没编码啊,怎么知道它的码流和重建图像?实际上,RDO就是对每个模式都实际编码一次,得到J(mode),然后选择J(mode)最小的模式为实际编码模式。就像编码器引入了一个大反馈,这也正是JM选用RDO编码起来龟速的原因,当然,编码效率最佳。
后来,“随意”注意到,不论熵编码选用cavlc还是cabac,各个模式下的residual编码都使用cavlc,这就是说选用cabac,模式选择时得到的R不是实际的R,为什么此时不用cabac呢?难道cabac复杂么?我的看法是因为cabac会对模型表更新数据。解码端是没有模式选择模块的,如果编码端此时使用cabac,会造成编解码端模型表不匹配,不能正常解码。
λ的取值是根据实验得到的。使用B帧与使用B帧的λ值是不一样的。具体值忘了,^_^,看相关文章。
前已所述,RDO包含各模式的实际编码过程,也就是变换量化、熵编码、反变换反量化、重建等,计算量是相当大的,实时编码领域不可能直接使用。因此,就有了下面的替代公式:
J(mode)=SAD+λ*R(ref,mode,mv)
J(mode)=SATD+λ*R(ref,mode,mv)
这里SAD就是该模式下预测块与源图像的绝对误差和。比特R中少了对residual的编码,也就是运动估计后就可以直接得到该模式的J(mode)值,极大的减少了运算复杂度。SATD就是对残差进行哈德曼变换后的系数绝对和,在大多数情形下,SATD比SAD评价效果更好些,我对foreman CIF图像的测试,psnr增加了约0.2db,码流差不多。当然,SATD比SAD多了个变换,计算量大些。
注意,此时的λ与RDO的λ取值是不一样的。
容易困惑的还有,运动估计的匹配准则,很多运动估计的论文中都直接是SAD或SSE。编码器中对残差、MV、ref都要编码,所以匹配准则也就是SAD和码流R的综合评价!!!在同一个模式下,参考块与编码块的不同信息有ref、MV,故匹配准则为:
Jmotion=SAD+λ*R(ref,mv)
最后,附上我以前在群“H264乐园”中的帖子,
Q:如果不用率失真最优化,为什么选择SATD+delta×r(mode,ref,mv)作为模式选择的依据?为什么运动估计中,整象素搜索用SAD,而亚象素用SATD?为什么帧内模式选择要用SATD?
A:
SAD即绝对误差和,仅反映残差时域差异,影响PSNR值,不能有效反映码流的大小。SATD即将残差经哈德曼变换的4×4块的预测残差绝对值总和,可以将其看作简单的时频变换,其值在一定程度上可以反映生成码流的大小。因此,不用率失真最优化时,可将其作为模式选择的依据。
一般帧内要对所有的模式进行检测,帧内预测选用SATD的原因同上。
在做运动估计时,一般而言,离最优匹配点越远,匹配误差值SAD越大,这就是有名的单一平面假设,现有的运动估计快速算法大都利用该特性。但是,转换后SATD值并不满足该条件,如果在整象素中运用SATD搜索,容易陷入局部最优点。而在亚象素中,待搜索点不多,各点处的SAD差异相对不大,可以用SATD选择码流较少的匹配位置。