Avformat_open_input函数的分析之--HTTP篇

本文主要分析ffmpeg的avformat_open_input函数在处理HTTP协议时的工作流程。从接口参数解析开始,逐步讲解init_input、ffio_open_whitelist、ffurl_open_whitelist等关键函数的实现,特别是http_open函数及其内部的http_open_cnx_internal函数,涉及TCP连接的建立、DNS解析和HTTP请求的发送。整个过程揭示了ffmpeg如何处理网络数据,对理解ffmpeg的网络流处理有重要帮助。
摘要由CSDN通过智能技术生成

前段时间在做直播的优化,主要是优化首屏时间,因为直播播放器大部分都会采用ffmpeg来处理,所以就会用到avformat_open_input这个函数,这也是首屏耗时比较多的一个地方,这里我主要跟踪一下http的请求以及rtmp的请求,源码都是开源的,这里主要是记录下来以备自己查询,本篇文章主要是是以ijkplayer源码为基础分析的。

avformat_open_input这个函数的作用是打开文件的链接,如果是网络连接,还会发起网络请求,并一直等待网络数据的返回,然后读取视频流的数据。接下来进行详细的分析。

1.接口参数的解析

首先看函数的声明

int avformat_open_input(AVFormatContext **ps, const char *filename,
                        AVInputFormat *fmt, AVDictionary **options)
  • AVFormatContext **ps

    该函数的主要作用是填充好AVFormatContext **ps这个结构体。AVFormatContext这个结构体里面的参数比较多,这里就不一一列举了,详细可以参考avformat.h这个头文件,具体用到啥到时再详细说明。

  • const char *filename

    文件的全部路径,比如http://flv-meipai.8686c.com/meipai-live/58e03ffd20a05d7a1410d08c.flv

  • AVInputFormat *fmt

    AVInputFormat 的结构体也比较复杂,主要是封装媒体数据封装类型的结构体,比如flv, mpegts, mp4等。在这里可以传入空,如果为空,后面就会从网络数据中读出。当然如果我们知道文件的类型,先用av_find_input_format("flv")初始化出对应的结构体,这里我们用的是flv,先初始化好这个结构体,对于直播来说,会比较节约时间。

  • AVDictionary **options

    struct AVDictionary {
      int count;
      AVDictionaryEntry *elems;
    };
    typedef struct AVDictionaryEntry {
      char *key;
      char *value;
    } AVDictionaryEntry;

    字典类型的可选参数,可以向ffmpeg中传入指定的参数的值。比如我们这里传入了 av_dict_set_int(&ffp->format_opts, "fpsprobesize", 0, 0); 表示fpsprobesize对应的参数值为0,当然还可以传入更多值,具体可以参考options_table.h这个头文件。

2.函数的关键函数实现

avformat_open_input的具体实现在libavformat/utils.c文件。

init_input函数

第一次调用avformat_open_input函数时,传入的ps是属于初始化状态,很多部分可以忽略,直接跳到以下部分

if ((ret = init_input(s, filename, &tmp)) < 0)
        goto fail;

init_input函数的声明如下

/* Open input file and probe the format if necessary. */
static int init_input(AVFormatContext *s, const char *filename,
                      AVDictionary **options)

函数的主要功能如注释一样,打开一个文件链接,并尽可能解析出该文件的格式。它里面关键的调用是

if ((ret = s->io_open(s, &s->pb, filename, AVIO_FLAG_READ | 
                      s->avio_flags, options)) < 0)
        return ret;

io_open函数是一个回调函数。一般情况下是采用的默认函数io_open_default,具体的赋值是在libavformat/option.c文件中,调用过程如下:

avformat_alloc_context->avformat_get_context_defaults->(s->io_open  = io_open_default;)
其中io_open_default的函数实现
static int io_open_default(AVFormatContext *s, AVIOContext **pb,
                           const char *url, int flags, AVDictionary **options)
{
    printf(
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值