FFMPEG函数之avformat_open_input

在进行输入和输出转码的过程中,会使用一个函数:

int avformat_open_input(AVFormatContext **ps, const char *filename,

                        AVInputFormat *fmt, AVDictionary **options)

其目的是打开流,并通过filename来初始化AVFormatContext中的AVIOContext *pb结构体数据。用来实现对数据进行读取(数据可能来源于file,memfifosocket)。到底是怎样的呢?下面我们来具体分析分析源码:

 

avformat_open_input

→avformat_alloc_context:AVFormatContext分配空间,并初始化。

→avformat_get_context_defaults:这个是里面比较重要的一个函数,设置的AVFormatContext默认参数,记住在这里已经初始化了AVFormatContext中的io_open()io_close()函数指针了,这儿很重要,因为后面在后面会用到这儿的函数。这个等我们后面用到的时候在分析。

→init_input:这儿很重要,打开文件并探测流的格式。在代码里面可以看到,如果已经初始化了AVIOContext *pb,这直接调用av_probe_input_buffer2来探测url的格式。否则会调用av_probe_input_format2进行源类型进行分析(主要是初始化AVIOContext *pb)。那我们来看看是如何来初始化pb的呢。

→av_probe_input_format2:

→av_probe_input_format3:在这里面会遍历注册的所以的demux解复用器,并通过demuxread_probe()函数来探测出流的格式。

下面我们来详细分析其过程:

If(fmt1->read_probe)如果解复用存在该函数,则使用该函数来分析。我们随意取一个demux看看,它是怎样来实现该read_probe的呢?以ff_rtsp_demuxer为例,rtsp_probe(av_strstart(p->filename, "rtsp:", NULL)))可以看出其仅仅使用url的头部进行匹配。如果匹配成功则返回maxsocore(100),这儿初始化了AVFormatContext中的AVInputFormat iformat参数; 接下来调用了s->io_open,看这儿应该可以想起当初初始化savformat_get_context_defaults函数,因为那里初始化了该函数指针。我们看看到底干了些什么呢?io_open实际调用过程如下:

io_open_default
{
      ffio_open_whitelist
      {
           ffurl_open_whitelist
           {
               ffurl_alloc
              {
                  url_find_protocol:
                  {
                       ffurl_get_protocols 
                       {
                               返回了URLProtoco的一个数组集合。Ffmpeg支持的urlprotocol都添加在此数组中。
                             根据文件名与下面获取的urlprotocol数组进行匹配。找到合适的URLProtocol。
                       }
                      url_alloc_for_protocol

                       {

                              这里完成了URLContext内存的分配

                             初始化(URLContext 中含有URLProtocol *prot的成员)。

                       }
                 }
             }//end  ffurl_alloc
        }//end  ffurl_open_whitelist
        ffio_fdopen(AVIOContext **s, URLContext *h)
        {
          *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE,
                            internal, io_read_packet, io_write_packet, io_seek);
          这里申请了AVIOContext 的内存,并初始化了AVIOContext 的指针函数。
          这个函数执行完后,输入的参数s即已有值了。这里AVFormatContext中的AVIOContext *pb已经初始化完毕。
        }
    }//ffio_open_whitelist
}//io_open_default


接下来,函数调用了av_probe_input_buffer2,主要是获取到iformat的空间以及初始化其相关参数,在上面已经分析过其过程了。


综上:该函数主要完成了申请并初始化了AVFormatContext,如果用户没有指定AVIOContext则先使用io_open来申请相应空间并初始化成员AVIOContext(实质是根据filename找到相应的URLProtocol结构,以后的读取和写入过程,实际是用过该URLProtocol结构进行的)。当得到相应的AVIOContext *pb后,调用av_probe_input_buffer2完成AVFormatContext 中的iformat成员的申请和初始化工作。至此,完成了该函数的所有功能。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值