FFMpeg中关键数据结构之间的关系
1 | graph LR |
- 每个AVStream存储一个视频/音频流的相关数据;
- 每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;
- 每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。
- 每种解码器都对应一个AVCodec结构。
数据结构的动态和静态关系
URLProtocol和URLContext、AVInputFormat和AVFormatContext、AVCodec和AVCodecContext
Context结构将多种类型的广义数据的共同部分抽象出来,着重于动态性,其核心成员只能在程序运行时动态确定其值。并且接口类的数据结构在运行时有多个实例,而相应的Context类只有一个实例,同时体现了数据结构的划分原则,如果有一对多的关系就要分开定义。
数据结构解析
AVInputFormat/AVFormatContext/AVIContext
分析AVInputFormat/AVFormatContext/AVIContext 三个结构体之间的关系。
AVFormatContext父类
AVInputFormat接口类,libavformat/avidec.c实现了avi封装器的接口。
AVIContext 子类,包含指向父类的指针以及子类特有属性。
AVFormatContext通过AVInputFormat调用avidec封装器的函数,设置AVIContext 特有属性和AVFormatContext通用属性。
1 | // libavformat/avformat.h |
URLProtocol/URLContext/AVIOContext/HTTPContext
URLContext通过URLProtocol调用http的函数,设置HTTPContext特有属性和URLContext通用属性。
AVIOContext在此之上,包含了opaque指针,可以指向URLContext使用对应URL的实现,也可以自定义结构体,实现read、write等函数。
1 | // libavformat/url.h |
AVCodec/AVCodecContext/MsrleContext
分析AVCodec/AVCodecContext/MsrleContext三个结构体之间的关系。
AVCodecContext父类
AVCodec接口类,libavcodec/msrle.c实现了Msrle解码器的接口。
MsrleContext子类,包含指向父类的指针以及子类特有属性。
AVCodecContext通过AVCodec调用Msrle解码器的函数,设置MsrleContext特有属性和AVCodecContext通用属性。
1 | typedef struct AVCodecContext{ // 类似父类 |
AVStream/AVIStream/AVCodecParameters
AVStream 结构表示当前媒体流的上下文context, 着重于所有媒体流共有的属性(并且是在程序运行时才能确定其值)和关联其他结构的字段。
codecpar 字段关联当前音视频媒体使用的编解码器; priv_data 字段关联解析各个具体媒体流与文件容器有关的独有的属性;还有一些媒体帧索引和时钟信息
与之前两个不同,这类结构体没有定义函数,都是stream属性
1 | // demux时候获取stream |
AVPacket/AVPacketList/AVFrame
1 | typedef struct AVPacket { |
AVUtil :工具类
- AVLog:日志输出
- AVOption (AVClass):选项设置,用ffmpeg查询支持哪些AVOption。例如:ffmpeg -h filter=volume。
- AVDictionary:键值对存储
- ParseUtil:字符串解析