千家信息网

FFmpeg avformat_open_input函数剖析以及问题

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,函数调用逻辑avformat_open_inputinit_inputav_probe_input_buffer2av_probe_input_format3read_header简介avformat
千家信息网最后更新 2026年10月31日FFmpeg avformat_open_input函数剖析以及问题

函数调用逻辑
avformat_open_input
init_input
av_probe_input_buffer2
av_probe_input_format3
read_header


简介
avformat_open_input函数初始化AVFormatContext结构体。其中在初始化AVIOContext结构体参数中调用init_input函数,而它会默认调用av_probe_input_buffer2填充AVIOContext结构体参数。一般情况下,可以优先调用av_probe_input_buffer函数,填充AVIOContext结构体参数,然后赋值给AVFormatContext结构体中的AVIOContext字段
代码
AVIOContext pIOContext= avio_alloc_context
AVInputFormat pInputFormat = NULL
av_probe_input_buffer(pIOContext, &pInputFormat, "", NULL, 0, 0)
AVFormatContext* pFormatContext = avformat_alloc_context();
pFormatContext->pb = pIOContext;
if (avformat_open_input(&FormatContext, "", pInputFormat, NULL) < 0)
根据av_probe_input_buffer会调用av_probe_input_buffer2,包裹了一层
简化代码如下
AVFormatContext* pFormatContext = avformat_alloc_context();
if (avformat_open_input(&FormatContext, "", pInputFormat, NULL) < 0)
根据实际的测试,关键的地方是AVIOContext的初始化,该结构体将会保存一个读取网络数据的函数入口,根据函数入口来分析数据流。avformat_open_input函数在目前的
测试结果是耗时1秒多,这个应该是一个优化的方向
av_probe_input_buffer2主要是针对输入输出结构体AVIOContext的初始化,如果知道avformat_open_input的赋值内容,对各种协议的读写格式的探测,就可以优化这一块代码。协议的探测分别有file协议,rtmp协议等等,目前在项目中只需要实现文件协议,而文件协议应该如何进行读写?
调用ffio_fdopen()函数创建AVIOContext()结构体并获取URLContext结构体引用的资源(调用avio_alloc_context()实现)


问题
avformat_open_input函数探测ES流开销是150毫秒,探测PS流开销是500毫秒。avformat_open_input函数里面已经实现了av_probe_input_buffer函数的调用,去探测AVInputFormat结构体的相关变量。所以在avformat_open_input函数之前,调用av_probe_input_buffer函数之后,就不会去探测AVInputFormat结构体

优化方向
尝试屏蔽avformat_open_input函数,直接指定码流的输入格式pInputFormat,代码如下:
pInputFormat = av_find_input_format("h364");
pFormatCtx->iformat = pInputFormat;
如果这个时候屏蔽掉avformat_open_input,图像是条带状的,按照参考文献的说法,该avformat_open_input
函数就是为了探测AVInputFormat结构体的相关变量

最终优化方案
没有屏蔽avformat_open_input函数,而是在调用之前指定AVInputFormat的码流输入格式
代码
AVInputFormat* pInputFormat = NULL;
AVFormatContext* pFormatContext = NULL;
pFormatContext = avformat_alloc_context();
pInputFormat = av_find_input_format("h364");
if (avformat_open_input(&pFormatContext, "", InputFormat, NULL) < 0)
{
av_free(...);
avformat_free_context(...);
fprintf(stdout, "open stream failed!\n");
}
else
{
fprintf(stdout, "open stream success!\n");
}


笔记
m_pVideoc->io_ctx = avio_alloc_context(m_pAvioBuf, BUF_SIZE, 0, this, ReadStreamData, NULL, NULL);
if (avformat_open_input(&pFormatCtx, "", piFmt, NULL) < 0)
上面的ReadStreamData实际的用途是在下面打开实时流的时候,如果需要读取数据,可以通过ReadStreamData函数获取到帧的消息内容
而不用通过avformat_open_input函数的第二个参数传递url

参考
http://blog.csdn.net/leo2007608/article/details/53421528
http://blog.csdn.net/leixiaohua1020/article/details/39759163
http://blog.csdn.net/leixiaohua1020/article/details/44064715


函数 结构 探测 代码 参数 数据 格式 输入 入口 内容 变量 实际 开销 文件 方向 时候 参考 测试 问题 不用 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 花魁咖啡 天津市摩尔互联网科技 互联网科技开发公司 互联网科技公司官网 远拓互联网科技 银优互联网科技有限公司 互联网科技股午盘股票涨跌 蓝色互联网科技 宁波青枫互联网科技有限公司 阿里互联网科技公司 广州恒生互联网科技有限 互联网为啥属于高科技 乌鲁木齐新华智原互联网科技学校 黑云互联网科技有限公司 宇信科技在杭州互联网排第几 上海乐五互联网科技有限公司 美国五大互联网科技公司市值多少 互联网科技品牌 互联网金融金融科技 山东亿川互联网科技有限责任公司 科技互联网公司装修 青岛互联网科技公司 互联网科技公司介绍 青岛中康互联网医疗科技有限公司 互联网科技博主是什么意思 中和天地互联网科技有限公司 济南小医互联网科技有限公司招聘 广西科技产业互联网是什么 安徽零酒互联网科技有限公司 颐高云石互联网科技
0