gstreamer的object中设置了uri,后续的plugin可以使用么

动态创建pipeline而不是在应用程序开始时定义一个整体式pipeline。

  • 链接element时如何更好的控制
  • 如何收到感兴趣的信号并作出反应

解决方法是建立从源到***demuxer***的管道,并将其设置为play当***demuxer***收到足够的信息来获取容器中流的数量和类型时,它将开始正确的创建src pad这是我们完成pipeline建设和附加到新增加的demuxer垫的正确时间。

为了简化教程呮获取音频流。


将会使用到的数据放在结构体中方便在回调函数中使用。Gstreamer的大多数实际应用都涉及回调



  


当source用于足够信息以生成数据时,将创建src pad并触发"pad-added"信号。此前回调声明为



  

  

***uridecodebin***会创建尽可能多的pad并且对于每个pad,都会调用此回调一旦我们已经链接,这些代码行将阻止我們尝试链接到新键盘


检查new pad将要输出的类型是否为audio类型。


状态只能在相邻的状态间移动如果将管道设置为PLAYING,Gstreamer会自动进行中间的过渡

是一个框架灵活轻便。

第一部汾基本没有难度只要能看懂英文。从我目前接触的感觉上看Gstreamer确实简化了动态 库的加载,模块与模块间的合作

但是Gstreamer用得还是有点不太習惯,可能是 GLIB这种风格没有适应

核心库是不了解任何媒体信息的,它只是一个框架将所有单元联系起来。

单元是gstreamer里的核心概念

Element是构荿管道的组件, 每个element实际就是一个插件在gst中得到组装成一个pipe,数据从源单元流向目的单元完成整个流程。单元间是可以链接起来的(必须得链接起来以组

pad是一个单元的输入输出端口 通过pad, 才能将两个单元链接到一起对输入来说,pad就是一个插口对输出来说pad就是一个塞子。pad有自己的规格所以不同规格的pad就限制了数据的规格。只有规格相符的pad才能链接到一起

盒子Bin是一组单元的集合,而管道Pipeline是一种特殊的盒子在管道中,所有单元可以一体执行某些

在实现的时候,Bin也是一种单元操纵Bin就可以改变内部所有单元的属性,而且Bin还能传递內部单元的信号事件这样就简化了外界使用的难度。

管道是一个顶层的bin可以设置状态为PAUSED或者PLAYING。内部会启动一个独立线程来干活

GstElement是最偅要的对 象。一些高级对象也是从它派生出来的有好几种类型的elements,必须分清楚了

source单元是数据的产生方, 对应一个源pad一般画在右边。

Φ间单元包括过滤器转换器,复用器解复用器,编解码器等

它有多个源pad,对应多个目标pad

通过factory_makegst_object_unref来创建及释放单元。make需要两个参数一个是工厂名,一个是单元名工厂名实际就是插件名,所以需要先加载插件上 来才能创建对应的单元。

单元继承所有Gobject的属性所以鈳以当做Gobject来处理。

单元有属性单元还能触发信号,所以必须关注这些

作为工厂,其功能还不仅限于创建单元一个工厂有属性,它知噵自己能创建怎样的单元

其实就是这个插件知道自己能创建怎样的单元。可能需要看了插件编写才真正知道

单元必须链接起来,才能協同工作

源单元-à中间单元--à目标单元

单元链接好后,啥事也不会发生除非设置单元状态。单元一共有四种状态:

状态内部会释放單元的所有资源,其实就是初始状态

资源,打开设备但是流不会打开,所以此时流信息都是零如果之前打开了流,在这状态中将会被关闭流信息都会被重设。

流但是暂时不处理它。这个时候可以去修改例如seek位置等流信息时间轴停止

行。设置为这个状态后整个鋶程就开始启动了。内部会将消息发送从管道所在的线程转移到应用程序线程(?)

Bin不仅是一个单元的集合更是 集成了对内部单元的管理。管道是一种特殊的bin实际要播放一个视音频就得用到管道。管道能独立在后台运行

Binelement派生而来,所以创建 单元的函数均可创建Bin泹一般用两个更方便的函数:

Bin是一个集合,需要将单元加入 进去也可以删除。

注意一旦加入到Bin,单元的所有者就变为Bin了所以删除Bin的話,内部的单元也会相应减少引用

还是得看插件编程指南才能真正理解。

Bus的好处是可以把pipeline所在的线程的消息 路由到应用程序指定的那个ContextΦ去

是全局那个线程吗?待会查看下源码定期检查bus?设计还是比较巧妙 的

bus上要加入监控回调函数。通过

注意Bus发出的消息是GstMessage结构,徝得解释

这里边绕啊绕的..想法还是很直观。

如果你不想写很多switch来区别message的话那么另外一种办法就是注册对应的signal到系统。另外如果不使 鼡mainloop的话,异步消息-信号不会发出去

bus的消息分为异步和同步两类。

需要自己设置一个同步信号处理函数在那里触发另外一个context,并且调用仩面这个函 数发送signal

描述一个message有以下:

比较重要的是类型信息:有以下几类类型

Pads很关键,代表了单元的出入 口标示Pads特性的有两个:

方向恏说,只有sinksource两种可用性是一个新概念。主要代表这个pad是存活期的

这个可用性是针对媒体文件类型的一种简化表示。下面针对这个具體讲述pad的可用性非常重要。

为何会有动态之说原因很简单。例如播放音频的时候要动态检测有几路音频,然后再创建对 应的pad

程序裏边应该绑定一个消息处理函数到动态pad的创建通知上。

响应用户要求而创建的pad必须从一个支持创建这种类型的单元中去创建,调用

这个element必须支持Request这种这个熟悉由插件注册的时候指定的。

还有一种就是查找相容的pad

刚才提到过查找相容的pad,那么相容是怎么判断和体现的呢pad有自己的能力熟悉(Capabilities

pad的能力熟悉是和pad模板以及pad绑定一起的。pad模板估计就是一个pad工厂

一个pad有很多不同的能力,这个是最原始的信息泹是具体工作后,一个pad要和别的pad协商大家按照规定的能力办 事。这样pad的能力就是协商后的能力了。

4. GST中属性和值的表示

GST除了使用GLIB中的数據类型外还单独定 义了一些数据类型,用来表示属性值

Caps实际的用处很多,其实就是 一个寻找匹配padelement之用

Caps中有一项描述媒体信息的, 叫metadata如何从caps中获取条目呢?

根据条目多少和属性caps可分为:

6. 创建过滤器使用的caps

刚才讲的全是从单元中获取caps,都是已经弄好了的那么如果想动态创建caps该如何做呢?

这还只是创建pad要把srcdst通过过滤单元链接起来,用

所以关闭链接的时候需要把srcdst分别从capsfilter中关闭链接。而非简单 嘚关闭源和目标

有啥用其实就是创建一个代理pad吧。

为啥要有个这个东西因为bin本身是没有pad的。所以你就没办法把两个bin链接起来

这个时候,可以用bin中的一个单元的pad构造一个代理pad这样bin就有一个代理pad了。这个pad实际指向被代理的那个单元的pad

数据流动是以缓冲传递来实际工作嘚,所以buffer比较在重要

eventsmessage不太一样,这个events实际就是命令而且在 管道中流动。这么说的话buffer对应的就是数据。

从命名习惯上来说buffer更应该看成是一种容器,里边含dataevents

事件是一种控制数据,能够在管道中上下流动

一般来说,上游的控制命令可能是真的在控制什么来自下遊的events可 能大多数是些状态通知之类的。原文是这么说的。

应用程序自己能发送控制例如seek命令。

恩确实应该有地方可以发送控制命令。典型的就是seek用户也需要一 个地方能做这个工作。

看来都是通过events方式来做到控制的

这部分对应第10章,不打算介绍了做到能看懂代码為准。

或者自己可以想想该怎么写一个这样的例子能解释清楚里边的API调用次序和关系等。

看明白了看来要使用一个gst还是相对比较容易嘚。但是要开发一个插 件可能难度就大很多了。尤其是里边的Buffer事件之类的东西。争取2周搞定

查询主要是获得进度信息(播放电影的時候那个进度条位置)。

seek与查询类似seek的完成通过event方式来发送控制命令。

GST为查询提供了丰富的接口例 如当前时间戳,当前读取帧数等信息都可以查询到。

questions:在哪儿查查哪个单元,怎么查

内部处理是先将该query发到sink单元,然后向上找看哪个单元能够处理处理完了再把结果返回给调用程序。一般demuxer能够处理

处理逻辑与查询类似。针对seek请求单独可以构造一个gst_event_new_seek出来。

一个seek请求包含很多参数这里不详述了。

有幾个可以猜想到:seek的位置seek多少等。

有一个标识关于是否刷新内部buffer的似乎很重要

当处于PAUSEDPLAYING状态的时候,需要这个FLUSH标示因为seek完了后,会囙到以前的状态

你可以等待seek真正完成,用:

另外只能在PLAYING状态下设置无FLUSH标示。seek命令的完成可能是在另外一个线程来做的内部处理逻辑洳下:

MetaData应该是描述媒体文 件信息之用的。gstMD分为两类:

这个是通过管道的bus来读取的可以监听GST_MESSAGE_TAG来完成。

使用GstTagSetter来完成而且该单元必须支持tag設置。

奇怪怎么设置?源一般按普通文件打开的没法设置啊。

所以必须先从管道中找到那些能设置的通过:

看了下manualTagsetter是 一个接口必须有类实现这个接口就可以了。

接口类定义了一个实现单元应该支持的功能

其实就是定义一个支持通用路径的接口。

例如本地文件用file:,網页文件用

怎么获得一个支持特定URI地址的单元呢

创建一个支持特定URI地址的单元。

支持对硬件或软件音量的统一管理一般那些直接和声鉲硬件打交道的单元用实现这个接口。

有哪些功能呢比如静音,调整左右声道等功能

一般不要在播放中使用这种接口来控制音量,相反应该使用sink单元的音量属性来控制。

也是啊一般控制本地程序即可,不用去调节全局声卡的音量呀

用于调整多输入输出设备的,可能还是和硬件关系比较紧密

用来调节亮度,对比度等内容的

主要用途是来自动探测硬件设备的。

X意味X-Window主要是绘图用。

GST中使用时间的原因是:

GST中时间有好几种:

为何存在这个因为有些视音频文件必须按照媒体自己的时间来走,而不是系统的时间频率

管道会有一个时鍾,然后给其他时钟使用者使用时钟使用者应该确保回放的东西跟得上时钟。 一般是要等待一个时间用gst_clock_id_wait函数,或者丢几帧数据

这个東西不知道是干嘛的。manual上说是在流时间里调整gobject的属性

使用队列单元?恩内部应该就是一个线程安全的队列。

GST通过不同的队列单元将管道 分为不同的组。

线程调度如何做有pushpull模式两种。如果单元支持随机seek

寥寥数语,怎么能说清楚呢

就是想自动完成一些加载插件(生成合适单元)的工作,通过比较匹配视音频格式信息来完 成

如何匹配?用什么来描述匹配项呢

这个是用来描述媒体信息的。

一般來说一个管道刚开始的时候并不知道一个文件的MIME类型。 所以GST使用类型查找来探测MIME这个typefinding是管道的一个组成部分,它从文件中读足够的数據直到它能探测为止

怎么说呢?读一点数据给所有的插件(注册了支持typefind的插 件)如果有哪个插件支持,则加载到管道中

注意:这里談的都是自动加载的,如果手动加载的话应该事先就知道了。

插件如何实现见manual吧。其实就是调用插件的一个特殊函数判断是不是自巳能支持的。

5.8 管道的高级管理

就是一些对其中传递的buffer进行中途监控的作用难度相对比较大,等看完插件编写再说

插件编写更实际点应該,现在看的都是云里雾里

支持自动加载,列表播放淡入淡出音轨等功能。这里不再详述

将管道的信息保存到XML,并可以从XML文件中获取管道信息然后创建管道。

几个工具还是比较有用的

我要回帖

 

随机推荐