Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ffmpeg结构梳理总结

ffmpeg结构梳理总结

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

导语:初学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 删除。

评论
登录后参与评论
1 条评论
热度
最新
是不是有种抄袭的意味
是不是有种抄袭的意味
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
音视频八股文(6)-- ffmpeg大体介绍和内存模型
• AVUtil:核心工具库,下面的许多其他模块都会依赖该库做一些基本的音视频处理操作。
福大大架构师每日一题
2023/04/26
5140
音视频开发之旅(60) -调试分析FFmpeg (解封装部分的)常用结构体
工欲善其事,必先利其器,断点调试,对我们梳理流程排查问题十分重要,可以ffmpeg的调试可以在XCode、VS code以及QT等ide上进行方便的调试分析。本篇我们以XCode为例来先介绍下ffplay的断点调试,以ffmpeg4.4版本来进行分析。
音视频开发之旅
2021/12/04
9410
音视频开发之旅(60) -调试分析FFmpeg (解封装部分的)常用结构体
FFmepg 核心开发库及重要数据结构与API
本文介绍 FFmpeg 骨架:“八大金刚” 核心开发库,重要数据结构与 API
Gnep@97
2023/11/28
4010
FFmepg 核心开发库及重要数据结构与API
安卓ffmpeg_有什么好用的视频解码
将封装格式解压后可以得到压缩过的音视频等. 将压缩过的视频解压后可以得到 视频像素数据(RGB,YUV等).常见的视频压缩格式有H.264, MPEG4等…
全栈程序员站长
2022/11/08
1.6K0
安卓ffmpeg_有什么好用的视频解码
FFmpeg菜鸡互啄#第3篇#视频解码
解码过程 基本过程:打开输入文件,查找视频流,打开解码器,循环读帧解码帧,关闭解码器,关闭输入文件。 解码数据结构 Code #define _CRT_SECURE_NO_WARNINGS #i
_gongluck
2018/03/08
1.2K0
FFmpeg菜鸡互啄#第3篇#视频解码
音视频开发之旅(34) - 基于FFmpeg实现简单的视频解码器
FFmpeg解码涉及的知识点比较多,很容易被函数和结构体搞定不知所错,我们先从整体上对解码流程有个认知,画了张图把解码流程图,如下
音视频开发之旅
2021/02/28
1.4K0
5.FFMPEG-Qt移植ffmpeg、ffmpeg结构体介绍
https://blog.csdn.net/leixiaohua1020/article/details/11693997
诺谦
2020/08/31
8140
FFmpeg 4.x 从入门到精通(一)—— QT 中如何用 FFmpeg 实现软件解码
因为在2021年给自己定了目标和计划,学习ffmpeg,所以这篇文章是实现计划的第一步。
全栈程序员站长
2022/09/13
1.3K0
ffmpeg的H.264解码
FFmpeg_allluckly.cn.png 新建工程,导入由Mac编译ffmpeg获取FFmpeg-iOS编译好的FFmpeg-iOS,然后导入系统依赖的库 AudioToolbox.framework CoreMedia.framework VideoToolbox.framework libiconv.tbd libbz2.tbd libz.tbd 编译的时候报错: 'libavcodec/avcodec.h' file not found ,修改Header search paths 里的路径:
Bison
2018/07/04
1.8K0
FFmpeg菜鸡互啄#第4篇#音频解码
解码过程 音频解码跟上一篇的视频解码过程是一样的:打开输入文件,查找音频流,打开解码器,循环读帧解码帧,关闭解码器,关闭输入文件。 Code #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> /* #define __STDC_CONSTANT_MACROS #ifndef INT64_C #define INT64_C(c) (c ## LL) #define UINT64_C(c) (c ## ULL) #endif */ extern "C" {
_gongluck
2018/03/08
1.2K0
FFmpeg菜鸡互啄#第4篇#音频解码
音视频文件解码
音视频处理流程中讲解了音视频处理的流程(解复用、解码、渲染等),针对于解复用部分在音视频的那几个关键参数中已经提过了,本文不再赘述,本文将重点介绍解码的过程。
程序员的园
2024/11/28
1610
音视频文件解码
ffmpeg常用库、术语、API、数据结构总结
封装格式步骤: 1、分配解复用器上下文(avformat_alloc_context()); 2、根据url打开本地文件或网络流(avformat_open_input()); 3、读取媒体的数据包,查找流信息(avformat_find_stream_info()); 4、遍历数据 (4-1)、从文件中读取数据包(av_read_frame()); (4-2)、或者 定位文件位置进行遍历(avformat_seek_file()、av_seek_frame()); 5、关闭解复用器(avformat_close_input())或释放不使用的资源; ​
手撕代码八百里
2021/12/28
1.1K0
音视频开发之旅(61)- 分析FFmpeg (解码部分的)常用结构体
然后分别开启音频和视频的解码线程开始解码。我们可以看到涉及的主要结构体有AVCodecContext 、AVCodecParameters 、AVCodec 、AVFrame
音视频开发之旅
2021/12/05
7530
音视频开发之旅(61)- 分析FFmpeg (解码部分的)常用结构体
FFmpeg简易播放器的实现-最简版
下图引用自“雷霄骅,视音频编解码技术零基础学习方法”,因原图太小,看不太清楚,故重新制作了一张图片。
叶余
2019/04/02
1.5K0
FFmpeg简易播放器的实现-最简版
FFmpeg4.0+SDL2.0笔记01:Making Screencaps
背景:在系统性学习FFmpeg时,发现官方推荐教程还是15年的,不少接口已经弃用,大版本也升了一级,所以在这里记录下FFmpeg4.0+SDL2.0的学习过程。
非一
2021/04/06
6600
ffmpeg源码学习
• AVUtil:核心工具库,下面的许多其他模块都会依赖该库做一些基本的音视频处理操作。
vitofliu
2021/07/05
3.2K0
音视频开发之旅(35) -FFmpeg + AudioTrack 实现音频解码和播放
上一篇我们了解了FFmpeg解码流程、关键函数和结构体,实现了视频解码器。这篇我们来实现下音频的解码器。解码流程和视频的基本一致。FFmpeg解码的音频裸数据是PCM格式,android上播放PCM音频数据可以通过AudioTrack和OpenSL ES来实现。
音视频开发之旅
2021/03/02
2K0
音视频开发之旅(35) -FFmpeg + AudioTrack 实现音频解码和播放
Android FFmpeg音视频编码(十六)
上一章,我们了解ffmpeg的解封装,解码过程,这一章我们来了解一下ffmpeg是怎样进行编码,和封装工作的,工作流程如下图所示:
PengJie
2021/01/17
1.9K0
偶遇FFmpeg(番外)——FFmpeg花样编译入魔1之裁剪大小
在偶遇FFmpeg(三)——Android集成这边文章中曾经介绍过FFmpeg和Android的交叉编译。文章中也提到过如何裁剪SO文件大小的方式。 这边文章就这个问题。进行实战。
deep_sadness
2018/10/25
3.4K0
FFmpeg中的常用结构体分析
  在学习使用FFmpeg进行编解码时,我们有必要先去熟悉FFmpeg中的常用结构体,只有对它们的含义和用途有深刻的了解,我们才能为后面的学习打下坚实的基础。所以,这篇文章将会介绍这些常用的结构体有哪些,然后再介绍它们的具体用途。
故乡的樱花开了
2023/10/22
2990
相关推荐
音视频八股文(6)-- ffmpeg大体介绍和内存模型
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档