• Gstreamer中pad的链接


    Gstreamer中的pad根据输入输出方向,有src和sink两种。根据pad创建的时机,有always pad、sometimes pad、request pad,这样不同的pad,链接方式就不同。

    pad相当与element的接口,element间的连接,实质上就是pad间的连接,所以这里总结下pad的链接。

    pad link的分类

    always pad

    • gst_element_link_many,按顺序链接element,元素列表以NULL结尾,链接前要确保已使用gst_bin_add()将element添加到bin或者pipeline里面。

    sometimes pad

    • sometimes pad不能用gst_element_link_many,得在element创建pad后,通过pad-addedsignal触发,调用回调函数才行。

    request pad

    • request pad的链接需要先gst_element_request_pad,获取reqest pad,链接到的目标pad如果是always pad的话可以通过gst_element_get_static_pad获得。然后通过gst_pad_link进行链接。

    filter link

    • gst_element_link_filtered使用给定的caps作为filter caps,将@src链接到@dest, 链接必须从源到目标;该函数查找尚未链接的现有pad。如有必要,它将要求提供新的pad。

    sometimes pad的链接

    初始时没有pad的element(如uridecodebin),pad会在数据流到element时才会创建,这种pad被成为Sometimes Pad,不同于Always Pad,sometimes pad不能通过gst_element_link_many直接将两个element link起来,需要根据pad-added信号,在pad创建后,在对应的回调函数里面链接pad到对应的pad之上才可以。

    参考1

    
      // gst-plugins-good/tests/examples/equalizer/demo.c
      /* Uri decoding */
      decodebin = gst_element_factory_make ("uridecodebin", "decoder");
      g_object_set (G_OBJECT (decodebin), "uri", argv[1], NULL);
    
      /* Force float32 samples */
      decconvert = gst_element_factory_make ("audioconvert", "decconvert");
      /* Handle dynamic pads */
      g_signal_connect (G_OBJECT (decodebin), "pad-added",
          G_CALLBACK (dynamic_link), gst_element_get_static_pad (decconvert, "sink"));
    
    // pad-added的回调函数
    static void
    dynamic_link (GstPadTemplate * templ, GstPad * newpad, gpointer user_data)
    {
      GstPad *target = GST_PAD (user_data);
    
      gst_pad_link (newpad, target);
      gst_object_unref (target);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    参考2

      // subprojects/gst-plugins-good/tests/examples/equalizer/demo.c
      gst_bin_add_many (GST_BIN (bin), decodebin, decconvert, capsfilter, equalizer, spectrum, sinkconvert, sink, NULL);
      if (!gst_element_link_many (decconvert, capsfilter, equalizer, spectrum, sinkconvert, sink, NULL)) {
        fprintf (stderr, "can't link elements\n");
        exit (1);
      }
    
      /* Handle dynamic pads */
      g_signal_connect (G_OBJECT (decodebin), "pad-added",
          G_CALLBACK (dynamic_link), gst_element_get_static_pad (decconvert,
              "sink"));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    实例

    pipeline原型:

    uridecodebin! parsebin ! decodebin
    
    • 1

    代码:

      uridecodebin_ = gst_element_factory_make("uridecodebin", "uridec");
      parsebin_ = gst_element_factory_make("parsebin", "parser");
      decodebin_ = gst_element_factory_make("decodebin", "decodebin");
    
      gst_bin_add_many (GST_BIN(pipeline_), uridecodebin_, parsebin_, decodebin_, NULL);
    
      g_signal_connect (G_OBJECT (uridecodebin_), "pad-added",
          G_CALLBACK (link_uridec_parsebin_cb), gst_element_get_static_pad (parsebin_, "sink"));
    
      g_signal_connect (G_OBJECT (parsebin_), "pad-added",
          G_CALLBACK (link_parsebin_decbin_cb), gst_element_get_static_pad (decodebin_, "sink"));
    
      g_signal_connect (G_OBJECT (parsebin_), "pad-added",
          G_CALLBACK (link_decbin_aconv_cb),
          gst_element_get_static_pad (audioconv_, "sink"));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    下面这样是不行的,因为uridecodebin/parsebin/decodebin都不是awlays pad:

      if (!gst_element_link_many(uridecodebin_, parsebin_, NULL) ||
        !gst_element_link_many(parsebin_, decodebin_, NULL) ||
        !gst_element_link_many(decodebin_, audioconv_, NULL)) {
          GST_ERROR("link many got error");
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    实例request pad的链接

    这段代码可以在gstreamer教程中找到,路径:

    gst-docs/examples/tutorials/basic-tutorial-7.c

    代码:

      /* Manually link the Tee, which has "Request" pads */
      tee_audio_pad = gst_element_request_pad_simple (tee, "src_%u");
      g_print ("Obtained request pad %s for audio branch.\n",
          gst_pad_get_name (tee_audio_pad));
      queue_audio_pad = gst_element_get_static_pad (audio_queue, "sink");
      tee_video_pad = gst_element_request_pad_simple (tee, "src_%u");
      g_print ("Obtained request pad %s for video branch.\n",
          gst_pad_get_name (tee_video_pad));
      queue_video_pad = gst_element_get_static_pad (video_queue, "sink");
      if (gst_pad_link (tee_audio_pad, queue_audio_pad) != GST_PAD_LINK_OK ||
          gst_pad_link (tee_video_pad, queue_video_pad) != GST_PAD_LINK_OK) {
        g_printerr ("Tee could not be linked.\n");
        gst_object_unref (pipeline);
        return -1;
      }
      gst_object_unref (queue_audio_pad);
      gst_object_unref (queue_video_pad);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    实例filter的链接

    搜索gst_element_link_filtered,可以看到源码中很多地方都有用到,比较简单:

      aresample_ = gst_element_factory_make("audioresample", "aresample");
      aconv_ = gst_element_factory_make("audioconvert", "aconv");
    
      GstCaps* filter;
      filter = gst_caps_from_string
      ("audio/x-raw, format=(string)S16LE, rate=(int)16000");
      if(!gst_element_link_filtered(aresample_, aconv_, filter)) {
        GST_ERROR("failed to link audioresample and audioconvert !");
      }
      gst_caps_unref (filter);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

  • 相关阅读:
    Springboot旅游餐饮服务平台r1n3j计算机毕业设计-课程设计-期末作业-毕设程序代做
    搜索与图论 ---- 染色法判定二分图
    JsonUtils
    如何办理软件企业认定证书
    Python实现双目标定、畸变矫正、立体矫正
    12. Java异常及异常处理处理
    Django DRF限流组件
    机器学习(六)构建机器学习模型
    为不同的调制方案设计一个单载波系统(映射器-信道-去映射器)(Matlab代码实现)
    java SE 基础
  • 原文地址:https://blog.csdn.net/hongszh/article/details/128112601