=====================================================

HEVC源代码分析文章列表:

【解码 -libavcodec HEVC 解码器】

FFmpeg的HEVC解码器源代码简单分析:概述

FFmpeg的HEVC解码器源代码简单分析:解析器(Parser)部分

FFmpeg的HEVC解码器源代码简单分析:解码器主干部分

FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-PU

FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-TU

FFmpeg的HEVC解码器源代码简单分析:环路滤波(LoopFilter)

=====================================================

从这篇文章开始,简单分析记录FFmpeg中libavcodec的HEVC(H.265)解码器(HEVC Decoder)的源代码。本文综述整个解码器的框架,后续几篇文章再对解码器的内部模块进行分析。

函数调用关系图

FFmpeg的HEVC(H.265)解码器的函数调用关系图如下所示。

 

下面解释一下图中关键标记的含义。

作为接口的结构体
FFmpeg和HEVC解码器之间作为接口的结构体有2个:

ff_hevc_parser:用于解析HEVC码流的AVCodecParser结构体。

ff_hevc_decoder:用于解码HEVC码流的AVCodec结构体。

函数背景色
函数在图中以方框的形式表现出来。不同的背景色标志了该函数不同的作用:

白色背景的函数:普通内部函数。

粉红色背景函数:解析函数(Parser)。这些函数用于解析SPS、PPS等信息。

绿色背景的函数:解码函数(Decode)。这些函数通过帧内预测、帧间预测、DCT反变换等方法解码压缩数据。

黄色背景的函数:滤波函数(Filter)。这些函数对解码后的数据进行滤波,去除方块效应。

蓝色背景函数:汇编函数(Assembly)。这些函数是做过汇编优化的函数。图中主要画出了这些函数的C语言版本,此外这些函数还包含MMX版本、SSE版本、NEON版本等。

箭头线
箭头线标志了函数的调用关系:

黑色箭头线:不加区别的调用关系。

粉红色的箭头线:解析函数(Parser)之间的调用关系。

绿色箭头线:解码函数(Decode)之间的调用关系。

黄色箭头线:环路滤波函数(Loop Filter)之间的调用关系。

函数所在的文件

每个函数标识了它所在的文件路径。

几个关键部分

下文简单记录几个关键的部分。

FFmpeg和HEVC解码器之间作为接口的结构体

FFmpeg和HEVC解码器之间作为接口的结构体有2个:ff_hevc_parser和ff_hevc_decoder。

ff_hevc_parser

ff_hevc_parser是用于解析HEVC码流的AVCodecParser结构体。AVCodecParser中包含了几个重要的函数指针:

parser_init():初始化解析器。
parser_parse():解析。
parser_close():关闭解析器。

在ff_hevc_parser结构体中,上述几个函数指针分别指向下面几个实现函数:

hevc_init():初始化HEVC解析器。
hevc_parse():解析HEVC码流。
hevc_close():关闭HEVC解析器。

ff_hevc_decoder

ff_hevc_decoder是用于解码HEVC(H.265)码流的AVCodec结构体。AVCodec中包含了几个重要的函数指针:

init():初始化解码器。
decode():解码。
close():关闭解码器。

在ff_hevc_decoder结构体中,上述几个函数指针分别指向下面几个实现函数:

hevc_decode_init():初始化HEVC解码器。
hevc_decode_frame():解码HEVC码流。
hevc_decode_free():关闭HEVC解码器。

解析函数(Parser)

解析函数(Parser)用于解析HEVC码流中的一些信息(例如SPS、PPS、Slice Header等)。在parse_nal_units()和decode_nal_units()中都调用这些解析函数完成了解析。下面举几个解析函数的例子:

ff_hevc_decode_nal_vps():解析VPS。
ff_hevc_decode_nal_sps():解析SPS。
ff_hevc_decode_nal_pps():解析PPS。
ff_hevc_decode_nal_sei():解析SEI。

普通内部函数

普通内部函数指的是HEVC解码器中还没有进行分类的函数。下面举几个例子。
ff_hevc_decoder中hevc_decode_init()调用的初始化函数:

hevc_init_context():初始化HEVC解码器上下文结构体。
hevc_decode_extradata():解析AVCodecContext中的extradata。
ff_hevc_decoder中hevc_decode_frame()逐层调用的和解码Slice相关的函数:
decode_nal_units(),decode_nal_unit(),hls_slice_data(),hls_decode_entry()等。

ff_hevc_decoder中hevc_parse()逐层调用的和解析Slice相关的函数:

hevc_find_frame_end():查找NALU的结尾。
parse_nal_units():解析一个NALU。

hls_decode_entry()

hls_decode_entry()是FFmpeg的HEVC解码器真正的解码函数。其中调用了解码函数和滤波函数HEVC中的CTU进行处理。在HEVC中CTU(Coding tree unit, 编码树单元)即对应H.264中的MB(Macroblock, 宏块)。

解码函数(Decode)

解码函数(Decode)通过帧内预测、帧间预测等方法解码CTU压缩数据。CTU解码模块对应的函数是hls_coding_quadtree()。hls_coding_quadtree()用于解析HEVC码流的四叉树结构的句法,是一个递归调用的函数。当解析到单个CU的时候,会调用CU的解码函数hls_coding_unit()。
hls_coding_unit()会调用hls_prediction_unit()和hls_transform_tree()分别对CU中的PU和TU进行处理。hls_prediction_unit()会调用luma_mc_uni()或者调用luma_mc_bi()进行预测。hls_transform_tree()用于解析TU的四叉树结构的句法,是一个递归调用的函数。当解析到单个TU的时候,会调用hls_transform_unit()对TU进行处理。

环路滤波函数(Loop Filter)

环路滤波函数(Loop Filter)对解码后的数据进行滤波,去除方块效应和振铃效应。滤波模块对应的环路滤波函数是ff_hevc_hls_filters()。ff_hevc_hls_filters()调用了ff_hevc_hls_filter()。而ff_hevc_hls_filter()调用去块效应滤波器函数deblocking_filter_CTB()去除解码过程中的块效应;调用SAO滤波器函数sao_filter_CTB()去除解码过程中的振铃效应。

汇编函数(Assembly)

汇编函数(Assembly)是做过汇编优化的函数。为了提高效率,整个HEVC解码器中包含了大量的汇编函数。实际解码的过程中,FFmpeg会根据系统的特性调用相应的汇编函数(而不是C语言函数)以提高解码的效率。如果系统不支持汇编优化的话,FFmpeg才会调用C语言版本的函数。

至此FFmpeg的HEVC解码器的结构就大致梳理完毕了。

雷霄骅
leixiaohua1020@126.com
http://blog.csdn.net/leixiaohua1020

FFmpeg的HEVC解码器源代码简单分析:概述的更多相关文章

  1. FFmpeg的HEVC解码器源代码简单分析:环路滤波(Loop Filter)

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  2. FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-TU

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  3. FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-PU

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  4. FFmpeg的HEVC解码器源代码简单分析:解码器主干部分

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  5. FFmpeg的HEVC解码器源代码简单分析:解析器(Parser)部分

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  6. FFmpeg的H.264解码器源代码简单分析:概述

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  7. FFmpeg的H.264解码器源代码简单分析:环路滤波(Loop Filter)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  8. FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧间宏块(Inter)

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  9. FFmpeg的H.264解码器源代码简单分析:熵解码(Entropy Decoding)部分

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

随机推荐

  1. 机器学习技法:11 Gradient Boosted Decision Tree

    Roadmap Adaptive Boosted Decision Tree Optimization View of AdaBoost Gradient Boosting Summary of Ag ...

  2. slf4j 与各个 logging框架的适配器说明

    在java领域里,日志框架纷杂繁多,项目中必然要使用很多的第三方库,而这些第三方库所使用的log框架又不尽相同.想要打出合理有效的日志,就必须在你的项目中将这些日志框架统一才行.幸好,slf4j, c ...

  3. [HNOI2010]PLANAR

    题目描述 若能将无向图G=(V,E)画在平面上使得任意两条无重合顶点的边不相交,则称G是平面图.判定一个图是否为平面图的问题是图论中的一个重要问题.现在假设你要判定的是一类特殊的图,图中存在一个包含所 ...

  4. [HAOI2006]数字序列

    题目描述 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变的幅度太大. 输入输出格式 输入格式: 第一行包含一个数 ...

  5. [JLOI2015]装备购买

    题目描述 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示 (1 <= i <= n; 1 <= j < ...

  6. [SCOI2012]滑雪与时间胶囊

    题目描述 a180285非常喜欢滑雪.他来到一座雪山,这里分布着MMM条供滑行的轨道和NNN个轨道之间的交点(同时也是景点),而且每个景点都有一编号iii(1≤i≤N1 \le i \le N1≤i≤ ...

  7. ●BZOJ 3270 博物馆

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3270题解: 期望DP,高斯消元 本来是定义的关于概率的dp, 但是发现这样定义有很多解释不通 ...

  8. POJ1222熄灯问题

    千年老题,以前用枚举做,现在用高斯消元做 自由元直接做成0即可 #include<cstdio> #include<cstdlib> #include<algorithm ...

  9. [poj1279]Art Gallery

    题意:求多边形的核的面积. 敲一下半平面交模板........  然后我wa了一早上就因为写了%lf  不知道poj什么破机制还不能用lf的,真的想跳楼 #include<iostream> ...

  10. 使用JdbcTemplate过程中使用到多个参数和like模糊

    项目中经常会用到模糊查询,最近使用JdbcTemplate过程中就遇到了. 一开始尝试了拼接的方式去 String sql = "select count(1) from web_users ...