FFmpeg 基本API avformat_alloc_context 函数内部调用流程分析

1、avformat_alloc_context 函数定义

avformat_alloc_context 是 FFmpeg 库中的一个函数,用于分配并初始化一个 AVFormatContext 结构体的指针。在使用 FFmpeg 进行音视频处理时,通常需要先调用这个函数来创建一个 AVFormatContext 对象。

函数原型如下:

cpp 复制代码
AVFormatContext *avformat_alloc_context(void)
{
    // 1. 分配FFFormatContext结构体
    FFFormatContext *const si = av_mallocz(sizeof(*si));
    AVFormatContext *s;

    // 2. 初始化FFFormatContext结构体
    s = &si->pub;
    s->av_class = &av_format_context_class;
    
    // 3. 设置默认的io_open和io_close2函数
    s->io_open  = io_open_default;
    s->io_close2= io_close2_default;

    // 4. 设置默认的选项
    av_opt_set_defaults(s);
    // 5. 分配AVPacket结构体
    si->pkt = av_packet_alloc();
    si->parse_pkt = av_packet_alloc();
    return s;
}

在使用完 AVFormatContext 对象后,可以通过调用 void avformat_free_context(AVFormatContext *s) 函数来释放分配的内存。

2、avformat_alloc_context分配主要流程

avformat_alloc_context() 关键流程:

  • 分配 AVFormatContext
  • 初始化内部成员(AVIOContext 为 NULL)
  • 设置默认参数:start_time, duration, packet_size, probesize, max_analyze_duration 等
  • 分配 AVFormatInternal 并初始化子字段
  • 分配 AVStreamList 等辅助结构(部分版本在 open 时延后)

3、avformat_alloc_context与avformat_open_input() / avformat_free_context() 的关系

  • avformat_alloc_context():只分配并做最小初始化。
  • avformat_open_input(&ic, url, iformat, options):
    • 如果 *ic 为 NULL,avformat_open_input() 会内部调用 avformat_alloc_context() 来创建。
    • avformat_open_input() 会做真正的"打开和初始化":探测格式、分配 pb(如果必要)、分配 demuxer 私有数据(ic->priv_data / iformat->priv_data)、调用 read_header 回调并填充 streams 等。
    • 如果 avformat_open_input() 失败,它会清理分配的资源(包括释放 ic,除非你传入已分配的 ic 并指定了不同的行为------实现细节随版本)。因此常见用法是把 ic 初始化为 NULL,直接把 &ic 交给 avformat_open_input(),让它负责分配与回滚。
  • avformat_free_context(AVFormatContext *s):释放 AVFormatContext 和已分配资源(streams、metadata、pb 等),适用于你只调用了 avformat_alloc_context() 或你想手动释放。另外 avformat_close_input() 是更常用的对输入 context 的清理方式(它会调用 avformat_free_context() 并关闭 I/O)

4、avformat_alloc_context初始化参数列表

AVFormatContext的初始化列表参数定义在 libavformat\options_table.h avformat_options中,其中比较重要如下:

cpp 复制代码
{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT64, {.i64 = 5000000 }, 32, INT64_MAX, D},
{"formatprobesize", "number of bytes to probe file format", OFFSET(format_probesize), AV_OPT_TYPE_INT, {.i64 = PROBE_BUF_MAX}, 0, INT_MAX-1, D},

5、avformat_alloc_context分配主要时序图

相关推荐
汉克老师10 小时前
《从C++小白到算法高手:GESP 1—8级成长地图》第一讲:认识GESP——从编程新手到算法探索者
c++·gesp·信息学竞赛·小学生学c++
晴天的雨.99212 小时前
【C++】继承篇
java·开发语言·c++
青少儿编程课堂12 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会图形化考级:校园大富翁经营闯关解析
c++·python·算法·bfs·信息学竞赛
another heaven12 小时前
【C/C++ 第一次跨越(上):用 C++11/14 停止制造新的旧代码】
c语言·c++·制造
qq_4069810312 小时前
c++ lamda(三)Lambda表达式
java·前端·c++
zhanlang021712 小时前
HTML 零基础入门到企业实战【第五章 5.4】内嵌网页 iframe 标签:嵌入网页、视频、地图实战
前端·html·音视频
TengTaiTech12 小时前
头戴耳机做运动相机外接麦:一颗麦克风同时服务蓝牙通话与 3.5mm 录音的底层重构
数码相机·音视频·蓝牙·qcc
I_belong_to_jesus1 天前
C++关于分支预测的优化1
开发语言·c++·算法
Rabitebla1 天前
【Linux】进程控制(十二) 自定义 Shell(二):内建命令与进程工作目录管理
linux·c++·笔记·学习·bash
码客-ygluu1 天前
一个通用游戏数据服务器
c++·架构