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