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

FFmpeg的库函数源码分析文章列表:

【架构图】

FFmpeg源码结构图 - 解码

FFmpeg源码结构图 - 编码

【通用】

FFmpeg 源码简单分析:av_register_all()

FFmpeg 源码简单分析:avcodec_register_all()

FFmpeg 源码简单分析:内存的分配和释放(av_malloc()、av_free()等)

FFmpeg 源码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)

FFmpeg 源码简单分析:avio_open2()

FFmpeg 源码简单分析:av_find_decoder()和av_find_encoder()

FFmpeg 源码简单分析:avcodec_open2()

FFmpeg 源码简单分析:avcodec_close()

【解码】

图解FFMPEG打开媒体的函数avformat_open_input

FFmpeg 源码简单分析:avformat_open_input()

FFmpeg 源码简单分析:avformat_find_stream_info()

FFmpeg 源码简单分析:av_read_frame()

FFmpeg 源码简单分析:avcodec_decode_video2()

FFmpeg 源码简单分析:avformat_close_input()

【编码】

FFmpeg 源码简单分析:avformat_alloc_output_context2()

FFmpeg 源码简单分析:avformat_write_header()

FFmpeg 源码简单分析:avcodec_encode_video()

FFmpeg 源码简单分析:av_write_frame()

FFmpeg 源码简单分析:av_write_trailer()

【其他】

FFmpeg源码简单分析:日志输出系统(av_log()等)

FFmpeg源码简单分析:结构体成员管理系统-AVClass

FFmpeg源码简单分析:结构体成员管理系统-AVOption

FFmpeg源码简单分析:libswscale的sws_getContext()

FFmpeg源码简单分析:libswscale的sws_scale()

FFmpeg源码简单分析:libavdevice的avdevice_register_all()

FFmpeg源码简单分析:libavdevice的gdigrab

【脚本】

FFmpeg源码简单分析:makefile

FFmpeg源码简单分析:configure

【H.264】

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

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

上一篇文章深入分析了FFmpeg解码过程中核心API的内部源码,本文继续分析FFmpeg编码过程中核心API的内部源码。

本文的编码流程能够參考程序《最简单的基于FFmpeg的视频编码器》。

函数调用关系图

首先呈现分析的结果,如图所看到的。这张图的尺寸非常大(大于4000x4000)。因此须要打开图片链接之后将图片保存为本地文件,然后才干查看。它表明了FFmpeg在编码一个视频的时候的函数调用流程。为了保证结构清晰,当中仅列出了最关键的函数。剔除了其他不是特别重要的函数。

单击查看更清晰的图片

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

函数背景色

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

粉红色背景函数:FFmpeg的API函数。

白色背景的函数:FFmpeg的内部函数。

黄色背景的函数:URLProtocol结构体中的函数,包括了读写各种协议的功能。
绿色背景的函数:AVOutputFormat结构体中的函数,包括了读写各种封装格式的功能。

蓝色背景的函数:AVCodec结构体中的函数。包括了编解码的功能。

区域

整个关系图能够分为以下几个区域:

左边区域——架构函数区域:这些函数并不针对某一特定的视频格式。
右上方黄色区域——协议处理函数区域:不同的协议(RTP,RTMP,FILE)会调用不同的协议处理函数。

右边中间绿色区域——封装格式处理函数区域:不同的封装格式(MKV,FLV,MPEG2TS,AVI)会调用不同的封装格式处理函数。
右边下方蓝色区域——编解码函数区域:不同的编码标准(HEVC,H.264,MPEG2)会调用不同的编解码函数。

箭头线

为了把调用关系表示的更明显,图中的箭头线也使用了不同的颜色:

红色的箭头线:标志了编码的流程。
其他颜色的箭头线:标志了函数之间的调用关系。当中:
调用URLProtocol结构体中的函数用黄色箭头线标识。

调用AVOutputFormat结构体中的函数用绿色箭头线标识;

调用AVCodec结构体中的函数用蓝色箭头线标识。

函数所在的文件

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

函数功能简述

以下简单列出几个区域中函数之间的调用关系(函数之间的调用关系使用缩进的方式表现出来)。

具体的函数分析能够參考相关的《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_output_context2()【函数简单分析

1) avformat_alloc_context()

(a) av_malloc(sizeof(AVFormatContext))

(b) avformat_get_context_defaults()

a) av_opt_set_defaults()

2) av_guess_format()

(a) av_oformat_next()

(b) av_match_name()

(c) av_match_ext()

3. avio_open2()【函数简单分析

1) ffurl_open()

(a) ffurl_alloc()

a) url_find_protocol()

b) url_alloc_for_protocol()

(b) ffurl_connect()

a) URLProtocol->url_open()

2) ffio_fdopen()

(a) av_malloc(buffer_size)

(b) avio_alloc_context()

a) av_mallocz(sizeof(AVIOContext))

b) ffio_init_context()

4. avformat_new_stream()【函数简单分析

1) av_mallocz(sizeof(AVStream))

2) avcodec_alloc_context3()

(a) av_malloc(sizeof(AVCodecContext))

(b) avcodec_get_context_defaults3()

5. avcodec_find_encoder()【函数简单分析

1) find_encdec()

6. avcodec_open2()【函数简单分析

1) AVCodec->init()

7. avformat_write_header()【函数简单分析

1) init_muxer()

2) AVOutputFormat->write_header()

3) init_pts()

8. avcodec_encode_video2()【函数简单分析

1) AVCodec->encode2()

9. av_write_frame()【函数简单分析

1) check_packet()

2) compute_pkt_fields2()

3) write_packet()

(a) AVOutputFormat->write_packet()

10. av_write_trailer()【函数简单分析

1) write_packet()

2) AVOutputFormat->write_trailer()

11. avcodec_close()【函数简单分析

1) AVCodec->close()

12. avformat_free_context()【函数简单分析

1) ff_free_stream()

13. avio_close()【函数简单分析

1) avio_flush()

(a) flush_buffer()

2) ffurl_close()

(a) ffurl_closep()

a) 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()

右中区域(AVOutputFormat封装格式处理函数)

AVOutputFormat包括例如以下封装格式处理函数指针:

write_header():写文件头
write_packet():写一帧数据
write_trailer():写文件尾

【样例】不同的封装格式相应着上述接口有不同的实现函数。举几个样例:

FLV封装格式相应的AVOutputFormat结构体ff_flv_muxer:
write_header() -> flv_write_header()
write_packet() –> flv_write_packet()

write_trailer() -> flv_write_trailer()

MKV封装格式相应的AVOutputFormat结构体ff_matroska_muxer:
write_header() -> mkv_write_header()
write_packet() –> mkv_write_flush_packet()

write_trailer() -> mkv_write_trailer()

MPEG2TS封装格式相应的AVOutputFormat结构体ff_mpegts_muxer:
write_header() -> mpegts_write_header()
write_packet() –> mpegts_write_packet()

write_trailer() -> mpegts_write_end()

AVI封装格式相应的AVOutputFormat结构体ff_avi_muxer:
write_header() -> avi_write_header()
write_packet() –> avi_write_packet()
write_trailer() -> avi_write_trailer()

右下区域(AVCodec编解码函数)

AVCodec包括例如以下编解码函数指针:

init():初始化
encode2():编码一帧数据
close():关闭

【样例】不同的编解码器相应着上述接口有不同的实现函数。举几个样例:

HEVC编码器相应的AVCodec结构体ff_libx265_encoder:
init() -> libx265_encode_init() -> x265_param_alloc(), x265_param_default_preset(), x265_encoder_open()
encode2() -> libx265_encode_frame() -> x265_encoder_encode()

close() -> libx265_encode_close() -> x265_param_free(), x265_encoder_close()

H.264编码器相应的AVCodec结构体ff_libx264_encoder:
init() -> X264_init() -> x264_param_default(), x264_encoder_open(), x264_encoder_headers()
encode2() -> X264_frame() -> x264_encoder_encode()

close() -> X264_close() -> x264_encoder_close()

VP8编码器(libVPX)相应的AVCodec结构体ff_libvpx_vp8_encoder:
init() -> vpx_init() -> vpx_codec_enc_config_default()
encode2() -> vp8_encode() -> vpx_codec_enc_init(), vpx_codec_encode()

close() -> vp8_free() -> vpx_codec_destroy()

MPEG2编码器相应的AVCodec结构体ff_mpeg2video_encoder:
init() -> encode_init()
encode2() -> ff_mpv_encode_picture()
close() -> ff_mpv_encode_end()

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

FFmpeg源码结构图 - 编码的更多相关文章

  1. FFmpeg源码结构图 - 解码

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  2. FFmpeg源码简单分析:libswscale的sws_scale()

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  3. FFmpeg源码简单分析:结构体成员管理系统-AVOption

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  4. 最新版ffmpeg源码分析

    最新版ffmpeg源码分析一:框架 (ffmpeg v0.9) 框架 最新版的ffmpeg中发现了一个新的东西:avconv,而且ffmpeg.c与avconv.c一个模样,一研究才发现是libav下 ...

  5. 修改FFMpeg源码—捕获丢包

    概述 最近我们项目有一个需求就是解决客户端播放RTSP视频流花屏的问题,一般来说丢包就会引起花屏,导致客户端花屏的因素又有很多,比如说: 相机到服务器丢包 服务器到客户端丢包 等等... 其中服务器到 ...

  6. 安卓图表引擎AChartEngine(六) - 框架源码结构图

    包结构: org.achartengine: org.achartengine.model: org.achartengine.renderer: org.achartengine.tools: 安卓 ...

  7. 把自定义的demuxer加入ffmpeg源码

    .简介:把上一篇文章中的demuxer加入ffmpeg源码中去,使可以用命令行方式调用自定义的demuxer 第一步: 在libavformat目录下新建mkdemuxer.c和mkdemuxer.h ...

  8. ffmpeg源码编译环境搭建

    ffmpeg是视频开发最常用到的开源软件,FFmpeg功能强大,用途广泛,提供几乎所有你能够想到的与视频开发相关的操作,许多商业软件都以ffmpeg为基础进行开发定制. FFmpeg: FFmpeg ...

  9. v74.01 鸿蒙内核源码分析(编码方式篇) | 机器指令是如何编码的 | 百篇博客分析OpenHarmony源码

    本篇关键词:指令格式.条件域.类型域.操作域.数据指令.访存指令.跳转指令.SVC(软件中断) 内核汇编相关篇为: v74.01 鸿蒙内核源码分析(编码方式) | 机器指令是如何编码的 v75.03 ...

随机推荐

  1. centos 6.5安装VMware tools

    系统描述:win7旗舰版64位系统+VMware Workstation10+CentOS6.5(win7系统上安装了VMware Workstation10虚拟化软件,在该虚拟化软件上安装了Cent ...

  2. Notepad++源代码阅读——窗口封装与继承

    引言 近期在看Notepad++的源代码,学习学习Win32 原生API的开发技巧. 本文以Notepad++ 1.0版本的源代码为例讲解如何封装windows窗口,实现面向对象开发,如何通过窗口的继 ...

  3. Shell脚本里的双冒号是什么意思

    这个是代码开发风格,其实也就是一个函数名,相当于下划线分割,但改读成包名之后就意义不一样.这个是根据Google的Shell开发规范进行定义的. 参考: https://google.github.i ...

  4. .NET泛型02,泛型的使用

    在" .NET泛型01,为什么需要泛型,泛型基本语法"中,了解了泛型的基本概念,本篇偏重于泛型的使用.主要包括: ■ 泛型方法重载需要注意的问题■ 泛型的类型推断■ 泛型方法也可以 ...

  5. datagrid在MVC中的运用04-同时添加搜索和操作区域

    本文介绍在datagrid上同时添加搜索和操作区域. 仅仅是增加操作区域 □ 方法1 $('#dg').datagrid({ toolbar: '#tb' }); <div id="t ...

  6. [转载] MATLAB快捷键

    原文地址,点此查看 一.常用对象操作 除了一般windows窗口的常用功能键外. 1.!dir 可以查看当前工作目录的文件. !dir& 可以在dos状态下查看. 2.who   可以查看当前 ...

  7. linux普通用户获取管理员权限

    原文:http://www.cnblogs.com/likwo/p/3435404.html 测试环境:CentOS 5.5 1.添加用户,首先用adduser命令添加一个普通用户,命令如下: #ad ...

  8. 浅用block 转

    block是一门有用的大后期学问.现在我只是列出一点基本用法. 1.快速枚举(Enumeration) 通常是和NSArray, NSDictionary, NSSet, NSIndexSet放在一起 ...

  9. arcgis10.5新功能图形缓冲

    摘要 在输入要素周围某一指定距离内创建缓冲区多边形.在要素周围生成缓冲区时,大部分制图形状对缓冲区末端(端头)和拐角(连接)可用. 插图  

  10. 通过微软的HTML Help Workshop 利用.html文件 生成简单的chm帮助类的文件

    1.下载并安装Microsoft HTML Help Workshop 下载链接:http://www.microsoft.com/en-us/download/details.aspx?id=211 ...