找回密码
 立即注册
首页 业界区 业界 GStreamer开发笔记(五):gstreamer创建组件、管道和总 ...

GStreamer开发笔记(五):gstreamer创建组件、管道和总线实现简单的播放器

雌鲳签 2025-6-9 10:31:35
前言

  前面是自动构建管道。本篇实例化每个元素并将它们链接在一起来手动构建一个管道。
  本篇创建管道分为:创建组件,连接组件,获取总线,阻塞提取需要的消息并处理。
 Demo

  
1.png

 管道图

  
2.png

  我们创建了两个元素:videotestsrc和autovideosink。不创建过滤元件。因此,管道看起来如下:
  
3.png

 连接源组件和接收组件程序

步骤一:初始化gst

  
4.png

步骤二:创建组件

  
5.png

  使用gst_element_factory_make()创建新组件。第一个参数是要创建的元素类型(默认就有一些常见类型,可通过gstreamer工具获取所有可用类型的列表)。第二个参数是给这个特定实例起的名字。如果没有保留指针,为元素命名对于以后检索它们很有用(并且可以获得更有意义的调试输出)。但是,如果为名称传递NULL,GStreamer将为您提供一个唯一的名称。
  代码创建了两个元素:videotestsrc和autovideosink。不创建过滤元件。因此,管道看起来如下:
  
6.png


  • videotestsrc是一个源组件(它生成数据),用于创建测试视频模式。此元素可用于调试目的,通常在实际应用程序中找不到。
  • autovideosink是一个接收组件(它消耗数据),它在窗口上显示它接收到的图像。根据操作系统的不同,存在几种具有不同功能的视频接收器。autovideosink会自动选择并实例化最佳的一个,因此不必担心细节,并且代码更加独立于平台。
步骤三:创建空管道

  
7.png

  GStreamer中的所有元素通常必须包含在管道中才能使用,因为它负责一些时钟和消息传递功能。我们使用gst_pipeline_new()创建管道。
步骤四:管道连接组件,此处连接:源组件、接收组件

  
8.png

步骤五:修改源组件属性

  
9.png

步骤六:设置组件状态PALYING,开始播放

  
10.png

步骤七:获取bus总线,阻塞函数直至总线触发错误或流结束后继续

  
11.png

步骤八:处理返回消息

  
12.png

步骤九:释放资源

  
13.png

 关键函数

gst_element_factory_make()

  gst_element_factory_make 是 GStreamer 框架中的一个函数,用于创建 GStreamer 元素(Element)。GStreamer 是一个强大的多媒体框架,允许开发者构建媒体处理管道,而元素是这些管道的基本构建块。
  1. GstElement* gst_element_factory_make(const gchar *factoryname, const gchar *name);
复制代码

  • 参数一:要创建的元素的工厂名称。例如,如果想创建一个视频源元素,可以使用 “videotestsrc”
  • 参数二:为创建的元素指定一个名称。如果为NULL,GStreamer 会为该元素自动分配一个唯一的名称。
      成功时:返回指向新创建元素的指针(GstElement*),失败时:返回NULL。
gst_pipeline_new()

  gst_pipeline_new()是GStreamer框架中的一个函数,用于创建一个新的管道(Pipeline)。管道是 GStreamer 中用于连接和管理多个元素的核心结构,它定义了媒体数据从源到接收器的处理路径。
  1. GstElement* gst_pipeline_new(const gchar *name);
复制代码

  • 参数一:为创建的管道指定一个名称。如果为 NULL,GStreamer 会为管道自动分配一个唯一的名称。
      成功时:返回指向新创建管道的指针(GstElement*),实际上是一个GstPipeline 类型的对象,但通常通过 GstElement 指针来引用。失败时:返回NULL。
gst_bin_add_many()

  gst_bin_add_many()是GStreamer框架中的一个函数,用于将多个元素添加到一个GstBin(如GstPipeline)中。GstBin 是一个可以包含其他元素的容器,GstPipeline是GstBin的一种特殊类型,用于管理媒体处理流程。
  1. guint gst_bin_add_many(GstBin *bin, GstElement *element_1, ..., NULL);
复制代码

  • 参数一:指向目标 GstBin 的指针,通常是一个 GstPipeline。
  • 参数二(实际多个):可变参数,GstElement* 类型,要添加到bin中的元素列表,可变参数允许一次添加多个元素,最后一个参数必须是 NULL,以指示参数列表的结束。
      成功时:返回添加的元素数量(不包括最后的NULL)。失败时:如果任何元素无法添加,函数将返回 0,并且不会添加任何元素。
gst_element_link()

  gst_element_link() 是 GStreamer 框架中的一个函数,用于将两个元素链接在一起,以便媒体数据可以在它们之间流动。在 GStreamer 管道中,元素通过“链接”来形成一个处理链,数据从源元素流向接收器元素,经过各种处理步骤。
  1. gboolean gst_element_link(GstElement *src, GstElement *dest);
复制代码

  • 参数一:指向源元素的指针,数据将从该元素流出。
  • 参数二:指向目标元素的指针,数据将流入该元素。
      成功时:返回 TRUE。失败时:返回 FALSE。
 Demo源码
  1. #include <gst/gst.h>
  2. Int main (int argc, char *argv[])
  3. {
  4.     GstElement *pipeline, *source, *sink;
  5.     GstBus *bus;
  6.     GstMessage *msg;
  7.     GstStateChangeReturn ret;
  8.     // 步骤一:初始化gst
  9.     gst_init (&argc, &argv);
  10.     // 步骤二:创建组件
  11.     source = gst_element_factory_make("videotestsrc", "source");
  12.     sink = gst_element_factory_make("autovideosink", "sink");
  13.     // 步骤三:创建空管道
  14.     pipeline = gst_pipeline_new("test-pipeline");
  15.     if(!pipeline || !source || !sink)
  16.     {
  17.         g_printerr("Not all elements could be created.\n");
  18.         return -1;
  19.     }
  20.     // 步骤四:管道连接组件,此处连接:源组件、接收组件
  21.     gst_bin_add_many(GST_BIN(pipeline), source, sink, NULL);
  22.     if(gst_element_link(source, sink) != TRUE)
  23.     {
  24.         g_printerr("Elements could not be linked.\n");
  25.         gst_object_unref(pipeline);
  26.         return -1;
  27.     }
  28.     // 步骤五:修改源组件属性
  29.     g_object_set(source, "pattern", 0, NULL);
  30.     // 步骤六:设置组件状态PALYING,开始播放
  31.     ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
  32.     if(ret == GST_STATE_CHANGE_FAILURE)
  33.     {
  34.         g_printerr("Unable to set the pipeline to the playing state.\n");
  35.         gst_object_unref(pipeline);
  36.         return -1;
  37.     }
  38.     // 步骤七:获取bus总线,阻塞函数直至总线触发错误或流结束后继续
  39.     bus = gst_element_get_bus(pipeline);
  40.     msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
  41.     // 步骤八:处理返回消息
  42.     if(msg != NULL)
  43.     {
  44.         GError *err;
  45.         gchar *debug_info;
  46.         switch(GST_MESSAGE_TYPE(msg))
  47.         {
  48.         case GST_MESSAGE_ERROR:
  49.             gst_message_parse_error(msg, &err, &debug_info);
  50.             g_printerr("Error received from element %s: %s\n",
  51.                         GST_OBJECT_NAME(msg->src),
  52.                         err->message);
  53.             g_printerr("Debugging information: %s\n",
  54.                         debug_info ? debug_info : "none");
  55.             g_clear_error(&err);
  56.             g_free(debug_info);
  57.             break;
  58.         case GST_MESSAGE_EOS:
  59.             g_print("End-Of-Stream reached.\n");
  60.             break;
  61.         default:
  62.             g_printerr("Unexpected message received.\n");
  63.             break;
  64.         }
  65.         gst_message_unref(msg);
  66.     }
  67.     // 步骤九:释放资源
  68.     gst_object_unref(bus);
  69.     gst_element_set_state(pipeline, GST_STATE_NULL);
  70.     gst_object_unref(pipeline);
  71.     return 0;
  72. }
复制代码
 工程模板v1.1.0

  
14.png

 入坑

入坑一:无法连接g_type_check_instace_cast

问题

  未定义库,无法连接
原因

  这是gobject2.0库的
解决

  
15.png


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册