]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gstreamer0-10.git/blob - plugins/elements/gstfakesrc.c
more autistic cleanliness in functions/names/defines
[glsdk/gstreamer0-10.git] / plugins / elements / gstfakesrc.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstfakesrc.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  */
24 #include <stdlib.h>
25 #include <string.h>
27 #ifdef HAVE_CONFIG_H
28 #  include "config.h"
29 #endif
31 #include "gstfakesrc.h"
32 #include <gst/gstmarshal.h>
34 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
35     GST_PAD_SRC,
36     GST_PAD_ALWAYS,
37     GST_STATIC_CAPS_ANY);
39 GST_DEBUG_CATEGORY_STATIC (gst_fake_src_debug);
40 #define GST_CAT_DEFAULT gst_fake_src_debug
42 GstElementDetails gst_fake_src_details = GST_ELEMENT_DETAILS ("Fake Source",
43     "Source",
44     "Push empty (no data) buffers around",
45     "Erik Walthinsen <omega@cse.ogi.edu>, "
46     "Wim Taymans <wim.taymans@chello.be>");
49 /* FakeSrc signals and args */
50 enum
51 {
52   /* FILL ME */
53   SIGNAL_HANDOFF,
54   LAST_SIGNAL
55 };
57 #define DEFAULT_OUTPUT          FAKE_SRC_FIRST_LAST_LOOP
58 #define DEFAULT_DATA            FAKE_SRC_DATA_ALLOCATE
59 #define DEFAULT_SIZETYPE        FAKE_SRC_SIZETYPE_NULL
60 #define DEFAULT_SIZEMIN         0
61 #define DEFAULT_SIZEMAX         4096
62 #define DEFAULT_FILLTYPE        FAKE_SRC_FILLTYPE_NULL
63 #define DEFAULT_DATARATE        0
64 #define DEFAULT_SYNC            FALSE
65 #define DEFAULT_PATTERN         NULL
66 #define DEFAULT_EOS             FALSE
67 #define DEFAULT_SIGNAL_HANDOFFS FALSE
68 #define DEFAULT_SILENT          FALSE
69 #define DEFAULT_DUMP            FALSE
70 #define DEFAULT_PARENTSIZE      4096*10
72 enum
73 {
74   PROP_0,
75   PROP_OUTPUT,
76   PROP_DATA,
77   PROP_SIZETYPE,
78   PROP_SIZEMIN,
79   PROP_SIZEMAX,
80   PROP_FILLTYPE,
81   PROP_DATARATE,
82   PROP_SYNC,
83   PROP_PATTERN,
84   PROP_EOS,
85   PROP_SIGNAL_HANDOFFS,
86   PROP_SILENT,
87   PROP_DUMP,
88   PROP_PARENTSIZE,
89   PROP_LAST_MESSAGE,
90   PROP_HAS_LOOP,
91   PROP_HAS_GETRANGE,
92   PROP_IS_LIVE
93 };
95 /* not implemented
96 #define GST_TYPE_FAKE_SRC_OUTPUT (gst_fake_src_output_get_type())
97 static GType
98 gst_fake_src_output_get_type (void)
99 {
100   static GType fakesrc_output_type = 0;
101   static GEnumValue fakesrc_output[] = {
102     {FAKE_SRC_FIRST_LAST_LOOP, "1", "First-Last loop"},
103     {FAKE_SRC_LAST_FIRST_LOOP, "2", "Last-First loop"},
104     {FAKE_SRC_PING_PONG, "3", "Ping-Pong"},
105     {FAKE_SRC_ORDERED_RANDOM, "4", "Ordered Random"},
106     {FAKE_SRC_RANDOM, "5", "Random"},
107     {FAKE_SRC_PATTERN_LOOP, "6", "Patttern loop"},
108     {FAKE_SRC_PING_PONG_PATTERN, "7", "Ping-Pong Pattern"},
109     {FAKE_SRC_GET_ALWAYS_SUCEEDS, "8", "'_get' Always succeeds"},
110     {0, NULL, NULL},
111   };
113   if (!fakesrc_output_type) {
114     fakesrc_output_type =
115         g_enum_register_static ("GstFakeSrcOutput", fakesrc_output);
116   }
117   return fakesrc_output_type;
119 */
121 #define GST_TYPE_FAKE_SRC_DATA (gst_fake_src_data_get_type())
122 static GType
123 gst_fake_src_data_get_type (void)
125   static GType fakesrc_data_type = 0;
126   static GEnumValue fakesrc_data[] = {
127     {FAKE_SRC_DATA_ALLOCATE, "1", "Allocate data"},
128     {FAKE_SRC_DATA_SUBBUFFER, "2", "Subbuffer data"},
129     {0, NULL, NULL},
130   };
132   if (!fakesrc_data_type) {
133     fakesrc_data_type = g_enum_register_static ("GstFakeSrcData", fakesrc_data);
134   }
135   return fakesrc_data_type;
138 #define GST_TYPE_FAKE_SRC_SIZETYPE (gst_fake_src_sizetype_get_type())
139 static GType
140 gst_fake_src_sizetype_get_type (void)
142   static GType fakesrc_sizetype_type = 0;
143   static GEnumValue fakesrc_sizetype[] = {
144     {FAKE_SRC_SIZETYPE_NULL, "1", "Send empty buffers"},
145     {FAKE_SRC_SIZETYPE_FIXED, "2", "Fixed size buffers (sizemax sized)"},
146     {FAKE_SRC_SIZETYPE_RANDOM, "3",
147         "Random sized buffers (sizemin <= size <= sizemax)"},
148     {0, NULL, NULL},
149   };
151   if (!fakesrc_sizetype_type) {
152     fakesrc_sizetype_type =
153         g_enum_register_static ("GstFakeSrcSizeType", fakesrc_sizetype);
154   }
155   return fakesrc_sizetype_type;
158 #define GST_TYPE_FAKE_SRC_FILLTYPE (gst_fake_src_filltype_get_type())
159 static GType
160 gst_fake_src_filltype_get_type (void)
162   static GType fakesrc_filltype_type = 0;
163   static GEnumValue fakesrc_filltype[] = {
164     {FAKE_SRC_FILLTYPE_NOTHING, "1", "Leave data as malloced"},
165     {FAKE_SRC_FILLTYPE_NULL, "2", "Fill buffers with zeros"},
166     {FAKE_SRC_FILLTYPE_RANDOM, "3", "Fill buffers with random crap"},
167     {FAKE_SRC_FILLTYPE_PATTERN, "4", "Fill buffers with pattern 0x00 -> 0xff"},
168     {FAKE_SRC_FILLTYPE_PATTERN_CONT, "5",
169         "Fill buffers with pattern 0x00 -> 0xff that spans buffers"},
170     {0, NULL, NULL},
171   };
173   if (!fakesrc_filltype_type) {
174     fakesrc_filltype_type =
175         g_enum_register_static ("GstFakeSrcFillType", fakesrc_filltype);
176   }
177   return fakesrc_filltype_type;
180 #define _do_init(bla) \
181     GST_DEBUG_CATEGORY_INIT (gst_fake_src_debug, "fakesrc", 0, "fakesrc element");
183 GST_BOILERPLATE_FULL (GstFakeSrc, gst_fake_src, GstBaseSrc, GST_TYPE_BASE_SRC,
184     _do_init);
186 static void gst_fake_src_set_property (GObject * object, guint prop_id,
187     const GValue * value, GParamSpec * pspec);
188 static void gst_fake_src_get_property (GObject * object, guint prop_id,
189     GValue * value, GParamSpec * pspec);
191 static gboolean gst_fake_src_start (GstBaseSrc * basesrc);
192 static gboolean gst_fake_src_stop (GstBaseSrc * basesrc);
194 static gboolean gst_fake_src_event_handler (GstBaseSrc * src, GstEvent * event);
195 static GstFlowReturn gst_fake_src_create (GstBaseSrc * src, guint64 offset,
196     guint length, GstBuffer ** buf);
198 static guint gst_fake_src_signals[LAST_SIGNAL] = { 0 };
200 static void
201 gst_fake_src_base_init (gpointer g_class)
203   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
205   gst_element_class_add_pad_template (gstelement_class,
206       gst_static_pad_template_get (&srctemplate));
208   gst_element_class_set_details (gstelement_class, &gst_fake_src_details);
211 static void
212 gst_fake_src_class_init (GstFakeSrcClass * klass)
214   GObjectClass *gobject_class;
215   GstElementClass *gstelement_class;
216   GstBaseSrcClass *gstbase_src_class;
218   gobject_class = (GObjectClass *) klass;
219   gstelement_class = (GstElementClass *) klass;
220   gstbase_src_class = (GstBaseSrcClass *) klass;
222   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fake_src_set_property);
223   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fake_src_get_property);
225 /*
226   FIXME: this is not implemented; would make sense once basesrc and fakesrc
227   support multiple pads
228   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_OUTPUT,
229       g_param_spec_enum ("output", "output", "Output method (currently unused)",
230           GST_TYPE_FAKE_SRC_OUTPUT, DEFAULT_OUTPUT, G_PARAM_READWRITE));
231 */
232   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DATA,
233       g_param_spec_enum ("data", "data", "Data allocation method",
234           GST_TYPE_FAKE_SRC_DATA, DEFAULT_DATA, G_PARAM_READWRITE));
235   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SIZETYPE,
236       g_param_spec_enum ("sizetype", "sizetype",
237           "How to determine buffer sizes", GST_TYPE_FAKE_SRC_SIZETYPE,
238           DEFAULT_SIZETYPE, G_PARAM_READWRITE));
239   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SIZEMIN,
240       g_param_spec_int ("sizemin", "sizemin", "Minimum buffer size", 0,
241           G_MAXINT, DEFAULT_SIZEMIN, G_PARAM_READWRITE));
242   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SIZEMAX,
243       g_param_spec_int ("sizemax", "sizemax", "Maximum buffer size", 0,
244           G_MAXINT, DEFAULT_SIZEMAX, G_PARAM_READWRITE));
245   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PARENTSIZE,
246       g_param_spec_int ("parentsize", "parentsize",
247           "Size of parent buffer for sub-buffered allocation", 0, G_MAXINT,
248           DEFAULT_PARENTSIZE, G_PARAM_READWRITE));
249   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FILLTYPE,
250       g_param_spec_enum ("filltype", "filltype",
251           "How to fill the buffer, if at all", GST_TYPE_FAKE_SRC_FILLTYPE,
252           DEFAULT_FILLTYPE, G_PARAM_READWRITE));
253   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DATARATE,
254       g_param_spec_int ("datarate", "Datarate",
255           "Timestamps buffers with number of bytes per second (0 = none)", 0,
256           G_MAXINT, DEFAULT_DATARATE, G_PARAM_READWRITE));
257   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SYNC,
258       g_param_spec_boolean ("sync", "Sync", "Sync to the clock to the datarate",
259           DEFAULT_SYNC, G_PARAM_READWRITE));
260   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PATTERN,
261       g_param_spec_string ("pattern", "pattern", "pattern", DEFAULT_PATTERN,
262           G_PARAM_READWRITE));
263   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LAST_MESSAGE,
264       g_param_spec_string ("last-message", "last-message",
265           "The last status message", NULL, G_PARAM_READABLE));
266   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SILENT,
267       g_param_spec_boolean ("silent", "Silent",
268           "Don't produce last_message events", DEFAULT_SILENT,
269           G_PARAM_READWRITE));
270   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SIGNAL_HANDOFFS,
271       g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
272           "Send a signal before pushing the buffer", DEFAULT_SIGNAL_HANDOFFS,
273           G_PARAM_READWRITE));
274   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DUMP,
275       g_param_spec_boolean ("dump", "Dump", "Dump produced bytes to stdout",
276           DEFAULT_DUMP, G_PARAM_READWRITE));
277   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HAS_LOOP,
278       g_param_spec_boolean ("has-loop", "Has loop function",
279           "True if the element exposes a loop function", TRUE,
280           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
281   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_HAS_GETRANGE,
282       g_param_spec_boolean ("has-getrange", "Has getrange function",
283           "True if the element exposes a getrange function", TRUE,
284           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
285   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_IS_LIVE,
286       g_param_spec_boolean ("is-live", "Is this a live source",
287           "True if the element cannot produce data in PAUSED", FALSE,
288           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
290   gst_fake_src_signals[SIGNAL_HANDOFF] =
291       g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
292       G_STRUCT_OFFSET (GstFakeSrcClass, handoff), NULL, NULL,
293       gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
295   /*gstbase_src_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fake_src_is_seekable); */
296   gstbase_src_class->start = GST_DEBUG_FUNCPTR (gst_fake_src_start);
297   gstbase_src_class->stop = GST_DEBUG_FUNCPTR (gst_fake_src_stop);
298   gstbase_src_class->event = GST_DEBUG_FUNCPTR (gst_fake_src_event_handler);
299   gstbase_src_class->create = GST_DEBUG_FUNCPTR (gst_fake_src_create);
302 static void
303 gst_fake_src_init (GstFakeSrc * fakesrc)
305   fakesrc->output = FAKE_SRC_FIRST_LAST_LOOP;
306   fakesrc->segment_start = -1;
307   fakesrc->segment_end = -1;
308   fakesrc->buffer_count = 0;
309   fakesrc->silent = DEFAULT_SILENT;
310   fakesrc->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
311   fakesrc->dump = DEFAULT_DUMP;
312   fakesrc->pattern_byte = 0x00;
313   fakesrc->data = FAKE_SRC_DATA_ALLOCATE;
314   fakesrc->sizetype = FAKE_SRC_SIZETYPE_NULL;
315   fakesrc->filltype = FAKE_SRC_FILLTYPE_NOTHING;
316   fakesrc->sizemin = DEFAULT_SIZEMIN;
317   fakesrc->sizemax = DEFAULT_SIZEMAX;
318   fakesrc->parent = NULL;
319   fakesrc->parentsize = DEFAULT_PARENTSIZE;
320   fakesrc->last_message = NULL;
321   fakesrc->datarate = DEFAULT_DATARATE;
322   fakesrc->sync = DEFAULT_SYNC;
325 static gboolean
326 gst_fake_src_event_handler (GstBaseSrc * basesrc, GstEvent * event)
328   GstFakeSrc *src;
330   src = GST_FAKE_SRC (basesrc);
332   if (!src->silent) {
333     g_free (src->last_message);
335     src->last_message =
336         g_strdup_printf ("event   ******* E (type: %d) %p",
337         GST_EVENT_TYPE (event), event);
339     g_object_notify (G_OBJECT (src), "last_message");
340   }
343   return TRUE;
346 static void
347 gst_fake_src_alloc_parent (GstFakeSrc * src)
349   GstBuffer *buf;
351   buf = gst_buffer_new ();
352   GST_BUFFER_DATA (buf) = g_malloc (src->parentsize);
353   GST_BUFFER_SIZE (buf) = src->parentsize;
355   src->parent = buf;
356   src->parentoffset = 0;
359 static void
360 gst_fake_src_set_property (GObject * object, guint prop_id,
361     const GValue * value, GParamSpec * pspec)
363   GstFakeSrc *src;
364   GstBaseSrc *basesrc;
366   src = GST_FAKE_SRC (object);
367   basesrc = GST_BASE_SRC (object);
369   switch (prop_id) {
370     case PROP_OUTPUT:
371       g_warning ("not yet implemented");
372       break;
373     case PROP_DATA:
374       src->data = g_value_get_enum (value);
376       if (src->data == FAKE_SRC_DATA_SUBBUFFER) {
377         if (!src->parent)
378           gst_fake_src_alloc_parent (src);
379       } else {
380         if (src->parent) {
381           gst_buffer_unref (src->parent);
382           src->parent = NULL;
383         }
384       }
385       break;
386     case PROP_SIZETYPE:
387       src->sizetype = g_value_get_enum (value);
388       break;
389     case PROP_SIZEMIN:
390       src->sizemin = g_value_get_int (value);
391       break;
392     case PROP_SIZEMAX:
393       src->sizemax = g_value_get_int (value);
394       break;
395     case PROP_PARENTSIZE:
396       src->parentsize = g_value_get_int (value);
397       break;
398     case PROP_FILLTYPE:
399       src->filltype = g_value_get_enum (value);
400       break;
401     case PROP_DATARATE:
402       src->datarate = g_value_get_int (value);
403       break;
404     case PROP_SYNC:
405       src->sync = g_value_get_boolean (value);
406       break;
407     case PROP_PATTERN:
408       break;
409     case PROP_SILENT:
410       src->silent = g_value_get_boolean (value);
411       break;
412     case PROP_SIGNAL_HANDOFFS:
413       src->signal_handoffs = g_value_get_boolean (value);
414       break;
415     case PROP_DUMP:
416       src->dump = g_value_get_boolean (value);
417       break;
418     case PROP_HAS_LOOP:
419       g_return_if_fail (!GST_FLAG_IS_SET (object, GST_BASE_SRC_STARTED));
420       src->has_loop = g_value_get_boolean (value);
421       break;
422     case PROP_HAS_GETRANGE:
423       g_return_if_fail (!GST_FLAG_IS_SET (object, GST_BASE_SRC_STARTED));
424       src->has_getrange = g_value_get_boolean (value);
425       break;
426     case PROP_IS_LIVE:
427       gst_base_src_set_live (basesrc, g_value_get_boolean (value));
428       break;
429     default:
430       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
431       break;
432   }
435 static void
436 gst_fake_src_get_property (GObject * object, guint prop_id, GValue * value,
437     GParamSpec * pspec)
439   GstFakeSrc *src;
440   GstBaseSrc *basesrc;
442   g_return_if_fail (GST_IS_FAKE_SRC (object));
444   src = GST_FAKE_SRC (object);
445   basesrc = GST_BASE_SRC (object);
447   switch (prop_id) {
448     case PROP_OUTPUT:
449       g_value_set_enum (value, src->output);
450       break;
451     case PROP_DATA:
452       g_value_set_enum (value, src->data);
453       break;
454     case PROP_SIZETYPE:
455       g_value_set_enum (value, src->sizetype);
456       break;
457     case PROP_SIZEMIN:
458       g_value_set_int (value, src->sizemin);
459       break;
460     case PROP_SIZEMAX:
461       g_value_set_int (value, src->sizemax);
462       break;
463     case PROP_PARENTSIZE:
464       g_value_set_int (value, src->parentsize);
465       break;
466     case PROP_FILLTYPE:
467       g_value_set_enum (value, src->filltype);
468       break;
469     case PROP_DATARATE:
470       g_value_set_int (value, src->datarate);
471       break;
472     case PROP_SYNC:
473       g_value_set_boolean (value, src->sync);
474       break;
475     case PROP_PATTERN:
476       g_value_set_string (value, src->pattern);
477       break;
478     case PROP_SILENT:
479       g_value_set_boolean (value, src->silent);
480       break;
481     case PROP_SIGNAL_HANDOFFS:
482       g_value_set_boolean (value, src->signal_handoffs);
483       break;
484     case PROP_DUMP:
485       g_value_set_boolean (value, src->dump);
486       break;
487     case PROP_LAST_MESSAGE:
488       g_value_set_string (value, src->last_message);
489       break;
490     case PROP_HAS_LOOP:
491       g_value_set_boolean (value, src->has_loop);
492       break;
493     case PROP_HAS_GETRANGE:
494       g_value_set_boolean (value, src->has_getrange);
495       break;
496     case PROP_IS_LIVE:
497       g_value_set_boolean (value, gst_base_src_is_live (basesrc));
498       break;
499     default:
500       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
501       break;
502   }
505 static void
506 gst_fake_src_prepare_buffer (GstFakeSrc * src, GstBuffer * buf)
508   if (GST_BUFFER_SIZE (buf) == 0)
509     return;
511   switch (src->filltype) {
512     case FAKE_SRC_FILLTYPE_NULL:
513       memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
514       break;
515     case FAKE_SRC_FILLTYPE_RANDOM:
516     {
517       gint i;
518       guint8 *ptr = GST_BUFFER_DATA (buf);
520       for (i = GST_BUFFER_SIZE (buf); i; i--) {
521         *ptr++ = (gint8) ((255.0) * rand () / (RAND_MAX));
522       }
523       break;
524     }
525     case FAKE_SRC_FILLTYPE_PATTERN:
526       src->pattern_byte = 0x00;
527     case FAKE_SRC_FILLTYPE_PATTERN_CONT:
528     {
529       gint i;
530       guint8 *ptr = GST_BUFFER_DATA (buf);
532       for (i = GST_BUFFER_SIZE (buf); i; i--) {
533         *ptr++ = src->pattern_byte++;
534       }
535       break;
536     }
537     case FAKE_SRC_FILLTYPE_NOTHING:
538     default:
539       break;
540   }
543 static GstBuffer *
544 gst_fake_src_alloc_buffer (GstFakeSrc * src, guint size)
546   GstBuffer *buf;
548   buf = gst_buffer_new ();
549   GST_BUFFER_SIZE (buf) = size;
551   if (size != 0) {
552     switch (src->filltype) {
553       case FAKE_SRC_FILLTYPE_NOTHING:
554         GST_BUFFER_DATA (buf) = g_malloc (size);
555         break;
556       case FAKE_SRC_FILLTYPE_NULL:
557         GST_BUFFER_DATA (buf) = g_malloc0 (size);
558         break;
559       case FAKE_SRC_FILLTYPE_RANDOM:
560       case FAKE_SRC_FILLTYPE_PATTERN:
561       case FAKE_SRC_FILLTYPE_PATTERN_CONT:
562       default:
563         GST_BUFFER_DATA (buf) = g_malloc (size);
564         gst_fake_src_prepare_buffer (src, buf);
565         break;
566     }
567   }
569   return buf;
572 static guint
573 gst_fake_src_get_size (GstFakeSrc * src)
575   guint size;
577   switch (src->sizetype) {
578     case FAKE_SRC_SIZETYPE_FIXED:
579       size = src->sizemax;
580       break;
581     case FAKE_SRC_SIZETYPE_RANDOM:
582       size =
583           src->sizemin +
584           (guint8) (((gfloat) src->sizemax) * rand () / (RAND_MAX +
585               (gfloat) src->sizemin));
586       break;
587     case FAKE_SRC_SIZETYPE_NULL:
588     default:
589       size = 0;
590       break;
591   }
593   return size;
596 static GstBuffer *
597 gst_fake_src_create_buffer (GstFakeSrc * src)
599   GstBuffer *buf;
600   guint size;
601   gboolean dump = src->dump;
603   size = gst_fake_src_get_size (src);
604   if (size == 0)
605     return gst_buffer_new ();
607   switch (src->data) {
608     case FAKE_SRC_DATA_ALLOCATE:
609       buf = gst_fake_src_alloc_buffer (src, size);
610       break;
611     case FAKE_SRC_DATA_SUBBUFFER:
612       /* see if we have a parent to subbuffer */
613       if (!src->parent) {
614         gst_fake_src_alloc_parent (src);
615         g_assert (src->parent);
616       }
617       /* see if it's large enough */
618       if ((GST_BUFFER_SIZE (src->parent) - src->parentoffset) >= size) {
619         buf = gst_buffer_create_sub (src->parent, src->parentoffset, size);
620         src->parentoffset += size;
621       } else {
622         /* the parent is useless now */
623         gst_buffer_unref (src->parent);
624         src->parent = NULL;
625         /* try again (this will allocate a new parent) */
626         return gst_fake_src_create_buffer (src);
627       }
628       gst_fake_src_prepare_buffer (src, buf);
629       break;
630     default:
631       g_warning ("fakesrc: dunno how to allocate buffers !");
632       buf = gst_buffer_new ();
633       break;
634   }
635   if (dump) {
636     gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
637   }
639   return buf;
642 static GstFlowReturn
643 gst_fake_src_create (GstBaseSrc * basesrc, guint64 offset, guint length,
644     GstBuffer ** ret)
646   GstFakeSrc *src;
647   GstBuffer *buf;
648   GstClockTime time;
650   src = GST_FAKE_SRC (basesrc);
652   if (src->buffer_count == src->segment_end) {
653     GST_INFO ("buffer_count reaches segment_end %d %d", src->buffer_count,
654         src->segment_end);
655     return GST_FLOW_UNEXPECTED;
656   }
658   buf = gst_fake_src_create_buffer (src);
659   GST_BUFFER_OFFSET (buf) = src->buffer_count++;
661   time = GST_CLOCK_TIME_NONE;
663   if (src->datarate > 0) {
664     time = (src->bytes_sent * GST_SECOND) / src->datarate;
665     if (src->sync) {
666       /* gst_element_wait (GST_ELEMENT (src), time); */
667     }
669     GST_BUFFER_DURATION (buf) =
670         GST_BUFFER_SIZE (buf) * GST_SECOND / src->datarate;
671   }
672   GST_BUFFER_TIMESTAMP (buf) = time;
674   if (!src->silent) {
675     g_free (src->last_message);
677     src->last_message =
678         g_strdup_printf ("get      ******* > (%d bytes, timestamp: %"
679         GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %"
680         G_GINT64_FORMAT ", offset_end: %" G_GINT64_FORMAT ", flags: %d) %p",
681         GST_BUFFER_SIZE (buf),
682         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
683         GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf),
684         GST_BUFFER_OFFSET_END (buf), GST_MINI_OBJECT (buf)->flags, buf);
686     g_object_notify (G_OBJECT (src), "last_message");
687   }
689   if (src->signal_handoffs) {
690     GST_LOG_OBJECT (src, "pre handoff emit");
691     g_signal_emit (G_OBJECT (src), gst_fake_src_signals[SIGNAL_HANDOFF], 0,
692         buf);
693     GST_LOG_OBJECT (src, "post handoff emit");
694   }
696   src->bytes_sent += GST_BUFFER_SIZE (buf);
698   *ret = buf;
699   return GST_FLOW_OK;
702 static gboolean
703 gst_fake_src_start (GstBaseSrc * basesrc)
705   GstFakeSrc *src;
707   src = GST_FAKE_SRC (basesrc);
709   src->buffer_count = 0;
710   src->pattern_byte = 0x00;
711   src->bytes_sent = 0;
713   return TRUE;
716 static gboolean
717 gst_fake_src_stop (GstBaseSrc * basesrc)
719   GstFakeSrc *src;
721   src = GST_FAKE_SRC (basesrc);
723   if (src->parent) {
724     gst_buffer_unref (src->parent);
725     src->parent = NULL;
726   }
727   g_free (src->last_message);
728   src->last_message = NULL;
730   return TRUE;