大体上将一个宏块的编码过程跟下来
上面分析完事宏块位置问题,下面看一个宏块的编码过程。
Macroblock.h中的一个编码过程
h->dctf.sub4x4_dct( dct4x4, p_src, p_dst ); //mutiply two parameter matrix
nz = x264_quant_4x4( h, dct4x4, i_qp, ctx_cat_plane[DCT_LUMA_4x4][p], 1, p, idx );
h->mb.cache.non_zero_count[x264_scan8[p*16+idx]] = nz;
if( nz )
{
h->mb.i_cbp_luma |= 1<<(idx>>2);
h->zigzagf.scan_4x4( h->dct.luma4x4[p*16+idx], dct4x4 );
h->quantf.dequant_4x4( dct4x4, h->dequant4_mf[p?CQM_4IC:CQM_4IY], i_qp );
h->dctf.add4x4_idct( p_dst, dct4x4 );
}
首先分析第一个 dct变换
h->dctf.sub4x4_dct( dct4x4, p_src, p_dst );
x264_dct_init( h->param.cpu, &h->dctf ); 初始化命令行
void x264_dct_init( int cpu, x264_dct_function_t *dctf ) 函数
所谓的蝶形 dct就是宏块内容 第一个和第二个都是h里面的全局内容
static void sub4x4_dct( dctcoef dct[16], pixel *pix1, pixel *pix2 )
{
dctcoef d[16];
dctcoef tmp[16];
//get the residual block
pixel_sub_wxh( d, 4, pix1, FENC_STRIDE, pix2, FDEC_STRIDE );
这里d里面存放的已经是残差了。其实就是进行了AXA的过程
两个矩阵为
1 1 1 1 1 2 1 1
2 1 -1 -2 X 1 1 -1 -2
1 -1 -1 1 1 -1 -1 2
1 -2 2 -1 1 -2 1 -1
for( int i = 0; i < 4; i++ )
{
int s03 = d[i*4+0] + d[i*4+3];
int s12 = d[i*4+1] + d[i*4+2];
int d03 = d[i*4+0] - d[i*4+3];
int d12 = d[i*4+1] - d[i*4+2];
0行i列
tmp[0*4+i] = s03 + s12;
1行i列
tmp[1*4+i] = 2*d03 + d12;
3行i列
tmp[2*4+i] = s03 - s12;
4行i列
tmp[3*4+i] = d03 - 2*d12;
}
for( int i = 0; i < 4; i++ )
{
int s03 = tmp[i*4+0] + tmp[i*4+3];
int s12 = tmp[i*4+1] + tmp[i*4+2];
int d03 = tmp[i*4+0] - tmp[i*4+3];
int d12 = tmp[i*4+1] - tmp[i*4+2];
dct[i*4+0] = s03 + s12;
dct[i*4+1] = 2*d03 + d12;
dct[i*4+2] = s03 - s12;
dct[i*4+3] = d03 - 2*d12;
}
}
pixel_sub_wxh( d, 4, pix1, FENC_STRIDE, pix2, FDEC_STRIDE );
d为空的像素数组 最后就是将残差放入到这个数组里面返回然后对其进行编码
static inline void pixel_sub_wxh( dctcoef *diff, int i_size,
pixel *pix1, int i_pix1, pixel *pix2, int i_pix2 )
{
for( int y = 0; y < i_size; y++ )
{
for( int x = 0; x < i_size; x++ )
diff[x + y*i_size] = pix1[x] - pix2[x];
pix1 += i_pix1;
pix2 += i_pix2;
}
}