在JM代码中共有3个方法进行RDCost的计算,主要为:
-
RDCost_for_4x4IntraBlocks,
RDCost_for_4x4IntraBlocks被调用的函数
可以发现, RDCost_for_4x4IntraBlocks只被一个函数直接调用, 从调用流程我们就可精确的知道RDCost_for_4x4IntraBlocks的用处:帧内模式I4MB在RDO方式下的计算函数, 主要是计算一个4x4块的RDO代价
-
RDCost_for_8x8blocks,
该函数一个宏块的4个8x8块在亚宏块模式下进行模式选择的时候, 计算其RDO代价, 根据求得的代价对当前的8x8块选择最佳的P8x8模式
- RDCost_for_macroblocks
这个函数很好理解, 对于一个宏块,分别计算在16x16,16x8, 8x16,P8x8,I4MB,I16MB模式下的RDO代价,然后选择最佳的模式, 由于包括的帧内和帧间的所有模式, 所以这个函数可以实现帧内和帧间模式的选择
2011年4月24日9:31:52
JM8.6中的RDO代价函数的分析: RDCost_for_8x8blocks, RDCost_for_macroblocks, RDCost_for_4x4IntraBlocks
在JM8.6中有三种计算RDO模式下代价的函数,分别为RDCost_for_8x8blocks, RDCost_for_macroblocks和RDCost_for_4x4IntraBlocks
帧内:RDCost_for_4x4Intrablocks是用于帧内I4MB模式的选择,
这个函数是在函数Mode_Decision_for_4x4IntraBlocks
中进行调用的, Mode_Decision_for_4x4IntraBlocks函数就是为了对于4x4块进行帧内9种模式的选择.在这个函数中.首先利用函数intrapred_luma计算出了9种模式下对应的预测值,存储在数组img->mprr[9*16*16]中,然后对9种模式进行for循环,在该for循环中,在进行9种模式的代价比较计算的时候,分RDO和非RDO两种情况,
在非RDO模式下,只考虑了SATD,最后的最优代价保存在 min_cost变量中,
在RDO模式下,由于考虑了到了rate,所以在函数RDCost_for_4x4Intrablocks中进行计算.在进入RDCost_for_4x4Intrablocks之前,先保存当前的编码状态,因为在RDCost_for_4x4Intrablocks函数中要进行编码,解码(重构)的过程.在RDCost_for_4x4Intrablocks函数中,因为是为了进行帧内9种模式的选择,所以Rate计算的时候只会考虑到了模式和亮度残差系数的编码比特数.并且对于distortion利用的是SSD,并且是只考虑了亮度分量
在代码中的表现如下:
在函数的最后利用公式计算出RDO下的代价:
帧间:RDCost_for_8x8blocks 计算的是P8x8 的最优模式代价,用于与其他 inter 模式比较得出最佳 inter 模式,
该函数在encode_one_macroblock函数中的计算亚宏块模式下的一个8x8块的rdcost代价
//+++RDCost_for_8x8blocks是在4种亚宏块模式中选择最佳的模式(代价)
//+++准确来说RDCost_for_8x8blocks主要是得到编号为block的8x8块,在mode模式下的代价
//+++RDCost包括SSD和rate两部分:
//+++(1)SSD,在此处只计算了亮度分量的失真
//+++(2)rate,由于是在帧间的亚宏块模式中进行选择,所以在这儿包括了模式(b8value),运动矢量(writeReferenceFrame和writeMotionVector8x8)和亮度残差
具体的代码中如下:
在函数的最后
帧内与帧间比较:RDCost_for_macroblocks 是在最佳 inter 与 intra 之间选择。
这个函数是在encode_one_macroblock函数中进行调用的.主要是在帧间16x16, 16x8, 8x16, P8x8, 帧内Intra4x4, Intra16x16这些模式间进行代价的计算
//+++为了计算代价rdcost,需要计算distortion和rate两部分:
//+++(1)这个函数中对应distortion的计算使用了亮度分量和色度分量
//+++(2)由于这儿是在帧内和帧间模式间进行选择,所以rate考虑了宏块头数据, 模式, 运动向量, 亮度残差数据以及色度残差数据。
在代码中
在函数最后
摘自:JM8.6核心代码研究
对于计算SSD来说, 有时程序只考虑了亮度分量, 例如RDCost_for_8x8blocks()函数, 有时候, 程序同时考虑了亮度分量和两个色度分量, 例如RDCost_for_macroblock()函数。Rate 表示编码所需要的比特数。程序将调用熵编码函数进行熵编码操作以确定Rate 值。在不同情况下, Rate 有不同的含义。在 Rdcost_for_8x8blocks()函数中, 为了进行帧间的模式选择, Rate的计算过程将编码下列的信息: 模式, 运动矢量和亮度残差数据。在RDCost_for_4x4IntraBlocks()函数中, 为了进行亮度帧内预测模式的选择, Rate只包括模式和亮度残差系数的编码比特数。 而在RDCost_for_macroblock()函数中, 由于同时进行了帧内, 帧间, 亮度和色度的模式选择, Rate 将同时包含以下部分: 宏块头数据, 模式, 运动向量, 亮度残差数据以及色度残差数据。