前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ffmpeg结构梳理总结

ffmpeg结构梳理总结

原创
作者头像
汪秀军
发布2018-08-11 21:51:47
2.3K1
发布2018-08-11 21:51:47
举报

导语:初学ffmpeg的人往往觉得ffmpeg纷繁复杂,不知道从何处下手,感觉理不清头绪。这篇文章就是尽量帮助大家理清ffmpeg的逻辑结构和学习路线。

ffmpeg是一个开源的处理音视频库。它内部包括很多组件,通过这些组件我们可以认识到ffmpeg的具体构成以及具有哪些功能。同样ffmpeg有命令行形式和函数形式,命令行可以在bash中或者dos界面运行,函数则是在程序中使用。

这篇文章将从ffmpeg框架,ffmpeg常用命令,ffmpeg常用结构体和ffmpeg常用函数四个方面总结一下。

一 ffmpeg框架

ffmpeg结构
ffmpeg结构

从官网下载ffmpeg可以下载三个版本:static,shared,dev。

前两个版本都包括了ffmpeg.exe,ffplay.exe,ffprobe.exe三个可执行文件。区别在于static版本是静态编译,shared版本是动态编译。而dev版本则是开发版本,里面包含了库文件和头文件。

  • 命令行工具:ffmpeg.exe,ffplay.exe,ffprobe.exe三个可执行文件都是可以在命令行下运行。其中ffmpeg.exe可以执行对音视频的各种处理,包括编解码,音视频混合截取等各种操作。Ffplay.exe是媒体播放器,可以播放视频。Ffprobe.exe则可以得到音视频文件的各种参数。
  • 源代码框架:ffmpeg的源代码包括了好多部分。如上图所示。Libavcodec这个文件夹主要是包括音视频的编码解码软件库。Libavdevice库提供了一个通用框架,用于从许多常见的多媒体输入/输出设备中获取和呈现,并支持多种输入和输出设备。Libavfilter是对音视频进行各种操作处理的软件库。Libavformat是对音视频转换各种协议的软件库。Libavutil库是一个实用程序库,用于辅助便携式多媒体编程的,里面提供了很多有用的工具函数。Libpostproc是音视频后期处理的软件库。Libswresample库执行高度优化的音频重采样,重新矩阵化和样本格式转换操作。Libswscale库执行高度优化的图像缩放以及色彩空间和像素格式转换操作。

二 ffmpeg命令

如果按照使用目的可以将命令归类为

  • 基本信息查询
  • 主要参数
  • 音频
  • 视频

如果按照使用的方面可以将命令归类为

  • 录制
  • 分解/复用
  • 处理原始数据
  • 滤镜
  • 切割与合并
  • 图片视频互换
  • 直播相关

下面介绍按照以下使用目的分类的常用命令行参数。

1 基本信息查询参数

-version 显示版本

-formats 显示可用的格式(包括设备)

-demuxers 显示可用的demuxers

-muxers 显示可用的muxers

-devices 显示可用的设备

-codecs 显示libavcodec已知的所有编解码器

-decoders 显示可用的解码器

-encoders 显示所有可用的编码器

-bsfs 显示可用的比特流filter

-protocols 显示可用的协议

-filters 显示可用的libavfilter过滤器

-pix_fmts 显示可用的像素格式

-sample_fmts 显示可用的采样格式

-layouts 显示声道名称和标准声道布局

-colors 显示识别的颜色名称

2 主要参数

-f fmt(输入/输出) 强制输入或输出文件格式。格式通常是自动检测输入文件,并从输出文件的拓展名中猜测出来, 所以在大多数情况下这个选项是不需要的。

-I url(输入) 输入文件的网址

-y(全局参数) 覆盖输出文件而不询问

-n(全局参数) 不要覆盖输出文件,如果指定的输出文件已经存在,请立即退出

-t 从输入文件读取数据的时间或限制输出数据的时间

-ss 位置 在输入输出文件中寻找位置

-frames framecount 停止在帧计数帧之后写入流

-filter filtergraph 创建由filtergraph指定的过滤器图,并使用它来过滤流。

3 视频参数

-vframes num(输出) 设置要输出的视频帧的数量

-r 设置帧率

-s 设置分辨率

-aspect 设置指定的视频显示宽高比

-vn 禁用视频录制

-vcodec 设置视频编解码器

-vf filtergraph(输出) 创建由filtergraph指定的过滤器图,并使用它来过滤流。

4 音频参数

-aframes 设置要输出的音频帧的数量

-ar 设置音频采样频率

-ac 设置音频通道的数量

-an 禁用录音

-acodec 设置音频解编码器

-sample_fmt 设置音频采样格式

-af filtergraph(输出) 创建由filtergraph指定的过滤器图

三 ffmpeg结构体

ffmpeg常用结构体关系图(图引自http://blog.csdn.net/leixiaohua1020)
ffmpeg常用结构体关系图(图引自http://blog.csdn.net/leixiaohua1020)

下面介绍一下ffmpeg编程中基础且常用到的结构体:

1 AVFormatContext

定义在avformat.h中,主要存储音视频封装格式中包含的信息,包含编解码码流丰富的信息,统领全局的基本结构体,主要用于处理封装格式,由avformat_alloc_context()初始化,由avformat_free_context()销毁。

2 AVFrame

定义在frame.h中,AVFrame结构体一般用于存储原始数据(非压缩数据,对视频来说就是YUV,RGB,对于音频来说就是PCM),此外还包含一些相关的信息。比如,解码的时候存储了宏块类型表,QP表,运动矢量表等数据。编码的时候也存储了相关的数据。因此在使用ffmpeg进行码流分析的时候,AVFrame是一个重要的结构体。由av_frame_alloc()或av_image_fill_arrays()初始化,由av_frame_free()销毁。

3 AVCodecContext

定义在avcodec.h,AVCodecContext中很多的参数是编码的时候使用的,而不是解码的时候使用的。由avcodec_alloc_context3()初始化。

4 AVIOContext

定义在avio.h文件中,AVIOContext是ffmpeg管理输入输出数据的结构体,用于输入输出(读写文件,rtmp协议等)。该结构体由avio_alloc_context()初始化。

5 AVCodec

每一个编码器对应一个AVCodec结构体。

6 AVStream

定义在avformat.h文件中,AVStream是存储每一个视频/音频流信息的结构体,由avformat_new_stream()初始化。

7 AVPacket

定义在avcodec.h文件中,AVPacket存储压缩数据(视频对应h264等码流数据,音频对应AAC/MP3等码流数据),由av_init_packet()或av_new_packet()初始化,av_free_packet()销毁。Av_init_packet()和av_new_packet()都不负责申请AVPacket结构体空间,而是申请一块给AVpacket的成员data指针指向的空间,该空间用于存储数据。而av_free_packet()也只是释放AVPacket的data成员指向的空间。

8 AVPacketList

AVPacketList把音视频AVPacket组成一个小链表。

9 PacketQueue

PacketQueue通过AVPacketList把音视频帧AVPacket 组成一个顺序队列,是数据交换中转站。

10 URLContext

表示程序运行的当前广义输入文件使用的上下文,着重于所有广义输入文件共有的属性。

11 ByteIOContext

结构扩展URLProtocol结构成内部由缓冲机制的广泛意义上的文件,改善广义输入文件的IO性能。由其数据结构定义的字段可知,主要是缓冲区相关字段,标记字段,和一个关联字段opaque来完成广义文件读写操作。Opaque关联字段用于关联URLContext结构,间接关联并扩展URLProtocol结构。

四 ffmpeg函数

下面介绍一下ffmpeg中常用到的函数。

1 avcodec_init()

#include <libavcodec/avcodec.h>

初始化libavcodec,一般最先调用该函数。非线程安全。

2 av_register_all()

#include <libavformat/avformat.h>

初始化libavformat和注册所有的muxers,demuxer和protocols。一般在调用avcodec_init调用该方法。在这个函数中,调用了avcodec_register_all()注册多种音视频格式的编解码器,并注册各种文件的编解复用器。

3 avformat_avformat_new_stream ()

#include<libavformat/avformat.h>

分配一个AVFormatContext结构的内存,并进行简单初始化。

4 avformat_free_context()

#include<libavformat/avformat.h>

对AVFormatContext结构的内存释放。

5 avio_alloc_context()

为I/O缓存申请并初始化一个AVIOContext结构,结束使用时必须使用av_free()进行释放。

6 av_open_input_file()

以输入方式打开一个媒体文件,也即源文件,codecs并没有打开,只读取了文件的头信息。

7 av_close_input_file()

关闭使用avformat_close_input()打开的输入文件容器,但并不关系它的codecs.

8 av_find_stream_info()

#include <libavformat/avformat.h>

通过读取媒体文件中的包来获取媒体文件中的流信息,对于没有头信息的文件是非常有用的。

9 avcodec_find_decoder(enum CodeID id)

#include <libavcodec/avcodec.h>

通过code ID 查找一个已经注册的音视频解码器。音视频解码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较解码器的ID来查找。

10 avcodec_find_decoder_by_name()

通过一个指定的名称查找一个已经注册的音视频解码器。

11 avcodec_find_encoder(enum CodecID id)

#include “libavcodec/avcodec.h”

查找编码器之前,必须调用av_register_all注册所有支持的编码器。音视频编码器保存在一个链表中,查找过程中,函数从头到尾遍历链表,通过比较编码器的ID来查找。

12 avcodec_find_encoder_by_name()

通过一个指定的名称查找一个已经注册的音视频编码器。

13 avcodec_open(AVCodecContext *avctx,AVCodec * codec)

打开编解码器。

14 av_guess_format(const char * short_name,const char* filename,const char* mime_type)

#include “libavformat/avformat.h”

返回一个已经注册的最合适的输出格式。

15 AVStream* av_new_stream(AVFormatContext* s,int id)

为媒体文件添加一个流,一般作为输出的媒体文件容器添加音视频流

16 void dump_format(AVFormatContext *ic, int index, constchar *url, int is_output);

有些版本函数名为av_dump_format()。

该函数的作用就是检查初始化过程中设置的参数是否符合规范。

17 av_set_parameters()

设置初始化参数。

18 av_init_packet()

使用默认值初始化AVPacket,定义AVPacket对象后,请使用av_init_packet进行初始化

19 av_free_packet()

释放AVPacket结构体。

20 av_read_frame(AVFormatContext* s,AVPacket* pkt)

从输入源文件容器中读取一个AVPacket数据包。

该函数读出的包并不是每次都是有效的,对于读出的包我们都应该进行相应的解码(视频解码/音频解码)。在返回值>=0时,循环调用该函数进行读取,循环调用之前请调用av_free_packet函数清理AVPacket。

21 avcodec_decode_video2(AVCodecContext* avctx,AVFrame* picture,int * got_picture_ptr,AVPacket* avpkt)

解码视频流AVPacket。使用av_read_frame读取媒体流后需要进行判断,如果为视频流则调用该函数解码。返回>=0时正常,假设读取包为:AVPacket vPacket,返回值为int vLen;每次解码正常时,对vPacket做如下处理:

vPacket.size-=vLen。

vPacket.data+=vLen。

如果vPacket.size==0,则继续读下一个流包,否则继续调度该方法进行解码,直到vPackt.size==0。返回got_picture_ptr>0时,表示解码到了AVFrame *picture,其后可以对picture进行处理。

22 avcodec_decode_audio3(AVCodecContext * avctx,int16_t * samples,int * frame_size_ptr,AVPacket *avpkt)

功能类似上一个函数,解码音频流AVPacket。

这是我这段时间学习ffmpeg做的一个小总结,抛砖引玉,欢迎大家多多指正。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 ffmpeg框架
  • 二 ffmpeg命令
  • 三 ffmpeg结构体
  • 四 ffmpeg函数
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档