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