在JM代码中共有3个方法进行RDCost的计算,主要为:

  1. RDCost_for_4x4IntraBlocks,

    JM8.6中三个RDCost函数的对比分析_for循环

    RDCost_for_4x4IntraBlocks被调用的函数

JM8.6中三个RDCost函数的对比分析_熵编码_02

可以发现, RDCost_for_4x4IntraBlocks只被一个函数直接调用, 从调用流程我们就可精确的知道RDCost_for_4x4IntraBlocks的用处:帧内模式I4MB在RDO方式下的计算函数, 主要是计算一个4x4块的RDO代价

  1. RDCost_for_8x8blocks,

    JM8.6中三个RDCost函数的对比分析_计算使用_03

    JM8.6中三个RDCost函数的对比分析_计算使用_04

    该函数一个宏块的4个8x8块在亚宏块模式下进行模式选择的时候, 计算其RDO代价, 根据求得的代价对当前的8x8块选择最佳的P8x8模式

  2. RDCost_for_macroblocks

JM8.6中三个RDCost函数的对比分析_计算使用_05

这个函数很好理解, 对于一个宏块,分别计算在16x16,16x8, 8x16,P8x8,I4MB,I16MB模式下的RDO代价,然后选择最佳的模式, 由于包括的帧内和帧间的所有模式, 所以这个函数可以实现帧内和帧间模式的选择

JM8.6中三个RDCost函数的对比分析_for循环_06

 

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,并且是只考虑了亮度分量

在代码中的表现如下:

JM8.6中三个RDCost函数的对比分析_熵编码_07

JM8.6中三个RDCost函数的对比分析_运动向量_08

JM8.6中三个RDCost函数的对比分析_for循环_09

在函数的最后利用公式计算出RDO下的代价:

JM8.6中三个RDCost函数的对比分析_for循环_10

 

帧间:RDCost_for_8x8blocks 计算的是P8x8 的最优模式代价,用于与其他 inter 模式比较得出最佳 inter 模式,

该函数在encode_one_macroblock函数中的计算亚宏块模式下的一个8x8块的rdcost代价

 //+++RDCost_for_8x8blocks是在4种亚宏块模式中选择最佳的模式(代价)
 //+++
准确来说RDCost_for_8x8blocks主要是得到编号为block8x8,mode模式下的代价

//+++RDCost包括SSDrate两部分:
  //+++(1)SSD,
在此处只计算了亮度分量的失真
  //+++(2)rate,
由于是在帧间的亚宏块模式中进行选择,所以在这儿包括了模式(b8value),运动矢量(writeReferenceFramewriteMotionVector8x8)和亮度残差

具体的代码中如下:

JM8.6中三个RDCost函数的对比分析_熵编码_11

JM8.6中三个RDCost函数的对比分析_运动向量_12JM8.6中三个RDCost函数的对比分析_熵编码_13

在函数的最后JM8.6中三个RDCost函数的对比分析_计算使用_14

 

帧内与帧间比较:RDCost_for_macroblocks 是在最佳 inter 与 intra 之间选择。

这个函数是在encode_one_macroblock函数中进行调用的.主要是在帧间16x16, 16x8, 8x16, P8x8, 帧内Intra4x4, Intra16x16这些模式间进行代价的计算

//+++为了计算代价rdcost,需要计算distortionrate两部分:
 //+++(1)
这个函数中对应distortion的计算使用了亮度分量和色度分量
 //+++(2)
由于这儿是在帧内和帧间模式间进行选择,所以rate考虑了宏块头数据, 模式, 运动向量, 亮度残差数据以及色度残差数据。

在代码中

JM8.6中三个RDCost函数的对比分析_数据_15

JM8.6中三个RDCost函数的对比分析_计算使用_16

JM8.6中三个RDCost函数的对比分析_for循环_17JM8.6中三个RDCost函数的对比分析_运动向量_18

在函数最后

JM8.6中三个RDCost函数的对比分析_数据_19

 

 

摘自:JM8.6核心代码研究

对于计算SSD来说, 有时程序只考虑了亮度分量, 例如RDCost_for_8x8blocks()函数, 有时候, 程序同时考虑了亮度分量和两个色度分量, 例如RDCost_for_macroblock()函数。Rate 表示编码所需要的比特数。程序将调用熵编码函数进行熵编码操作以确定Rate 值。在不同情况下, Rate 有不同的含义。在 Rdcost_for_8x8blocks()函数中, 为了进行帧间的模式选择, Rate的计算过程将编码下列的信息: 模式, 运动矢量和亮度残差数据。在RDCost_for_4x4IntraBlocks()函数中, 为了进行亮度帧内预测模式的选择, Rate只包括模式和亮度残差系数的编码比特数。 而在RDCost_for_macroblock()函数中, 由于同时进行了帧内, 帧间, 亮度和色度的模式选择, Rate 将同时包含以下部分: 宏块头数据, 模式, 运动向量, 亮度残差数据以及色度残差数据。