diff --git a/tools/gst-md5sum.1 b/tools/gst-md5sum.1 new file mode 100644 index 0000000000..9bd71cbc45 --- /dev/null +++ b/tools/gst-md5sum.1 @@ -0,0 +1,53 @@ +.TH "GStreamer" "1" "September 2002" +.SH "NAME" +gst\-md5sum \- get an md5sum of a GStreamer pipeline through md5sink +.SH "SYNOPSIS" +\fBgst\-md5sum\fR \fI[OPTION...]\fR PARTIAL\-PIPELINE\-DESCRIPTION +.SH "DESCRIPTION" +.LP +\fIgst\-md5sum\fP is a tool that is used to get an md5 sum of +a basic \fIGStreamer\fP pipeline. + +In theory, running + + gst-md5sum filesrc location=music.mp3 + +should print out the same md5sum as + + md5sum music.mp3 + +Make sure the pipeline given is a partial one, to which a sink still +needs to be connected. + +See other docs, examples, and the source for description on how to +create a PARTIAL\-PIPELINE\-DESCRIPTION. +. +.SH "OPTIONS" +.l +\fIgst\-md5sum\fP accepts the following options: +.TP 8 +.B \-\-help +Print help synopsis and available FLAGS +.TP 8 +.B \-v +Output verbose information +.TP 8 +.B \-\-gst\-info\-mask=FLAGS +\fIGStreamer\fP info flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-debug\-mask=FLAGS +\fIGStreamer\fP debugging flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-mask=FLAGS +\fIGStreamer\fP info and debugging flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-plugin\-spew +\fIGStreamer\fP info flags to set +Enable printout of errors while loading \fIGStreamer\fP plugins +.TP 8 +.B \-\-gst\-plugin\-path=PATH +Add directories separated with ':' to the plugin search path +.SH "SEE ALSO" +.BR gst\-launch (1) +.SH "AUTHOR" +The GStreamer team at http://gstreamer.net/ diff --git a/tools/gst-md5sum.c b/tools/gst-md5sum.c new file mode 100644 index 0000000000..c916873f13 --- /dev/null +++ b/tools/gst-md5sum.c @@ -0,0 +1,123 @@ +#include +#include +#include + +static guint64 iterations = 0; +static guint64 sum = 0; +static guint64 min = G_MAXINT64; +static guint64 max = 0; +static GstClock *s_clock; + +gboolean +idle_func (gpointer data) +{ + gboolean busy; + GTimeVal tfthen, tfnow; + GstClockTimeDiff diff; + + if (s_clock) { + //g_print ("%lld\n", gst_clock_get_time (s_clock)); + } + + g_get_current_time (&tfthen); + busy = gst_bin_iterate (GST_BIN (data)); + iterations++; + g_get_current_time (&tfnow); + + diff = GST_TIMEVAL_TO_TIME (tfnow) - + GST_TIMEVAL_TO_TIME (tfthen); + + sum += diff; + min = MIN (min, diff); + max = MAX (max, diff); + + if (!busy) { + gst_main_quit (); + /* + g_print ("execution ended after %llu iterations (sum %llu ns, average %llu ns, min %llu ns, max %llu ns)\n", + iterations, sum, sum/iterations, min, max); + */ + } + + return busy; +} + +int +main (int argc, char *argv[]) +{ + /* options */ + gboolean verbose = FALSE; + gchar *exclude_args = NULL; + struct poptOption options[] = { + {"verbose", 'v', POPT_ARG_NONE|POPT_ARGFLAG_STRIP, &verbose, 0, + "do not output status information", NULL}, + POPT_TABLEEND + }; + + GstElement *pipeline; + gchar **argvn; + GError *error = NULL; + GstElement *md5sink; + gchar *md5string = g_malloc0 (33); + + free (malloc (8)); /* -lefence */ + + gst_init_with_popt_table (&argc, &argv, options); + + /* make a null-terminated version of argv with ! md5sink appended + * ! is stored in argvn[argc - 1], md5sink in argvn[argc], + * NULL pointer in argvn[argc + 1] */ + argvn = g_new0 (char *, argc + 2); + memcpy (argvn, argv + 1, sizeof (char *) * (argc - 1)); + argvn[argc - 1] = g_strdup_printf ("!"); + argvn[argc] = g_strdup_printf ("md5sink"); + + pipeline = (GstElement*) gst_parse_launchv ((const gchar**) argvn, &error); + + if (!pipeline) { + if (error) + { + g_warning ("pipeline could not be constructed: %s\n", error->message); + g_error_free (error); + } + else + g_warning ("pipeline could not be constructed\n"); + return 1; + } + + if (verbose) + { + gchar **exclude_list = exclude_args ? g_strsplit (exclude_args, ",", 0) + : NULL; + g_signal_connect (pipeline, "deep_notify", + G_CALLBACK (gst_element_default_deep_notify), + exclude_list); + } + g_signal_connect (pipeline, "error", + G_CALLBACK (gst_element_default_error), NULL); + + if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) + { + g_warning ("pipeline doesn't want to play\n"); + return 0; + } + + if (!GST_FLAG_IS_SET (GST_OBJECT (pipeline), GST_BIN_SELF_SCHEDULABLE)) { + g_idle_add (idle_func, pipeline); + gst_main (); + } else { + gst_element_wait_state_change (pipeline); + } + + gst_element_set_state (pipeline, GST_STATE_NULL); + + /* print out md5sink here */ + md5sink = gst_bin_get_by_name (GST_BIN (pipeline), "md5sink0"); + g_assert (md5sink); + g_object_get (G_OBJECT (md5sink), "md5", &md5string, NULL); + printf ("%s\n", md5string); + + gst_object_unref (GST_OBJECT (pipeline)); + + return 0; +}