
#include <gst/gst.h>

static GMainLoop *loop;
static GstElement *pipeline;
static GstElement *audiosrc;
static GstElement *sink;
static GstSegment segment;

static gint64 basetime;
static GstClock *gstclock;

static gboolean
drop_eos (GstPad * pad, GstEvent * evt, gpointer data)
{
  if (GST_EVENT_TYPE (evt) == GST_EVENT_EOS)
    return FALSE;

  if (GST_EVENT_TYPE (evt) == GST_EVENT_NEWSEGMENT) {
    gboolean update;
    gdouble rate;
    GstFormat format;
    guint64 start, stop, pos;

    gst_event_parse_new_segment (evt, &update, &rate, &format, &start, &stop, &pos);

    gst_segment_set_newsegment (&segment, update, rate, format, start, stop, pos);

    g_print ("New segment:\n");
    g_print ("Start: %" GST_TIME_FORMAT "; %llu\n", GST_TIME_ARGS (start), start);
    g_print ("Stop : %" GST_TIME_FORMAT "; %llu\n", GST_TIME_ARGS (stop), stop);
    g_print ("Pos  : %" GST_TIME_FORMAT "; %llu\n", GST_TIME_ARGS (pos), pos);
    g_print ("\n");
  }

  return TRUE;
}

static gboolean
buffer_probe (GstPad * pad, GstBuffer * buf, gpointer data)
{
  GstClockTime ts = GST_BUFFER_TIMESTAMP (buf);

  g_print ("Ts: %" GST_TIME_FORMAT "; %llu\n", GST_TIME_ARGS (ts), ts);
  return TRUE;
}

static gboolean
reset_src (gpointer data)
{
  gst_element_set_state (audiosrc, GST_STATE_READY);
  g_usleep(1 * G_USEC_PER_SEC);
  gst_element_set_base_time (audiosrc, gst_element_get_base_time (pipeline));
  gst_element_set_clock (audiosrc, gst_element_get_clock (pipeline));
  gst_element_set_state (audiosrc, GST_STATE_PLAYING);
}

static gboolean
finish (gpointer data)
{
  g_main_loop_quit (loop);
  return FALSE;
}

int main()
{
  gst_init (NULL, NULL);

  loop = g_main_loop_new (NULL, FALSE);
  gst_segment_init (&segment, GST_FORMAT_TIME);

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

  g_object_set (audiosrc, "provide-clock", FALSE, NULL);
  g_object_set (sink, "sync", FALSE, NULL);

  gst_bin_add_many (GST_BIN (pipeline), audiosrc, sink);
  gst_element_link (audiosrc, sink);

  {
    GstPad *pad;

    pad = gst_element_get_static_pad (audiosrc, "src");

    gst_pad_add_event_probe (pad, (GCallback) drop_eos, NULL);
    gst_pad_add_buffer_probe (pad, (GCallback) buffer_probe, NULL);

    gst_object_unref (pad);
  }

  g_timeout_add (2 * 1000, reset_src, audiosrc);
  g_timeout_add (4 * 1000, finish, audiosrc);

  gst_element_set_state (pipeline, GST_STATE_PLAYING);
  g_main_loop_run (loop);
  gst_element_set_state (pipeline, GST_STATE_NULL);

  gst_object_unref (pipeline);
  g_main_loop_unref (loop);

  return 0;
}
