/* gcc -o test -Wall -Werror `pkg-config --libs --cflags gstreamer-0.10` main.c */
/* ./test <uri> */

#include <gst/gst.h>

static gboolean async_msg_handler (GstBus *bus, GstMessage *msg, gpointer data);
static gboolean start_playback (gpointer data);
static void pipeline_set_sink (gpointer pipeline);

static GstElement *pipeline;
static GstState gst_state = GST_STATE_NULL;

int
main (int argc, char **argv)
{
  if (argc != 2)
    {
      g_print ("Usage: test <uri>\n");
      return -1;
    }

  gst_init (&argc, &argv);

  pipeline = gst_element_factory_make ("playbin2", "playbin");
  g_assert (pipeline);
  g_object_set (pipeline, "flags", 99, NULL);
  g_object_set (pipeline, "uri", argv[1], NULL);

  gst_bus_add_watch_full (gst_pipeline_get_bus (GST_PIPELINE (pipeline)),
                          G_PRIORITY_HIGH, (GstBusFunc) async_msg_handler,
                          NULL, NULL);

  pipeline_set_sink (pipeline);

  g_idle_add (start_playback, NULL);
  g_main_loop_run (g_main_loop_new (NULL, FALSE));

  return 0;
}

static void
pipeline_set_sink (gpointer pipeline)
{
  GstElement *newSink = gst_element_factory_make ("autovideosink", NULL);
  g_assert (newSink);
  g_print ("Setting new sink: %p\n", newSink);
  g_object_set (pipeline, "video-sink", newSink, NULL);

  g_object_get (pipeline, "video-sink", &newSink, NULL);
  g_print ("Current sink is: %p (%d refs)\n", newSink, G_OBJECT (newSink)->ref_count);
}

static gboolean
pipeline_playing_timeout (gpointer pipeline)
{
  gst_element_set_state (pipeline, GST_STATE_READY);
  return FALSE;
}

static gboolean
pipeline_ready_timeout (gpointer pipeline)
{
  gst_element_set_state (pipeline, GST_STATE_NULL);
  pipeline_set_sink (pipeline);
  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  return FALSE;
}


static gboolean
async_msg_handler (GstBus *bus, GstMessage *message, gpointer data)
{
  GstState old_state, new_state, pending_state;
  GstStateChange state_transition;

  switch (GST_MESSAGE_TYPE (message))
    {
    case GST_MESSAGE_STATE_CHANGED:

      gst_message_parse_state_changed (message, &old_state, &new_state,
                                       &pending_state);

      if (GST_ELEMENT (GST_MESSAGE_SRC (message)) != pipeline)
        return TRUE;

      gst_state = new_state;
      g_print ("%s: %s->%s=>%s\n",
              gst_element_get_name (GST_ELEMENT (GST_MESSAGE_SRC (message))),
              gst_element_state_get_name (old_state),
              gst_element_state_get_name (new_state),
              gst_element_state_get_name (pending_state));

      state_transition = GST_STATE_TRANSITION (old_state, gst_state);
      switch (state_transition)
        {
        case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
          g_timeout_add_seconds (1, pipeline_playing_timeout, pipeline);
          break;
        case GST_STATE_CHANGE_PAUSED_TO_READY:
          g_timeout_add_seconds (1, pipeline_ready_timeout, pipeline);
          break;
        default:
          break;
        }

      break;

    default:
      break;
    }

  return TRUE;
}

static gboolean
start_playback (gpointer data)
{
  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  return FALSE;
}
