Commit c7c2f057 authored by Seungha Yang's avatar Seungha Yang

gst-launch: Add support printing current position of pipeline

Add new opetion "position" to enable print out current position.
Without this, users couldn't estimate how long the task will take.
parent b5286f05
Pipeline #23229 passed with stages
in 25 minutes and 9 seconds
......@@ -66,6 +66,7 @@ static gboolean messages = FALSE;
static gboolean is_live = FALSE;
static gboolean waiting_eos = FALSE;
static gchar **exclude_args = NULL;
static gboolean buffering = FALSE;
/* convenience macro so we don't have to litter the code with if(!quiet) */
#define PRINT if(!quiet)g_print
......@@ -539,7 +540,7 @@ event_loop (GstElement * pipeline, gboolean blocking, gboolean do_progress,
GstBus *bus;
GstMessage *message = NULL;
EventLoopResult res = ELR_NO_ERROR;
gboolean buffering = FALSE, in_progress = FALSE;
gboolean in_progress = FALSE;
gboolean prerolled = target_state != GST_STATE_PAUSED;
bus = gst_element_get_bus (GST_ELEMENT (pipeline));
......@@ -974,6 +975,68 @@ bus_sync_handler (GstBus * bus, GstMessage * message, gpointer data)
return GST_BUS_PASS;
}
typedef struct _PositionMonitorData
{
GMainContext *context;
GMainLoop *loop;
GstElement *pipeline;
} PositionMonitorData;
static gboolean
query_pipeline_position (gpointer user_data)
{
GstElement *pipeline = (GstElement *) user_data;
gint64 pos = -1, dur = -1;
if (buffering)
return G_SOURCE_CONTINUE;
gst_element_query_position (pipeline, GST_FORMAT_TIME, &pos);
gst_element_query_duration (pipeline, GST_FORMAT_TIME, &dur);
if (pos >= 0) {
gchar dstr[32], pstr[32];
/* FIXME: pretty print in nicer format */
g_snprintf (pstr, 32, "%" GST_TIME_FORMAT, GST_TIME_ARGS (pos));
pstr[9] = '\0';
g_snprintf (dstr, 32, "%" GST_TIME_FORMAT, GST_TIME_ARGS (dur));
dstr[9] = '\0';
if (dur > 0 && dur >= pos) {
gdouble percent;
percent = 100 * (gdouble) (pos) / dur;
g_print ("%s / %s (%.1f %%)\r", pstr, dstr, percent);
} else
g_print ("%s / %s\r", pstr, dstr);
}
return G_SOURCE_CONTINUE;
}
static gpointer
position_progress (gpointer data)
{
PositionMonitorData *pos_data = (PositionMonitorData *) data;
GSource *timeout_source;
g_main_context_push_thread_default (pos_data->context);
timeout_source = g_timeout_source_new (100);
g_source_set_callback (timeout_source, query_pipeline_position,
pos_data->pipeline, NULL);
g_source_attach (timeout_source, pos_data->context);
g_main_loop_run (pos_data->loop);
g_source_destroy (timeout_source);
g_source_unref (timeout_source);
g_main_context_pop_thread_default (pos_data->context);
return NULL;
}
int
main (int argc, char *argv[])
{
......@@ -981,6 +1044,7 @@ main (int argc, char *argv[])
gboolean verbose = FALSE;
gboolean no_fault = FALSE;
gboolean eos_on_shutdown = FALSE;
gboolean position = FALSE;
#if 0
gboolean check_index = FALSE;
#endif
......@@ -1010,6 +1074,8 @@ main (int argc, char *argv[])
N_("Gather and print index statistics"), NULL},
#endif
GST_TOOLS_GOPTION_VERSION,
{"position", 'p', 0, G_OPTION_ARG_NONE, &position,
N_("Output current position of pipeline"), NULL},
{NULL}
};
GOptionContext *ctx;
......@@ -1165,6 +1231,8 @@ main (int argc, char *argv[])
} else {
GstClockTime tfthen, tfnow;
GstClockTimeDiff diff;
GThread *pos_thread = NULL;
PositionMonitorData pos_data = { 0, };
PRINT (_("Setting pipeline to PLAYING ...\n"));
......@@ -1185,6 +1253,24 @@ main (int argc, char *argv[])
}
tfthen = gst_util_get_timestamp ();
if (position) {
pos_data.context = g_main_context_new ();
pos_data.loop = g_main_loop_new (pos_data.context, FALSE);
pos_data.pipeline = pipeline;
pos_thread = g_thread_try_new ("gst-launch-position-monitor",
position_progress, &pos_data, NULL);
if (!pos_thread) {
g_printerr (_("ERROR: cannot monitor pipeline's position.\n"));
g_main_loop_unref (pos_data.loop);
g_main_context_unref (pos_data.context);
pos_data.loop = NULL;
pos_data.context = NULL;
pos_data.pipeline = NULL;
}
}
caught_error = event_loop (pipeline, TRUE, FALSE, GST_STATE_PLAYING);
res = caught_error;
if (eos_on_shutdown && caught_error != ELR_NO_ERROR) {
......@@ -1228,6 +1314,14 @@ main (int argc, char *argv[])
PRINT (_("Execution ended after %" GST_TIME_FORMAT "\n"),
GST_TIME_ARGS (diff));
if (pos_thread) {
g_main_loop_quit (pos_data.loop);
g_thread_join (pos_thread);
g_main_loop_unref (pos_data.loop);
g_main_context_unref (pos_data.context);
}
}
PRINT (_("Setting pipeline to PAUSED ...\n"));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment