From 8b8562ea858e54b5b92b59a95a09610ee06086c2 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Fri, 24 Jan 2014 11:29:50 +0100 Subject: [PATCH] validate:tools: Implement Buffering support in the various tools --- validate/tools/gst-validate-transcoding.c | 65 ++++++++++++++++++-- validate/tools/gst-validate.c | 72 ++++++++++++++++++++--- validate/tools/launcher/utils.py | 8 ++- 3 files changed, 131 insertions(+), 14 deletions(-) diff --git a/validate/tools/gst-validate-transcoding.c b/validate/tools/gst-validate-transcoding.c index ef11bed64a..994aef95cf 100644 --- a/validate/tools/gst-validate-transcoding.c +++ b/validate/tools/gst-validate-transcoding.c @@ -47,6 +47,10 @@ static GstEncodingProfile *encoding_profile = NULL; static gboolean eos_on_shutdown = FALSE; static gboolean force_reencoding = FALSE; static GList *all_raw_caps = NULL; +static guint print_pos_srcid = 0; + +static gboolean buffering = FALSE; +static gboolean is_live = FALSE; typedef struct { @@ -458,6 +462,9 @@ bus_callback (GstBus * bus, GstMessage * message, gpointer data) gst_message_parse_state_changed (message, &old, &new, &pending); if (new == GST_STATE_PLAYING) { + if (print_pos_srcid == 0) + print_pos_srcid = + g_timeout_add (50, (GSourceFunc) print_position, NULL); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "gst-validate-transcode.playing"); } @@ -489,6 +496,39 @@ bus_callback (GstBus * bus, GstMessage * message, gpointer data) case GST_MESSAGE_EOS: g_main_loop_quit (loop); break; + case GST_MESSAGE_BUFFERING:{ + gint percent; + + if (!buffering) { + g_print ("\n"); + } + + gst_message_parse_buffering (message, &percent); + g_print ("%s %d%% \r", "Buffering...", percent); + + /* no state management needed for live pipelines */ + if (is_live) + break; + + if (percent == 100) { + /* a 100% message means buffering is done */ + if (buffering) { + buffering = FALSE; + gst_element_set_state (pipeline, GST_STATE_PLAYING); + } + } else { + /* buffering... */ + if (!buffering) { + gst_element_set_state (pipeline, GST_STATE_PAUSED); + if (print_pos_srcid) { + if (g_source_remove (print_pos_srcid)) + print_pos_srcid = 0; + } + buffering = TRUE; + } + } + break; + } default: break; } @@ -704,6 +744,8 @@ main (int argc, gchar ** argv) GstValidateMonitor *monitor; GOptionContext *ctx; int rep_err; + GstStateChangeReturn sret; + #ifdef G_OS_UNIX guint signal_watch_id; #endif @@ -833,13 +875,24 @@ main (int argc, gchar ** argv) gst_object_unref (bus); g_print ("Starting pipeline\n"); - if (gst_element_set_state (pipeline, - GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { - g_print ("Pipeline failed to go to PLAYING state\n"); - ret = -1; - goto exit; + sret = gst_element_set_state (pipeline, GST_STATE_PLAYING); + switch (sret) { + case GST_STATE_CHANGE_FAILURE: + /* ignore, we should get an error message posted on the bus */ + g_print ("Pipeline failed to go to PLAYING state\n"); + ret = -1; + goto exit; + case GST_STATE_CHANGE_NO_PREROLL: + g_print ("Pipeline is live.\n"); + is_live = TRUE; + break; + case GST_STATE_CHANGE_ASYNC: + g_print ("Prerolling...\r"); + break; + default: + break; } - g_timeout_add (50, (GSourceFunc) print_position, NULL); + g_main_loop_run (mainloop); rep_err = gst_validate_runner_printf (runner); diff --git a/validate/tools/gst-validate.c b/validate/tools/gst-validate.c index bb1c69c941..2f199b21ec 100644 --- a/validate/tools/gst-validate.c +++ b/validate/tools/gst-validate.c @@ -40,6 +40,10 @@ static gint ret = 0; static GMainLoop *mainloop; static GstElement *pipeline; +static gboolean buffering = FALSE; +static gboolean is_live = FALSE; +static guint print_pos_srcid = 0; + #ifdef G_OS_UNIX static gboolean intr_handler (gpointer user_data) @@ -111,9 +115,50 @@ bus_callback (GstBus * bus, GstMessage * message, gpointer data) gst_element_state_get_name (oldstate), gst_element_state_get_name (newstate), gst_element_state_get_name (pending)); + + if (newstate == GST_STATE_PLAYING) { + if (print_pos_srcid == 0) + print_pos_srcid = + g_timeout_add (50, (GSourceFunc) print_position, NULL); + GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), + GST_DEBUG_GRAPH_SHOW_ALL, "gst-validate.playing"); + } } break; + case GST_MESSAGE_BUFFERING:{ + gint percent; + + if (!buffering) { + g_print ("\n"); + } + + gst_message_parse_buffering (message, &percent); + g_print ("%s %d%% \r", "Buffering...", percent); + + /* no state management needed for live pipelines */ + if (is_live) + break; + + if (percent == 100) { + /* a 100% message means buffering is done */ + if (buffering) { + buffering = FALSE; + gst_element_set_state (pipeline, GST_STATE_PLAYING); + } + } else { + /* buffering... */ + if (!buffering) { + gst_element_set_state (pipeline, GST_STATE_PAUSED); + if (print_pos_srcid) { + if (g_source_remove (print_pos_srcid)) + print_pos_srcid = 0; + } + buffering = TRUE; + } + } + break; + } default: break; } @@ -127,6 +172,8 @@ main (int argc, gchar ** argv) GError *err = NULL; const gchar *scenario = NULL, *configs = NULL; gboolean list_scenarios = FALSE; + GstStateChangeReturn sret; + #ifdef G_OS_UNIX guint signal_watch_id; #endif @@ -237,21 +284,32 @@ main (int argc, gchar ** argv) gst_object_unref (bus); g_print ("Starting pipeline\n"); - if (gst_element_set_state (pipeline, - GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { - g_print ("Pipeline failed to go to PLAYING state\n"); - ret = -1; - goto exit; + sret = gst_element_set_state (pipeline, GST_STATE_PLAYING); + switch (sret) { + case GST_STATE_CHANGE_FAILURE: + /* ignore, we should get an error message posted on the bus */ + g_print ("Pipeline failed to go to PLAYING state\n"); + ret = -1; + goto exit; + case GST_STATE_CHANGE_NO_PREROLL: + g_print ("Pipeline is live.\n"); + is_live = TRUE; + break; + case GST_STATE_CHANGE_ASYNC: + g_print ("Prerolling...\r"); + break; + default: + break; } - g_timeout_add (50, (GSourceFunc) print_position, NULL); g_print ("Pipeline started\n"); g_main_loop_run (mainloop); rep_err = gst_validate_runner_printf (runner); if (ret == 0) { ret = rep_err; - g_print ("Returning %d as error where found", rep_err); + if (rep_err != 0) + g_print ("Returning %d as error where found", rep_err); } exit: diff --git a/validate/tools/launcher/utils.py b/validate/tools/launcher/utils.py index d92b27782a..5a4ea43c95 100644 --- a/validate/tools/launcher/utils.py +++ b/validate/tools/launcher/utils.py @@ -210,6 +210,10 @@ def _parse_position(p): return parse_gsttimeargs(start_stop[0]), parse_gsttimeargs(start_stop[1]) +def _parse_buffering(b): + return b.split("buffering... ")[1].split("%")[0], 100 + + def _get_position(test): position = duration = -1 @@ -217,7 +221,7 @@ def _get_position(test): m = None for l in reversed(test.reporter.out.readlines()): l = l.lower() - if ""): position, duration = _parse_position(j) + elif j.startswith("buffering") and j.endswith("%"): + position, duration = _parse_buffering(j) return position, duration