JM8.5中的7種宏塊模式問題 收藏
Outline:
1、? CFG文件中有關可變尺寸宏塊模式的相關選項
2、? 7種宏塊模式對應的數值常量
2、? 7種宏塊模式對應的數值常量
3、? 7種宏塊模式被分成宏塊和亞宏塊
4、? 如何對宏塊和亞宏塊的運動估計,采用一個共同的函數來處理
5、? 遺留問題
?1、CFG文件中有關可變尺寸宏塊模式的相關選項
###############################################################################
#Encoder Control
#Encoder Control
###############################################################################
…
InterSearch16x16????? =? 1? # Inter block search 16x16 (0=disable, 1=enable)
InterSearch16x8?????? =? 1? # Inter block search 16x8? (0=disable, 1=enable)
InterSearch16x8?????? =? 1? # Inter block search 16x8? (0=disable, 1=enable)
InterSearch8x16?????? =? 1? # Inter block search? 8x16 (0=disable, 1=enable)
InterSearch8x8??????? =? 1? # Inter block search? 8x8? (0=disable, 1=enable)
InterSearch8x4??????? =? 1? # Inter block search? 8x4? (0=disable, 1=enable)
InterSearch4x8??????? =? 1? # Inter block search? 4x8? (0=disable, 1=enable)
InterSearch4x4??????? =? 1? # Inter block search? 4x4? (0=disable, 1=enable)
解釋:
各種宏塊尺寸可以在程序外部進行選擇。
2、? 7種宏塊模式對應的數值常量
各種宏塊模式對應的數值常量如下:
16×16-1???? 16×8-2?????? 8×16-3?????? 8×8-4??? 8×4-5???? 4×8-6????? 4×4-7?
16×16-1???? 16×8-2?????? 8×16-3?????? 8×8-4??? 8×4-5???? 4×8-6????? 4×4-7?
以上的數值常量的rdopt.c的encode_one_macroblock()中的valid[]數組和mode變量中會用到,另外在mv_search.c的PartitionMotionSearch()中的blocktype變量也會用到。
?
3、?? 7種宏塊模式被分成宏塊和亞宏塊
16x16, 16x8, 8x16(,8×8)被稱為宏塊級,而8×8,8×4,4×8,4×4被稱為亞宏塊級。
所用到的函數是:encode_one_macroblock(),rdopt.c
所用到的函數是:encode_one_macroblock(),rdopt.c
該函數的作用是編碼一個宏塊(包括幀間、幀內、幀內預測的方式)。
其中重要的程序段如下:
//宏塊級運動估計
//===== MOTION ESTIMATION FOR 16x16, 16x8, 8x16 BLOCKS =====
//===== MOTION ESTIMATION FOR 16x16, 16x8, 8x16 BLOCKS =====
for (min_cost=1<<20, best_mode=1, mode=1; mode<4; mode++)
{
if (valid[mode])//對應于程序外部(即CFG文件中)的設置
{
//對于16×16,MB只分一個塊;對于16×8和8×16,MB被分成兩個塊
for (cost=0, block=0; block<(mode==1?1:2); block++)
{
//塊匹配!!!lambda_motion用來求運動矢量消耗的碼率
PartitionMotionSearch (mode, block, lambda_motion);
…
//亞宏塊級運動估計
if (valid[P8x8])
if (valid[P8x8])
{
…
//=====? LOOP OVER POSSIBLE CODING MODES FOR 8x8 SUB-PARTITION? =====
for (min_cost8x8=(1<<20), min_rdcost=1e30, index=(bframe?0:1); index<5; index++)
{
if (valid[mode=b8_mode_table[index]])//b8_mode_table[6] = {0, 4, 5, 6, 7};
{
curr_cbp_blk = 0;
if (mode==0) //--- Direct Mode ---
{
…
} // if (mode==0)
else
{
//--- motion estimation for all reference frames ---
PartitionMotionSearch (mode, block, lambda_motion);
…
NOTE:從上面程序段中可以看出JM8.5中對7種宏塊模式是采用全部遍歷的方式,所以導致的計算復雜度很高。
4、? 如何對宏塊和亞宏塊的運動估計,采用一個共同的函數來處理
從3中的程序可以看到,對于宏塊和亞宏塊級的運動估計,都采用了一個共同的函數:PartitionMotionSearch(), mv_search.c
從3中的程序可以看到,對于宏塊和亞宏塊級的運動估計,都采用了一個共同的函數:PartitionMotionSearch(), mv_search.c
其中重要的程序段如下:
……
//各種宏塊模式下的子塊的起始偏移量,相對4*4塊來講,這有利于運動矢量的存放
//[5]表示宏塊的類型,[4]表示各種類型下的子塊序號,最多子塊情況為P8X8模式下有4個
//[5]表示宏塊的類型,[4]表示各種類型下的子塊序號,最多子塊情況為P8X8模式下有4個
static int? bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
static int? by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
……
static int? by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
……
int?? parttype? = (blocktype<4?blocktype:4);//亞宏塊的parttype都設為4
//step_?是用來求4*4塊級別的步長,
//由于parttype和blocktype的區別使得兩組步長之間存在微妙的差異,為下面的循環做好了鋪墊
int?? step_h0?? = (input->blc_size[ parttype][0]>>2);
int?? step_v0?? = (input->blc_size[ parttype][1]>>2);
int?? step_v0?? = (input->blc_size[ parttype][1]>>2);
int?? step_h??? = (input->blc_size[blocktype][0]>>2);
int?? step_v??? = (input->blc_size[blocktype][1]>>2);
…
//===== LOOP OVER SUB MACRO BLOCK partitions
//這里對于亞宏塊的循環是自適應的,
//假如小于8*8塊尺寸時,自動采取循環
for (v=by0[parttype][block8x8]; v<by0[parttype][block8x8]+step_v0; v+=step_v)
{
pic_block_y = img->block_y + v;
for (h=bx0[parttype][block8x8]; h<bx0[parttype][block8x8]+step_h0; h+=step_h)
{
……
……