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解码详细流程的更多相关文章

  1. FFmpeg编码详细流程

    FFmpeg在编码一个视频的时候的函数调用流程.为了保证结构清晰,其中仅列出了最关键的函数,剔除了其它不是特别重要的函数. 函数背景色 函数在图中以方框的形式表现出来.不同的背景色标志了该函数不同的作 ...

  2. WebRTC VideoEngine超详细教程(三)——集成X264编码和ffmpeg解码

    转自:http://blog.csdn.net/nonmarking/article/details/47958395 本系列目前共三篇文章,后续还会更新 WebRTC VideoEngine超详细教 ...

  3. ffmpeg 编解码详细过程

    ffmpeg编解码详细过程     bobbypollo 转:ffmpeg编解码详细过程 原文地址:ffmpeg编解码详细过程(转)作者:心在飞翔原文出处: http://www.360doc.com ...

  4. FFmpeg开发笔记(四):ffmpeg解码的基本流程详解

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  5. FFmpeg开发笔记(五):ffmpeg解码的基本流程详解(ffmpeg3新解码api)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  6. FFMPEG解码流程

    FFMPEG解码流程:  1. 注册所有容器格式和CODEC: av_register_all()  2. 打开文件: av_open_input_file()  3. 从文件中提取流信息: av_f ...

  7. (转)FFMPEG解码流程

    http://www.douban.com/note/228831821/ FFMPEG解码流程:     1. 注册所有容器格式和CODEC: av_register_all()     2. 打开 ...

  8. 最新FFMPEG解码流程

    FFMPEG解码流程: 1. 注册所有容器格式和CODEC:  av_register_all() 2. 打开文件:                    av_open_input_file() 3 ...

  9. FFmpeg解码H264及swscale缩放详解

    本文概要: 本文介绍著名开源音视频编解码库ffmpeg如何解码h264码流,比较详细阐述了其h264码流输入过程,解码原理,解码过程.同时,大部分应用环境下,以原始码流视频大小展示并不是最佳方式,因此 ...

随机推荐

  1. element-ui select组件使用需要注意的

    当在使用select组件的时候,要注意 <el-select v-model="scope.row.state" @change="editDriftStatus& ...

  2. uva 11732 (trie树)

    题意:求N个字符串两两比较,共比较了多少次? #include<iostream> #include<cstring> #include<cstdio> using ...

  3. linux环境内存分配原理 mallocinfo【转】

    转自:http://www.cnblogs.com/dongzhiquan/p/5621906.html Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和fr ...

  4. 40深入理解C指针之---指针与单链表

    一.指针与单链表 1.定义:通过使用指针将节点(结点)链接起来成为链表 2.节点(结点): 1).数据域:主要用来存储数据,可以基本数据类型,也可以是构造数据类型: 2).指针域:主要用来当前节点(结 ...

  5. Cython 一篇通

    Cython的类型 1 类型定义 1.1 定义一个C变量: 1.1.1 在Cython里定义一个C变量和C语言类似,不同的地方就是在声明的最前面要加上cdef,另外,末尾不用加分号";“如: ...

  6. LeetCode OJ--Best Time to Buy and Sell Stock III

    http://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ 这三道题,很好的进阶.1题简单处理,2题使用贪心,3题使用动态 ...

  7. AC日记——花店橱窗布置 codevs 1028

    题目描述 Description 假设以最美观的方式布置花店的橱窗,有F束花,V个花瓶,我们用美学值(一个整数)表示每束花放入每个花瓶所产生的美学效果.为了取得最佳的美学效果,必须使花的摆放取得最大的 ...

  8. guava之cache

    转自:http://ifeve.com/google-guava-cachesexplained/ 范例 01 LoadingCache<Key, Graph> graphs = Cach ...

  9. C++: 多态 虚函数

    一.多态: 1.多态是什么:具有不同功能的函数可以用同一个函数名 2.静态多态:程序编译时决定,通过函数重载实现. 3.动态多态:程序运行时决定,通过虚函数实现. 二.虚函数: 1.引入目的:可以通过 ...

  10. PE 512 Sums of totients of powers

    可以很简单的发现,当n是奇数的时候,f(n)=φ(n),否则f(n)=0. 所以我们就是求n<=5*10^8且n为奇数的φ的和. 首先我们可以做到用杜教筛算出φ的前缀和,但是如何把偶数的减去? ...