pad: remove getcaps and use caps query
[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_PAD_PEER (GST_PROXY_PAD_INTERNAL (pad)))
58 #define GST_PROXY_PAD_INTERNAL(pad)     (GST_PROXY_PAD_PRIVATE (pad)->internal)
59
60 struct _GstProxyPadPrivate
61 {
62   GstPad *internal;
63 };
64
65 G_DEFINE_TYPE (GstProxyPad, gst_proxy_pad, GST_TYPE_PAD);
66
67 static GstPad *gst_proxy_pad_get_target (GstPad * pad);
68
69 /**
70  * gst_proxy_pad_event_default:
71  * @pad: a #GstPad to push the event to.
72  * @event: (transfer full): the #GstEvent to send to the pad.
73  *
74  * Invoke the default event of the proxy pad.
75  *
76  * Returns: TRUE if the event was handled.
77  *
78  * Since: 0.10.36
79  */
80 gboolean
81 gst_proxy_pad_event_default (GstPad * pad, GstEvent * event)
82 {
83   gboolean res;
84   GstPad *internal;
85
86   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
87   g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
88
89   internal = GST_PROXY_PAD_INTERNAL (pad);
90   res = gst_pad_push_event (internal, event);
91
92   return res;
93 }
94
95 static gboolean
96 gst_proxy_pad_query_caps (GstPad * pad, GstQuery * query)
97 {
98   gboolean res;
99   GstPad *target;
100   GstCaps *result;
101   GstPadTemplate *templ;
102
103   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
104
105   templ = GST_PAD_PAD_TEMPLATE (pad);
106   target = gst_proxy_pad_get_target (pad);
107   if (target) {
108     /* if we have a real target, proxy the call */
109     res = gst_pad_query (target, query);
110
111     GST_DEBUG_OBJECT (pad, "get caps of target %s:%s : %" GST_PTR_FORMAT,
112         GST_DEBUG_PAD_NAME (target), query);
113
114     gst_object_unref (target);
115
116     /* filter against the template */
117     if (templ && res) {
118       GstCaps *filt, *tmp;
119
120       filt = GST_PAD_TEMPLATE_CAPS (templ);
121       if (filt) {
122         gst_query_parse_caps_result (query, &result);
123         tmp = gst_caps_intersect_full (result, filt, GST_CAPS_INTERSECT_FIRST);
124         gst_query_set_caps_result (query, tmp);
125         GST_DEBUG_OBJECT (pad,
126             "filtered against template gives %" GST_PTR_FORMAT, tmp);
127         gst_caps_unref (tmp);
128       }
129     }
130   } else {
131     GstCaps *filter;
132
133     res = TRUE;
134
135     gst_query_parse_caps (query, &filter);
136
137     /* else, if we have a template, use its caps. */
138     if (templ) {
139       result = GST_PAD_TEMPLATE_CAPS (templ);
140       GST_DEBUG_OBJECT (pad,
141           "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
142           result);
143
144       if (filter) {
145         GstCaps *intersection;
146
147         GST_DEBUG_OBJECT (pad, "intersect with filter");
148         intersection =
149             gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
150         gst_query_set_caps_result (query, intersection);
151         gst_caps_unref (intersection);
152       } else {
153         gst_query_set_caps_result (query, result);
154       }
155       goto done;
156     }
157
158     /* If there's a filter, return that */
159     if (filter != NULL) {
160       GST_DEBUG_OBJECT (pad, "return filter");
161       gst_query_set_caps_result (query, filter);
162       goto done;
163     }
164
165     /* last resort, any caps */
166     GST_DEBUG_OBJECT (pad, "pad has no template, returning ANY");
167     result = gst_caps_new_any ();
168     gst_query_set_caps_result (query, result);
169     gst_caps_unref (result);
170   }
171
172 done:
173   return res;
174 }
175
176 /**
177  * gst_proxy_pad_query_default:
178  * @pad: a #GstPad to invoke the default query on.
179  * @query: (transfer none): the #GstQuery to perform.
180  *
181  * Invoke the default query function of the proxy pad.
182  *
183  * Returns: TRUE if the query could be performed.
184  *
185  * Since: 0.10.36
186  */
187 gboolean
188 gst_proxy_pad_query_default (GstPad * pad, GstQuery * query)
189 {
190   gboolean res;
191   GstPad *target;
192
193   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
194   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
195
196
197   switch (GST_QUERY_TYPE (query)) {
198     case GST_QUERY_ACCEPT_CAPS:
199     {
200       target = gst_proxy_pad_get_target (pad);
201       if (target) {
202         res = gst_pad_query (target, query);
203         gst_object_unref (target);
204       } else {
205         GST_DEBUG_OBJECT (pad, "no target");
206         /* We don't have a target, we return TRUE and we assume that any future
207          * target will be able to deal with any configured caps. */
208         res = TRUE;
209       }
210       break;
211     }
212     case GST_QUERY_CAPS:
213     {
214       res = gst_proxy_pad_query_caps (pad, query);
215       break;
216     }
217     default:
218     {
219       target = gst_proxy_pad_get_target (pad);
220       if (target) {
221         res = gst_pad_query (target, query);
222         gst_object_unref (target);
223       } else {
224         GST_DEBUG_OBJECT (pad, "no target pad");
225         res = FALSE;
226       }
227       break;
228     }
229   }
230   return res;
231 }
232
233 /**
234  * gst_proyx_pad_iterate_internal_links_default:
235  * @pad: the #GstPad to get the internal links of.
236  *
237  * Invoke the default iterate internal links function of the proxy pad.
238  *
239  * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
240  * returned pad with gst_object_unref().
241  *
242  * Since: 0.10.36
243  */
244 GstIterator *
245 gst_proxy_pad_iterate_internal_links_default (GstPad * pad)
246 {
247   GstIterator *res = NULL;
248   GstPad *internal;
249   GValue v = { 0, };
250
251   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
252
253   internal = GST_PROXY_PAD_INTERNAL (pad);
254   g_value_init (&v, GST_TYPE_PAD);
255   g_value_set_object (&v, internal);
256   res = gst_iterator_new_single (GST_TYPE_PAD, &v);
257   g_value_unset (&v);
258
259   return res;
260 }
261
262 /**
263  * gst_proxy_pad_chain_default:
264  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
265  * @buffer: (transfer full): the #GstBuffer to send, return GST_FLOW_ERROR
266  *     if not.
267  *
268  * Invoke the default chain function of the proxy pad.
269  *
270  * Returns: a #GstFlowReturn from the pad.
271  *
272  * Since: 0.10.36
273  */
274 GstFlowReturn
275 gst_proxy_pad_chain_default (GstPad * pad, GstBuffer * buffer)
276 {
277   GstFlowReturn res;
278   GstPad *internal;
279
280   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
281   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
282
283   internal = GST_PROXY_PAD_INTERNAL (pad);
284   res = gst_pad_push (internal, buffer);
285
286   return res;
287 }
288
289 /**
290  * gst_proxy_pad_chain_list_default:
291  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
292  * @list: (transfer full): the #GstBufferList to send, return GST_FLOW_ERROR
293  *     if not.
294  *
295  * Invoke the default chain list function of the proxy pad.
296  *
297  * Returns: a #GstFlowReturn from the pad.
298  *
299  * Since: 0.10.36
300  */
301 GstFlowReturn
302 gst_proxy_pad_chain_list_default (GstPad * pad, GstBufferList * list)
303 {
304   GstFlowReturn res;
305   GstPad *internal;
306
307   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
308   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
309
310   internal = GST_PROXY_PAD_INTERNAL (pad);
311   res = gst_pad_push_list (internal, list);
312
313   return res;
314 }
315
316 /**
317  * gst_proxy_pad_get_range_default:
318  * @pad: a src #GstPad, returns #GST_FLOW_ERROR if not.
319  * @offset: The start offset of the buffer
320  * @size: The length of the buffer
321  * @buffer: (out callee-allocates): a pointer to hold the #GstBuffer,
322  *     returns #GST_FLOW_ERROR if %NULL.
323  *
324  * Invoke the default getrange function of the proxy pad.
325  *
326  * Returns: a #GstFlowReturn from the pad.
327  *
328  * Since: 0.10.36
329  */
330 GstFlowReturn
331 gst_proxy_pad_getrange_default (GstPad * pad, guint64 offset, guint size,
332     GstBuffer ** buffer)
333 {
334   GstFlowReturn res;
335   GstPad *internal;
336
337   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
338   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
339
340   internal = GST_PROXY_PAD_INTERNAL (pad);
341   res = gst_pad_pull_range (internal, offset, size, buffer);
342
343   return res;
344 }
345
346 static GstPad *
347 gst_proxy_pad_get_target (GstPad * pad)
348 {
349   GstPad *target;
350
351   GST_OBJECT_LOCK (pad);
352   target = GST_PROXY_PAD_TARGET (pad);
353   if (target)
354     gst_object_ref (target);
355   GST_OBJECT_UNLOCK (pad);
356
357   return target;
358 }
359
360 /**
361  * gst_proxy_pad_get_internal:
362  * @pad: the #GstProxyPad
363  *
364  * Get the internal pad of @pad. Unref target pad after usage.
365  *
366  * The internal pad of a #GstGhostPad is the internally used
367  * pad of opposite direction, which is used to link to the target.
368  *
369  * Returns: (transfer full): the target #GstProxyPad, can be NULL.
370  * Unref target pad after usage.
371  *
372  * Since: 0.10.36
373  */
374 GstProxyPad *
375 gst_proxy_pad_get_internal (GstProxyPad * pad)
376 {
377   GstPad *internal;
378
379   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
380
381   GST_OBJECT_LOCK (pad);
382   internal = GST_PROXY_PAD_INTERNAL (pad);
383   if (internal)
384     gst_object_ref (internal);
385   GST_OBJECT_UNLOCK (pad);
386
387   return GST_PROXY_PAD_CAST (internal);
388 }
389
390 /**
391  * gst_proxy_pad_unlink_default:
392  * @pad: a #GstPad to unlink
393  *
394  * Invoke the default unlink function of the proxy pad.
395  *
396  * Since: 0.10.36
397  */
398 void
399 gst_proxy_pad_unlink_default (GstPad * pad)
400 {
401   /* nothing to do anymore */
402   GST_DEBUG_OBJECT (pad, "pad is unlinked");
403 }
404
405 static void
406 gst_proxy_pad_class_init (GstProxyPadClass * klass)
407 {
408   g_type_class_add_private (klass, sizeof (GstProxyPadPrivate));
409
410   /* Register common function pointer descriptions */
411   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_event_default);
412   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_query_default);
413   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_iterate_internal_links_default);
414   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_unlink_default);
415   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_default);
416   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_list_default);
417   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_getrange_default);
418 }
419
420 static void
421 gst_proxy_pad_init (GstProxyPad * ppad)
422 {
423   GstPad *pad = (GstPad *) ppad;
424
425   GST_PROXY_PAD_PRIVATE (ppad) = G_TYPE_INSTANCE_GET_PRIVATE (ppad,
426       GST_TYPE_PROXY_PAD, GstProxyPadPrivate);
427
428   gst_pad_set_event_function (pad, gst_proxy_pad_event_default);
429   gst_pad_set_query_function (pad, gst_proxy_pad_query_default);
430   gst_pad_set_iterate_internal_links_function (pad,
431       gst_proxy_pad_iterate_internal_links_default);
432
433   gst_pad_set_unlink_function (pad, gst_proxy_pad_unlink_default);
434 }
435
436
437 /***********************************************************************
438  * Ghost pads, implemented as a pair of proxy pads (sort of)
439  */
440
441
442 #define GST_GHOST_PAD_PRIVATE(obj)      (GST_GHOST_PAD_CAST (obj)->priv)
443
444 struct _GstGhostPadPrivate
445 {
446   /* with PROXY_LOCK */
447   gboolean constructed;
448 };
449
450 G_DEFINE_TYPE (GstGhostPad, gst_ghost_pad, GST_TYPE_PROXY_PAD);
451
452 static void gst_ghost_pad_dispose (GObject * object);
453
454 /**
455  * gst_ghost_pad_internal_activate_push_default:
456  * @pad: the #GstPad to activate or deactivate.
457  * @active: whether the pad should be active or not.
458  *
459  * Invoke the default activate push function of a proxy pad that is
460  * owned by a ghost pad.
461  *
462  * Returns: %TRUE if the operation was successful.
463  *
464  * Since: 0.10.36
465  */
466 gboolean
467 gst_ghost_pad_internal_activate_push_default (GstPad * pad, gboolean active)
468 {
469   gboolean ret;
470   GstPad *other;
471
472   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
473
474   GST_LOG_OBJECT (pad, "%sactivate push on %s:%s, we're ok",
475       (active ? "" : "de"), GST_DEBUG_PAD_NAME (pad));
476
477   /* in both cases (SRC and SINK) we activate just the internal pad. The targets
478    * will be activated later (or already in case of a ghost sinkpad). */
479   other = GST_PROXY_PAD_INTERNAL (pad);
480   ret = gst_pad_activate_push (other, active);
481
482   return ret;
483 }
484
485 /**
486  * gst_ghost_pad_internal_activate_pull_default:
487  * @pad: the #GstPad to activate or deactivate.
488  * @active: whether the pad should be active or not.
489  *
490  * Invoke the default activate pull function of a proxy pad that is
491  * owned by a ghost pad.
492  *
493  * Returns: %TRUE if the operation was successful.
494  *
495  * Since: 0.10.36
496  */
497 gboolean
498 gst_ghost_pad_internal_activate_pull_default (GstPad * pad, gboolean active)
499 {
500   gboolean ret;
501   GstPad *other;
502
503   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
504
505   GST_LOG_OBJECT (pad, "%sactivate pull on %s:%s", (active ? "" : "de"),
506       GST_DEBUG_PAD_NAME (pad));
507
508   if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
509     /* we are activated in pull mode by our peer element, which is a sinkpad
510      * that wants to operate in pull mode. This activation has to propagate
511      * upstream through the pipeline. We call the internal activation function,
512      * which will trigger gst_ghost_pad_activate_pull_default, which propagates even
513      * further upstream */
514     GST_LOG_OBJECT (pad, "pad is src, activate internal");
515     other = GST_PROXY_PAD_INTERNAL (pad);
516     ret = gst_pad_activate_pull (other, active);
517   } else if (G_LIKELY ((other = gst_pad_get_peer (pad)))) {
518     /* We are SINK, the ghostpad is SRC, we propagate the activation upstream
519      * since we hold a pointer to the upstream peer. */
520     GST_LOG_OBJECT (pad, "activating peer");
521     ret = gst_pad_activate_pull (other, active);
522     gst_object_unref (other);
523   } else {
524     /* this is failure, we can't activate pull if there is no peer */
525     GST_LOG_OBJECT (pad, "not src and no peer, failing");
526     ret = FALSE;
527   }
528
529   return ret;
530 }
531
532 /**
533  * gst_ghost_pad_activate_push_default:
534  * @pad: the #GstPad to activate or deactivate.
535  * @active: whether the pad should be active or not.
536  *
537  * Invoke the default activate push function of a ghost pad.
538  *
539  * Returns: %TRUE if the operation was successful.
540  *
541  * Since: 0.10.36
542  */
543 gboolean
544 gst_ghost_pad_activate_push_default (GstPad * pad, gboolean active)
545 {
546   gboolean ret;
547   GstPad *other;
548
549   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), FALSE);
550
551   GST_LOG_OBJECT (pad, "%sactivate push on %s:%s, proxy internal",
552       (active ? "" : "de"), GST_DEBUG_PAD_NAME (pad));
553
554   /* just activate the internal pad */
555   other = GST_PROXY_PAD_INTERNAL (pad);
556   ret = gst_pad_activate_push (other, active);
557
558   return ret;
559 }
560
561 /**
562  * gst_ghost_pad_activate_pull_default:
563  * @pad: the #GstPad to activate or deactivate.
564  * @active: whether the pad should be active or not.
565  *
566  * Invoke the default activate pull function of a ghost pad.
567  *
568  * Returns: %TRUE if the operation was successful.
569  *
570  * Since: 0.10.36
571  */
572 gboolean
573 gst_ghost_pad_activate_pull_default (GstPad * pad, gboolean active)
574 {
575   gboolean ret;
576   GstPad *other;
577
578   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), FALSE);
579
580   GST_LOG_OBJECT (pad, "%sactivate pull on %s:%s", (active ? "" : "de"),
581       GST_DEBUG_PAD_NAME (pad));
582
583   if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
584     /* the ghostpad is SRC and activated in pull mode by its peer, call the
585      * activation function of the internal pad to propagate the activation
586      * upstream */
587     GST_LOG_OBJECT (pad, "pad is src, activate internal");
588     other = GST_PROXY_PAD_INTERNAL (pad);
589     ret = gst_pad_activate_pull (other, active);
590   } else if (G_LIKELY ((other = gst_pad_get_peer (pad)))) {
591     /* We are SINK and activated by the internal pad, propagate activation
592      * upstream because we hold a ref to the upstream peer */
593     GST_LOG_OBJECT (pad, "activating peer");
594     ret = gst_pad_activate_pull (other, active);
595     gst_object_unref (other);
596   } else {
597     /* no peer, we fail */
598     GST_LOG_OBJECT (pad, "pad not src and no peer, failing");
599     ret = FALSE;
600   }
601
602   return ret;
603 }
604
605 /**
606  * gst_ghost_pad_link_default:
607  * @pad: the #GstPad to link.
608  * @peer: the #GstPad peer
609  *
610  * Invoke the default link function of a ghost pad.
611  *
612  * Returns: #GstPadLinkReturn of the operation
613  *
614  * Since: 0.10.36
615  */
616 GstPadLinkReturn
617 gst_ghost_pad_link_default (GstPad * pad, GstPad * peer)
618 {
619   GstPadLinkReturn ret;
620
621   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), GST_PAD_LINK_REFUSED);
622   g_return_val_if_fail (GST_IS_PAD (peer), GST_PAD_LINK_REFUSED);
623
624   GST_DEBUG_OBJECT (pad, "linking ghostpad");
625
626   ret = GST_PAD_LINK_OK;
627   /* if we are a source pad, we should call the peer link function
628    * if the peer has one, see design docs. */
629   if (GST_PAD_IS_SRC (pad)) {
630     if (GST_PAD_LINKFUNC (peer)) {
631       ret = GST_PAD_LINKFUNC (peer) (peer, pad);
632       if (ret != GST_PAD_LINK_OK)
633         GST_DEBUG_OBJECT (pad, "linking failed");
634     }
635   }
636   return ret;
637 }
638
639 /**
640  * gst_ghost_pad_unlink_default:
641  * @pad: the #GstPad to link.
642  *
643  * Invoke the default unlink function of a ghost pad.
644  *
645  * Since: 0.10.36
646  */
647 void
648 gst_ghost_pad_unlink_default (GstPad * pad)
649 {
650   g_return_if_fail (GST_IS_GHOST_PAD (pad));
651
652   GST_DEBUG_OBJECT (pad, "unlinking ghostpad");
653 }
654
655 static void
656 gst_ghost_pad_class_init (GstGhostPadClass * klass)
657 {
658   GObjectClass *gobject_class = (GObjectClass *) klass;
659
660   g_type_class_add_private (klass, sizeof (GstGhostPadPrivate));
661
662   gobject_class->dispose = gst_ghost_pad_dispose;
663
664   GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_pull_default);
665   GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_push_default);
666   GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_link_default);
667 }
668
669 static void
670 gst_ghost_pad_init (GstGhostPad * pad)
671 {
672   GST_GHOST_PAD_PRIVATE (pad) = G_TYPE_INSTANCE_GET_PRIVATE (pad,
673       GST_TYPE_GHOST_PAD, GstGhostPadPrivate);
674
675   gst_pad_set_activatepull_function (GST_PAD_CAST (pad),
676       gst_ghost_pad_activate_pull_default);
677   gst_pad_set_activatepush_function (GST_PAD_CAST (pad),
678       gst_ghost_pad_activate_push_default);
679 }
680
681 static void
682 gst_ghost_pad_dispose (GObject * object)
683 {
684   GstPad *pad;
685   GstPad *internal;
686   GstPad *peer;
687
688   pad = GST_PAD (object);
689
690   GST_DEBUG_OBJECT (pad, "dispose");
691
692   gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL);
693
694   /* Unlink here so that gst_pad_dispose doesn't. That would lead to a call to
695    * gst_ghost_pad_unlink_default when the ghost pad is in an inconsistent state */
696   peer = gst_pad_get_peer (pad);
697   if (peer) {
698     if (GST_PAD_IS_SRC (pad))
699       gst_pad_unlink (pad, peer);
700     else
701       gst_pad_unlink (peer, pad);
702
703     gst_object_unref (peer);
704   }
705
706   GST_OBJECT_LOCK (pad);
707   internal = GST_PROXY_PAD_INTERNAL (pad);
708
709   gst_pad_set_activatepull_function (internal, NULL);
710   gst_pad_set_activatepush_function (internal, NULL);
711
712   /* disposes of the internal pad, since the ghostpad is the only possible object
713    * that has a refcount on the internal pad. */
714   gst_object_unparent (GST_OBJECT_CAST (internal));
715   GST_PROXY_PAD_INTERNAL (pad) = NULL;
716
717   GST_OBJECT_UNLOCK (pad);
718
719   G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object);
720 }
721
722 /**
723  * gst_ghost_pad_construct:
724  * @gpad: the newly allocated ghost pad
725  *
726  * Finish initialization of a newly allocated ghost pad.
727  *
728  * This function is most useful in language bindings and when subclassing
729  * #GstGhostPad; plugin and application developers normally will not call this
730  * function. Call this function directly after a call to g_object_new
731  * (GST_TYPE_GHOST_PAD, "direction", @dir, ..., NULL).
732  *
733  * Returns: %TRUE if the construction succeeds, %FALSE otherwise.
734  *
735  * Since: 0.10.22
736  */
737 gboolean
738 gst_ghost_pad_construct (GstGhostPad * gpad)
739 {
740   GstPadDirection dir, otherdir;
741   GstPadTemplate *templ;
742   GstPad *pad, *internal;
743
744   g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
745   g_return_val_if_fail (GST_GHOST_PAD_PRIVATE (gpad)->constructed == FALSE,
746       FALSE);
747
748   g_object_get (gpad, "direction", &dir, "template", &templ, NULL);
749
750   g_return_val_if_fail (dir != GST_PAD_UNKNOWN, FALSE);
751
752   pad = GST_PAD (gpad);
753
754   /* Set directional padfunctions for ghostpad */
755   if (dir == GST_PAD_SINK) {
756     gst_pad_set_chain_function (pad, gst_proxy_pad_chain_default);
757     gst_pad_set_chain_list_function (pad, gst_proxy_pad_chain_list_default);
758   } else {
759     gst_pad_set_getrange_function (pad, gst_proxy_pad_getrange_default);
760   }
761
762   /* link/unlink functions */
763   gst_pad_set_link_function (pad, gst_ghost_pad_link_default);
764   gst_pad_set_unlink_function (pad, gst_ghost_pad_unlink_default);
765
766   /* INTERNAL PAD, it always exists and is child of the ghostpad */
767   otherdir = (dir == GST_PAD_SRC) ? GST_PAD_SINK : GST_PAD_SRC;
768   if (templ) {
769     internal =
770         g_object_new (GST_TYPE_PROXY_PAD, "name", NULL,
771         "direction", otherdir, "template", templ, NULL);
772     /* release ref obtained via g_object_get */
773     gst_object_unref (templ);
774   } else {
775     internal =
776         g_object_new (GST_TYPE_PROXY_PAD, "name", NULL,
777         "direction", otherdir, NULL);
778   }
779   GST_PAD_UNSET_FLUSHING (internal);
780
781   /* Set directional padfunctions for internal pad */
782   if (dir == GST_PAD_SRC) {
783     gst_pad_set_chain_function (internal, gst_proxy_pad_chain_default);
784     gst_pad_set_chain_list_function (internal,
785         gst_proxy_pad_chain_list_default);
786   } else {
787     gst_pad_set_getrange_function (internal, gst_proxy_pad_getrange_default);
788   }
789
790   GST_OBJECT_LOCK (pad);
791
792   /* now make the ghostpad a parent of the internal pad */
793   if (!gst_object_set_parent (GST_OBJECT_CAST (internal),
794           GST_OBJECT_CAST (pad)))
795     goto parent_failed;
796
797   /* The ghostpad is the parent of the internal pad and is the only object that
798    * can have a refcount on the internal pad.
799    * At this point, the GstGhostPad has a refcount of 1, and the internal pad has
800    * a refcount of 1.
801    * When the refcount of the GstGhostPad drops to 0, the ghostpad will dispose
802    * its refcount on the internal pad in the dispose method by un-parenting it.
803    * This is why we don't take extra refcounts in the assignments below
804    */
805   GST_PROXY_PAD_INTERNAL (pad) = internal;
806   GST_PROXY_PAD_INTERNAL (internal) = pad;
807
808   /* special activation functions for the internal pad */
809   gst_pad_set_activatepull_function (internal,
810       gst_ghost_pad_internal_activate_pull_default);
811   gst_pad_set_activatepush_function (internal,
812       gst_ghost_pad_internal_activate_push_default);
813
814   GST_OBJECT_UNLOCK (pad);
815
816   GST_GHOST_PAD_PRIVATE (gpad)->constructed = TRUE;
817   return TRUE;
818
819   /* ERRORS */
820 parent_failed:
821   {
822     GST_WARNING_OBJECT (gpad, "Could not set internal pad %s:%s",
823         GST_DEBUG_PAD_NAME (internal));
824     g_critical ("Could not set internal pad %s:%s",
825         GST_DEBUG_PAD_NAME (internal));
826     GST_OBJECT_UNLOCK (pad);
827     gst_object_unref (internal);
828     return FALSE;
829   }
830 }
831
832 static GstPad *
833 gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir,
834     GstPadTemplate * templ)
835 {
836   GstGhostPad *ret;
837
838   g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL);
839
840   /* OBJECT CREATION */
841   if (templ) {
842     ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name,
843         "direction", dir, "template", templ, NULL);
844   } else {
845     ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name,
846         "direction", dir, NULL);
847   }
848
849   if (!gst_ghost_pad_construct (ret))
850     goto construct_failed;
851
852   return GST_PAD_CAST (ret);
853
854 construct_failed:
855   /* already logged */
856   gst_object_unref (ret);
857   return NULL;
858 }
859
860 /**
861  * gst_ghost_pad_new_no_target:
862  * @name: (allow-none): the name of the new pad, or NULL to assign a default name.
863  * @dir: the direction of the ghostpad
864  *
865  * Create a new ghostpad without a target with the given direction.
866  * A target can be set on the ghostpad later with the
867  * gst_ghost_pad_set_target() function.
868  *
869  * The created ghostpad will not have a padtemplate.
870  *
871  * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
872  */
873 GstPad *
874 gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
875 {
876   GstPad *ret;
877
878   g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL);
879
880   GST_LOG ("name:%s, direction:%d", GST_STR_NULL (name), dir);
881
882   ret = gst_ghost_pad_new_full (name, dir, NULL);
883
884   return ret;
885 }
886
887 /**
888  * gst_ghost_pad_new:
889  * @name: (allow-none): the name of the new pad, or NULL to assign a default name
890  * @target: (transfer none): the pad to ghost.
891  *
892  * Create a new ghostpad with @target as the target. The direction will be taken
893  * from the target pad. @target must be unlinked.
894  *
895  * Will ref the target.
896  *
897  * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
898  */
899 GstPad *
900 gst_ghost_pad_new (const gchar * name, GstPad * target)
901 {
902   GstPad *ret;
903
904   g_return_val_if_fail (GST_IS_PAD (target), NULL);
905   g_return_val_if_fail (!gst_pad_is_linked (target), NULL);
906
907   GST_LOG ("name:%s, target:%s:%s", GST_STR_NULL (name),
908       GST_DEBUG_PAD_NAME (target));
909
910   if ((ret = gst_ghost_pad_new_no_target (name, GST_PAD_DIRECTION (target))))
911     if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
912       goto set_target_failed;
913
914   return ret;
915
916   /* ERRORS */
917 set_target_failed:
918   {
919     GST_WARNING_OBJECT (ret, "failed to set target %s:%s",
920         GST_DEBUG_PAD_NAME (target));
921     gst_object_unref (ret);
922     return NULL;
923   }
924 }
925
926 /**
927  * gst_ghost_pad_new_from_template:
928  * @name: (allow-none): the name of the new pad, or NULL to assign a default name.
929  * @target: (transfer none): the pad to ghost.
930  * @templ: (transfer none): the #GstPadTemplate to use on the ghostpad.
931  *
932  * Create a new ghostpad with @target as the target. The direction will be taken
933  * from the target pad. The template used on the ghostpad will be @template.
934  *
935  * Will ref the target.
936  *
937  * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
938  *
939  * Since: 0.10.10
940  */
941
942 GstPad *
943 gst_ghost_pad_new_from_template (const gchar * name, GstPad * target,
944     GstPadTemplate * templ)
945 {
946   GstPad *ret;
947
948   g_return_val_if_fail (GST_IS_PAD (target), NULL);
949   g_return_val_if_fail (!gst_pad_is_linked (target), NULL);
950   g_return_val_if_fail (templ != NULL, NULL);
951   g_return_val_if_fail (GST_PAD_TEMPLATE_DIRECTION (templ) ==
952       GST_PAD_DIRECTION (target), NULL);
953
954   GST_LOG ("name:%s, target:%s:%s, templ:%p", GST_STR_NULL (name),
955       GST_DEBUG_PAD_NAME (target), templ);
956
957   if ((ret = gst_ghost_pad_new_full (name, GST_PAD_DIRECTION (target), templ)))
958     if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
959       goto set_target_failed;
960
961   return ret;
962
963   /* ERRORS */
964 set_target_failed:
965   {
966     GST_WARNING_OBJECT (ret, "failed to set target %s:%s",
967         GST_DEBUG_PAD_NAME (target));
968     gst_object_unref (ret);
969     return NULL;
970   }
971 }
972
973 /**
974  * gst_ghost_pad_new_no_target_from_template:
975  * @name: (allow-none): the name of the new pad, or NULL to assign a default name
976  * @templ: (transfer none): the #GstPadTemplate to create the ghostpad from.
977  *
978  * Create a new ghostpad based on @templ, without setting a target. The
979  * direction will be taken from the @templ.
980  *
981  * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
982  *
983  * Since: 0.10.10
984  */
985 GstPad *
986 gst_ghost_pad_new_no_target_from_template (const gchar * name,
987     GstPadTemplate * templ)
988 {
989   GstPad *ret;
990
991   g_return_val_if_fail (templ != NULL, NULL);
992
993   ret =
994       gst_ghost_pad_new_full (name, GST_PAD_TEMPLATE_DIRECTION (templ), templ);
995
996   return ret;
997 }
998
999 /**
1000  * gst_ghost_pad_get_target:
1001  * @gpad: the #GstGhostPad
1002  *
1003  * Get the target pad of @gpad. Unref target pad after usage.
1004  *
1005  * Returns: (transfer full): the target #GstPad, can be NULL if the ghostpad
1006  * has no target set. Unref target pad after usage.
1007  */
1008 GstPad *
1009 gst_ghost_pad_get_target (GstGhostPad * gpad)
1010 {
1011   GstPad *ret;
1012
1013   g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), NULL);
1014
1015   ret = gst_proxy_pad_get_target (GST_PAD_CAST (gpad));
1016
1017   GST_DEBUG_OBJECT (gpad, "get target %s:%s", GST_DEBUG_PAD_NAME (ret));
1018
1019   return ret;
1020 }
1021
1022 /**
1023  * gst_ghost_pad_set_target:
1024  * @gpad: the #GstGhostPad
1025  * @newtarget: (transfer none) (allow-none): the new pad target
1026  *
1027  * Set the new target of the ghostpad @gpad. Any existing target
1028  * is unlinked and links to the new target are established. if @newtarget is
1029  * NULL the target will be cleared.
1030  *
1031  * Returns: (transfer full): TRUE if the new target could be set. This function
1032  *     can return FALSE when the internal pads could not be linked.
1033  */
1034 gboolean
1035 gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
1036 {
1037   GstPad *internal;
1038   GstPad *oldtarget;
1039   GstPadLinkReturn lret;
1040
1041   g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
1042   g_return_val_if_fail (GST_PAD_CAST (gpad) != newtarget, FALSE);
1043   g_return_val_if_fail (newtarget != GST_PROXY_PAD_INTERNAL (gpad), FALSE);
1044
1045   /* no need for locking, the internal pad's lifecycle is directly linked to the
1046    * ghostpad's */
1047   internal = GST_PROXY_PAD_INTERNAL (gpad);
1048
1049   if (newtarget)
1050     GST_DEBUG_OBJECT (gpad, "set target %s:%s", GST_DEBUG_PAD_NAME (newtarget));
1051   else
1052     GST_DEBUG_OBJECT (gpad, "clearing target");
1053
1054   /* clear old target */
1055   GST_OBJECT_LOCK (gpad);
1056   if ((oldtarget = GST_PROXY_PAD_TARGET (gpad))) {
1057     GST_OBJECT_UNLOCK (gpad);
1058
1059     /* unlink internal pad */
1060     if (GST_PAD_IS_SRC (internal))
1061       gst_pad_unlink (internal, oldtarget);
1062     else
1063       gst_pad_unlink (oldtarget, internal);
1064   } else {
1065     GST_OBJECT_UNLOCK (gpad);
1066   }
1067
1068   if (newtarget) {
1069     /* and link to internal pad without any checks */
1070     GST_DEBUG_OBJECT (gpad, "connecting internal pad to target");
1071
1072     if (GST_PAD_IS_SRC (internal))
1073       lret =
1074           gst_pad_link_full (internal, newtarget, GST_PAD_LINK_CHECK_NOTHING);
1075     else
1076       lret =
1077           gst_pad_link_full (newtarget, internal, GST_PAD_LINK_CHECK_NOTHING);
1078
1079     if (lret != GST_PAD_LINK_OK)
1080       goto link_failed;
1081   }
1082
1083   return TRUE;
1084
1085   /* ERRORS */
1086 link_failed:
1087   {
1088     GST_WARNING_OBJECT (gpad, "could not link internal and target, reason:%d",
1089         lret);
1090     return FALSE;
1091   }
1092 }