fixes for make distcheck does GST_ELEMENT_IS_COTHREAD_STOPPING still exist ? and...
[platform/upstream/gstreamer.git] / testsuite / bytestream / gstbstest.c
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  */
22
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include <gst/gst.h>
27 #include <gst/bytestream/bytestream.h>
28
29 #define GST_TYPE_BSTEST                 (gst_bstest_get_type())
30 #define GST_BSTEST(obj)                 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BSTEST,GstBsTest))
31 #define GST_BSTEST_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BSTEST,GstBsTestClass))
32 #define GST_IS_BSTEST(obj)              (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BSTEST))
33 #define GST_IS_BSTEST_CLASS(obj)        (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BSTEST))
34
35 typedef struct _GstBsTest GstBsTest;
36 typedef struct _GstBsTestClass GstBsTestClass;
37
38 struct _GstBsTest
39 {
40   GstElement element;
41
42   GstPad *sinkpad;
43   GstPad *srcpad;
44
45   GstByteStream *bs;
46   
47   gchar         *accesspattern;
48   guint         num_patterns;
49   gchar         **patterns;
50   guint         sizemin;
51   guint         sizemax;
52   gint          count;
53   gboolean      silent;
54 };
55
56 struct _GstBsTestClass
57 {
58   GstElementClass parent_class;
59 };
60
61 GType gst_bstest_get_type (void);
62
63
64 GstElementDetails gst_bstest_details = {
65   "ByteStreamTest",
66   "Filter",
67   "Test for the GstByteStream code",
68   VERSION,
69   "Erik Walthinsen <omega@temple-baptist.com>," "Wim Taymans <wim.taymans@chello.be>",
70   "(C) 2001",
71 };
72
73
74 /* BsTest signals and args */
75 enum
76 {
77   /* FILL ME */
78   LAST_SIGNAL
79 };
80
81 enum
82 {
83   ARG_0,
84   ARG_SIZEMIN,
85   ARG_SIZEMAX,
86   ARG_COUNT,
87   ARG_SILENT,
88   ARG_ACCESSPATTERN,
89 };
90
91
92 static void     gst_bstest_class_init           (GstBsTestClass * klass);
93 static void     gst_bstest_init                 (GstBsTest * bstest);
94
95 static void gst_bstest_set_property (GObject * object, guint prop_id, const GValue * value,
96                                      GParamSpec * pspec);
97 static void gst_bstest_get_property (GObject * object, guint prop_id, GValue * value,
98                                      GParamSpec * pspec);
99
100 static GstElementStateReturn    gst_bstest_change_state         (GstElement *element);
101 static void                     gst_bstest_loop                 (GstElement * element);
102
103 static GstElementClass *parent_class = NULL;
104
105 // static guint gst_bstest_signals[LAST_SIGNAL] = { 0 };
106
107 GType
108 gst_bstest_get_type (void)
109 {
110   static GType bstest_type = 0;
111
112   if (!bstest_type) {
113     static const GTypeInfo bstest_info = {
114       sizeof (GstBsTestClass), NULL,
115       NULL,
116       (GClassInitFunc) gst_bstest_class_init,
117       NULL,
118       NULL,
119       sizeof (GstBsTest),
120       0,
121       (GInstanceInitFunc) gst_bstest_init,
122     };
123
124     bstest_type = g_type_register_static (GST_TYPE_ELEMENT, "BSTest", &bstest_info, 0);
125   }
126   return bstest_type;
127 }
128
129 static void
130 gst_bstest_class_init (GstBsTestClass * klass)
131 {
132   GObjectClass *gobject_class;
133   GstElementClass *gstelement_class;
134
135   gobject_class = (GObjectClass *) klass;
136   gstelement_class = (GstElementClass*)klass;
137
138   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
139
140   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
141                                    g_param_spec_int ("sizemin", "sizemin", "sizemin", 0, G_MAXINT,
142                                                      0, G_PARAM_READWRITE));
143   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX,
144                                    g_param_spec_int ("sizemax", "sizemax", "sizemax", 0, G_MAXINT,
145                                                      384, G_PARAM_READWRITE));
146   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACCESSPATTERN,
147                                    g_param_spec_string ("accesspattern", "accesspattern", "accesspattern",
148                                                       "r", G_PARAM_READWRITE));
149   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COUNT,
150                                    g_param_spec_uint ("count", "count", "count",
151                                                       0, G_MAXUINT, 0, G_PARAM_READWRITE));
152   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
153                                    g_param_spec_boolean ("silent", "silent", "silent",
154                                                           FALSE, G_PARAM_READWRITE));
155
156   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bstest_set_property);
157   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bstest_get_property);
158
159   gstelement_class->change_state = gst_bstest_change_state;
160
161 }
162
163 static GstPadNegotiateReturn
164 gst_bstest_negotiate_src (GstPad * pad, GstCaps ** caps, gpointer * data)
165 {
166   GstBsTest *bstest;
167
168   bstest = GST_BSTEST (gst_pad_get_parent (pad));
169
170   return gst_pad_negotiate_proxy (pad, bstest->sinkpad, caps);
171 }
172
173 static GstPadNegotiateReturn
174 gst_bstest_negotiate_sink (GstPad * pad, GstCaps ** caps, gpointer * data)
175 {
176   GstBsTest *bstest;
177
178   bstest = GST_BSTEST (gst_pad_get_parent (pad));
179
180   return gst_pad_negotiate_proxy (pad, bstest->srcpad, caps);
181 }
182
183 static void
184 gst_bstest_init (GstBsTest * bstest)
185 {
186   bstest->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
187   gst_element_add_pad (GST_ELEMENT (bstest), bstest->sinkpad);
188   gst_pad_set_negotiate_function (bstest->sinkpad, gst_bstest_negotiate_sink);
189
190   bstest->srcpad = gst_pad_new ("src", GST_PAD_SRC);
191   gst_element_add_pad (GST_ELEMENT (bstest), bstest->srcpad);
192   gst_pad_set_negotiate_function (bstest->srcpad, gst_bstest_negotiate_src);
193
194   gst_element_set_loop_function (GST_ELEMENT (bstest), gst_bstest_loop);
195
196   bstest->sizemin = 0;
197   bstest->sizemax = 384;
198   bstest->accesspattern = g_strdup ("r");
199   bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0);
200   bstest->count = 5;
201   bstest->silent = FALSE;
202   bstest->bs = NULL;
203 }
204
205 static guint
206 gst_bstest_get_size (GstBsTest *bstest, gchar *sizestring, guint prevsize)
207 {
208   guint size;
209
210   if (sizestring[0] == 0) {
211     size = bstest->sizemax;
212   }
213   else if (sizestring[0] == 'r') {
214     size = bstest->sizemin + (guint8)(((gfloat)bstest->sizemax)*rand()/(RAND_MAX + (gfloat)bstest->sizemin));
215   }
216   else if (sizestring[0] == '<') {
217     size = prevsize;
218   }
219   else {
220     size = atoi (sizestring);
221   }
222
223   if (size == 0) size++;
224
225   return size;
226 }
227
228 static void
229 gst_bstest_loop (GstElement * element)
230 {
231   GstBsTest *bstest;
232   GstBuffer *buf = NULL;
233
234   g_return_if_fail (element != NULL);
235   g_return_if_fail (GST_IS_BSTEST (element));
236
237   bstest = GST_BSTEST (element);
238
239   do {
240     guint size = 0;
241     guint i = 0;
242
243     while (i < bstest->num_patterns) {
244       buf = NULL;
245
246       if (bstest->patterns[i][0] == 'r') {
247         size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
248         if (!bstest->silent) g_print ("bstest: ***** read %d bytes\n", size);
249         buf = gst_bytestream_read (bstest->bs, size);
250       }
251       else if (bstest->patterns[i][0] == 'f') {
252         size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
253         if (!bstest->silent) g_print ("bstest: ***** flush %d bytes\n", size);
254         gst_bytestream_flush (bstest->bs, size);
255       }
256       else if (!strncmp (bstest->patterns[i], "pb", 2)) {
257         size = gst_bstest_get_size (bstest, &bstest->patterns[i][2], size);
258         if (!bstest->silent) g_print ("bstest: ***** peek bytes %d bytes\n", size);
259         gst_bytestream_peek_bytes (bstest->bs, size);
260       }
261       else if (bstest->patterns[i][0] == 'p') {
262         size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
263         if (!bstest->silent) g_print ("bstest: ***** peek %d bytes\n", size);
264         buf = gst_bytestream_peek (bstest->bs, size);
265         gst_buffer_unref (buf);
266         buf = NULL;
267       }
268
269       if (buf)
270         gst_pad_push (bstest->srcpad, buf);
271       
272       i++;
273     }
274 /*  } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); */
275
276   } while (0);
277 }
278
279 static void
280 gst_bstest_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
281 {
282   GstBsTest *bstest;
283
284   /* it's not null if we got it, but it might not be ours */
285   g_return_if_fail (GST_IS_BSTEST (object));
286
287   bstest = GST_BSTEST (object);
288
289   switch (prop_id) {
290     case ARG_SIZEMIN:
291       bstest->sizemin = g_value_get_int (value);
292       break;
293     case ARG_SIZEMAX:
294       bstest->sizemax = g_value_get_int (value);
295       break;
296     case ARG_ACCESSPATTERN:
297       if (bstest->accesspattern) {
298         g_free (bstest->accesspattern);
299         g_strfreev (bstest->patterns);
300       }
301       if (g_value_get_string (value) == NULL) {
302         gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL);
303         bstest->accesspattern = NULL;
304         bstest->num_patterns = 0;
305       } else {
306         guint i = 0;
307
308         bstest->accesspattern = g_strdup (g_value_get_string (value));
309         bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0);
310         while (bstest->patterns[i++]);
311         bstest->num_patterns = i-1;
312       }
313       break;
314     case ARG_COUNT:
315       bstest->count = g_value_get_uint (value);
316       break;
317     case ARG_SILENT:
318       bstest->silent = g_value_get_boolean (value);
319       break;
320     default:
321       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
322       break;
323   }
324 }
325
326 static void
327 gst_bstest_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
328 {
329   GstBsTest *bstest;
330
331   /* it's not null if we got it, but it might not be ours */
332   g_return_if_fail (GST_IS_BSTEST (object));
333
334   bstest = GST_BSTEST (object);
335
336   switch (prop_id) {
337     case ARG_SIZEMIN:
338       g_value_set_int (value, bstest->sizemin);
339       break;
340     case ARG_SIZEMAX:
341       g_value_set_int (value, bstest->sizemax);
342       break;
343     case ARG_ACCESSPATTERN:
344       g_value_set_string (value, bstest->accesspattern);
345       break;
346     case ARG_COUNT:
347       g_value_set_uint (value, bstest->count);
348       break;
349     case ARG_SILENT:
350       g_value_set_boolean (value, bstest->silent);
351       break;
352     default:
353       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
354       break;
355   }
356 }
357
358 static GstElementStateReturn
359 gst_bstest_change_state (GstElement *element)
360 {
361   GstBsTest *bstest;
362
363   g_return_val_if_fail (GST_IS_BSTEST (element), GST_STATE_FAILURE);
364
365   bstest = GST_BSTEST (element);
366
367   if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
368     if (bstest->bs) {
369       gst_bytestream_destroy (bstest->bs);
370       bstest->bs = NULL;
371     }
372   }
373   else {
374     if (!bstest->bs) {
375       bstest->bs = gst_bytestream_new (bstest->sinkpad);
376     }
377   }
378
379   if (GST_ELEMENT_CLASS (parent_class)->change_state)
380     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
381
382   return GST_STATE_SUCCESS;
383 }
384
385 static gboolean
386 plugin_init (GModule * module, GstPlugin * plugin)
387 {
388   GstElementFactory *factory;
389
390   // we need gstbytestream
391   if (!gst_library_load ("gstbytestream")) {
392     g_print ("can't load bytestream\n");
393     return FALSE;
394   }
395
396   /* We need to create an ElementFactory for each element we provide.
397    * This consists of the name of the element, the GType identifier,
398    * and a pointer to the details structure at the top of the file.
399    */
400   factory = gst_elementfactory_new ("bstest", GST_TYPE_BSTEST, &gst_bstest_details);
401   g_return_val_if_fail (factory != NULL, FALSE);
402
403   /* The very last thing is to register the elementfactory with the plugin. */
404   gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
405
406   return TRUE;
407 }
408
409 GST_PLUGIN_DESC (GST_VERSION_MAJOR, GST_VERSION_MINOR, "bstest", plugin_init);