首页 > 其他分享 >gstreamer教程(7)——构建应用之Bus的使用

gstreamer教程(7)——构建应用之Bus的使用

时间:2024-08-29 12:37:33浏览次数:13  
标签:教程 gst Bus gstreamer pipeline 应用程序 消息 bus message

Bus 总线:

  bus 总线是一个简单的系统,它负责将消息从流线程转发到其自己的线程上下文中的应用程序。总线的优点是,即使 GStreamer 本身是大量线程的,应用程序也不需要线程感知即可使用 GStreamer。

  默认情况下,每个 pipeline 管道都包含一条 bus 总线,因此应用程序不需要创建总线或任何东西。应用程序唯一应该做的是在总线上设置一个消息处理程序,这类似于对象的信号处理程序。当主循环运行时,将定期检查总线是否有新消息,当有任意消息可用时,将调用回调。

如何使用Bus总线:

  有两种方式使用 bus 总线:

  • 运行一个 GLib/Gtk+ 主循环(或者自己定期迭代默认的 GLib 主上下文)并将某种监听附加到总线上。这样, GLib 主循环将检查总线是否有新消息,有消息时就会通知你。

   要使用bus总线,请使用 gst_bus_add_watch() 将消息处理程序附加到 pipeline 管道的总线上。每当 pipeline 向 bus 发出消息时,都会调用此处理函数。在此处理函数中,检查信号类型(请参阅下一章节) 并相应地执行一些操作。处理程序的返回值应为 TRUE 以保持处理程序附加到总线,返回 FALSE 以将其删除。

  • 自己检查 bus 信息。这可以使用 gst_bus_peek() 和/或 gst_bus_poll() 来完成。

  basic-example-10.c

#include <stdio.h>
#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;
    guint bus_watch_id;

    /* 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));
    bus_watch_id = 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_source_remove (bus_watch_id);
    g_main_loop_unref (loop);

    return 0;
}

  重要的是要知道处理程序将在 mainloop 的线程上下文中调用。这意味着管道和应用程序之间通过总线的交互是异步的,因此不适合某些实时处理,例如音轨之间的交叉淡化、执行(理论上)无缝播放或视频效果。所有这些事情都应该在pipeline管道上下文中完成,最简单的方法是编写 GStreamer 插件。不过,它对于其主要目的非常有用:将消息从管道传递到应用程序。这种方法的优点是 GStreamer 在内部执行的所有线程操作都对应用程序不可见的,应用程序开发人员根本不需要担心线程问题。

  请注意,如果您使用的是默认的 GLib mainloop 集成,则可以连接到总线上的 “message” 信号,而不是添加一个watch监听。这样你就不必对所有可能的消息类型进行 switch() ;只需以 message::<type> 的形式连接感兴趣的信号,其中 <type> 是特定的消息类型(有关消息类型的解释,请参阅下一节)。

  上面的代码段也可以写成:

GstBus *bus;

[..]

bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_signal_watch (bus);
g_signal_connect (bus, "message::error", G_CALLBACK (cb_message_error), NULL);
g_signal_connect (bus, "message::eos", G_CALLBACK (cb_message_eos), NULL);

[..]

  如果您不使用 GLib mainloop,则默认情况下异步消息信号将不可用。但是,您可以安装一个自定义同步处理程序,该处理程序唤醒自定义 mainloop 并使用 gst_bus_async_signal_func() 发出信号。

message type 消息类型:

  GStreamer 有一些可以通过总线传递的预定义消息类型。但是,这些消息是可扩展的。插件可以定义其他消息,应用程序可以决定为这些消息提供特定代码或忽略它们。强烈建议所有应用程序至少通过向用户提供视觉反馈来处理错误消息。

  所有消息都有消息来源、类型和时间戳。消息源可用于查看哪个元素发出了消息。例如,对于某些消息,只有顶级管道发出的消息才会对大多数应用程序感兴趣(例如,对于状态更改通知)。以下是所有消息的列表,以及它们的作用以及如何解析特定于消息的内容的简短说明。

  • Error, warning and info(错误、警告和信息):如果需要向用户展示有关管道状态的消息,element 元素会使用这些消息。错误消息是致命的,会终止数据传递。应修复此错误以恢复管道活动。警告不是致命的,但仍然意味着存在问题。信息消息用于非问题通知。所有这些消息都包含一个 GError,其中包含主要错误类型和消息,以及可选的调试字符串。所有的这些都可以使用 gst_message_parse_error()、gst_message_parse_warning() 和 gst_message_parse_info() 进行提取。使用后,错误字符串和调试字符串都应释放掉。
  • EOS:当流结束时发出此通知。管道的状态不会改变,但进一步的媒体处理将停止。应用程序可以使用它来跳到播放列表中的下一首歌曲。在EOS之后,也可以跳回当前的流的起始位置。然后,会自动继续播放。此消息没有特定的参数。
  • -Tags:在流中找到元数据时发出。对于管道,可以多次发出此消息(例如,一次用于描述性元数据,如艺术家姓名或歌曲名称,另一次用于流信息,如采样率和比特率)。应用程序应在内部缓存元数据。gst_message_parse_tag() 应该用于解析标签列表,当不再需要时,应该gst_tag_list_unref () 来。
  • state-changes:在成功更改状态后发出。 gst_message_parse_state_changed () 可用于解析此转换的旧状态和新状态。
  • Buffering:在缓存网络流期间发出。可以通过从 gst_message_get_structure() 返回的结构中提取 “buffer-percent” 属性,从消息中手动提取进度(以百分比表示)。另请参阅缓冲
  • 元素消息:这些是某些元素独有的特殊消息,通常表示附加功能。元素的文档应详细提及特定元素可以发送哪些元素消息。例如,如果流包含重定向指令,则 'qtdemux' QuickTime 解复用器元素可能会在某些情况下发送 'redirect' 元素消息。
  • 特定于应用程序的消息:可以通过获取消息结构(见上文)并读取其字段来提取有关这些消息的任何信息。通常,可以安全地忽略这些消息。

  应用程序消息主要用于应用程序内部使用,以防应用程序需要将信息从某个线程封送到主线程中。当应用程序使用 element 信号时,这特别有用(因为这些信号将在 streaming thread 的上下文中发出)。

标签:教程,gst,Bus,gstreamer,pipeline,应用程序,消息,bus,message
From: https://www.cnblogs.com/a4234613/p/18386386

相关文章

  • Luma AI,让你的视频像电影一样精彩!附带使用教程
    Luma视频生成API对接说明随着AI的应用变广,各类AI程序已逐渐普及。AI已逐渐深入到人们的工作生活方方面面。而AI涉及的行业也越来越多,从最初的写作,到医疗教育,再到现在的视频。Luma是一个专业高质量的视频生成平台,用户只需上传素材,即可根据不同风格和效果自动生......
  • Clion\+OpenCV(C\+\+版)开发环境配置教程Win/Mac
    合集-环境配置(2)1.最全!嵌入式STM32单片机开发环境配置教学Win/Mac!!!08-282.最简最速!C++版OpenCV安装配置教程Win/Mac!!!08-28收起Clion+OpenCV(C++版)开发环境配置教程Win/Mac平时在学习和比赛的时候都是使用的Python版本的OpenCV,最近遇到了一个项目使用的上位机性能有限于是决定......
  • Windows下安装MySQL详细教程
    Windows下安装MySQL详细教程1、安装包下载  2、安装教程(1)配置环境变量(2)生成data文件(3)安装MySQL(4)启动服务(5)登录MySQL(6)查询用户密码(7)设置修改用户密码(8)退出 3、解决问题1、安......
  • Stable Diffusion 系列教程 - 3 模型下载和LORA模型的小白入门
    前言**首先,一个比较广泛的模型下载地址为黄框是一些过滤器,比如checkpoints可以理解为比如把1.5版本的SD模型拷贝一份后交叉识别新的画风或场景后得到的模型,可以单独拿出来使用。Hypernetwork和lora在特定场景下都非常好用。我们以majicMIXrealistic麦橘写实模型为例子......
  • gstreamer教程(6)——构建应用之Bin的使用
    Bin:bin是一个容器元素。您可以将element元素添加到bin中。由于bin本身就是一个元素,因此bin可以像任何其他元素一样处理。因此,上一章(element)的操作也适用于bin。什么是bin:bin允许您将一组链接起来的元素合并为一个逻辑元素。您不再处理每一个元素,而只处理一......
  • Git使用教程(小白也能看懂)
    git的使用教程(学习和工作中都能用到)1、所需工具gitbash1)安装gitbash官网:https://git-scm.com/download/win2)在文件夹空白处鼠标右键若出现上图说明安装成功2、使用1)我们想要克隆一个新项目1.1进入一个空文件夹右键点击OpenGitBashhere输入以下命令本......
  • DevExpress WinForms中文教程:Data Grid - 如何设置条件格式?
    本文介绍DevExpressWinForms中的Excel样式的条件格式设置,您可以了解最终用户可用的特性,了解可用的格式类型以及如何在设计时或在代码中设置条件格式。P.S:DevExpressWinForms拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForms能完美构......
  • 最简最速!C++版OpenCV安装配置教程Win/Mac!!!
    Clion+OpenCV(C++版)开发环境配置教程Win/Mac        平时在学习和比赛的时候都是使用的Python版本的OpenCV,最近遇到了一个项目使用的上位机性能有限于是决定视觉方面使用C++的OpenCV来节约上位机资源提高运行的速度,在查阅了网上的各种资料后发现这些资料参差不齐......
  • Clion+OpenCV(C++版)开发环境配置教程WinMac
    Clion+OpenCV(C++版)开发环境配置教程Win/Mac        平时在学习和比赛的时候都是使用的Python版本的OpenCV,最近遇到了一个项目使用的上位机性能有限于是决定视觉方面使用C++的OpenCV来节约上位机资源提高运行的速度,在查阅了网上的各种资料后发现这些资料参差不齐有些博......
  • 2024年最新版Typora免费使用教程心得
    在数字化时代,写作已成为我们日常沟通、知识分享的重要手段。然而,繁琐的排版格式常常让人望而却步。幸运的是,Markdown编辑器以其简洁的语法和高效的排版功能,为我们带来了福音。Typora是一款功能强大的文本编辑器,它采用所见即所得的编辑方式,能够让用户快速地编辑各种文本格式,包括Mar......