当前位置: 首页 > article >正文

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 结构

image-20241226110723488

1 AVFormatContext

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

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

  • avformat_open_input()

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

    • 创建一个新的输出 AVFormatContext

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

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

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

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

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

//基本信息成员
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

    • AVInputFormat *av_find_input_format(const char *short_name);
      
    • 根据指定的格式名称查找\打开 AVInputFormat

  • avformat_find_stream_info

    • int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
      
    • 函数内部会根据输入格式(通过 AVInputFormat)对媒体文件进行处理,提取其中的流信息。

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 操作
//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

    • int url_open(URLContext **puc, const char *filename, int flags)
      
    • 打开一个 URL 或文件。

char* name://协议名称
const struct URLProtocol *prot://协议操作对象(ff_file_protocol、ff_librtmp_protocol...)
void *priv_data://协议对象(FileContext、LibRTMPContext)

3.3 URLProtocol

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

4 AVStream

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

//其它
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 来完成初始化。
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

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 可写,如果当前数据不可写,会分配新的缓冲区。
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://显示帧序号

http://www.kler.cn/a/453434.html

相关文章:

  • LangChain教程 - 表达式语言 (LCEL) -构建智能链
  • 蓝牙BLE开发——解决iOS设备获取MAC方式
  • 大模型应用技术系列(三): 深入理解大模型应用中的Cache:GPTCache
  • DP动态规划+贪心题目汇总
  • WSL2上Ubuntu22.04安装Docker
  • NPM老是无法install,timeout?npm install失败
  • Linux高并发服务器开发 第六天(rwx 对于目录和文件的区别 gcc编译器 动态库静态库)
  • yolov4算法及其改进
  • C#异步1
  • 蚂蚁集团 CTO 线大规模调整、多个 AI 业务部门被合并
  • 工业大数据分析算法实战-day16
  • 天池工业蒸汽量预测教程
  • FTT变换Matlab代码解释及应用场景
  • go window安装protoc protoc生成protobuf文件
  • vue关闭eslint校验及开启debugger
  • 【jenkins插件】
  • Java 集合使用注意事项总结
  • PYNQ2.7镜像直接升级成3.0以支持XCV(Xilinx Virtual Cable)
  • 代码随想录-笔记-其八
  • Jenkins 任意文件读取(CVE-2024-23897)修复及复现
  • 【Vue3学习】使用ref调用子组件的方法,实现子组件的显示与隐藏
  • HarmonyOS NEXT 实战之元服务:静态案例效果---歌单推荐
  • 如何在 Linux 上使用 Rsync 同步本地和远程目录
  • 机器学习之pandas
  • 多功能jquery图片预览放大镜插件
  • 【C++动态规划】1105. 填充书架|2104