Removed the old eos and qos functions.
[platform/upstream/gstreamer.git] / gst / 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  */
22
23
24 #include <gstfakesrc.h>
25
26
27 GstElementDetails gst_fakesrc_details = {
28   "Fake Source",
29   "Source",
30   "Push empty (no data) buffers around",
31   VERSION,
32   "Erik Walthinsen <omega@cse.ogi.edu>\n"
33   "Wim Taymans <wim.taymans@chello.be>",
34   "(C) 1999",
35 };
36
37
38 /* FakeSrc signals and args */
39 enum {
40   /* FILL ME */
41   SIGNAL_HANDOFF,
42   LAST_SIGNAL
43 };
44
45 enum {
46   ARG_0,
47   ARG_NUM_SOURCES,
48   ARG_LOOP_BASED,
49   ARG_OUTPUT,
50   ARG_PATTERN,
51   ARG_NUM_BUFFERS,
52   ARG_EOS,
53   ARG_SILENT
54 };
55
56 GST_PADTEMPLATE_FACTORY (fakesrc_src_factory,
57   "src%d",
58   GST_PAD_SRC,
59   GST_PAD_REQUEST,
60   NULL                  /* no caps */
61 );
62
63 #define GST_TYPE_FAKESRC_OUTPUT (gst_fakesrc_output_get_type())
64 static GType
65 gst_fakesrc_output_get_type (void) 
66 {
67   static GType fakesrc_output_type = 0;
68   static GEnumValue fakesrc_output[] = {
69     { FAKESRC_FIRST_LAST_LOOP,          "1", "First-Last loop"},
70     { FAKESRC_LAST_FIRST_LOOP,          "2", "Last-First loop"},
71     { FAKESRC_PING_PONG,                "3", "Ping-Pong"},
72     { FAKESRC_ORDERED_RANDOM,           "4", "Ordered Random"},
73     { FAKESRC_RANDOM,                   "5", "Random"},
74     { FAKESRC_PATTERN_LOOP,             "6", "Patttern loop"},
75     { FAKESRC_PING_PONG_PATTERN,        "7", "Ping-Pong Pattern"},
76     { FAKESRC_GET_ALWAYS_SUCEEDS,       "8", "'_get' Always succeeds"},
77     {0, NULL, NULL},
78   };
79   if (!fakesrc_output_type) {
80     fakesrc_output_type = g_enum_register_static ("GstFakeSrcOutput", fakesrc_output);
81   }
82   return fakesrc_output_type;
83 }
84
85 static void             gst_fakesrc_class_init          (GstFakeSrcClass *klass);
86 static void             gst_fakesrc_init                (GstFakeSrc *fakesrc);
87
88 static GstPad*          gst_fakesrc_request_new_pad     (GstElement *element, GstPadTemplate *templ);
89 static void             gst_fakesrc_set_property        (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
90 static void             gst_fakesrc_get_property        (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
91
92 static GstBuffer*       gst_fakesrc_get                 (GstPad *pad);
93 static void             gst_fakesrc_loop                (GstElement *element);
94
95 static GstElementClass *parent_class = NULL;
96 static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
97
98 GType
99 gst_fakesrc_get_type (void) 
100 {
101   static GType fakesrc_type = 0;
102
103   if (!fakesrc_type) {
104     static const GTypeInfo fakesrc_info = {
105       sizeof(GstFakeSrcClass),
106       NULL,
107       NULL,
108       (GClassInitFunc)gst_fakesrc_class_init,
109       NULL,
110       NULL,
111       sizeof(GstFakeSrc),
112       0,
113       (GInstanceInitFunc)gst_fakesrc_init,
114     };
115     fakesrc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstFakeSrc", &fakesrc_info, 0);
116   }
117   return fakesrc_type;
118 }
119
120 static void
121 gst_fakesrc_class_init (GstFakeSrcClass *klass) 
122 {
123   GObjectClass *gobject_class;
124   GstElementClass *gstelement_class;
125
126   gobject_class = (GObjectClass*)klass;
127   gstelement_class = (GstElementClass*)klass;
128
129   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
130
131   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
132     g_param_spec_int ("num_sources", "num_sources", "num_sources",
133                       1, G_MAXINT, 1, G_PARAM_READABLE));
134   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_LOOP_BASED,
135     g_param_spec_boolean("loop_based","loop_based","loop_based",
136                          FALSE, G_PARAM_READWRITE)); // CHECKME
137   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_OUTPUT,
138     g_param_spec_enum("output","output","output",
139                       GST_TYPE_FAKESRC_OUTPUT,FAKESRC_FIRST_LAST_LOOP,G_PARAM_READWRITE)); // CHECKME!
140   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PATTERN,
141     g_param_spec_string("pattern","pattern","pattern",
142                         NULL, G_PARAM_READWRITE)); // CHECKME
143   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NUM_BUFFERS,
144     g_param_spec_int("num_buffers","num_buffers","num_buffers",
145                      G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME
146   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_EOS,
147     g_param_spec_boolean("eos","eos","eos",
148                          TRUE,G_PARAM_READWRITE)); // CHECKME
149   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SILENT,
150     g_param_spec_boolean("silent","silent","silent",
151                          FALSE, G_PARAM_READWRITE)); // CHECKME
152
153   gst_fakesrc_signals[SIGNAL_HANDOFF] =
154     g_signal_newc ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
155                     G_STRUCT_OFFSET (GstFakeSrcClass, handoff), NULL, NULL,
156                     g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
157                     G_TYPE_POINTER);
158
159   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesrc_set_property);
160   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesrc_get_property);
161
162   gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
163 }
164
165 static void 
166 gst_fakesrc_init (GstFakeSrc *fakesrc) 
167 {
168   GstPad *pad;
169
170   // set the default number of 
171   fakesrc->numsrcpads = 1;
172
173   // create our first output pad
174   pad = gst_pad_new ("src", GST_PAD_SRC);
175   gst_element_add_pad (GST_ELEMENT (fakesrc), pad);
176   fakesrc->srcpads = g_slist_append (NULL, pad);
177
178   fakesrc->loop_based = FALSE;
179
180   if (fakesrc->loop_based)
181     gst_element_set_loop_function (GST_ELEMENT (fakesrc), GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
182   else
183     gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
184
185   fakesrc->num_buffers = -1;
186   fakesrc->buffer_count = 0;
187   fakesrc->silent = FALSE;
188   // we're ready right away, since we don't have any args...
189 //  gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_READY);
190 }
191
192 static GstPad*
193 gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ)
194 {
195   gchar *name;
196   GstPad *srcpad;
197   GstFakeSrc *fakesrc;
198
199   g_return_val_if_fail (GST_IS_FAKESRC (element), NULL);
200
201   if (templ->direction != GST_PAD_SRC) {
202     g_warning ("gstfakesrc: request new pad that is not a SRC pad\n");
203     return NULL;
204   }
205
206   fakesrc = GST_FAKESRC (element);
207
208   name = g_strdup_printf ("src%d", fakesrc->numsrcpads);
209
210   srcpad = gst_pad_new_from_template (templ, name);
211   gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
212
213   fakesrc->srcpads = g_slist_prepend (fakesrc->srcpads, srcpad);
214   fakesrc->numsrcpads++;
215
216   return srcpad;
217 }
218
219 static void
220 gst_fakesrc_update_functions (GstFakeSrc *src)
221 {
222   GSList *pads;
223
224   if (src->loop_based) {
225     gst_element_set_loop_function (GST_ELEMENT (src), GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
226   }
227   else {
228     gst_element_set_loop_function (GST_ELEMENT (src), NULL);
229   }
230
231   pads = src->srcpads;
232   while (pads) {
233     GstPad *pad = GST_PAD (pads->data);
234
235     if (src->loop_based) {
236       gst_pad_set_get_function (pad, NULL);
237     }
238     else {
239       gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
240     }
241     pads = g_slist_next (pads);
242   }
243 }
244
245 static void
246 gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
247 {
248   GstFakeSrc *src;
249
250   /* it's not null if we got it, but it might not be ours */
251   src = GST_FAKESRC (object);
252    
253   switch (prop_id) {
254     case ARG_LOOP_BASED:
255       src->loop_based = g_value_get_boolean (value);
256       gst_fakesrc_update_functions (src);
257       break;
258     case ARG_OUTPUT:
259       break;
260     case ARG_PATTERN:
261       break;
262     case ARG_NUM_BUFFERS:
263       src->num_buffers = g_value_get_int (value);
264       break;
265     case ARG_EOS:
266       src->eos = g_value_get_boolean (value);
267 GST_INFO (0, "will EOS on next buffer");
268       break;
269     case ARG_SILENT:
270       src->silent = g_value_get_boolean (value);
271       break;
272     default:
273       break;
274   }
275 }
276
277 static void 
278 gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
279 {
280   GstFakeSrc *src;
281    
282   /* it's not null if we got it, but it might not be ours */
283   g_return_if_fail (GST_IS_FAKESRC (object));
284   
285   src = GST_FAKESRC (object);
286    
287   switch (prop_id) {
288     case ARG_NUM_SOURCES:
289       g_value_set_int (value, src->numsrcpads);
290       break;
291     case ARG_LOOP_BASED:
292       g_value_set_boolean (value, src->loop_based);
293       break;
294     case ARG_OUTPUT:
295       g_value_set_int (value, src->output);
296       break;
297     case ARG_PATTERN:
298       g_value_set_string (value, src->pattern);
299       break;
300     case ARG_NUM_BUFFERS:
301       g_value_set_int (value, src->num_buffers);
302       break;
303     case ARG_EOS:
304       g_value_set_boolean (value, src->eos);
305       break;
306     case ARG_SILENT:
307       g_value_set_boolean (value, src->silent);
308       break;
309     default:
310       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
311       break;
312   }
313 }
314
315
316 /**
317  * gst_fakesrc_get:
318  * @src: the faksesrc to get
319  * 
320  * generate an empty buffer and return it
321  *
322  * Returns: a new empty buffer
323  */
324 static GstBuffer *
325 gst_fakesrc_get(GstPad *pad)
326 {
327   GstFakeSrc *src;
328   GstBuffer *buf;
329
330   g_return_val_if_fail (pad != NULL, NULL);
331
332   src = GST_FAKESRC (gst_pad_get_parent (pad));
333
334   g_return_val_if_fail (GST_IS_FAKESRC (src), NULL);
335
336   if (src->num_buffers == 0) {
337     gst_pad_event (pad, (void*)GST_EVENT_EOS);
338     return NULL;
339   }
340   else {
341     if (src->num_buffers > 0)
342       src->num_buffers--;
343   }
344
345   if (src->eos) {
346     GST_INFO (0, "fakesrc is setting eos on pad");
347     gst_pad_event (pad, (void*)GST_EVENT_EOS);
348     return NULL;
349   }
350
351   buf = gst_buffer_new();
352   GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
353
354   if (!src->silent)
355     g_print("fakesrc: get      ******* (%s:%s)> (%d bytes, %llu) \n",
356                GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
357
358   g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
359                    buf);
360
361   return buf;
362 }
363
364 /**
365  * gst_fakesrc_loop:
366  * @element: the faksesrc to loop
367  * 
368  * generate an empty buffer and push it to the next element.
369  */
370 static void
371 gst_fakesrc_loop(GstElement *element)
372 {
373   GstFakeSrc *src;
374
375   g_return_if_fail(element != NULL);
376   g_return_if_fail(GST_IS_FAKESRC(element));
377
378   src = GST_FAKESRC (element);
379
380   do {
381     GSList *pads;
382
383     pads = src->srcpads;
384
385     while (pads) {
386       GstPad *pad = GST_PAD (pads->data);
387       GstBuffer *buf;
388
389       if (src->num_buffers == 0) {
390         gst_pad_event (pad, (void*)GST_EVENT_EOS);
391         return;
392       }
393       else {
394       if (src->num_buffers > 0)
395          src->num_buffers--;
396       }
397
398       if (src->eos) {
399         GST_INFO (0, "fakesrc is setting eos on pad");
400         gst_pad_event (pad, (void*)GST_EVENT_EOS);
401         return;
402       }
403
404       buf = gst_buffer_new();
405       GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
406
407       if (!src->silent)
408         g_print("fakesrc:  loop    ******* (%s:%s)  > (%d bytes, %llu) \n",
409                GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
410
411       g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
412                        buf);
413       gst_pad_push (pad, buf);
414
415       pads = g_slist_next (pads);
416     }
417   } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
418 }
419
420 gboolean
421 gst_fakesrc_factory_init (GstElementFactory *factory)
422 {
423   gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (fakesrc_src_factory));
424
425   return TRUE;
426 }
427