FFMPEG结构体分析

FFMPEG结构体分析

附录:参考文献

[1] 结构体分析:https://www.cnblogs.com/linuxAndMcu/p/12041578.html#_label2

[2] 音视频入门系列

FFmpeg结构体主要分为三个层次:

  • 协议层(Protocol:http, rtsp, rtmp,file
    • AVIOContext,URLProtocol,URLContext 主要存储音视频使用的协议的类型以及状态。URLProtocol 存储输入音视频使用的封装格式。每种协议都对应一个 URLProtocol 结构。
  • 封装层(Format:flv, avi, rmvb, mp4
    • AVFormatContext 主要存储音视频封装格式中包含的信息;AVInputFormat 存储输入音视频使用的封装格式。每种音视频封装格式都对应一个 AVInputFormat 结构。
  • 解码层(Codec:h264, mpeg2, aac, mp3
    • 每个 AVStream 存储一个视频/音频流的相关数据;每个 AVStream 对应一个 AVCodecContext ,存储该视频/音频流使用解码方式的相关数据;每个 AVCodecContext 中对应一个 AVCodec ,包含该视频/音频对应的解码器。每种解码器都对应一个 AVCodec 结构

1 AVFormatContext

描述媒体文件或媒体流的构成和基本信息,贯穿ffmpeg使用整个流程

表示一个多媒体文件或流的全局上下文信息。它包含输入输出格式、媒体流信息,以及操作文件或流所需的状态。

  • avformat_open_input()

    • 用于打开媒体文件或流,初始化 AVFormatContext
  • avformat_alloc_output_context2()

    • 创建一个新的输出 AVFormatContext

    • AVFormatContext 用于描述目标输出文件的格式和流。

  • **avformat_find_stream_info()**获取媒体流信息(如视频流、音频流等)。

    • AVFormatContext 用于存储和返回文件的流信息。
  • **av_read_frame()**从媒体文件中读取一个数据包(帧)。

    • 使用 AVFormatContext 来获取流信息和文件数据。

...许多API函数都使用到该结构体

c++ 复制代码
//基本信息成员
AVInputFormat *iformat、AVOutputFormat *oformat://输入或者输出流的格式(只能存在一个)
char *url://文件名

//IO操作成员
AVIOContext *pb://管理输入输出数据(缓存)

//流媒体相关成员
unsigned int nb_streams://音视频流的个数 
AVStream **streams://音视频流
    
//时间和同步
int64_t duration://时长

//其它
int bit_rate://比特率(单位bite/s)

AVDictionary *metadata://元数据(查看元数据:ffprobe filename)

2 AVInputFormat

表示输入媒体文件或流的封装格式。它定义了如何读取、解析、和处理特定格式的媒体文件或流,例如 MP4、MKV、FLV 等。

  • av_find_input_format、avformat_open_input

    c++ 复制代码
    AVInputFormat *av_find_input_format(const char *short_name);
    • 根据指定的格式名称查找\打开 AVInputFormat
  • avformat_find_stream_info

    c++ 复制代码
    int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
    • 函数内部会根据输入格式(通过 AVInputFormat)对媒体文件进行处理,提取其中的流信息。
c++ 复制代码
char* name://封装格式的名字
char* long_name://封装格式的长名字
char* extensions://文件扩展名,例如 "mp4,mov"。

3 AVIOContext->URLContext->URLProtocol

3.1 AVIOContext

文件(协议)操作的顶层对象,用于管理媒体文件或流的输入输出操作。它提供了一套通用的接口,用于读取和写入文件、网络流、内存缓冲区等数据源或数据目标。

  • avio_alloc_context
    • AVIOContext *avio_alloc_context(...)
    • 分配一个 AVIOContext,用来进行 I/O 操作
c++ 复制代码
//IO 缓冲区
unsigned char *buffer://缓冲开始位置
int buffer_size://缓冲区大小(默认32768)
unsigned char *buf_ptr://当前指针读取到的位置
unsigned char *buf_end://缓存结束的位置
    
//其它
void *opaque://URLContext结构体,通常传递到回调函数中,允许用户存储自定义上下文信息。

//读写回调函数
(*read_packet)(...)://自定义的读取函数回调。
(*write_packet)(...)://自定义的写入函数回调。
(*read_pause)(...)://网络流媒体协议的暂停或恢复播放函数指针

3.2 URLContext

用于抽象和管理底层的 I/O 操作。它为各种协议(如文件系统、网络协议等)提供了统一的访问接口。

URLContextAVIOContext 的底层实现之一。通过 URLContext,FFmpeg 可以对文件、网络流、管道等不同类型的数据源或目标进行操作,而用户通常通过更高级别的 AVIOContext 接口与之交互。

  • url_open

    c++ 复制代码
    int url_open(URLContext **puc, const char *filename, int flags)
    • 打开一个 URL 或文件。
c++ 复制代码
char* name://协议名称
const struct URLProtocol *prot://协议操作对象(ff_file_protocol、ff_librtmp_protocol...)
void *priv_data://协议对象(FileContext、LibRTMPContext)

3.3 URLProtocol

用于实现协议层抽象的结构体,负责定义如何与特定协议(如文件系统、HTTP、RTSP 等)交互。

4 AVStream

存储音频流或视频流的结构体

c++ 复制代码
//其它
int index://流的索引值,唯一标识容器中的每个流。
AVRational avg_frame_rate://平均帧率

//元数据相关
AVCodecParameters *codecpar://解码器参数,例如编码类型(音频、视频、字幕),采样率,分辨率等。
int64_t duration://流的持续时间
AVRational time_base://流的时间基,用于将时间戳转换为秒。

5 AVCodecParameter 和 AVCodecContext

  • 新的 ffmpeg 中AVStream.codecpar(struct AVCodecParameter)

    ​ 代替 AVStream.codec(struct AVCodecContext)

    ​ AVCodecParameter 是由 AVCodecContext 分离出来的,AVCodecParameter中没有函数

  • AVCodecContext 结构体仍然是编解码时不可或缺的结构体:avcodec_send_packet 和 avcodec_receive_frame 使用 AVCodecContext

5.1 AVCodecContext

用于表示编解码器的静态描述信息

5.2 AVCodecParameters

用于存储与媒体流(如音频、视频或字幕)相关的编码参数。ffmpeg3.1引入,用来分离编解码器的参数信息与解码器/编码器的具体实现。

6 AVCodec

表示编解码器的静态描述信息,每一个解码器对应一个AVCodec结构体

1. 查找编解码器
  • 使用 avcodec_find_decoder()avcodec_find_encoder(),通过 AVCodec 获取解码器或编码器。
2. 编解码器初始化
  • AVCodecContext 中,通过关联 AVCodec 来完成初始化。
c++ 复制代码
const char *name://编解码器短名字(形如:"h264")
    
const char *long_name://编解码器全称(形如:"H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10")
    
enum AVMediaType type://媒体类型:视频、音频或字母
    
enum AVCodecID id://标示特定的编码器
    
const AVRational *supported_framerates://支持的帧率(仅视频)
    
const enum AVPixelFormat *pix_fmts://支持的像素格式(仅视频)
    
const int *supported_samplerates://支持的采样率(仅音频)
    
const enum AVSampleFormat *sample_fmts://支持的采样格式(仅音频)
    
const uint64_t *channel_layouts://支持的声道数(仅音频)

7 AVPacket

存储压缩编码数据相关信息的结构体;

例如 从解复用器(av_read_frame)读取压缩数据包。

​ 将数据包发送到解码器(avcodec_send_packet)。

​ 解码器将解码后的帧输出为 AVFrame

c++ 复制代码
AVBufferRef *buf://管理data指向的数据
uint8_t *data:	//压缩编码的数据
int size:		//data的大小
int64_t pts:	//显示时间戳
int64_t dts:	//解码时间戳
int stream_index://标识该AVPacket所属的视频/音频流

8 AVFrame

用于存储原始数据(即非压缩数据,例如对视频来说是 YUV,RGB,对音频来说是 PCM),此外还包含了一些相关的信息。

1. 初始化和分配
  • av_frame_alloc()
    分配一个新的 AVFrame
2. 释放资源
  • av_frame_unref(AVFrame *frame)
    释放帧数据,清空 AVFrame 的内容。
  • av_frame_free(AVFrame **frame)
    释放 AVFrame 的内存。
3. 数据管理
  • av_frame_get_buffer(AVFrame *frame, int align)
    AVFrame 分配缓冲区。
  • av_frame_make_writable(AVFrame *frame)
    确保 AVFrame 可写,如果当前数据不可写,会分配新的缓冲区。
c++ 复制代码
uint8_t *data[AV_NUM_DATA_POINTERS]://解码后原始数据(对视频来说是YUV,RGB,对音频来说是PCM)
    
int linesize[AV_NUM_DATA_POINTERS]://data中"一行"数据的大小。注意:未必等于图像的宽,一般大于图像的宽。
    
int width, height://视频帧宽和高(1920x1080,1280x720...)
    
int nb_samples://音频的一个AVFrame中可能包含多个音频帧,在此标记包含了几个
    
int format://解码后原始数据类型(YUV420,YUV422,RGB24...)
    
int key_frame://是否是关键帧
    
enum AVPictureType pict_type://帧类型(I,B,P...)
    
AVRational sample_aspect_ratio://图像宽高比(16:9,4:3...)
    
int64_t pts://显示时间戳
    
int coded_picture_number://编码帧序号
    
int display_picture_number://显示帧序号
相关推荐
Liveweb视频汇聚平台1 小时前
FFmpeg来从HTTP拉取流并实时推流到RTMP服务器
服务器·http·ffmpeg
Say-hai10 小时前
FFmpeg 的常用API
ffmpeg
Say-hai15 小时前
FFMPEG解码+SDL2播放视频
ffmpeg·音视频
runing_an_min17 小时前
ffmpeg: stream_loop报错 Error while filtering: Operation not permitted
ffmpeg·permitted
Liveweb视频汇聚平台1 天前
FFmpeg推拉流命令
ffmpeg
cuijiecheng20181 天前
音视频入门基础:MPEG2-TS专题(22)——FFmpeg源码中,获取TS流的音频信息的实现
ffmpeg·音视频
叶余2 天前
FFmpeg命令行选项
ffmpeg
从后端到QT2 天前
音视频采集推流时间戳记录方案
ffmpeg·音视频
悠着,大嘟嘟2 天前
FFmpeg音频解码详解
ffmpeg·音视频