x264代码剖析(十四):核心算法之宏块编码函数x264_macroblock_encode()
宏块编码函数x264_macroblock_encode()是完成变换与量化的主要函数,而x264_macroblock_encode()调用了x264_macroblock_encode_internal()函数,在x264_macroblock_encode_internal()函数中,主要完成了如下功能:
x264_macroblock_encode_skip():编码Skip类型宏块。
x264_mb_encode_i16x16():编码Intra16x16类型的宏块。该函数除了进行DCT变换之外,还对16个小块的DC系数进行了Hadamard变换。
x264_mb_encode_i4x4():编码Intra4x4类型的宏块。
帧间宏块编码:这一部分代码直接写在了函数体里面。
x264_mb_encode_chroma():编码色度块。
x264_macroblock_encode()函数与x264_macroblock_encode_internal()函数都处于encoder文件夹内的macroblock.c中,其调用关系图如下所示:
1、x264_macroblock_encode()函数
x264_macroblock_encode()函数处于encoder文件夹内的macroblock.c中,x264_macroblock_encode()封装了x264_macroblock_encode_internal()。如果色度模式是YUV444的话,传递的参数plane_count=3而chroma=0;如果不是YUV444的话,传递的参数plane_count=1而chroma=1。
对应的代码如下:
/******************************************************************/
/******************************************************************/
/*
======Analysed by RuiDong Fang
======Csdn Blog:http://blog.csdn.net/frd2009041510
======Date:2016.03.22
*/
/******************************************************************/
/******************************************************************/
/************====== 宏块编码函数x264_macroblock_encode() ======************/
/*
功能:x264_macroblock_encode()封装了x264_macroblock_encode_internal(),即编码的内部函数——残差DCT变换、量化
*/
void x264_macroblock_encode( x264_t *h )
{
if( CHROMA444 )
x264_macroblock_encode_internal( h, 3, 0 );//YUV444相当于把YUV3个分量都当做Y编码
else
x264_macroblock_encode_internal( h, 1, 1 );
}
2、x264_macroblock_encode_internal()函数
x264_macroblock_encode_internal()函数也处于encoder文件夹内的macroblock.c中,具体的代码分析如下:
/************====== 宏块编码函数x264_macroblock_encode_internal() ======************/
/*
功能:调用了编码-残差DCT变换、量化-内部函数
*/
/*****************************************************************************
* x264_macroblock_encode:
*****************************************************************************/
static ALWAYS_INLINE void x264_macroblock_encode_internal( x264_t *h, int plane_count, int chroma )
{
int i_qp = h->mb.i_qp;
int b_decimate = h->mb.b_dct_decimate;
int b_force_no_skip = 0;
int nz;
h->mb.i_cbp_luma = 0;
for( int p = 0; p < plane_count; p++ )
h->mb.cache.non_zero_count[x264_scan8[LUMA_DC+p]] = 0;
/*======== PCM ========*/
if( h->mb.i_type == I_PCM )//PCM
{
/*