|
1 /* GStreamer |
|
2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu> |
|
3 * 2005 Wim Taymans <wim@fluendo.com> |
|
4 * |
|
5 * gstfakesink.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-fakesink |
|
24 * @short_description: black hole for data |
|
25 * @see_also: #GstFakeSrc |
|
26 * |
|
27 * Dummy sink that swallows everything. |
|
28 */ |
|
29 |
|
30 #ifdef HAVE_CONFIG_H |
|
31 # include "config.h" |
|
32 #endif |
|
33 #ifdef __SYMBIAN32__ |
|
34 #include <gst_global.h> |
|
35 #endif |
|
36 |
|
37 #include "gstfakesink.h" |
|
38 #include <gst/gstmarshal.h> |
|
39 #ifdef __SYMBIAN32__ |
|
40 #include <glib_global.h> |
|
41 #include <gobject_global.h> |
|
42 |
|
43 #include <gstelement.h> |
|
44 #endif |
|
45 |
|
46 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", |
|
47 GST_PAD_SINK, |
|
48 GST_PAD_ALWAYS, |
|
49 GST_STATIC_CAPS_ANY); |
|
50 |
|
51 GST_DEBUG_CATEGORY_STATIC (gst_fake_sink_debug); |
|
52 #define GST_CAT_DEFAULT gst_fake_sink_debug |
|
53 |
|
54 /* FakeSink signals and args */ |
|
55 enum |
|
56 { |
|
57 /* FILL ME */ |
|
58 SIGNAL_HANDOFF, |
|
59 SIGNAL_PREROLL_HANDOFF, |
|
60 LAST_SIGNAL |
|
61 }; |
|
62 |
|
63 #define DEFAULT_SYNC FALSE |
|
64 |
|
65 #define DEFAULT_STATE_ERROR FAKE_SINK_STATE_ERROR_NONE |
|
66 #define DEFAULT_SILENT FALSE |
|
67 #define DEFAULT_DUMP FALSE |
|
68 #define DEFAULT_SIGNAL_HANDOFFS FALSE |
|
69 #define DEFAULT_LAST_MESSAGE NULL |
|
70 #define DEFAULT_CAN_ACTIVATE_PUSH TRUE |
|
71 #define DEFAULT_CAN_ACTIVATE_PULL FALSE |
|
72 #define DEFAULT_NUM_BUFFERS -1 |
|
73 |
|
74 enum |
|
75 { |
|
76 PROP_0, |
|
77 PROP_STATE_ERROR, |
|
78 PROP_SILENT, |
|
79 PROP_DUMP, |
|
80 PROP_SIGNAL_HANDOFFS, |
|
81 PROP_LAST_MESSAGE, |
|
82 PROP_CAN_ACTIVATE_PUSH, |
|
83 PROP_CAN_ACTIVATE_PULL, |
|
84 PROP_NUM_BUFFERS |
|
85 }; |
|
86 |
|
87 #define GST_TYPE_FAKE_SINK_STATE_ERROR (gst_fake_sink_state_error_get_type()) |
|
88 static GType |
|
89 gst_fake_sink_state_error_get_type (void) |
|
90 { |
|
91 static GType fakesink_state_error_type = 0; |
|
92 static const GEnumValue fakesink_state_error[] = { |
|
93 {FAKE_SINK_STATE_ERROR_NONE, "No state change errors", "none"}, |
|
94 {FAKE_SINK_STATE_ERROR_NULL_READY, |
|
95 "Fail state change from NULL to READY", "null-to-ready"}, |
|
96 {FAKE_SINK_STATE_ERROR_READY_PAUSED, |
|
97 "Fail state change from READY to PAUSED", "ready-to-paused"}, |
|
98 {FAKE_SINK_STATE_ERROR_PAUSED_PLAYING, |
|
99 "Fail state change from PAUSED to PLAYING", "paused-to-playing"}, |
|
100 {FAKE_SINK_STATE_ERROR_PLAYING_PAUSED, |
|
101 "Fail state change from PLAYING to PAUSED", "playing-to-paused"}, |
|
102 {FAKE_SINK_STATE_ERROR_PAUSED_READY, |
|
103 "Fail state change from PAUSED to READY", "paused-to-ready"}, |
|
104 {FAKE_SINK_STATE_ERROR_READY_NULL, |
|
105 "Fail state change from READY to NULL", "ready-to-null"}, |
|
106 {0, NULL, NULL}, |
|
107 }; |
|
108 |
|
109 if (!fakesink_state_error_type) { |
|
110 fakesink_state_error_type = |
|
111 g_enum_register_static ("GstFakeSinkStateError", fakesink_state_error); |
|
112 } |
|
113 return fakesink_state_error_type; |
|
114 } |
|
115 |
|
116 #define _do_init(bla) \ |
|
117 GST_DEBUG_CATEGORY_INIT (gst_fake_sink_debug, "fakesink", 0, "fakesink element"); |
|
118 |
|
119 GST_BOILERPLATE_FULL (GstFakeSink, gst_fake_sink, GstBaseSink, |
|
120 GST_TYPE_BASE_SINK, _do_init); |
|
121 |
|
122 static void gst_fake_sink_set_property (GObject * object, guint prop_id, |
|
123 const GValue * value, GParamSpec * pspec); |
|
124 static void gst_fake_sink_get_property (GObject * object, guint prop_id, |
|
125 GValue * value, GParamSpec * pspec); |
|
126 |
|
127 static GstStateChangeReturn gst_fake_sink_change_state (GstElement * element, |
|
128 GstStateChange transition); |
|
129 |
|
130 static GstFlowReturn gst_fake_sink_preroll (GstBaseSink * bsink, |
|
131 GstBuffer * buffer); |
|
132 static GstFlowReturn gst_fake_sink_render (GstBaseSink * bsink, |
|
133 GstBuffer * buffer); |
|
134 static gboolean gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event); |
|
135 |
|
136 static guint gst_fake_sink_signals[LAST_SIGNAL] = { 0 }; |
|
137 |
|
138 static void |
|
139 gst_fake_sink_base_init (gpointer g_class) |
|
140 { |
|
141 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); |
|
142 |
|
143 gst_element_class_set_details_simple (gstelement_class, |
|
144 "Fake Sink", |
|
145 "Sink", |
|
146 "Black hole for data", |
|
147 "Erik Walthinsen <omega@cse.ogi.edu>, " |
|
148 "Wim Taymans <wim@fluendo.com>, " |
|
149 "Mr. 'frag-me-more' Vanderwingo <wingo@fluendo.com>"); |
|
150 gst_element_class_add_pad_template (gstelement_class, |
|
151 gst_static_pad_template_get (&sinktemplate)); |
|
152 } |
|
153 |
|
154 static void |
|
155 gst_fake_sink_class_init (GstFakeSinkClass * klass) |
|
156 { |
|
157 GObjectClass *gobject_class; |
|
158 GstElementClass *gstelement_class; |
|
159 GstBaseSinkClass *gstbase_sink_class; |
|
160 |
|
161 gobject_class = G_OBJECT_CLASS (klass); |
|
162 gstelement_class = GST_ELEMENT_CLASS (klass); |
|
163 gstbase_sink_class = GST_BASE_SINK_CLASS (klass); |
|
164 |
|
165 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fake_sink_set_property); |
|
166 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fake_sink_get_property); |
|
167 |
|
168 g_object_class_install_property (gobject_class, PROP_STATE_ERROR, |
|
169 g_param_spec_enum ("state_error", "State Error", |
|
170 "Generate a state change error", GST_TYPE_FAKE_SINK_STATE_ERROR, |
|
171 DEFAULT_STATE_ERROR, G_PARAM_READWRITE)); |
|
172 g_object_class_install_property (gobject_class, PROP_LAST_MESSAGE, |
|
173 g_param_spec_string ("last_message", "Last Message", |
|
174 "The message describing current status", DEFAULT_LAST_MESSAGE, |
|
175 G_PARAM_READABLE)); |
|
176 g_object_class_install_property (gobject_class, PROP_SIGNAL_HANDOFFS, |
|
177 g_param_spec_boolean ("signal-handoffs", "Signal handoffs", |
|
178 "Send a signal before unreffing the buffer", DEFAULT_SIGNAL_HANDOFFS, |
|
179 G_PARAM_READWRITE)); |
|
180 g_object_class_install_property (gobject_class, PROP_SILENT, |
|
181 g_param_spec_boolean ("silent", "Silent", |
|
182 "Don't produce last_message events", DEFAULT_SILENT, |
|
183 G_PARAM_READWRITE)); |
|
184 g_object_class_install_property (gobject_class, PROP_DUMP, |
|
185 g_param_spec_boolean ("dump", "Dump", "Dump buffer contents to stdout", |
|
186 DEFAULT_DUMP, G_PARAM_READWRITE)); |
|
187 g_object_class_install_property (gobject_class, |
|
188 PROP_CAN_ACTIVATE_PUSH, |
|
189 g_param_spec_boolean ("can-activate-push", "Can activate push", |
|
190 "Can activate in push mode", DEFAULT_CAN_ACTIVATE_PUSH, |
|
191 G_PARAM_READWRITE)); |
|
192 g_object_class_install_property (gobject_class, |
|
193 PROP_CAN_ACTIVATE_PULL, |
|
194 g_param_spec_boolean ("can-activate-pull", "Can activate pull", |
|
195 "Can activate in pull mode", DEFAULT_CAN_ACTIVATE_PULL, |
|
196 G_PARAM_READWRITE)); |
|
197 g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS, |
|
198 g_param_spec_int ("num-buffers", "num-buffers", |
|
199 "Number of buffers to accept going EOS", -1, G_MAXINT, |
|
200 DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE)); |
|
201 |
|
202 /** |
|
203 * GstFakeSink::handoff: |
|
204 * @fakesink: the fakesink instance |
|
205 * @buffer: the buffer that just has been received |
|
206 * @pad: the pad that received it |
|
207 * |
|
208 * This signal gets emitted before unreffing the buffer. |
|
209 */ |
|
210 gst_fake_sink_signals[SIGNAL_HANDOFF] = |
|
211 g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, |
|
212 G_STRUCT_OFFSET (GstFakeSinkClass, handoff), NULL, NULL, |
|
213 gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2, |
|
214 GST_TYPE_BUFFER, GST_TYPE_PAD); |
|
215 |
|
216 /** |
|
217 * GstFakeSink::preroll-handoff: |
|
218 * @fakesink: the fakesink instance |
|
219 * @buffer: the buffer that just has been received |
|
220 * @pad: the pad that received it |
|
221 * |
|
222 * This signal gets emitted before unreffing the buffer. |
|
223 * |
|
224 * Since: 0.10.7 |
|
225 */ |
|
226 gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF] = |
|
227 g_signal_new ("preroll-handoff", G_TYPE_FROM_CLASS (klass), |
|
228 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstFakeSinkClass, preroll_handoff), |
|
229 NULL, NULL, gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2, |
|
230 GST_TYPE_BUFFER, GST_TYPE_PAD); |
|
231 |
|
232 gstelement_class->change_state = |
|
233 GST_DEBUG_FUNCPTR (gst_fake_sink_change_state); |
|
234 |
|
235 gstbase_sink_class->event = GST_DEBUG_FUNCPTR (gst_fake_sink_event); |
|
236 gstbase_sink_class->preroll = GST_DEBUG_FUNCPTR (gst_fake_sink_preroll); |
|
237 gstbase_sink_class->render = GST_DEBUG_FUNCPTR (gst_fake_sink_render); |
|
238 } |
|
239 |
|
240 static void |
|
241 gst_fake_sink_init (GstFakeSink * fakesink, GstFakeSinkClass * g_class) |
|
242 { |
|
243 fakesink->silent = DEFAULT_SILENT; |
|
244 fakesink->dump = DEFAULT_DUMP; |
|
245 GST_BASE_SINK (fakesink)->sync = DEFAULT_SYNC; |
|
246 fakesink->last_message = g_strdup (DEFAULT_LAST_MESSAGE); |
|
247 fakesink->state_error = DEFAULT_STATE_ERROR; |
|
248 fakesink->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS; |
|
249 fakesink->num_buffers = DEFAULT_NUM_BUFFERS; |
|
250 } |
|
251 |
|
252 static void |
|
253 gst_fake_sink_set_property (GObject * object, guint prop_id, |
|
254 const GValue * value, GParamSpec * pspec) |
|
255 { |
|
256 GstFakeSink *sink; |
|
257 |
|
258 sink = GST_FAKE_SINK (object); |
|
259 |
|
260 switch (prop_id) { |
|
261 case PROP_SILENT: |
|
262 sink->silent = g_value_get_boolean (value); |
|
263 break; |
|
264 case PROP_STATE_ERROR: |
|
265 sink->state_error = g_value_get_enum (value); |
|
266 break; |
|
267 case PROP_DUMP: |
|
268 sink->dump = g_value_get_boolean (value); |
|
269 break; |
|
270 case PROP_SIGNAL_HANDOFFS: |
|
271 sink->signal_handoffs = g_value_get_boolean (value); |
|
272 break; |
|
273 case PROP_CAN_ACTIVATE_PUSH: |
|
274 GST_BASE_SINK (sink)->can_activate_push = g_value_get_boolean (value); |
|
275 break; |
|
276 case PROP_CAN_ACTIVATE_PULL: |
|
277 GST_BASE_SINK (sink)->can_activate_pull = g_value_get_boolean (value); |
|
278 break; |
|
279 case PROP_NUM_BUFFERS: |
|
280 sink->num_buffers = g_value_get_int (value); |
|
281 break; |
|
282 default: |
|
283 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
|
284 break; |
|
285 } |
|
286 } |
|
287 |
|
288 static void |
|
289 gst_fake_sink_get_property (GObject * object, guint prop_id, GValue * value, |
|
290 GParamSpec * pspec) |
|
291 { |
|
292 GstFakeSink *sink; |
|
293 |
|
294 sink = GST_FAKE_SINK (object); |
|
295 |
|
296 switch (prop_id) { |
|
297 case PROP_STATE_ERROR: |
|
298 g_value_set_enum (value, sink->state_error); |
|
299 break; |
|
300 case PROP_SILENT: |
|
301 g_value_set_boolean (value, sink->silent); |
|
302 break; |
|
303 case PROP_DUMP: |
|
304 g_value_set_boolean (value, sink->dump); |
|
305 break; |
|
306 case PROP_SIGNAL_HANDOFFS: |
|
307 g_value_set_boolean (value, sink->signal_handoffs); |
|
308 break; |
|
309 case PROP_LAST_MESSAGE: |
|
310 GST_OBJECT_LOCK (sink); |
|
311 g_value_set_string (value, sink->last_message); |
|
312 GST_OBJECT_UNLOCK (sink); |
|
313 break; |
|
314 case PROP_CAN_ACTIVATE_PUSH: |
|
315 g_value_set_boolean (value, GST_BASE_SINK (sink)->can_activate_push); |
|
316 break; |
|
317 case PROP_CAN_ACTIVATE_PULL: |
|
318 g_value_set_boolean (value, GST_BASE_SINK (sink)->can_activate_pull); |
|
319 break; |
|
320 case PROP_NUM_BUFFERS: |
|
321 g_value_set_int (value, sink->num_buffers); |
|
322 break; |
|
323 default: |
|
324 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
|
325 break; |
|
326 } |
|
327 } |
|
328 |
|
329 static gboolean |
|
330 gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event) |
|
331 { |
|
332 GstFakeSink *sink = GST_FAKE_SINK (bsink); |
|
333 |
|
334 if (!sink->silent) { |
|
335 const GstStructure *s; |
|
336 gchar *sstr; |
|
337 |
|
338 GST_OBJECT_LOCK (sink); |
|
339 g_free (sink->last_message); |
|
340 |
|
341 if ((s = gst_event_get_structure (event))) |
|
342 sstr = gst_structure_to_string (s); |
|
343 else |
|
344 sstr = g_strdup (""); |
|
345 |
|
346 sink->last_message = |
|
347 g_strdup_printf ("event ******* E (type: %d, %s) %p", |
|
348 GST_EVENT_TYPE (event), sstr, event); |
|
349 g_free (sstr); |
|
350 GST_OBJECT_UNLOCK (sink); |
|
351 |
|
352 g_object_notify (G_OBJECT (sink), "last_message"); |
|
353 } |
|
354 |
|
355 return TRUE; |
|
356 } |
|
357 |
|
358 static GstFlowReturn |
|
359 gst_fake_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer) |
|
360 { |
|
361 GstFakeSink *sink = GST_FAKE_SINK (bsink); |
|
362 |
|
363 if (sink->num_buffers_left == 0) |
|
364 goto eos; |
|
365 |
|
366 if (!sink->silent) { |
|
367 GST_OBJECT_LOCK (sink); |
|
368 g_free (sink->last_message); |
|
369 |
|
370 sink->last_message = g_strdup_printf ("preroll ******* "); |
|
371 GST_OBJECT_UNLOCK (sink); |
|
372 |
|
373 g_object_notify (G_OBJECT (sink), "last_message"); |
|
374 } |
|
375 if (sink->signal_handoffs) { |
|
376 g_signal_emit (sink, |
|
377 gst_fake_sink_signals[SIGNAL_PREROLL_HANDOFF], 0, buffer, |
|
378 bsink->sinkpad); |
|
379 } |
|
380 return GST_FLOW_OK; |
|
381 |
|
382 /* ERRORS */ |
|
383 eos: |
|
384 { |
|
385 GST_DEBUG_OBJECT (sink, "we are EOS"); |
|
386 return GST_FLOW_UNEXPECTED; |
|
387 } |
|
388 } |
|
389 |
|
390 static GstFlowReturn |
|
391 gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf) |
|
392 { |
|
393 GstFakeSink *sink = GST_FAKE_SINK_CAST (bsink); |
|
394 |
|
395 if (sink->num_buffers_left == 0) |
|
396 goto eos; |
|
397 |
|
398 if (sink->num_buffers_left != -1) |
|
399 sink->num_buffers_left--; |
|
400 |
|
401 if (!sink->silent) { |
|
402 gchar ts_str[64], dur_str[64]; |
|
403 |
|
404 GST_OBJECT_LOCK (sink); |
|
405 g_free (sink->last_message); |
|
406 |
|
407 if (GST_BUFFER_TIMESTAMP (buf) != GST_CLOCK_TIME_NONE) { |
|
408 g_snprintf (ts_str, sizeof (ts_str), "%" GST_TIME_FORMAT, |
|
409 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); |
|
410 } else { |
|
411 g_strlcpy (ts_str, "none", sizeof (ts_str)); |
|
412 } |
|
413 |
|
414 if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE) { |
|
415 g_snprintf (dur_str, sizeof (dur_str), "%" GST_TIME_FORMAT, |
|
416 GST_TIME_ARGS (GST_BUFFER_DURATION (buf))); |
|
417 } else { |
|
418 g_strlcpy (dur_str, "none", sizeof (dur_str)); |
|
419 } |
|
420 |
|
421 sink->last_message = |
|
422 g_strdup_printf ("chain ******* < (%5d bytes, timestamp: %s" |
|
423 ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %" |
|
424 G_GINT64_FORMAT ", flags: %d) %p", GST_BUFFER_SIZE (buf), ts_str, |
|
425 dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf), |
|
426 GST_MINI_OBJECT (buf)->flags, buf); |
|
427 GST_OBJECT_UNLOCK (sink); |
|
428 |
|
429 g_object_notify (G_OBJECT (sink), "last_message"); |
|
430 } |
|
431 if (sink->signal_handoffs) |
|
432 g_signal_emit (G_OBJECT (sink), gst_fake_sink_signals[SIGNAL_HANDOFF], 0, |
|
433 buf, bsink->sinkpad); |
|
434 |
|
435 if (sink->dump) { |
|
436 gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); |
|
437 } |
|
438 if (sink->num_buffers_left == 0) |
|
439 goto eos; |
|
440 |
|
441 return GST_FLOW_OK; |
|
442 |
|
443 /* ERRORS */ |
|
444 eos: |
|
445 { |
|
446 GST_DEBUG_OBJECT (sink, "we are EOS"); |
|
447 return GST_FLOW_UNEXPECTED; |
|
448 } |
|
449 } |
|
450 |
|
451 static GstStateChangeReturn |
|
452 gst_fake_sink_change_state (GstElement * element, GstStateChange transition) |
|
453 { |
|
454 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; |
|
455 GstFakeSink *fakesink = GST_FAKE_SINK (element); |
|
456 |
|
457 switch (transition) { |
|
458 case GST_STATE_CHANGE_NULL_TO_READY: |
|
459 if (fakesink->state_error == FAKE_SINK_STATE_ERROR_NULL_READY) |
|
460 goto error; |
|
461 break; |
|
462 case GST_STATE_CHANGE_READY_TO_PAUSED: |
|
463 if (fakesink->state_error == FAKE_SINK_STATE_ERROR_READY_PAUSED) |
|
464 goto error; |
|
465 fakesink->num_buffers_left = fakesink->num_buffers; |
|
466 break; |
|
467 case GST_STATE_CHANGE_PAUSED_TO_PLAYING: |
|
468 if (fakesink->state_error == FAKE_SINK_STATE_ERROR_PAUSED_PLAYING) |
|
469 goto error; |
|
470 break; |
|
471 default: |
|
472 break; |
|
473 } |
|
474 |
|
475 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); |
|
476 |
|
477 switch (transition) { |
|
478 case GST_STATE_CHANGE_PLAYING_TO_PAUSED: |
|
479 if (fakesink->state_error == FAKE_SINK_STATE_ERROR_PLAYING_PAUSED) |
|
480 goto error; |
|
481 break; |
|
482 case GST_STATE_CHANGE_PAUSED_TO_READY: |
|
483 if (fakesink->state_error == FAKE_SINK_STATE_ERROR_PAUSED_READY) |
|
484 goto error; |
|
485 break; |
|
486 case GST_STATE_CHANGE_READY_TO_NULL: |
|
487 if (fakesink->state_error == FAKE_SINK_STATE_ERROR_READY_NULL) |
|
488 goto error; |
|
489 GST_OBJECT_LOCK (fakesink); |
|
490 g_free (fakesink->last_message); |
|
491 fakesink->last_message = NULL; |
|
492 GST_OBJECT_UNLOCK (fakesink); |
|
493 break; |
|
494 default: |
|
495 break; |
|
496 } |
|
497 |
|
498 return ret; |
|
499 |
|
500 /* ERROR */ |
|
501 error: |
|
502 GST_ELEMENT_ERROR (element, CORE, STATE_CHANGE, (NULL), |
|
503 ("Erroring out on state change as requested")); |
|
504 return GST_STATE_CHANGE_FAILURE; |
|
505 } |