1 #include <string.h>
2 #include <stdlib.h>
4 #include <gst/gst.h>
6 #define VM_THRES 1000
7 #define MAX_CONFIG_LINE 255
8 #define MAX_CONFIG_PATTERN 64
10 typedef struct
11 {
12 gint src_data;
13 gint src_sizetype;
15 gchar *bs_accesspattern;
17 gboolean integrity_check;
18 }
19 TestParam;
21 static GSList *params = NULL;
23 static guint8 count;
24 static guint iterations;
25 static gboolean integrity_check = TRUE;
26 static gboolean verbose = FALSE;
27 static gboolean dump = FALSE;
29 static void
30 handoff (GstElement * element, GstBuffer * buf, GstPad * pad, gpointer data)
31 {
32 if (GST_IS_BUFFER (buf)) {
33 if (integrity_check) {
34 gint i;
35 guint8 *ptr = GST_BUFFER_DATA (buf);
37 for (i = 0; i < GST_BUFFER_SIZE (buf); i++) {
38 if (*ptr++ != count++) {
39 g_print ("data error!\n");
40 return;
41 }
42 }
43 }
44 } else {
45 g_print ("not a buffer ! %p\n", buf);
46 }
47 }
48 static gchar *
49 create_desc (TestParam * param)
50 {
51 gchar *desc;
53 desc =
54 g_strdup_printf ("%s %s, pattern %s",
55 (param->src_sizetype == 2 ? "fixed" : "random"),
56 (param->src_data == 1 ? "src" : "subbuffer"), param->bs_accesspattern);
57 return desc;
58 }
60 static gboolean
61 read_param_file (gchar * filename)
62 {
63 FILE *fp;
64 gchar line[MAX_CONFIG_LINE + 1];
65 guint linenr = 0;
66 gchar pattern[MAX_CONFIG_PATTERN];
67 gint data, sizetype, integrity_check;
68 gchar *scan_str;
69 gboolean res = TRUE;
71 fp = fopen (filename, "r");
72 if (fp == NULL)
73 return FALSE;
75 scan_str = g_strdup_printf ("%%d %%d %%%ds %%d", MAX_CONFIG_PATTERN - 1);
77 while (fgets (line, MAX_CONFIG_LINE, fp)) {
78 linenr++;
80 if (line[0] == '\n' || line[0] == '#')
81 continue;
83 if (sscanf (line, scan_str, &data, &sizetype, pattern,
84 &integrity_check) != 4) {
85 g_print ("error on line: %d\n", linenr);
86 res = FALSE;
87 break;
88 } else {
89 TestParam *param = g_malloc (sizeof (TestParam));
91 param->src_data = data;
92 param->src_sizetype = sizetype;
93 param->bs_accesspattern = g_strdup (pattern);
94 param->integrity_check = (integrity_check == 0 ? FALSE : TRUE);
96 params = g_slist_append (params, param);
97 }
98 }
99 g_free (scan_str);
101 return res;
102 }
104 static void
105 run_test (GstBin * pipeline, gint iters)
106 {
107 gint vm = 0;
108 gint maxiters = iters;
109 gint prev_percent = -1;
111 count = 0;
112 gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
114 while (iters) {
115 gint newvm = gst_alloc_trace_live_all ();
116 gint percent;
118 percent = (gint) ((maxiters - iters + 1) * 100.0 / maxiters);
120 if (percent != prev_percent || newvm - vm > VM_THRES) {
121 g_print ("\r%d (delta %d) %.3d%% ", newvm, newvm - vm,
122 percent);
123 prev_percent = percent;
124 vm = newvm;
125 }
126 gst_bin_iterate (pipeline);
128 if (iters > 0)
129 iters--;
130 }
131 gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
132 }
134 static void
135 usage (char *argv[])
136 {
137 g_print ("usage: %s [--verbose] [--dump] <paramfile> <iterations>\n",
138 argv[0]);
139 }
141 int
142 main (int argc, char *argv[])
143 {
144 GstElement *src;
145 GstElement *sink;
146 GstElement *bs;
147 GstElement *pipeline;
148 gint testnum = 0;
149 GSList *walk;
150 gint arg_walk;
152 gst_alloc_trace_set_flags_all (GST_ALLOC_TRACE_LIVE);
153 gst_init (&argc, &argv);
155 arg_walk = 1;
156 while ((arg_walk < argc) && (argv[arg_walk][0] == '-')) {
157 if (!strncmp (argv[arg_walk], "--verbose", 9))
158 verbose = TRUE;
159 else if (!strncmp (argv[arg_walk], "--dump", 6))
160 dump = TRUE;
161 else {
162 g_print ("unknown option %s (ignored)\n", argv[arg_walk]);
163 }
165 arg_walk++;
166 }
167 if (argc - arg_walk < 2) {
168 usage (argv);
169 return -1;
170 }
171 if (!read_param_file (argv[arg_walk])) {
172 g_print ("error reading file %s\n", argv[arg_walk]);
173 usage (argv);
174 return -1;
175 }
176 arg_walk++;
177 iterations = atoi (argv[arg_walk]);
179 pipeline = gst_element_factory_make ("pipeline", "pipeline");
180 g_assert (pipeline);
182 src = gst_element_factory_make ("fakesrc", "src");
183 g_assert (src);
185 sink = gst_element_factory_make ("fakesink", "sink");
186 g_assert (sink);
187 g_object_set (sink, "signal-handoff", TRUE, NULL);
188 g_signal_connect (G_OBJECT (sink), "handoff", G_CALLBACK (handoff), NULL);
190 bs = gst_element_factory_make ("bstest", "bs");
191 g_assert (bs);
193 gst_element_link_many (src, bs, sink);
195 gst_bin_add_many (GST_BIN (pipeline), src, bs, sink);
197 walk = params;
199 while (walk) {
200 gchar *desc;
201 TestParam *param = (TestParam *) (walk->data);
203 integrity_check = param->integrity_check;
205 g_print ("\n\nrunning test %d (%d iterations):\n", testnum + 1, iterations);
206 desc = create_desc (param);
207 g_print ("%s\n", desc);
208 g_free (desc);
210 g_object_set (G_OBJECT (src), "data", param->src_data,
211 "sizetype", param->src_sizetype,
212 "filltype", (integrity_check ? 5 : 0), "silent", !verbose, NULL);
214 g_object_set (G_OBJECT (bs), "accesspattern", param->bs_accesspattern,
215 "silent", !verbose, NULL);
217 g_object_set (G_OBJECT (sink), "dump", dump, "silent", !verbose, NULL);
219 run_test (GST_BIN (pipeline), iterations);
221 testnum++;
223 walk = g_slist_next (walk);
224 }
226 g_print ("\n\ndone\n");
228 return 0;
230 }