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

GstElement *pipeline = NULL;
GstElement *src = NULL;
GstElement *sink = NULL;
GMainLoop *loop = NULL;
GstClockTime last_pipeline_time = GST_CLOCK_TIME_NONE;
GstClockTime last_clock_time = GST_CLOCK_TIME_NONE;

static gboolean quit(gpointer data) {
  g_main_loop_quit(loop);

  return FALSE;
}

static gboolean check_time(gpointer data) {
  GstClock *clock = gst_pipeline_get_clock(GST_PIPELINE(pipeline));
  GstClockTime pipeline_time = gst_clock_get_time(clock);

  struct timespec tp;
  clock_gettime(CLOCK_MONOTONIC, &tp);
  GstClockTime clock_time = GST_TIMESPEC_TO_TIME(tp);
  gst_object_unref(clock);

  int diff1 = 0;
  int diff2 = 0;

  if (last_clock_time != GST_CLOCK_TIME_NONE) {
    diff1 = (clock_time - last_clock_time) / 1000000;
  }

  if (last_pipeline_time != GST_CLOCK_TIME_NONE) {
    diff2 = (pipeline_time - last_pipeline_time) / 1000000;
  }

  g_printf("%i\t%i\t%i\n", diff1, diff2, diff2 - diff1);

  last_pipeline_time = pipeline_time;
  last_clock_time = clock_time;

  return TRUE;
}

int main(int argc, char *argv[]) {
  gst_init(&argc, &argv);

  loop = g_main_loop_new(NULL, FALSE);

  src = gst_element_factory_make("pulsesrc", NULL);
  sink = gst_element_factory_make("fakesink", NULL);
  pipeline = gst_pipeline_new(NULL);

  assert(src != NULL);
  assert(sink != NULL);

  gst_bin_add_many(GST_BIN(pipeline), src, sink, NULL);
  gst_element_link(src, sink);

  g_timeout_add(1000/30, check_time, NULL);

  g_timeout_add(2000, quit, NULL);

  gst_element_set_state(pipeline, GST_STATE_PLAYING);

  g_main_loop_run(loop);

  gst_element_set_state(pipeline, GST_STATE_NULL);

  gst_deinit();

  return 0;
}
