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