FFmpeg 结构体关系分析
FFmpeg中结构体众多,各司其职,我们迫切需要来从宏观上分析这些结构体之间的关系,这有助于我们了解FFmpeg的底层结构。
一、分类
FFMPEG中结构体很多。最关键的结构体可以分成以下几类:
a) 解协议(http,rtsp,rtmp,mms)
AVIOContext,URLProtocol,URLContext主要存储视音频使用的协议的类型以及状态。URLProtocol存储输入视音频使用的封装格式。每种协议都对应一个URLProtocol结构。(注意:FFMPEG中文件也被当做一种协议“file”)
b) 解封装(flv,avi,rmvb,mp4)
AVFormatContext主要存储视音频封装格式中包含的信息;AVInputFormat存储输入视音频使用的封装格式。每种视音频封装格式都对应一个AVInputFormat 结构。
音视频解封装操作细节参见: FFmpeg 音视频解封装.
c) 解码(h264,mpeg2,aac,mp3)
每个AVStream存储一个视频/音频流的相关数据;每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。每种解码器都对应一个AVCodec结构。
音视频解码操作细节参见: FFmpeg 音视频解码🐎.
d) 存数据
视频的话,每个结构一般是存一帧;音频可能有好几帧
解码前数据:AVPacket
解码后数据:AVFrame
储存数据相关操作参见: FFmpeg 内存模型.
他们之间的对应关系如下所示
二、各个数据结构
- AVFormatContext
封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息。 - AVInputFormat
每种封装格式(例如FLV, MKV, MP4, AVI)对应一个该结构体。
AVOutputFormat muxer - AVStream
视频文件中每个视频(音频)流对应一个该结构体。 - AVCodecContext
编解码器上下文结构体,保存了视频(音频)编解码相关信息。 - AVCodec
每种视频(音频)编解码器(例如H.264解码器)对应一个该结构体。 - AVPacket
存储一帧压缩编码数据。 - AVFrame
存储一帧解码后像素(采样)数据。
三、结构体之间的关系
1.AVFormatContext和AVInputFormat之间的关系
- AVInputFormat被封装在AVFormatContext里
- AVFormatContext 作为API被外界调用
AVInputFormat 主要是FFmpeg内部调用 - AVFormatContext里保存了视频文件封装格式相关信息,他是负责储存数据的结构体。而AVInputFormat代表了各个封装格式,属于方法,这是一种面向对象的封装。
- 通过 int avformat_open_input(AVFormatContext **ps, const char *filename,
AVInputFormat *fmt, AVDictionary **options)函数装载解封装器
2. AVCodecContext和AVCodec之间的关系
和1非常类似,可以类比思考。AVCodec被封装在 AVCodecContext内,AVCodecContext是编解码器上下文结构体,保存了视频(音频)编解码相关信息。AVCodec各种视频(音频)编解码器(例如H.264解码器)。也是数据和方法的关系。
3.AVFormatContext, AVStream和AVCodecContext之间的关系
AVStream和AVpacket中都有index字段用于区分不同的码流(视频、音频、字幕等),AVFormatContext中包含输入的AVStream数组用于记录各个码流,nb_streams记录输入码流的数量。
这篇文章前半部分来源于https://blog.csdn.net/leixiaohua1020/article/details/11693997,后半部分为本人原创。