文档章节

FFMPEG函数avformat_open_input()-输入url为rtmp

andrew810810
 andrew810810
发布于 2016/12/06 18:29
字数 668
阅读 94
收藏 0

FFMPEG版本为3.2,输入url为rtmp

函数init_input()

/* Open input file and probe the format if necessary. */
static int init_input(AVFormatContext *s, const char *filename,
                      AVDictionary **options)
{
    int ret;
    AVProbeData pd = { filename, NULL, 0 };
    int score = AVPROBE_SCORE_RETRY;

    if (s->pb) {
        s->flags |= AVFMT_FLAG_CUSTOM_IO;
        if (!s->iformat)
            return av_probe_input_buffer2(s->pb, &s->iformat, filename,
                                         s, 0, s->format_probesize);
        else if (s->iformat->flags & AVFMT_NOFILE)
            av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
                                      "will be ignored with AVFMT_NOFILE format.\n");
        return 0;
    }

    if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
        (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score))))
        return score;

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

    if (s->iformat)
        return 0;
    return av_probe_input_buffer2(s->pb, &s->iformat, filename,
                                 s, 0, s->format_probesize);
}

函数av_probe_input_format2()返回值为空,即没有得到输入文件的格式。

函数s->io_open()回调io_open_default()

static int io_open_default(AVFormatContext *s, AVIOContext **pb,
                           const char *url, int flags, AVDictionary **options)
{
#if FF_API_OLD_OPEN_CALLBACKS
FF_DISABLE_DEPRECATION_WARNINGS
    if (s->open_cb)
        return s->open_cb(s, pb, url, flags, &s->interrupt_callback, options);
FF_ENABLE_DEPRECATION_WARNINGS
#endif

    return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist, s->protocol_blacklist);
}
int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags,
                         const AVIOInterruptCB *int_cb, AVDictionary **options,
                         const char *whitelist, const char *blacklist
                        )
{
    URLContext *h;
    int err;

    err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist, NULL);
    if (err < 0)
        return err;
    err = ffio_fdopen(s, h);
    if (err < 0) {
        ffurl_close(h);
        return err;
    }
    return 0;
}
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags,
                         const AVIOInterruptCB *int_cb, AVDictionary **options,
                         const char *whitelist, const char* blacklist,
                         URLContext *parent)
{
    AVDictionary *tmp_opts = NULL;
    AVDictionaryEntry *e;
    int ret = ffurl_alloc(puc, filename, flags, int_cb);
    if (ret < 0)
        return ret;
    if (parent)
        av_opt_copy(*puc, parent);
    if (options &&
        (ret = av_opt_set_dict(*puc, options)) < 0)
        goto fail;
    if (options && (*puc)->prot->priv_data_class &&
        (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0)
        goto fail;

    if (!options)
        options = &tmp_opts;

    av_assert0(!whitelist ||
               !(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) ||
               !strcmp(whitelist, e->value));
    av_assert0(!blacklist ||
               !(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) ||
               !strcmp(blacklist, e->value));

    if ((ret = av_dict_set(options, "protocol_whitelist", whitelist, 0)) < 0)
        goto fail;

    if ((ret = av_dict_set(options, "protocol_blacklist", blacklist, 0)) < 0)
        goto fail;

    if ((ret = av_opt_set_dict(*puc, options)) < 0)
        goto fail;

    ret = ffurl_connect(*puc, options);

    if (!ret)
        return 0;
fail:
    ffurl_close(*puc);
    *puc = NULL;
    return ret;
}

函数ffurl_alloc()

int ffurl_alloc(URLContext **puc, const char *filename, int flags,
                const AVIOInterruptCB *int_cb)
{
    const URLProtocol *p = NULL;

    p = url_find_protocol(filename);
    if (p)
       return url_alloc_for_protocol(puc, p, filename, flags, int_cb);

    *puc = NULL;
    if (av_strstart(filename, "https:", NULL))
        av_log(NULL, AV_LOG_WARNING, "https protocol not found, recompile FFmpeg with "
                                     "openssl, gnutls "
                                     "or securetransport enabled.\n");
    return AVERROR_PROTOCOL_NOT_FOUND;
}

通过filename和函数url_find_protocol()得到指针p的内容,例如:

(gdb) p *p
$7 = {name = 0x18b0c31 "rtmp", url_open = 0x6c0760 <rtmp_open>, url_open2 = 0, url_accept = 0, url_handshake = 0, url_read = 0x6c06b0 <rtmp_read>, url_write = 0x6bfac0 <rtmp_write>, url_seek = 0, url_close = 0x6bc1e0 <rtmp_close>, 
  url_read_pause = 0x6bc0a0 <rtmp_pause>, url_read_seek = 0x6bbf50 <rtmp_seek>, url_get_file_handle = 0, url_get_multi_file_handle = 0, url_shutdown = 0, priv_data_size = 1000, priv_data_class = 0x18b1560, flags = 2, url_check = 0, 
  url_open_dir = 0, url_read_dir = 0, url_close_dir = 0, url_delete = 0, url_move = 0, default_whitelist = 0x0}

执行函数url_alloc_for_protocol()后,puc的内容如下:

gdb) p **puc
$23 = {av_class = 0x1884920, prot = 0x18b1040, priv_data = 0x2768680, filename = 0x2768618 "rtmp://180.97.184.107:1936/live?vhost=cc.com/stream_1", flags = 1, max_packet_size = 0, is_streamed = 0, is_connected = 0, 
  interrupt_callback = {callback = 0x4861d0 <decode_interrupt_cb>, opaque = 0x0}, rw_timeout = 0, protocol_whitelist = 0x0, protocol_blacklist = 0x0}
(gdb) p *(puc->prot)
$24 = {name = 0x18b0c31 "rtmp", url_open = 0x6c0760 <rtmp_open>, url_open2 = 0, url_accept = 0, url_handshake = 0, url_read = 0x6c06b0 <rtmp_read>, url_write = 0x6bfac0 <rtmp_write>, url_seek = 0, url_close = 0x6bc1e0 <rtmp_close>, 
  url_read_pause = 0x6bc0a0 <rtmp_pause>, url_read_seek = 0x6bbf50 <rtmp_seek>, url_get_file_handle = 0, url_get_multi_file_handle = 0, url_shutdown = 0, priv_data_size = 1000, priv_data_class = 0x18b1560, flags = 2, url_check = 0, 
  url_open_dir = 0, url_read_dir = 0, url_close_dir = 0, url_delete = 0, url_move = 0, default_whitelist = 0x0}

 

函数ffurl_connect()调用uc->prot->url_open(uc, uc->filename, uc->flags);其中回调libavformat/rtmpproto.c:rtmp_open()

© 著作权归作者所有

共有 人打赏支持
andrew810810
粉丝 3
博文 141
码字总数 117648
作品 0
朝阳
利用FFmpeg和管道(pipe),解决非URL和非文件的输入形式

利用FFmpeg和管道(pipe),解决非URL和非文件的输入形式 问题描述:利用FFmpeg来解码,但是输入方式不是URL,也不是文件系统中的文件,而是内存中的buffer。 解决此问题有两个思路,首先明确...

Michael_Yuan
2012/07/10
0
1
FFmpeg代码导读——基础篇

从事音视频技术开发对FFmpeg都不会感到陌生,通过它可以完成音视频采集、编解码、转码、后处理以及流媒体服务等诸多的功能,可以说涵盖了音视频开发中绝大多数的领域。金山云多媒体SDK团队在...

livevideostack
01/08
0
0
FFmpeg命令行工具学习(五):FFmpeg 编解码 API 分析

在上一篇文章 FFmpeg命令行工具学习(四):FFmpeg API 介绍与通用 API 分析 中,我们简单的讲解了一下FFmpeg 的API基本概念,并分析了一下通用API,本文我们将分析 FFmpeg 在编解码时使用的A...

灰色飘零
07/20
0
0
学习FFmpeg API – 解码视频

ffmpeg是编解码的利器,用了很久,以前看过dranger 的教程,非常精彩,受益颇多,是学习ffmpeg api很好的材料。可惜的是其针对的ffmpeg版本已经比较老了,而ffmpeg的更新又很快,有些API已经...

霄霄月月
2012/05/08
0
32
使用ffmpeg推流到Wowza

Step by step instructions for using FFmpeg as a live video/audio encoder with Wowza Media Server. Updated for FFMpeg build r25705 (22 November 2010) Note: Wowza Media Systems pr......

Johnny_feng
2013/12/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

arts-week10

Algorithm 905. Sort Array By Parity - LeetCode Review Who’s Afraid of the Big Bad Preloader? 一文读懂前端缓存 一个网络请求3个步骤:请求,处理,响应,而前端缓存主要在请求处响应这两步...

yysue
今天
4
0
00.编译OpenJDK-8u40的整个过程

前言 历经2天的折腾总算把OpenJDK给编译成功了,要说为啥搞这个,还得从面试说起,最近出去面试经常被问到JVM的相关东西,总感觉自己以前学的太浅薄,所以回来就打算深入学习,目标把《深入理...

凌晨一点
今天
5
0
python: 一些关于元组的碎碎念

初始化元组的时候,尤其是元组里面只有一个元素的时候,会出现一些很蛋疼的情况: def checkContentAndType(obj): print(obj) print(type(obj))if __name__=="__main__": tu...

Oh_really
昨天
6
2
jvm crash分析工具

介绍一款非常好用的jvm crash分析工具,当jvm挂掉时,会产生hs_err_pid.log。里面记录了jvm当时的运行状态以及错误信息,但是内容量比较庞大,不好分析。所以我们要借助工具来帮我们。 Cras...

xpbob
昨天
158
0
Qt编写自定义控件属性设计器

以前做.NET开发中,.NET直接就集成了属性设计器,VS不愧是宇宙第一IDE,你能够想到的都给你封装好了,用起来不要太爽!因为项目需要自从全面转Qt开发已经6年有余,在工业控制领域,有一些应用...

飞扬青云
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部