2009-05-11 16:56:03 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <gst/gst.h>
|
|
|
|
|
|
|
|
static void
|
|
|
|
event_loop (GstElement * pipe)
|
|
|
|
{
|
|
|
|
GstBus *bus;
|
|
|
|
GstMessage *message = NULL;
|
2010-07-09 12:58:50 +00:00
|
|
|
gboolean running = TRUE;
|
2009-05-11 16:56:03 +00:00
|
|
|
|
|
|
|
bus = gst_element_get_bus (GST_ELEMENT (pipe));
|
|
|
|
|
2010-07-09 12:58:50 +00:00
|
|
|
while (running) {
|
2011-08-25 22:13:16 +00:00
|
|
|
message = gst_bus_timed_pop_filtered (bus, -1, GST_MESSAGE_ANY);
|
2009-05-11 16:56:03 +00:00
|
|
|
|
|
|
|
g_assert (message != NULL);
|
|
|
|
|
|
|
|
switch (message->type) {
|
|
|
|
case GST_MESSAGE_EOS:
|
|
|
|
g_message ("got EOS");
|
2010-07-09 12:58:50 +00:00
|
|
|
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;
|
|
|
|
}
|
2009-05-15 10:02:02 +00:00
|
|
|
case GST_MESSAGE_ERROR:
|
|
|
|
{
|
2009-05-11 16:56:03 +00:00
|
|
|
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);
|
2010-07-09 12:58:50 +00:00
|
|
|
running = FALSE;
|
|
|
|
break;
|
2009-05-11 16:56:03 +00:00
|
|
|
}
|
2009-05-15 10:02:02 +00:00
|
|
|
case GST_MESSAGE_STEP_DONE:
|
|
|
|
{
|
|
|
|
GstFormat format;
|
|
|
|
guint64 amount;
|
|
|
|
gdouble rate;
|
2009-05-18 13:48:20 +00:00
|
|
|
gboolean flush, intermediate;
|
2009-05-15 10:02:02 +00:00
|
|
|
guint64 duration;
|
2009-06-12 11:18:21 +00:00
|
|
|
gboolean eos;
|
2009-05-15 10:02:02 +00:00
|
|
|
|
|
|
|
gst_message_parse_step_done (message, &format, &amount, &rate,
|
2009-06-12 11:18:21 +00:00
|
|
|
&flush, &intermediate, &duration, &eos);
|
2009-05-15 10:02:02 +00:00
|
|
|
|
2009-05-15 13:24:30 +00:00
|
|
|
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));
|
|
|
|
}
|
2010-07-09 12:58:50 +00:00
|
|
|
break;
|
2009-05-15 10:02:02 +00:00
|
|
|
}
|
2009-05-11 16:56:03 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2010-07-09 12:58:50 +00:00
|
|
|
gst_message_unref (message);
|
2009-05-11 16:56:03 +00:00
|
|
|
}
|
2010-07-09 12:58:50 +00:00
|
|
|
gst_object_unref (bus);
|
2009-05-11 16:56:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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;
|
2009-05-15 13:24:30 +00:00
|
|
|
GstFormat format;
|
|
|
|
gint64 pos;
|
2009-05-11 16:56:03 +00:00
|
|
|
|
|
|
|
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);
|
2009-05-15 10:02:02 +00:00
|
|
|
g_object_set (appsink, "sync", TRUE, NULL);
|
2009-05-11 16:56:03 +00:00
|
|
|
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 */
|
2009-05-15 13:24:30 +00:00
|
|
|
g_message ("stepping three frames");
|
2009-05-11 16:56:03 +00:00
|
|
|
g_assert (gst_element_send_event (bin,
|
|
|
|
gst_event_new_step (GST_FORMAT_BUFFERS, 2, 1.0, TRUE, FALSE)));
|
|
|
|
|
2009-05-15 10:02:02 +00:00
|
|
|
/* blocks and returns when we received the step done message */
|
|
|
|
event_loop (bin);
|
|
|
|
|
|
|
|
/* wait for step to really complete */
|
2009-05-11 16:56:03 +00:00
|
|
|
gst_element_get_state (bin, NULL, NULL, -1);
|
|
|
|
|
2009-05-15 13:24:30 +00:00
|
|
|
format = GST_FORMAT_TIME;
|
|
|
|
gst_element_query_position (bin, &format, &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 ");
|
|
|
|
g_assert (gst_element_send_event (bin,
|
|
|
|
gst_event_new_step (GST_FORMAT_TIME, 120 * GST_MSECOND, 1.0, TRUE,
|
|
|
|
FALSE)));
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
|
|
format = GST_FORMAT_TIME;
|
|
|
|
gst_element_query_position (bin, &format, &pos);
|
|
|
|
g_message ("stepped 120ms frames, now at %" GST_TIME_FORMAT,
|
|
|
|
GST_TIME_ARGS (pos));
|
2009-05-11 16:56:03 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|