pyVision
A Machine Learning and Signal Processing toolbox

Download .zip Download.tar.gz View on GitHub


Basics of GStreamer - Part 1

Introduction

GStreamer is a framework designed to handle streaming multimedia flows. Media travels from the “source” elements (the producers), down to the “sink” elements (the consumers), passing through a series of intermediate elements performing all kinds of tasks. The set of all the interconnected elements is called a “pipeline”.

The basic construction block of GStreamer are the elements, which process the data as it flows downstream from the source elements (the producers of data) to the sink elements (the consumers of data), passing through filter elements.

In this article we will look at two methods to implement the GStreamer Pipeline.

gst_parse_launch

This function takes a textual representation of a pipeline and turns it into an actual pipeline.This method can be used in case if you are satisfied using basic Gstreamer features .

The ‘gst-launch’ GStreamer utility uses this method to execute GStreamer pipeline.The textual representation of pipelines are passed through command like arguments to the utility.

Lets look at example to play a http://docs.gstreamer.com/media/sintel_trailer-480p.webm video file using GStreamer.

playbin2 Gstreamer Element We will be using Gstreamer element playbin2 in the present example.

playbin2 is a special element which acts as a source and as a sink, and is capable of implementing a whole pipeline. Internally, it creates and connects all the necessary elements to play your media, so you do not have to worry about it.

If figures out how to play the video for you and renders the video . It is one of easiest ways to implement media flow since there is not input from user at all apart from the video file name.However It does not allow the control granularity that a manual pipeline does, but, still, it permits enough customization to suffice for a wide range of applications.

Initialization


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

  • This is the first command in any GStreamer application.
  • The function initializes the GStreamer library by initializing all internal structures , setting up internal path lists, registering built-in elements, and loading standard plugins.

  • The user can pass inputs to GStreamer initialization function via command line options (argv and argc)which can be processed by the gst-init function.

Building Pipeline In this example, we are only passing one parameter to playbin2, which is the URI of the media we want to play


/* Build the pipeline */
  pipeline = gst_parse_launch ("playbin2 uri=http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL);

or

  pipeline = gst_parse_launch ("playbin2 uri=file:/home/pi19404/Downloads/sample.webm", NULL);

Start Playing

Every GStreamer element has an associated state which indicates the mode in which GStreamer element is in. One such state is the GST_STATE_PLAYING.Video playback will only start if the state of the pipeline is set to the PLAYING state.


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

Feedback

If you mistype the URI, or the file does not exist, or you are missing a plug-in, GStreamer provides several notification mechanisms.In this example we will be exiting on error.


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

gst_element_get_bus() retrieves the pipeline’s bus, and gst_bus_timed_pop_filtered() is a blocking call till either ERROR or an EOS (End-Of-Stream) occurs on the bus

The gst_bus_pop_filtered returns a element of type GSTMessage.The GSTMessage can be checked to see if the pipeline has exited because of an error or 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, &err, &debug_info);
      g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
      g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
      g_clear_error (&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);
}

Cleanup We free GStreamer resources gracefully bu setting the pipeline to NULL State before releasing GStreamer objects/references.


/* 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);


Compilation and Execution

The file containing the code is example1.c.We will use gstreamer-0.10

 #compile the commands
gcc example1.c -o example1 `pkg-config --cflags --libs gstreamer-0.10

 #run the program
 ./example1

Verifying the pipeline

The gstreamer also comes with a utility called gst-launch.This utility can be used to verify the textual representation of pipeline by passing it as command line parameter to the utility.This will execute the same function as the above program


gst-launch-0.10 playbin2 uri=file:/home/pi19404/Downloads/sample.webm

Manual Method In GStreamer you usually build the pipeline by manually assembling the individual elements.This is a more complicated method but provides developer with tools for more advanced features and customizations.

The basic construction block of GStreamer are the elements, which process the data as it flows downstream from the source elements (the producers of data) to the sink elements (the consumers of data), passing through filter elements.

enter image description here

In this method instead of specifying a textual representation we create pipeline using GStreamer API function calls.

Element creation

The new GStreamer elements can be created with gst_element_factory_make() The first parameter is the type of element to create and the second parameter is the name we want to give to this particular instance .

The various GStreamer element type can be found in the below link http://docs.gstreamer.com/display/GstSDK/Basic+tutorial+14%3A+Handy+elements


/* Create the elements */

playbin = gst_element_factory_make("playbin2","playbin");


We need to pass paramters to playbin2 gstreamer element

This is done using the function call g_object_set which can be set to set arguments for gstreamer elements


//Create Elemet
playbin   = gst_element_factory_make ("playbin2" ,"playbin");

//Set Parameters
g_object_set (playbin, "uri", "file:/home/pi19404/Downloads/sample.webm", NULL);

Start Playing

As mentioned in the playbin2 element is of GstBin type .This element contains a set of gstreamer elements which realizes a pipeline.Thus to start playing the video we set the playbin2 element to playing state.


/* Start playing */
  ret = gst_element_set_state (playbin, GST_STATE_PLAYING);
  if (ret == GST_STATE_CHANGE_FAILURE) {
    g_printerr ("Unable to set the pipeline to the playing state.\n");
    gst_object_unref (playbin);
    return -1;
  }
   

Feedback

We wait till end of stream or error.We parse the message to check for errors


/* Wait until EOS of error */
  bus = gst_element_get_bus (playbin);
  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, &err, &debug_info);
      g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
      g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
      g_clear_error (&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);
}

Cleanup

And finally the cleanup code to free the resources


 /* Free resources */
  if (msg != NULL)
    gst_message_unref (msg);
  gst_object_unref (bus);
  gst_element_set_state (playbin, GST_STATE_NULL);
  gst_object_unref (playbin);

The file containing the code us example2.c.The compilation command for the same is as below


gcc example2.c -o example2 `pkg-config --cflags --libs gstreamer-0.10` -g

./example2

#Code

The code mentioned in the article can be found in my tutorials github repository at path

  • gst/example1.c
  • gst/example2.c

The webM video files can be found at

  • http://docs.gstreamer.com/media/sintel_trailer-480p.webm
  • http://www.http://pi19404.github.io/pyVision/media/others/sample.webm
blog comments powered by Disqus