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

GstPipeline *pipeline;
GstElement *audiosrc, *queue, *firstsink, *secondsink;

static GstPipeline* create_pipeline () {
	GstElement *pipeline;

	pipeline = gst_pipeline_new (NULL);
	audiosrc = gst_element_factory_make ("audiotestsrc", NULL);
	queue = gst_element_factory_make ("queue", NULL);
	firstsink = gst_element_factory_make ("fakesink", "firstsink");
	secondsink = gst_element_factory_make ("fakesink", "secondsink");

	/* Increase ref count to not loose element when going to NULL state */
	gst_object_ref (firstsink);
	gst_object_ref (secondsink);

	g_object_set (audiosrc, "is-live", TRUE, NULL);
	g_object_set (queue, "min-threshold-time", 0 * GST_SECOND,
			"max-size-time", 0, "max-size-buffers", 0, "max-size-bytes", 0, NULL);

	gst_bin_add_many (GST_BIN (pipeline), audiosrc, queue, firstsink, NULL);
	gst_element_link_many (audiosrc, queue, firstsink, NULL);

	return GST_PIPELINE (pipeline);
}

GstPadProbeReturn pad_probe_cb (GstPad *pad, GstPadProbeInfo *info) {
	gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));

	gst_element_set_state (firstsink, GST_STATE_NULL);
	gst_bin_remove (GST_BIN (pipeline), firstsink);
	gst_bin_add (GST_BIN (pipeline), secondsink);

	gst_element_link (queue, secondsink);
	gst_element_sync_state_with_parent (secondsink);

	return GST_PAD_PROBE_OK;
}

gboolean add_probe () {
	GstPad *pad;

	pad = gst_element_get_static_pad (queue, "src");
	gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BLOCKING,
			(GstPadProbeCallback)pad_probe_cb, NULL, NULL);
	gst_object_unref (pad);

	return FALSE;
}

gboolean get_position (GstElement *pipeline) {
	gint64 cur;
	gint64 level;
	gst_element_query_position (pipeline, GST_FORMAT_TIME, &cur);
	g_object_get (queue, "current-level-time", &level, NULL);
	printf ("Pipeline position: %"GST_TIME_FORMAT", Queue level: %"GST_TIME_FORMAT"\n",
			GST_TIME_ARGS(cur),	GST_TIME_ARGS(level));

	GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL,
			"pipeline");

	return TRUE;
}

int main (int argc, char *argv[]) {
	GMainLoop *loop;

	gst_init (&argc, &argv);

	loop = g_main_loop_new (NULL, FALSE);

	pipeline = create_pipeline ();
	gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);

	g_timeout_add_seconds (8, (GSourceFunc)add_probe, NULL);
	g_timeout_add_seconds (1, (GSourceFunc)get_position, GST_ELEMENT (pipeline));

	g_main_loop_run (loop);

	return 0;
}
