Branch data Line data Source code
1 : : /* GStreamer
2 : : * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 : : * 2000 Wim Taymans <wim@fluendo.com>
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 : : * SECTION:element-fakesrc
24 : : * @see_also: #GstFakeSink
25 : : *
26 : : * The fakesrc element is a multipurpose element that can generate
27 : : * a wide range of buffers and can operate in various scheduling modes.
28 : : *
29 : : * It is mostly used as a testing element, one trivial example for testing
30 : : * basic <application>GStreamer</application> core functionality is:
31 : : *
32 : : * <refsect2>
33 : : * <title>Example launch line</title>
34 : : * |[
35 : : * gst-launch -v fakesrc num-buffers=5 ! fakesink
36 : : * ]| This pipeline will push 5 empty buffers to the fakesink element and then
37 : : * sends an EOS.
38 : : * </refsect2>
39 : : *
40 : : * Last reviewed on 2008-06-20 (0.10.21)
41 : : */
42 : :
43 : : /* FIXME: this ignores basesrc::blocksize property, which could be used as an
44 : : * alias to ::sizemax (see gst_base_src_get_blocksize()).
45 : : */
46 : :
47 : : #ifdef HAVE_CONFIG_H
48 : : # include "config.h"
49 : : #endif
50 : :
51 : : #include <stdlib.h>
52 : : #include <string.h>
53 : :
54 : : #include "gstfakesrc.h"
55 : : #include <gst/gstmarshal.h>
56 : :
57 : : static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
58 : : GST_PAD_SRC,
59 : : GST_PAD_ALWAYS,
60 : : GST_STATIC_CAPS_ANY);
61 : :
62 : : GST_DEBUG_CATEGORY_STATIC (gst_fake_src_debug);
63 : : #define GST_CAT_DEFAULT gst_fake_src_debug
64 : :
65 : : /* FakeSrc signals and args */
66 : : enum
67 : : {
68 : : /* FILL ME */
69 : : SIGNAL_HANDOFF,
70 : : LAST_SIGNAL
71 : : };
72 : :
73 : : #define DEFAULT_OUTPUT FAKE_SRC_FIRST_LAST_LOOP
74 : : #define DEFAULT_DATA FAKE_SRC_DATA_ALLOCATE
75 : : #define DEFAULT_SIZETYPE FAKE_SRC_SIZETYPE_EMPTY
76 : : #define DEFAULT_SIZEMIN 0
77 : : #define DEFAULT_SIZEMAX 4096
78 : : #define DEFAULT_FILLTYPE FAKE_SRC_FILLTYPE_ZERO
79 : : #define DEFAULT_DATARATE 0
80 : : #define DEFAULT_SYNC FALSE
81 : : #define DEFAULT_PATTERN NULL
82 : : #define DEFAULT_EOS FALSE
83 : : #define DEFAULT_SIGNAL_HANDOFFS FALSE
84 : : #define DEFAULT_SILENT FALSE
85 : : #define DEFAULT_DUMP FALSE
86 : : #define DEFAULT_PARENTSIZE 4096*10
87 : : #define DEFAULT_CAN_ACTIVATE_PULL TRUE
88 : : #define DEFAULT_CAN_ACTIVATE_PUSH TRUE
89 : : #define DEFAULT_FORMAT GST_FORMAT_BYTES
90 : :
91 : : enum
92 : : {
93 : : PROP_0,
94 : : PROP_OUTPUT,
95 : : PROP_DATA,
96 : : PROP_SIZETYPE,
97 : : PROP_SIZEMIN,
98 : : PROP_SIZEMAX,
99 : : PROP_FILLTYPE,
100 : : PROP_DATARATE,
101 : : PROP_SYNC,
102 : : PROP_PATTERN,
103 : : PROP_EOS,
104 : : PROP_SIGNAL_HANDOFFS,
105 : : PROP_SILENT,
106 : : PROP_DUMP,
107 : : PROP_PARENTSIZE,
108 : : PROP_LAST_MESSAGE,
109 : : PROP_CAN_ACTIVATE_PULL,
110 : : PROP_CAN_ACTIVATE_PUSH,
111 : : PROP_IS_LIVE,
112 : : PROP_FORMAT,
113 : : PROP_LAST,
114 : : };
115 : :
116 : : /* not implemented
117 : : #define GST_TYPE_FAKE_SRC_OUTPUT (gst_fake_src_output_get_type())
118 : : static GType
119 : : gst_fake_src_output_get_type (void)
120 : : {
121 : : static GType fakesrc_output_type = 0;
122 : : static const GEnumValue fakesrc_output[] = {
123 : : {FAKE_SRC_FIRST_LAST_LOOP, "1", "First-Last loop"},
124 : : {FAKE_SRC_LAST_FIRST_LOOP, "2", "Last-First loop"},
125 : : {FAKE_SRC_PING_PONG, "3", "Ping-Pong"},
126 : : {FAKE_SRC_ORDERED_RANDOM, "4", "Ordered Random"},
127 : : {FAKE_SRC_RANDOM, "5", "Random"},
128 : : {FAKE_SRC_PATTERN_LOOP, "6", "Patttern loop"},
129 : : {FAKE_SRC_PING_PONG_PATTERN, "7", "Ping-Pong Pattern"},
130 : : {FAKE_SRC_GET_ALWAYS_SUCEEDS, "8", "'_get' Always succeeds"},
131 : : {0, NULL, NULL},
132 : : };
133 : :
134 : : if (!fakesrc_output_type) {
135 : : fakesrc_output_type =
136 : : g_enum_register_static ("GstFakeSrcOutput", fakesrc_output);
137 : : }
138 : : return fakesrc_output_type;
139 : : }
140 : : */
141 : :
142 : : #define GST_TYPE_FAKE_SRC_DATA (gst_fake_src_data_get_type())
143 : : static GType
144 : 97 : gst_fake_src_data_get_type (void)
145 : : {
146 : : static GType fakesrc_data_type = 0;
147 : : static const GEnumValue fakesrc_data[] = {
148 : : {FAKE_SRC_DATA_ALLOCATE, "Allocate data", "allocate"},
149 : : {FAKE_SRC_DATA_SUBBUFFER, "Subbuffer data", "subbuffer"},
150 : : {0, NULL, NULL},
151 : : };
152 : :
153 [ + - ]: 97 : if (!fakesrc_data_type) {
154 : 97 : fakesrc_data_type =
155 : 97 : g_enum_register_static ("GstFakeSrcDataType", fakesrc_data);
156 : : }
157 : 97 : return fakesrc_data_type;
158 : : }
159 : :
160 : : #define GST_TYPE_FAKE_SRC_SIZETYPE (gst_fake_src_sizetype_get_type())
161 : : static GType
162 : 97 : gst_fake_src_sizetype_get_type (void)
163 : : {
164 : : static GType fakesrc_sizetype_type = 0;
165 : : static const GEnumValue fakesrc_sizetype[] = {
166 : : {FAKE_SRC_SIZETYPE_EMPTY, "Send empty buffers", "empty"},
167 : : {FAKE_SRC_SIZETYPE_FIXED, "Fixed size buffers (sizemax sized)", "fixed"},
168 : : {FAKE_SRC_SIZETYPE_RANDOM,
169 : : "Random sized buffers (sizemin <= size <= sizemax)", "random"},
170 : : {0, NULL, NULL},
171 : : };
172 : :
173 [ + - ]: 97 : if (!fakesrc_sizetype_type) {
174 : 97 : fakesrc_sizetype_type =
175 : 97 : g_enum_register_static ("GstFakeSrcSizeType", fakesrc_sizetype);
176 : : }
177 : 97 : return fakesrc_sizetype_type;
178 : : }
179 : :
180 : : #define GST_TYPE_FAKE_SRC_FILLTYPE (gst_fake_src_filltype_get_type())
181 : : static GType
182 : 97 : gst_fake_src_filltype_get_type (void)
183 : : {
184 : : static GType fakesrc_filltype_type = 0;
185 : : static const GEnumValue fakesrc_filltype[] = {
186 : : {FAKE_SRC_FILLTYPE_NOTHING, "Leave data as malloced", "nothing"},
187 : : {FAKE_SRC_FILLTYPE_ZERO, "Fill buffers with zeros", "zero"},
188 : : {FAKE_SRC_FILLTYPE_RANDOM, "Fill buffers with random crap", "random"},
189 : : {FAKE_SRC_FILLTYPE_PATTERN, "Fill buffers with pattern 0x00 -> 0xff",
190 : : "pattern"},
191 : : {FAKE_SRC_FILLTYPE_PATTERN_CONT,
192 : : "Fill buffers with pattern 0x00 -> 0xff that spans buffers",
193 : : "pattern-span"},
194 : : {0, NULL, NULL},
195 : : };
196 : :
197 [ + - ]: 97 : if (!fakesrc_filltype_type) {
198 : 97 : fakesrc_filltype_type =
199 : 97 : g_enum_register_static ("GstFakeSrcFillType", fakesrc_filltype);
200 : : }
201 : 97 : return fakesrc_filltype_type;
202 : : }
203 : :
204 : : #define _do_init(bla) \
205 : : GST_DEBUG_CATEGORY_INIT (gst_fake_src_debug, "fakesrc", 0, "fakesrc element");
206 : :
207 [ + + ][ + - ]: 1080510 : GST_BOILERPLATE_FULL (GstFakeSrc, gst_fake_src, GstBaseSrc, GST_TYPE_BASE_SRC,
208 : 1080510 : _do_init);
209 : :
210 : : static void gst_fake_src_finalize (GObject * object);
211 : : static void gst_fake_src_set_property (GObject * object, guint prop_id,
212 : : const GValue * value, GParamSpec * pspec);
213 : : static void gst_fake_src_get_property (GObject * object, guint prop_id,
214 : : GValue * value, GParamSpec * pspec);
215 : :
216 : : static gboolean gst_fake_src_start (GstBaseSrc * basesrc);
217 : : static gboolean gst_fake_src_stop (GstBaseSrc * basesrc);
218 : : static gboolean gst_fake_src_is_seekable (GstBaseSrc * basesrc);
219 : :
220 : : static gboolean gst_fake_src_event_handler (GstBaseSrc * src, GstEvent * event);
221 : : static void gst_fake_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
222 : : GstClockTime * start, GstClockTime * end);
223 : : static GstFlowReturn gst_fake_src_create (GstBaseSrc * src, guint64 offset,
224 : : guint length, GstBuffer ** buf);
225 : :
226 : : static guint gst_fake_src_signals[LAST_SIGNAL] = { 0 };
227 : :
228 : : static GParamSpec *pspec_last_message = NULL;
229 : :
230 : : static void
231 : 0 : marshal_VOID__MINIOBJECT_OBJECT (GClosure * closure, GValue * return_value,
232 : : guint n_param_values, const GValue * param_values, gpointer invocation_hint,
233 : : gpointer marshal_data)
234 : : {
235 : : typedef void (*marshalfunc_VOID__MINIOBJECT_OBJECT) (gpointer obj,
236 : : gpointer arg1, gpointer arg2, gpointer data2);
237 : : register marshalfunc_VOID__MINIOBJECT_OBJECT callback;
238 : 0 : register GCClosure *cc = (GCClosure *) closure;
239 : : register gpointer data1, data2;
240 : :
241 [ # # ]: 0 : g_return_if_fail (n_param_values == 3);
242 : :
243 [ # # ]: 0 : if (G_CCLOSURE_SWAP_DATA (closure)) {
244 : 0 : data1 = closure->data;
245 : 0 : data2 = g_value_peek_pointer (param_values + 0);
246 : : } else {
247 : 0 : data1 = g_value_peek_pointer (param_values + 0);
248 : 0 : data2 = closure->data;
249 : : }
250 : 0 : callback =
251 [ # # ]: 0 : (marshalfunc_VOID__MINIOBJECT_OBJECT) (marshal_data ? marshal_data :
252 : : cc->callback);
253 : :
254 : 0 : callback (data1, gst_value_get_mini_object (param_values + 1),
255 : : g_value_get_object (param_values + 2), data2);
256 : : }
257 : :
258 : : static void
259 : 97 : gst_fake_src_base_init (gpointer g_class)
260 : : {
261 : 97 : GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
262 : :
263 : 97 : gst_element_class_set_details_simple (gstelement_class,
264 : : "Fake Source",
265 : : "Source",
266 : : "Push empty (no data) buffers around",
267 : : "Erik Walthinsen <omega@cse.ogi.edu>, " "Wim Taymans <wim@fluendo.com>");
268 : 97 : gst_element_class_add_pad_template (gstelement_class,
269 : : gst_static_pad_template_get (&srctemplate));
270 : 97 : }
271 : :
272 : : static void
273 : 97 : gst_fake_src_class_init (GstFakeSrcClass * klass)
274 : : {
275 : : GObjectClass *gobject_class;
276 : : GstBaseSrcClass *gstbase_src_class;
277 : :
278 : 97 : gobject_class = G_OBJECT_CLASS (klass);
279 : 97 : gstbase_src_class = GST_BASE_SRC_CLASS (klass);
280 : :
281 : 97 : gobject_class->finalize = gst_fake_src_finalize;
282 : :
283 : 97 : gobject_class->set_property = gst_fake_src_set_property;
284 : 97 : gobject_class->get_property = gst_fake_src_get_property;
285 : :
286 : : /*
287 : : FIXME: this is not implemented; would make sense once basesrc and fakesrc
288 : : support multiple pads
289 : : g_object_class_install_property (gobject_class, PROP_OUTPUT,
290 : : g_param_spec_enum ("output", "output", "Output method (currently unused)",
291 : : GST_TYPE_FAKE_SRC_OUTPUT, DEFAULT_OUTPUT, G_PARAM_READWRITE));
292 : : */
293 : 97 : g_object_class_install_property (gobject_class, PROP_DATA,
294 : : g_param_spec_enum ("data", "data", "Data allocation method",
295 : : GST_TYPE_FAKE_SRC_DATA, DEFAULT_DATA,
296 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
297 : 97 : g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_SIZETYPE,
298 : : g_param_spec_enum ("sizetype", "sizetype",
299 : : "How to determine buffer sizes", GST_TYPE_FAKE_SRC_SIZETYPE,
300 : : DEFAULT_SIZETYPE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
301 : 97 : g_object_class_install_property (gobject_class, PROP_SIZEMIN,
302 : : g_param_spec_int ("sizemin", "sizemin", "Minimum buffer size", 0,
303 : : G_MAXINT, DEFAULT_SIZEMIN,
304 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
305 : 97 : g_object_class_install_property (gobject_class, PROP_SIZEMAX,
306 : : g_param_spec_int ("sizemax", "sizemax", "Maximum buffer size", 0,
307 : : G_MAXINT, DEFAULT_SIZEMAX,
308 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
309 : 97 : g_object_class_install_property (gobject_class, PROP_PARENTSIZE,
310 : : g_param_spec_int ("parentsize", "parentsize",
311 : : "Size of parent buffer for sub-buffered allocation", 0, G_MAXINT,
312 : : DEFAULT_PARENTSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
313 : 97 : g_object_class_install_property (gobject_class, PROP_FILLTYPE,
314 : : g_param_spec_enum ("filltype", "filltype",
315 : : "How to fill the buffer, if at all", GST_TYPE_FAKE_SRC_FILLTYPE,
316 : : DEFAULT_FILLTYPE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
317 : 97 : g_object_class_install_property (gobject_class, PROP_DATARATE,
318 : : g_param_spec_int ("datarate", "Datarate",
319 : : "Timestamps buffers with number of bytes per second (0 = none)", 0,
320 : : G_MAXINT, DEFAULT_DATARATE,
321 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
322 : 97 : g_object_class_install_property (gobject_class, PROP_SYNC,
323 : : g_param_spec_boolean ("sync", "Sync", "Sync to the clock to the datarate",
324 : : DEFAULT_SYNC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
325 : 97 : g_object_class_install_property (gobject_class, PROP_PATTERN,
326 : : g_param_spec_string ("pattern", "pattern", "pattern", DEFAULT_PATTERN,
327 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
328 : 97 : pspec_last_message = g_param_spec_string ("last-message", "last-message",
329 : : "The last status message", NULL,
330 : : G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
331 : 97 : g_object_class_install_property (gobject_class, PROP_LAST_MESSAGE,
332 : : pspec_last_message);
333 : 97 : g_object_class_install_property (gobject_class, PROP_SILENT,
334 : : g_param_spec_boolean ("silent", "Silent",
335 : : "Don't produce last_message events", DEFAULT_SILENT,
336 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
337 : 97 : g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS,
338 : : g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
339 : : "Send a signal before pushing the buffer", DEFAULT_SIGNAL_HANDOFFS,
340 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
341 : 97 : g_object_class_install_property (gobject_class, PROP_DUMP,
342 : : g_param_spec_boolean ("dump", "Dump", "Dump buffer contents to stdout",
343 : : DEFAULT_DUMP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
344 : 97 : g_object_class_install_property (gobject_class, PROP_CAN_ACTIVATE_PUSH,
345 : : g_param_spec_boolean ("can-activate-push", "Can activate push",
346 : : "Can activate in push mode", DEFAULT_CAN_ACTIVATE_PUSH,
347 : : G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
348 : 97 : g_object_class_install_property (gobject_class, PROP_CAN_ACTIVATE_PULL,
349 : : g_param_spec_boolean ("can-activate-pull", "Can activate pull",
350 : : "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL,
351 : : G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
352 : 97 : g_object_class_install_property (gobject_class, PROP_IS_LIVE,
353 : : g_param_spec_boolean ("is-live", "Is this a live source",
354 : : "True if the element cannot produce data in PAUSED", FALSE,
355 : : G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
356 : : /**
357 : : * GstFakeSrc:format
358 : : *
359 : : * Set the format of the newsegment events to produce.
360 : : *
361 : : * Since: 0.10.20
362 : : */
363 : 97 : g_object_class_install_property (gobject_class, PROP_FORMAT,
364 : : g_param_spec_enum ("format", "Format",
365 : : "The format of the segment events", GST_TYPE_FORMAT,
366 : : DEFAULT_FORMAT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
367 : :
368 : : /**
369 : : * GstFakeSrc::handoff:
370 : : * @fakesrc: the fakesrc instance
371 : : * @buffer: the buffer that will be pushed
372 : : * @pad: the pad that will sent it
373 : : *
374 : : * This signal gets emitted before sending the buffer.
375 : : */
376 : 97 : gst_fake_src_signals[SIGNAL_HANDOFF] =
377 : 97 : g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
378 : : G_STRUCT_OFFSET (GstFakeSrcClass, handoff), NULL, NULL,
379 : : marshal_VOID__MINIOBJECT_OBJECT, G_TYPE_NONE, 2, GST_TYPE_BUFFER,
380 : : GST_TYPE_PAD);
381 : :
382 : 97 : gstbase_src_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fake_src_is_seekable);
383 : 97 : gstbase_src_class->start = GST_DEBUG_FUNCPTR (gst_fake_src_start);
384 : 97 : gstbase_src_class->stop = GST_DEBUG_FUNCPTR (gst_fake_src_stop);
385 : 97 : gstbase_src_class->event = GST_DEBUG_FUNCPTR (gst_fake_src_event_handler);
386 : 97 : gstbase_src_class->get_times = GST_DEBUG_FUNCPTR (gst_fake_src_get_times);
387 : 97 : gstbase_src_class->create = GST_DEBUG_FUNCPTR (gst_fake_src_create);
388 : 97 : }
389 : :
390 : : static void
391 : 125 : gst_fake_src_init (GstFakeSrc * fakesrc, GstFakeSrcClass * g_class)
392 : : {
393 : 125 : fakesrc->output = FAKE_SRC_FIRST_LAST_LOOP;
394 : 125 : fakesrc->buffer_count = 0;
395 : 125 : fakesrc->silent = DEFAULT_SILENT;
396 : 125 : fakesrc->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
397 : 125 : fakesrc->dump = DEFAULT_DUMP;
398 : 125 : fakesrc->pattern_byte = 0x00;
399 : 125 : fakesrc->data = FAKE_SRC_DATA_ALLOCATE;
400 : 125 : fakesrc->sizetype = FAKE_SRC_SIZETYPE_EMPTY;
401 : 125 : fakesrc->filltype = FAKE_SRC_FILLTYPE_NOTHING;
402 : 125 : fakesrc->sizemin = DEFAULT_SIZEMIN;
403 : 125 : fakesrc->sizemax = DEFAULT_SIZEMAX;
404 : 125 : fakesrc->parent = NULL;
405 : 125 : fakesrc->parentsize = DEFAULT_PARENTSIZE;
406 : 125 : fakesrc->last_message = NULL;
407 : 125 : fakesrc->datarate = DEFAULT_DATARATE;
408 : 125 : fakesrc->sync = DEFAULT_SYNC;
409 : 125 : fakesrc->format = DEFAULT_FORMAT;
410 : 125 : }
411 : :
412 : : static void
413 : 117 : gst_fake_src_finalize (GObject * object)
414 : : {
415 : : GstFakeSrc *src;
416 : :
417 : 117 : src = GST_FAKE_SRC (object);
418 : :
419 : 117 : g_free (src->last_message);
420 [ + + ]: 117 : if (src->parent) {
421 : 1 : gst_buffer_unref (src->parent);
422 : 1 : src->parent = NULL;
423 : : }
424 : :
425 : 117 : G_OBJECT_CLASS (parent_class)->finalize (object);
426 : 117 : }
427 : :
428 : : static gboolean
429 : 97 : gst_fake_src_event_handler (GstBaseSrc * basesrc, GstEvent * event)
430 : : {
431 : : GstFakeSrc *src;
432 : :
433 : 97 : src = GST_FAKE_SRC (basesrc);
434 : :
435 [ + + ]: 97 : if (!src->silent) {
436 : : const GstStructure *s;
437 : : gchar *sstr;
438 : :
439 : 86 : GST_OBJECT_LOCK (src);
440 : 86 : g_free (src->last_message);
441 : :
442 [ + - ]: 86 : if ((s = gst_event_get_structure (event)))
443 : 86 : sstr = gst_structure_to_string (s);
444 : : else
445 : 0 : sstr = g_strdup ("");
446 : :
447 : 86 : src->last_message =
448 : 86 : g_strdup_printf ("event ******* E (type: %d, %s) %p",
449 : 86 : GST_EVENT_TYPE (event), sstr, event);
450 : 86 : g_free (sstr);
451 : 86 : GST_OBJECT_UNLOCK (src);
452 : :
453 : : #if !GLIB_CHECK_VERSION(2,26,0)
454 : : g_object_notify ((GObject *) src, "last-message");
455 : : #else
456 : 86 : g_object_notify_by_pspec ((GObject *) src, pspec_last_message);
457 : : #endif
458 : : }
459 : :
460 : 97 : return GST_BASE_SRC_CLASS (parent_class)->event (basesrc, event);
461 : : }
462 : :
463 : : static void
464 : 1 : gst_fake_src_alloc_parent (GstFakeSrc * src)
465 : : {
466 : : GstBuffer *buf;
467 : :
468 : 1 : buf = gst_buffer_new ();
469 : 1 : GST_BUFFER_DATA (buf) = g_malloc (src->parentsize);
470 : 1 : GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
471 : 1 : GST_BUFFER_SIZE (buf) = src->parentsize;
472 : :
473 : 1 : src->parent = buf;
474 : 1 : src->parentoffset = 0;
475 : 1 : }
476 : :
477 : : static void
478 : 429 : gst_fake_src_set_property (GObject * object, guint prop_id,
479 : : const GValue * value, GParamSpec * pspec)
480 : : {
481 : : GstFakeSrc *src;
482 : : GstBaseSrc *basesrc;
483 : :
484 : 429 : src = GST_FAKE_SRC (object);
485 : 429 : basesrc = GST_BASE_SRC (object);
486 : :
487 [ - + + + : 429 : switch (prop_id) {
+ - - + -
- + - - +
+ + - - ]
488 : : case PROP_OUTPUT:
489 : 0 : g_warning ("not yet implemented");
490 : 0 : break;
491 : : case PROP_DATA:
492 : 1 : src->data = g_value_get_enum (value);
493 : :
494 [ + - ]: 1 : if (src->data == FAKE_SRC_DATA_SUBBUFFER) {
495 [ + - ]: 1 : if (!src->parent)
496 : 1 : gst_fake_src_alloc_parent (src);
497 : : } else {
498 [ # # ]: 0 : if (src->parent) {
499 : 0 : gst_buffer_unref (src->parent);
500 : 0 : src->parent = NULL;
501 : : }
502 : : }
503 : 1 : break;
504 : : case PROP_SIZETYPE:
505 : 8 : src->sizetype = g_value_get_enum (value);
506 : 8 : break;
507 : : case PROP_SIZEMIN:
508 : 2 : src->sizemin = g_value_get_int (value);
509 : 2 : break;
510 : : case PROP_SIZEMAX:
511 : 5 : src->sizemax = g_value_get_int (value);
512 : 5 : break;
513 : : case PROP_PARENTSIZE:
514 : 0 : src->parentsize = g_value_get_int (value);
515 : 0 : break;
516 : : case PROP_FILLTYPE:
517 : 0 : src->filltype = g_value_get_enum (value);
518 : 0 : break;
519 : : case PROP_DATARATE:
520 : 4 : src->datarate = g_value_get_int (value);
521 : 4 : break;
522 : : case PROP_SYNC:
523 : 0 : src->sync = g_value_get_boolean (value);
524 : 0 : break;
525 : : case PROP_PATTERN:
526 : 0 : break;
527 : : case PROP_SILENT:
528 : 3 : src->silent = g_value_get_boolean (value);
529 : 3 : break;
530 : : case PROP_SIGNAL_HANDOFFS:
531 : 0 : src->signal_handoffs = g_value_get_boolean (value);
532 : 0 : break;
533 : : case PROP_DUMP:
534 : 0 : src->dump = g_value_get_boolean (value);
535 : 0 : break;
536 : : case PROP_CAN_ACTIVATE_PUSH:
537 [ - + ]: 137 : g_return_if_fail (!GST_OBJECT_FLAG_IS_SET (object, GST_BASE_SRC_STARTED));
538 : 137 : GST_BASE_SRC (src)->can_activate_push = g_value_get_boolean (value);
539 : 137 : break;
540 : : case PROP_CAN_ACTIVATE_PULL:
541 [ - + ]: 132 : g_return_if_fail (!GST_OBJECT_FLAG_IS_SET (object, GST_BASE_SRC_STARTED));
542 : 132 : src->can_activate_pull = g_value_get_boolean (value);
543 : 132 : break;
544 : : case PROP_IS_LIVE:
545 : 137 : gst_base_src_set_live (basesrc, g_value_get_boolean (value));
546 : 137 : break;
547 : : case PROP_FORMAT:
548 : 0 : src->format = g_value_get_enum (value);
549 : 0 : break;
550 : : default:
551 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
552 : 429 : break;
553 : : }
554 : : }
555 : :
556 : : static void
557 : 3 : gst_fake_src_get_property (GObject * object, guint prop_id, GValue * value,
558 : : GParamSpec * pspec)
559 : : {
560 : : GstFakeSrc *src;
561 : : GstBaseSrc *basesrc;
562 : :
563 [ - + ][ + - ]: 6 : g_return_if_fail (GST_IS_FAKE_SRC (object));
[ + - ][ - + ]
564 : :
565 : 3 : src = GST_FAKE_SRC (object);
566 : 3 : basesrc = GST_BASE_SRC (object);
567 : :
568 [ - + + - : 3 : switch (prop_id) {
- - - - -
- + - - -
- - - -
- ]
569 : : case PROP_OUTPUT:
570 : 0 : g_value_set_enum (value, src->output);
571 : 0 : break;
572 : : case PROP_DATA:
573 : 1 : g_value_set_enum (value, src->data);
574 : 1 : break;
575 : : case PROP_SIZETYPE:
576 : 1 : g_value_set_enum (value, src->sizetype);
577 : 1 : break;
578 : : case PROP_SIZEMIN:
579 : 0 : g_value_set_int (value, src->sizemin);
580 : 0 : break;
581 : : case PROP_SIZEMAX:
582 : 0 : g_value_set_int (value, src->sizemax);
583 : 0 : break;
584 : : case PROP_PARENTSIZE:
585 : 0 : g_value_set_int (value, src->parentsize);
586 : 0 : break;
587 : : case PROP_FILLTYPE:
588 : 0 : g_value_set_enum (value, src->filltype);
589 : 0 : break;
590 : : case PROP_DATARATE:
591 : 0 : g_value_set_int (value, src->datarate);
592 : 0 : break;
593 : : case PROP_SYNC:
594 : 0 : g_value_set_boolean (value, src->sync);
595 : 0 : break;
596 : : case PROP_PATTERN:
597 : 0 : g_value_set_string (value, src->pattern);
598 : 0 : break;
599 : : case PROP_SILENT:
600 : 1 : g_value_set_boolean (value, src->silent);
601 : 1 : break;
602 : : case PROP_SIGNAL_HANDOFFS:
603 : 0 : g_value_set_boolean (value, src->signal_handoffs);
604 : 0 : break;
605 : : case PROP_DUMP:
606 : 0 : g_value_set_boolean (value, src->dump);
607 : 0 : break;
608 : : case PROP_LAST_MESSAGE:
609 : 0 : GST_OBJECT_LOCK (src);
610 : 0 : g_value_set_string (value, src->last_message);
611 : 0 : GST_OBJECT_UNLOCK (src);
612 : 0 : break;
613 : : case PROP_CAN_ACTIVATE_PUSH:
614 : 0 : g_value_set_boolean (value, GST_BASE_SRC (src)->can_activate_push);
615 : 0 : break;
616 : : case PROP_CAN_ACTIVATE_PULL:
617 : 0 : g_value_set_boolean (value, src->can_activate_pull);
618 : 0 : break;
619 : : case PROP_IS_LIVE:
620 : 0 : g_value_set_boolean (value, gst_base_src_is_live (basesrc));
621 : 0 : break;
622 : : case PROP_FORMAT:
623 : 0 : g_value_set_enum (value, src->format);
624 : 0 : break;
625 : : default:
626 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
627 : 0 : break;
628 : : }
629 : : }
630 : :
631 : : static void
632 : 0 : gst_fake_src_prepare_buffer (GstFakeSrc * src, GstBuffer * buf)
633 : : {
634 [ # # ]: 0 : if (GST_BUFFER_SIZE (buf) == 0)
635 : 0 : return;
636 : :
637 [ # # # # : 0 : switch (src->filltype) {
# ]
638 : : case FAKE_SRC_FILLTYPE_ZERO:
639 : 0 : memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
640 : 0 : break;
641 : : case FAKE_SRC_FILLTYPE_RANDOM:
642 : : {
643 : : gint i;
644 : 0 : guint8 *ptr = GST_BUFFER_DATA (buf);
645 : :
646 [ # # ]: 0 : for (i = GST_BUFFER_SIZE (buf); i; i--) {
647 : 0 : *ptr++ = g_random_int_range (0, 256);
648 : : }
649 : 0 : break;
650 : : }
651 : : case FAKE_SRC_FILLTYPE_PATTERN:
652 : 0 : src->pattern_byte = 0x00;
653 : : case FAKE_SRC_FILLTYPE_PATTERN_CONT:
654 : : {
655 : : gint i;
656 : 0 : guint8 *ptr = GST_BUFFER_DATA (buf);
657 : :
658 [ # # ]: 0 : for (i = GST_BUFFER_SIZE (buf); i; i--) {
659 : 0 : *ptr++ = src->pattern_byte++;
660 : : }
661 : 0 : break;
662 : : }
663 : : case FAKE_SRC_FILLTYPE_NOTHING:
664 : : default:
665 : 0 : break;
666 : : }
667 : : }
668 : :
669 : : static GstBuffer *
670 : 539214 : gst_fake_src_alloc_buffer (GstFakeSrc * src, guint size)
671 : : {
672 : : GstBuffer *buf;
673 : :
674 : 539214 : buf = gst_buffer_new ();
675 : 539214 : GST_BUFFER_SIZE (buf) = size;
676 : :
677 [ + + ]: 539214 : if (size != 0) {
678 [ + - - ]: 519 : switch (src->filltype) {
679 : : case FAKE_SRC_FILLTYPE_NOTHING:
680 : 519 : GST_BUFFER_DATA (buf) = g_malloc (size);
681 : 519 : GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
682 : 519 : break;
683 : : case FAKE_SRC_FILLTYPE_ZERO:
684 : 0 : GST_BUFFER_DATA (buf) = g_malloc0 (size);
685 : 0 : GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
686 : 0 : break;
687 : : case FAKE_SRC_FILLTYPE_RANDOM:
688 : : case FAKE_SRC_FILLTYPE_PATTERN:
689 : : case FAKE_SRC_FILLTYPE_PATTERN_CONT:
690 : : default:
691 : 0 : GST_BUFFER_DATA (buf) = g_malloc (size);
692 : 0 : GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
693 : 0 : gst_fake_src_prepare_buffer (src, buf);
694 : 0 : break;
695 : : }
696 : : }
697 : :
698 : 539214 : return buf;
699 : : }
700 : :
701 : : static guint
702 : 539214 : gst_fake_src_get_size (GstFakeSrc * src)
703 : : {
704 : : guint size;
705 : :
706 [ + + + ]: 539214 : switch (src->sizetype) {
707 : : case FAKE_SRC_SIZETYPE_FIXED:
708 : 419 : size = src->sizemax;
709 : 419 : break;
710 : : case FAKE_SRC_SIZETYPE_RANDOM:
711 : 100 : size = g_random_int_range (src->sizemin, src->sizemax);
712 : 100 : break;
713 : : case FAKE_SRC_SIZETYPE_EMPTY:
714 : : default:
715 : 538695 : size = 0;
716 : 538695 : break;
717 : : }
718 : :
719 : 539214 : return size;
720 : : }
721 : :
722 : : static GstBuffer *
723 : 539214 : gst_fake_src_create_buffer (GstFakeSrc * src)
724 : : {
725 : : GstBuffer *buf;
726 : 539214 : guint size = gst_fake_src_get_size (src);
727 : 539214 : gboolean dump = src->dump;
728 : :
729 [ + - - ]: 539214 : switch (src->data) {
730 : : case FAKE_SRC_DATA_ALLOCATE:
731 : 539214 : buf = gst_fake_src_alloc_buffer (src, size);
732 : 539214 : break;
733 : : case FAKE_SRC_DATA_SUBBUFFER:
734 : : /* see if we have a parent to subbuffer */
735 [ # # ]: 0 : if (!src->parent) {
736 : 0 : gst_fake_src_alloc_parent (src);
737 [ # # ]: 0 : g_assert (src->parent);
738 : : }
739 : : /* see if it's large enough */
740 [ # # ]: 0 : if ((GST_BUFFER_SIZE (src->parent) - src->parentoffset) >= size) {
741 : 0 : buf = gst_buffer_create_sub (src->parent, src->parentoffset, size);
742 : 0 : src->parentoffset += size;
743 : : } else {
744 : : /* the parent is useless now */
745 : 0 : gst_buffer_unref (src->parent);
746 : 0 : src->parent = NULL;
747 : : /* try again (this will allocate a new parent) */
748 : 0 : return gst_fake_src_create_buffer (src);
749 : : }
750 : 0 : gst_fake_src_prepare_buffer (src, buf);
751 : 0 : break;
752 : : default:
753 : 0 : g_warning ("fakesrc: dunno how to allocate buffers !");
754 : 0 : buf = gst_buffer_new ();
755 : 0 : break;
756 : : }
757 [ - + ]: 539214 : if (dump) {
758 : 0 : gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
759 : : }
760 : :
761 : 539214 : return buf;
762 : : }
763 : :
764 : : static void
765 : 539213 : gst_fake_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
766 : : GstClockTime * start, GstClockTime * end)
767 : : {
768 : : GstFakeSrc *src;
769 : :
770 : 539213 : src = GST_FAKE_SRC (basesrc);
771 : :
772 : : /* sync on the timestamp of the buffer if requested. */
773 [ - + ]: 539213 : if (src->sync) {
774 : 0 : GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
775 : :
776 [ # # ]: 0 : if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
777 : : /* get duration to calculate end time */
778 : 0 : GstClockTime duration = GST_BUFFER_DURATION (buffer);
779 : :
780 [ # # ]: 0 : if (GST_CLOCK_TIME_IS_VALID (duration)) {
781 : 0 : *end = timestamp + duration;
782 : : }
783 : 0 : *start = timestamp;
784 : : }
785 : : } else {
786 : 539213 : *start = -1;
787 : 539213 : *end = -1;
788 : : }
789 : 539213 : }
790 : :
791 : : static GstFlowReturn
792 : 539214 : gst_fake_src_create (GstBaseSrc * basesrc, guint64 offset, guint length,
793 : : GstBuffer ** ret)
794 : : {
795 : : GstFakeSrc *src;
796 : : GstBuffer *buf;
797 : : GstClockTime time;
798 : :
799 : 539214 : src = GST_FAKE_SRC (basesrc);
800 : :
801 : 539214 : buf = gst_fake_src_create_buffer (src);
802 : 539214 : GST_BUFFER_OFFSET (buf) = src->buffer_count++;
803 : :
804 [ + + ]: 539214 : if (src->datarate > 0) {
805 : 5318 : time = (src->bytes_sent * GST_SECOND) / src->datarate;
806 : :
807 : 5318 : GST_BUFFER_DURATION (buf) =
808 : 5318 : GST_BUFFER_SIZE (buf) * GST_SECOND / src->datarate;
809 [ + + ]: 533896 : } else if (gst_base_src_is_live (basesrc)) {
810 : : GstClock *clock;
811 : :
812 : 3446 : clock = gst_element_get_clock (GST_ELEMENT (src));
813 : :
814 [ + - ]: 3446 : if (clock) {
815 : 3446 : time = gst_clock_get_time (clock);
816 : 3446 : time -= gst_element_get_base_time (GST_ELEMENT (src));
817 : 3446 : gst_object_unref (clock);
818 : : } else {
819 : : /* not an error not to have a clock */
820 : 0 : time = GST_CLOCK_TIME_NONE;
821 : : }
822 : : } else {
823 : 530450 : time = GST_CLOCK_TIME_NONE;
824 : : }
825 : :
826 : 539214 : GST_BUFFER_TIMESTAMP (buf) = time;
827 : :
828 [ + + ]: 539214 : if (!src->silent) {
829 : : gchar ts_str[64], dur_str[64];
830 : :
831 : 538871 : GST_OBJECT_LOCK (src);
832 : 538871 : g_free (src->last_message);
833 : :
834 [ + + ]: 538871 : if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) {
835 [ + - ][ + - ]: 8448 : g_snprintf (ts_str, sizeof (ts_str), "%" GST_TIME_FORMAT,
[ + - ][ + - ]
836 : 67584 : GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
837 : : } else {
838 : 530423 : g_strlcpy (ts_str, "none", sizeof (ts_str));
839 : : }
840 : :
841 [ + + ]: 538871 : if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE) {
842 [ + - ][ + - ]: 5002 : g_snprintf (dur_str, sizeof (dur_str), "%" GST_TIME_FORMAT,
[ + - ][ + - ]
843 : 40016 : GST_TIME_ARGS (GST_BUFFER_DURATION (buf)));
844 : : } else {
845 : 533869 : g_strlcpy (dur_str, "none", sizeof (dur_str));
846 : : }
847 : :
848 : 538871 : src->last_message =
849 : 538871 : g_strdup_printf ("get ******* > (%5d bytes, timestamp: %s"
850 : : ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %"
851 : : G_GINT64_FORMAT ", flags: %d) %p", GST_BUFFER_SIZE (buf), ts_str,
852 : : dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
853 : 538871 : GST_MINI_OBJECT (buf)->flags, buf);
854 : 538871 : GST_OBJECT_UNLOCK (src);
855 : :
856 : : #if !GLIB_CHECK_VERSION(2,26,0)
857 : : g_object_notify ((GObject *) src, "last-message");
858 : : #else
859 : 538871 : g_object_notify_by_pspec ((GObject *) src, pspec_last_message);
860 : : #endif
861 : : }
862 : :
863 [ - + ]: 539214 : if (src->signal_handoffs) {
864 [ # # ]: 0 : GST_LOG_OBJECT (src, "pre handoff emit");
865 : 0 : g_signal_emit (src, gst_fake_src_signals[SIGNAL_HANDOFF], 0, buf,
866 : : basesrc->srcpad);
867 [ # # ]: 0 : GST_LOG_OBJECT (src, "post handoff emit");
868 : : }
869 : :
870 : 539214 : src->bytes_sent += GST_BUFFER_SIZE (buf);
871 : :
872 : 539214 : *ret = buf;
873 : 539214 : return GST_FLOW_OK;
874 : : }
875 : :
876 : : static gboolean
877 : 394 : gst_fake_src_start (GstBaseSrc * basesrc)
878 : : {
879 : : GstFakeSrc *src;
880 : :
881 : 394 : src = GST_FAKE_SRC (basesrc);
882 : :
883 : 394 : src->buffer_count = 0;
884 : 394 : src->pattern_byte = 0x00;
885 : 394 : src->bytes_sent = 0;
886 : :
887 : 394 : gst_base_src_set_format (basesrc, src->format);
888 : :
889 : 394 : return TRUE;
890 : : }
891 : :
892 : : static gboolean
893 : 394 : gst_fake_src_stop (GstBaseSrc * basesrc)
894 : : {
895 : : GstFakeSrc *src;
896 : :
897 : 394 : src = GST_FAKE_SRC (basesrc);
898 : :
899 : 394 : GST_OBJECT_LOCK (src);
900 [ - + ]: 394 : if (src->parent) {
901 : 0 : gst_buffer_unref (src->parent);
902 : 0 : src->parent = NULL;
903 : : }
904 : 394 : g_free (src->last_message);
905 : 394 : src->last_message = NULL;
906 : 394 : GST_OBJECT_UNLOCK (src);
907 : :
908 : 394 : return TRUE;
909 : : }
910 : :
911 : : static gboolean
912 : 396 : gst_fake_src_is_seekable (GstBaseSrc * basesrc)
913 : : {
914 : 396 : GstFakeSrc *src = GST_FAKE_SRC (basesrc);
915 : :
916 : 396 : return src->can_activate_pull;
917 : : }
|