#include <gst/gst.h>

#define SWITCH_TIMEOUT 1
#define NUM_VIDEO_BUFFERS 500

static GMainLoop *loop;

/* Output selector src pads */
static GstPad *osel_src1 = NULL;
static GstPad *osel_src2 = NULL;

static gboolean
my_bus_callback (GstBus * bus, GstMessage * message, gpointer data)
{
  g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));

  switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ERROR:{
      GError *err;
      gchar *debug;

      gst_message_parse_error (message, &err, &debug);
      g_print ("Error: %s\n", err->message);
      g_error_free (err);
      g_free (debug);

      g_main_loop_quit (loop);
      break;
    }
    case GST_MESSAGE_EOS:
      /* end-of-stream */
      g_main_loop_quit (loop);
      break;
    default:
      /* unhandled message */
      break;
  }
  /* we want to be notified again the next time there is a message
   * on the bus, so returning TRUE (FALSE means we want to stop watching
   * for messages on the bus and our callback should not be called again)
   */
  return TRUE;
}

static gboolean
switch_cb (gpointer user_data)
{
  GstElement *sel = GST_ELEMENT (user_data);
  GstPad *old_pad, *new_pad = NULL;

  g_object_get (G_OBJECT (sel), "active-pad", &old_pad, NULL);

  if (old_pad == osel_src1)
    new_pad = osel_src2;
  else
    new_pad = osel_src1;

  g_object_set (G_OBJECT (sel), "active-pad", new_pad, NULL);

  g_print ("switched from %s:%s to %s:%s\n", GST_DEBUG_PAD_NAME (old_pad),
      GST_DEBUG_PAD_NAME (new_pad));

  gst_object_unref (old_pad);

  return TRUE;

}

static void
on_bin_element_added (GstBin * bin, GstElement * element, gpointer user_data)
{
  g_object_set (G_OBJECT (element), "sync", FALSE, "async", FALSE, NULL);
}

gint
main (gint argc, gchar * argv[])
{
  GstElement *pipeline, *src, *toverlay, *osel, *sink1, *sink2, *c1, *c2, *c0;
  GstPad *sinkpad;
  GstBus *bus;

  /* init GStreamer */
  gst_init (&argc, &argv);
  loop = g_main_loop_new (NULL, FALSE);

  /* create elements */
  pipeline = gst_element_factory_make ("pipeline", "pipeline");
  src = gst_element_factory_make ("videotestsrc", "src");
  c0 = gst_element_factory_make ("videoconvert", NULL);
  toverlay = gst_element_factory_make ("timeoverlay", "timeoverlay");
  osel = gst_element_factory_make ("output-selector", "osel");
  c1 = gst_element_factory_make ("videoconvert", NULL);
  c2 = gst_element_factory_make ("videoconvert", NULL);
  sink1 = gst_element_factory_make ("autovideosink", "sink1");
  sink2 = gst_element_factory_make ("autovideosink", "sink2");

  if (!pipeline || !src || !c0 || !toverlay || !osel || !c1 || !c2 || !sink1 ||
      !sink2) {
    g_print ("missing element\n");
    return -1;
  }

  /* add them to bin */
  gst_bin_add_many (GST_BIN (pipeline), src, c0, toverlay, osel, c1, sink1, c2,
      sink2, NULL);

  /* set properties */
  g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
  g_object_set (G_OBJECT (src), "do-timestamp", TRUE, NULL);
  g_object_set (G_OBJECT (src), "num-buffers", NUM_VIDEO_BUFFERS, NULL);
  g_object_set (G_OBJECT (osel), "resend-latest", TRUE, NULL);

  /* handle deferred properties */
  g_signal_connect (G_OBJECT (sink1), "element-added",
      G_CALLBACK (on_bin_element_added), NULL);
  g_signal_connect (G_OBJECT (sink2), "element-added",
      G_CALLBACK (on_bin_element_added), NULL);

  /* link src ! timeoverlay ! osel */
  if (!gst_element_link_many (src, c0, toverlay, osel, NULL)) {
    g_print ("linking failed\n");
    return -1;
  }

  /* link output 1 */
  sinkpad = gst_element_get_static_pad (c1, "sink");
  osel_src1 = gst_element_get_request_pad (osel, "src_%u");
  if (gst_pad_link (osel_src1, sinkpad) != GST_PAD_LINK_OK) {
    g_print ("linking output 1 converter failed\n");
    return -1;
  }
  gst_object_unref (sinkpad);

  if (!gst_element_link (c1, sink1)) {
    g_print ("linking output 1 failed\n");
    return -1;
  }

  /* link output 2 */
  sinkpad = gst_element_get_static_pad (c2, "sink");
  osel_src2 = gst_element_get_request_pad (osel, "src_%u");
  if (gst_pad_link (osel_src2, sinkpad) != GST_PAD_LINK_OK) {
    g_print ("linking output 2 converter failed\n");
    return -1;
  }
  gst_object_unref (sinkpad);

  if (!gst_element_link (c2, sink2)) {
    g_print ("linking output 2 failed\n");
    return -1;
  }

  /* add switch callback */
  g_timeout_add_seconds (SWITCH_TIMEOUT, switch_cb, osel);

  /* change to playing */
  bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  gst_bus_add_watch (bus, my_bus_callback, loop);
  gst_object_unref (bus);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);

  /* now run */
  g_main_loop_run (loop);

  /* also clean up */
  gst_element_set_state (pipeline, GST_STATE_NULL);
  gst_element_release_request_pad (osel, osel_src1);
  gst_element_release_request_pad (osel, osel_src2);
  gst_object_unref (GST_OBJECT (pipeline));

  return 0;
}
