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
andargc
)which can be processed by thegst-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.
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