# Threads

GStreamer has support for multithreading throught the use of the `GstThread` object. This object is in fact a special `GstBin` that will become a thread when started.

To construct a new thread you will perform something like:

      GstElement *my_thread;

      // create the thread object
      my_thread = gst_thread_new ("my_thread");
      g_return_if_fail (audio_thread != NULL);

      // add some plugins
      gst_bin_add (GST_BIN (my_thread), GST_ELEMENT (funky_src));
      gst_bin_add (GST_BIN (my_thread), GST_ELEMENT (cool_effect));

      // connect the elements here...
      ...

      // start playing
      gst_element_set_state (GST_ELEMENT (my_thread), GST_STATE_PLAYING);

The above program will create a thread with two elements in it. As soon as it is set to the PLAYING state, the thread will start to iterate.

A thread should normally contain a source element. Most often, the thread is fed with data from a queue.

A thread will be visualised as below

## a thread

As an example we show the helloworld program using a thread.

    #include <gst/gst.h>

    /* eos will be called when the src element has an end of stream */
    void
    eos (GstSrc *src, gpointer data)
    {
      GstThread *thread = GST_THREAD (data);
      g_print ("have eos, quitting\n");

      /* stop the bin */
      gst_element_set_state (GST_ELEMENT (thread), GST_STATE_NULL);

      gst_main_quit ();
    }

    int
    main (int argc, char *argv[])
    {
      GstElement *filesrc, *audiosink;
      GstElement *pipeline;
      GstElement *thread;

      if (argc != 2) {
        g_print ("usage: &percnt;s <filename>\n", argv[0]);
        exit (-1);
      }

      gst_init (&argc, &argv);

      /* create a new thread to hold the elements */
      thread = gst_thread_new ("thread");
      g_assert (thread != NULL);

      /* create a new bin to hold the elements */
      pipeline = gst_pipeline_new ("pipeline");
      g_assert (pipeline != NULL);

      /* create a disk reader */
      filesrc = gst_elementfactory_make ("filesrc", "disk_source");
      g_assert (filesrc != NULL);
      g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
      g_signal_connect (G_OBJECT (filesrc), "eos",
                         G_CALLBACK (eos), thread);

      /* and an audio sink */
      audiosink = gst_elementfactory_make ("audiosink", "play_audio");
      g_assert (audiosink != NULL);

      /* add objects to the main pipeline */
      gst_bin_add (GST_BIN (pipeline), filesrc);
      gst_bin_add (GST_BIN (pipeline), audiosink);

      /* automatically setup the pipeline */
      if (!gst_pipeline_autoplug (GST_PIPELINE (pipeline))) {
        g_print ("unable to handle stream\n");
        exit (-1);
      }

      /* remove the source element from the pipeline */
      gst_bin_remove (GST_BIN (pipeline), filesrc);

      /* insert the source element in the thread, remember a thread needs at
         least one source or connection element */
      gst_bin_add (GST_BIN (thread), filesrc);

      /* add the pipeline to the thread too */
      gst_bin_add (GST_BIN (thread), GST_ELEMENT (pipeline));

      /* start playing */
      gst_element_set_state (GST_ELEMENT (thread), GST_STATE_PLAYING);

      /* do whatever you want here, the thread will be playing */
      ...

      gst_main ();

      gst_pipeline_destroy (thread);

      exit (0);
    }