Al ver el elemento “filesrc”, solo posee un pad, “src”. Esto lo hace candidato a ser el origen del stream
El elemento “mad” posee dos pads, “src” y “sink”. Estos pads estan indicando, precisamente, donde conectarse (el pad de src a un elemento de origen, el pad de sink a un sink).
El elemento osssink solo posee un pad, “sink”.
Asi que nuestra cadena de elementos podria ser:
+
+ +
+ +
+| filesrc | | mad | | osssink || +
+ +
+ +
+ +
+ || |src|
|sink| |src|
|sink| |+
+
+ +
+
+
+ +
+
+
Parecido al ejemplo inicial
3. Programando el MP3 Player
Ya que GStreamer ocupa las facilidades de GLib, es necesario dominarlo de forma previa. Para eso, hay un articulo en este mismo sitio que tiene una introducción de GLib.
Adicionalmente, necesitamos echar una mirada a la documentación de la API de GStreamer. Hay un programa llamado Devhelp que coleccciona esta documentación en un unico programa, asi que no es una mala idea para consultar además a GLib.
Antes de pensar en utilizar GStreamer en nuestro código, es necesario inicializar el subsistema de GStreamer:
gst_init(&argc, &argv);
Haciendo más análisis a la salida de gst-inspect, aparece una herencia de elementos bastante particular:
GObject +
GstObject +
GstElement +
GstFileSrc
Esto indica que GstFileSrc hereda las propiedades y metodos de GstElement, el elemento mas básico de GStreamer (en codigo). A su vez, el elemento mas básico es GObject, básico en la programación de objetos en GLib.
Una salvedad adicional es que las propiedades de los objetos se hacen atraves de GObject.
Un ejemplo de codigo:
GstElement * filesrc;g_object_set((GObject *) filesrc, "foo", "bar", NULL);
No olvidar tampoco que cada elemento, en código, se define como GstElement. La forma, entonces, de crear los elementos especificos, es a traves de factorias (o plantillas) que indican el tipo de elemento (por ejemplo, filesrc).
GstElement * element;element = gst_element_factory_make("filesrc", "foo");
El nombre (importante!) es asignado en la funcion (”foo”).
Para nuestro MP3 Player:
GstElement * origen, * filtro, * salida;origen = gst_element_factory_make("filesrc","origen");filtro = gst_element_factory_create("mad","decodificador");salida = gst_element_factory_create("osssink","salida");
Necesitamos además crear la tubería,
GstElement * tuberia;tuberia = gst_pipeline_new("foo");
(solo requiere un valor la función, el nombre de la tubería).
Es necesario ahora enlazar dentro de la tubería los elementos. En este simple caso, sólo indicamos los elementos de forma secuencial. En casos más complejos, hay que indicar como se enlazan. Esto queda a ejercicio del lector
Queda entonces crear un “bin” que contenga todos los elementos (origen, filtro, salida) dentro de la tubería:
gst_bin_add_many(GST_BIN(tuberia), origen, filtro, salida, NULL);
Como dijimos que GStreamer une los pads “src” con “sink”, no hay que indicar explicitamente la forma de conexión. Esta es la gran ventaja de GStreamer:
Una forma puede ser enlazar los elementos de a uno:
gst_element_link(origen,filtro);gst_element_link(filtro,salida);
o bien, enlazarlos en una cadena completa. Esto sólo es posible en este ejemplo, en que los elementos sólo poseen un enlace (y no existen muxers/demuxers):
gst_element_link_many(origen, filtro, salida, NULL);
Pensarán que el MP3 player estaría listo, pero es necesario entender un concepto previo, el estado de la tubería.