FFMPEG结构体分析

FFMPEG结构体分析

附录:参考文献

1\] 结构体分析:https://www.cnblogs.com/linuxAndMcu/p/12041578.html#_label2 \[2\] [音视频入门系列](http://mp.weixin.qq.com/s?__biz=Mzg2MzA0NjM3Ng==&mid=2247483963&idx=6&sn=a2fb3dc7516d33a043f0eeb2acc46d92&chksm=ce7fddbcf90854aa4c0054e454346b7ff893adcc8205c053bcf94c5ad50da07477769f1d9cb3&scene=21#wechat_redirect) > 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 结构**。 ![image-20241226110723488](https://i-blog.csdnimg.cn/img_convert/c3294054fc650c4ed810b970f560feb6.png) ### 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 操作**。它为各种协议(如文件系统、网络协议等)提供了统一的访问接口。 > > `URLContext` 是 `AVIOContext` 的底层实现之一。通过 `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://显示帧序号 ```

相关推荐
l***77523 小时前
从MySQL5.7平滑升级到MySQL8.0的最佳实践分享
ffmpeg
ZouZou老师9 小时前
FFmpeg性能优化经典案例
性能优化·ffmpeg
aqi0012 小时前
FFmpeg开发笔记(九十)采用FFmpeg套壳的音视频转码百宝箱FFBox
ffmpeg·音视频·直播·流媒体
齐齐大魔王14 小时前
FFmpeg
ffmpeg
你好音视频15 小时前
FFmpeg RTSP拉流流程深度解析
ffmpeg
IFTICing1 天前
【环境配置】ffmpeg下载、安装、配置(Windows环境)
windows·ffmpeg
haiy20111 天前
FFmpeg 编译
ffmpeg
aqi001 天前
FFmpeg开发笔记(八十九)基于FFmpeg的直播视频录制工具StreamCap
ffmpeg·音视频·直播·流媒体
八月的雨季 最後的冰吻1 天前
FFmepg--28- 滤镜处理 YUV 视频帧:实现上下镜像效果
ffmpeg·音视频
ganqiuye1 天前
向ffmpeg官方源码仓库提交patch
大数据·ffmpeg·video-codec