We'll start with a simple main function:
</para>
<programlisting>
-#include <gnome.h>
+/* example-begin dynamic.c */
#include <gst/gst.h>
+#include <gnome.h>
-void eof(GstElement *src) {
- g_print("have eos, quitting\n");
- exit(0);
+void
+eof (GstElement *src)
+{
+ g_print ("have eos, quitting\n");
+ exit (0);
}
gboolean
return TRUE;
}
-int
-main(int argc, char *argv[])
-{
- GstElement *pipeline, *src, *demux;
- struct poptOption *gst_table;
-
- gst_init (&argc, &argv);
-
- pipeline = gst_pipeline_new ("pipeline");
- g_return_val_if_fail (pipeline != NULL, -1);
-
- src = gst_element_factory_make ("filesrc", "src");
- g_return_val_if_fail (src != NULL, -1);
- g_object_set (G_OBJECT (src), "location", argv[1], NULL);
-
- demux = gst_element_factory_make ("mpegdemux", "demux");
- g_return_val_if_fail (demux != NULL, -1);
-
- gst_bin_add_many (GST_BIN (pipeline), src, demux, NULL);
-
- g_signal_connect (G_OBJECT (demux), "new_pad",
- G_CALLBACK (new_pad_created), pipeline);
-
- g_signal_connect (G_OBJECT (src), "eos",
- G_CALLBACK (eof), NULL);
-
- gst_element_connect (src, parse);
-
- gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
-
- g_idle_add (idle_func, pipeline);
-
- gdk_threads_enter ();
- gst_main ();
- gdk_threads_leave ();
-
- return 0;
-}
-
- </programlisting>
- <para>
- We create two elements: a file source and an MPEG demuxer.. We also add an EOS (End Of Stream)
- signal to the filesrc so that we will be notified when the file has ended. There's nothing
- special about this piece of code except for the signal 'new_pad' that we connected to the
- mpegdemux using:
- </para>
- <programlisting>
- g_signal_connect (G_OBJECT (demux), "new_pad",
- G_CALLBACK (new_pad_created), pipeline);
- </programlisting>
- <para>
- When an elementary stream has been detected in the system stream,
- mpegdemux will create a new pad that will provide the data of the
- elementary stream. A function 'new_pad_created' will be called when
- the pad is created:
- </para>
- <programlisting>
void
new_pad_created (GstElement *parse, GstPad *pad, GstElement *pipeline)
{
- GstElement *decode_audio, *parse_video, *decode_video, *play, *videoscale, *show;
+ GstElement *decode_video = NULL;
+ GstElement *decode_audio, *play, *show;
GstElement *audio_queue, *video_queue;
GstElement *audio_thread, *video_thread;
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
- // connect to audio pad
+ /* connect to audio pad */
if (strncmp (gst_pad_get_name (pad), "audio_", 6) == 0) {
- // construct internal pipeline elements
- decode = gst_element_factory_make ("mad", "decode_audio");
- g_return_if_fail (decode != NULL);
+ /* construct internal pipeline elements */
+ decode_audio = gst_element_factory_make ("mad", "decode_audio");
+ g_return_if_fail (decode_audio != NULL);
play = gst_element_factory_make ("osssink", "play_audio");
g_return_if_fail (play != NULL);
- // create the thread and pack stuff into it
+ /* create the thread and pack stuff into it */
audio_thread = gst_thread_new ("audio_thread");
g_return_if_fail (audio_thread != NULL);
gst_bin_add_many (GST_BIN (audio_thread), decode_audio, play, NULL);
- // set up pad connections
+ /* set up pad connections */
gst_element_add_ghost_pad (GST_ELEMENT (audio_thread),
gst_element_get_pad (decode_audio, "sink"),
"sink");
- gst_element_connect (decode, play);
+ gst_element_connect (decode_audio, play);
- // construct queue and connect everything in the main pipeline
+ /* construct queue and connect everything in the main pipeline */
audio_queue = gst_element_factory_make ("queue", "audio_queue");
+ g_return_if_fail (audio_queue != NULL);
gst_bin_add_many (GST_BIN (pipeline), audio_queue, audio_thread, NULL);
gst_pad_connect (pad, gst_element_get_pad (audio_queue, "sink"));
gst_element_connect (audio_queue, audio_thread);
- // set up thread state and kick things off
+ /* set up thread state and kick things off */
g_print ("setting to READY state\n");
gst_element_set_state (GST_ELEMENT (audio_thread), GST_STATE_READY);
}
else if (strncmp (gst_pad_get_name (pad), "video_", 6) == 0) {
- // construct internal pipeline elements
+ /* construct internal pipeline elements */
decode_video = gst_element_factory_make ("mpeg2dec", "decode_video");
g_return_if_fail (decode_video != NULL);
show = gst_element_factory_make ("xvideosink", "show");
g_return_if_fail (show != NULL);
- // create the thread and pack stuff into it
+ /* create the thread and pack stuff into it */
video_thread = gst_thread_new ("video_thread");
g_return_if_fail (video_thread != NULL);
gst_bin_add_many (GST_BIN (video_thread), decode_video, show, NULL);
- // set up pad connections
+ /* set up pad connections */
gst_element_add_ghost_pad (GST_ELEMENT (video_thread),
- gst_element_get_pad (parse_video, "sink"));
+ gst_element_get_pad (parse, "sink"),
+ "sink");
gst_element_connect (decode_video, show);
- // construct queue and connect everything in the main pipeline
+ /* construct queue and connect everything in the main pipeline */
video_queue = gst_element_factory_make ("queue", "video_queue");
+ g_return_if_fail (video_queue != NULL);
- gst_bin_add_many (GST_BIN (pipeline), video_queue, video_thread);
+ gst_bin_add_many (GST_BIN (pipeline), video_queue, video_thread, NULL);
gst_pad_connect (pad, gst_element_get_pad (video_queue, "sink"));
gst_element_connect (video_queue, video_thread);
- // set up thread state and kick things off
+ /* set up thread state and kick things off */
g_print ("setting to READY state\n");
gst_element_set_state (GST_ELEMENT (video_thread), GST_STATE_READY);
}
g_print("\n");
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
}
+
+int
+main (int argc, char *argv[])
+{
+ GstElement *pipeline, *src, *demux;
+
+ gst_init (&argc, &argv);
+
+ pipeline = gst_pipeline_new ("pipeline");
+ g_return_val_if_fail (pipeline != NULL, -1);
+
+ src = gst_element_factory_make ("filesrc", "src");
+ g_return_val_if_fail (src != NULL, -1);
+ if (argc < 2)
+ g_error ("Please specify a video file to play !");
+
+ g_object_set (G_OBJECT (src), "location", argv[1], NULL);
+
+ demux = gst_element_factory_make ("mpegdemux", "demux");
+ g_return_val_if_fail (demux != NULL, -1);
+
+ gst_bin_add_many (GST_BIN (pipeline), src, demux, NULL);
+
+ g_signal_connect (G_OBJECT (demux), "new_pad",
+ G_CALLBACK (new_pad_created), pipeline);
+
+ g_signal_connect (G_OBJECT (src), "eos",
+ G_CALLBACK (eof), NULL);
+
+ gst_element_connect (src, demux);
+
+ gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+
+ g_idle_add (idle_func, pipeline);
+
+ gdk_threads_enter ();
+ gst_main ();
+ gdk_threads_leave ();
+
+ return 0;
+}
+/* example-end dynamic.c */
+ </programlisting>
+ <para>
+ We create two elements: a file source and an MPEG demuxer.
+ We also add an EOS (End Of Stream) signal to the filesrc so that
+ we will be notified when the file has ended. There's nothing
+ special about this piece of code except for the signal 'new_pad'
+ that we connected to the
+ mpegdemux element using:
+ </para>
+ <programlisting>
+ g_signal_connect (G_OBJECT (demux), "new_pad",
+ G_CALLBACK (new_pad_created), pipeline);
</programlisting>
+ <para>
+ When an elementary stream has been detected in the system stream,
+ mpegdemux will create a new pad that will provide the data of the
+ elementary stream. A function 'new_pad_created' will be called when
+ the pad is created.
+ </para>
<para>
- In the above example, we created new elements based on the name of the newly created pad. We
- then added them to a new thread. There are other possibilities to check the type of the pad, for
+ In the above example, we created new elements based on the name of
+ the newly created pad. We then added them to a new thread.
+ There are other possibilities to check the type of the pad, for
example by using the MIME type and the properties of the pad.
</para>
</chapter>