宏塊編碼函數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中,其調用關系圖如下所示:

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。
對應的代碼如下:
x264_macroblock_encode_internal()函數也處于encoder檔案夾内的macroblock.c中,具體的代碼分析如下:
從源代碼可以看出,x264_macroblock_encode_internal()的流程大緻如下:
(1)、如果是skip類型,調用x264_macroblock_encode_skip()編碼宏塊。
(2)、如果是intra16x16類型,調用x264_mb_encode_i16x16()編碼宏塊。
(3)、如果是intra4x4類型,循環16次調用x264_mb_encode_i4x4()編碼宏塊。
(4)、如果是inter類型,則不再調用子函數,而是直接進行編碼:
a)、對16x16塊調用x264_dct_function_t的sub16x16_dct()彙編函數,求得編碼宏塊資料p_fenc與重建宏塊資料p_fdec之間的殘差(“sub”),并對殘差進行dct變換。
b)、分成4個8x8的塊,對每個8x8塊分别調用x264_quant_function_t的quant_4x4x4()彙編函數進行量化。
c)、分成16個4x4的塊,對每個4x4塊分别調用x264_quant_function_t的dequant_4x4()彙編函數進行反量化(用于重建幀)。
d)、分成4個8x8的塊,對每個8x8塊分别調用x264_dct_function_t的add8x8_idct()彙編函數,對殘差進行dct反變換,并将反變換後的資料疊加(“add”)至預測資料上(用于重建幀)。
(5)、如果對色度編碼,調用x264_mb_encode_chroma()。
從inter宏塊編碼的步驟可以看出,編碼就是“dct變換+量化”兩步的組合。在接下來的文章中将依次分析變換、量化的具體代碼。