189 8069 5689

FFmpegavformat_open_input函数剖析以及问题-创新互联

函数调用逻辑
avformat_open_input
       init_input
            av_probe_input_buffer2
                av_probe_input_format3
                      read_header

创新互联建站坚信:善待客户,将会成为终身客户。我们能坚持多年,是因为我们一直可值得信赖。我们从不忽悠初访客户,我们用心做好本职工作,不忘初心,方得始终。10年网站建设经验创新互联建站是成都老牌网站营销服务商,为您提供成都网站设计、网站制作、网站设计、H5网站设计、网站制作、品牌网站制作成都微信小程序服务,给众多知名企业提供过好品质的建站服务。

简介
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

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章名称:FFmpegavformat_open_input函数剖析以及问题-创新互联
标题链接:http://jkwzsj.com/article/djgiic.html

其他资讯