我对libavcodec/h264_cavlc.c
中的以下代码感到困惑
这是ffmpeg的h264解码器的一部分。
int ff_h264_decode_mb_cavlc(const H264Context *h, H264SliceContext *sl)
.
.
.
if(IS_INTRA4x4(mb_type)){
int i;
int di = 1;
if(dct8x8_allowed && get_bits1(&sl->gb)){
mb_type |= MB_TYPE_8x8DCT;
di = 4;
}
// fill_intra4x4_pred_table(h);
for(i=0; i<16; i+=di){
int mode = pred_intra_mode(h, sl, i);
if(!get_bits1(&sl->gb)){
const int rem_mode= get_bits(&sl->gb, 3);
mode = rem_mode + (rem_mode >= mode);
}
if(di==4)
fill_rectangle(&sl->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1);
else
sl->intra4x4_pred_mode_cache[scan8[i]] = mode;
}
write_back_intra_pred_mode(h, sl);
if (ff_h264_check_intra4x4_pred_mode(h, sl) < 0)
return -1;
}
当di == 4
时,它只读取四种预测模式
比特流。我希望从那以后提取16种pred模式
我们正在开发一个INTRA4x4宏块。
fill_rectangle()
正在做什么?
答案 0 :(得分:2)
di = 4表示我们为此子块使用8x8 DCT。仅当此宏块中的所有子块都使用4x4 DCT时,才有多达16种模式。如果您正在使用8x8 DCT,则每个宏块只能有4个子块。每个模块可以选择8x8或4x4 DCT,因此每个宏块可以编码4个(4x DCT8,0x DCT4),7个(3x DCT8,1x2x2 DCT4),10,13或16个帧内模式。
对于宏块中的以下4x4矩形子块:
a b c d
e f g h
i j k l
m n o p
scan8 []给出右下对齐的8x5数组中的索引,如下所示:
x x x tl t1 t2 t3 t4
x x x l1 a b c d
x x x l2 e f g h
x x x l3 i j k l
x x x l4 m n o p
允许您为了预测当前块的帧内模式而获得上/左边缘以用于上下文目的。 fill_rectangle填充2x2&#34;矩形&#34;使用相同的模式,步幅为8,例如a,b,e和f用于topleft 8x8 DCT块。
出于可视化目的,如果topleft和bottomright块使用8x8 DCT,该块将基本上使用这样的帧内预测模式布局:
A c d
g h
i j K
m n