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

static void
event_loop (GstElement * pipe)
{
  GstBus *bus;
  GstMessage *message = NULL;
  gboolean running = TRUE;

  bus = gst_element_get_bus (GST_ELEMENT (pipe));

  while (running) {
    message = gst_bus_timed_pop_filtered (bus, -1, GST_MESSAGE_ANY);

    g_assert (message != NULL);

    switch (message->type) {
      case GST_MESSAGE_EOS:
        g_message ("got EOS");
        running = FALSE;
        break;
      case GST_MESSAGE_WARNING:{
        GError *gerror;
        gchar *debug;

        gst_message_parse_warning (message, &gerror, &debug);
        gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
        g_error_free (gerror);
        g_free (debug);
        break;
      }
      case GST_MESSAGE_ERROR:
      {
        GError *gerror;
        gchar *debug;

        gst_message_parse_error (message, &gerror, &debug);
        gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
        g_error_free (gerror);
        g_free (debug);
        running = FALSE;
        break;
      }
      case GST_MESSAGE_STEP_DONE:
      {
        GstFormat format;
        guint64 amount;
        gdouble rate;
        gboolean flush, intermediate;
        guint64 duration;
        gboolean eos;

        gst_message_parse_step_done (message, &format, &amount, &rate,
            &flush, &intermediate, &duration, &eos);

        if (format == GST_FORMAT_DEFAULT) {
          g_message ("step done: %" GST_TIME_FORMAT " skipped in %"
              G_GUINT64_FORMAT " frames", GST_TIME_ARGS (duration), amount);
        } else {
          g_message ("step done: %" GST_TIME_FORMAT " skipped",
              GST_TIME_ARGS (duration));
        }
        break;
      }
      default:
        break;
    }
    gst_message_unref (message);
  }
  gst_object_unref (bus);
}

/* signalled when a new preroll buffer is available */
static void
new_preroll (GstElement * appsink, gpointer user_data)
{
  GstBuffer *buffer;

  g_signal_emit_by_name (appsink, "pull-preroll", &buffer);

  g_message ("have new-preroll buffer %p, timestamp %" GST_TIME_FORMAT, buffer,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));

  gst_buffer_unref (buffer);
}

int
main (int argc, char *argv[])
{
  GstElement *bin, *videotestsrc, *appsink;
  gint64 pos;

  gst_init (&argc, &argv);

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

  /* create a fake source */
  videotestsrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
  g_assert (videotestsrc);
  g_object_set (videotestsrc, "num-buffers", 10, NULL);

  /* and a fake sink */
  appsink = gst_element_factory_make ("appsink", "appsink");
  g_assert (appsink);
  g_object_set (appsink, "emit-signals", TRUE, NULL);
  g_object_set (appsink, "sync", TRUE, NULL);
  g_signal_connect (appsink, "new-preroll", (GCallback) new_preroll, NULL);

  /* add objects to the main pipeline */
  gst_bin_add (GST_BIN (bin), videotestsrc);
  gst_bin_add (GST_BIN (bin), appsink);

  /* link the elements */
  gst_element_link_many (videotestsrc, appsink, NULL);

  /* go to the PAUSED state and wait for preroll */
  g_message ("prerolling first frame");
  gst_element_set_state (bin, GST_STATE_PAUSED);
  gst_element_get_state (bin, NULL, NULL, -1);

  /* step two frames, flush so that new preroll is queued */
  g_message ("stepping three frames");
  if (!gst_element_send_event (bin,
          gst_event_new_step (GST_FORMAT_BUFFERS, 2, 1.0, TRUE, FALSE)))
    g_warning ("Filed to send STEP event!");

  /* blocks and returns when we received the step done message */
  event_loop (bin);

  /* wait for step to really complete */
  gst_element_get_state (bin, NULL, NULL, -1);

  gst_element_query_position (bin, GST_FORMAT_TIME, &pos);
  g_message ("stepped two frames, now at %" GST_TIME_FORMAT,
      GST_TIME_ARGS (pos));

  /* step 3 frames, flush so that new preroll is queued */
  g_message ("stepping 120 milliseconds ");
  if (!gst_element_send_event (bin,
          gst_event_new_step (GST_FORMAT_TIME, 120 * GST_MSECOND, 1.0, TRUE,
              FALSE)))
    g_warning ("Filed to send STEP event!");

  /* blocks and returns when we received the step done message */
  event_loop (bin);

  /* wait for step to really complete */
  gst_element_get_state (bin, NULL, NULL, -1);

  gst_element_query_position (bin, GST_FORMAT_TIME, &pos);
  g_message ("stepped 120ms frames, now at %" GST_TIME_FORMAT,
      GST_TIME_ARGS (pos));

  g_message ("playing until EOS");
  gst_element_set_state (bin, GST_STATE_PLAYING);
  /* Run event loop listening for bus messages until EOS or ERROR */
  event_loop (bin);
  g_message ("finished");

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

  exit (0);
}
