2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
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.
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.
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.
24 #include <gstfakesrc.h>
27 GstElementDetails gst_fakesrc_details = {
30 "Push empty (no data) buffers around",
32 "Erik Walthinsen <omega@cse.ogi.edu>\n"
33 "Wim Taymans <wim.taymans@chello.be>",
38 /* FakeSrc signals and args */
56 GST_PADTEMPLATE_FACTORY (fakesrc_src_factory,
63 #define GST_TYPE_FAKESRC_OUTPUT (gst_fakesrc_output_get_type())
65 gst_fakesrc_output_get_type (void)
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"},
79 if (!fakesrc_output_type) {
80 fakesrc_output_type = g_enum_register_static ("GstFakeSrcOutput", fakesrc_output);
82 return fakesrc_output_type;
85 static void gst_fakesrc_class_init (GstFakeSrcClass *klass);
86 static void gst_fakesrc_init (GstFakeSrc *fakesrc);
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);
92 static GstBuffer* gst_fakesrc_get (GstPad *pad);
93 static void gst_fakesrc_loop (GstElement *element);
95 static GstElementClass *parent_class = NULL;
96 static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 };
99 gst_fakesrc_get_type (void)
101 static GType fakesrc_type = 0;
104 static const GTypeInfo fakesrc_info = {
105 sizeof(GstFakeSrcClass),
108 (GClassInitFunc)gst_fakesrc_class_init,
113 (GInstanceInitFunc)gst_fakesrc_init,
115 fakesrc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstFakeSrc", &fakesrc_info, 0);
121 gst_fakesrc_class_init (GstFakeSrcClass *klass)
123 GObjectClass *gobject_class;
124 GstElementClass *gstelement_class;
126 gobject_class = (GObjectClass*)klass;
127 gstelement_class = (GstElementClass*)klass;
129 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
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
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,
159 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesrc_set_property);
160 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesrc_get_property);
162 gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
166 gst_fakesrc_init (GstFakeSrc *fakesrc)
170 // set the default number of
171 fakesrc->numsrcpads = 1;
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);
178 fakesrc->loop_based = FALSE;
180 if (fakesrc->loop_based)
181 gst_element_set_loop_function (GST_ELEMENT (fakesrc), GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
183 gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
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);
193 gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ)
199 g_return_val_if_fail (GST_IS_FAKESRC (element), NULL);
201 if (templ->direction != GST_PAD_SRC) {
202 g_warning ("gstfakesrc: request new pad that is not a SRC pad\n");
206 fakesrc = GST_FAKESRC (element);
208 name = g_strdup_printf ("src%d", fakesrc->numsrcpads);
210 srcpad = gst_pad_new_from_template (templ, name);
211 gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad);
213 fakesrc->srcpads = g_slist_prepend (fakesrc->srcpads, srcpad);
214 fakesrc->numsrcpads++;
220 gst_fakesrc_update_functions (GstFakeSrc *src)
224 if (src->loop_based) {
225 gst_element_set_loop_function (GST_ELEMENT (src), GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
228 gst_element_set_loop_function (GST_ELEMENT (src), NULL);
233 GstPad *pad = GST_PAD (pads->data);
235 if (src->loop_based) {
236 gst_pad_set_get_function (pad, NULL);
239 gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
241 pads = g_slist_next (pads);
246 gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
250 /* it's not null if we got it, but it might not be ours */
251 src = GST_FAKESRC (object);
255 src->loop_based = g_value_get_boolean (value);
256 gst_fakesrc_update_functions (src);
262 case ARG_NUM_BUFFERS:
263 src->num_buffers = g_value_get_int (value);
266 src->eos = g_value_get_boolean (value);
267 GST_INFO (0, "will EOS on next buffer");
270 src->silent = g_value_get_boolean (value);
278 gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
282 /* it's not null if we got it, but it might not be ours */
283 g_return_if_fail (GST_IS_FAKESRC (object));
285 src = GST_FAKESRC (object);
288 case ARG_NUM_SOURCES:
289 g_value_set_int (value, src->numsrcpads);
292 g_value_set_boolean (value, src->loop_based);
295 g_value_set_int (value, src->output);
298 g_value_set_string (value, src->pattern);
300 case ARG_NUM_BUFFERS:
301 g_value_set_int (value, src->num_buffers);
304 g_value_set_boolean (value, src->eos);
307 g_value_set_boolean (value, src->silent);
310 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
318 * @src: the faksesrc to get
320 * generate an empty buffer and return it
322 * Returns: a new empty buffer
325 gst_fakesrc_get(GstPad *pad)
330 g_return_val_if_fail (pad != NULL, NULL);
332 src = GST_FAKESRC (gst_pad_get_parent (pad));
334 g_return_val_if_fail (GST_IS_FAKESRC (src), NULL);
336 if (src->num_buffers == 0) {
337 gst_pad_event (pad, (void*)GST_EVENT_EOS);
341 if (src->num_buffers > 0)
346 GST_INFO (0, "fakesrc is setting eos on pad");
347 gst_pad_event (pad, (void*)GST_EVENT_EOS);
351 buf = gst_buffer_new();
352 GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
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));
358 g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
366 * @element: the faksesrc to loop
368 * generate an empty buffer and push it to the next element.
371 gst_fakesrc_loop(GstElement *element)
375 g_return_if_fail(element != NULL);
376 g_return_if_fail(GST_IS_FAKESRC(element));
378 src = GST_FAKESRC (element);
386 GstPad *pad = GST_PAD (pads->data);
389 if (src->num_buffers == 0) {
390 gst_pad_event (pad, (void*)GST_EVENT_EOS);
394 if (src->num_buffers > 0)
399 GST_INFO (0, "fakesrc is setting eos on pad");
400 gst_pad_event (pad, (void*)GST_EVENT_EOS);
404 buf = gst_buffer_new();
405 GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
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));
411 g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
413 gst_pad_push (pad, buf);
415 pads = g_slist_next (pads);
417 } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
421 gst_fakesrc_factory_init (GstElementFactory *factory)
423 gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (fakesrc_src_factory));