Gstreamer was buzzing around the town with a loud and good noise.Nearby folks like stagefright, open core were making their stand strong for not getting replaced by the Gstreamer.While the cold war was going on I decided to take on the gstreamer tyranny in the Multimedia World .
Here is how I planned my Gstreamer knowledge sabotage.I decided I will not waste time(not so derogatory here for a software like gstreamer) much on reading the manuals and documentation.Even If I do I will hit straight to the points which makes me understand the gstreamer concepts.
So I started to follow this plan :
- Reading the Manuals and documentation- especially
GStreamer Plugin Writer's Guide and
GStreamer Application Development Manual .This was the toughest part, required lot of patience to sit and roll your eyes all over the screen to read the manuals and user guide documentation.
- Read the mailing list on gstreamer site - gstreamer-devel ,
- Following stack overflow on whatever I though is doubtful for me.I wanted to earn reputation as well on
SO so a dual greedy motive behind this.I read most of the
Gstreamer Tagged Question and posted few as well.I followed people with good reputation on the Gstreamer tags and they even replied most of my questions.
-After going though the Gstreamer manuals and User Guides , I decided to read the
Application's source codes being written with the Gstreamer.
- Ok Now enough of reading the manuals and Documentations and goitn though the source codes I decided to contribute (no matter even if i contribute to the review comments of the
Gstreamer Modules) to the
Gstreamer code.So for this I joined the github,sourceforgenet and watched teh gstreamer based projects ............<under construction >
While i was studying the Gstreamer i decided to make the note(which I intended to take the form of Tutorials) so I decide to jot down my understanding on the Gstreamer.
I found few good people and really really good questions.I not only read them but also contacted them on LinkedIN
People like
Felipe Contreras and their work gave me insight on whats currently going in the Gstreamer Field.
Following are the good links I came across : ............<under construction >
I started with the simple hello world pro-gramme given in the Gstreamer manual :
Here is the code for it :
#include <gst/gst.h>
#include <glib.h>
static gboolean
bus_call (GstBus *bus,
GstMessage *msg,
gpointer data)
{
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS:
g_print ("End of stream\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_ERROR: {
gchar *debug;
GError *error;
gst_message_parse_error (msg, &error, &debug);
g_free (debug);
g_printerr ("Error: %s\n", error->message);
g_error_free (error);
g_main_loop_quit (loop);
break;
}
default:
break;
}
return TRUE;
}
static void
on_pad_added (GstElement *element,
GstPad *pad,
gpointer data)
{
GstPad *sinkpad;
GstElement *decoder = (GstElement *) data;
/* We can now link this pad with the vorbis-decoder sink pad */
g_print ("Dynamic pad created, linking demuxer/decoder\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;
GstElement *pipeline, *source, *demuxer, *decoder, *conv, *sink;
GstBus *bus;
/* Initialisation */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* Check input arguments */
if (argc != 2) {
g_printerr ("Usage: %s <Ogg/Vorbis filename>\n", argv[0]);
return -1;
}
/* Create gstreamer elements */
pipeline = gst_pipeline_new ("audio-player");
source = gst_element_factory_make ("filesrc", "file-source");
demuxer = gst_element_factory_make ("oggdemux", "ogg-demuxer");
decoder = gst_element_factory_make ("vorbisdec", "vorbis-decoder");
conv = gst_element_factory_make ("audioconvert", "converter");
sink = gst_element_factory_make ("autoaudiosink", "audio-output");
if (!pipeline || !source || !demuxer || !decoder || !conv || !sink) {
g_printerr ("One element could not be created. Exiting.\n");
return -1;
}
/* Set up the pipeline */
/* we set the input filename to the source element */
g_object_set (G_OBJECT (source), "location", argv[1], NULL);
/* we add a message handler */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/* we add all elements into the pipeline */
/* file-source | ogg-demuxer | vorbis-decoder | converter | alsa-output */
gst_bin_add_many (GST_BIN (pipeline),
source, demuxer, decoder, conv, sink, NULL);
/* we link the elements together */
/* file-source -> ogg-demuxer ~> vorbis-decoder -> converter -> alsa-output */
gst_element_link (source, demuxer);
gst_element_link_many (decoder, conv, sink, NULL);
g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added), decoder);
/* note that the demuxer will be linked to the decoder dynamically.
The reason is that Ogg may contain various streams (for example
audio and video). The source pad(s) will be created at run time,
by the demuxer when it detects the amount and nature of streams.
Therefore we connect a callback function which will be executed
when the "pad-added" is emitted.*/
/* 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;
}
Before compiling and running this you have to install the Gstreamer from the synaptic manager or you have download the sources(tar ball) form here and then compile and install it .(follow the INSTALL document)
Gstreamer will be installed in /usr/local/bin
You may also need the Glib so do the same for Glib source also , download the Glib from here and compile and install it.
Also before compiling the Gstreamer export the path :
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
pkg-config is computer software that provides a unified interface for querying installed libraries for the purpose of compiling software from its source code. pkg-config was originally designed for Linux but is now also available for the various BSDs, Microsoft Windows, Mac OS X, and Solaris (defintion from the wikipedia)
When a library is installed (automatically through the use of an RPM, deb, or other binary packaging system or by compiling from the source), a .pc file should be included and placed into a directory with other .pc files (the exact directory is dependent upon your system and outlined in the pkg-config man page). This file has several entries.
Here is an example .pc file for libpng:
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${exec_prefix}/include
Name: libpng
Description: Loads and saves PNG files
Version: 1.2.8
Libs: -L${libdir} -lpng12 -lz
Cflags: -I${includedir}/libpng12
This file demonstrates how libpng informs that its libraries can be found in /usr/local/lib and its headers in /usr/local/include, that the library name is libpng, and that the version is 1.2.8. It also gives the additional linker flags that are needed to compile code that uses this library.
Here is an example of usage of pkg-config while compiling:
gcc -o test test.c $(pkg-config --libs --cflags libpng)
gcc -Wall helloworld.c -o helloworld $(pkg-config --cflags --libs gstreamer-0.10)
To be continued....