]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gstreamer0-10.git/blob - gst/elements/gstfakesrc.c
Merged from INCSCHED on 200505251!!!
[glsdk/gstreamer0-10.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  */
24 #include <gstfakesrc.h>
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 };
38 /* FakeSrc signals and args */
39 enum {
40   /* FILL ME */
41   SIGNAL_HANDOFF,
42   LAST_SIGNAL
43 };
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 };
56 #define GST_TYPE_FAKESRC_OUTPUT (gst_fakesrc_output_get_type())
57 static GtkType
58 gst_fakesrc_output_get_type(void) {
59   static GtkType fakesrc_output_type = 0;
60   static GtkEnumValue fakesrc_output[] = {
61     { FAKESRC_FIRST_LAST_LOOP,          "1", "First-Last loop"},
62     { FAKESRC_LAST_FIRST_LOOP,          "2", "Last-First loop"},
63     { FAKESRC_PING_PONG,                "3", "Ping-Pong"},
64     { FAKESRC_ORDERED_RANDOM,           "4", "Ordered Random"},
65     { FAKESRC_RANDOM,                   "5", "Random"},
66     { FAKESRC_PATTERN_LOOP,             "6", "Patttern loop"},
67     { FAKESRC_PING_PONG_PATTERN,        "7", "Ping-Pong Pattern"},
68     { FAKESRC_GET_ALWAYS_SUCEEDS,       "8", "'_get' Always succeeds"},
69     {0, NULL, NULL},
70   };
71   if (!fakesrc_output_type) {
72     fakesrc_output_type = gtk_type_register_enum("GstFakeSrcOutput", fakesrc_output);
73   }
74   return fakesrc_output_type;
75 }
77 static void             gst_fakesrc_class_init  (GstFakeSrcClass *klass);
78 static void             gst_fakesrc_init        (GstFakeSrc *fakesrc);
80 static void             gst_fakesrc_set_arg     (GtkObject *object, GtkArg *arg, guint id);
81 static void             gst_fakesrc_get_arg     (GtkObject *object, GtkArg *arg, guint id);
83 static GstBuffer*       gst_fakesrc_get         (GstPad *pad);
84 static void             gst_fakesrc_loop        (GstElement *element);
86 static GstElementClass *parent_class = NULL;
87 static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
89 GtkType
90 gst_fakesrc_get_type (void) 
91 {
92   static GtkType fakesrc_type = 0;
94   if (!fakesrc_type) {
95     static const GtkTypeInfo fakesrc_info = {
96       "GstFakeSrc",
97       sizeof(GstFakeSrc),
98       sizeof(GstFakeSrcClass),
99       (GtkClassInitFunc)gst_fakesrc_class_init,
100       (GtkObjectInitFunc)gst_fakesrc_init,
101       (GtkArgSetFunc)NULL,
102       (GtkArgGetFunc)NULL,
103       (GtkClassInitFunc)NULL,
104     };
105     fakesrc_type = gtk_type_unique (GST_TYPE_ELEMENT, &fakesrc_info);
106   }
107   return fakesrc_type;
110 static void
111 gst_fakesrc_class_init (GstFakeSrcClass *klass) 
113   GtkObjectClass *gtkobject_class;
115   gtkobject_class = (GtkObjectClass*)klass;
117   parent_class = gtk_type_class (GST_TYPE_ELEMENT);
119   gtk_object_add_arg_type ("GstFakeSrc::num_sources", GTK_TYPE_INT,
120                            GTK_ARG_READWRITE, ARG_NUM_SOURCES);
121   gtk_object_add_arg_type ("GstFakeSrc::loop_based", GTK_TYPE_BOOL,
122                            GTK_ARG_READWRITE, ARG_LOOP_BASED);
123   gtk_object_add_arg_type ("GstFakeSrc::output", GST_TYPE_FAKESRC_OUTPUT,
124                            GTK_ARG_READWRITE, ARG_OUTPUT);
125   gtk_object_add_arg_type ("GstFakeSrc::pattern", GTK_TYPE_STRING,
126                            GTK_ARG_READWRITE, ARG_PATTERN);
127   gtk_object_add_arg_type ("GstFakeSrc::num_buffers", GTK_TYPE_INT,
128                            GTK_ARG_READWRITE, ARG_NUM_BUFFERS);
129   gtk_object_add_arg_type ("GstFakeSrc::eos", GTK_TYPE_BOOL,
130                            GTK_ARG_READWRITE, ARG_EOS);
131   gtk_object_add_arg_type ("GstFakeSrc::silent", GTK_TYPE_BOOL,
132                            GTK_ARG_READWRITE, ARG_SILENT);
134   gtkobject_class->set_arg = gst_fakesrc_set_arg;
135   gtkobject_class->get_arg = gst_fakesrc_get_arg;
137   gst_fakesrc_signals[SIGNAL_HANDOFF] =
138     gtk_signal_new ("handoff", GTK_RUN_LAST, gtkobject_class->type,
139                     GTK_SIGNAL_OFFSET (GstFakeSrcClass, handoff),
140                     gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1,
141                     GTK_TYPE_POINTER);
143   gtk_object_class_add_signals (gtkobject_class, gst_fakesrc_signals,
144                                 LAST_SIGNAL);
147 static void 
148 gst_fakesrc_init (GstFakeSrc *fakesrc) 
150   GstPad *pad;
152   // set the default number of 
153   fakesrc->numsrcpads = 1;
155   // create our first output pad
156   pad = gst_pad_new("src",GST_PAD_SRC);
157   gst_element_add_pad(GST_ELEMENT(fakesrc),pad);
158   fakesrc->srcpads = g_slist_append(NULL,pad);
160   fakesrc->loop_based = TRUE;
162   if (fakesrc->loop_based)
163     gst_element_set_loop_function (GST_ELEMENT (fakesrc), gst_fakesrc_loop);
164   else
165     gst_pad_set_get_function(pad,gst_fakesrc_get);
167   fakesrc->num_buffers = -1;
168   fakesrc->silent = FALSE;
169   // we're ready right away, since we don't have any args...
170 //  gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_READY);
173 static void
174 gst_fakesrc_update_functions (GstFakeSrc *src)
176   GSList *pads;
178   pads = src->srcpads;
179   while (pads) {
180     GstPad *pad = GST_PAD (pads->data);
182     if (src->loop_based) {
183       gst_element_set_loop_function (GST_ELEMENT (src), gst_fakesrc_loop);
184       gst_pad_set_get_function (pad, NULL);
185     }
186     else {
187       gst_pad_set_get_function (pad, gst_fakesrc_get);
188       gst_element_set_loop_function (GST_ELEMENT (src), NULL);
189     }
190     pads = g_slist_next (pads);
191   }
194 static void
195 gst_fakesrc_set_arg (GtkObject *object, GtkArg *arg, guint id)
197   GstFakeSrc *src;
198   gint new_numsrcs;
199   GstPad *pad;
201   /* it's not null if we got it, but it might not be ours */
202   src = GST_FAKESRC (object);
203    
204   switch(id) {
205     case ARG_NUM_SOURCES:
206       new_numsrcs = GTK_VALUE_INT (*arg);
207       if (new_numsrcs > src->numsrcpads) {
208         while (src->numsrcpads != new_numsrcs) {
209           pad = gst_pad_new(g_strdup_printf("src%d",src->numsrcpads),GST_PAD_SRC);
210           gst_element_add_pad(GST_ELEMENT(src),pad);
211           src->srcpads = g_slist_append(src->srcpads,pad);
212           src->numsrcpads++;
213         }
214         gst_fakesrc_update_functions (src);
215       }
216       break;
217     case ARG_LOOP_BASED:
218       src->loop_based = GTK_VALUE_BOOL (*arg);
219       gst_fakesrc_update_functions (src);
220       break;
221     case ARG_OUTPUT:
222       break;
223     case ARG_PATTERN:
224       break;
225     case ARG_NUM_BUFFERS:
226       src->num_buffers = GTK_VALUE_INT (*arg);
227       break;
228     case ARG_EOS:
229       src->eos = GTK_VALUE_BOOL (*arg);
230 GST_INFO (0, "will EOS on next buffer");
231       break;
232     case ARG_SILENT:
233       src->silent = GTK_VALUE_BOOL (*arg);
234       break;
235     default:
236       break;
237   }
240 static void 
241 gst_fakesrc_get_arg (GtkObject *object, GtkArg *arg, guint id)
243   GstFakeSrc *src;
244    
245   /* it's not null if we got it, but it might not be ours */
246   g_return_if_fail (GST_IS_FAKESRC (object));
247   
248   src = GST_FAKESRC (object);
249    
250   switch (id) {
251     case ARG_NUM_SOURCES:
252       GTK_VALUE_INT (*arg) = src->numsrcpads;
253       break;
254     case ARG_LOOP_BASED:
255       GTK_VALUE_BOOL (*arg) = src->loop_based;
256       break;
257     case ARG_OUTPUT:
258       GTK_VALUE_INT (*arg) = src->output;
259       break;
260     case ARG_PATTERN:
261       GTK_VALUE_STRING (*arg) = src->pattern;
262       break;
263     case ARG_NUM_BUFFERS:
264       GTK_VALUE_INT (*arg) = src->num_buffers;
265       break;
266     case ARG_EOS:
267       GTK_VALUE_BOOL (*arg) = src->eos;
268     case ARG_SILENT:
269       GTK_VALUE_BOOL (*arg) = src->silent;
270       break;
271     default:
272       arg->type = GTK_TYPE_INVALID;
273       break;
274   }
278 /**
279  * gst_fakesrc_get:
280  * @src: the faksesrc to get
281  * 
282  * generate an empty buffer and return it
283  *
284  * Returns: a new empty buffer
285  */
286 static GstBuffer *
287 gst_fakesrc_get(GstPad *pad)
289   GstFakeSrc *src;
290   GstBuffer *buf;
292   g_return_val_if_fail (pad != NULL, NULL);
294   src = GST_FAKESRC (gst_pad_get_parent (pad));
296   g_return_val_if_fail (GST_IS_FAKESRC (src), NULL);
298   if (src->num_buffers == 0) {
299     gst_pad_set_eos (pad);
300     return NULL;
301   }
302   else {
303     if (src->num_buffers > 0)
304       src->num_buffers--;
305   }
307   if (src->eos) {
308     GST_INFO (0, "fakesrc is setting eos on pad");
309     gst_pad_set_eos (pad);
310     return NULL;
311   }
313   if (!src->silent)
314     g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad));
315   buf = gst_buffer_new();
317   gtk_signal_emit (GTK_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF],
318                    buf);
320   return buf;
323 /**
324  * gst_fakesrc_loop:
325  * @element: the faksesrc to loop
326  * 
327  * generate an empty buffer and push it to the next element.
328  */
329 static void
330 gst_fakesrc_loop(GstElement *element)
332   GstFakeSrc *src;
334   g_return_if_fail(element != NULL);
335   g_return_if_fail(GST_IS_FAKESRC(element));
337   src = GST_FAKESRC (element);
339   do {
340     GSList *pads;
342     pads = src->srcpads;
344     while (pads) {
345       GstPad *pad = GST_PAD (pads->data);
346       GstBuffer *buf;
348       if (src->num_buffers == 0) {
349         gst_pad_set_eos (pad);
350         return;
351       }
352       else {
353       if (src->num_buffers > 0)
354          src->num_buffers--;
355       }
357       if (src->eos) {
358         GST_INFO (0, "fakesrc is setting eos on pad");
359         gst_pad_set_eos (pad);
360         return;
361       }
363       buf = gst_buffer_new();
364       if (!src->silent)
365         g_print("fakesrc: ******* (%s:%s)> \n",GST_DEBUG_PAD_NAME(pad));
367       gtk_signal_emit (GTK_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF],
368                        buf);
369       gst_pad_push (pad, buf);
371       pads = g_slist_next (pads);
372     }
373   } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));