现在的位置: 首页 > 综合 > 正文

x264宏块模式选择

2013年10月15日 ⁄ 综合 ⁄ 共 3507字 ⁄ 字号 评论关闭

转】x264宏块模式选择

   选择模式前,先把mb模块的类型列举出来。
enum mb_class_e
{    
//以I_表示的是I帧内的宏块模式,采用帧内预测
I_4x4           = 0,
I_8x8           = 1,
I_16x16         = 2,
I_PCM           = 3,
//P帧的宏块模式
P_L0            = 4,
P_8x8           = 5,
P_SKIP          = 6,
//B帧的宏块模式
B_DIRECT        = 7,
B_L0_L0         = 8,
B_L0_L1         = 9,
B_L0_BI         = 10,
B_L1_L0         = 11,
B_L1_L1         = 12,
B_L1_BI         = 13,
B_BI_L0         = 14,
B_BI_L1         = 15,
B_BI_BI         = 16,
B_8x8           = 17,
B_SKIP          = 18,

X264_MBTYPE_MAX = 19
};
1.p/b_skip,一种宏块类型,当图像采用帧间预测编码时,在图像平坦的区域使用“跳跃”块,“跳跃”块本身不携带任何数据,在解码端是通过 direct方式预测出MV或者直接周围已重建的宏块来恢复。对于B片中的skip宏块是采用direct模式,有时间和空间的direct预测方式。对 于P片的skip宏块采用利用周围已重建的宏块copy而来。(http://bbs.chinavideo.org /viewthread.php?tid=994&highlight=direct)
2.b_direct, 一种宏块类型,采用direct的预测模式。
3.其他参数代表的含义在<新一代视频压缩标准>中有对应的解释,见7.3.9节 “宏块层的语义”.

下面是将Mb分割的块列举:
enum mb_partition_e
{
/* sub partition type for P_8x8 and B_8x8 */
D_L0_4x4          = 0,
D_L0_8x4          = 1,
D_L0_4x8          = 2,
D_L0_8x8          = 3,

/* sub partition type for B_8x8 only */
D_L1_4x4          = 4,
D_L1_8x4          = 5,
D_L1_4x8          = 6,
D_L1_8x8          = 7,

D_BI_4x4          = 8,
D_BI_8x4          = 9,
D_BI_4x8          = 10,
D_BI_8x8          = 11,
D_DIRECT_8x8      = 12,

/* partition */
D_8x8             = 13,
D_16x8            = 14,
D_8x16            = 15,
D_16x16           = 16,
X264_PARTTYPE_MAX = 17,
};

模式选择:

A. 帧内预测:
根据H.264标准规定的9种帧内4x4亮度分量预测、4种帧内16xl6亮度分量预测以及4种帧内8x8色差分量预测模式,针对宏块左邻和上邻宏块存在 或缺失的不同情况,分别直接调用不同的预测函数,以节约逻辑判断的时间。《新一代视频编码标准》P104.

B. 帧间预测:
在对P帧或B帧的宏块进行预测之前,先判断当前帧是否适宜用帧内模式,如果宏块的临近已编码宏块
均不采用帧内模式,并且若宏块所在的slice为p的话,参考帧相应位置的宏块也不采用帧内模式的话,则该宏块采用帧内预测的可能性就很小。那么在该宏块用帧间模式得到的最小的SAD后,只要计算帧内16*16预测模式的SAD,将二者相比,当比值超过门限值时,即用帧间预测模式,而不用计算帧内4*4的模式了。

                                          

1. P_SKIP模式:先判断是否是SKIP模式,其模式的判断有以下几个条件:
(1)最佳模式选择为Inter16×16;
(2)MC得到的最终运动矢量等于预测运动矢量,即运动矢量的残差为0;
(3)变换系数均被量化为0。

2.亮度宏块划分子宏块预测模式的选择:当在判断不是skip模式的时候,可以根据命令行的输入来决定是否进行对16*16,8*8的宏块进行子宏块的划分。
1),首先计算16*16宏块的运动矢量即其cost.
2).进行子宏块的划分,计算4个8*8子宏块的运动矢量所对应的cost和,与16*16模式进行比较,若16*16的cost较小时,则结束划分更小 的宏块。否则,继续对8*8的块继续下分:8*4,4*8,4*4,分别进行比较,得到最小的cost,并保存对应的最佳的Mv.
3).计算8*16,16*8模式的cost,与上面的mv的cost进行比较,得到最终的mv(1or2or4o8or16个)。


下面将对应程序中的实现:这部分函数主要对应于x264_slice_write( x264_t *h )中:

1. x264_macroblock_cache_load( h, i_mb_x, i_mb_y ); 它是将要编码的宏块的周围的宏块的值读进来, 要想得到当前块的预测值,要先知道上面,左面的预测值,将参考帧的编码信息存储在h->mb.cache中,可以反复使用。

2. x264_macroblock_analyse(h) 在此处通过计算一系列Mv的SAD值算出最优化的方案,这些包括帧内和帧间的SAD值的计算,比较大小,得到最好的宏块模式。进入本函数:
1)x264_mb_analyse_init( x264_t *h, x264_mb_analysis_t *a, int i_qp ),主要是初始化变量a,如,帧间,帧内的satd值,初始化MV的范围等一些参数。
2)开始对个类型帧进行分析:

1.当是I帧,调用x264_mb_analyse_intra( h, &analysis, COST_MAX );进行帧内预测。进入此函数:(1)predict_16x16_mode_available( h->mb.i_neighbour_intra, predict_mode, &i_max );是进行的16x16块的可选用模式的计算,16x16有4中预测模式,知道左边或上边的前提下,对每种模式下的方式进行设置,即在知道左边和上边时候
可供选择的不同的预测模式。然后将所选模式下的i_satd赋给a->i_satd_i16x16_dir[i_mode]。(2),分析8*8 块:得到a->i_satd_i8x8_dir[i_mode][idx] = i_satd;在进行分析的时候,会用4*4来预测,获取4*4的帧间模式,进行编码了??(是不是把8*8的块在分成4*4的块,对4*4的块进行模式选择,最后整合,这样的好处?a->i_satd_i8x8 = i_cost;)(3)进行4*4模块分析:其流程和8*8相似,计算16次,在此处也对4*4的模块进行了编码。求的
a->i_satd_i4x4。

此时x264_mb_analyse_intra( h, &analysis, COST_MAX );完成,获得16x16,8x8,4x4的cost,然后进行比较这几个cost的大小,获得帧间编码的宏块的模式。

2.当是P帧时,首先判断是否是skip模式,只有在左,上,左上,右上有一个是skip模式的时候,这时mb才   可能是skip模式:b_skip = x264_macroblock_probe_pskip( h ); 当不采用p_skip模式时,则调用x264_mb_analyse_inter_p16x16(
x264_t *h, x264_mb_analysis_t *a )进行帧间16*16块的分析:计算p16x16模式的运动适量及cost(其中还要考虑到参考帧部分,运动估计)。然后在允许16*16块分割时,进一 步分析8*8,4*4,16*8,8*16块的运动矢量,并比较cost的大小。获得最佳的运动估计模式。得到子宏块的分割方式存储在 i_partion。随后根据i_partion进行像素细化。


3.当是B帧时,调用x264_mb_predict_mv_direct16x16( x264_t *h, int *b_changed )判断是否采用B_Direct模式,如果采用直接模式,则分别进行空间和时间的直接预测。这里B帧双向参考,前向和后向的参考和p帧的方向是类似的。B 模式下最低支持的是8*8子宏块

抱歉!评论已关闭.