title: pad creation and some mistakes on gst_parse_launch
body: <p>I am a newbie to gstreamer and I would like to know if we have to create source and sink pads for convert like video convert in a pipeline. I have a pipeline like this</p>
  
  <pre><code>gst-launch-1.0 v4l2src ! video/x-raw,format=YUY2 !  videoconvert ! xvimagesink
  
  </code></pre>
  
  <p>I am trying to create a simple c application to understand the creation of pads and would like to know if video convert has a source pad and sink pad too. I am creating a source and sink pad for the filter. </p>
  
  <p>EDIT:
  yeah well you see, I tried following the dynamic pipelines example and wrote the code below </p>
  
  <pre><code>#include &lt;gst/gst.h&gt;
  
  
  // easier to pass them as callbacks
  typedef struct _CustomData{
    GstElement *pipeline;
    GstElement *source;
    GstElement *convert;
    GstElement *sink;
  }CustomData;
  
  // callback function
  
  // here src is the v4l2src, newpad is gstpad that has just been added to src element. This is usually the pad to which we want to lnk
  // data is the pointer we provided when attaching to the signal.
  
  static void pad_added_handler(GstElement *src, GstPad *new_pad,CustomData *data)
  {
    g_print("In pad handler\n");
    GstPad *sink_pad = gst_element_get_static_pad(data-&gt;convert, "sink");
    GstPadLinkReturn ret;
    GstCaps *new_pad_caps = NULL;
    GstStructure *new_pad_struct = NULL;
    const gchar *new_pad_type = NULL;
  
    if(gst_pad_is_linked(sink_pad))
      {
        g_print("we are linked. igonring\n");
      }
    // check the new pad types
    // we have previously created a piece of pipeline which deals with videoconvert linked with xvimagesink and we will nto be able to link it to a pad producing video.
    //gst-pad_get_current_caps()- retrieves current capabilities of pad 
      new_pad_caps = gst_pad_get_current_caps(new_pad);
      new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
      new_pad_type = gst_structure_get_name(new_pad_struct);
       g_print ("It has type '%s' which is not raw audio. Ignoring.\n", new_pad_type);
  
       if(!g_str_has_prefix(new_pad_type, "video/x-raw,format=(string)YUY2"))
       {
           g_print("It has new pad type");
        }
  
    // gst_pad_link tries to link two pads . the link must be specified from source to sink and both pads must be owned by elements residing in same pipeline
    ret = gst_pad_link(new_pad, sink_pad);
    if(GST_PAD_LINK_FAILED(ret))
      {
        g_print("type is new_pad_type");
      }
    if(new_pad_caps !=NULL)
      {
        gst_caps_unref(new_pad_caps);
          }
      gst_object_unref(sink_pad);
  }
  
  int main(int argc, char *argv[])
  {
    GMainLoop *loop;
    CustomData data;
      GstBus *bus;
    GstMessage *msg;
    gboolean terminate = FALSE;
    gst_init(&amp;argc, &amp;argv);
    //  loop = g_main_loop_new(NULL, FALSE);
    // create the elements
    data.source = gst_element_factory_make("v4l2src", "source");
    data.convert = gst_element_factory_make("videoconvert", "convert");
    data.sink = gst_element_factory_make("xvimagesink", "sink");
  
    data.pipeline = gst_pipeline_new("new-pipeline");
  
    if(!data.pipeline || !data.source || !data.convert || !data.sink)
      {
        g_printerr("Not all elements could be created\n");
        return -1;
      }
  
    //we did not link source at this point of time, we will do it later
    gst_bin_add_many(GST_BIN(data.pipeline), data.source, data.convert, data.sink, NULL);
    // we link convert element to sink, do not link them with source. we dont have source pads here. so we just have videoconvert-&gt;sink unlinked
    //    gst_element_link(data.source, data.convert);
    if(!gst_element_link( data.convert,data.sink))
      {
        g_printerr("elements could not be linked\n");
        gst_object_unref(data.pipeline);
        return -1;
      }
  
    // we set the device source
    //g_object_set(source, "device", "/dev/video0", NULL);
  
    //connect to pad added signal.
    // we want to attach pad added signal to source element. to do so, we are using g_signal_connect and provide callback function and datapointer.
    // when source element has enough information to start producing data, it will create source pads and trigger the pad added signal. at this point, our callback is called
    g_print("before signal connect\n");
          gint id= g_signal_connect(G_OBJECT(data.source), "pad-added", G_CALLBACK(pad_added_handler), &amp;data );
      g_print("after signal connect with id = %d\n", id);
    //g_signal_connect(G_OBJECT(data.source), "pad-added", G_CALLBACK(handler), &amp;data);
      //   gst_element_link(data.source, data.convert);
       GstStateChangeReturn ret;
    ret =gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
     if (ret == GST_STATE_CHANGE_FAILURE) {
      g_printerr ("Unable to set the pipeline to the playing state.\n");
      gst_object_unref (data.pipeline);
      return -1;
      }
     //   g_main_loop_run(loop);
      /* Listen to the bus */
    bus = gst_element_get_bus (data.pipeline);
    do {
      msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
          GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
  
      /* Parse message */
      if (msg != NULL) {
        GError *err;
        gchar *debug_info;
  
        switch (GST_MESSAGE_TYPE (msg)) {
          case GST_MESSAGE_ERROR:
            gst_message_parse_error (msg, &amp;err, &amp;debug_info);
            g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg-&gt;src), err-&gt;message);
            g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
            g_clear_error (&amp;err);
            g_free (debug_info);
            terminate = TRUE;
            break;
          case GST_MESSAGE_EOS:
            g_print ("End-Of-Stream reached.\n");
            terminate = TRUE;
            break;
          case GST_MESSAGE_STATE_CHANGED:
            /* We are only interested in state-changed messages from the pipeline */
            if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data.pipeline)) {
              GstState old_state, new_state, pending_state;
              gst_message_parse_state_changed (msg, &amp;old_state, &amp;new_state, &amp;pending_state);
              g_print ("Pipeline state changed from %s to %s:\n",
                  gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));
            }
            break;
          default:
            /* We should not reach here */
            g_printerr ("Unexpected message received.\n");
            break;
        }
        gst_message_unref (msg);
      }
    } while (!terminate);
  
    /* Free resources */
    gst_object_unref (bus);
  
    gst_element_set_state(data.pipeline, GST_STATE_NULL);
    gst_object_unref(data.pipeline);
    return 0;
  }
  
  </code></pre>
  
  <p>and it gave me an error </p>
  
  <pre><code>before signal connect
  after signal connect with id = 1
  Pipeline state changed from NULL to READY:
  Pipeline state changed from READY to PAUSED:
  Error received from element source: Internal data stream error.
  Debugging information: gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:new-pipeline/GstV4l2Src:source:
  streaming stopped, reason not-linked (-1)
  </code></pre>
  
  <p>(The above code works if I write gst_elements_link(data.source, data.convert) after the element link statement for convert and sink)</p>
  
  <p>So I tried the normal way in which I just added and linked all the elements together and it began to work without use of the pads.</p>
  
  <pre><code>#include &lt;gst/gst.h&gt;
  
  int main(int argc, char *argv[])
  {
    GstElement *pipeline, *source, *convert, *sink;
    GstBus *bus;
    GstMessage *msg;
  
    gst_init(&amp;argc, &amp;argv);
  
    source = gst_element_factory_make("v4l2src", "source");
    convert = gst_element_factory_make("nvvidconv", "convert");
    sink = gst_element_factory_make("xvimagesink", "sink");
  
    pipeline = gst_pipeline_new("pipe");
  
    gst_bin_add_many(GST_BIN(pipeline), source,convert,sink, NULL);
    gst_element_link_many(source,convert,sink,NULL);
    gst_element_set_state(pipeline,GST_STATE_PLAYING);
  
  
  
  bus = gst_element_get_bus (pipeline);
    msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
  
    /* Parse message */
    if (msg != NULL) {
      GError *err;
      gchar *debug_info;
  
      switch (GST_MESSAGE_TYPE (msg)) {
        case GST_MESSAGE_ERROR:
          gst_message_parse_error (msg, &amp;err, &amp;debug_info);
          g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg-&gt;src), err-&gt;message);
          g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
          g_clear_error (&amp;err);
          g_free (debug_info);
          break;
        case GST_MESSAGE_EOS:
          g_print ("End-Of-Stream reached.\n");
          break;
        default:
          /* We should not reach here because we only asked for ERRORs and EOS */
          g_printerr ("Unexpected message received.\n");
          break;
      }
      gst_message_unref (msg);
    }
  
    /* Free resources */
    gst_object_unref(bus);
  
    gst_element_set_state(pipeline,GST_STATE_NULL);
    gst_object_unref(pipeline);
  
  }
  </code></pre>
  
  <p>But, inorder to fully grasp the knowledge of pads, I wanted to execute simpler pipelines with pads. 
  I just don't fully understand the usage of pads and link them and all. </p>
  
  <p>EDIT2: </p>
  
  <p>Ultimately I want to write application for pipeline like this which works on command line perfectly well,</p>
  
  <pre><code>gst-launch-1.0 v4l2src device='/dev/video0' ! 'video/x-raw,format=(string)YUY2,width=(int)640,height=(int)480' ! nvvidconv ! 'video/x-raw(memory:NVMM),format=(string)NV12,width=(int)640,height=(int)480' ! nvvidconv ! 'video/x-raw,format=(string)NV12,width=(int)640,height=(int)480' ! nvvideoconvert ! 'video/x-raw(memory:NVMM),format=(string)NV12,width=(int)640,height=(int)480' ! mux.sink_0 nvstreammux live-source=1 name=mux batch-size=1 width=640 height=480 ! nvinfer config-file-path=/opt/nvidia/deepstream/deepstream-4.0/sources/apps/sample_apps/deepstream-test1/dstest1_pgie_config.txt batch-size=1 ! nvmultistreamtiler rows=1 columns=1 width=640 height=480 ! nvvideoconvert ! nvdsosd ! nvegltransform ! nveglglessink sync=false -v
  </code></pre>
  
  <p>But as I don't understand the usage of both pads and bins, I am unable to implement them in my above pipeline. However, I tried this,</p>
  
  <pre><code>#include &lt;gst/gst.h&gt;
  #include &lt;glib.h&gt;
  #include &lt;stdio.h&gt;
  #include "gstnvdsmeta.h"
  
  
  #define MAX_DISPLAY_LEN 64
  
  #define PGIE_CLASS_ID_VEHICLE 0
  #define PGIE_CLASS_ID_PERSON 2
  
  gint frame_number = 0;
  gchar pgie_classes_str[4][32] = { "Vehicle", "TwoWheeler", "Person",
    "Roadsign"
  };
  
  
  static GstPadProbeReturn osd_sink_pad_buffer_probe(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
  {
    GstBuffer *buf=(GstBuffer *)info-&gt;data;
    guint num_rects =0;
    NvDsObjectMeta *obj_meta = NULL;
      guint vehicle_count = 0;
      guint person_count = 0;
      NvDsMetaList * l_frame = NULL;
      NvDsMetaList * l_obj = NULL;
      NvDsDisplayMeta *display_meta = NULL;
  
      NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);
  
      for (l_frame = batch_meta-&gt;frame_meta_list; l_frame != NULL;
        l_frame = l_frame-&gt;next) {
          NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame-&gt;data);
          int offset = 0;
          for (l_obj = frame_meta-&gt;obj_meta_list; l_obj != NULL;
                  l_obj = l_obj-&gt;next) {
              obj_meta = (NvDsObjectMeta *) (l_obj-&gt;data);
              if (obj_meta-&gt;class_id == PGIE_CLASS_ID_VEHICLE) {
                  vehicle_count++;
                  num_rects++;
              }
              if (obj_meta-&gt;class_id == PGIE_CLASS_ID_PERSON) {
                  person_count++;
                  num_rects++;
              }
          }
          display_meta = nvds_acquire_display_meta_from_pool(batch_meta);
          NvOSD_TextParams *txt_params  = &amp;display_meta-&gt;text_params[0];
          display_meta-&gt;num_labels = 1;
          txt_params-&gt;display_text = g_malloc0 (MAX_DISPLAY_LEN);
          offset = snprintf(txt_params-&gt;display_text, MAX_DISPLAY_LEN, "Person = %d ", person_count);
          offset = snprintf(txt_params-&gt;display_text + offset , MAX_DISPLAY_LEN, "Vehicle = %d ", vehicle_count);
  
          /* Now set the offsets where the string should appear */
          txt_params-&gt;x_offset = 10;
          txt_params-&gt;y_offset = 12;
  
          /* Font , font-color and font-size */
          txt_params-&gt;font_params.font_name = "Serif";
          txt_params-&gt;font_params.font_size = 10;
          txt_params-&gt;font_params.font_color.red = 1.0;
          txt_params-&gt;font_params.font_color.green = 1.0;
          txt_params-&gt;font_params.font_color.blue = 1.0;
          txt_params-&gt;font_params.font_color.alpha = 1.0;
  
          /* Text background color */
          txt_params-&gt;set_bg_clr = 1;
          txt_params-&gt;text_bg_clr.red = 0.0;
          txt_params-&gt;text_bg_clr.green = 0.0;
          txt_params-&gt;text_bg_clr.blue = 0.0;
          txt_params-&gt;text_bg_clr.alpha = 1.0;
  
          nvds_add_display_meta_to_frame(frame_meta, display_meta);
      }
  
      g_print ("Frame Number = %d Number of objects = %d "
              "Vehicle Count = %d Person Count = %d\n",
              frame_number, num_rects, vehicle_count, person_count);
      frame_number++;
      return GST_PAD_PROBE_OK;
  
  }
  
  int main(int argc, char *argv[])
  {
     GstElement *pipeline,  *source, *filter1, *convert,*filter2, *filter3, *vidconv, *filter4, *mux, *infer, *tiler, *osd, *transform , *sink, *bin, *convert2 , *vidconv2;
     GMainLoop *loop;
     GstCaps *caps1, *caps2, *caps3, *caps4;
     GstPad *osd_sink_pad =NULL, *srcpad, *sinkpad;
  
  
     loop = g_main_loop_new(NULL,FALSE);
     gst_init(&amp;argc, &amp;argv);
     pipeline = gst_pipeline_new("nv_pipeline");
     gchar *string1 = "video/x-raw(memory:NVMM),format=(string)NV12";
  
     source = gst_element_factory_make("v4l2src", "source");
     filter1 = gst_element_factory_make("capsfilter", "filter1");
     convert = gst_element_factory_make("nvvidconv", "convert");
     filter2 = gst_element_factory_make("capsfilter", "filter2");
     filter3 = gst_element_factory_make("capsfilter", "filter3");
     filter4 = gst_element_factory_make("capsfilter", "filter4");
     vidconv = gst_element_factory_make("nvvideoconvert", "vidconv");
     mux = gst_element_factory_make("nvstreammux", "mux");
     infer = gst_element_factory_make("nvinfer", "infer");
     tiler = gst_element_factory_make("nvmultistreamtiler", "tiler");
     osd = gst_element_factory_make("nvosd", "osd");
     transform = gst_element_factory_make("nvegltransform", "transform");
     sink = gst_element_factory_make("nveglglessink", "sink");
     convert2 = gst_element_factory_make("nvvidconv", "convert2");
     vidconv2 = gst_element_factory_make("nvvideoconvert", "vidconv2");
  
     gst_bin_add_many(GST_BIN(pipeline), source,filter1,convert,filter2, convert2,filter3,vidconv, filter4,mux,infer, tiler,vidconv2, osd,transform,sink,NULL);
  
     gst_element_link_many(source,filter1,convert,filter2, convert2,filter3, vidconv, filter4,mux,infer, tiler,vidconv2, osd,transform,sink,NULL);
  
     osd_sink_pad = gst_element_get_static_pad(osd, "sink");
     gst_pad_add_probe(osd_sink_pad, GST_PAD_PROBE_TYPE_BUFFER, osd_sink_pad_buffer_probe, NULL, NULL);
  
     caps1 = gst_caps_new_simple("video/x-raw", "format",G_TYPE_STRING,"YUY2",NULL);
     caps2 = gst_caps_from_string(string1);
     caps3 = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING,"NV12", NULL);
     caps4 = gst_caps_from_string(string1);
  
     g_object_set(G_OBJECT(filter1), "caps", caps1, NULL);
     g_object_set(G_OBJECT(filter2), "caps", caps2, NULL);
     g_object_set(G_OBJECT(filter3), "caps", caps3, NULL);
     g_object_set(G_OBJECT(filter4), "caps", caps4, NULL);
  
     g_object_set(G_OBJECT(mux), "live-source", 1, "name", "mux", "batch-size", 1, "width", 1280, "height", 720, NULL);
     g_object_set(G_OBJECT(infer), "config-file-path","/opt/nvidia/deepstream/deepstream-4.0/sources/apps/sample_apps/deepstream-test1/dstest1_pgie_config.txt",NULL);
     g_object_set(G_OBJECT(infer), "batch-size", 1, NULL);
     g_object_set(G_OBJECT(tiler), "rows", 1, "columns", 1, "width", 1280, "height", 720, NULL);
  
     gst_caps_unref(caps1);
     gst_caps_unref(caps2);
     gst_caps_unref(caps3);
     gst_caps_unref(caps4);
  
     gst_element_set_state(pipeline, GST_STATE_PLAYING);
     g_print("Running ...\n");
     g_main_loop_run(loop);
  
     gst_element_set_state(pipeline,GST_STATE_NULL);
     gst_object_unref(pipeline);
     return 0;
  }
  
  </code></pre>
  
  <p>which gives the exact same output as the command line gst-launch-1.0 like,</p>
  
  <pre><code>(deep_pads:15648): GLib-GObject-WARNING **: 11:29:18.761: cannot register existing type 'GstInterpolationMethod'
  
  (deep_pads:15648): GLib-GObject-CRITICAL **: 11:29:18.761: g_param_spec_enum: assertion 'G_TYPE_IS_ENUM (enum_type)' failed
  
  (deep_pads:15648): GLib-GObject-CRITICAL **: 11:29:18.761: validate_pspec_to_install: assertion 'G_IS_PARAM_SPEC (pspec)' failed
  
  (deep_pads:15648): GStreamer-CRITICAL **: 11:29:18.814: gst_element_get_static_pad: assertion 'GST_IS_ELEMENT (element)' failed
  
  (deep_pads:15648): GStreamer-CRITICAL **: 11:29:18.814: gst_pad_add_probe: assertion 'GST_IS_PAD (pad)' failed
  0:00:00.843318172 15648   0x5591be52c0 INFO                 nvinfer gstnvinfer.cpp:519:gst_nvinfer_logger:&lt;infer&gt; NvDsInferContext[UID 1]:initialize(): Trying to create engine from model files
  0:00:20.693301580 15648   0x5591be52c0 INFO                 nvinfer gstnvinfer.cpp:519:gst_nvinfer_logger:&lt;infer&gt; NvDsInferContext[UID 1]:generateTRTModel(): Storing the serialized cuda engine to file at /opt/nvidia/deepstream/deepstream-4.0/samples/models/Primary_Detector/resnet10.caffemodel_b1_int8.engine
  
  </code></pre>
  
  <p>except It doesn't display an output window from the above c application and doesn't display the rest. </p>