导语:初学ffmpeg的人往往觉得ffmpeg纷繁复杂,不知道从何处下手,感觉理不清头绪。这篇文章就是尽量帮助大家理清ffmpeg的逻辑结构和学习路线。
ffmpeg是一个开源的处理音视频库。它内部包括很多组件,通过这些组件我们可以认识到ffmpeg的具体构成以及具有哪些功能。同样ffmpeg有命令行形式和函数形式,命令行可以在bash中或者dos界面运行,函数则是在程序中使用。
这篇文章将从ffmpeg框架,ffmpeg常用命令,ffmpeg常用结构体和ffmpeg常用函数四个方面总结一下。
从官网下载ffmpeg可以下载三个版本:static,shared,dev。
前两个版本都包括了ffmpeg.exe,ffplay.exe,ffprobe.exe三个可执行文件。区别在于static版本是静态编译,shared版本是动态编译。而dev版本则是开发版本,里面包含了库文件和头文件。
如果按照使用目的可以将命令归类为
如果按照使用的方面可以将命令归类为
下面介绍按照以下使用目的分类的常用命令行参数。
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编程中基础且常用到的结构体:
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中常用到的函数。
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 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有