热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

FFmpeg源码学习(一):avformat_open_input源码分析

一、源码方法参数分析下面是avformat_open_input的方法及参数:***Openaninputstreamandreadtheheader.Thecode

一、源码方法参数分析

下面是avformat_open_input的方法及参数:

/**
* Open an input stream and read the header. The codecs are not opened.
* The stream must be closed with avformat_close_input().
*
* @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).
* May be a pointer to NULL, in which case an AVFormatContext is allocated by this
* function and written into ps.
* Note that a user-supplied AVFormatContext will be freed on failure.
* @param url URL of the stream to open.
* @param fmt If non-NULL, this parameter forces a specific input format.
* Otherwise the format is autodetected.
* @param options A dictionary filled with AVFormatContext and demuxer-private options.
* On return this parameter will be destroyed and replaced with a dict containing
* options that were not found. May be NULL.
*
* @return 0 on success, a negative AVERROR on failure.
*
* @note If you want to use custom IO, preallocate the format context and set its pb field.
*/

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

这里我们提供的是英文的参数注释,主要是翻译不好,对此方法的理解也没有什么帮助。下面针对此方法的这几个参数进行一下说明:

  • AVFormatContext **ps : 参数ps包含一切媒体相关的上下文结构,有它就有了一切,本函数如果打开媒体成功,会返回一个AVFormatContext的实例。此参数可以为avformat_alloc_context创建的,也可以是NULL。
  • 参数filename是媒体文件名或URL.  
  • 参数fmt是要打开的媒体格式的操作结构,因为是读,所以是inputFormat.此处可以传入一个调用者定义的inputFormat,对应命令行中的 -f xxx段,如果指定了它,在打开文件中就不会探测文件的实际格式了,以它为准了. 
  • 参数options是对某种格式的一些操作,是为了在命令行中可以对不同的格式传入,特殊的操作参数而建的, 可以无视。

二、方法的作用及流程

1. 输入输出结构体AVIOContext的初始化;

2. 输入数据的协议(例如RTMP,或者File)的识别(通过一套评分机制)

  • 判断文件名的后缀

  • 读取文件头的数据进行比对;

3. 使用获得最高分的文件协议对应的URLProtocol,通过函数指针的方式,与FFMPEG连接,剩下的就是调用该URLProtocol的函数进行open,read等操作。

 

下图用来了解一下和avformat_open_input有关系的函数调用流程图:

 

可见最终都调用了URLProtocol结构体中的函数指针。

下面是URLProtocol结构,可以看出来URLProtocol是一大堆函数指针的集合(avio.h文件)

typedef struct URLProtocol {const char *name;int (*url_open)(URLContext *h, const char *url, int flags);int (*url_read)(URLContext *h, unsigned char *buf, int size);int (*url_write)(URLContext *h, const unsigned char *buf, int size);int64_t (*url_seek)(URLContext *h, int64_t pos, int whence);int (*url_close)(URLContext *h);struct URLProtocol *next;int (*url_read_pause)(URLContext *h, int pause);int64_t (*url_read_seek)(URLContext *h, int stream_index,int64_t timestamp, int flags);int (*url_get_file_handle)(URLContext *h);int priv_data_size;const AVClass *priv_data_class;int flags;int (*url_check)(URLContext *h, int mask);
} URLProtocol;

URLProtocol功能就是完成各种输入协议的读写等操作

但输入协议种类繁多,它是怎样做到“大一统”的呢?

原来,每个具体的输入协议都有自己对应的URLProtocol。

比如file协议(FFMPEG把文件也当做一种特殊的协议)(*file.c文件)

URLProtocol ff_pipe_protocol = {.name = "pipe",.url_open = pipe_open,.url_read = file_read,.url_write = file_write,.url_get_file_handle = file_get_handle,.url_check = file_check,
};

或者rtmp协议(此处使用了librtmp)(librtmp.c文件)

URLProtocol ff_rtmp_protocol = {.name = "rtmp",.url_open = rtmp_open,.url_read = rtmp_read,.url_write = rtmp_write,.url_close = rtmp_close,.url_read_pause = rtmp_read_pause,.url_read_seek = rtmp_read_seek,.url_get_file_handle = rtmp_get_file_handle,.priv_data_size = sizeof(RTMP),.flags = URL_PROTOCOL_FLAG_NETWORK,
};

可见它们把各自的函数指针都赋值给了URLProtocol结构体的函数指针

因此avformat_open_input只需调用url_open,url_read这些函数就可以完成各种具体输入协议的open,read等操作了

三、方法的使用技巧

合理的使用 avformat_open_input 方法能够加快视频的首屏播放。

首先我们知道avformat_open_input这个函数的作用是打开文件的链接,如果是网络连接,还会发起网络请求,并一直等待网络数据的返回,然后读取视频流的数据。

那如何加快首屏播放呢?

我们可以利用方法中的第三个参数——AVInputFormat。AVInputFormat的结构体比较复杂,主要是封装媒体数据封装类型的结构体,比如flv, mpegts, mp4等,在这里可以传入空(或者0),如果为空(或者0),那么FFmpeg就会自行去检测获取。

当然如果我们知道文件的类型,先用av_find_input_format("flv")初始化出对应的结构体,这里我们用的是flv,先初始化好这个结构体,就能够节约时间加快首屏播放了。

 



推荐阅读
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 本文整理了Java中java.lang.NoSuchMethodError.getMessage()方法的一些代码示例,展示了NoSuchMethodErr ... [详细]
  • 流数据流和IO流的使用及应用
    本文介绍了流数据流和IO流的基本概念和用法,包括输入流、输出流、字节流、字符流、缓冲区等。同时还介绍了异常处理和常用的流类,如FileReader、FileWriter、FileInputStream、FileOutputStream、OutputStreamWriter、InputStreamReader、BufferedReader、BufferedWriter等。此外,还介绍了系统流和标准流的使用。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 本文介绍了关于Java异常的八大常见问题,包括异常管理的最佳做法、在try块中定义的变量不能用于catch或finally的原因以及为什么Double.parseDouble(null)和Integer.parseInt(null)会抛出不同的异常。同时指出这些问题是由于不同的开发人员开发所导致的,不值得过多思考。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
  • 本文整理了Java中org.apache.solr.common.SolrDocument.setField()方法的一些代码示例,展示了SolrDocum ... [详细]
  • 利用空间换时间减少时间复杂度以及以C语言字符串处理为例减少空间复杂度
    在处理字符串的过程当中,通常情况下都会逐个遍历整个字符串数组,在多个字符串的处理中,处理不同,时间复杂度不同,这里通过利用空间换时间等不同方法,以字符串处理为例来讨论几种情况:1: ... [详细]
author-avatar
手机用户2502901575_836
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有