在ffmpeg中h264 intra4x4 pred模式解码

时间:2016-01-23 08:22:25

标签: ffmpeg h.264 libavcodec

我对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()正在做什么?

1 个答案:

答案 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