FFmpeg的HEVC解码器源码简单分析:概述
=====================================================
HEVC源码分析文章列表:
【解码 -libavcodec HEVC 解码器】
FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分
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解码器源码简单分析:概述的更多相关文章
- FFmpeg的HEVC解码器源码简单分析:解析器(Parser)部分
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- FFmpeg的HEVC解码器源码简单分析:解码器主干部分
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- FFmpeg源码简单分析:libswscale的sws_scale()
===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...
- FFmpeg源码简单分析:结构体成员管理系统-AVOption
===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...
- Django-session中间件源码简单分析
Django-session中间件源码简单分析 settings里有关中间件的配置 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddlew ...
- negroni-gzip源码简单分析解读
negroni-gzip源码简单分析解读 这是一个为Negroni设计的gzip压缩处理中间件,需要用到已有的compress中的gzip,阅读了不长的源码之后,总结了一些关键要点和注意点. 检查是否 ...
- urllib源码简单分析
对下面这段代码做分析 import urllib params = urllib.urlencode({'wd': 'python'}) f = urllib.urlopen("http:/ ...
- CardboardSDK-iOS 源码简单分析
该项目地址: 地址 克隆地址为 https://github.com/rsanchezsaez/CardboardSDK-iOS.git 目前如果想在iOS设备上实现双目VR的功能,Google 已经 ...
- MongoDB 默认写入关注保存数据丢失问题与源码简单分析
MongoDB 默认写入关注可能保存数据丢失问题分析 问题描述: EDI服务进行优化,将原有MQ发送成功并且DB写入成功,两个条件都达成,响应接收订单数据成功,修改为只有有一个条件成功就响应接收数据成 ...
随机推荐
- Python_练习_VS清理器
#导入os import os #创建列表放入后缀 d=[ '.txt','obj','tlog','lastbuildstate','idb','pdb','pch','res','ilk','sd ...
- Tensorflow入门-上
前置准备 在阅读本文之前,请确定你已经了解神经网络的基本结构以及前向传播.后向传播的基本原理,如果尚未了解,可以查看下文. 深度学习之神经网络 什么是TensorFlow? TensorFlow是Go ...
- 5-Java-C(位平方和)
题目描述: 把一个整数的每个数位都平方后求和,又得到一个整数,我们称这个整数为:位平方和. 对新得到的整数仍然可以继续这一运算过程. 比如,给定整数为4,则一系列的运算结果为: 16,37,58,89 ...
- C3P0连接池参数配置说明
C3P0连接池参数配置说明 created by cjk on 2017.8.15 常用配置 initialPoolSize:连接池初始化时创建的连接数,default : 3(建议使用) minPo ...
- ubuntulinux 更改时区设置时间
Linux/shell命令的实际应用——查看并修改系统时区 命令: www.2cto.com date -R //查询当前系统时间与默认时区 cp /usr/share/zoneinfo/Asia/S ...
- Linux运维到底是做什么的?在开始学习之前,你必须了解这些!
首先祝贺你选择学习Linux,你可能即将踏上Linux的工作之旅,出发之前,让我带你来看一看关于Linux和Linux运维的一切. Linux因其高效率.易于裁剪.应用广等优势,成为了当今中高端服务器 ...
- babun
Table of Contents 1. 环境 2. 检查/更新 3. 包管理 4. 版本管理 Git 4.1. 设置姓名邮箱(全局方式) 4.2. 添加 SSH 4.3. 链接测试 4.4. 权 ...
- buf.includes()
buf.includes(value[, byteOffset][, encoding]) value {String} | {Buffer} | {Number} byteOffset {Numbe ...
- ecshop 修改支持php7 方案
修改方法 http://jsb.php-php.com/2016/05/472/ 修改数据库配置 data/config.php
- rbac组件之权限操作(四)
对于权限表的操作有两种方式,第一种是一个个的权限进行curd,另外一种是批量操作,自动发现django程序中的路由,进行批量curd,首先介绍第一种方式. 因为在列出菜单时,已经将权限列表列出来了,所 ...