art vanderlay
art vanderlay

Reputation: 2463

why is gstreamer caps is blocking pipeline

I am trying a basic pipeline below. If I run the pipeline without the caps function it passes straight through (assuming same I/O format). Once I add the caps the pre-roll starts but the video does not continue through to the sink output.

Am I coding this wrong?

thx Art

    #include <gst/gst.h>
#include <glib.h>



static void
on_pad_added (GstElement *element,
              GstPad     *pad,
              gpointer    data)
{
  GstPad *sinkpad;
  GstElement *decoder = (GstElement *) data;

 g_print ("Dynamic pad created, linking out/in \n");

  sinkpad = gst_element_get_static_pad (decoder, "sink");

  gst_pad_link (pad, sinkpad);

  gst_object_unref (sinkpad);
}

int
main (int   argc,
      char *argv[])
{
  GMainLoop *loop;

  gboolean link_ok;

  GstElement *pipeline, *source, *decoder, *ffcs, *vidsc, *capsfout, *sink;
  GstBus *bus;
  GstCaps *caps;


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

  loop = g_main_loop_new (NULL, FALSE);

  /* Create gstreamer elements */
  pipeline = gst_pipeline_new ("video-player");
  source   = gst_element_factory_make ("filesrc",           "file-source");
  decoder  = gst_element_factory_make ("decodebin2",        "dec-bin2");
  ffcs     = gst_element_factory_make ("ffmpegcolorspace",  "ffcs");
  vidsc    = gst_element_factory_make ("videoscale",        "vidsc");
  capsfout = gst_element_factory_make ("capsfilter",        "capsfout");
  sink     = gst_element_factory_make ("filesink",          "vidout");

  if (!pipeline || !source || !decoder || !ffcs || !vidsc || !capsfout || !sink) {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
  }

  /* we set the input/output filename to the source element */
  g_object_set (G_OBJECT (source), "location", argv[1], NULL);
  g_object_set (G_OBJECT (sink), "location", argv[2], NULL);

  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));

  gst_bin_add_many (GST_BIN (pipeline),
                    source, decoder, ffcs, vidsc, capsfout, sink, NULL);


  /* we link the elements together */
   gst_element_link (source, decoder);
   gst_element_link (decoder, ffcs);
   gst_element_link (ffcs, vidsc);

  caps = gst_caps_new_simple("video/x-raw-yuv",
                      "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
                      "width", G_TYPE_INT, 384,
                      "height", G_TYPE_INT, 216,
                      "framerate", GST_TYPE_FRACTION, 25, 1,
                      NULL);

  link_ok = gst_element_link_filtered(vidsc,sink,caps);
  gst_caps_unref (caps);

  if (!link_ok) {
      g_warning ("Failed to link vidsc to sink!");
    }else{
        g_print("seems ok, no error reported?\n");
    }


  /* Set the pipeline to "playing" state*/
  g_print ("Now playing: %s\n", argv[1]);
  gst_element_set_state (pipeline, GST_STATE_PLAYING);


  /* Iterate */
  g_print ("Running...\n");
  g_main_loop_run (loop);


  /* Out of the main loop, clean up nicely */
  g_print ("Returned, stopping playback\n");
  gst_element_set_state (pipeline, GST_STATE_NULL);

  g_print ("Deleting pipeline\n");
  gst_object_unref (GST_OBJECT (pipeline));

  return 0;
}

Upvotes: 3

Views: 2446

Answers (2)

Ely J
Ely J

Reputation: 31

It may be late to answer but you maybe forgot to do the dynamic pad link between some elements and you never call the on_pad_added function. I had the same problem.

Have you tried to add it since then? For example this line to dynamically link two elements instead of the gst_element_link:

g_signal_connect (decoder, "pad-added", G_CALLBACK (on_pad_added), ffcs);

Upvotes: 3

ensonic
ensonic

Reputation: 3450

For what reasons do you need the capsfilter? Only constrain the properties you need. E.g. you set a framerate, but don't have a videorate element before the capsfilter. If you don't care about the framerate (e.g. just want to force a size) remove the framerate from the caps you set on capsfilter..

Upvotes: 1

Related Questions