1. 数据结构

AVInputFormat为FFMPEG的解复用器对象,通过调用av_register_all(),FFMPEG所有的解复用器保存在以first_iformat为链表头的链表中,且还有个链表尾指针last_iformat。

以ff_srt_demuxer为例子来看看该结构体的初始化流程。

先看ff_srt_demuxer的定义:

  1. AVInputFormat ff_srt_demuxer = {
  2. .name        = "srt",
  3. .long_name   = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
  4. .priv_data_size = sizeof(SRTContext),
  5. .read_probe  = srt_probe,
  6. .read_header = srt_read_header,
  7. .read_packet = srt_read_packet,
  8. .read_seek2  = srt_read_seek,
  9. .read_close  = srt_read_close,
  10. };

易知,name成员为解复用器的名称,long_name为对应的文件格式,priv_data_size为和解复用器关联的对象(SRTContext)的大小,read_probe,read_header,read_packet,read_seek2,read_close分别为探测函数,读头函数,读包函数,seek函数及close函数指针。先看SRTContext定义,再看看这几个具体的函数。

SRTContext定义:

  1. typedef struct {
  2. AVPacket *subs;         //字幕包数组
  3. int nb_subs;            //字幕包条数
  4. int allocated_size;     //(每条)字幕的大小
  5. int current_sub_idx;    ///当前字幕索引
  6. enum sub_sort sort;     ///字幕排序方式
  7. } FFDemuxSubtitlesQueue;

从代码(比如srt_read_packet)易知,解复用器的关联对象指针存储在AVFormatContext的priv_data成员中。

srt_probe()是探测函数,它从AVProbeData对象的buf成员中读取数据,然后探测2次是否存在以下规则的字符串,若存在,则返回AVPROBE_SCORE_MAX,否则返回0:

  1. "%*d:%*2d:%*2d%*1[,.]%*3d --> %*d:%*2d:%*2d%*1[,.]%3d"

即srt的格式要为:

  1. 1
  2. 00:00:02,436 --> 00:00:06,505

即一行索引+“开始时间-->结束时间”的形式。

srt_read_header()是读头函数(可以看作是初始化函数),该函数实际上把字幕文件中多有的字幕都解析了出来放在FFDemuxSubtitlesQueue对象的队列中。(AVStream???)

注意:1. 该函数会创建流(AVStream),并将流保存到AVFormatContext的streams数组中。

2. 该函数读写文件内容时用的是AVFormat的pb成员(即AVIOContext)。

3. 该函数最后调用了ff_subtitles_queue_finalize()对字幕包进行排序。

srt_read_packet()是读包函数,该函数实际上是从FFDemuxSubtitlesQueue中将当前字幕索引指向的字幕拷贝到传入的包中。(AVPacket???)

srt_read_seek()是搜索函数。

srt_read_close()是关闭函数,主要是释放队列成员及队列本身所占的内存空间。

2. 函数调用:

即:

1. init_input()先调用avio_open2()创建并打开一个AVIOContext对象,用于文件读写;

2. init_input()然后调用av_probe_input_buffer2()探测解复用器类型;

3. av_probe_input_buffer2()包含三个步骤:avio_read()读入探测数据(AVProbeData),然后调用av_probe_input_format2()探测合适的解复用器,最后调用ffio_rewind_witdh_probe_data()将探测数据返回给AVIOContext的缓冲buffer。

av_probe_input_format2()调用av_probe_input_format3(),将得到的匹配分数与要求的匹配值相比较,如果匹配分数>匹配值,这返回得到的解复用器,否则返回NULL。

av_probe_input_format3(),该函数遍历所有的解复用器,调用它们的read_probe()函数计算匹配得分,如果解复用器定义了文件扩展名,还会比较输匹配数据跟扩展名的匹配得分。函数最终返回计算找到的最匹配的解复用器,并将匹配分数也返回。

http://blog.csdn.net/finewind/article/details/39502963

3——FFMPEG之解复用器-----AVInputFormat(转)的更多相关文章

  1. XBMC源代码简析 5:视频播放器(dvdplayer)-解复用器(以ffmpeg为例)

    XBMC分析系列文章: XBMC源代码分析 1:整体结构以及编译方法 XBMC源代码分析 2:Addons(皮肤Skin) XBMC源代码分析 3:核心部分(core)-综述 XBMC源代码分析 4: ...

  2. FFmpeg详解

    认识FFMPEG FFMPEG堪称自由软件中最完备的一套多媒体支持库,它几乎实现了所有当下常见的数据封装格式.多媒体传输协议以及音视频编解码器.因此,对于从事多媒体技术开发的工程师来说,深入研究FFM ...

  3. ffmpeg 详解

    来源:http://blog.itpub.net/9399028/viewspace-1242300/ FFMPEG详解   认识FFMPEG FFMPEG堪称自由软件中最完备的一套多媒体支持库,它几 ...

  4. FFmpeg4.0笔记:封装ffmpeg的解封装功能类CDemux

    Github https://github.com/gongluck/FFmpeg4.0-study/tree/master/Cff CDemux.h /*********************** ...

  5. FFmpeg(二) 解封装相关函数理解

    一.解封装基本流程 ①av_register_All()////初始化解封装,注册解析和封装的格式. ②avformat_netword_init()//初始化网络,解析rtsp协议 ③avforma ...

  6. window64 PHP ffmpeg详解简单上手 音频amr转mp3

    从网上找了一大堆关于window 64 ffmpeg的信息,都是又长又不关键,让人难消化. 我只要简单的amr转MP3格式而已. 终于搞明白.自己总结了下! 希望能帮助到喜欢言简意赅,一眼上手的同学. ...

  7. FFmpeg软硬解和多线程解码

    一. AVCodecContext解码上下文 1.avcodec_register_all() : 注册所有的解码器 2.AVCodec *avcodec_find_decoder(enum AVCo ...

  8. FFmpeg结构体:AVInputFormat

    1.描述 AVInputFormat 是类似COM 接口的数据结构,表示输入文件容器格式,着重于功能函数,一种文件容器格式对应一个AVInputFormat 结构,在程序运行时有多个实例,位于avof ...

  9. FFmpeg开发笔记(四):ffmpeg解码的基本流程详解

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

随机推荐

  1. 微信小程序:页面配置 page.json

    微信小程序:页面配置 page.json 一.页面配置 page.json 如果整个小程序的风格是蓝色调,那么可以在 app.json 里边声明顶部颜色是蓝色即可. 实际情况可能不是这样,可能你小程序 ...

  2. 一个PE文件的逆向分析

    一个PE文件的逆向分析 idf-ctf上有个题,是PE文件的逆向,反正对我来说做出来就是有意思的题,做不出来就没劲.言归正传,下面看一下吧 大家想玩可以去这个地方去拿题http://pan.baidu ...

  3. 20162314 Experiment 4 - Graph

    Experiment report of Besti course:<Program Design & Data Structures> Class: 1623 Student N ...

  4. API设计原则(觉得太合适,转发做记录)

    API设计原则 对于云计算系统,系统API实际上处于系统设计的统领地位,正如本文前面所说,K8s集群系统每支持一项新功能,引入一项新技术,一定会新引入对应的API对象,支持对该功能的管理操作,理解掌握 ...

  5. mybatis generator为实体类生成自定义注释(读取数据库字段的注释添加到实体类,不修改源码)

    我们都知道mybatis generator自动生成的注释没什么实际作用,而且还增加了代码量.如果能将注释从数据库中捞取到,不仅能很大程度上增加代码的可读性,而且减少了后期手动加注释的工作量. 1.首 ...

  6. php特级课---5、网络数据转发原理

    php特级课---5.网络数据转发原理 一.总结 一句话总结: OSI七层模型 路由器 交换机 ARP 代理ARP 1.OSI7层模型? 电缆 MAC地址 ip 端口 应用 1层 通信电缆 2层 原M ...

  7. Rails 5 Test Prescriptions 第11章其他部分的测试。

    Routes✅ Helper Methods✅ Controllers and Requests✅ Simulating Requests⚠️,看之前的博客 What to Expect in a R ...

  8. ✅javascript 语法:附加子节点

    received: function(data) { $("#notifications").prepend(data.html); } 如何用原生js写出jquery的功能: 先 ...

  9. BooStrap4文档摘录 2 Content, Component

    Content Reboot:从新写了主要元素的排列. 本章讲了各种元素及其相关的类. ⚠️ 文档左上角有搜索栏. Components Alert✅ Badge✅ Button✅和Button gr ...

  10. Android Eclipse keystore.jks文件生成,根据keystore密钥获取SHA1安全码 ,apk打包

    keystore.jks文件生成,打包APK 选中项目右键-> Android Tools->Export Signed Application Package ,如图: 之后 点击Nex ...