ghostpad: If we don't control a pad/template, return proper caps
[platform/upstream/gstreamer.git] / gst / gstghostpad.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *                    2005 Andy Wingo <wingo@pobox.com>
5  *                    2006 Edward Hervey <bilboed@bilboed.com>
6  *
7  * gstghostpad.c: Proxy pads
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 /**
26  * SECTION:gstghostpad
27  * @short_description: Pseudo link pads
28  * @see_also: #GstPad
29  *
30  * GhostPads are useful when organizing pipelines with #GstBin like elements.
31  * The idea here is to create hierarchical element graphs. The bin element
32  * contains a sub-graph. Now one would like to treat the bin-element like any
33  * other #GstElement. This is where GhostPads come into play. A GhostPad acts as
34  * a proxy for another pad. Thus the bin can have sink and source ghost-pads
35  * that are associated with sink and source pads of the child elements.
36  *
37  * If the target pad is known at creation time, gst_ghost_pad_new() is the
38  * function to use to get a ghost-pad. Otherwise one can use gst_ghost_pad_new_no_target()
39  * to create the ghost-pad and use gst_ghost_pad_set_target() to establish the
40  * association later on.
41  *
42  * Note that GhostPads add overhead to the data processing of a pipeline.
43  *
44  * Last reviewed on 2005-11-18 (0.9.5)
45  */
46
47 #include "gst_private.h"
48 #include "gstinfo.h"
49
50 #include "gstghostpad.h"
51 #include "gst.h"
52
53 #define GST_CAT_DEFAULT GST_CAT_PADS
54
55 #define GST_PROXY_PAD_CAST(obj)         ((GstProxyPad *)obj)
56 #define GST_PROXY_PAD_PRIVATE(obj)      (GST_PROXY_PAD_CAST (obj)->priv)
57 #define GST_PROXY_PAD_TARGET(pad)       (GST_PROXY_PAD_PRIVATE (pad)->target)
58 #define GST_PROXY_PAD_INTERNAL(pad)     (GST_PROXY_PAD_PRIVATE (pad)->internal)
59 #define GST_PROXY_PAD_RETARGET(pad)     (GST_PROXY_PAD_PRIVATE (pad)->retarget)
60 #define GST_PROXY_GET_LOCK(pad) (GST_PROXY_PAD_PRIVATE (pad)->proxy_lock)
61 #define GST_PROXY_LOCK(pad)     (g_mutex_lock (GST_PROXY_GET_LOCK (pad)))
62 #define GST_PROXY_UNLOCK(pad)   (g_mutex_unlock (GST_PROXY_GET_LOCK (pad)))
63
64 struct _GstProxyPadPrivate
65 {
66   /* with PROXY_LOCK */
67   GMutex *proxy_lock;
68   GstPad *target;
69   GstPad *internal;
70   gboolean retarget;
71 };
72
73 G_DEFINE_TYPE (GstProxyPad, gst_proxy_pad, GST_TYPE_PAD);
74
75 static GstPad *gst_proxy_pad_get_target (GstPad * pad);
76
77 static void gst_proxy_pad_dispose (GObject * object);
78 static void gst_proxy_pad_finalize (GObject * object);
79
80 /**
81  * gst_proxy_pad_query_type_default:
82  * @pad: a #GstPad.
83  *
84  * Invoke the default query type handler of the proxy pad.
85  *
86  * Returns: (transfer none) (array zero-terminated=1): a zero-terminated array
87  *     of #GstQueryType.
88  *
89  * Since: 0.10.35
90  */
91 const GstQueryType *
92 gst_proxy_pad_query_type_default (GstPad * pad)
93 {
94   GstPad *target;
95   const GstQueryType *res = NULL;
96
97   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
98
99   if (!(target = gst_proxy_pad_get_target (pad)))
100     goto no_target;
101
102   res = gst_pad_get_query_types (target);
103   gst_object_unref (target);
104
105   return res;
106
107   /* ERRORS */
108 no_target:
109   {
110     GST_DEBUG_OBJECT (pad, "no target pad");
111     return FALSE;
112   }
113 }
114
115 /**
116  * gst_proxy_pad_event_default:
117  * @pad: a #GstPad to push the event to.
118  * @event: (transfer full): the #GstEvent to send to the pad.
119  *
120  * Invoke the default event of the proxy pad.
121  *
122  * Returns: TRUE if the event was handled.
123  *
124  * Since: 0.10.35
125  */
126 gboolean
127 gst_proxy_pad_event_default (GstPad * pad, GstEvent * event)
128 {
129   gboolean res;
130   GstPad *internal;
131
132   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
133   g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
134
135   internal = GST_PROXY_PAD_INTERNAL (pad);
136   res = gst_pad_push_event (internal, event);
137
138   return res;
139 }
140
141 /**
142  * gst_proxy_pad_query_default:
143  * @pad: a #GstPad to invoke the default query on.
144  * @query: (transfer none): the #GstQuery to perform.
145  *
146  * Invoke the default query function of the proxy pad.
147  *
148  * Returns: TRUE if the query could be performed.
149  *
150  * Since: 0.10.35
151  */
152 gboolean
153 gst_proxy_pad_query_default (GstPad * pad, GstQuery * query)
154 {
155   gboolean res;
156   GstPad *target;
157
158   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
159   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
160
161   if (!(target = gst_proxy_pad_get_target (pad)))
162     goto no_target;
163
164   res = gst_pad_query (target, query);
165   gst_object_unref (target);
166
167   return res;
168
169   /* ERRORS */
170 no_target:
171   {
172     GST_DEBUG_OBJECT (pad, "no target pad");
173     return FALSE;
174   }
175 }
176
177 /**
178  * gst_proyx_pad_iterate_internal_links_default:
179  * @pad: the #GstPad to get the internal links of.
180  *
181  * Invoke the default iterate internal links function of the proxy pad.
182  *
183  * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
184  * returned pad with gst_object_unref().
185  *
186  * Since: 0.10.35
187  */
188 GstIterator *
189 gst_proxy_pad_iterate_internal_links_default (GstPad * pad)
190 {
191   GstIterator *res = NULL;
192   GstPad *internal;
193   GValue v = { 0, };
194
195   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
196
197   internal = GST_PROXY_PAD_INTERNAL (pad);
198   g_value_init (&v, GST_TYPE_PAD);
199   g_value_set_object (&v, internal);
200   res = gst_iterator_new_single (GST_TYPE_PAD, &v);
201   g_value_unset (&v);
202   gst_object_unref (internal);
203
204   return res;
205 }
206
207 /**
208  * gst_proxy_pad_chain_default:
209  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
210  * @buffer: (transfer full): the #GstBuffer to send, return GST_FLOW_ERROR
211  *     if not.
212  *
213  * Invoke the default chain function of the proxy pad.
214  *
215  * Returns: a #GstFlowReturn from the pad.
216  *
217  * Since: 0.10.35
218  */
219 GstFlowReturn
220 gst_proxy_pad_chain_default (GstPad * pad, GstBuffer * buffer)
221 {
222   GstFlowReturn res;
223   GstPad *internal;
224
225   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
226   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
227
228   internal = GST_PROXY_PAD_INTERNAL (pad);
229   res = gst_pad_push (internal, buffer);
230
231   return res;
232 }
233
234 /**
235  * gst_proxy_pad_chain_list_default:
236  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
237  * @list: (transfer full): the #GstBufferList to send, return GST_FLOW_ERROR
238  *     if not.
239  *
240  * Invoke the default chain list function of the proxy pad.
241  *
242  * Returns: a #GstFlowReturn from the pad.
243  *
244  * Since: 0.10.35
245  */
246 GstFlowReturn
247 gst_proxy_pad_chain_list_default (GstPad * pad, GstBufferList * list)
248 {
249   GstFlowReturn res;
250   GstPad *internal;
251
252   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
253   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
254
255   internal = GST_PROXY_PAD_INTERNAL (pad);
256   res = gst_pad_push_list (internal, list);
257
258   return res;
259 }
260
261 /**
262  * gst_proxy_pad_get_range_default:
263  * @pad: a src #GstPad, returns #GST_FLOW_ERROR if not.
264  * @offset: The start offset of the buffer
265  * @size: The length of the buffer
266  * @buffer: (out callee-allocates): a pointer to hold the #GstBuffer,
267  *     returns #GST_FLOW_ERROR if %NULL.
268  *
269  * Invoke the default getrange function of the proxy pad.
270  *
271  * Returns: a #GstFlowReturn from the pad.
272  *
273  * Since: 0.10.35
274  */
275 GstFlowReturn
276 gst_proxy_pad_getrange_default (GstPad * pad, guint64 offset, guint size,
277     GstBuffer ** buffer)
278 {
279   GstFlowReturn res;
280   GstPad *internal;
281
282   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
283   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
284
285   internal = GST_PROXY_PAD_INTERNAL (pad);
286   res = gst_pad_pull_range (internal, offset, size, buffer);
287
288   return res;
289 }
290
291 /**
292  * gst_proxy_pad_getcaps_default:
293  * @pad: a #GstPad to get the capabilities of.
294  * @filter: a #GstCaps filter.
295  *
296  * Invoke the default getcaps function of the proxy pad.
297  *
298  * Returns: (transfer full): the caps of the pad with incremented ref-count
299  *
300  * Since: 0.10.35
301  */
302 GstCaps *
303 gst_proxy_pad_getcaps_default (GstPad * pad, GstCaps * filter)
304 {
305   GstPad *target;
306   GstCaps *res;
307   GstPadTemplate *templ;
308
309   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
310
311   templ = GST_PAD_PAD_TEMPLATE (pad);
312   target = gst_proxy_pad_get_target (pad);
313   if (target) {
314     /* if we have a real target, proxy the call */
315     res = gst_pad_get_caps (target, filter);
316
317     GST_DEBUG_OBJECT (pad, "get caps of target %s:%s : %" GST_PTR_FORMAT,
318         GST_DEBUG_PAD_NAME (target), res);
319
320     gst_object_unref (target);
321
322     /* filter against the template */
323     if (templ && res) {
324       GstCaps *filt, *tmp;
325
326       filt = GST_PAD_TEMPLATE_CAPS (templ);
327       if (filt) {
328         tmp = gst_caps_intersect_full (res, filt, GST_CAPS_INTERSECT_FIRST);
329         gst_caps_unref (res);
330         res = tmp;
331         GST_DEBUG_OBJECT (pad,
332             "filtered against template gives %" GST_PTR_FORMAT, res);
333       }
334     }
335   } else {
336     /* else, if we have a template, use its caps. */
337     if (templ) {
338       res = GST_PAD_TEMPLATE_CAPS (templ);
339       GST_DEBUG_OBJECT (pad,
340           "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, res,
341           res);
342       res = gst_caps_ref (res);
343
344       if (filter) {
345         GstCaps *intersection =
346             gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
347
348         gst_caps_unref (res);
349         res = intersection;
350       }
351
352       goto done;
353     }
354
355     /* If there's a filter, return that */
356     if (filter != NULL) {
357       res = gst_caps_ref (filter);
358       goto done;
359     }
360
361     /* last resort, any caps */
362     GST_DEBUG_OBJECT (pad, "pad has no template, returning ANY");
363     res = gst_caps_new_any ();
364   }
365
366 done:
367   return res;
368 }
369
370 /**
371  * gst_proxy_pad_acceptcaps_default:
372  * @pad: a #GstPad to check
373  * @caps: a #GstCaps to check on the pad
374  *
375  * Invoke the default acceptcaps function of the proxy pad.
376  *
377  * Returns: TRUE if the pad can accept the caps.
378  *
379  * Since: 0.10.35
380  */
381 gboolean
382 gst_proxy_pad_acceptcaps_default (GstPad * pad, GstCaps * caps)
383 {
384   GstPad *target;
385   gboolean res;
386
387   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
388   g_return_val_if_fail (caps == NULL || GST_IS_CAPS (caps), FALSE);
389
390   target = gst_proxy_pad_get_target (pad);
391   if (target) {
392     res = gst_pad_accept_caps (target, caps);
393     gst_object_unref (target);
394   } else {
395     GST_DEBUG_OBJECT (pad, "no target");
396     /* We don't have a target, we return TRUE and we assume that any future
397      * target will be able to deal with any configured caps. */
398     res = TRUE;
399   }
400
401   return res;
402 }
403
404 /**
405  * gst_proxy_pad_fixatecaps_default:
406  * @pad: a  #GstPad to fixate
407  * @caps: the  #GstCaps to fixate
408  *
409  * Invoke the default fixatecaps function of the proxy pad.
410  *
411  * Since: 0.10.35
412  */
413 void
414 gst_proxy_pad_fixatecaps_default (GstPad * pad, GstCaps * caps)
415 {
416   GstPad *target;
417
418   g_return_if_fail (GST_IS_PROXY_PAD (pad));
419   g_return_if_fail (GST_IS_CAPS (caps));
420
421   if (!(target = gst_proxy_pad_get_target (pad)))
422     goto no_target;
423
424   gst_pad_fixate_caps (target, caps);
425   gst_object_unref (target);
426
427   return;
428
429   /* ERRORS */
430 no_target:
431   {
432     GST_DEBUG_OBJECT (pad, "no target");
433     return;
434   }
435 }
436
437 static gboolean
438 gst_proxy_pad_set_target_unlocked (GstPad * pad, GstPad * target)
439 {
440   GstPad *oldtarget;
441
442   if (target) {
443     GST_LOG_OBJECT (pad, "setting target %s:%s", GST_DEBUG_PAD_NAME (target));
444
445     if (G_UNLIKELY (GST_PAD_DIRECTION (pad) != GST_PAD_DIRECTION (target)))
446       goto wrong_direction;
447   } else
448     GST_LOG_OBJECT (pad, "clearing target");
449
450   /* clear old target */
451   if ((oldtarget = GST_PROXY_PAD_TARGET (pad)))
452     gst_object_unref (oldtarget);
453
454   /* set and ref new target if any */
455   if (target)
456     GST_PROXY_PAD_TARGET (pad) = gst_object_ref (target);
457   else
458     GST_PROXY_PAD_TARGET (pad) = NULL;
459
460   return TRUE;
461
462   /* ERRORS */
463 wrong_direction:
464   {
465     GST_ERROR_OBJECT (pad,
466         "target pad doesn't have the same direction as ourself");
467     return FALSE;
468   }
469 }
470
471 static gboolean
472 gst_proxy_pad_set_target (GstPad * pad, GstPad * target)
473 {
474   gboolean result;
475
476   GST_PROXY_LOCK (pad);
477   result = gst_proxy_pad_set_target_unlocked (pad, target);
478   GST_PROXY_UNLOCK (pad);
479
480   return result;
481 }
482
483 static GstPad *
484 gst_proxy_pad_get_target (GstPad * pad)
485 {
486   GstPad *target;
487
488   GST_PROXY_LOCK (pad);
489   target = GST_PROXY_PAD_TARGET (pad);
490   if (target)
491     gst_object_ref (target);
492   GST_PROXY_UNLOCK (pad);
493
494   return target;
495 }
496
497 /**
498  * gst_proxy_pad_get_internal:
499  * @pad: the #GstProxyPad
500  *
501  * Get the internal pad of @pad. Unref target pad after usage.
502  *
503  * The internal pad of a #GstGhostPad is the internally used
504  * pad of opposite direction, which is used to link to the target.
505  *
506  * Returns: (transfer full): the target #GstProxyPad, can be NULL.
507  * Unref target pad after usage.
508  *
509  * Since: 0.10.35
510  */
511 GstProxyPad *
512 gst_proxy_pad_get_internal (GstProxyPad * pad)
513 {
514   GstPad *internal;
515
516   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
517
518   GST_PROXY_LOCK (pad);
519   internal = GST_PROXY_PAD_INTERNAL (pad);
520   if (internal)
521     gst_object_ref (internal);
522   GST_PROXY_UNLOCK (pad);
523
524   return GST_PROXY_PAD_CAST (internal);
525 }
526
527 /**
528  * gst_proxy_pad_unlink_default:
529  * @pad: a #GstPad to unlink
530  *
531  * Invoke the default unlink function of the proxy pad.
532  *
533  * Since: 0.10.35
534  */
535 void
536 gst_proxy_pad_unlink_default (GstPad * pad)
537 {
538   GstPad *internal;
539
540   /* don't do anything if this unlink resulted from retargeting the pad
541    * controlled by the ghostpad. We only want to invalidate the target pad when
542    * the element suddenly unlinked with our internal pad. */
543   if (GST_PROXY_PAD_RETARGET (pad))
544     return;
545
546   internal = GST_PROXY_PAD_INTERNAL (pad);
547
548   GST_DEBUG_OBJECT (pad, "pad is unlinked");
549
550   gst_proxy_pad_set_target (internal, NULL);
551 }
552
553 static void
554 gst_proxy_pad_class_init (GstProxyPadClass * klass)
555 {
556   GObjectClass *gobject_class = (GObjectClass *) klass;
557
558   g_type_class_add_private (klass, sizeof (GstProxyPadPrivate));
559
560   gobject_class->dispose = gst_proxy_pad_dispose;
561   gobject_class->finalize = gst_proxy_pad_finalize;
562
563   /* Register common function pointer descriptions */
564   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_query_type_default);
565   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_event_default);
566   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_query_default);
567   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_iterate_internal_links_default);
568   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_getcaps_default);
569   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_acceptcaps_default);
570   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_fixatecaps_default);
571   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_unlink_default);
572   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_default);
573   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_list_default);
574   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_getrange_default);
575 }
576
577 static void
578 gst_proxy_pad_dispose (GObject * object)
579 {
580   GstPad *pad = GST_PAD (object);
581   GstPad **target_p;
582
583   GST_PROXY_LOCK (pad);
584   /* remove and unref the target */
585   target_p = &GST_PROXY_PAD_TARGET (pad);
586   gst_object_replace ((GstObject **) target_p, NULL);
587   /* The internal is only cleared by GstGhostPad::dispose, since it is the 
588    * parent of non-ghost GstProxyPad and owns the refcount on the internal.
589    */
590   GST_PROXY_UNLOCK (pad);
591
592   G_OBJECT_CLASS (gst_proxy_pad_parent_class)->dispose (object);
593 }
594
595 static void
596 gst_proxy_pad_finalize (GObject * object)
597 {
598   GstProxyPad *pad = GST_PROXY_PAD (object);
599
600   g_mutex_free (GST_PROXY_GET_LOCK (pad));
601   GST_PROXY_GET_LOCK (pad) = NULL;
602
603   G_OBJECT_CLASS (gst_proxy_pad_parent_class)->finalize (object);
604 }
605
606 static void
607 gst_proxy_pad_init (GstProxyPad * ppad)
608 {
609   GstPad *pad = (GstPad *) ppad;
610
611   GST_PROXY_PAD_PRIVATE (ppad) = G_TYPE_INSTANCE_GET_PRIVATE (ppad,
612       GST_TYPE_PROXY_PAD, GstProxyPadPrivate);
613   GST_PROXY_GET_LOCK (pad) = g_mutex_new ();
614
615   gst_pad_set_query_type_function (pad, gst_proxy_pad_query_type_default);
616   gst_pad_set_event_function (pad, gst_proxy_pad_event_default);
617   gst_pad_set_query_function (pad, gst_proxy_pad_query_default);
618   gst_pad_set_iterate_internal_links_function (pad,
619       gst_proxy_pad_iterate_internal_links_default);
620
621   gst_pad_set_getcaps_function (pad, gst_proxy_pad_getcaps_default);
622   gst_pad_set_acceptcaps_function (pad, gst_proxy_pad_acceptcaps_default);
623   gst_pad_set_fixatecaps_function (pad, gst_proxy_pad_fixatecaps_default);
624   gst_pad_set_unlink_function (pad, gst_proxy_pad_unlink_default);
625 }
626
627
628 /***********************************************************************
629  * Ghost pads, implemented as a pair of proxy pads (sort of)
630  */
631
632
633 #define GST_GHOST_PAD_PRIVATE(obj)      (GST_GHOST_PAD_CAST (obj)->priv)
634
635 struct _GstGhostPadPrivate
636 {
637   /* with PROXY_LOCK */
638   gboolean constructed;
639 };
640
641 G_DEFINE_TYPE (GstGhostPad, gst_ghost_pad, GST_TYPE_PROXY_PAD);
642
643 static void gst_ghost_pad_dispose (GObject * object);
644
645 /**
646  * gst_ghost_pad_internal_activate_push_default:
647  * @pad: the #GstPad to activate or deactivate.
648  * @active: whether the pad should be active or not.
649  *
650  * Invoke the default activate push function of a proxy pad that is
651  * owned by a ghost pad.
652  *
653  * Returns: %TRUE if the operation was successful.
654  *
655  * Since: 0.10.35
656  */
657 gboolean
658 gst_ghost_pad_internal_activate_push_default (GstPad * pad, gboolean active)
659 {
660   gboolean ret;
661   GstPad *other;
662
663   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
664
665   GST_LOG_OBJECT (pad, "%sactivate push on %s:%s, we're ok",
666       (active ? "" : "de"), GST_DEBUG_PAD_NAME (pad));
667
668   /* in both cases (SRC and SINK) we activate just the internal pad. The targets
669    * will be activated later (or already in case of a ghost sinkpad). */
670   other = GST_PROXY_PAD_INTERNAL (pad);
671   ret = gst_pad_activate_push (other, active);
672
673   return ret;
674 }
675
676 /**
677  * gst_ghost_pad_internal_activate_pull_default:
678  * @pad: the #GstPad to activate or deactivate.
679  * @active: whether the pad should be active or not.
680  *
681  * Invoke the default activate pull function of a proxy pad that is
682  * owned by a ghost pad.
683  *
684  * Returns: %TRUE if the operation was successful.
685  *
686  * Since: 0.10.35
687  */
688 gboolean
689 gst_ghost_pad_internal_activate_pull_default (GstPad * pad, gboolean active)
690 {
691   gboolean ret;
692   GstPad *other;
693
694   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
695
696   GST_LOG_OBJECT (pad, "%sactivate pull on %s:%s", (active ? "" : "de"),
697       GST_DEBUG_PAD_NAME (pad));
698
699   if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
700     /* we are activated in pull mode by our peer element, which is a sinkpad
701      * that wants to operate in pull mode. This activation has to propagate
702      * upstream through the pipeline. We call the internal activation function,
703      * which will trigger gst_ghost_pad_activate_pull_default, which propagates even
704      * further upstream */
705     GST_LOG_OBJECT (pad, "pad is src, activate internal");
706     other = GST_PROXY_PAD_INTERNAL (pad);
707     ret = gst_pad_activate_pull (other, active);
708   } else if (G_LIKELY ((other = gst_pad_get_peer (pad)))) {
709     /* We are SINK, the ghostpad is SRC, we propagate the activation upstream
710      * since we hold a pointer to the upstream peer. */
711     GST_LOG_OBJECT (pad, "activating peer");
712     ret = gst_pad_activate_pull (other, active);
713     gst_object_unref (other);
714   } else {
715     /* this is failure, we can't activate pull if there is no peer */
716     GST_LOG_OBJECT (pad, "not src and no peer, failing");
717     ret = FALSE;
718   }
719
720   return ret;
721 }
722
723 /**
724  * gst_ghost_pad_activate_push_default:
725  * @pad: the #GstPad to activate or deactivate.
726  * @active: whether the pad should be active or not.
727  *
728  * Invoke the default activate push function of a ghost pad.
729  *
730  * Returns: %TRUE if the operation was successful.
731  *
732  * Since: 0.10.35
733  */
734 gboolean
735 gst_ghost_pad_activate_push_default (GstPad * pad, gboolean active)
736 {
737   gboolean ret;
738   GstPad *other;
739
740   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), FALSE);
741
742   GST_LOG_OBJECT (pad, "%sactivate push on %s:%s, proxy internal",
743       (active ? "" : "de"), GST_DEBUG_PAD_NAME (pad));
744
745   /* just activate the internal pad */
746   other = GST_PROXY_PAD_INTERNAL (pad);
747   ret = gst_pad_activate_push (other, active);
748
749   return ret;
750 }
751
752 /**
753  * gst_ghost_pad_activate_pull_default:
754  * @pad: the #GstPad to activate or deactivate.
755  * @active: whether the pad should be active or not.
756  *
757  * Invoke the default activate pull function of a ghost pad.
758  *
759  * Returns: %TRUE if the operation was successful.
760  *
761  * Since: 0.10.35
762  */
763 gboolean
764 gst_ghost_pad_activate_pull_default (GstPad * pad, gboolean active)
765 {
766   gboolean ret;
767   GstPad *other;
768
769   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), FALSE);
770
771   GST_LOG_OBJECT (pad, "%sactivate pull on %s:%s", (active ? "" : "de"),
772       GST_DEBUG_PAD_NAME (pad));
773
774   if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
775     /* the ghostpad is SRC and activated in pull mode by its peer, call the
776      * activation function of the internal pad to propagate the activation
777      * upstream */
778     GST_LOG_OBJECT (pad, "pad is src, activate internal");
779     other = GST_PROXY_PAD_INTERNAL (pad);
780     ret = gst_pad_activate_pull (other, active);
781   } else if (G_LIKELY ((other = gst_pad_get_peer (pad)))) {
782     /* We are SINK and activated by the internal pad, propagate activation
783      * upstream because we hold a ref to the upstream peer */
784     GST_LOG_OBJECT (pad, "activating peer");
785     ret = gst_pad_activate_pull (other, active);
786     gst_object_unref (other);
787   } else {
788     /* no peer, we fail */
789     GST_LOG_OBJECT (pad, "pad not src and no peer, failing");
790     ret = FALSE;
791   }
792
793   return ret;
794 }
795
796 /**
797  * gst_ghost_pad_link_default:
798  * @pad: the #GstPad to link.
799  * @peer: the #GstPad peer
800  *
801  * Invoke the default link function of a ghost pad.
802  *
803  * Returns: #GstPadLinkReturn of the operation
804  *
805  * Since: 0.10.35
806  */
807 GstPadLinkReturn
808 gst_ghost_pad_link_default (GstPad * pad, GstPad * peer)
809 {
810   GstPadLinkReturn ret;
811   GstPad *internal;
812
813   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), GST_PAD_LINK_REFUSED);
814   g_return_val_if_fail (GST_IS_PAD (peer), GST_PAD_LINK_REFUSED);
815
816   GST_DEBUG_OBJECT (pad, "linking ghostpad");
817
818   internal = GST_PROXY_PAD_INTERNAL (pad);
819   if (!gst_proxy_pad_set_target (internal, peer))
820     goto target_failed;
821
822   ret = GST_PAD_LINK_OK;
823   /* if we are a source pad, we should call the peer link function
824    * if the peer has one, see design docs. */
825   if (GST_PAD_IS_SRC (pad)) {
826     if (GST_PAD_LINKFUNC (peer)) {
827       ret = GST_PAD_LINKFUNC (peer) (peer, pad);
828       if (ret != GST_PAD_LINK_OK)
829         goto link_failed;
830     }
831   }
832   return ret;
833
834   /* ERRORS */
835 target_failed:
836   {
837     GST_DEBUG_OBJECT (pad, "setting target failed");
838     return GST_PAD_LINK_REFUSED;
839   }
840 link_failed:
841   {
842     GST_DEBUG_OBJECT (pad, "linking failed");
843     /* clear target again */
844     gst_proxy_pad_set_target (internal, NULL);
845     return ret;
846   }
847 }
848
849 /**
850  * gst_ghost_pad_unlink_default:
851  * @pad: the #GstPad to link.
852  *
853  * Invoke the default unlink function of a ghost pad.
854  *
855  * Since: 0.10.35
856  */
857 void
858 gst_ghost_pad_unlink_default (GstPad * pad)
859 {
860   GstPad *internal;
861
862   g_return_if_fail (GST_IS_GHOST_PAD (pad));
863
864   internal = GST_PROXY_PAD_INTERNAL (pad);
865
866   GST_DEBUG_OBJECT (pad, "unlinking ghostpad");
867
868   /* The target of the internal pad is no longer valid */
869   gst_proxy_pad_set_target (internal, NULL);
870 }
871
872 static void
873 gst_ghost_pad_class_init (GstGhostPadClass * klass)
874 {
875   GObjectClass *gobject_class = (GObjectClass *) klass;
876
877   g_type_class_add_private (klass, sizeof (GstGhostPadPrivate));
878
879   gobject_class->dispose = gst_ghost_pad_dispose;
880
881   GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_pull_default);
882   GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_push_default);
883   GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_link_default);
884 }
885
886 static void
887 gst_ghost_pad_init (GstGhostPad * pad)
888 {
889   GST_GHOST_PAD_PRIVATE (pad) = G_TYPE_INSTANCE_GET_PRIVATE (pad,
890       GST_TYPE_GHOST_PAD, GstGhostPadPrivate);
891
892   gst_pad_set_activatepull_function (GST_PAD_CAST (pad),
893       gst_ghost_pad_activate_pull_default);
894   gst_pad_set_activatepush_function (GST_PAD_CAST (pad),
895       gst_ghost_pad_activate_push_default);
896 }
897
898 static void
899 gst_ghost_pad_dispose (GObject * object)
900 {
901   GstPad *pad;
902   GstPad *internal;
903   GstPad *peer;
904
905   pad = GST_PAD (object);
906
907   GST_DEBUG_OBJECT (pad, "dispose");
908
909   gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL);
910
911   /* Unlink here so that gst_pad_dispose doesn't. That would lead to a call to
912    * gst_ghost_pad_unlink_default when the ghost pad is in an inconsistent state */
913   peer = gst_pad_get_peer (pad);
914   if (peer) {
915     if (GST_PAD_IS_SRC (pad))
916       gst_pad_unlink (pad, peer);
917     else
918       gst_pad_unlink (peer, pad);
919
920     gst_object_unref (peer);
921   }
922
923   GST_PROXY_LOCK (pad);
924   internal = GST_PROXY_PAD_INTERNAL (pad);
925
926   gst_pad_set_activatepull_function (internal, NULL);
927   gst_pad_set_activatepush_function (internal, NULL);
928
929   /* disposes of the internal pad, since the ghostpad is the only possible object
930    * that has a refcount on the internal pad. */
931   gst_object_unparent (GST_OBJECT_CAST (internal));
932   GST_PROXY_PAD_INTERNAL (pad) = NULL;
933
934   GST_PROXY_UNLOCK (pad);
935
936   G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object);
937 }
938
939 /**
940  * gst_ghost_pad_construct:
941  * @gpad: the newly allocated ghost pad
942  *
943  * Finish initialization of a newly allocated ghost pad.
944  *
945  * This function is most useful in language bindings and when subclassing
946  * #GstGhostPad; plugin and application developers normally will not call this
947  * function. Call this function directly after a call to g_object_new
948  * (GST_TYPE_GHOST_PAD, "direction", @dir, ..., NULL).
949  *
950  * Returns: %TRUE if the construction succeeds, %FALSE otherwise.
951  *
952  * Since: 0.10.22
953  */
954 gboolean
955 gst_ghost_pad_construct (GstGhostPad * gpad)
956 {
957   GstPadDirection dir, otherdir;
958   GstPadTemplate *templ;
959   GstPad *pad, *internal;
960
961   g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
962   g_return_val_if_fail (GST_GHOST_PAD_PRIVATE (gpad)->constructed == FALSE,
963       FALSE);
964
965   g_object_get (gpad, "direction", &dir, "template", &templ, NULL);
966
967   g_return_val_if_fail (dir != GST_PAD_UNKNOWN, FALSE);
968
969   pad = GST_PAD (gpad);
970
971   /* Set directional padfunctions for ghostpad */
972   if (dir == GST_PAD_SINK) {
973     gst_pad_set_chain_function (pad, gst_proxy_pad_chain_default);
974     gst_pad_set_chain_list_function (pad, gst_proxy_pad_chain_list_default);
975   } else {
976     gst_pad_set_getrange_function (pad, gst_proxy_pad_getrange_default);
977   }
978
979   /* link/unlink functions */
980   gst_pad_set_link_function (pad, gst_ghost_pad_link_default);
981   gst_pad_set_unlink_function (pad, gst_ghost_pad_unlink_default);
982
983   /* INTERNAL PAD, it always exists and is child of the ghostpad */
984   otherdir = (dir == GST_PAD_SRC) ? GST_PAD_SINK : GST_PAD_SRC;
985   if (templ) {
986     internal =
987         g_object_new (GST_TYPE_PROXY_PAD, "name", NULL,
988         "direction", otherdir, "template", templ, NULL);
989     /* release ref obtained via g_object_get */
990     gst_object_unref (templ);
991   } else {
992     internal =
993         g_object_new (GST_TYPE_PROXY_PAD, "name", NULL,
994         "direction", otherdir, NULL);
995   }
996   GST_PAD_UNSET_FLUSHING (internal);
997
998   /* Set directional padfunctions for internal pad */
999   if (dir == GST_PAD_SRC) {
1000     gst_pad_set_chain_function (internal, gst_proxy_pad_chain_default);
1001     gst_pad_set_chain_list_function (internal,
1002         gst_proxy_pad_chain_list_default);
1003   } else {
1004     gst_pad_set_getrange_function (internal, gst_proxy_pad_getrange_default);
1005   }
1006
1007   GST_PROXY_LOCK (pad);
1008
1009   /* now make the ghostpad a parent of the internal pad */
1010   if (!gst_object_set_parent (GST_OBJECT_CAST (internal),
1011           GST_OBJECT_CAST (pad)))
1012     goto parent_failed;
1013
1014   /* The ghostpad is the parent of the internal pad and is the only object that
1015    * can have a refcount on the internal pad.
1016    * At this point, the GstGhostPad has a refcount of 1, and the internal pad has
1017    * a refcount of 1.
1018    * When the refcount of the GstGhostPad drops to 0, the ghostpad will dispose
1019    * its refcount on the internal pad in the dispose method by un-parenting it.
1020    * This is why we don't take extra refcounts in the assignments below
1021    */
1022   GST_PROXY_PAD_INTERNAL (pad) = internal;
1023   GST_PROXY_PAD_INTERNAL (internal) = pad;
1024
1025   /* special activation functions for the internal pad */
1026   gst_pad_set_activatepull_function (internal,
1027       gst_ghost_pad_internal_activate_pull_default);
1028   gst_pad_set_activatepush_function (internal,
1029       gst_ghost_pad_internal_activate_push_default);
1030
1031   GST_PROXY_UNLOCK (pad);
1032
1033   GST_GHOST_PAD_PRIVATE (gpad)->constructed = TRUE;
1034   return TRUE;
1035
1036   /* ERRORS */
1037 parent_failed:
1038   {
1039     GST_WARNING_OBJECT (gpad, "Could not set internal pad %s:%s",
1040         GST_DEBUG_PAD_NAME (internal));
1041     g_critical ("Could not set internal pad %s:%s",
1042         GST_DEBUG_PAD_NAME (internal));
1043     GST_PROXY_UNLOCK (pad);
1044     gst_object_unref (internal);
1045     return FALSE;
1046   }
1047 }
1048
1049 static GstPad *
1050 gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir,
1051     GstPadTemplate * templ)
1052 {
1053   GstGhostPad *ret;
1054
1055   g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL);
1056
1057   /* OBJECT CREATION */
1058   if (templ) {
1059     ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name,
1060         "direction", dir, "template", templ, NULL);
1061   } else {
1062     ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name,
1063         "direction", dir, NULL);
1064   }
1065
1066   if (!gst_ghost_pad_construct (ret))
1067     goto construct_failed;
1068
1069   return GST_PAD_CAST (ret);
1070
1071 construct_failed:
1072   /* already logged */
1073   gst_object_unref (ret);
1074   return NULL;
1075 }
1076
1077 /**
1078  * gst_ghost_pad_new_no_target:
1079  * @name: (allow-none): the name of the new pad, or NULL to assign a default name.
1080  * @dir: the direction of the ghostpad
1081  *
1082  * Create a new ghostpad without a target with the given direction.
1083  * A target can be set on the ghostpad later with the
1084  * gst_ghost_pad_set_target() function.
1085  *
1086  * The created ghostpad will not have a padtemplate.
1087  *
1088  * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
1089  */
1090 GstPad *
1091 gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
1092 {
1093   GstPad *ret;
1094
1095   g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL);
1096
1097   GST_LOG ("name:%s, direction:%d", GST_STR_NULL (name), dir);
1098
1099   ret = gst_ghost_pad_new_full (name, dir, NULL);
1100
1101   return ret;
1102 }
1103
1104 /**
1105  * gst_ghost_pad_new:
1106  * @name: (allow-none): the name of the new pad, or NULL to assign a default name
1107  * @target: (transfer none): the pad to ghost.
1108  *
1109  * Create a new ghostpad with @target as the target. The direction will be taken
1110  * from the target pad. @target must be unlinked.
1111  *
1112  * Will ref the target.
1113  *
1114  * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
1115  */
1116 GstPad *
1117 gst_ghost_pad_new (const gchar * name, GstPad * target)
1118 {
1119   GstPad *ret;
1120
1121   g_return_val_if_fail (GST_IS_PAD (target), NULL);
1122   g_return_val_if_fail (!gst_pad_is_linked (target), NULL);
1123
1124   GST_LOG ("name:%s, target:%s:%s", GST_STR_NULL (name),
1125       GST_DEBUG_PAD_NAME (target));
1126
1127   if ((ret = gst_ghost_pad_new_no_target (name, GST_PAD_DIRECTION (target))))
1128     if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
1129       goto set_target_failed;
1130
1131   return ret;
1132
1133   /* ERRORS */
1134 set_target_failed:
1135   {
1136     GST_WARNING_OBJECT (ret, "failed to set target %s:%s",
1137         GST_DEBUG_PAD_NAME (target));
1138     gst_object_unref (ret);
1139     return NULL;
1140   }
1141 }
1142
1143 /**
1144  * gst_ghost_pad_new_from_template:
1145  * @name: (allow-none): the name of the new pad, or NULL to assign a default name.
1146  * @target: (transfer none): the pad to ghost.
1147  * @templ: (transfer none): the #GstPadTemplate to use on the ghostpad.
1148  *
1149  * Create a new ghostpad with @target as the target. The direction will be taken
1150  * from the target pad. The template used on the ghostpad will be @template.
1151  *
1152  * Will ref the target.
1153  *
1154  * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
1155  *
1156  * Since: 0.10.10
1157  */
1158
1159 GstPad *
1160 gst_ghost_pad_new_from_template (const gchar * name, GstPad * target,
1161     GstPadTemplate * templ)
1162 {
1163   GstPad *ret;
1164
1165   g_return_val_if_fail (GST_IS_PAD (target), NULL);
1166   g_return_val_if_fail (!gst_pad_is_linked (target), NULL);
1167   g_return_val_if_fail (templ != NULL, NULL);
1168   g_return_val_if_fail (GST_PAD_TEMPLATE_DIRECTION (templ) ==
1169       GST_PAD_DIRECTION (target), NULL);
1170
1171   GST_LOG ("name:%s, target:%s:%s, templ:%p", GST_STR_NULL (name),
1172       GST_DEBUG_PAD_NAME (target), templ);
1173
1174   if ((ret = gst_ghost_pad_new_full (name, GST_PAD_DIRECTION (target), templ)))
1175     if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
1176       goto set_target_failed;
1177
1178   return ret;
1179
1180   /* ERRORS */
1181 set_target_failed:
1182   {
1183     GST_WARNING_OBJECT (ret, "failed to set target %s:%s",
1184         GST_DEBUG_PAD_NAME (target));
1185     gst_object_unref (ret);
1186     return NULL;
1187   }
1188 }
1189
1190 /**
1191  * gst_ghost_pad_new_no_target_from_template:
1192  * @name: (allow-none): the name of the new pad, or NULL to assign a default name
1193  * @templ: (transfer none): the #GstPadTemplate to create the ghostpad from.
1194  *
1195  * Create a new ghostpad based on @templ, without setting a target. The
1196  * direction will be taken from the @templ.
1197  *
1198  * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
1199  *
1200  * Since: 0.10.10
1201  */
1202 GstPad *
1203 gst_ghost_pad_new_no_target_from_template (const gchar * name,
1204     GstPadTemplate * templ)
1205 {
1206   GstPad *ret;
1207
1208   g_return_val_if_fail (templ != NULL, NULL);
1209
1210   ret =
1211       gst_ghost_pad_new_full (name, GST_PAD_TEMPLATE_DIRECTION (templ), templ);
1212
1213   return ret;
1214 }
1215
1216 /**
1217  * gst_ghost_pad_get_target:
1218  * @gpad: the #GstGhostPad
1219  *
1220  * Get the target pad of @gpad. Unref target pad after usage.
1221  *
1222  * Returns: (transfer full): the target #GstPad, can be NULL if the ghostpad
1223  * has no target set. Unref target pad after usage.
1224  */
1225 GstPad *
1226 gst_ghost_pad_get_target (GstGhostPad * gpad)
1227 {
1228   GstPad *ret;
1229
1230   g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), NULL);
1231
1232   ret = gst_proxy_pad_get_target (GST_PAD_CAST (gpad));
1233
1234   GST_DEBUG_OBJECT (gpad, "get target %s:%s", GST_DEBUG_PAD_NAME (ret));
1235
1236   return ret;
1237 }
1238
1239 /**
1240  * gst_ghost_pad_set_target:
1241  * @gpad: the #GstGhostPad
1242  * @newtarget: (transfer none) (allow-none): the new pad target
1243  *
1244  * Set the new target of the ghostpad @gpad. Any existing target
1245  * is unlinked and links to the new target are established. if @newtarget is
1246  * NULL the target will be cleared.
1247  *
1248  * Returns: (transfer full): TRUE if the new target could be set. This function
1249  *     can return FALSE when the internal pads could not be linked.
1250  */
1251 gboolean
1252 gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
1253 {
1254   GstPad *internal;
1255   GstPad *oldtarget;
1256   gboolean result;
1257   GstPadLinkReturn lret;
1258
1259   g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
1260   g_return_val_if_fail (GST_PAD_CAST (gpad) != newtarget, FALSE);
1261   g_return_val_if_fail (newtarget != GST_PROXY_PAD_INTERNAL (gpad), FALSE);
1262
1263   /* no need for locking, the internal pad's lifecycle is directly linked to the
1264    * ghostpad's */
1265   internal = GST_PROXY_PAD_INTERNAL (gpad);
1266
1267   if (newtarget)
1268     GST_DEBUG_OBJECT (gpad, "set target %s:%s", GST_DEBUG_PAD_NAME (newtarget));
1269   else
1270     GST_DEBUG_OBJECT (gpad, "clearing target");
1271
1272   /* clear old target */
1273   GST_PROXY_LOCK (gpad);
1274   if ((oldtarget = GST_PROXY_PAD_TARGET (gpad))) {
1275
1276     GST_PROXY_PAD_RETARGET (internal) = TRUE;
1277
1278     /* unlink internal pad */
1279     if (GST_PAD_IS_SRC (internal))
1280       gst_pad_unlink (internal, oldtarget);
1281     else
1282       gst_pad_unlink (oldtarget, internal);
1283
1284     GST_PROXY_PAD_RETARGET (internal) = FALSE;
1285   }
1286
1287   result = gst_proxy_pad_set_target_unlocked (GST_PAD_CAST (gpad), newtarget);
1288   GST_PROXY_UNLOCK (gpad);
1289
1290   if (result && newtarget) {
1291     /* and link to internal pad without any checks */
1292     GST_DEBUG_OBJECT (gpad, "connecting internal pad to target");
1293
1294     if (GST_PAD_IS_SRC (internal))
1295       lret =
1296           gst_pad_link_full (internal, newtarget, GST_PAD_LINK_CHECK_NOTHING);
1297     else
1298       lret =
1299           gst_pad_link_full (newtarget, internal, GST_PAD_LINK_CHECK_NOTHING);
1300
1301     if (lret != GST_PAD_LINK_OK)
1302       goto link_failed;
1303   }
1304
1305   return result;
1306
1307   /* ERRORS */
1308 link_failed:
1309   {
1310     GST_WARNING_OBJECT (gpad, "could not link internal and target, reason:%d",
1311         lret);
1312     /* and unset target again */
1313     GST_PROXY_LOCK (gpad);
1314     gst_proxy_pad_set_target_unlocked (GST_PAD_CAST (gpad), NULL);
1315     GST_PROXY_UNLOCK (gpad);
1316     return FALSE;
1317   }
1318 }