As an example we show the helloworld program that we coded in Chapter 9 using a thread. Note that the whole application lives in a thread (as opposed to half of the application living in a thread and the other half being another thread or a pipeline). Therefore, it does not need a queue element in this specific case.
#include <gst/gst.h> GstElement *thread, *source, *decodebin, *audiosink; static gboolean idle_eos (gpointer data) { g_print ("Have idle-func in thread %p\n", g_thread_self ()); gst_main_quit (); /* do this function only once */ return FALSE; } /* * EOS will be called when the src element has an end of stream. * Note that this function will be called in the thread context. * We will place an idle handler to the function that really * quits the application. */ static void cb_eos (GstElement *thread, gpointer data) { g_print ("Have eos in thread %p\n", g_thread_self ()); g_idle_add ((GSourceFunc) idle_eos, NULL); } /* * On error, too, you'll want to forward signals to the main * thread, especially when using GUI applications. */ static void cb_error (GstElement *thread, GstElement *source, GError *error, gchar *debug, gpointer data) { g_print ("Error in thread %p: %s\n", g_thread_self (), error->message); g_idle_add ((GSourceFunc) idle_eos, NULL); } /* * Link new pad from decodebin to audiosink. * Contains no further error checking. */ static void cb_newpad (GstElement *decodebin, GstPad *pad, gboolean last, gpointer data) { gst_pad_link (pad, gst_element_get_pad (audiosink, "sink")); gst_bin_add (GST_BIN (thread), audiosink); gst_bin_sync_children_state (GST_BIN (thread)); } gint main (gint argc, gchar *argv[]) { /* init GStreamer */ gst_init (&argc, &argv); /* make sure we have a filename argument */ if (argc != 2) { g_print ("usage: %s <Ogg/Vorbis filename>\n", argv[0]); return -1; } /* create a new thread to hold the elements */ thread = gst_thread_new ("thread"); g_signal_connect (thread, "eos", G_CALLBACK (cb_eos), NULL); g_signal_connect (thread, "error", G_CALLBACK (cb_error), NULL); /* create elements */ source = gst_element_factory_make ("filesrc", "source"); g_object_set (G_OBJECT (source), "location", argv[1], NULL); decodebin = gst_element_factory_make ("decodebin", "decoder"); g_signal_connect (decodebin, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL); audiosink = gst_element_factory_make ("alsasink", "audiosink"); /* setup */ gst_bin_add_many (GST_BIN (thread), source, decodebin, NULL); gst_element_link (source, decodebin); gst_element_set_state (audiosink, GST_STATE_PAUSED); gst_element_set_state (thread, GST_STATE_PLAYING); /* no need to iterate. We can now use a mainloop */ gst_main (); /* unset */ gst_element_set_state (thread, GST_STATE_NULL); gst_object_unref (GST_OBJECT (thread)); return 0; }