選擇模式前,先把mb模塊的類(lèi)型列舉出來(lái)。
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,一種宏塊類(lèi)型,當圖像采用幀間預測編碼時(shí),在圖像平坦的區域使用“跳躍”塊,“跳躍”塊本身不攜帶任何數據,在解碼端是通過(guò) direct方式預測出MV或者直接周?chē)阎亟ǖ暮陦K來(lái)恢復。對于B片中的skip宏塊是采用direct模式,有時(shí)間和空間的direct預測方式。對 于P片的skip宏塊采用利用周?chē)阎亟ǖ暮陦Kcopy而來(lái)。(http://bbs.chinavideo.org /viewthread.php?tid=994&highlight=direct)
2.b_direct, 一種宏塊類(lèi)型,采用direct的預測模式。
3.其他參數代表的含義在<新一代視頻壓縮標準>中有對應的解釋?zhuān)?jiàn)7.3.9節 “宏塊層的語(yǔ)義”.
下面是將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色差分量預測模式,針對宏塊左鄰和上鄰宏塊存在 或缺失的不同情況,分別直接調用不同的預測函數,以節約邏輯判斷的時(shí)間?!缎乱淮曨l編碼標準》P104.
B. 幀間預測:
在對P幀或B幀的宏塊進(jìn)行預測之前,先判斷當前幀是否適宜用幀內模式,如果宏塊的臨近已編碼宏塊
均不采用幀內模式,并且若宏塊所在的slice為p的話(huà),參考幀相應位置的宏塊也不采用幀內模式的話(huà),則該宏塊采用幀內預測的可能性就很小。那么在該宏塊用幀間模式得到的最小的SAD后,只要計算幀內16*16預測模式的SAD,將二者相比,當比值超過(guò)門(mén)限值時(shí),即用幀間預測模式,而不用計算幀內4*4的模式了。
pre MB
cur MB
1. P_SKIP模式:先判斷是否是SKIP模式,其模式的判斷有以下幾個(gè)條件:
(1)最佳模式選擇為Inter16×16;
(2)MC得到的最終運動(dòng)矢量等于預測運動(dòng)矢量,即運動(dòng)矢量的殘差為0;
(3)變換系數均被量化為0。
2.亮度宏塊劃分子宏塊預測模式的選擇:當在判斷不是skip模式的時(shí)候,可以根據命令行的輸入來(lái)決定是否進(jìn)行對16*16,8*8的宏塊進(jìn)行子宏塊的劃分。
1),首先計算16*16宏塊的運動(dòng)矢量即其cost.
2).進(jìn)行子宏塊的劃分,計算4個(gè)8*8子宏塊的運動(dòng)矢量所對應的cost和,與16*16模式進(jìn)行比較,若16*16的cost較小時(shí),則結束劃分更小 的宏塊。否則,繼續對8*8的塊繼續下分:8*4,4*8,4*4,分別進(jìn)行比較,得到最小的cost,并保存對應的最佳的Mv.
3).計算8*16,16*8模式的cost,與上面的mv的cost進(jìn)行比較,得到最終的mv(1or2or4o8or16個(gè))。
下面將對應程序中的實(shí)現:這部分函數主要對應于x264_slice_write( x264_t *h )中:
1. x264_macroblock_cache_load( h, i_mb_x, i_mb_y ); 它是將要編碼的宏塊的周?chē)暮陦K的值讀進(jìn)來(lái), 要想得到當前塊的預測值,要先知道上面,左面的預測值,將參考幀的編碼信息存儲在h->mb.cache中,可以反復使用。
2. x264_macroblock_analyse(h) 在此處通過(guò)計算一系列Mv的SAD值算出最優(yōu)化的方案,這些包括幀內和幀間的SAD值的計算,比較大小,得到最好的宏塊模式。進(jìn)入本函數:
1)x264_mb_analyse_init( x264_t *h, x264_mb_analysis_t *a, int i_qp ),主要是初始化變量a,如,幀間,幀內的satd值,初始化MV的范圍等一些參數。
2)開(kāi)始對個(gè)類(lèi)型幀進(jìn)行分析:
1.當是I幀,調用x264_mb_analyse_intra( h, &analysis, COST_MAX );進(jìn)行幀內預測。進(jìn)入此函數:(1)predict_16x16_mode_available( h->mb.i_neighbour_intra, predict_mode, &i_max );是進(jìn)行的16x16塊的可選用模式的計算,16x16有4中預測模式,知道左邊或上邊的前提下,對每種模式下的方式進(jìn)行設置,即在知道左邊和上邊時(shí)候 可供選擇的不同的預測模式。然后將所選模式下的i_satd賦給a->i_satd_i16x16_dir[i_mode]。(2),分析8*8 塊:得到a->i_satd_i8x8_dir[i_mode][idx] = i_satd;在進(jìn)行分析的時(shí)候,會(huì )用4*4來(lái)預測,獲取4*4的幀間模式,進(jìn)行編碼了??(是不是把8*8的塊在分成4*4的塊,對4*4的塊進(jìn)行模式選擇,最后整合,這樣的好處?a->i_satd_i8x8 = i_cost;)(3)進(jìn)行4*4模塊分析:其流程和8*8相似,計算16次,在此處也對4*4的模塊進(jìn)行了編碼。求的 a->i_satd_i4x4。
此時(shí)x264_mb_analyse_intra( h, &analysis, COST_MAX );完成,獲得16x16,8x8,4x4的cost,然后進(jìn)行比較這幾個(gè)cost的大小,獲得幀間編碼的宏塊的模式。
2.當是P幀時(shí),首先判斷是否是skip模式,只有在左,上,左上,右上有一個(gè)是skip模式的時(shí)候,這時(shí)mb才 可能是skip模式:b_skip = x264_macroblock_probe_pskip( h ); 當不采用p_skip模式時(shí),則調用x264_mb_analyse_inter_p16x16( x264_t *h, x264_mb_analysis_t *a )進(jìn)行幀間16*16塊的分析:計算p16x16模式的運動(dòng)適量及cost(其中還要考慮到參考幀部分,運動(dòng)估計)。然后在允許16*16塊分割時(shí),進(jìn)一 步分析8*8,4*4,16*8,8*16塊的運動(dòng)矢量,并比較cost的大小。獲得最佳的運動(dòng)估計模式。得到子宏塊的分割方式存儲在 i_partion。隨后根據i_partion進(jìn)行像素細化。
3.當是B幀時(shí),調用x264_mb_predict_mv_direct16x16( x264_t *h, int *b_changed )判斷是否采用B_Direct模式,如果采用直接模式,則分別進(jìn)行空間和時(shí)間的直接預測。這里B幀雙向參考,前向和后向的參考和p幀的方向是類(lèi)似的。B 模式下最低支持的是8*8子宏塊
實(shí)驗部分:
本實(shí)驗參數設置:--frames 10 --qp 26 -o test.264 F:\......\bin\akiyo_qcif.yuv 176x144
可以針對每一幀的MB打印其mb_type,partion_mode。本次試驗選取的每一幀的第49個(gè)MB:
試驗結果如下:
x264 [info]: 176x144 @ 25.00 fps
x264 [info]: using cpu capabilities: MMX2 SSE2 Cache64 Slow_mod4_stack
x264 [info]: profile High, level 1.1
the no.49mb' type is :0
the no.49mb' partion type is: 0
the no.49mb' type is :6
the no.49mb' partion type is: 16
the no.49mb' type is :18
the no.49mb' partion type is: 16
the no.49mb' type is :18
the no.49mb' partion type is: 16
the no.49mb' type is :18
the no.49mb' partion type is: 16
the no.49mb' type is :5
the no.49mb' partion type is: 13
the no.49mb' type is :18
the no.49mb' partion type is: 16
the no.49mb' type is :18
the no.49mb' partion type is: 16
the no.49mb' type is :18
the no.49mb' partion type is: 16
the no.49mb' type is :4
the no.49mb' partion type is: 16
x264 [info]: frame I:1 Avg QP:23.00 size: 4189
x264 [info]: frame P:3 Avg QP:26.00 size: 62
x264 [info]: frame B:6 Avg QP:28.00 size: 38
x264 [info]: consecutive B-frames: 11.1% 0.0% 0.0% 88.9%
x264 [info]: mb I I16..4: 3.0% 41.4% 55.6%
x264 [info]: mb P I16..4: 0.0% 0.0% 0.0% P16..4: 3.0% 1.3% 1.7% 0.0% 0
.0% skip:93.9%
x264 [info]: mb B I16..4: 0.0% 0.0% 0.0% B16..8: 4.4% 0.2% 0.3% direct:
0.7% skip:94.4% L0:56.0% L1:40.5% BI: 3.4%
x264 [info]: 8x8 transform intra:41.4% inter:25.9%
x264 [info]: coded y,uvDC,uvAC intra: 83.6% 81.8% 68.7% inter: 1.1% 0.1% 0.0%
x264 [info]: i16 v,h,dc,p: 100% 0% 0% 0%
x264 [info]: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 25% 30% 15% 4% 4% 4% 7% 5% 6%
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 35% 18% 8% 5% 5% 10% 5% 8% 6%
x264 [info]: ref P L0: 88.9% 0.0% 11.1%
x264 [info]: kb/s:92.08
encoded 10 frames, 35.71 fps, 92.08 kb/s
| 幀數 參數 | MB_TYPE | PARTION_MODE |
| 1 | I_4x4 | D_L0_4x4 |
| 2 | P_SKIP | D_16x16 |
| 3 | B_SKIP | D_16x16 |
| 4 | B_SKIP | D_16x16 |
| 5 | B_SKIP | D_16x16 |
| 6 | P_8x8 | D_16x16 |
| 7 | B_SKIP | D_16x16 |
| 8 | B_SKIP | D_16x16 |
| 9 | B_SKIP | D_16x16 |
| 10 | P_L0 | D_16x16 |