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)的更多相关文章

  1. openwrt gstreamer实例学习笔记(一.初始化gstreamer)

    GStreamer 是一个非常强大而且通用的流媒体应用程序框架. GStreamer所具备的很多优点来源于其框架的模块化: GStreamer能够无缝的合并新的插件. 但是, 由于追求模块化和高效率, ...

  2. openwrt gstreamer实例学习笔记(七. gstreamer 缓冲区(Buffers)和事件(Events))

    1)概述 管道的数据流由一组缓冲区和事件组成,缓冲区包括实际的管道数据,事件包括控制信息,如寻找信息和流的终止信号.所有这些数据流在运行的时候自动的流过管道. 2) 缓冲区(Buffers) 缓冲区包 ...

  3. openwrt gstreamer实例学习笔记(六. gstreamer Pads及其功能)

    一:概述 如我们在Elements一章中看到的那样,Pads是element对外的接口.数据流从一个element的source pad到另一个element的sink pad.pads的功能(cap ...

  4. openwrt gstreamer实例学习笔记(四. gstreamer Bins)

    1)概述 Bins是一种容器element.你可以往Bins中添加element.由于Bins本身也是一种element,所以你可以像普通element一样 操作Bins.因此,先前关element的 ...

  5. openwrt gstreamer实例学习笔记(三.深入了解gstreamer 的 Element)

    在前面的部分,我们简要介绍过 GstElementFactory 可以用来创建一个element的实例,但是GstElementFactory不仅仅只能做这件事,GstElementFactory作为 ...

  6. openwrt gstreamer实例学习笔记(二.gstreamer 的 Element)

    对程序员来说,GStreamer 中最重要的一个概念就是 GstElement 对象.该对象是构建一个媒体管道的基本块.所有上层(high-level)部件都源自GstElement对象.任何一个解码 ...

  7. gstreamer应用笔记

    gstreamer官网 https://gstreamer.freedesktop.org/ 应用手册 https://gstreamer.freedesktop.org/documentation/ ...

  8. [Openwrt 项目开发笔记]:DDNS设置(五)

    [Openwrt项目开发笔记]系列文章传送门:http://www.cnblogs.com/double-win/p/3888399.html 正文: 在上一节中,我主要讲述了如何在Openwrt上安 ...

  9. [openwrt 项目开发笔记]: 传送门

    “Openwrt 项目开发笔记”系列传送门: [Openwrt 项目开发笔记]:Openwrt平台搭建(一) (2014-07-11 00:11) [Openwrt 项目开发笔记]:Openwrt平台 ...

随机推荐

  1. pytest分布式执行(pytest-xdist)

    前言 平常我们手工测试用例非常多时,比如有1千条用例,假设每个用例执行需要1分钟.如果一个测试人员执行需要1000分钟才能执行完,当项目非常紧急的时候, 我们会用测试人力成本换取时间成本,这个时候多找 ...

  2. 修复Centos7双系统引导

    1.进入CentOS系统 2.命令行输入 vi /boot/grub2/grub.cfg 3.在文件空白处添加下列代码 menuentry 'Windows 7'{ insmod part_msdos ...

  3. bzoj3000 Big Number 数论,斯特林公式

    Description 给你两个整数N和K,要求你输出N!的K进制的位数. Input 有多组输入数据,每组输入数据各一行,每行两个数——N,K Output 每行一个数为输出结果 Sample In ...

  4. jenkins使用流程

    jenkins使用流程 看下面那个连接的吧. http://www.cnblogs.com/zz0412/p/jenkins02.html 1.设置git库 2.点击add添加github用户名.密码 ...

  5. *AtCoder Regular Contest 094 F - Normalization

    $n \leq 200000$的abc字符串,现能进行如下变换零次或若干次:选一个$i<n$且$s_i \neq s_{i+1}$,把$s_i$和$s_{i+1}$替换成abc三个字母中除了这两 ...

  6. dedecms--需要注意的细节

    在系统的系统配置参数里面修改一些参数 1:站点设置: (1):站点根网址:本地测试的话:就是你设置的虚拟主机:http://www.abc.cc (2):网页主页链接:为空 2:核心设置: DedeC ...

  7. HDU 5676 ztr loves lucky numbers【DFS】

    题目链接; http://acm.hdu.edu.cn/showproblem.php?pid=5676 题意: 由4和7组成的且4和7出现次数相同的数称为幸运数字,给定n,求不大于n的最大幸运数字. ...

  8. 2017 ACM/ICPC Asia Regional Guangxi Online 记录

    题目链接  Guangxi 感觉这场比赛完全是读题场啊…… 比赛过程中丢失了一波进度,最后想开题的时候已经来不及了…… Problem A 按题意模拟……按照那个矩阵算就可以了 #include &l ...

  9. ACM用到的算法。先做个笔记,记一下

    ACM 所有算法 数据结构 栈,队列,链表 哈希表,哈希数组 堆,优先队列 双端队列 可并堆 左偏堆 二叉查找树 Treap 伸展树 并查集 集合计数问题 二分图的识别 平衡二叉树 二叉排序树 线段树 ...

  10. List 与 ArrayList 的使用

    最近回顾 java 集合,发现大部分程序中都在使用 List list = new ArrayList(); 也有部分程序使用 ArrayList list = new ArrayList(); 那么 ...