DLI course on DeepStream SDK: Pad Question

Full disclosure, I’m not a programming whiz, but I really want to learn DeepStream. I’ve got my nano and media player all set up, and have been able to compile and run the demos, so everything’s working. But I don’t really understand, in the first example, deepstream_test1_app.c, how the elements are “connected”.

The design itself consists of 13 GstElements:

*pipeline = NULL,
*source = NULL,
*h264parser = NULL,
*decoder = NULL,
*streammux = NULL,
*sink = NULL,
*pgie = NULL,
*nvvidconv = NULL,
*nvosd = NULL,
*encoder = NULL,
*rtppay = NULL,
*transform = NULL,
*cap_filter = NULL;

From the documentation I would expect each of them to have a sink and a source. But the code only puts a sinkpad and srcpad on the streammux and decoder. Why just those two elements?

Then it links the elements together in two different gst_element_link_many function calls. Why not just do one?

I surfed the Gstreamer documentation, but I’m still confused. Any guidance is greatly appreciated.

Here’s the two relevant blocks of code.

Note there’s only two pads:

gst_bin_add_many (GST_BIN (pipeline),
      source, h264parser, decoder, streammux, pgie,
      nvvidconv, nvosd, transform, cap_filter, encoder, rtppay, sink, NULL);

  GstPad *sinkpad, *srcpad;
  gchar pad_name_sink[16] = "sink_0";
  gchar pad_name_src[16] = "src";

  sinkpad = gst_element_get_request_pad (streammux, pad_name_sink);
  if (!sinkpad) {
    g_printerr ("Streammux request sink pad failed. Exiting.\n");
    return -1;
  }

  srcpad = gst_element_get_static_pad (decoder, pad_name_src);
  if (!srcpad) {
    g_printerr ("Decoder request src pad failed. Exiting.\n");
    return -1;
  }

  if (gst_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK) {
      g_printerr ("Failed to link decoder to stream muxer. Exiting.\n");
      return -1;
  }

  gst_object_unref (sinkpad);
  gst_object_unref (srcpad);

And here’s where it’s linking two gropus, instead of one big group.

if (!gst_element_link_many (source, h264parser, decoder, NULL)) {
    g_printerr ("Elements could not be linked: 1. Exiting.\n");
    return -1;
  }

  if (!gst_element_link_many (streammux, pgie,
      nvvidconv, nvosd, transform, cap_filter, encoder, rtppay, sink, NULL)) {
    g_printerr ("Elements could not be linked: 2. Exiting.\n");
    return -1;
  }

Hi,

From the documentation I would expect each of them to have a sink and a source. But the code only puts a sinkpad and srcpad on the streammux and decoder. Why just those two elements?
sink and source are GStreamer elements.
Sinkpad and srcpad are the element’s interface to the outside world, e.g. other elements.
For streammux and decoder, the sample calls gst_element_get_request_pad() and gst_element_get_static_pad() to get pads and link them. You can refer to https://gstreamer.freedesktop.org/documentation/application-development/basics/pads.html?gi-language=c#request-pads, the sample requests the pad dynamically according to the attributes.

Then it links the elements together in two different gst_element_link_many function calls. Why not just do one?
Do you mean below code? As you can, the 2nd gst_element_link_many() is called according to the platform (Jetson or x86+dGPU).

if (!gst_element_link_many (source, h264parser, decoder, NULL)) {
    g_printerr ("Elements could not be linked: 1. Exiting.\n");
    return -1;
  }

#ifdef PLATFORM_TEGRA
  if (!gst_element_link_many (streammux, pgie,
      nvvidconv, nvosd, transform, sink, NULL)) {
    g_printerr ("Elements could not be linked: 2. Exiting.\n");
    return -1;
  }
#else
  if (!gst_element_link_many (streammux, pgie,
      nvvidconv, nvosd, sink, NULL)) {
    g_printerr ("Elements could not be linked: 2. Exiting.\n");
    return -1;
  }
#endif

Sorry! Missed you update 17 minutes before. Which DeepStream package are you referring to?

It’s deepstream_sdk_v4.0.2_jetson, the one that is part of the DeepStream DLI training. Running on the Jetson Nano.

https://courses.nvidia.com/courses/course-v1:DLI+C-IV-02+V1/course/

As stated in https://gstreamer.freedesktop.org/documentation/gstreamer/gstpad.html?gi-language=c

After two pads are retrieved from an element by gst_element_get_static_pad, the pads can be linked with gst_pad_link. (For quick links, you can also use gst_element_link, which will make the obvious link for you if it’s straightforward.). Pads can be unlinked again with gst_pad_unlink. gst_pad_get_peer can be used to check what the pad is linked to.

So, since decoder and streammux are linked by gst_pad_link(), you can’t link them again by gst_element_link_many(), so it breaks into two gst_element_link_many().

Thank you for your reply and I know I’m being very dense but my bigger question is “why”? That is, “why” do we need pads between decoder and streammux when we don’t need pads between any of the other elements?

Ok, maybe I didn’t make it clear enough in previous comments. streammux plugin manages the batch buffers for following processing, which buffer size depends on the input height and width, so the pad of streammux is not created automatically as other elements but are only created according to the input height and width, so we need request the pad(sinkpad) and then connect it to srcpad.