openwrt gstreamer实例学习笔记(五. gstreamer BUS)
1)概述
BUS(总线) 是一个简单的系统,它采用自己的线程机制将一个管道线程的消息分发到一个应用程序当中。总线的优势是:当使用GStreamer的时候,应用程序不需要线程识别,即便GStreamer已经被加载了多个线程。
每一个管道默认包含一个总线,所以应用程序不需要再创建总线。应用程序只需要在总线上设置一个类似于对象的信号处理器的消息处理器。当主循环运行的时候,总线将会轮询这个消息处理器是否有新的消息,当消息被采集到后,总线将呼叫相应的回调函数来完成任务。
2)如何使用一个总线(Bus)
使用总线有两种方法,如下:
I.运行GLib/Gtk+ 主循环 (你也可以自己运行默认的GLib的主循环),然后使用侦听器对总线进行侦听。使用这种方法,GLib的主循环将轮询总线上是否存在新的消息,当存在新的消息的时候,总线会马上通知你。在这种情况下,你会用到gst_bus_add_watch () / gst_bus_add_signal_watch ()两个函数。当使用总线时,设置消息处理器到管道的总线上可以使用gst_bus_add_watch ()。 来创建一个消息处理器来侦听管道。每当管道发出一个消息到总线,这个消息处理器就会被触发,消息处理器则开始检测消息信号类型从而决定哪些事件将被处理。当处理器从总线删除某个消息的时候,其返回值应为TRUE。
II. 自己侦听总线消息,使用gst_bus_peek () 和/或 gst_bus_poll () 就可以实现。
#include <gst/gst.h>
static GMainLoop *loop;
static gboolean my_bus_callback (GstBus *bus, GstMessage *message, gpointer data)
{
g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_ERROR: {
GError *err;
gchar *debug;
gst_message_parse_error (message, &err, &debug);
g_print ("Error: %s\n", err->message);
g_error_free (err);
g_free (debug);
g_main_loop_quit (loop);
break;
}
case GST_MESSAGE_EOS:
/* end-of-stream */
g_main_loop_quit (loop);
break;
default:
/* unhandled message */
break;
}
/* we want to be notified again the next time there is a message
* on the bus, so returning TRUE (FALSE means we want to stop watching
* for messages on the bus and our callback should not be called again)
*/
return TRUE;
}
gint main (gint argc, gchar *argv[])
{
GstElement *pipeline;
GstBus *bus;
/* init */
gst_init (&argc, &argv);
/* create pipeline, add handler */
pipeline = gst_pipeline_new ("my_pipeline");
/* adds a watch for new message on our pipeline's message bus to
* the default GLib main context, which is the main context that our
* GLib main loop is attached to below
*/
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, my_bus_callback, NULL);
gst_object_unref (bus);
//[..]
/* create a mainloop that runs/iterates the default GLib main context
* (context NULL), in other words: makes the context check if anything
* it watches for has happened. When a message has been posted on the
* bus, the default main context will automatically call our
* my_bus_callback() function to notify us of that message.
* The main loop will be run until someone calls g_main_loop_quit()
*/
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
/* clean up */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
g_main_loop_unref (loop);
return 0;
}
3) 消息类型(Message types)
GStreamer有几种由总线传递的预定义消息类型,这些消息都是可扩展的。插件可以定义另外的一些消息,应用程序可以有这些消息的绝对代码或者忽略它们。强烈推荐应用程序至少要处理错误消息并直接的反馈给用户。
所有的消息都有一个消息源、类型和时间戳。这个消息源能被用来判断由哪个element发出消息。例如,在众多的消息中,应用程序只对上层的管道发出的消息感兴趣(如状态变换的提示)。下面列出所有的消息种类、代表的意义,以及如何解析具体消息的内容。
1) 错误、警告和消息提示:它们被各个元件用来在必要的时候告知用户现在管道的状态。错误信息表明有致命的错误并且终止数据传送。错误应该被修复,这样才能继续管道的工作。警告并不是致命的,但是暗示有问题存在。消息提示用来告知非错误的信息。这些消息含有一个带有主要的错误类型和消息的GError,和一个任选的调试字符串。这两项都可以用gst_message_parse_error (), _parse_warning () 以及 _parse_info ()三个函数来提取其信息。当使用完毕后,错误和修正字符串都将被释放。
2) 数据流结束(End-of-stream)提示:当数据流结束的时候,该消息被发送。管道的状态不会改变,但是之后的媒体操作将会停止。应用程序可以通过收到这一消息来跳到播放列表的下一首歌。在数据流结束提示出现之后,仍然可以通过向后搜索来回到以前数据流前面的位置。之后的播放工作将会自动的继续执行。这个消息没有特殊的参数。
3) 标签(Tags):当元数据在数据流中被找到的时候,此消息被发送。一个管道可以发出多个Tag(如元数据的描述里有艺术家、歌曲名,另外的例子如流的信息采样率和比特率)。应用程序应该将元数据存储在缓存里。函数gst_message_parse_tag () 被用来解析tag的列表,当该列表不再使用的时候,函数gst_tag_list_free () 释放其相应的tag。
4) 状态转换(State-changes):当状态成功的转换时发送该消息。函数gst_message_parse_state_changed ()可以用来解析转换中的新旧状态。
5) 缓冲(Buffering):当缓冲网络数据流时此消息被发送。你可以通过函数gst_message_get_structure ()的返回值,来解析"buffer-percent" 属性,从而手动的得到缓冲进度(该缓冲进度以百分比的形式表示)。
6) 元件消息(Element messages):它是一组特殊的消息,用以标识一个特定元件。这样一组特殊的消息通常表述了一些额外的信息。元件的信息应该被详细的描述,因为这样一些元件信息将被作为消息而发送给其他元件。例如:'qtdemux' QuickTime 整流器(demuxer)应该把'redirect'信息保存于该元件信息当中,以便在某种特殊情况下将'redirect'元件信息发送出去。
7) Application-specific消息:我们可以将取得的消息结构解析出来,从而得到有关Application-specific消息的任何信息。通常这些信息是能够被安全地忽略。
应用程序消息主要用于内部,以备从一些线程排列信息到主线程应用的需求。这些在使用元件信号的应用中非常实用(这些信号在数据流线程的上下文被发射)。
openwrt gstreamer实例学习笔记(五. gstreamer BUS)的更多相关文章
- openwrt gstreamer实例学习笔记(一.初始化gstreamer)
GStreamer 是一个非常强大而且通用的流媒体应用程序框架. GStreamer所具备的很多优点来源于其框架的模块化: GStreamer能够无缝的合并新的插件. 但是, 由于追求模块化和高效率, ...
- openwrt gstreamer实例学习笔记(七. gstreamer 缓冲区(Buffers)和事件(Events))
1)概述 管道的数据流由一组缓冲区和事件组成,缓冲区包括实际的管道数据,事件包括控制信息,如寻找信息和流的终止信号.所有这些数据流在运行的时候自动的流过管道. 2) 缓冲区(Buffers) 缓冲区包 ...
- openwrt gstreamer实例学习笔记(六. gstreamer Pads及其功能)
一:概述 如我们在Elements一章中看到的那样,Pads是element对外的接口.数据流从一个element的source pad到另一个element的sink pad.pads的功能(cap ...
- openwrt gstreamer实例学习笔记(四. gstreamer Bins)
1)概述 Bins是一种容器element.你可以往Bins中添加element.由于Bins本身也是一种element,所以你可以像普通element一样 操作Bins.因此,先前关element的 ...
- openwrt gstreamer实例学习笔记(三.深入了解gstreamer 的 Element)
在前面的部分,我们简要介绍过 GstElementFactory 可以用来创建一个element的实例,但是GstElementFactory不仅仅只能做这件事,GstElementFactory作为 ...
- openwrt gstreamer实例学习笔记(二.gstreamer 的 Element)
对程序员来说,GStreamer 中最重要的一个概念就是 GstElement 对象.该对象是构建一个媒体管道的基本块.所有上层(high-level)部件都源自GstElement对象.任何一个解码 ...
- gstreamer应用笔记
gstreamer官网 https://gstreamer.freedesktop.org/ 应用手册 https://gstreamer.freedesktop.org/documentation/ ...
- [Openwrt 项目开发笔记]:DDNS设置(五)
[Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 在上一节中,我主要讲述了如何在Openwrt上安 ...
- [openwrt 项目开发笔记]: 传送门
“Openwrt 项目开发笔记”系列传送门: [Openwrt 项目开发笔记]:Openwrt平台搭建(一) (2014-07-11 00:11) [Openwrt 项目开发笔记]:Openwrt平台 ...
随机推荐
- BRVAH(让RecyclerView变得更高效) (2)
本文来自网易云社区 作者:吴思博 1.2 宫格和列表的混排样式 关于 Grid 和List 的混排样式,Grid 样式是一行有多个,而 List样式是一行只有一个. 我们可以把 List 样式看成是G ...
- 【转载】C语言中的static 详细分析
原blog地址:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少, ...
- 【LeetCode】Permutations(全排列)
这道题是LeetCode里的第46道题. 题目要求: 给定一个没有重复数字的序列,返回其所有可能的全排列. 示例: 输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3 ...
- Laya 屏幕适配
Laya 屏幕适配 @author ixenos 2019-03-20 21:44:52 1.最简单的方案:原比例,对照屏幕尺寸的最小比率缩放,有黑边 Laya.stage.scaleMode = S ...
- 【Go】错误处理
· error类型是一个接口类型,也是一个Go语言的内建类型.在这个接口类型的声明中只包含了一个方法Error.这个方法不接受任何参数,但是会返回一个string类型的结果.它的作用是返回错误信息的字 ...
- 九度oj 题目1114:神奇的口袋
题目描述: 有一个神奇的口袋,总的容积是40,用这个口袋可以变出一些物品,这些物品的总体积必须是40.John现在有n个想要得到的物品,每个物品的体积分别是a1,a2……an.John可以从这些物品中 ...
- Luogu【P2904】跨河(DP)
题目链接在这里 此题DP.用一个前缀和一样的东西,把载i个奶牛的时间求出来,然后DP代码如下: ;i<=n;++i){ f[i]=que[i]; ;j<i;++j) f[i]=min(f[ ...
- SPOJ QTREE3 Query on a tree again! ——Link-Cut Tree
[题目分析] QTREE2,一看是倍增算法,太懒了,不写了.( ̄_, ̄ ) QTREE3,树链剖分可以做,发现链上的问题LCT也很好做. 要是子树问题貌似可以DFS序. 然后就成LCT模板题了. 考前 ...
- getParameter 与 getAttribute的区别
request.getAttribute():是request时设置的变量的值,用request.setAttribute("name","您自己的值");来设 ...
- Android Studio升级到3.0,抛出Aapt2Exception异常
android studiao错误: Android resource linking failedOutput: D:\_ASWorkSpace\phone_new\app\src\main\res ...