文章目录
- 一、FFmpeg 封装 / 解封装 相关结构体
- 1、封装 / 解封装 概念
- 2、封装 / 解封装 相关结构体
- 3、AVFormatContext 与 AVInputFormat / AVOutputFormat 之间的关系
- 二、FFmpeg 编码 / 解码 相关结构体
- 1、编码 / 解码 相关结构体
- 2、AVCodecContext 和 AVCodec 之间的关系
- 三、AVFormatContext / AVStream / AVCodecContext 之间的关系
- 1、AVFormatContext 与 AVStream 之间的关系
- 2、AVStream 中的 AVCodecParameters 字段
- 3、AVStream 与 AVCodecContext 之间的关系
FFmpeg 4.0 版本源码地址 :
- GitHub : https://github.com/FFmpeg/FFmpeg/tree/release/4.0
- GitCode : https://gitcode.com/gh_mirrors/ff/FFmpeg/tree/release/4.0
FFmpeg 是一个强大的多媒体处理工具 , 其核心功能包括 封装 / 解封装 和 编码 / 解码 ;
这两组 核心功能 分别对应 两组 重要 数据结构
一、FFmpeg 封装 / 解封装 相关结构体
1、封装 / 解封装 概念
封装 / 解封装 概念 :
- 封装 指的是 将 编码压缩后的 音视频数据包 放入 多媒体文件容器中
- 解封装 指的是 从 多媒体文件容器 中 , 取出 编码压缩后的 音视频数据包 ;
2、封装 / 解封装 相关结构体
封装 / 解封装 对应的 结构体如下 :
- AVFormatContext : 这是 封装 和 解封装 操作的主要数据结构 , 该结构体中 包含了多媒体文件的通用信息 ( 文件的比特率、时长、流的数量 ) , 以及 每个媒体流 ( AVStream 结构体 ) 的详细描述 ;
- 封装过程 , AVFormatContext 提供 文件或流 的 写入功能;
- 解封装过程 , AVFormatContext 提供了 文件或流 的 读取功能
- AVInputFormat : 该结构体 定义了 输入格式 , 用于处理 特定文件格式 的 解封装 操作 , 包含了 打开 和 读取 多媒体文件所需的各种 函数和属性 ;
- AVOutputFormat : 该结构体 定义了 输出格式 , 用于处理 特定文件格式 的 封装 操作 ;
- AVStream : 描述 一个 多媒体流 , 如 : 音频流 , 视频流 , 字幕流 , 包含 每个流的编码参数、时间基准等信息 ;
3、AVFormatContext 与 AVInputFormat / AVOutputFormat 之间的关系
上述结构体更详细的介绍 , 可参考 【FFmpeg】FFmpeg 播放器框架 ① ( “ 解封装 - 解码 - 播放 过程 “ 涉及到的函数和结构体 | AVFormatContext 结构体详解 ) 博客 ,
AVFormatContext 结构体 与 AVInputFormat / AVOutputFormat 结构体 之间的关系 :
- AVFormatContext 结构体 中 定义的是 封装 / 解封装 过程中 需要使用到的 数据 ;
- AVInputFormat / AVOutputFormat 结构体 中 定义的是 封装 / 解封装 过程中 执行的 方法 ;
显然 , FFmpeg 虽然是 C 语言程序 , 但是在程序设计时 , 使用到了 面向对象 的设计思想 ;
在 AVFormatContext 结构体 中 , 定义了 AVInputFormat 和 AVOutputFormat 结构体成员 ;
typedef struct AVFormatContext {
/**
* 输入容器格式。
*
* 仅用于解复用,由 avformat_open_input() 设置。
*/
ff_const59 struct AVInputFormat *iformat;
/**
* 输出容器格式。
*
* 仅用于复用,调用者必须在 avformat_write_header() 之前设置。
*/
ff_const59 struct AVOutputFormat *oformat;
}
二、FFmpeg 编码 / 解码 相关结构体
1、编码 / 解码 相关结构体
编码 和 解码 指的是 对多媒体数据 进行 压缩 和 解压缩
- AVCodecContext : 这是用于 编码 和 解码 的 主要上下文结构体 , 该结构体中包含了 特定 编码器 或 解码器 所需的配置参数 , 如 : 比特率、帧率、采样率、编码格式等 ;
- 编解码过程中 AVCodecContext 结构体 负责管理数据缓冲区 , 执行编码 / 解码操作 ;
- 编码时 , 它 将 原始数据 压缩 成编码格式 ;
- 解码时 , 则 将 压缩数据 恢复 成原始格式 ;
- AVCodec : 该结构体 表示 编码器 和 解码器 的具体实现 , 每种编码方式 ( 如 : H.264 视频 编码器 / 解码器 或 AAC 音频 编码器 / 解码器 ) 都 对应一个 AVCodec 实例
- AVPacket : 表示一个编码的数据包 , 用于 存储 压缩后的音视频数据
- AVFrame : 表示一个解码后的帧 , 用于 存储 未压缩的原始音视频数据
2、AVCodecContext 和 AVCodec 之间的关系
AVCodecContext 结构体 和 AVCodec 结构体 之间的关系 :
- AVCodecContext 是 编码器上下文结构体 , 用于 存储 编解码过程中 使用到的 数据 ;
- AVCodec 结构体 对应 具体的 编解码器 , 如 : H.264 编码器 或 解码器 , 其中 封装了 编解码 过程需要的 方法 ;
在 AVCodecContext 编解码上下文 结构体中 , 封装了 AVCodec 编解码器 结构体 的引用 ;
typedef struct AVCodecContext {
const AVClass *av_class; // FFmpeg的类对象,用于日志和选项处理
const struct AVCodec *codec; // 编码器或解码器
}
三、AVFormatContext / AVStream / AVCodecContext 之间的关系
1、AVFormatContext 与 AVStream 之间的关系
AVFormatContext 与 AVStream 之间的关系 :
使用 FFmpeg 时 , 第一件事就是 调用 avcodec_open2 函数 打开一个 多媒体文件 或 多媒体流 , 得到 AVFormatContext 结构体 ;
AVFormatContext 结构体 中 封装了 该 多媒体文件 或 多媒体流 中 AVStream 媒体流 的 个数 和 种类 , 在 AVFormatContext 结构体中封装了一个 AVStream 数组
2、AVStream 中的 AVCodecParameters 字段
调用 avformat_find_stream_info 函数 , 可以获取 AVStream 多媒体流 的 编解码器 的参数情况 ;
该函数可以从 文件 或 数据流 中读取并分析流的基本信息 , 如 : 分辨率、编码格式、采样率等 , 读取的信息存储在 AVFormatContext 结构体 的 streams 数组成员 中 ;
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
在 AVStream 流中 , 包含了一个 AVCodecParameters *codecpar;
参数字段 , 该字段用于存储 该流的 编码参数 , 包含 分辨率、比特率、编码格式等信息 ;
typedef struct AVStream {
int index; // 流在文件中的索引位置
int id; // 流的唯一标识
AVCodecParameters *codecpar; // 编解码参数 (包含分辨率、采样率等信息)
}
3、AVStream 与 AVCodecContext 之间的关系
AVStream 与 AVCodecContext 之间的关系 :
调用 avcodec_parameters_to_context 函数 , 可以将 AVStream 中的 AVCodecParameters 字段中的 编解码器参数 复制到 AVCodecContext 中 , 以便 AVCodecContext 拥有 正确的参数 来进行 解码 或 编码 操作 ;