1 /* GStreamer
2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
4 *
5 * gstbstest.c:
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 #include <stdlib.h>
27 #include <string.h>
29 #include <gst/gst.h>
30 #include <gst/bytestream/bytestream.h>
32 #define GST_TYPE_BSTEST (gst_bstest_get_type())
33 #define GST_BSTEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BSTEST,GstBsTest))
34 #define GST_BSTEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BSTEST,GstBsTestClass))
35 #define GST_IS_BSTEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BSTEST))
36 #define GST_IS_BSTEST_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BSTEST))
38 typedef struct _GstBsTest GstBsTest;
39 typedef struct _GstBsTestClass GstBsTestClass;
41 struct _GstBsTest
42 {
43 GstElement element;
45 GstPad *sinkpad;
46 GstPad *srcpad;
48 GstByteStream *bs;
50 gchar *accesspattern;
51 guint num_patterns;
52 gchar **patterns;
53 guint sizemin;
54 guint sizemax;
55 gint count;
56 gboolean silent;
57 };
59 struct _GstBsTestClass
60 {
61 GstElementClass parent_class;
62 };
64 GType gst_bstest_get_type (void);
67 GstElementDetails gst_bstest_details = GST_ELEMENT_DETAILS ("ByteStreamTest",
68 "Filter",
69 "Test for the GstByteStream code",
70 "Erik Walthinsen <omega@temple-baptist.com>, "
71 "Wim Taymans <wim.taymans@chello.be>");
74 /* BsTest signals and args */
75 enum
76 {
77 /* FILL ME */
78 LAST_SIGNAL
79 };
81 enum
82 {
83 ARG_0,
84 ARG_SIZEMIN,
85 ARG_SIZEMAX,
86 ARG_COUNT,
87 ARG_SILENT,
88 ARG_ACCESSPATTERN,
89 };
92 static void gst_bstest_base_init (gpointer g_class);
93 static void gst_bstest_class_init (GstBsTestClass * klass);
94 static void gst_bstest_init (GstBsTest * bstest);
96 static void gst_bstest_set_property (GObject * object, guint prop_id,
97 const GValue * value, GParamSpec * pspec);
98 static void gst_bstest_get_property (GObject * object, guint prop_id,
99 GValue * value, GParamSpec * pspec);
101 static GstElementStateReturn gst_bstest_change_state (GstElement * element);
102 static void gst_bstest_loop (GstElement * element);
104 static GstElementClass *parent_class = NULL;
106 /* static guint gst_bstest_signals[LAST_SIGNAL] = { 0 }; */
108 GType
109 gst_bstest_get_type (void)
110 {
111 static GType bstest_type = 0;
113 if (!bstest_type) {
114 static const GTypeInfo bstest_info = {
115 sizeof (GstBsTestClass),
116 gst_bstest_base_init,
117 NULL,
118 (GClassInitFunc) gst_bstest_class_init,
119 NULL,
120 NULL,
121 sizeof (GstBsTest),
122 0,
123 (GInstanceInitFunc) gst_bstest_init,
124 };
126 bstest_type =
127 g_type_register_static (GST_TYPE_ELEMENT, "BSTest", &bstest_info, 0);
128 }
129 return bstest_type;
130 }
131 static void
132 gst_bstest_base_init (gpointer g_class)
133 {
134 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
136 gst_element_class_set_details (gstelement_class, &gst_bstest_details);
137 }
139 static void
140 gst_bstest_class_init (GstBsTestClass * klass)
141 {
142 GObjectClass *gobject_class;
143 GstElementClass *gstelement_class;
145 gobject_class = (GObjectClass *) klass;
146 gstelement_class = (GstElementClass *) klass;
148 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
150 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
151 g_param_spec_int ("sizemin", "sizemin", "sizemin", 0, G_MAXINT,
152 0, G_PARAM_READWRITE));
153 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX,
154 g_param_spec_int ("sizemax", "sizemax", "sizemax", 0, G_MAXINT,
155 384, G_PARAM_READWRITE));
156 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACCESSPATTERN,
157 g_param_spec_string ("accesspattern", "accesspattern", "accesspattern",
158 "r", G_PARAM_READWRITE));
159 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COUNT,
160 g_param_spec_uint ("count", "count", "count",
161 0, G_MAXUINT, 0, G_PARAM_READWRITE));
162 g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
163 g_param_spec_boolean ("silent", "silent", "silent",
164 FALSE, G_PARAM_READWRITE));
166 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bstest_set_property);
167 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bstest_get_property);
169 gstelement_class->change_state = gst_bstest_change_state;
171 }
173 static GstCaps *
174 gst_bstest_getcaps (GstPad * pad)
175 {
176 GstBsTest *bstest = GST_BSTEST (gst_pad_get_parent (pad));
177 GstPad *otherpad;
179 otherpad = (pad == bstest->srcpad) ? bstest->sinkpad : bstest->srcpad;
181 return gst_pad_get_allowed_caps (otherpad);
182 }
184 static void
185 gst_bstest_init (GstBsTest * bstest)
186 {
187 bstest->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
188 gst_element_add_pad (GST_ELEMENT (bstest), bstest->sinkpad);
189 gst_pad_set_getcaps_function (bstest->sinkpad, gst_bstest_getcaps);
191 bstest->srcpad = gst_pad_new ("src", GST_PAD_SRC);
192 gst_element_add_pad (GST_ELEMENT (bstest), bstest->srcpad);
193 gst_pad_set_getcaps_function (bstest->srcpad, gst_bstest_getcaps);
195 gst_element_set_loop_function (GST_ELEMENT (bstest), gst_bstest_loop);
197 bstest->sizemin = 0;
198 bstest->sizemax = 384;
199 bstest->accesspattern = g_strdup ("r");
200 bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0);
201 bstest->count = 5;
202 bstest->silent = FALSE;
203 bstest->bs = NULL;
204 }
206 static guint
207 gst_bstest_get_size (GstBsTest * bstest, gchar * sizestring, guint prevsize)
208 {
209 guint size;
211 if (sizestring[0] == 0) {
212 size = bstest->sizemax;
213 } else if (sizestring[0] == 'r') {
214 size =
215 bstest->sizemin +
216 (guint8) (((gfloat) bstest->sizemax) * rand () / (RAND_MAX +
217 (gfloat) bstest->sizemin));
218 } else if (sizestring[0] == '<') {
219 size = prevsize;
220 } else {
221 size = atoi (sizestring);
222 }
224 if (size == 0)
225 size++;
227 return size;
228 }
230 static void
231 gst_bstest_loop (GstElement * element)
232 {
233 GstBsTest *bstest;
234 GstBuffer *buf = NULL;
236 g_return_if_fail (element != NULL);
237 g_return_if_fail (GST_IS_BSTEST (element));
239 bstest = GST_BSTEST (element);
241 do {
242 guint size = 0;
243 guint i = 0;
244 guint8 *ptr;
246 while (i < bstest->num_patterns) {
247 buf = NULL;
249 if (bstest->patterns[i][0] == 'r') {
250 size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
251 if (!bstest->silent)
252 g_print ("bstest: ***** read %d bytes\n", size);
253 gst_bytestream_read (bstest->bs, &buf, size);
254 } else if (bstest->patterns[i][0] == 'f') {
255 size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
256 if (!bstest->silent)
257 g_print ("bstest: ***** flush %d bytes\n", size);
258 gst_bytestream_flush (bstest->bs, size);
259 } else if (!strncmp (bstest->patterns[i], "pb", 2)) {
260 size = gst_bstest_get_size (bstest, &bstest->patterns[i][2], size);
261 if (!bstest->silent)
262 g_print ("bstest: ***** peek bytes %d bytes\n", size);
263 gst_bytestream_peek_bytes (bstest->bs, &ptr, size);
264 } else if (bstest->patterns[i][0] == 'p') {
265 size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
266 if (!bstest->silent)
267 g_print ("bstest: ***** peek %d bytes\n", size);
268 gst_bytestream_peek (bstest->bs, &buf, size);
269 gst_buffer_unref (buf);
270 buf = NULL;
271 }
273 if (buf)
274 gst_pad_push (bstest->srcpad, GST_DATA (buf));
276 i++;
277 }
278 /* } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); */
280 } while (0);
281 }
283 static void
284 gst_bstest_set_property (GObject * object, guint prop_id, const GValue * value,
285 GParamSpec * pspec)
286 {
287 GstBsTest *bstest;
289 /* it's not null if we got it, but it might not be ours */
290 g_return_if_fail (GST_IS_BSTEST (object));
292 bstest = GST_BSTEST (object);
294 switch (prop_id) {
295 case ARG_SIZEMIN:
296 bstest->sizemin = g_value_get_int (value);
297 break;
298 case ARG_SIZEMAX:
299 bstest->sizemax = g_value_get_int (value);
300 break;
301 case ARG_ACCESSPATTERN:
302 if (bstest->accesspattern) {
303 g_free (bstest->accesspattern);
304 g_strfreev (bstest->patterns);
305 }
306 if (g_value_get_string (value) == NULL) {
307 gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL);
308 bstest->accesspattern = NULL;
309 bstest->num_patterns = 0;
310 } else {
311 guint i = 0;
313 bstest->accesspattern = g_strdup (g_value_get_string (value));
314 bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0);
315 while (bstest->patterns[i++]);
316 bstest->num_patterns = i - 1;
317 }
318 break;
319 case ARG_COUNT:
320 bstest->count = g_value_get_uint (value);
321 break;
322 case ARG_SILENT:
323 bstest->silent = g_value_get_boolean (value);
324 break;
325 default:
326 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
327 break;
328 }
329 }
331 static void
332 gst_bstest_get_property (GObject * object, guint prop_id, GValue * value,
333 GParamSpec * pspec)
334 {
335 GstBsTest *bstest;
337 /* it's not null if we got it, but it might not be ours */
338 g_return_if_fail (GST_IS_BSTEST (object));
340 bstest = GST_BSTEST (object);
342 switch (prop_id) {
343 case ARG_SIZEMIN:
344 g_value_set_int (value, bstest->sizemin);
345 break;
346 case ARG_SIZEMAX:
347 g_value_set_int (value, bstest->sizemax);
348 break;
349 case ARG_ACCESSPATTERN:
350 g_value_set_string (value, bstest->accesspattern);
351 break;
352 case ARG_COUNT:
353 g_value_set_uint (value, bstest->count);
354 break;
355 case ARG_SILENT:
356 g_value_set_boolean (value, bstest->silent);
357 break;
358 default:
359 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
360 break;
361 }
362 }
364 static GstElementStateReturn
365 gst_bstest_change_state (GstElement * element)
366 {
367 GstBsTest *bstest;
369 g_return_val_if_fail (GST_IS_BSTEST (element), GST_STATE_FAILURE);
371 bstest = GST_BSTEST (element);
373 if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
374 if (bstest->bs) {
375 gst_bytestream_destroy (bstest->bs);
376 bstest->bs = NULL;
377 }
378 } else {
379 if (!bstest->bs) {
380 bstest->bs = gst_bytestream_new (bstest->sinkpad);
381 }
382 }
384 if (GST_ELEMENT_CLASS (parent_class)->change_state)
385 return GST_ELEMENT_CLASS (parent_class)->change_state (element);
387 return GST_STATE_SUCCESS;
388 }
390 static gboolean
391 plugin_init (GstPlugin * plugin)
392 {
393 /* We need to create an ElementFactory for each element we provide.
394 * This consists of the name of the element, the GType identifier,
395 * and a pointer to the details structure at the top of the file.
396 */
397 return gst_element_register (plugin, "bstest", GST_RANK_PRIMARY,
398 GST_TYPE_BSTEST);
399 }
401 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
402 GST_VERSION_MINOR,
403 "bstest",
404 "test for the bytestream element",
405 plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)