#include <gst/gst.h>
#include <glib.h>

int playFunc(void *user_data)
{
    GstElement* pipeline = GST_ELEMENT(user_data);
    gst_element_set_state(pipeline, GST_STATE_PLAYING);
    return FALSE;
}

void* sourceThreadFunc(void* data)
{
    GMainContext* cxt = g_main_context_new();
    GMainLoop* loop = g_main_loop_new(cxt, FALSE);

    GSource* src = g_timeout_source_new(500);
    g_source_set_callback(src, playFunc, data, NULL);
    g_source_attach(src, cxt);

    g_main_loop_run(loop);

    g_main_loop_unref(loop);
    g_main_context_unref(cxt);

    return 0;
}

int
main (int   argc, char *argv[])
{
  GMainLoop *loop;

  GstElement *pipeline, *src, *videosink;

  gst_debug_set_default_threshold(GST_LEVEL_INFO);

  /* Initialisation */
  gst_init (&argc, &argv);

  loop = g_main_loop_new (NULL, FALSE);

  /* Create gstreamer elements */
  pipeline = gst_pipeline_new ("testplay");
  src = gst_element_factory_make ("videotestsrc", NULL);
  videosink = gst_element_factory_make ("osxvideosink", NULL);

  if (!pipeline)
  {
    g_printerr ("One element could not be created. Exiting.\n");
    return -1;
  }

  /* Set up the pipeline */
  gst_bin_add_many(GST_BIN(pipeline), src, videosink, NULL);
  gst_element_link(src, videosink);

  /* Set the pipeline to "playing" state*/
  g_print ("Now playing\n");
#ifdef TEST_THREADED
  GThread* thread = g_thread_new("sourceThread", sourceThreadFunc, pipeline);
#else
  gst_element_set_state(pipeline, GST_STATE_PLAYING);
#endif


  /* Iterate */
  g_print ("Running...\n");
  g_main_loop_run (loop);

#ifdef TEST_THREADED
  g_thread_exit(thread);
#endif


  /* 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));
  g_main_loop_unref (loop);

  return 0;
}
