【Gstreamer 23】播放教程7:自定义playbin接收器

官网地址

Playback tutorial 7: Custom playbin sinks

一、目标

       通过手动选择其音频和视频接收器,可以进一步定制playbin。这允许应用程序依赖playbin检索和解码媒体,然后自行管理最终的渲染/显示。本教程展示了:

  • 如何替换playbin选择的接收器。
  • 如何使用复杂的管道作为接收器。

二、介绍

       playbin有两个属性允许选择所需的音频和视频接收器:分别是audio-sink和video-sink。应用程序只需要实例化适当的GstElement并通过这些属性传递给playbin即可。

       然而,这种方法只允许使用单个元素作为接收器。如果需要更复杂的管道,例如,一个均衡器加上一个音频接收器,则需要将其封装在一个Bin中,这样对于playbin来说,它看起来就像是一个单一的元素。

       Bin(GstBin)是一种容器,用于封装部分管道以便将其作为一个单一元素进行管理。例如,我们在所有教程中使用的GstPipeline就是一种不与外部元素交互的GstBin。Bin内的元素通过Ghost Pads(GstGhostPad)连接到外部元素,也就是说,位于Bin表面的Pads简单地将数据从外部Pad转发到内部元素的特定Pad上。

图1:包含两个元素和一个Ghost Pad的Bin。

      GstBin也是一种GstElement,因此可以在任何需要元素的地方使用它们,特别是作为playbin的接收器(这时它们被称为sink-bins)。

三、一个带有均衡器的播放器

将这些代码复制到一个名为playback-tutorial-7.c的文本文件中。

playback-tutorial7.c

#include <gst/gst.h>

int main(int argc, char *argv[]) {
  GstElement *pipeline, *bin, *equalizer, *convert, *sink;
  GstPad *pad, *ghost_pad;
  GstBus *bus;
  GstMessage *msg;

  /* Initialize GStreamer */
  gst_init (&argc, &argv);

  /* Build the pipeline */
  pipeline = gst_parse_launch ("playbin uri=https://gstreamer.freedesktop.org/data/media/sintel_trailer-480p.webm", NULL);

  /* Create the elements inside the sink bin */
  equalizer = gst_element_factory_make ("equalizer-3bands", "equalizer");
  convert = gst_element_factory_make ("audioconvert", "convert");
  sink = gst_element_factory_make ("autoaudiosink", "audio_sink");
  if (!equalizer || !convert || !sink) {
    g_printerr ("Not all elements could be created.\n");
    return -1;
  }

  /* Create the sink bin, add the elements and link them */
  bin = gst_bin_new ("audio_sink_bin");
  gst_bin_add_many (GST_BIN (bin), equalizer, convert, sink, NULL);
  gst_element_link_many (equalizer, convert, sink, NULL);
  pad = gst_element_get_static_pad (equalizer, "sink");
  ghost_pad = gst_ghost_pad_new ("sink", pad);
  gst_pad_set_active (ghost_pad, TRUE);
  gst_element_add_pad (bin, ghost_pad);
  gst_object_unref (pad);

  /* Configure the equalizer */
  g_object_set (G_OBJECT (equalizer), "band1", (gdouble)-24.0, NULL);
  g_object_set (G_OBJECT (equalizer), "band2", (gdouble)-24.0, NULL);

  /* Set playbin's audio sink to be our sink bin */
  g_object_set (GST_OBJECT (pipeline), "audio-sink", bin, NULL);

  /* Start playing */
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* Wait until error or EOS */
  bus = gst_element_get_bus (pipeline);
  msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);

  /* Free resources */
  if (msg != NULL)
    gst_message_unref (msg);
  gst_object_unref (bus);
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_object_unref (pipeline);
  return 0;
}

Linux 安装库(Install GStreamer on Ubuntu or Debian)

apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio

其他的系统看官网教程。

Installing on Mac OS X

执行编译

gcc playback-tutorial-7.c -o playback-tutorial-7 `pkg-config --cflags --libs gstreamer-1.0`

必需的库:gstreamer-1.0

四、代码解析

/* Create the elements inside the sink bin */
equalizer = gst_element_factory_make ("equalizer-3bands", "equalizer");
convert = gst_element_factory_make ("audioconvert", "convert");
sink = gst_element_factory_make ("autoaudiosink", "audio_sink");
if (!equalizer || !convert || !sink) {
  g_printerr ("Not all elements could be created.\n");
  return -1;
}

       我们实例化了组成sink-bin的所有元素。这里使用了一个equalizer-3bands和一个autoaudiosink,并在它们之间加入了一个audioconvert,因为我们不确定音频接收器的能力(因为这些能力依赖于硬件)。

/* Create the sink bin, add the elements and link them */
bin = gst_bin_new ("audio_sink_bin");
gst_bin_add_many (GST_BIN (bin), equalizer, convert, sink, NULL);
gst_element_link_many (equalizer, convert, sink, NULL);

     这将新元素添加到Bin中,并像处理管道一样链接它们。

pad = gst_element_get_static_pad (equalizer, "sink");
ghost_pad = gst_ghost_pad_new ("sink", pad);
gst_pad_set_active (ghost_pad, TRUE);
gst_element_add_pad (bin, ghost_pad);
gst_object_unref (pad);

       现在我们需要创建一个Ghost Pad,以便Bin内部的部分管道可以连接到外部。这个Ghost Pad将连接到内部元素中的一个Pad(这里是均衡器的sink pad),所以我们使用gst_element_get_static_pad()获取这个Pad。记住,如果这是一个请求Pad而不是始终存在的Pad,我们将需要使用gst_element_request_pad()。

     Ghost Pad通过gst_ghost_pad_new()创建(指向我们刚刚获得的内部Pad),并通过gst_pad_set_active()激活。然后它通过gst_element_add_pad()添加到Bin中,转移Ghost Pad的所有权给Bin,因此我们不需要担心释放它。

    最后,从均衡器获得的sink Pad需要用gst_object_unref()释放。

    此时,我们有了一个功能性的sink-bin,可以用作playbin中的音频接收器。只需要指示playbin使用它:

/* Set playbin's audio sink to be our sink bin */
g_object_set (GST_OBJECT (pipeline), "audio-sink", bin, NULL);

   只需简单地将playbin的audio-sink属性设置为新创建的sink即可。

/* Configure the equalizer */
g_object_set (G_OBJECT (equalizer), "band1", (gdouble)-24.0, NULL);
g_object_set (G_OBJECT (equalizer), "band2", (gdouble)-24.0, NULL);

       剩下的唯一工作是配置均衡器。在这个例子中,两个较高频率段被设置为最大衰减,以增强低音效果。尝试调整这些值以感受不同(查看equalizer-3bands元素的文档以了解允许的值范围)。

五、练习

       构建一个视频bin而不是音频bin,使用GStreamer提供的许多有趣视频滤镜之一,如solarize、vertigotv或effectv插件中的任何元素。如果由于不兼容的caps导致管道无法链接,请记得使用颜色空间转换元素videoconvert。

六、结论

本教程展示了:

  • 如何使用audio-sink和video-sink属性为playbin设置自己的接收器。
  • 如何将一段管道封装进GstBin中,以便作为playbin的sink-bin使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值