概述
AVCodecParameters是 FFmpeg 库中用于描述编解码器参数的结构体,在 FFmpeg 3.0+ 版本中引入,用于替代部分 AVCodecContext 的功能,使得参数传递更加清晰和模块化。
主要用途
-
描述音视频流的编解码属性
-
在解复用(demuxing)和复用(muxing)过程中传递编解码信息
-
独立于编解码器上下文(AVCodecContext)存储参数
核心成员详解
基本参数
enum AVMediaType codec_type; // 媒体类型
enum AVCodecID codec_id; // 编解码器ID
uint32_t codec_tag; // 编解码器标签(四字符码)
格式参数
int format; // 格式(像素格式/采样格式)
int64_t bit_rate; // 比特率(bits/s)
视频相关参数
int width; // 图像宽度
int height; // 图像高度
AVRational sample_aspect_ratio; // 像素宽高比
int field_order; // 场序
int color_range; // 色彩范围
int color_primaries; // 颜色原色
int color_trc; // 传输特性
int color_space; // 色彩空间
int chroma_location; // 色度位置
音频相关参数
int sample_rate; // 采样率(Hz)
int channels; // 声道数
uint64_t channel_layout; // 声道布局
int frame_size; // 每帧采样数
额外数据
uint8_t *extradata; // 编解码器私有数据
int extradata_size; // 私有数据大小
其他参数
int level; // 编解码器级别
int profile; // 编解码器档次
int video_delay; // 视频延迟
使用示例
获取流参数
AVFormatContext *fmt_ctx = NULL;
avformat_open_input(&fmt_ctx, filename, NULL, NULL);
// 从AVStream中获取编解码参数
AVCodecParameters *codecpar = fmt_ctx->streams[stream_index]->codecpar;
// 读取具体参数
printf("Codec ID: %d\n", codecpar->codec_id);
printf("Video size: %dx%d\n", codecpar->width, codecpar->height);
printf("Bitrate: %lld\n", codecpar->bit_rate);
创建解码器上下文
// 查找解码器
const AVCodec *codec = avcodec_find_decoder(codecpar->codec_id);
// 创建解码器上下文
AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
// 将参数复制到解码器上下文
avcodec_parameters_to_context(codec_ctx, codecpar);
// 打开解码器
avcodec_open2(codec_ctx, codec, NULL);
复制参数
AVCodecParameters *dst_params = avcodec_parameters_alloc();
avcodec_parameters_copy(dst_params, src_params);
与 AVCodecContext 的关系
| 特性 | AVCodecParameters | AVCodecContext |
|---|---|---|
| 用途 | 存储编解码器静态参数 | 编解码器运行时上下文 |
| 内存管理 | 通常由AVStream管理 | 需要手动分配/释放 |
| 线程安全 | 只读,线程安全 | 非线程安全 |
| 包含内容 | 编解码器描述信息 | 编解码器状态和控制信息 |
| 版本 | FFmpeg 3.0+ | 所有版本 |
重要函数
参数管理
// 分配参数结构体
AVCodecParameters *avcodec_parameters_alloc(void);
// 释放参数结构体
void avcodec_parameters_free(AVCodecParameters **ppar);
// 复制参数
int avcodec_parameters_copy(AVCodecParameters *dst,
const AVCodecParameters *src);
// 从上下文获取参数
int avcodec_parameters_from_context(AVCodecParameters *par,
const AVCodecContext *codec);
// 将参数应用到上下文
int avcodec_parameters_to_context(AVCodecContext *codec,
const AVCodecParameters *par);
实际应用场景
1. 流信息分析
void print_stream_info(AVFormatContext *fmt_ctx) {
for (int i = 0; i < fmt_ctx->nb_streams; i++) {
AVCodecParameters *par = fmt_ctx->streams[i]->codecpar;
printf("Stream #%d:\n", i);
printf(" Type: %s\n", av_get_media_type_string(par->codec_type));
printf(" Codec: %s\n", avcodec_get_name(par->codec_id));
if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
printf(" Resolution: %dx%d\n", par->width, par->height);
} else if (par->codec_type == AVMEDIA_TYPE_AUDIO) {
printf(" Sample Rate: %d Hz\n", par->sample_rate);
printf(" Channels: %d\n", par->channels);
}
}
}
2. 转码参数设置
// 设置输出流参数
AVCodecParameters *out_par = out_stream->codecpar;
avcodec_parameters_copy(out_par, in_stream->codecpar);
// 修改特定参数
out_par->bit_rate = 2000000; // 设置目标码率
注意事项
-
内存管理 :
AVCodecParameters通常由AVStream管理,不需要手动分配/释放 -
线程安全 :
AVCodecParameters是只读结构,可以在多线程环境中安全访问 -
生命周期:参数在流生命周期内保持不变
-
与AVCodecContext配合 :在编解码过程中,需要将参数复制到
AVCodecContext中使用
常见问题
1. 参数复制失败
// 确保目标参数已分配
if (!dst_par) {
dst_par = avcodec_parameters_alloc();
}
int ret = avcodec_parameters_copy(dst_par, src_par);
if (ret < 0) {
// 错误处理
}
2. 新旧API兼容
// FFmpeg 2.x
AVCodecContext *codec_ctx = stream->codec;
// FFmpeg 3.x+
AVCodecParameters *par = stream->codecpar;
总结
AVCodecParameters是 FFmpeg 中重要的编解码器参数描述结构体,它分离了编解码器的静态参数 和运行时状态 ,使得代码更加清晰和模块化。在现代 FFmpeg 编程中,应优先使用 AVCodecParameters来处理编解码器描述信息,而将 AVCodecContext用于编解码过程的控制。