GStreamer应用程序——Pads 和 capabilities(功能)

news2024/12/24 0:21:06

Pads 和 capabilities(功能)

正如我们在元素中看到的,pads是元素与外部世界的接口。来自一个的数据流元素的源pad到另一个元素的接收pad。特定类型的元素可以处理的媒体将被pad暴露能力。我们将在本章后面更多地讨论功能 (参见pad的功能)。

Pads

pad类型由两个属性定义:方向和可用性。正如我们之前提到的,GStreamer定义了两个pad方向:源pad和接收pad。这个术语是从元素内部的角度定义的:元素在其接收pad上接收数据,并在其源pad上生成数据。示意性地,接收pad绘制在元素的左侧,而源pad绘制在元素的右侧。在这样的图表中,数据从左到右流动。[1]

与pad可用性相比,pad方向非常简单。pad可以具有三种可用性中的任何一种:始终、有时和应请求。这三种类型的含义与它所说的完全相同:pad始终存在,有时pad仅在某些情况下存在(并且可以随机消失),应请求pads仅在应用程序明确请求时出现。

动态(或有时)pads

创建元素时,某些元素可能没有所有的pad。例如,这可能发生在Ogg解复用器元素上。当元素在Ogg流中检测到这样的流时,该元素将读取Ogg流并为每个包含的基本流(Vorbis、theora)创建动态pad。同样,当流结束时,它将删除pad。例如,这个原则对于解复用器元素非常有用。

运行gst-inspect-1.0 oggdemux将显示元素只有一个 pad:一个叫做“sink”的sink pad。其他pad是“休眠的”。你可以看到 这在pad模板中,因为有一个“可用性:有时” 属性。根据您播放的Ogg文件类型,pads 将 创建。我们会看到这是非常重要的,当你要去 创建动态管道。您可以将信号处理程序附加到元素 通知您元素何时从其之一创建了一个新pad “有时”pad模板。以下代码是一个示例如何做到这一点:

#include <gst/gst.h>

static void
cb_new_pad (GstElement *element,
        GstPad     *pad,
        gpointer    data)
{
  gchar *name;

  name = gst_pad_get_name (pad);
  g_print ("A new pad %s was created\n", name);
  g_free (name);

  /* here, you would setup a new pad link for the newly created pad */
[..]

}

int
main (int   argc,
      char *argv[])
{
  GstElement *pipeline, *source, *demux;
  GMainLoop *loop;

  /* init */
  gst_init (&argc, &argv);

  /* create elements */
  pipeline = gst_pipeline_new ("my_pipeline");
  source = gst_element_factory_make ("filesrc", "source");
  g_object_set (source, "location", argv[1], NULL);
  demux = gst_element_factory_make ("oggdemux", "demuxer");

  /* you would normally check that the elements were created properly */

  /* put together a pipeline */
  gst_bin_add_many (GST_BIN (pipeline), source, demux, NULL);
  gst_element_link_pads (source, "src", demux, "sink");

  /* listen for newly created pads */
  g_signal_connect (demux, "pad-added", G_CALLBACK (cb_new_pad), NULL);

  /* start the pipeline */
  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
  loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (loop);

[..]

}

仅从管道中添加元素并不少见 “填充添加”回调。如果您这样做,请不要忘记设置 使用管道的目标状态新添加的元素 gst_element_set_state ()gst_element_sync_state_with_parent ()

请求pads

一个元素也可以有请求pads。这些pads不是自动创建的,而是根据需要创建的。这对多路复用器、聚合器和三通元素非常有用。聚合器是将几个输入流的内容合并成一个输出流的元素。三通元素正好相反:它们是具有一个输入流的元素,并将此流复制到它们的每个输出pad上,这些输出pad是根据请求创建的。每当应用程序需要流的另一个副本时,它可以简单地从三通元素请求一个新的输出pad。

以下代码显示了如何从“tee”元素请求新的输出pad:

static void
some_function (GstElement * tee)
{
  GstPad *pad;
  gchar *name;

  pad = gst_element_request_pad_simple (tee, "src%d");
  name = gst_pad_get_name (pad);
  g_print ("A new pad %s was created\n", name);
  g_free (name);

  /* here, you would link the pad */

  /* [..] */

  /* and, after doing that, free our reference */
  gst_object_unref (GST_OBJECT (pad));
}

使用gst_element_request_pad_simple ()方法可以得到一个pad 来自基于pad模板名称的元素。它也是 可以请求与另一个pad模板兼容的pad。 如果您想将元素链接到多路复用器,这将非常有用 元素,您需要请求一个兼容的pad。方法 gst_element_get_compatible_pad ()可用于请求兼容的 pad,如下一个示例所示。它将从来自任何输入的Ogg多路复用器。

static void
link_to_multiplexer (GstPad * tolink_pad, GstElement * mux)
{
  GstPad *pad;
  gchar *srcname, *sinkname;

  srcname = gst_pad_get_name (tolink_pad);
  pad = gst_element_get_compatible_pad (mux, tolink_pad, NULL);
  gst_pad_link (tolink_pad, pad);
  sinkname = gst_pad_get_name (pad);
  gst_object_unref (GST_OBJECT (pad));

  g_print ("A new pad %s was created and linked to %s\n", sinkname, srcname);
  g_free (sinkname);
  g_free (srcname);
}

pad的功能

因为pad在如何查看元素方面起着非常重要的作用通过外部世界,实现了一种机制来描述数据 可以通过使用功能流过或当前流过pad。 在这里,我们将简要描述什么是能力以及如何使用他们,足以理解这个概念。为了深入查看功能和中定义的所有功能的列表 GStreamer,请参阅插件编写器指南

功能附加到pad模板和pad。对于pad模板,它将描述可以流过从该模板创建的pad的媒体类型。对于pad,它可以是可能的上限列表(通常是pad模板功能的副本),在这种情况下,pad尚未协商,或者是当前流过该pad的媒体类型,在这种情况下,pad已经协商过了。

分析能力

pad的功能在GstCaps对象中描述 GstCaps 将包含一个或多个 GstStructure 这将描述一种媒体类型。协商pad将有 只包含一个结构的能力集 结构将只包含固定值。这些约束不是对于未协商的pads或pad模板为真。

例如,下面是“Vorbisdec”功能的转储元素,您将通过运行gst-inspect vorbisdec。你会的看两个pad:一个源pad和一个sink pad。这两个pad总是可用,并且两者都具有附加功能。sink pad将接受Vorbis编码的音频数据,具有媒体类型 “音频/x-Vorbis”。源 pad将用于发送原始(解码) 音频样本到下一个元素,具有原始音频媒体类型(在此案例,“音频/x-原始”)。源pad还将包含以下属性 音频采样率和通道数量,加上更多您暂时不需要担心。

Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:
      audio/x-raw
                 format: F32LE
                   rate: [ 1, 2147483647 ]
               channels: [ 1, 256 ]

  SINK template: 'sink'
    Availability: Always
    Capabilities:
      audio/x-vorbis

属性和值

属性用于描述功能的额外信息。属性由键(字符串)和值组成。可以使用不同的可能值类型:

  • 基本类型,这几乎可以是任何GType注册 Glib。这些属性指示特定的非动态值 这个属性。示例包括:

    • 整数值(G_TYPE_INT):该属性具有以下精确值 值。

    • 布尔值(G_TYPE_BOOLEAN):属性TRUE 或者FALSE

    • 浮点值(G_TYPE_FLOAT):该属性具有以下精确值 浮点值。

    • 字符串值(G_TYPE_STRING):属性包含UTF-8 字符串。

    • 分数值(GST_TYPE_FRACTION):包含一个分数 由整数分子和分母表示。

  • 范围类型是由GStreamer注册的GType,用于指示范围可能的值。它们用于指示允许的音频采样值或支持的视频大小。中定义的两种类型 GStreamer是:

    • 整数范围值(GST_TYPE_INT_RANGE):属性表示可能的整数范围,有一个下限和一个上限 边界。例如,“Vorbisdec”元素有一个速率 可以在8000到50000之间的属性。

    • 浮点范围值(GST_TYPE_FLOAT_RANGE):属性表示一系列可能的浮点值,具有较低的 和一个上边界。

    • 分数范围值(GST_TYPE_FRACTION_RANGE):属性表示一系列可能的分数值,其中包含 上边界。

  • 列表值(GST_TYPE_LIST):属性可以从 此列表中给出的基本值列表。

    示例:表示支持44100 Hz采样率和48000 Hz采样率的上限将使用整数值列表,其中一个值为44100,一个值为48000。

  • 数组值(GST_TYPE_ARRAY):属性是一个数组值。数组中的每个值本身也是一个完整值。所有 数组中的值应该是相同的基本类型。这 意味着数组可以包含整数、列表的任意组合 整数,整数范围在一起,浮点数或 字符串,但它不能同时包含浮点数和整数 时间。

    示例:对于涉及两个以上通道的音频 需要指定通道布局(对于一个和两个通道 音频通道布局是隐式的,除非在 大写)。所以通道布局将是一个整数枚举数组 每个枚举值代表扬声器位置的值。 与GST_TYPE_LIST不同,数组中的值将被解释 作为一个整体。

capabilities(功能)是用来做什么的

功能(简称:caps)描述在两个pads之间流式传输的数据类型,或者一个pad(模板)支持的数据类型。这使得它们对于各种目的非常有用:

  • 自动插拔:根据其功能自动查找链接到pad的元素。所有自动插拔器都使用此方法。

  • 兼容性检测:当两个pad链接时,GStreamer可以验证两个pad是否在谈论相同的媒体类型。链接两个pad并检查它们是否兼容的过程称为“大写协商”。

  • 元数据:通过从pad读取功能,应用程序可以提供有关在pad上流式传输的媒体类型的信息,即有关当前正在播放的流的信息。

  • 过滤:应用程序可以使用功能来限制可能的 可以在两个pad之间流式传输到特定子集的媒体类型 他们支持的流类型。例如,应用程序可以使用 “过滤大写”以设置特定(固定或非固定)视频大小 应该在两个pad之间流动。您将看到一个示例过滤大写在本手册后面的手动向管道添加或删除数据中。 您可以通过将caps filter元素插入到 您的管道并设置其“大写”属性。大写过滤器是通常放置在audio转换器等转换器元素之后, 音频采样、视频转换或视频缩放以强制这些转换器 在某个点将数据转换为特定的输出格式 流。

对元数据使用功能

一个pad可以附加一组(即一个或多个)功能。 能力(GstCaps)表示为一个或多个 GstStructureGstStructure都是一个字段数组,其中 每个字段由一个字段名称字符串(例如“宽度”)和一个类型化的值(例如G_TYPE_INTGST_TYPE_INT_RANGE)。

请注意,有一个明显的差异之间的垫可能的能力(即通常你发现的垫模板的上限,因为他们显示在gst-inspect),允许的上限的pad(可以是相同的pad的模板上限或其子集,取决于对等pad的可能上限)和最后协商的上限(这些描述流或缓冲区的确切格式,只包含一个结构,没有可变位,如范围或列表,即它们是固定的上限)。

您可以通过查询获取一组功能中的属性值 一种结构的单个属性。您可以从 使用gst_caps_get_structure ()和结构数量的大写 GstCaps使用gst_caps_get_size ()

当Caps仅包含一个结构时,Caps称为简单caps;当它们只包含一个结构且没有可变字段类型(如范围或可能值列表)时,将称为固定caps。另外两种特殊类型的caps是ANY caps和empty caps。

以下是如何从一组固定视频caps中提取宽度和高度的示例:

static void
read_video_props (GstCaps *caps)
{
  gint width, height;
  const GstStructure *str;

  g_return_if_fail (gst_caps_is_fixed (caps));

  str = gst_caps_get_structure (caps, 0);
  if (!gst_structure_get_int (str, "width", &width) ||
      !gst_structure_get_int (str, "height", &height)) {
    g_print ("No width/height available\n");
    return;
  }

  g_print ("The video size of this set of capabilities is %dx%d\n",
       width, height);
}

创建过滤功能

虽然功能主要用于插件内部来描述媒体 Pad的类型,应用程序程序员通常也必须拥有对功能的基本了解,以便与插件,尤其是在使用过滤caps时。当你使用过滤 caps或固定caps,您将限制在两个pads之间流动的媒体类型为其支持的媒体类型的子集。你使用管道中的capsfilter元素执行此操作 您还需要创建自己的GstCaps。最简单的方法这是通过使用方便函数gst_caps_new_simple ()

static gboolean
link_elements_with_filter (GstElement *element1, GstElement *element2)
{
  gboolean link_ok;
  GstCaps *caps;

  caps = gst_caps_new_simple ("video/x-raw",
          "format", G_TYPE_STRING, "I420",
          "width", G_TYPE_INT, 384,
          "height", G_TYPE_INT, 288,
          "framerate", GST_TYPE_FRACTION, 25, 1,
          NULL);

  link_ok = gst_element_link_filtered (element1, element2, caps);
  gst_caps_unref (caps);

  if (!link_ok) {
    g_warning ("Failed to link element1 and element2!");
  }

  return link_ok;
}

这将强制两个元素之间的数据流采用特定的视频格式、宽度、高度和帧率(或者,如果无法在涉及的元素上下文中实现这一点,链接将失败)。请记住,当您使用gst_element_link_filtered ()时,它会自动创建一个 capsfilter元素,并将其插入到您的bin或管道中 在您要连接的两个元素之间(如果您曾经想断开这些元素,因为那样你就必须 改为从capsfilter断开两个元素)。

在某些情况下,您会希望创建一组更精细的 过滤两个pads之间链接的功能。然后,这个功能是太简单了,你会想使用方法gst_caps_new_full ()

static gboolean
link_elements_with_filter (GstElement *element1, GstElement *element2)
{
  gboolean link_ok;
  GstCaps *caps;

  caps = gst_caps_new_full (
      gst_structure_new ("video/x-raw",
             "width", G_TYPE_INT, 384,
             "height", G_TYPE_INT, 288,
             "framerate", GST_TYPE_FRACTION, 25, 1,
             NULL),
      gst_structure_new ("video/x-bayer",
             "width", G_TYPE_INT, 384,
             "height", G_TYPE_INT, 288,
             "framerate", GST_TYPE_FRACTION, 25, 1,
             NULL),
      NULL);

  link_ok = gst_element_link_filtered (element1, element2, caps);
  gst_caps_unref (caps);

  if (!link_ok) {
    g_warning ("Failed to link element1 and element2!");
  }

  return link_ok;
}

请参阅API参考以获取完整的API GstStructure 和 GstCaps。

Ghost Pads

你可以看到从可视化的Gstbin元素没有Ghost Pads如何没有自己的Pads。这就是“Ghost Pads”发挥作用的地方。

Ghost Pads是来自bin中某些元素的pad,也可以直接从bin访问。将其与UNIX文件系统中的符号链接进行比较。在bin上使用Ghost Pads,bin也有一个pad,并且可以透明地用作代码其他部分的元素。

带有Ghost Pads的GstBin元素的可视化是Ghost Pads的一个表示。元素一的接收pad现在也是bin的一个pad。由于Ghost Pads在外观和功能上与其他pad无异,它们可以像普通pad一样被添加到任何类型的元素中,而不仅仅是GstBin。

创建Ghost Pads使用的是gst_ghost_pad_new()函数。

#include <gst/gst.h>

int
main (int   argc,
      char *argv[])
{
  GstElement *bin, *sink;
  GstPad *pad;

  /* init */
  gst_init (&argc, &argv);

  /* create element, add to bin */
  sink = gst_element_factory_make ("fakesink", "sink");
  bin = gst_bin_new ("mybin");
  gst_bin_add (GST_BIN (bin), sink);

  /* add ghostpad */
  pad = gst_element_get_static_pad (sink, "sink");
  gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad));
  gst_object_unref (GST_OBJECT (pad));

[..]

}

在上面的例子中,bin现在还有一个pad:给定元素的称为“接收器”的pad。从这里开始,bin可以用作接收器元素的替代品。例如,您可以将另一个元素链接到bin。

  1. 实际上,数据从元素的源pad流向上游(图中此元素左侧)的接收pad并无不可。然而,数据总是会从一个元素的源pad流向另一个元素的接收pad。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1814734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

k8s之包管理器Helm

每个成功的软件平台都有一个优秀的打包系统&#xff0c;比如Debian、Ubuntu 的 apt&#xff0c;RedHat、CentOS 的 yum。Helm 则是 Kubernetes上 的包管理器&#xff0c;方便我们更好的管理应用。 一、Helm 的相关知识 1.1 Helm的简介 在没使用 helm 之前&#xff0c;向 kuber…

中国四大高原矢量示意图分享

我们在《中国地势三级阶梯示意图分享》一文中&#xff0c;为你分享了中国三级阶梯示意图的矢量文件。 现在&#xff0c;我们再为你分享中国四大高原的矢量示意图文件&#xff0c;你可以在文末查看文件的领取方法。 我国四大高原是如何划分的&#xff1f; 中国四大高原分别为…

【十大排序算法】桶排序

在时间的琴弦上&#xff0c;桶排序如同一曲清澈的溪流&#xff0c;将数字的芬芳温柔地分拣&#xff0c;沉静地落入各自的花瓣般的容器中。 文章目录 一、桶排序二、发展历史三、处理流程四、算法实现五、算法特性六、小结推荐阅读 一、桶排序 桶排序&#xff08;Bucket sort&…

组长:你熟悉过React,开发个Next项目模板吧,我:怎么扯上关系的?

最近工作安排我开发一个Next.js项目模板&#xff0c;心里默笑&#xff0c;React用得少得都快忘光了&#xff0c;现在得搞Next&#xff1f;虽然我曾是React的老用户&#xff0c;但转投Vue阵营已久&#xff0c;React的点点滴滴早已一干二净。 不过&#xff0c;挑战归挑战&#x…

【ARM】MDK如何进入\退出debug模式时断点不会消失

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 在对于工程进行调试的情况下&#xff0c;退出debug模式后再次进入&#xff0c;之前设置的断点不会消失。 2、 问题场景 在对于工程进行调试的时候&#xff0c;通常是通过设置断点的方式对于语句进行检测&#xff0…

【启明智显实战指南】SSD202D方案双网口开发板烧录全攻略---从入门到精通

提示&#xff1a;作为Espressif&#xff08;乐鑫科技&#xff09;大中华区合作伙伴及sigmastar&#xff08;厦门星宸&#xff09;VAD合作伙伴&#xff0c;我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考。同时也用心整理了乐鑫及星宸…

游戏试玩站打码zq平台系统可运营的任务网源码

安装说明 1.恢复数据&#xff1b; 2.数据连接库配置路径&#xff1a;protected\config\mail.php 文件中修改第60行 &#xff08;记得不要用记事本修改&#xff0c;否则可能会出现验证码显示不了问题&#xff0c;建议用Notepad&#xff09; 3.浏览器访问输入 127.0.0.2 显示界…

哈尔滨等保测评内容科普

#网络安全等级保护 #哈尔滨等保测评 1. 等保测评的概念 等保测评的全称为“信息安全等级保护测评”。它通过对各个层次的信息系统提供安全保障&#xff0c;从而保证了信息的安全与保密性。 2. 哈尔滨等保测评的意义 随着我国信息化进程的不断推进&#xff0c;网络的信息安…

【学习笔记】C++每日一记[20240612]

给定两个有序的数组&#xff0c;计算两者的交集 给定两个有序整型数组&#xff0c;数组中 的元素是递增的&#xff0c;且各数组中没有重复元素。 第一时间解法&#xff1a;通过一个循环扫描array_1中的每一个元素&#xff0c;然后利用该元素去比较array_2中的每一个元素&…

说说你对Rust的了解?

Rust 是一种系统编程语言&#xff0c;由Mozilla开发&#xff0c;于2010年首次发布。它旨在提供与C和C等低级语言相媲美的性能&#xff0c;同时通过其独特的内存安全保证来避免诸如缓冲区溢出等常见安全问题。Rust的设计哲学融合了现代编程语言的特性&#xff0c;包括内存安全、…

精密结构件核心供应商「东创集团」×企企通启动SRM采购数字化项目,共同驱动供应链价值跃升

导读 此次采购数字化项目上线可有效打通东创集团业务全面信息化的最后一公里&#xff0c;为公司柔性交付提供系统助力。在项目建设阶段&#xff0c;希望各业务关键人员从业务需求出发&#xff0c;设计好蓝图去打通堵点、断点&#xff0c;各相关部门要高度配合&#xff0c;组织…

Java从放弃到继续放弃

并发编程 为什么需要多线程&#xff1f; 由于硬件的发展&#xff0c;CPU的核数增多&#xff0c;如果仍然使用单线程对CPU资源会造成浪费。同时&#xff0c;单线程也会出现阻塞的问题。所以&#xff0c;选择向多线程转变。 多线程的使用使得程序能够并行计算&#xff0c;提高计…

MT2092 水温调节

代码&#xff1a; #include <bits/stdc.h> using namespace std; double t1, t2, x1, x2, t0; double y1, y2, t; double tmax 0x3f3f3f3f, ans1, ans2; int main() {cin >> t1 >> t2 >> x1 >> x2 >> t0;y1 x1, y2 x2; // 初始流速赋最…

提升易用性,OceanBase生态管控产品的“从小到大”

2022年&#xff0c;OceanBase发布4.0版本“小鱼”&#xff0c;并首次公开提出了单机分布式一体化这一理念&#xff0c;旨在适应大小不同规模的工作负载&#xff0c;全面满足用户数据库“从小到大”全生命周期的需求。当时&#xff0c;我们所说的“从小到大”主要聚焦于数据库的…

Stable Diffusion 如何写出更优雅的 Prompt

在看了前面的课程后&#xff0c; 相信很多人都会有一个困惑&#xff0c;这个 prompt 咋写… 为什么我写的时候只能憋出来了一个 a girl, a boy, beautify … 再也想不到其他的了&#xff0c; 总感觉是吃了没文化的亏&#xff1f; 这一节课我们就来讲一讲 如何写好 prompt …

JVM (四)GC过程

一。概述 程序计数器、虚拟机栈、本地方法栈都是随线程生灭&#xff0c;栈帧随着方法的进入和退出做入栈和出栈操作&#xff0c;实现了自动的内存清理&#xff0c;因此&#xff0c;内存垃圾回收主要集中于Java堆和方法区中。 GC整体流程示意图&#xff1a; ① 年轻代对象的移动…

【UE5|水文章】在UMG上显示帧率

参考视频&#xff1a; https://www.youtube.com/watch?vH_NdvImlI68 蓝图&#xff1a;

解决生产问题的万能接口(Java编译器API的使用)

文章目录 前言Tool和ToolProvider编译器工具&#xff1a;JavaCompiler文件管理文件&#xff1a;FileObject文件管理器&#xff1a;JavaFileManager 诊断监听器&#xff1a;DiagnosticDemo&#xff1a;allPowerfulInterface具体实现测试 结语 前言 当生产环境出现问题时&#x…

【大模型应用开发极简入门】提示工程一:1. 通过context、task、role文本结构设计有效的提示词、 2. OpenAI的提示词任务示例

文章目录 一. chat_completion函数二. 设计有效的提示词1.上下文1.1. 更多细节的上下文1.2. 让GPT改进上下文 2.任务2.1. 提供足够的任务信息2.2. OpenAI的任务示例语法纠正总结TL;DR概要Python转自然语言计算时间复杂度修复Python bug产生python函数 3.角色 了解LLM和OpenAI A…

【Linux】基础IO [万字之作]

目录 一.重谈文件 二.重谈C文件操作 1.操作 1.文件的打开和关闭 2.文件的读写操作 ​编辑 1.fgetc函数 2.fputc函数 3.fputs函数 4.fgets函数 5.fprintf函数 6.fscanf函数 7.fread函数 8.fwrite函数 三.重谈当前路径 四.系统文件操作接口 1.Open函数 2.write函数 3…