]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gstreamer0-10.git/blob - plugins/elements/gstfakesrc.c
- removing some trailing commas in enums to please C90 only compilers (AIX, Forte...
[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 #define DEFAULT_SIZEMIN         0
35 #define DEFAULT_SIZEMAX         4096
36 #define DEFAULT_PARENTSIZE      4096*10
38 GST_DEBUG_CATEGORY_STATIC (gst_fakesrc_debug);
39 #define GST_CAT_DEFAULT gst_fakesrc_debug
41 GstElementDetails gst_fakesrc_details = GST_ELEMENT_DETAILS ("Fake Source",
42     "Source",
43     "Push empty (no data) buffers around",
44     "Erik Walthinsen <omega@cse.ogi.edu>, "
45     "Wim Taymans <wim.taymans@chello.be>");
48 /* FakeSrc signals and args */
49 enum
50 {
51   /* FILL ME */
52   SIGNAL_HANDOFF,
53   LAST_SIGNAL
54 };
56 enum
57 {
58   ARG_0,
59   ARG_NUM_SOURCES,
60   ARG_LOOP_BASED,
61   ARG_OUTPUT,
62   ARG_DATA,
63   ARG_SIZETYPE,
64   ARG_SIZEMIN,
65   ARG_SIZEMAX,
66   ARG_FILLTYPE,
67   ARG_PATTERN,
68   ARG_NUM_BUFFERS,
69   ARG_EOS,
70   ARG_SIGNAL_HANDOFFS,
71   ARG_SILENT,
72   ARG_DUMP,
73   ARG_PARENTSIZE,
74   ARG_LAST_MESSAGE
75 };
77 GstStaticPadTemplate fakesrc_src_template = GST_STATIC_PAD_TEMPLATE ("src%d",
78     GST_PAD_SRC,
79     GST_PAD_REQUEST,
80     GST_STATIC_CAPS_ANY);
82 #define GST_TYPE_FAKESRC_OUTPUT (gst_fakesrc_output_get_type())
83 static GType
84 gst_fakesrc_output_get_type (void)
85 {
86   static GType fakesrc_output_type = 0;
87   static GEnumValue fakesrc_output[] = {
88     {FAKESRC_FIRST_LAST_LOOP, "1", "First-Last loop"},
89     {FAKESRC_LAST_FIRST_LOOP, "2", "Last-First loop"},
90     {FAKESRC_PING_PONG, "3", "Ping-Pong"},
91     {FAKESRC_ORDERED_RANDOM, "4", "Ordered Random"},
92     {FAKESRC_RANDOM, "5", "Random"},
93     {FAKESRC_PATTERN_LOOP, "6", "Patttern loop"},
94     {FAKESRC_PING_PONG_PATTERN, "7", "Ping-Pong Pattern"},
95     {FAKESRC_GET_ALWAYS_SUCEEDS, "8", "'_get' Always succeeds"},
96     {0, NULL, NULL},
97   };
99   if (!fakesrc_output_type) {
100     fakesrc_output_type =
101         g_enum_register_static ("GstFakeSrcOutput", fakesrc_output);
102   }
103   return fakesrc_output_type;
106 #define GST_TYPE_FAKESRC_DATA (gst_fakesrc_data_get_type())
107 static GType
108 gst_fakesrc_data_get_type (void)
110   static GType fakesrc_data_type = 0;
111   static GEnumValue fakesrc_data[] = {
112     {FAKESRC_DATA_ALLOCATE, "1", "Allocate data"},
113     {FAKESRC_DATA_SUBBUFFER, "2", "Subbuffer data"},
114     {0, NULL, NULL},
115   };
117   if (!fakesrc_data_type) {
118     fakesrc_data_type = g_enum_register_static ("GstFakeSrcData", fakesrc_data);
119   }
120   return fakesrc_data_type;
123 #define GST_TYPE_FAKESRC_SIZETYPE (gst_fakesrc_sizetype_get_type())
124 static GType
125 gst_fakesrc_sizetype_get_type (void)
127   static GType fakesrc_sizetype_type = 0;
128   static GEnumValue fakesrc_sizetype[] = {
129     {FAKESRC_SIZETYPE_NULL, "1", "Send empty buffers"},
130     {FAKESRC_SIZETYPE_FIXED, "2", "Fixed size buffers (sizemax sized)"},
131     {FAKESRC_SIZETYPE_RANDOM, "3",
132         "Random sized buffers (sizemin <= size <= sizemax)"},
133     {0, NULL, NULL},
134   };
136   if (!fakesrc_sizetype_type) {
137     fakesrc_sizetype_type =
138         g_enum_register_static ("GstFakeSrcSizeType", fakesrc_sizetype);
139   }
140   return fakesrc_sizetype_type;
143 #define GST_TYPE_FAKESRC_FILLTYPE (gst_fakesrc_filltype_get_type())
144 static GType
145 gst_fakesrc_filltype_get_type (void)
147   static GType fakesrc_filltype_type = 0;
148   static GEnumValue fakesrc_filltype[] = {
149     {FAKESRC_FILLTYPE_NOTHING, "1", "Leave data as malloced"},
150     {FAKESRC_FILLTYPE_NULL, "2", "Fill buffers with zeros"},
151     {FAKESRC_FILLTYPE_RANDOM, "3", "Fill buffers with random crap"},
152     {FAKESRC_FILLTYPE_PATTERN, "4", "Fill buffers with pattern 0x00 -> 0xff"},
153     {FAKESRC_FILLTYPE_PATTERN_CONT, "5",
154         "Fill buffers with pattern 0x00 -> 0xff that spans buffers"},
155     {0, NULL, NULL},
156   };
158   if (!fakesrc_filltype_type) {
159     fakesrc_filltype_type =
160         g_enum_register_static ("GstFakeSrcFillType", fakesrc_filltype);
161   }
162   return fakesrc_filltype_type;
165 #define _do_init(bla) \
166     GST_DEBUG_CATEGORY_INIT (gst_fakesrc_debug, "fakesrc", 0, "fakesrc element");
168 GST_BOILERPLATE_FULL (GstFakeSrc, gst_fakesrc, GstElement, GST_TYPE_ELEMENT,
169     _do_init);
171 static GstPad *gst_fakesrc_request_new_pad (GstElement * element,
172     GstPadTemplate * templ, const gchar * unused);
173 static void gst_fakesrc_update_functions (GstFakeSrc * src);
174 static void gst_fakesrc_set_property (GObject * object, guint prop_id,
175     const GValue * value, GParamSpec * pspec);
176 static void gst_fakesrc_get_property (GObject * object, guint prop_id,
177     GValue * value, GParamSpec * pspec);
179 static GstElementStateReturn gst_fakesrc_change_state (GstElement * element);
181 static GstData *gst_fakesrc_get (GstPad * pad);
182 static void gst_fakesrc_loop (GstElement * element);
184 static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
186 static void
187 gst_fakesrc_base_init (gpointer g_class)
189   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
191   gst_element_class_set_details (gstelement_class, &gst_fakesrc_details);
192   gst_element_class_add_pad_template (gstelement_class,
193       gst_static_pad_template_get (&fakesrc_src_template));
196 static void
197 gst_fakesrc_class_init (GstFakeSrcClass * klass)
199   GObjectClass *gobject_class;
200   GstElementClass *gstelement_class;
202   gobject_class = (GObjectClass *) klass;
203   gstelement_class = (GstElementClass *) klass;
206   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
207       g_param_spec_int ("num-sources", "num-sources", "Number of sources",
208           1, G_MAXINT, 1, G_PARAM_READABLE));
209   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED,
210       g_param_spec_boolean ("loop-based", "loop-based",
211           "Enable loop-based operation", FALSE, G_PARAM_READWRITE));
212   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_OUTPUT,
213       g_param_spec_enum ("output", "output", "Output method (currently unused)",
214           GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE));
215   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATA,
216       g_param_spec_enum ("data", "data", "Data allocation method",
217           GST_TYPE_FAKESRC_DATA, FAKESRC_DATA_ALLOCATE, G_PARAM_READWRITE));
218   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZETYPE,
219       g_param_spec_enum ("sizetype", "sizetype",
220           "How to determine buffer sizes", GST_TYPE_FAKESRC_SIZETYPE,
221           FAKESRC_SIZETYPE_NULL, G_PARAM_READWRITE));
222   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
223       g_param_spec_int ("sizemin", "sizemin", "Minimum buffer size", 0,
224           G_MAXINT, DEFAULT_SIZEMIN, G_PARAM_READWRITE));
225   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX,
226       g_param_spec_int ("sizemax", "sizemax", "Maximum buffer size", 0,
227           G_MAXINT, DEFAULT_SIZEMAX, G_PARAM_READWRITE));
228   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PARENTSIZE,
229       g_param_spec_int ("parentsize", "parentsize",
230           "Size of parent buffer for sub-buffered allocation", 0, G_MAXINT,
231           DEFAULT_PARENTSIZE, G_PARAM_READWRITE));
232   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILLTYPE,
233       g_param_spec_enum ("filltype", "filltype",
234           "How to fill the buffer, if at all", GST_TYPE_FAKESRC_FILLTYPE,
235           FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE));
236   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PATTERN,
237       g_param_spec_string ("pattern", "pattern", "pattern", NULL,
238           G_PARAM_READWRITE));
239   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_BUFFERS,
240       g_param_spec_int ("num-buffers", "num-buffers",
241           "Number of buffers to output before sending EOS", -1, G_MAXINT,
242           0, G_PARAM_READWRITE));
243   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EOS,
244       g_param_spec_boolean ("eos", "eos", "Send out the EOS event?", TRUE,
245           G_PARAM_READWRITE));
246   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
247       g_param_spec_string ("last-message", "last-message",
248           "The last status message", NULL, G_PARAM_READABLE));
249   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
250       g_param_spec_boolean ("silent", "Silent",
251           "Don't produce last_message events", FALSE, G_PARAM_READWRITE));
252   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIGNAL_HANDOFFS,
253       g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
254           "Send a signal before pushing the buffer", FALSE, G_PARAM_READWRITE));
255   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
256       g_param_spec_boolean ("dump", "Dump", "Dump produced bytes to stdout",
257           FALSE, G_PARAM_READWRITE));
259   gst_fakesrc_signals[SIGNAL_HANDOFF] =
260       g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
261       G_STRUCT_OFFSET (GstFakeSrcClass, handoff), NULL, NULL,
262       gst_marshal_VOID__POINTER_OBJECT, G_TYPE_NONE, 2,
263       GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE, GST_TYPE_PAD);
265   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesrc_set_property);
266   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesrc_get_property);
268   gstelement_class->request_new_pad =
269       GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
270   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_fakesrc_change_state);
273 static void
274 gst_fakesrc_init (GstFakeSrc * fakesrc)
276   GstPad *pad;
278   /* create our first output pad */
279   pad = gst_pad_new ("src", GST_PAD_SRC);
280   gst_element_add_pad (GST_ELEMENT (fakesrc), pad);
282   fakesrc->loop_based = FALSE;
283   gst_fakesrc_update_functions (fakesrc);
285   fakesrc->output = FAKESRC_FIRST_LAST_LOOP;
286   fakesrc->segment_start = -1;
287   fakesrc->segment_end = -1;
288   fakesrc->num_buffers = -1;
289   fakesrc->rt_num_buffers = -1;
290   fakesrc->buffer_count = 0;
291   fakesrc->silent = FALSE;
292   fakesrc->signal_handoffs = FALSE;
293   fakesrc->dump = FALSE;
294   fakesrc->pattern_byte = 0x00;
295   fakesrc->need_flush = FALSE;
296   fakesrc->data = FAKESRC_DATA_ALLOCATE;
297   fakesrc->sizetype = FAKESRC_SIZETYPE_NULL;
298   fakesrc->filltype = FAKESRC_FILLTYPE_NOTHING;
299   fakesrc->sizemin = DEFAULT_SIZEMIN;
300   fakesrc->sizemax = DEFAULT_SIZEMAX;
301   fakesrc->parent = NULL;
302   fakesrc->parentsize = DEFAULT_PARENTSIZE;
303   fakesrc->last_message = NULL;
306 static GstPad *
307 gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ,
308     const gchar * unused)
310   gchar *name;
311   GstPad *srcpad;
312   GstFakeSrc *fakesrc;
314   g_return_val_if_fail (GST_IS_FAKESRC (element), NULL);
316   if (templ->direction != GST_PAD_SRC) {
317     g_warning ("gstfakesrc: request new pad that is not a SRC pad\n");
318     return NULL;
319   }
321   fakesrc = GST_FAKESRC (element);
323   name = g_strdup_printf ("src%d", GST_ELEMENT (fakesrc)->numsrcpads);
325   srcpad = gst_pad_new_from_template (templ, name);
326   gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
327   gst_fakesrc_update_functions (fakesrc);
329   g_free (name);
331   return srcpad;
334 static const GstFormat *
335 gst_fakesrc_get_formats (GstPad * pad)
337   static const GstFormat formats[] = {
338     GST_FORMAT_DEFAULT,
339     0,
340   };
342   return formats;
345 static const GstQueryType *
346 gst_fakesrc_get_query_types (GstPad * pad)
348   static const GstQueryType types[] = {
349     GST_QUERY_TOTAL,
350     GST_QUERY_POSITION,
351     GST_QUERY_START,
352     GST_QUERY_SEGMENT_END,
353     0,
354   };
356   return types;
359 static gboolean
360 gst_fakesrc_query (GstPad * pad, GstQueryType type,
361     GstFormat * format, gint64 * value)
363   GstFakeSrc *src = GST_FAKESRC (GST_PAD_PARENT (pad));
365   switch (type) {
366     case GST_QUERY_TOTAL:
367       *value = src->num_buffers;
368       break;
369     case GST_QUERY_POSITION:
370       *value = src->buffer_count;
371       break;
372     case GST_QUERY_START:
373       *value = src->segment_start;
374       break;
375     case GST_QUERY_SEGMENT_END:
376       *value = src->segment_end;
377       break;
378     default:
379       return FALSE;
380   }
381   return TRUE;
384 static const GstEventMask *
385 gst_fakesrc_get_event_mask (GstPad * pad)
387   static const GstEventMask masks[] = {
388     {GST_EVENT_SEEK, GST_SEEK_FLAG_FLUSH},
389     {GST_EVENT_SEEK_SEGMENT, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SEGMENT_LOOP},
390     {GST_EVENT_FLUSH, 0},
391     {0, 0},
392   };
394   return masks;
397 static gboolean
398 gst_fakesrc_event_handler (GstPad * pad, GstEvent * event)
400   GstFakeSrc *src;
402   src = GST_FAKESRC (gst_pad_get_parent (pad));
404   switch (GST_EVENT_TYPE (event)) {
405     case GST_EVENT_SEEK:
406       src->buffer_count = GST_EVENT_SEEK_OFFSET (event);
408       if (!GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) {
409         break;
410       }
411       /* else we do a flush too */
412     case GST_EVENT_SEEK_SEGMENT:
413       src->segment_start = GST_EVENT_SEEK_OFFSET (event);
414       src->segment_end = GST_EVENT_SEEK_ENDOFFSET (event);
415       src->buffer_count = src->segment_start;
416       src->segment_loop =
417           GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_SEGMENT_LOOP;
418       break;
419     case GST_EVENT_FLUSH:
420       src->need_flush = TRUE;
421       break;
422     default:
423       break;
424   }
425   gst_event_unref (event);
427   return TRUE;
430 static void
431 gst_fakesrc_update_functions (GstFakeSrc * src)
433   GList *pads;
435   if (src->loop_based) {
436     gst_element_set_loop_function (GST_ELEMENT (src),
437         GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
438   } else {
439     gst_element_set_loop_function (GST_ELEMENT (src), NULL);
440   }
442   pads = GST_ELEMENT (src)->pads;
443   while (pads) {
444     GstPad *pad = GST_PAD (pads->data);
446     if (src->loop_based) {
447       gst_pad_set_get_function (pad, NULL);
448     } else {
449       gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
450     }
452     gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
453     gst_pad_set_event_mask_function (pad, gst_fakesrc_get_event_mask);
454     gst_pad_set_query_function (pad, gst_fakesrc_query);
455     gst_pad_set_query_type_function (pad, gst_fakesrc_get_query_types);
456     gst_pad_set_formats_function (pad, gst_fakesrc_get_formats);
457     pads = g_list_next (pads);
458   }
461 static void
462 gst_fakesrc_alloc_parent (GstFakeSrc * src)
464   GstBuffer *buf;
466   buf = gst_buffer_new ();
467   GST_BUFFER_DATA (buf) = g_malloc (src->parentsize);
468   GST_BUFFER_SIZE (buf) = src->parentsize;
470   src->parent = buf;
471   src->parentoffset = 0;
474 static void
475 gst_fakesrc_set_property (GObject * object, guint prop_id, const GValue * value,
476     GParamSpec * pspec)
478   GstFakeSrc *src;
480   /* it's not null if we got it, but it might not be ours */
481   src = GST_FAKESRC (object);
483   switch (prop_id) {
484     case ARG_LOOP_BASED:
485       src->loop_based = g_value_get_boolean (value);
486       gst_fakesrc_update_functions (src);
487       break;
488     case ARG_OUTPUT:
489       g_warning ("not yet implemented");
490       break;
491     case ARG_DATA:
492       src->data = g_value_get_enum (value);
494       if (src->data == FAKESRC_DATA_SUBBUFFER) {
495         if (!src->parent)
496           gst_fakesrc_alloc_parent (src);
497       } else {
498         if (src->parent) {
499           gst_buffer_unref (src->parent);
500           src->parent = NULL;
501         }
502       }
503       break;
504     case ARG_SIZETYPE:
505       src->sizetype = g_value_get_enum (value);
506       break;
507     case ARG_SIZEMIN:
508       src->sizemin = g_value_get_int (value);
509       break;
510     case ARG_SIZEMAX:
511       src->sizemax = g_value_get_int (value);
512       break;
513     case ARG_PARENTSIZE:
514       src->parentsize = g_value_get_int (value);
515       break;
516     case ARG_FILLTYPE:
517       src->filltype = g_value_get_enum (value);
518       break;
519     case ARG_PATTERN:
520       break;
521     case ARG_NUM_BUFFERS:
522       src->num_buffers = g_value_get_int (value);
523       break;
524     case ARG_EOS:
525       src->eos = g_value_get_boolean (value);
526       GST_INFO ("will EOS on next buffer");
527       break;
528     case ARG_SILENT:
529       src->silent = g_value_get_boolean (value);
530       break;
531     case ARG_SIGNAL_HANDOFFS:
532       src->signal_handoffs = g_value_get_boolean (value);
533       break;
534     case ARG_DUMP:
535       src->dump = g_value_get_boolean (value);
536       break;
537     default:
538       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
539       break;
540   }
543 static void
544 gst_fakesrc_get_property (GObject * object, guint prop_id, GValue * value,
545     GParamSpec * pspec)
547   GstFakeSrc *src;
549   /* it's not null if we got it, but it might not be ours */
550   g_return_if_fail (GST_IS_FAKESRC (object));
552   src = GST_FAKESRC (object);
554   switch (prop_id) {
555     case ARG_NUM_SOURCES:
556       g_value_set_int (value, GST_ELEMENT (src)->numsrcpads);
557       break;
558     case ARG_LOOP_BASED:
559       g_value_set_boolean (value, src->loop_based);
560       break;
561     case ARG_OUTPUT:
562       g_value_set_enum (value, src->output);
563       break;
564     case ARG_DATA:
565       g_value_set_enum (value, src->data);
566       break;
567     case ARG_SIZETYPE:
568       g_value_set_enum (value, src->sizetype);
569       break;
570     case ARG_SIZEMIN:
571       g_value_set_int (value, src->sizemin);
572       break;
573     case ARG_SIZEMAX:
574       g_value_set_int (value, src->sizemax);
575       break;
576     case ARG_PARENTSIZE:
577       g_value_set_int (value, src->parentsize);
578       break;
579     case ARG_FILLTYPE:
580       g_value_set_enum (value, src->filltype);
581       break;
582     case ARG_PATTERN:
583       g_value_set_string (value, src->pattern);
584       break;
585     case ARG_NUM_BUFFERS:
586       g_value_set_int (value, src->num_buffers);
587       break;
588     case ARG_EOS:
589       g_value_set_boolean (value, src->eos);
590       break;
591     case ARG_SILENT:
592       g_value_set_boolean (value, src->silent);
593       break;
594     case ARG_SIGNAL_HANDOFFS:
595       g_value_set_boolean (value, src->signal_handoffs);
596       break;
597     case ARG_DUMP:
598       g_value_set_boolean (value, src->dump);
599       break;
600     case ARG_LAST_MESSAGE:
601       g_value_set_string (value, src->last_message);
602       break;
603     default:
604       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
605       break;
606   }
609 static void
610 gst_fakesrc_prepare_buffer (GstFakeSrc * src, GstBuffer * buf)
612   if (GST_BUFFER_SIZE (buf) == 0)
613     return;
615   switch (src->filltype) {
616     case FAKESRC_FILLTYPE_NULL:
617       memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
618       break;
619     case FAKESRC_FILLTYPE_RANDOM:
620     {
621       gint i;
622       guint8 *ptr = GST_BUFFER_DATA (buf);
624       for (i = GST_BUFFER_SIZE (buf); i; i--) {
625         *ptr++ = (gint8) ((255.0) * rand () / (RAND_MAX));
626       }
627       break;
628     }
629     case FAKESRC_FILLTYPE_PATTERN:
630       src->pattern_byte = 0x00;
631     case FAKESRC_FILLTYPE_PATTERN_CONT:
632     {
633       gint i;
634       guint8 *ptr = GST_BUFFER_DATA (buf);
636       for (i = GST_BUFFER_SIZE (buf); i; i--) {
637         *ptr++ = src->pattern_byte++;
638       }
639       break;
640     }
641     case FAKESRC_FILLTYPE_NOTHING:
642     default:
643       break;
644   }
647 static GstBuffer *
648 gst_fakesrc_alloc_buffer (GstFakeSrc * src, guint size)
650   GstBuffer *buf;
652   buf = gst_buffer_new ();
653   GST_BUFFER_SIZE (buf) = size;
655   if (size != 0) {
656     switch (src->filltype) {
657       case FAKESRC_FILLTYPE_NOTHING:
658         GST_BUFFER_DATA (buf) = g_malloc (size);
659         break;
660       case FAKESRC_FILLTYPE_NULL:
661         GST_BUFFER_DATA (buf) = g_malloc0 (size);
662         break;
663       case FAKESRC_FILLTYPE_RANDOM:
664       case FAKESRC_FILLTYPE_PATTERN:
665       case FAKESRC_FILLTYPE_PATTERN_CONT:
666       default:
667         GST_BUFFER_DATA (buf) = g_malloc (size);
668         gst_fakesrc_prepare_buffer (src, buf);
669         break;
670     }
671   }
673   return buf;
676 static guint
677 gst_fakesrc_get_size (GstFakeSrc * src)
679   guint size;
681   switch (src->sizetype) {
682     case FAKESRC_SIZETYPE_FIXED:
683       size = src->sizemax;
684       break;
685     case FAKESRC_SIZETYPE_RANDOM:
686       size =
687           src->sizemin +
688           (guint8) (((gfloat) src->sizemax) * rand () / (RAND_MAX +
689               (gfloat) src->sizemin));
690       break;
691     case FAKESRC_SIZETYPE_NULL:
692     default:
693       size = 0;
694       break;
695   }
697   return size;
700 static GstBuffer *
701 gst_fakesrc_create_buffer (GstFakeSrc * src)
703   GstBuffer *buf;
704   guint size;
705   gboolean dump = src->dump;
707   size = gst_fakesrc_get_size (src);
708   if (size == 0)
709     return gst_buffer_new ();
711   switch (src->data) {
712     case FAKESRC_DATA_ALLOCATE:
713       buf = gst_fakesrc_alloc_buffer (src, size);
714       break;
715     case FAKESRC_DATA_SUBBUFFER:
716       /* see if we have a parent to subbuffer */
717       if (!src->parent) {
718         gst_fakesrc_alloc_parent (src);
719         g_assert (src->parent);
720       }
721       /* see if it's large enough */
722       if ((GST_BUFFER_SIZE (src->parent) - src->parentoffset) >= size) {
723         buf = gst_buffer_create_sub (src->parent, src->parentoffset, size);
724         src->parentoffset += size;
725       } else {
726         /* the parent is useless now */
727         gst_buffer_unref (src->parent);
728         src->parent = NULL;
729         /* try again (this will allocate a new parent) */
730         return gst_fakesrc_create_buffer (src);
731       }
732       gst_fakesrc_prepare_buffer (src, buf);
733       break;
734     default:
735       g_warning ("fakesrc: dunno how to allocate buffers !");
736       buf = gst_buffer_new ();
737       break;
738   }
739   if (dump) {
740     gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
741   }
743   return buf;
746 static GstData *
747 gst_fakesrc_get (GstPad * pad)
749   GstFakeSrc *src;
750   GstBuffer *buf;
752   g_return_val_if_fail (pad != NULL, NULL);
754   src = GST_FAKESRC (GST_OBJECT_PARENT (pad));
756   g_return_val_if_fail (GST_IS_FAKESRC (src), NULL);
758   if (src->need_flush) {
759     src->need_flush = FALSE;
760     return GST_DATA (gst_event_new (GST_EVENT_FLUSH));
761   }
763   if (src->buffer_count == src->segment_end) {
764     if (src->segment_loop) {
765       return GST_DATA (gst_event_new (GST_EVENT_SEGMENT_DONE));
766     } else {
767       gst_element_set_eos (GST_ELEMENT (src));
768       return GST_DATA (gst_event_new (GST_EVENT_EOS));
769     }
770   }
772   if (src->rt_num_buffers == 0) {
773     gst_element_set_eos (GST_ELEMENT (src));
774     return GST_DATA (gst_event_new (GST_EVENT_EOS));
775   } else {
776     if (src->rt_num_buffers > 0)
777       src->rt_num_buffers--;
778   }
780   if (src->eos) {
781     GST_INFO ("fakesrc is setting eos on pad");
782     return GST_DATA (gst_event_new (GST_EVENT_EOS));
783   }
785   buf = gst_fakesrc_create_buffer (src);
786   GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
788   if (!src->silent) {
789     g_free (src->last_message);
791     src->last_message =
792         g_strdup_printf ("get      ******* (%s:%s)> (%d bytes, %"
793         G_GUINT64_FORMAT " ) %p", GST_DEBUG_PAD_NAME (pad),
794         GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf);
796     g_object_notify (G_OBJECT (src), "last_message");
797   }
799   if (src->signal_handoffs) {
800     GST_LOG_OBJECT (src, "pre handoff emit");
801     g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
802         buf, pad);
803     GST_LOG_OBJECT (src, "post handoff emit");
804   }
806   return GST_DATA (buf);
809 /**
810  * gst_fakesrc_loop:
811  * @element: the faksesrc to loop
812  * 
813  * generate an empty buffer and push it to the next element.
814  */
815 static void
816 gst_fakesrc_loop (GstElement * element)
818   GstFakeSrc *src;
819   const GList *pads;
821   g_return_if_fail (element != NULL);
822   g_return_if_fail (GST_IS_FAKESRC (element));
824   src = GST_FAKESRC (element);
826   pads = gst_element_get_pad_list (element);
828   while (pads) {
829     GstPad *pad = GST_PAD (pads->data);
830     GstData *data;
832     data = gst_fakesrc_get (pad);
833     gst_pad_push (pad, data);
835     if (src->eos) {
836       return;
837     }
839     pads = g_list_next (pads);
840   }
843 static GstElementStateReturn
844 gst_fakesrc_change_state (GstElement * element)
846   GstFakeSrc *fakesrc;
848   g_return_val_if_fail (GST_IS_FAKESRC (element), GST_STATE_FAILURE);
850   fakesrc = GST_FAKESRC (element);
852   switch (GST_STATE_TRANSITION (element)) {
853     case GST_STATE_NULL_TO_READY:
854       break;
855     case GST_STATE_READY_TO_PAUSED:
856       fakesrc->buffer_count = 0;
857       fakesrc->pattern_byte = 0x00;
858       fakesrc->need_flush = FALSE;
859       fakesrc->eos = FALSE;
860       fakesrc->rt_num_buffers = fakesrc->num_buffers;
861       break;
862     case GST_STATE_PAUSED_TO_PLAYING:
863     case GST_STATE_PLAYING_TO_PAUSED:
864       break;
865     case GST_STATE_PAUSED_TO_READY:
866       if (fakesrc->parent) {
867         gst_buffer_unref (fakesrc->parent);
868         fakesrc->parent = NULL;
869       }
870       g_free (fakesrc->last_message);
871       fakesrc->last_message = NULL;
872       break;
873     case GST_STATE_READY_TO_NULL:
874       break;
875     default:
876       g_assert_not_reached ();
877       break;
878   }
880   if (GST_ELEMENT_CLASS (parent_class)->change_state)
881     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
883   return GST_STATE_SUCCESS;