1 | #ifdef HAVE_CONFIG_H |
---|
2 | # include "config.h" |
---|
3 | #endif |
---|
4 | |
---|
5 | #include <string.h> |
---|
6 | #include <stdlib.h> |
---|
7 | #include <gst/gst.h> |
---|
8 | #include <locale.h> |
---|
9 | |
---|
10 | static guint64 iterations = 0; |
---|
11 | static guint64 sum = 0; |
---|
12 | static guint64 min = G_MAXINT64; |
---|
13 | static guint64 max = 0; |
---|
14 | static GstClock *s_clock; |
---|
15 | |
---|
16 | gboolean |
---|
17 | idle_func (gpointer data) |
---|
18 | { |
---|
19 | gboolean busy; |
---|
20 | GTimeVal tfthen, tfnow; |
---|
21 | GstClockTimeDiff diff; |
---|
22 | |
---|
23 | if (s_clock) { |
---|
24 | //g_print ("%lld\n", gst_clock_get_time (s_clock)); |
---|
25 | } |
---|
26 | |
---|
27 | g_get_current_time (&tfthen); |
---|
28 | busy = gst_bin_iterate (GST_BIN (data)); |
---|
29 | iterations++; |
---|
30 | g_get_current_time (&tfnow); |
---|
31 | |
---|
32 | diff = GST_TIMEVAL_TO_TIME (tfnow) - GST_TIMEVAL_TO_TIME (tfthen); |
---|
33 | |
---|
34 | sum += diff; |
---|
35 | min = MIN (min, diff); |
---|
36 | max = MAX (max, diff); |
---|
37 | |
---|
38 | if (!busy) { |
---|
39 | gst_main_quit (); |
---|
40 | /* |
---|
41 | g_print ("execution ended after %llu iterations (sum %llu ns, average %llu ns, min %llu ns, max %llu ns)\n", |
---|
42 | iterations, sum, sum/iterations, min, max); |
---|
43 | */ |
---|
44 | } |
---|
45 | |
---|
46 | return busy; |
---|
47 | } |
---|
48 | |
---|
49 | int |
---|
50 | main (int argc, char *argv[]) |
---|
51 | { |
---|
52 | /* options */ |
---|
53 | gboolean verbose = FALSE; |
---|
54 | gchar *exclude_args = NULL; |
---|
55 | struct poptOption options[] = { |
---|
56 | {"verbose", 'v', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &verbose, 0, |
---|
57 | "do not output status information", NULL}, |
---|
58 | POPT_TABLEEND |
---|
59 | }; |
---|
60 | |
---|
61 | GstElement *pipeline = NULL; |
---|
62 | gchar **argvn; |
---|
63 | GError *error = NULL; |
---|
64 | GstElement *md5sink; |
---|
65 | gchar *md5string = g_malloc0 (33); |
---|
66 | |
---|
67 | free (malloc (8)); /* -lefence */ |
---|
68 | |
---|
69 | setlocale (LC_ALL, ""); |
---|
70 | |
---|
71 | gst_init_with_popt_table (&argc, &argv, options); |
---|
72 | |
---|
73 | /* make a parseable argvn array */ |
---|
74 | argvn = g_new0 (char *, argc); |
---|
75 | memcpy (argvn, argv + 1, sizeof (char *) * (argc - 1)); |
---|
76 | |
---|
77 | /* Check if we have an element already that is called md5sink0 |
---|
78 | in the pipeline; if not, add one */ |
---|
79 | pipeline = (GstElement *) gst_parse_launchv ((const gchar **) argvn, &error); |
---|
80 | if (!pipeline) { |
---|
81 | if (error) { |
---|
82 | g_warning ("pipeline could not be constructed: %s\n", error->message); |
---|
83 | g_error_free (error); |
---|
84 | } else |
---|
85 | g_warning ("pipeline could not be constructed\n"); |
---|
86 | return 1; |
---|
87 | } |
---|
88 | |
---|
89 | md5sink = gst_bin_get_by_name (GST_BIN (pipeline), "md5sink0"); |
---|
90 | if (md5sink == NULL) { |
---|
91 | g_print ("adding an md5sink element to the pipeline\n"); |
---|
92 | /* make a null-terminated version of argv with ! md5sink appended |
---|
93 | * ! is stored in argvn[argc - 1], md5sink in argvn[argc], |
---|
94 | * NULL pointer in argvn[argc + 1] */ |
---|
95 | g_free (argvn); |
---|
96 | argvn = g_new0 (char *, argc + 2); |
---|
97 | memcpy (argvn, argv + 1, sizeof (char *) * (argc - 1)); |
---|
98 | argvn[argc - 1] = g_strdup_printf ("!"); |
---|
99 | argvn[argc] = g_strdup_printf ("md5sink"); |
---|
100 | pipeline = |
---|
101 | (GstElement *) gst_parse_launchv ((const gchar **) argvn, &error); |
---|
102 | } |
---|
103 | |
---|
104 | if (!pipeline) { |
---|
105 | if (error) { |
---|
106 | g_warning ("pipeline could not be constructed: %s\n", error->message); |
---|
107 | g_error_free (error); |
---|
108 | } else |
---|
109 | g_warning ("pipeline could not be constructed\n"); |
---|
110 | return 1; |
---|
111 | } |
---|
112 | |
---|
113 | if (verbose) { |
---|
114 | gchar **exclude_list = exclude_args ? g_strsplit (exclude_args, ",", 0) |
---|
115 | : NULL; |
---|
116 | |
---|
117 | g_signal_connect (pipeline, "deep_notify", |
---|
118 | G_CALLBACK (gst_element_default_deep_notify), exclude_list); |
---|
119 | } |
---|
120 | g_signal_connect (pipeline, "error", |
---|
121 | G_CALLBACK (gst_element_default_error), NULL); |
---|
122 | |
---|
123 | if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) { |
---|
124 | g_warning ("pipeline doesn't want to play\n"); |
---|
125 | return 0; |
---|
126 | } |
---|
127 | |
---|
128 | if (!GST_FLAG_IS_SET (GST_OBJECT (pipeline), GST_BIN_SELF_SCHEDULABLE)) { |
---|
129 | g_idle_add (idle_func, pipeline); |
---|
130 | gst_main (); |
---|
131 | } else { |
---|
132 | gst_element_wait_state_change (pipeline); |
---|
133 | } |
---|
134 | |
---|
135 | gst_element_set_state (pipeline, GST_STATE_NULL); |
---|
136 | |
---|
137 | /* print out md5sink here */ |
---|
138 | md5sink = gst_bin_get_by_name (GST_BIN (pipeline), "md5sink0"); |
---|
139 | g_assert (md5sink); |
---|
140 | g_object_get (G_OBJECT (md5sink), "md5", &md5string, NULL); |
---|
141 | printf ("%s\n", md5string); |
---|
142 | |
---|
143 | gst_object_unref (GST_OBJECT (pipeline)); |
---|
144 | |
---|
145 | return 0; |
---|
146 | } |
---|