=====================================================
H.264源代码分析文章列表:
【编码 - x264】
x264源代码简单分析:概述
x264源代码简单分析:x264命令行工具(x264.exe)
x264源代码简单分析:编码器主干部分-1
x264源代码简单分析:编码器主干部分-2
x264源代码简单分析:x264_slice_write()
x264源代码简单分析:滤波(Filter)部分
x264源代码简单分析:宏块分析(Analysis)部分-帧内宏块(Intra)
x264源代码简单分析:宏块分析(Analysis)部分-帧间宏块(Inter)
x264源代码简单分析:宏块编码(Encode)部分
x264源代码简单分析:熵编码(Entropy Encoding)部分
FFmpeg与libx264接口源代码简单分析
【解码 - libavcodec H.264 解码器】
FFmpeg的H.264解码器源代码简单分析:概述
FFmpeg的H.264解码器源代码简单分析:解析器(Parser)部分
FFmpeg的H.264解码器源代码简单分析:解码器主干部分
FFmpeg的H.264解码器源代码简单分析:熵解码(EntropyDecoding)部分
FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧内宏块(Intra)
FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)
FFmpeg的H.264解码器源代码简单分析:环路滤波(Loop Filter)部分
=====================================================
本文简单记录FFmpeg中libavcodec的H.264解码器(H.264 Decoder)的源代码。这个H.264解码器十分重要,可以说FFmpeg项目今天可以几乎“垄断”视音频编解码技术,很大一部分贡献就来自于这个H.264解码器。这个H.264解码器一方面功能强大,性能稳定;另一方面源代码也比较复杂,难以深入研究。本文打算梳理一下这个H.264解码器的源代码结构,以方便以后深入学习H.264使用。
PS:这部分代码挺复杂的,还有不少地方还比较模糊,还需要慢慢学习......H.264解码器的函数调用关系图如下所示。
下面解释一下图中关键标记的含义。
作为接口的结构体
FFmpeg和H.264解码器之间作为接口的结构体有2个:ff_h264_parser:用于解析H.264码流的AVCodecParser结构体。ff_h264_decoder:用于解码H.264码流的AVCodec结构体。
函数背景色
函数在图中以方框的形式表现出来。不同的背景色标志了该函数不同的作用:白色背景的函数:普通内部函数。粉红色背景函数:解析函数(Parser)。这些函数用于解析SPS、PPS等信息。紫色背景的函数:熵解码函数(Entropy Decoding)。这些函数读取码流数据并且进行CABAC或者CAVLC熵解码。绿色背景的函数:解码函数(Decode)。这些函数通过帧内预测、帧间预测、DCT反变换等方法解码压缩数据。黄色背景的函数:环路滤波函数(Loop Filter)。这些函数对解码后的数据进行滤波,去除方块效应。蓝色背景函数:汇编函数(Assembly)。这些函数是做过汇编优化的函数。图中主要画出了这些函数的C语言版本,此外这些函数还包含MMX版本、SSE版本、NEON版本等。
箭头线
箭头线标志了函数的调用关系:黑色箭头线:不加区别的调用关系。粉红色的箭头线:解析函数(Parser)之间的调用关系。紫色箭头线:熵解码函数(Entropy Decoding)之间的调用关系。绿色箭头线:解码函数(Decode)之间的调用关系。黄色箭头线:环路滤波函数(Loop Filter)之间的调用关系。函数所在的文件
每个函数标识了它所在的文件路径。
下文简单记录几个关键的部分。
FFmpeg和H.264解码器之间作为接口的结构体有2个:ff_h264_parser和ff_h264_decoder。
ff_h264_parserparser_init():初始化解析器。在ff_h264_parser结构体中,上述几个函数指针分别指向下面几个实现函数:
parser_parse():解析。
parser_close():关闭解析器。
init():初始化H.264解析器。ff_h264_decoder
h264_parse():解析H.264码流。
close():关闭H.264解析器。
init():初始化解码器。在ff_h264_decoder结构体中,上述几个函数指针分别指向下面几个实现函数:
decode():解码。
close():关闭解码器。
ff_h264_decode_init():初始化H.264解码器。
h264_decode_frame():解码H.264码流。
h264_decode_end():关闭H.264解码器。
ff_h264dsp_init():初始化DSP相关的函数。包含了IDCT、环路滤波函数等。ff_h264_decoder中h264_decode_frame()逐层调用的和解码Slice相关的函数:
ff_h264qpel_init():初始化四分之一像素运动补偿相关的函数。
ff_h264_pred_init():初始化帧内预测相关的函数。
ff_h264_decode_extradata():解析AVCodecContext中的extradata。
decode_nal_units(),ff_h264_execute_decode_slices(),decode_slice()等。ff_h264_decoder中h264_decode_end()调用的清理函数:
ff_h264_remove_all_refs():移除所有参考帧。ff_h264_parser中h264_parse()逐层调用的和解析Slice相关的函数:
ff_h264_free_context():释放在初始化H.264解码器的时候分配的内存。
h264_find_frame_end():查找NALU的结尾。
parse_nal_units():解析一个NALU。
ff_h264_decode_nal():解析NALU。这个函数是后几个解析函数的前提。
ff_h264_decode_slice_header():解析Slice Header。
ff_h264_decode_sei():解析SEI。
ff_h264_decode_seq_parameter_set():解析SPS。
ff_h264_decode_picture_parameter_set():解析PPS。
filter_mb_edgeh():亮度水平滤波
filter_mb_edgev():亮度垂直滤波
filter_mb_edgech():色度水平滤波filter_mb_edgecv():色度垂直滤波
C语言版本的pred16x16_dc_8_c()
NEON版本的ff_pred16x16_dc_neon()
MMXEXT版本的ff_pred16x16_dc_8_mmxext()
SSE2版本的ff_pred16x16_dc_8_sse2()
在网上找到一张图(出处不详),分析了FFmpeg的H.264解码器每个函数运行的耗时情况,比较有参考意义,在这里附上。
单击查看更清晰的图片
从图中可以看出,熵解码、宏块解码、环路滤波耗时比例分别为:23.64%、51.85%、22.22%。