JM8.6中encode_one_macroblock函数的运作流程
JM8.6中encode_one_macroblock函数的运作流程[宏块代价函数的使用或帧间帧内模式选择流程]
在JM中最重要, 最核心的一个函数就是encode_one_macroblock, 这个函数是整个编码器的核心, 其实, 通过读源码,可以发现, encode_one_macroblock中的大部分工作是在进行模式的选择, 下面我们跟着代码走一下, 看看具体的流程: (我们假设帧间帧内同时都允许)
1. 帧间三种帧间宏块级模式( 16×16, 16×8,8×16) 循环, 进行择优
同时将min_cost初始化为最大值, 将best_mode初始化为1(16x16)
1.1. 对三种模式下的每一个块进行计算最佳代价
16*16 分割方式只需要计算一次,16*8 和8*16 分割方式需要计算两次
1.1.1 运动搜索
在函数PartitionMotionSearch中对模式mode进行运动搜索, 在搜索中利用MV_COST计算搜索代价, 得到该模式下的最优代价保存在motion_cost中及最佳MV保存在 img->all_mv中.
其中也包含对非RDO 方式下P 帧SKIP 模式的择优
1.1.2 参考帧择优
在计算时利用代价函数REF _COST得到参考帧代价, 并且加上对应模式下对应参考帧的搜索代价, 总起来作为代价进行参考帧的选择(在利用REF_COST时根据是否是RDO进行区分,如果使用的是RDO方式, 则选择该方式下的最优参考帧.
另外对于B帧的情况要考虑后向参考和双向参考的情况.
对于P帧的情况,也就是前向参考的情况
只将前向参考代价加入到cost中, cost是以整个宏块的所有代价和
1.2 根据一整个宏块的代价选择出最优的代价
2. 帧间亚宏块模式( P8x8 模式:8x8,8x4,4x8,4x4)循环,进行择优
对于一个整宏块是分为4个8x8块, 然后每个8x8块进行P8x8模式的选择
进行P8x8选择时, 先初始化min_cost8x8(非RDO)为最大, min_rdcost(RDO)为最大
2. 1 运动搜索,
与宏块级类似
代价函数用MV _ COST (包含对非RDO 方式下P 帧SKIP 模式的择优) ;
step2. 2 参考帧择优, 代价函数用 REF _COST ;
step2. 3 块模式择优, 代价函数用 MODE _COST ;
step2. 4 对于非RDO 方式,将step2. 3 的择优结果与step1 中的最佳大模式进行比较决策,选出最优
模式。
step3 所有模式择优
step3. 1 RDO 方式下,对三种帧间大块模式、 最佳P8 模式、 两种帧内预测模式以及SKIP、 DIRECT
模式进行RDO 模式代价MODE _ COST 的比较择优:
step3. 1. 1 四种色度块帧内预测模式循环;
step3. 1. 2 设置运动预测和参考帧模式;
step3. 1. 3 计算七种模式的 RDO 模式代价MODE_ COST ,进行比较决策。
step3. 2 非RDO 方式下,将step2 的择优结果与DIRECT 模式、 帧内预测模式进行比较择优:
step3. 2. 1 获得DIRECT 模式下的代价MODE_ COST ,进行比较择优;
step3. 2. 2 进行4×4 和16×16 的帧内预测, 用MODE_ COST 对预测模式择优。