一、源码方法参数分析

下面是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,先初始化好这个结构体,就能够节约时间加快首屏播放了。

FFmpeg 源码学习(一):avformat_open_input 源码分析相关推荐

  1. mybatis源码学习篇之——执行流程分析

    前言 在正式学习mybatis框架源码之前,需要先弄懂几个问题?myabtis框架是什么?为什么需要mybatis框架?使用mybatis框架带来的好处是什么? 回答这几个问题之前,我们先来看一下,之 ...

  2. 【Android 源码学习】SharedPreferences 源码学习

    第一章:SharedPreferences 源码学习 文章目录 第一章:SharedPreferences 源码学习 Android SharedPreferences的缺陷 MMKV.Jetpack ...

  3. spring源码学习之整合Mybatis原理分析

    本文主要解析spring是如何与mybatis进行整合,整合的过程中需要哪些组件的支持.以前面提到过的配置例子<spring源码学习之aop事物标签解析> 整合的过程中需要使用以下这个依赖 ...

  4. mybatis源码学习1--学习源码的目的

    在开始分析mybatis源码之前,需要定一个目标,也就是我们不是为了读源码而去读,一定是带着问题去读,在读的时候去寻找到答案,然后再读码的同时整理总结,学习一些高级的编码方式和技巧. 首先我们知道my ...

  5. Golang源码学习(二)----Go源码学习基础

    ### 本文源码版本为 GO 1.17.8 Windows/amd64: ### 可能参与对比的版本:GO 1.16.2 Linux/amd64一.Golang的编译器究竟是如何工作的? (学习源码有 ...

  6. Spark源码学习之IDEA源码阅读环境搭建

    软件准备 (1)Java 1.8 (2)Scala 2.11.12(需要在IDEA中安装) (3)Maven 3.8.2(需要在IDEA中配置) (4)Git 2.33 以上软件需要安装好,并进行环境 ...

  7. spark源码学习(十)--- blockManager分析

    blockManager主要原理: blockmanager位于org.apache.spark.storage中,包含四个重要的组件:DiskStore,MemoryStore,Blocktrans ...

  8. nimble源码学习——广播流程源码分析1

    广播流程源码分析1 在controller层有多种状态:广播.空闲.连接等等,这次分析的是广播这个状态或者叫 做角色.在前面controller层循环的分析中,可以明确controller层也有eve ...

  9. Spring源码学习---------(最简单易懂的源码学习笔记)

  10. Java多线程之JUC包:Semaphore源码学习笔记

    若有不正之处请多多谅解,并欢迎批评指正. 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.com/go2sea/p/5625536.html Semaphore是JUC ...

最新文章

  1. 电磁信号检测 | 本是同根生,相煎何太急
  2. mysql yn 字段类型_mysql常用数据类型
  3. HDU 2852 KiKi's K-Number 主席树
  4. 【蓝桥杯】基础练习 十六进制转八进制(Java实现)
  5. Tomcat集群快速入门2
  6. PCL:全程详解 VS2010+PCL配置
  7. 移动IM开发那些事:技术选型和常见问题
  8. python项目之站长素材爬取
  9. 基于权重的节点驱逐 - Oracle RAC 12.2 新特性
  10. powershell提取html字段,使用PowerShell或VBS从HTML文件中提取表
  11. 编写一个文件目录常用操作的类
  12. 计算机维修与销售探讨,《计算机维修与维护》面向市场教学的探讨.pdf
  13. VS2013 安装配置 C++ boost 库
  14. 常见类 --Object
  15. 轻量级日志收集转发 | fluent-bit外部插件详解(三)
  16. 维汉语音翻译android,维汉语音翻译助手
  17. 《数据结构导论》之树
  18. java手机号码加密_用户名-手机号加密特殊处理
  19. 联想小新锁屏壁纸怎么换_如何设置联想小新电脑锁屏时间
  20. html 菜单栏横向排列,响应式可弹出横向导航栏

热门文章

  1. php唯一性查询,ThinkPHP5.0数据更新验证唯一性怎么验证。
  2. 炫酷的元素周期表html,HTML5 经典化学元素周期表
  3. java ui调试_如何使用 IBM i System Debugger 调试 Java 程序
  4. 关于去中心化身份的一点思考
  5. c语言socket原理,Socket底层原理
  6. java中间缓存变量机制_Java中间缓存变量机制
  7. java 监控执行时间_java-监测方法运行时间 | 学步园
  8. Android平滑图片加载和缓存库Glide使用详解
  9. 360浏览器极速模式_【小技巧】解除浏览器主页以及,锁定主页~
  10. SpringBoot自动装载