H.264笔记之二——宏块结构

这里主要有一下几个过程:
1. 初始化h->stat.frame,即全部清零。
2. 写条带头:x264_slice_header_write,即把刚才x264_slice_header_init设置的一些参数写入。
3. 如果是CABAC编码,则初始化CABAC。有关CABAC在后续相关章节讨论。
4. 遍历一帧中的所有宏块,这是编码的主要部分:
for( mb_xy = h->sh.i_first_mb, i_skip = 0; mb_xy < h->sh.i_last_mb; )
其中sh.i_first_mb和sh.i_last_mb在x264_slice_header_init中赋值,分别是0和宏块行列数乘积。
5. 最后输出码流尾部。
其间穿插一些必要的初始化和配置。

本章着重分析编码的主要部分,包括一下过程:
需要注意的是,这里讨论的宏块是固定尺寸的,即Y分量计为16x16。(而运动宏块的尺寸则是多变的)

1. 首先根据宏块的序号得出宏块的坐标。然后统计当前宏块的码流位置:
int mb_spos = bs_pos(&h->out.bs) + x264_cabac_pos(&h->cabac);

2. 然后出现一句:
if( i_mb_x == 0 )
    x264_fdec_filter_row( h, i_mb_y );
这是对行进行去块过程。详细情况专门论述。

3. 随后是x264_macroblock_cache_load,这里主要进行当前宏块和相关信息的提取。这个函数比较大,也在专题中论述。

4. 接下去进行解码分析操作
x264_macroblock_analyse

5. 以及解码实体:
x264_macroblock_encode

6. 而后处理码流输出,也分CABAC和CAVLC两种情况。

7. 接着出现x264_macroblock_cache_save,和x264_macroblock_cache_load对应,保存处理完的宏块。

8. 更新宏块统计


下面,首先看编码主体x264_macroblock_encode的结构。
该函数按不同宏块类型情况进行不同的处理。包括如下类型:
P_SKIP
B_SKIP
I_16x16 - 一次完成一个块h->mb.pic.p_fdec[0]的编码。
   用函数指针h->predict_16x16[i_mode]进行帧内预测
I_8x8   - 分4次完成。h->mb.pic.p_fdec[0][8 * (i&1) + 8 * (i>>1) * FDEC_STRIDE]指定了当前位置。即:
   [0][1]
   [2][3]
   用函数指针完成4个宏块的帧内预测
I_4x4 - 分16次完成。h->mb.pic.p_fdec[0][4 * block_idx_x[i] + 4 * block_idx_y[i] * FDEC_STRIDE]指定当前位置。
   根据block_idx_x和block_idx_y的定义,其顺序是:
   [0][1][4][5]
   [2][3][6][7]
   [8][9][c][d]
   [a][b][e][f]
   用函数指针完成4个宏块的帧内预测
Inter - 首先进行运动补偿。见后续讨论。
          然后分多种情形:
   1. 无损压缩情况:h->mb.b_lossless == TRUE(必须采用4x4DCT)
      根据上述I_4x4中描述的顺序遍历16个4x4块。
      这里调用的函数是zigzag_sub_4x4_field,完成残差。(无损情况直接发送残差)
   2. 指定采用8x8DCT情况:h->mb.b_transform_8x8 == TRUE
      首先是作残差并DCT的函数:sub16x16_dct8。
      然后对4个8x8的DCT系数块进行处理:包括可能的去噪x264_denoise_dct,量化(标量/矢量)。有关量化也在专题中论述。量化完成后进行系数扫描(对角平衡的普通扫描)。
   3. 一般情况
     
接着处理色差分量,如果是Intra的则进行预测。
最后写Coded Block Pattern。

你可能感兴趣的:(笔记)