FFmpeg API 数据结构及其详细说明:

1. AVCodec

c 复制代码
typedef struct AVCodec {
    const char *name;           // 编解码器名称(如 "aac", "libfdk_aac")
    const char *long_name;      // 完整描述名称
    enum AVMediaType type;      // 媒体类型(AVMEDIA_TYPE_AUDIO/VIDEO等)
    enum AVCodecID id;          // 编解码器ID(AV_CODEC_ID_AAC等)
    
    // 支持的采样格式列表(以AV_SAMPLE_FMT_NONE结尾)
    const enum AVSampleFormat *sample_fmts;
    
    // 支持的采样率列表(以0结尾)
    const int *supported_samplerates;
    
    // 支持的声道布局列表(以0结尾,新版FFmpeg已废弃)
    const uint64_t *channel_layouts;
    
    // 支持的像素格式(视频编解码器使用)
    const enum AVPixelFormat *pix_fmts;
    
    // 编解码器能力标志
    int capabilities;
} AVCodec;

2. AVCodecContext

c 复制代码
typedef struct AVCodecContext {
    // 基本信息
    enum AVMediaType codec_type;    // 媒体类型
    const struct AVCodec *codec;    // 关联的编解码器
    enum AVCodecID codec_id;        // 编解码器ID
    
    // 音频相关参数
    int bit_rate;                   // 比特率(bits/sec)
    int sample_rate;                // 采样率(Hz)
    enum AVSampleFormat sample_fmt; // 采样格式(AV_SAMPLE_FMT_S16/FLTP等)
    int frame_size;                 // 每帧采样点数(单个通道)
    
    // 新版本:声道布局(替代channel_layout和channels)
    AVChannelLayout ch_layout;      // 声道布局结构
    
    // 旧版本(已废弃,但兼容性保留):
    // uint64_t channel_layout;     // 声道布局(位掩码)
    // int channels;                // 通道数
    
    // 编解码器特定参数
    int profile;                    // 编码配置文件(如FF_PROFILE_AAC_LOW)
    int level;                      // 编码级别
    
    // 标志位
    int flags;                      // 编解码器标志
                                    // AV_CODEC_FLAG_GLOBAL_HEADER: 全局头信息
    
    // 时间相关
    AVRational time_base;           // 时间基(用于PTS/DTS计算)
    
    // 私有数据
    void *priv_data;                // 编解码器私有数据
} AVCodecContext;

3. AVFrame

c 复制代码
typedef struct AVFrame {
    // 数据平面
    uint8_t *data[AV_NUM_DATA_POINTERS];    // 数据指针数组
    int linesize[AV_NUM_DATA_POINTERS];     // 每行字节数
    
    // 音频相关
    int nb_samples;                    // 本帧中的采样点数(单个通道)
    enum AVSampleFormat format;        // 采样格式
    int sample_rate;                   // 采样率
    
    // 新版本:声道布局
    AVChannelLayout ch_layout;         // 声道布局结构
    
    // 时间戳
    int64_t pts;                       // 显示时间戳(以time_base为单位)
    int64_t pkt_dts;                   // 解码时间戳
    
    // 质量指标
    int quality;                       // 质量值(编码器使用)
    
    // 引用计数
    int width, height;                 // 图像尺寸(视频用)
    int key_frame;                     // 是否为关键帧(视频用)
    enum AVPictureType pict_type;      // 图像类型(视频用)
    
    // 扩展数据
    AVDictionary *metadata;            // 元数据
} AVFrame;

4. AVPacket

c 复制代码
typedef struct AVPacket {
    // 数据缓冲区
    uint8_t *data;                     // 压缩数据
    int size;                          // 数据大小
    
    // 时间信息
    int64_t pts;                       // 显示时间戳
    int64_t dts;                       // 解码时间戳
    int64_t duration;                  // 数据持续时间
    AVRational time_base;              // 时间基
    
    // 流索引
    int stream_index;                  // 所属流的索引
    
    // 标志位
    int flags;                         // 包标志
                                        // AV_PKT_FLAG_KEY: 关键帧
    
    // 编解码器私有数据
    void *opaque;                      // 私有数据指针
    void *opaque_ref;                  // 引用计数私有数据
    
    // 缓冲区管理
    AVBufferRef *buf;                  // 缓冲区引用(引用计数管理)
    
    // 扩展数据
    AVDictionary *metadata;            // 元数据
} AVPacket;

5. AVChannelLayout(新版本FFmpeg,≥5.0)

c 复制代码
typedef struct AVChannelLayout {
    // 布局类型
    enum AVChannelOrder order;         // 声道顺序类型:
                                        // AV_CHANNEL_ORDER_UNSPEC: 未指定
                                        // AV_CHANNEL_ORDER_NATIVE: 原生顺序
                                        // AV_CHANNEL_ORDER_CUSTOM: 自定义
    
    // 声道数量
    int nb_channels;                   // 声道数
    
    union {
        // 当order == AV_CHANNEL_ORDER_NATIVE时使用
        uint64_t mask;                 // 声道掩码(兼容旧API)
        
        // 当order == AV_CHANNEL_ORDER_CUSTOM时使用
        struct {
            AVChannelCustom *map;      // 自定义声道映射
            int nb_channels;           // 声道数
        } custom;
    } u;
    
    // 布局名称
    char *name;                        // 布局描述名称
} AVChannelLayout;

6. AVDictionary(选项字典)

c 复制代码
typedef struct AVDictionaryEntry {
    char *key;                         // 键名
    char *value;                       // 键值
} AVDictionaryEntry;

typedef struct AVDictionary AVDictionary;  // 不透明结构

7. 重要枚举类型

AVSampleFormat(采样格式)

c 复制代码
enum AVSampleFormat {
    AV_SAMPLE_FMT_NONE = -1,
    AV_SAMPLE_FMT_U8,          ///< 无符号8位整数
    AV_SAMPLE_FMT_S16,         ///< 有符号16位整数(常用)
    AV_SAMPLE_FMT_S32,         ///< 有符号32位整数
    AV_SAMPLE_FMT_FLT,         ///< 单精度浮点数(packed)
    AV_SAMPLE_FMT_DBL,         ///< 双精度浮点数
    
    AV_SAMPLE_FMT_U8P,         ///< 无符号8位整数(planar)
    AV_SAMPLE_FMT_S16P,        ///< 有符号16位整数(planar)
    AV_SAMPLE_FMT_S32P,        ///< 有符号32位整数(planar)
    AV_SAMPLE_FMT_FLTP,        ///< 单精度浮点数(planar,AAC编码器常用)
    AV_SAMPLE_FMT_DBLP,        ///< 双精度浮点数(planar)
    
    AV_SAMPLE_FMT_NB           ///< 格式数量
};

AVMediaType(媒体类型)

c 复制代码
enum AVMediaType {
    AVMEDIA_TYPE_UNKNOWN = -1,  ///< 未知类型
    AVMEDIA_TYPE_VIDEO,         ///< 视频
    AVMEDIA_TYPE_AUDIO,         ///< 音频
    AVMEDIA_TYPE_DATA,          ///< 数据
    AVMEDIA_TYPE_SUBTITLE,      ///< 字幕
    AVMEDIA_TYPE_ATTACHMENT,    ///< 附件
    AVMEDIA_TYPE_NB             ///< 类型数量
};

AVCodecID(编解码器ID)

c 复制代码
enum AVCodecID {
    AV_CODEC_ID_NONE,
    // 音频编解码器
    AV_CODEC_ID_MP2,
    AV_CODEC_ID_MP3,
    AV_CODEC_ID_AAC,
    AV_CODEC_ID_AC3,
    AV_CODEC_ID_DTS,
    AV_CODEC_ID_VORBIS,
    AV_CODEC_ID_OPUS,
    AV_CODEC_ID_FLAC,
    // 视频编解码器...
};

8. 关键API函数

编解码器相关

c 复制代码
// 查找编解码器
const AVCodec *avcodec_find_encoder(enum AVCodecID id);
const AVCodec *avcodec_find_encoder_by_name(const char *name);

// 分配编解码器上下文
AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);

// 打开编解码器
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);

// 发送帧到编码器
int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame);

// 从编码器接收包
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt);

// 释放资源
void avcodec_free_context(AVCodecContext **avctx);

帧和包管理

c 复制代码
// 分配帧
AVFrame *av_frame_alloc(void);

// 分配包
AVPacket *av_packet_alloc(void);

// 为帧分配数据缓冲区
int av_frame_get_buffer(AVFrame *frame, int align);

// 确保帧可写
int av_frame_make_writable(AVFrame *frame);

// 填充音频样本数组
int av_samples_fill_arrays(uint8_t **audio_data, int *linesize,
                           const uint8_t *buf, int nb_channels,
                           int nb_samples, enum AVSampleFormat sample_fmt,
                           int align);

// 释放帧
void av_frame_free(AVFrame **frame);

// 释放包
void av_packet_free(AVPacket **pkt);

// 取消包的引用
void av_packet_unref(AVPacket *pkt);

声道布局相关(新API)

c 复制代码
// 初始化默认声道布局
int av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels);

// 复制声道布局
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src);

// 获取声道布局描述
int av_channel_layout_describe(const AVChannelLayout *ch_layout,
                               char *buf, size_t buf_size);

// 释放声道布局资源
void av_channel_layout_uninit(AVChannelLayout *ch_layout);

// 获取声道数
int av_get_channel_layout_nb_channels(uint64_t channel_layout);  // 旧API

采样格式相关

c 复制代码
// 获取采样格式名称
const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt);

// 获取采样格式的字节数
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt);

// 检查采样格式是否为planar
int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt);

9. 数据结构关系图

复制代码
AVCodec
    ↓ (avcodec_find_encoder)
    ↓
AVCodecContext  ←─ 编码参数配置
    ↓ (avcodec_open2)
    ↓
AVFrame         ←─ 原始音频数据
    ↓ (avcodec_send_frame)
    ↓
编码器内部处理
    ↓
AVPacket        ←─ 编码后数据
    ↓ (avcodec_receive_packet)
    ↓
输出文件/网络

10. 内存管理原则

  1. 分配与释放配对

    • avcodec_alloc_context3()avcodec_free_context()
    • av_frame_alloc()av_frame_free()
    • av_packet_alloc()av_packet_free()
  2. 引用计数

    • AVPacket 使用 buf 字段管理引用计数
    • 调用 av_packet_unref() 减少引用计数
  3. 深度复制

    • 使用 av_packet_ref() 复制数据
    • 使用 av_frame_ref() 复制帧数据
  4. RAII原则(C++中):

    • 使用智能指针包装FFmpeg资源
    • 在析构函数中自动释放资源

11. 常见问题与解决方案

采样格式不匹配

c 复制代码
// AAC编码器通常需要FLTP格式
if (strcmp(codec->name, "aac") == 0) {
    ctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
}
// libfdk_aac通常需要S16格式
else if (strcmp(codec->name, "libfdk_aac") == 0) {
    ctx->sample_fmt = AV_SAMPLE_FMT_S16;
}

声道布局兼容性

c 复制代码
// 新旧API兼容处理
#if LIBAVUTIL_VERSION_MAJOR >= 57
    // 使用AVChannelLayout
    AVChannelLayout layout = AV_CHANNEL_LAYOUT_STEREO;
    av_channel_layout_copy(&ctx->ch_layout, &layout);
#else
    // 使用旧API
    ctx->channel_layout = AV_CH_LAYOUT_STEREO;
    ctx->channels = 2;
#endif

全局头标志

c 复制代码
// 设置全局头标志
ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

// 编码AAC时,需要手动添加ADTS头
if (ctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
    // 添加ADTS头
    write_adts_header(ctx, packet);
}
相关推荐
Industio_触觉智能1 小时前
瑞芯微RK3568平台FFmpeg硬件编解码移植及性能测试实战攻略
ffmpeg·rk3588·rk3568·瑞芯微·rk3562·rk3576
AI视觉网奇1 小时前
视频选帧截取
python·opencv·音视频
Ayanami_Reii1 小时前
进阶数据结构-线段树
数据结构·算法·线段树
liu****1 小时前
11.字符函数和字符串函数(一)
linux·运维·c语言·开发语言·数据结构·算法
ZouZou老师1 小时前
视频编解码颜色空间:RGB与YUV全解析
音视频
!chen1 小时前
SQL Server 2025 新功能概览
数据结构
埃伊蟹黄面1 小时前
双指针算法
数据结构·c++·算法
Elias不吃糖1 小时前
Leetcode-10.正则表达式匹配(暴力 或 记忆暴力)
数据结构·c++·算法·leetcode·深度优先
小年糕是糕手2 小时前
【C++】类和对象(四) -- 取地址运算符重载、构造函数plus
c语言·开发语言·数据结构·c++·算法·leetcode·蓝桥杯