FFmpeg解码详细流程
FFmpeg在解码一个视频的时候的函数调用流程。为了保证结构清晰,其中仅列出了最关键的函数,剔除了其它不是特别重要的函数。
下面解释一下图中关键标记的含义。
函数背景色
函数在图中以方框的形式表现出来。不同的背景色标志了该函数不同的作用:
- 粉红色背景函数:FFmpeg的API函数。
- 白色背景的函数:FFmpeg的内部函数。
- 黄色背景的函数:URLProtocol结构体中的函数,包含处理协议(Protocol)的功能。
- 绿色背景的函数:AVInputFormat结构体中的函数,包含处理封装格式(Format)的功能。
- 蓝色背景的函数:AVCodec结构体中的函数,包含了编解码器(Codec)的功能。
PS:URLProtocol,AVInputFormat,AVCodec在FFmpeg开始运行并且注册完组件之后,都会分别被连接成一个个的链表。因此实际上是有很多的URLProtocol,AVInputFormat,AVCodec的。图中画出了解码一个输入协议是“文件”(其实就是打开一个文件。“文件”也被当做是一种广义的协议),封装格式为FLV,视频编码格式是H.264的数据的函数调用关系。
区域
整个架构图可以分为以下几个区域:
- 左边区域——架构函数区域:这些函数并不针对某一特定的视频格式。
- 右上方黄色区域——协议处理函数区域:不同的协议(RTP,RTMP,FILE)会调用不同的协议处理函数。
- 右边中间绿色区域——封装格式处理函数区域:不同的封装格式(MKV,FLV,MPEGTS,AVI)会调用不同的封装格式处理函数。
- 右边下方蓝色区域——编解码函数区域:不同的编码标准(HEVC,H.264,MPEG2)会调用不同的编解码函数。
箭头线
为了把调用关系表示的更明显,图中的箭头线也使用了不同的颜色:
黑色箭头线:标志了函数之间的调用关系。
红色的箭头线:标志了解码的流程。
其他颜色的箭头线:标志了函数之间的调用关系。其中:
调用URLProtocol结构体中的函数用黄色箭头线标识;
调用AVInputFormat结构体中的函数用绿色箭头线标识;
调用AVCodec结构体中的函数用蓝色箭头线标识。
函数所在的文件
每个函数旁边标识了它所在的文件的路径。
此外,还有一点需要注意的是,一些API函数内部也调用了另一些API函数。也就是说,API函数并不一定全部都调用FFmpeg的内部函数,他也有可能调用其他的API函数。例如从图中可以看出来,avformat_close_input()调用了avformat_free_context()和avio_close()。这些在内部代码中被调用的API函数也标记为粉红色。
函数调用关系
下面简单列出几个区域中函数之间的调用关系(函数之间的调用关系使用缩进的方式表现出来)。
左边区域(FFmpeg架构函数)
1. av_register_all()
1) avcodec_register_all()
(a) REGISTER_HWACCEL()
(b) REGISTER_ENCODER()
(c) REGISTER_DECODER()
(d) REGISTER_PARSER()
(e) REGISTER_BSF()
2) REGISTER_MUXER()
3) REGISTER_DEMUXER()
4) REGISTER_PROTOCOL()
2. avformat_alloc_context()
1) av_malloc(sizeof(AVFormatContext))
2) avformat_get_context_defaults()
(a) av_opt_set_defaults()
3. avformat_open_input()
1) init_input()
(a) avio_open2()
a) ffurl_open()
i. ffurl_alloc()
l url_find_protocol()
l url_alloc_for_protocol()
ii. ffurl_connect()
URLProtocol->url_open()
b) ffio_fdopen()
i. av_malloc(buffer_size)
ii. avio_alloc_context()
l av_mallocz(sizeof(AVIOContext))
l ffio_init_context()
(b) av_probe_input_buffer2()
a) avio_read()
i. AVInputFormat->read_packet()
b) av_probe_input_format2()
c) av_probe_input_format3()
i. av_iformat_next()
ii. av_match_name()
iii. av_match_ext()
iv. AVInputFormat->read_probe()
2) AVInputFormat->read_header()
4. avformat_find_stream_info()
1) find_decoder()
(a) avcodec_find_decoder()
2) avcodec_open2()
3) read_frame_internal()
4) try_decode_frame()
(a) avcodec_decode_video2()
5) avcodec_close()
6) estimate_timings()
(a) estimate_timings_from_pts()
(b) estimate_timings_from_bit_rate()
(c) update_stream_timings()
5. avcodec_find_decoder()
1) find_encdec()
6. avcodec_open2()
1) AVCodec->init()
7. av_read_frame()
1) read_from_packet_buffer()
2) read_frame_internal()
(a) ff_read_packet()
a) AVInputFormat->read_packet()
(b) parse_packet()
a) av_parser_parse2()
8. avcodec_decode_video2()
1) av_packet_split_side_data()
2) AVCodec->decode()
3) av_frame_set_pkt_pos()
4) av_frame_set_best_effort_timestamp()
9. avcodec_close()
1) AVCodec->close()
10. avformat_close_input()
1) AVInputFormat->read_close()
2) avformat_free_context()
(a) ff_free_stream()
3) avio_close()
(a) avio_flush()
a) flush_buffer()
(b) ffurl_close()
a) ffurl_closep()
URLProtocol->url_close()
右上区域(URLProtocol协议处理函数)
URLProtocol结构体包含如下协议处理函数指针:
url_open():打开
url_read():读取
url_write():写入
url_seek():调整进度
url_close():关闭
【例子】不同的协议对应着上述接口有不同的实现函数,举几个例子:
File协议(即文件)对应的URLProtocol结构体ff_file_protocol:
url_open() -> file_open() -> open()
url_read() -> file_read() -> read()
url_write() -> file_write() -> write()
url_seek() -> file_seek() -> lseek()
url_close() -> file_close() -> close()
RTMP协议(libRTMP)对应的URLProtocol结构体ff_librtmp_protocol:
url_open() -> rtmp_open() -> RTMP_Init(), RTMP_SetupURL(), RTMP_Connect(), RTMP_ConnectStream()
url_read() -> rtmp_read() -> RTMP_Read()
url_write() -> rtmp_write() -> RTMP_Write()
url_seek() -> rtmp_read_seek() -> RTMP_SendSeek()
url_close() -> rtmp_close() -> RTMP_Close()
UDP协议对应的URLProtocol结构体ff_udp_protocol:
url_open() -> udp_open()
url_read() -> udp_read()
url_write() -> udp_write()
url_seek() -> udp_close()
url_close() -> udp_close()
右中区域(AVInputFormat封装格式处理函数)
AVInputFormat包含如下封装格式处理函数指针:
read_probe():检查格式
read_header():读取文件头
read_packet():读取一帧数据
read_seek():调整进度
read_close():关闭
【例子】不同的封装格式对应着上述接口有不同的实现函数,举几个例子:
FLV封装格式对应的AVInputFormat结构体ff_flv_demuxer:
read_probe() -> flv_probe() –> probe()
read_header() -> flv_read_header() -> create_stream() -> avformat_new_stream()
read_packet() -> flv_read_packet()
read_seek() -> flv_read_seek()
read_close() -> flv_read_close()
MKV封装格式对应的AVInputFormat结构体ff_matroska_demuxer:
read_probe() -> matroska_probe()
read_header() -> matroska_read_header()
read_packet() -> matroska_read_packet()
read_seek() -> matroska_read_seek()
read_close() -> matroska_read_close()
MPEG2TS封装格式对应的AVInputFormat结构体ff_mpegts_demuxer:
read_probe() -> mpegts_probe()
read_header() -> mpegts_read_header()
read_packet() -> mpegts_read_packet()
read_close() -> mpegts_read_close()
AVI封装格式对应的AVInputFormat结构体ff_avi_demuxer:
read_probe() -> avi_probe()
read_header() -> avi_read_header()
read_packet() -> avi_read_packet()
read_seek() -> avi_read_seek()
read_close() -> avi_read_close()
右下区域(AVCodec编解码函数)
AVCodec包含如下编解码函数指针:
init():初始化
decode():解码一帧数据
close():关闭
【例子】不同的编解码器对应着上述接口有不同的实现函数,举几个例子:
HEVC解码对应的AVCodec结构体ff_hevc_decoder:
init() -> hevc_decode_init()
decode() -> hevc_decode_frame() -> decode_nal_units()
close() -> hevc_decode_free()
H.264解码对应的AVCodec结构体ff_h264_decoder:
init() -> ff_h264_decode_init()
decode() -> h264_decode_frame() -> decode_nal_units()
close() -> h264_decode_end()
VP8解码(libVPX)对应的AVCodec结构体ff_libvpx_vp8_decoder:
init() -> vpx_init() -> vpx_codec_dec_init()
decode() -> vp8_decode() -> vpx_codec_decode(), vpx_codec_get_frame()
close() -> vp8_free() -> vpx_codec_destroy()
MPEG2解码对应的AVCodec结构体ff_mpeg2video_decoder:
init() -> mpeg_decode_init()
decode() -> mpeg_decode_frame()
close() -> mpeg_decode_end()
参考:
FFmpeg解码详细流程的更多相关文章
- FFmpeg编码详细流程
FFmpeg在编码一个视频的时候的函数调用流程.为了保证结构清晰,其中仅列出了最关键的函数,剔除了其它不是特别重要的函数. 函数背景色 函数在图中以方框的形式表现出来.不同的背景色标志了该函数不同的作 ...
- WebRTC VideoEngine超详细教程(三)——集成X264编码和ffmpeg解码
转自:http://blog.csdn.net/nonmarking/article/details/47958395 本系列目前共三篇文章,后续还会更新 WebRTC VideoEngine超详细教 ...
- ffmpeg 编解码详细过程
ffmpeg编解码详细过程 bobbypollo 转:ffmpeg编解码详细过程 原文地址:ffmpeg编解码详细过程(转)作者:心在飞翔原文出处: http://www.360doc.com ...
- FFmpeg开发笔记(四):ffmpeg解码的基本流程详解
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- FFmpeg开发笔记(五):ffmpeg解码的基本流程详解(ffmpeg3新解码api)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- FFMPEG解码流程
FFMPEG解码流程: 1. 注册所有容器格式和CODEC: av_register_all() 2. 打开文件: av_open_input_file() 3. 从文件中提取流信息: av_f ...
- (转)FFMPEG解码流程
http://www.douban.com/note/228831821/ FFMPEG解码流程: 1. 注册所有容器格式和CODEC: av_register_all() 2. 打开 ...
- 最新FFMPEG解码流程
FFMPEG解码流程: 1. 注册所有容器格式和CODEC: av_register_all() 2. 打开文件: av_open_input_file() 3 ...
- FFmpeg解码H264及swscale缩放详解
本文概要: 本文介绍著名开源音视频编解码库ffmpeg如何解码h264码流,比较详细阐述了其h264码流输入过程,解码原理,解码过程.同时,大部分应用环境下,以原始码流视频大小展示并不是最佳方式,因此 ...
随机推荐
- 《快速开发》通过Maven创建WebService项目Hello World!
有多快? 整个过程3分钟.不用下载jar包,不用一步一步创建Web Project... 你需要的就是在Maven库里选一个archetype,然后一路Next~ 先看结果: 准备好了吗?我们起飞: ...
- 标准C程序设计七---107
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- 52深入理解C指针之---不透明指针
该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教.一.size_t:用于安全表示长度,所有平台和系统都会解析成自己对应的长度 1.定义:s ...
- jmeter登录禅道案例
下载jmeter,配置环境变量 变量名:JMETER_HOME 变量值:C:\Program Files\apache-jmeter-2.11 变量名:CLASSPATH 变量值:%JMETER_HO ...
- Vijos 1323: 化工厂装箱员
题形:DP 题意:A,B,C三种物品,一共N个,顺序摆放,按顺序拿.每次手上最多能拿10个物品,然后可以将某个类别的物品分类放好,再从剩下的拿,补全10个.问最少放几次,可以把所有物品分类好. 思路: ...
- POJ 3140 Contestants Division (树dp)
题目链接:http://poj.org/problem?id=3140 题意: 给你一棵树,问你删去一条边,形成的两棵子树的节点权值之差最小是多少. 思路: dfs #include <iost ...
- Java随机数技巧-新手篇
package 向家康; import java.util.concurrent.ThreadLocalRandom; public class 练习21 { public static void m ...
- "visual studio 2012 安装引擎拒绝访问" 错误的解决
首先,我们看一下错误的具体提示,如下图所示: 这个错误,是我安装了那么多年Visual Studio的经历中,第一次遇到.太恶心了,昨天一直安装失败,导致后续其它软件的安装一再拖延.目前网上的解决方案 ...
- cookie读取设置name
cookie就是k-v形式,可以理解为一个hashmap cookie就是k-v形式,可以理解为一个hashmap cookie就是k-v形式,可以理解为一个hashmap 建立一个无生命周期的coo ...
- Android获取状态栏和标题栏的高度
版权声明:本文为博主原创文章,未经博主允许不得转载. 1.获取状态栏高度: decorView是window中的最顶层view,可以从window中获取到decorView,然后decorView有个 ...