source: trunk/third/gstreamer/gst/gstpad.c @ 21448

Revision 21448, 126.3 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21447, which included commits to RCS files with non-trunk default branches.
Line 
1/* GStreamer
2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 *                    2000 Wim Taymans <wtay@chello.be>
4 *
5 * gstpad.c: Pads for linking elements together
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23#include "gst_private.h"
24
25#include "gstpad.h"
26#include "gstmarshal.h"
27#include "gstutils.h"
28#include "gstelement.h"
29#include "gstbin.h"
30#include "gstscheduler.h"
31#include "gstevent.h"
32#include "gstinfo.h"
33#include "gsterror.h"
34#include "gstvalue.h"
35
36GST_DEBUG_CATEGORY_STATIC (debug_dataflow);
37#define DEBUG_DATA(obj,data,notice) G_STMT_START{\
38  if (!data) { \
39    GST_CAT_DEBUG_OBJECT (debug_dataflow, obj, "NULL data value"); \
40  } else if (GST_IS_EVENT (data)) { \
41    GST_CAT_DEBUG_OBJECT (debug_dataflow, obj, "%s event %p (type %d, refcount %d)", notice, data, \
42        GST_EVENT_TYPE (data), GST_DATA_REFCOUNT_VALUE (data)); \
43  } else { \
44    GST_CAT_LOG_OBJECT (debug_dataflow, obj, "%s buffer %p (size %u, refcount %d)", notice, data, \
45        GST_BUFFER_SIZE (data), GST_BUFFER_REFCOUNT_VALUE (data)); \
46  } \
47}G_STMT_END
48#define GST_CAT_DEFAULT GST_CAT_PADS
49
50struct _GstPadLink
51{
52  GType type;
53
54  gboolean bla;
55  gboolean srcnotify;
56  gboolean sinknotify;
57
58  GstPad *srcpad;
59  GstPad *sinkpad;
60
61  GstCaps *srccaps;
62  GstCaps *sinkcaps;
63  GstCaps *filtercaps;
64  GstCaps *caps;
65
66  GstPadFixateFunction app_fixate;
67
68  gboolean engaged;
69  GstData *temp_store;          /* used only when we invented a DISCONT */
70};
71
72enum
73{
74  TEMPL_PAD_CREATED,
75  /* FILL ME */
76  TEMPL_LAST_SIGNAL
77};
78
79static GstObject *padtemplate_parent_class = NULL;
80static guint gst_pad_template_signals[TEMPL_LAST_SIGNAL] = { 0 };
81
82GType _gst_pad_type = 0;
83
84/***** Start with the base GstPad class *****/
85static void gst_pad_class_init (GstPadClass * klass);
86static void gst_pad_init (GstPad * pad);
87static void gst_pad_dispose (GObject * object);
88
89static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ);
90static GstCaps *_gst_pad_default_fixate_func (GstPad * pad,
91    const GstCaps * caps);
92
93static gboolean gst_pad_link_try (GstPadLink * link);
94static void gst_pad_link_free (GstPadLink * link);
95
96#ifndef GST_DISABLE_LOADSAVE
97static xmlNodePtr gst_pad_save_thyself (GstObject * object, xmlNodePtr parent);
98#endif
99
100static GstObject *pad_parent_class = NULL;
101
102GType
103gst_pad_get_type (void)
104{
105  if (!_gst_pad_type) {
106    static const GTypeInfo pad_info = {
107      sizeof (GstPadClass), NULL, NULL,
108      (GClassInitFunc) gst_pad_class_init, NULL, NULL,
109      sizeof (GstPad),
110      0,
111      (GInstanceInitFunc) gst_pad_init, NULL
112    };
113
114    _gst_pad_type = g_type_register_static (GST_TYPE_OBJECT, "GstPad",
115        &pad_info, 0);
116
117    GST_DEBUG_CATEGORY_INIT (debug_dataflow, "GST_DATAFLOW",
118        GST_DEBUG_BOLD | GST_DEBUG_FG_GREEN, "dataflow inside pads");
119  }
120  return _gst_pad_type;
121}
122
123static void
124gst_pad_class_init (GstPadClass * klass)
125{
126  GObjectClass *gobject_class;
127
128  gobject_class = (GObjectClass *) klass;
129
130  pad_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
131
132  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose);
133}
134
135static void
136gst_pad_init (GstPad * pad)
137{
138  /* all structs are initialized to NULL by glib */
139}
140static void
141gst_pad_dispose (GObject * object)
142{
143  GstPad *pad = GST_PAD (object);
144
145  gst_pad_set_pad_template (pad, NULL);
146
147  G_OBJECT_CLASS (pad_parent_class)->dispose (object);
148}
149
150
151
152/***** Then do the Real Pad *****/
153/* Pad signals and args */
154enum
155{
156  REAL_LINKED,
157  REAL_UNLINKED,
158  REAL_FIXATE,
159  /* FILL ME */
160  REAL_LAST_SIGNAL
161};
162
163enum
164{
165  REAL_ARG_0,
166  REAL_ARG_CAPS,
167  REAL_ARG_ACTIVE
168      /* FILL ME */
169};
170
171static void gst_real_pad_class_init (GstRealPadClass * klass);
172static void gst_real_pad_init (GstRealPad * pad);
173static void gst_real_pad_dispose (GObject * object);
174
175static gboolean _gst_real_pad_fixate_accumulator (GSignalInvocationHint * ihint,
176    GValue * return_accu, const GValue * handler_return, gpointer dummy);
177static void gst_real_pad_set_property (GObject * object, guint prop_id,
178    const GValue * value, GParamSpec * pspec);
179static void gst_real_pad_get_property (GObject * object, guint prop_id,
180    GValue * value, GParamSpec * pspec);
181
182GType _gst_real_pad_type = 0;
183
184static GstPad *real_pad_parent_class = NULL;
185static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
186
187GType
188gst_real_pad_get_type (void)
189{
190  if (!_gst_real_pad_type) {
191    static const GTypeInfo pad_info = {
192      sizeof (GstRealPadClass), NULL, NULL,
193      (GClassInitFunc) gst_real_pad_class_init, NULL, NULL,
194      sizeof (GstRealPad),
195      0,
196      (GInstanceInitFunc) gst_real_pad_init, NULL
197    };
198
199    _gst_real_pad_type = g_type_register_static (GST_TYPE_PAD, "GstRealPad",
200        &pad_info, 0);
201  }
202  return _gst_real_pad_type;
203}
204
205static void
206gst_real_pad_class_init (GstRealPadClass * klass)
207{
208  GObjectClass *gobject_class;
209  GstObjectClass *gstobject_class;
210
211  gobject_class = (GObjectClass *) klass;
212  gstobject_class = (GstObjectClass *) klass;
213
214  real_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
215
216  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_real_pad_dispose);
217  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_real_pad_set_property);
218  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_real_pad_get_property);
219
220  gst_real_pad_signals[REAL_LINKED] =
221      g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
222      G_STRUCT_OFFSET (GstRealPadClass, linked), NULL, NULL,
223      gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
224  gst_real_pad_signals[REAL_UNLINKED] =
225      g_signal_new ("unlinked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
226      G_STRUCT_OFFSET (GstRealPadClass, unlinked), NULL, NULL,
227      gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
228  gst_real_pad_signals[REAL_FIXATE] =
229      g_signal_new ("fixate", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
230      G_STRUCT_OFFSET (GstRealPadClass, appfixatefunc),
231      _gst_real_pad_fixate_accumulator, NULL,
232      gst_marshal_BOXED__BOXED, GST_TYPE_CAPS, 1,
233      GST_TYPE_CAPS | G_SIGNAL_TYPE_STATIC_SCOPE);
234
235  g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_ACTIVE,
236      g_param_spec_boolean ("active", "Active", "Whether the pad is active.",
237          TRUE, G_PARAM_READWRITE));
238  g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_CAPS,
239      g_param_spec_boxed ("caps", "Caps", "The capabilities of the pad",
240          GST_TYPE_CAPS, G_PARAM_READABLE));
241
242#ifndef GST_DISABLE_LOADSAVE
243  gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_pad_save_thyself);
244#endif
245  gstobject_class->path_string_separator = ".";
246}
247
248static gboolean
249_gst_real_pad_fixate_accumulator (GSignalInvocationHint * ihint,
250    GValue * return_accu, const GValue * handler_return, gpointer dummy)
251{
252  if (gst_value_get_caps (handler_return)) {
253    g_value_copy (handler_return, return_accu);
254    /* stop emission if something was returned */
255    return FALSE;
256  }
257  return TRUE;
258}
259
260static void
261gst_real_pad_init (GstRealPad * pad)
262{
263  pad->direction = GST_PAD_UNKNOWN;
264  pad->peer = NULL;
265
266  pad->chainfunc = NULL;
267  pad->getfunc = NULL;
268
269  pad->chainhandler = NULL;
270  pad->gethandler = NULL;
271
272  pad->ghostpads = NULL;
273  pad->caps = NULL;
274
275  pad->linkfunc = NULL;
276  pad->getcapsfunc = NULL;
277
278  pad->eventfunc = gst_pad_event_default;
279  pad->convertfunc = gst_pad_convert_default;
280  pad->queryfunc = gst_pad_query_default;
281  pad->intlinkfunc = gst_pad_get_internal_links_default;
282
283  pad->eventmaskfunc = gst_pad_get_event_masks_default;
284  pad->formatsfunc = gst_pad_get_formats_default;
285  pad->querytypefunc = gst_pad_get_query_types_default;
286
287  GST_FLAG_SET (pad, GST_PAD_DISABLED);
288  GST_FLAG_UNSET (pad, GST_PAD_NEGOTIATING);
289
290  gst_probe_dispatcher_init (&pad->probedisp);
291}
292
293static void
294gst_real_pad_set_property (GObject * object, guint prop_id,
295    const GValue * value, GParamSpec * pspec)
296{
297  g_return_if_fail (GST_IS_PAD (object));
298
299  switch (prop_id) {
300    case REAL_ARG_ACTIVE:
301      gst_pad_set_active (GST_PAD (object), g_value_get_boolean (value));
302      break;
303    default:
304      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
305      break;
306  }
307}
308
309static void
310gst_real_pad_get_property (GObject * object, guint prop_id,
311    GValue * value, GParamSpec * pspec)
312{
313  g_return_if_fail (GST_IS_PAD (object));
314
315  switch (prop_id) {
316    case REAL_ARG_ACTIVE:
317      g_value_set_boolean (value, !GST_FLAG_IS_SET (object, GST_PAD_DISABLED));
318      break;
319    case REAL_ARG_CAPS:
320      g_value_set_boxed (value, GST_PAD_CAPS (GST_REAL_PAD (object)));
321      break;
322    default:
323      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
324      break;
325  }
326}
327
328/* FIXME-0.9: Replace these custom functions with proper inheritance via _init
329   functions and object properties */
330/**
331 * gst_pad_custom_new:
332 * @type: the #Gtype of the pad.
333 * @name: the name of the new pad.
334 * @direction: the #GstPadDirection of the pad.
335 *
336 * Creates a new pad with the given name and type in the given direction.
337 * If name is NULL, a guaranteed unique name (across all pads)
338 * will be assigned.
339 *
340 * Returns: a new #GstPad, or NULL in case of an error.
341 */
342GstPad *
343gst_pad_custom_new (GType type, const gchar * name, GstPadDirection direction)
344{
345  GstRealPad *pad;
346
347  g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
348
349  pad = g_object_new (type, NULL);
350  gst_object_set_name (GST_OBJECT (pad), name);
351  GST_RPAD_DIRECTION (pad) = direction;
352
353  return GST_PAD (pad);
354}
355
356/**
357 * gst_pad_new:
358 * @name: the name of the new pad.
359 * @direction: the #GstPadDirection of the pad.
360 *
361 * Creates a new real pad with the given name in the given direction.
362 * If name is NULL, a guaranteed unique name (across all pads)
363 * will be assigned.
364 *
365 * Returns: a new #GstPad, or NULL in case of an error.
366 */
367GstPad *
368gst_pad_new (const gchar * name, GstPadDirection direction)
369{
370  return gst_pad_custom_new (gst_real_pad_get_type (), name, direction);
371}
372
373/**
374 * gst_pad_custom_new_from_template:
375 * @type: the custom #GType of the pad.
376 * @templ: the #GstPadTemplate to instantiate from.
377 * @name: the name of the new pad.
378 *
379 * Creates a new custom pad with the given name from the given template.
380 * If name is NULL, a guaranteed unique name (across all pads)
381 * will be assigned.
382 *
383 * Returns: a new #GstPad, or NULL in case of an error.
384 */
385GstPad *
386gst_pad_custom_new_from_template (GType type, GstPadTemplate * templ,
387    const gchar * name)
388{
389  GstPad *pad;
390
391  g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
392
393  pad = gst_pad_custom_new (type, name, templ->direction);
394  gst_pad_set_pad_template (pad, templ);
395
396  return pad;
397}
398
399/**
400 * gst_pad_new_from_template:
401 * @templ: the pad template to use
402 * @name: the name of the element
403 *
404 * Creates a new real pad with the given name from the given template.
405 * If name is NULL, a guaranteed unique name (across all pads)
406 * will be assigned.
407 *
408 * Returns: a new #GstPad, or NULL in case of an error.
409 */
410GstPad *
411gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name)
412{
413  return gst_pad_custom_new_from_template (gst_real_pad_get_type (),
414      templ, name);
415}
416
417/* FIXME 0.9: GST_PAD_UNKNOWN needs to die! */
418/**
419 * gst_pad_get_direction:
420 * @pad: a #GstPad to get the direction of.
421 *
422 * Gets the direction of the pad.
423 *
424 * Returns: the #GstPadDirection of the pad.
425 */
426GstPadDirection
427gst_pad_get_direction (GstPad * pad)
428{
429  g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
430
431  if (GST_IS_REAL_PAD (pad))
432    return GST_PAD_DIRECTION (pad);
433  else
434    return GST_PAD_UNKNOWN;
435}
436
437/**
438 * gst_pad_set_active:
439 * @pad: the #GstPad to activate or deactivate.
440 * @active: TRUE to activate the pad.
441 *
442 * Activates or deactivates the given pad.
443 */
444void
445gst_pad_set_active (GstPad * pad, gboolean active)
446{
447  GstRealPad *realpad;
448  gboolean old;
449  GstPadLink *link;
450
451  g_return_if_fail (GST_IS_PAD (pad));
452
453  old = GST_PAD_IS_ACTIVE (pad);
454
455  if (old == active)
456    return;
457
458  realpad = GST_PAD_REALIZE (pad);
459
460  if (active) {
461    GST_CAT_DEBUG (GST_CAT_PADS, "activating pad %s:%s",
462        GST_DEBUG_PAD_NAME (realpad));
463    GST_FLAG_UNSET (realpad, GST_PAD_DISABLED);
464  } else {
465    GST_CAT_DEBUG (GST_CAT_PADS, "de-activating pad %s:%s",
466        GST_DEBUG_PAD_NAME (realpad));
467    GST_FLAG_SET (realpad, GST_PAD_DISABLED);
468  }
469  link = GST_RPAD_LINK (realpad);
470  if (link) {
471    if (link->temp_store) {
472      GST_CAT_INFO (GST_CAT_PADS,
473          "deleting cached data %p from bufpen of pad %s:%s", link->temp_store,
474          GST_DEBUG_PAD_NAME (realpad));
475      gst_data_unref (link->temp_store);
476      link->temp_store = NULL;
477    }
478  }
479
480  g_object_notify (G_OBJECT (realpad), "active");
481}
482
483/**
484 * gst_pad_set_active_recursive:
485 * @pad: the #GstPad to activate or deactivate.
486 * @active: TRUE to activate the pad.
487 *
488 * Activates or deactivates the given pad and all internally linked
489 * pads upstream until it finds an element with multiple source pads.
490 */
491void
492gst_pad_set_active_recursive (GstPad * pad, gboolean active)
493{
494  GstElement *parent;
495  const GList *int_links;
496
497  g_return_if_fail (GST_IS_PAD (pad));
498  g_return_if_fail (GST_PAD_IS_SRC (pad));
499
500  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
501      "Recursively %s pad %s:%s", active ? "activating" : "deactivating",
502      GST_DEBUG_PAD_NAME (pad));
503
504  gst_pad_set_active (pad, active);
505
506  /* If we have more than one sourcepad, then the other pads should
507   * possibly be kept active. FIXME: maybe we should recurse
508   * activation if any one pad is active and recurse deactivation
509   * if no single pad is active? */
510  parent = gst_pad_get_parent (pad);
511  if (!parent || parent->numsrcpads > 1)
512    return;
513
514  for (int_links = gst_pad_get_internal_links (pad);
515      int_links; int_links = g_list_next (int_links)) {
516    GstPad *sinkpad = GST_PAD (int_links->data);
517    GstPad *peer = GST_PAD_PEER (sinkpad);
518
519    GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, sinkpad,
520        "Recursing %s on pad %s:%s",
521        active ? "activation" : "deactivation", GST_DEBUG_PAD_NAME (sinkpad));
522
523    gst_pad_set_active (sinkpad, active);
524    if (peer)
525      gst_pad_set_active_recursive (peer, active);
526  }
527}
528
529/**
530 * gst_pad_is_active:
531 * @pad: the #GstPad to query
532 *
533 * Query if a pad is active
534 *
535 * Returns: TRUE if the pad is active.
536 */
537gboolean
538gst_pad_is_active (GstPad * pad)
539{
540  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
541
542  return !GST_FLAG_IS_SET (pad, GST_PAD_DISABLED);
543}
544
545/**
546 * gst_pad_set_name:
547 * @pad: a #GstPad to set the name of.
548 * @name: the name of the pad.
549 *
550 * Sets the name of a pad.  If name is NULL, then a guaranteed unique
551 * name will be assigned.
552 */
553void
554gst_pad_set_name (GstPad * pad, const gchar * name)
555{
556  g_return_if_fail (GST_IS_PAD (pad));
557
558  gst_object_set_name (GST_OBJECT (pad), name);
559}
560
561/* FIXME 0.9: This function must die */
562/**
563 * gst_pad_get_name:
564 * @pad: a #GstPad to get the name of.
565 *
566 * Gets the name of a pad.
567 *
568 * Returns: the name of the pad.  This is not a newly allocated pointer
569 * so you must not free it.
570 */
571const gchar *
572gst_pad_get_name (GstPad * pad)
573{
574  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
575
576  return GST_OBJECT_NAME (pad);
577}
578
579/**
580 * gst_pad_set_chain_function:
581 * @pad: a real sink #GstPad.
582 * @chain: the #GstPadChainFunction to set.
583 *
584 * Sets the given chain function for the pad. The chain function is called to
585 * process a #GstData input buffer.
586 */
587void
588gst_pad_set_chain_function (GstPad * pad, GstPadChainFunction chain)
589{
590  g_return_if_fail (GST_IS_REAL_PAD (pad));
591  g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK);
592
593  GST_RPAD_CHAINFUNC (pad) = chain;
594  GST_CAT_DEBUG (GST_CAT_PADS, "chainfunc for %s:%s set to %s",
595      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (chain));
596}
597
598/**
599 * gst_pad_set_get_function:
600 * @pad: a real source #GstPad.
601 * @get: the #GstPadGetFunction to set.
602 *
603 * Sets the given get function for the pad. The get function is called to
604 * produce a new #GstData to start the processing pipeline. Get functions cannot
605 * return %NULL.
606 */
607void
608gst_pad_set_get_function (GstPad * pad, GstPadGetFunction get)
609{
610  g_return_if_fail (GST_IS_REAL_PAD (pad));
611  g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
612
613  GST_RPAD_GETFUNC (pad) = get;
614
615  GST_CAT_DEBUG (GST_CAT_PADS, "getfunc for %s:%s  set to %s",
616      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (get));
617}
618
619/**
620 * gst_pad_set_event_function:
621 * @pad: a real source #GstPad.
622 * @event: the #GstPadEventFunction to set.
623 *
624 * Sets the given event handler for the pad.
625 */
626void
627gst_pad_set_event_function (GstPad * pad, GstPadEventFunction event)
628{
629  g_return_if_fail (GST_IS_REAL_PAD (pad));
630  g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC);
631
632  GST_RPAD_EVENTFUNC (pad) = event;
633
634  GST_CAT_DEBUG (GST_CAT_PADS, "eventfunc for %s:%s  set to %s",
635      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (event));
636}
637
638/**
639 * gst_pad_set_event_mask_function:
640 * @pad: a real #GstPad of either direction.
641 * @mask_func: the #GstPadEventMaskFunction to set.
642 *
643 * Sets the given event mask function for the pad.
644 */
645void
646gst_pad_set_event_mask_function (GstPad * pad,
647    GstPadEventMaskFunction mask_func)
648{
649  g_return_if_fail (GST_IS_REAL_PAD (pad));
650
651  GST_RPAD_EVENTMASKFUNC (pad) = mask_func;
652
653  GST_CAT_DEBUG (GST_CAT_PADS, "eventmaskfunc for %s:%s  set to %s",
654      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (mask_func));
655}
656
657/**
658 * gst_pad_get_event_masks:
659 * @pad: a #GstPad.
660 *
661 * Gets the array of eventmasks from the given pad.
662 *
663 * Returns: a zero-terminated array of #GstEventMask, or NULL if the pad does
664 * not have an event mask function.
665 */
666const GstEventMask *
667gst_pad_get_event_masks (GstPad * pad)
668{
669  GstRealPad *rpad;
670
671  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
672
673  rpad = GST_PAD_REALIZE (pad);
674
675  g_return_val_if_fail (rpad, NULL);
676
677  if (GST_RPAD_EVENTMASKFUNC (rpad))
678    return GST_RPAD_EVENTMASKFUNC (rpad) (GST_PAD (pad));
679
680  return NULL;
681}
682
683static gboolean
684gst_pad_get_event_masks_dispatcher (GstPad * pad, const GstEventMask ** data)
685{
686  *data = gst_pad_get_event_masks (pad);
687
688  return TRUE;
689}
690
691/**
692 * gst_pad_get_event_masks_default:
693 * @pad: a #GstPad.
694 *
695 * Invokes the default event masks dispatcher on the pad.
696 *
697 * Returns: a zero-terminated array of #GstEventMask, or NULL if none of the
698 * internally-linked pads have an event mask function.
699 */
700const GstEventMask *
701gst_pad_get_event_masks_default (GstPad * pad)
702{
703  GstEventMask *result = NULL;
704
705  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
706
707  gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
708      gst_pad_get_event_masks_dispatcher, &result);
709
710  return result;
711}
712
713/**
714 * gst_pad_set_convert_function:
715 * @pad: a real #GstPad of either direction.
716 * @convert: the #GstPadConvertFunction to set.
717 *
718 * Sets the given convert function for the pad.
719 */
720void
721gst_pad_set_convert_function (GstPad * pad, GstPadConvertFunction convert)
722{
723  g_return_if_fail (GST_IS_REAL_PAD (pad));
724
725  GST_RPAD_CONVERTFUNC (pad) = convert;
726
727  GST_CAT_DEBUG (GST_CAT_PADS, "convertfunc for %s:%s  set to %s",
728      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (convert));
729}
730
731/**
732 * gst_pad_set_query_function:
733 * @pad: a real #GstPad of either direction.
734 * @query: the #GstPadQueryFunction to set.
735 *
736 * Set the given query function for the pad.
737 */
738void
739gst_pad_set_query_function (GstPad * pad, GstPadQueryFunction query)
740{
741  g_return_if_fail (GST_IS_REAL_PAD (pad));
742
743  GST_RPAD_QUERYFUNC (pad) = query;
744
745  GST_CAT_DEBUG (GST_CAT_PADS, "queryfunc for %s:%s  set to %s",
746      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query));
747}
748
749/**
750 * gst_pad_set_query_type_function:
751 * @pad: a real #GstPad of either direction.
752 * @type_func: the #GstPadQueryTypeFunction to set.
753 *
754 * Set the given query type function for the pad.
755 */
756void
757gst_pad_set_query_type_function (GstPad * pad,
758    GstPadQueryTypeFunction type_func)
759{
760  g_return_if_fail (GST_IS_REAL_PAD (pad));
761
762  GST_RPAD_QUERYTYPEFUNC (pad) = type_func;
763
764  GST_CAT_DEBUG (GST_CAT_PADS, "querytypefunc for %s:%s  set to %s",
765      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (type_func));
766}
767
768/**
769 * gst_pad_get_query_types:
770 * @pad: a #GstPad.
771 *
772 * Get an array of supported queries that can be performed
773 * on this pad.
774 *
775 * Returns: a zero-terminated array of #GstQueryType.
776 */
777const GstQueryType *
778gst_pad_get_query_types (GstPad * pad)
779{
780  GstRealPad *rpad;
781
782  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
783
784  rpad = GST_PAD_REALIZE (pad);
785
786  g_return_val_if_fail (rpad, NULL);
787
788  if (GST_RPAD_QUERYTYPEFUNC (rpad))
789    return GST_RPAD_QUERYTYPEFUNC (rpad) (GST_PAD (pad));
790
791  return NULL;
792}
793
794static gboolean
795gst_pad_get_query_types_dispatcher (GstPad * pad, const GstQueryType ** data)
796{
797  *data = gst_pad_get_query_types (pad);
798
799  return TRUE;
800}
801
802/**
803 * gst_pad_get_query_types_default:
804 * @pad: a #GstPad.
805 *
806 * Invoke the default dispatcher for the query types on
807 * the pad.
808 *
809 * Returns: an zero-terminated array of #GstQueryType, or NULL if none of the
810 * internally-linked pads has a query types function.
811 */
812const GstQueryType *
813gst_pad_get_query_types_default (GstPad * pad)
814{
815  GstQueryType *result = NULL;
816
817  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
818
819  gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
820      gst_pad_get_query_types_dispatcher, &result);
821
822  return result;
823}
824
825/**
826 * gst_pad_set_internal_link_function:
827 * @pad: a real #GstPad of either direction.
828 * @intlink: the #GstPadIntLinkFunction to set.
829 *
830 * Sets the given internal link function for the pad.
831 */
832void
833gst_pad_set_internal_link_function (GstPad * pad, GstPadIntLinkFunction intlink)
834{
835  g_return_if_fail (GST_IS_REAL_PAD (pad));
836
837  GST_RPAD_INTLINKFUNC (pad) = intlink;
838  GST_CAT_DEBUG (GST_CAT_PADS, "internal link for %s:%s  set to %s",
839      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (intlink));
840}
841
842/**
843 * gst_pad_set_formats_function:
844 * @pad: a real #GstPad of either direction.
845 * @formats: the #GstPadFormatsFunction to set.
846 *
847 * Sets the given formats function for the pad.
848 */
849void
850gst_pad_set_formats_function (GstPad * pad, GstPadFormatsFunction formats)
851{
852  g_return_if_fail (GST_IS_REAL_PAD (pad));
853
854  GST_RPAD_FORMATSFUNC (pad) = formats;
855  GST_CAT_DEBUG (GST_CAT_PADS, "formats function for %s:%s  set to %s",
856      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (formats));
857}
858
859/**
860 * gst_pad_set_link_function:
861 * @pad: a real #GstPad.
862 * @link: the #GstPadLinkFunction to set.
863 *
864 * Sets the given link function for the pad. It will be called when the pad is
865 * linked or relinked with caps. The caps passed to the link function are
866 * guaranteed to be fixed. This means that you can assume that the caps is not
867 * ANY or EMPTY, and that there is exactly one structure in the caps, and that
868 * all the fields in the structure are fixed.
869 *
870 * The return value GST_PAD_LINK_OK should be used when the caps are acceptable,
871 * and you've extracted all the necessary information from the caps and set the
872 * element's internal state appropriately.
873 *
874 * The return value GST_PAD_LINK_REFUSED should be used when the caps are
875 * unacceptable for whatever reason.
876 *
877 * The return value GST_PAD_LINK_DELAYED should be used when the element is in a
878 * state where it can't determine whether the caps are acceptable or not. This
879 * is often used if the element needs to open a device or process data before
880 * determining acceptable caps.
881 *
882 * @link must not call gst_caps_try_set_caps() on the pad that was specified as
883 * a parameter, although it may (and often should) call gst_caps_try_set_caps()
884 * on other pads.
885 */
886void
887gst_pad_set_link_function (GstPad * pad, GstPadLinkFunction link)
888{
889  g_return_if_fail (GST_IS_REAL_PAD (pad));
890
891  GST_RPAD_LINKFUNC (pad) = link;
892  GST_CAT_DEBUG (GST_CAT_PADS, "linkfunc for %s:%s set to %s",
893      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (link));
894}
895
896/**
897 * gst_pad_set_unlink_function:
898 * @pad: a real #GstPad.
899 * @unlink: the #GstPadUnlinkFunction to set.
900 *
901 * Sets the given unlink function for the pad. It will be called
902 * when the pad is unlinked.
903 */
904void
905gst_pad_set_unlink_function (GstPad * pad, GstPadUnlinkFunction unlink)
906{
907  g_return_if_fail (GST_IS_REAL_PAD (pad));
908
909  GST_RPAD_UNLINKFUNC (pad) = unlink;
910  GST_CAT_DEBUG (GST_CAT_PADS, "unlinkfunc for %s:%s set to %s",
911      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (unlink));
912}
913
914/**
915 * gst_pad_set_fixate_function:
916 * @pad: a real #GstPad.
917 * @fixate: the #GstPadFixateFunction to set.
918 *
919 * Sets the given fixate function for the pad. Its job is to narrow down the
920 * possible caps for a connection. Fixate functions are called with a const
921 * caps, and should return a caps that is a strict subset of the given caps.
922 * That is, @fixate should create a caps that is "more fixed" than previously,
923 * but it does not have to return fixed caps. If @fixate can't provide more
924 * fixed caps, it should return %NULL.
925 *
926 * Note that @fixate will only be called after the "fixate" signal is emitted,
927 * and only if the caps are still non-fixed.
928 */
929void
930gst_pad_set_fixate_function (GstPad * pad, GstPadFixateFunction fixate)
931{
932  g_return_if_fail (GST_IS_REAL_PAD (pad));
933
934  GST_RPAD_FIXATEFUNC (pad) = fixate;
935  GST_CAT_DEBUG (GST_CAT_PADS, "fixatefunc for %s:%s set to %s",
936      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (fixate));
937}
938
939/**
940 * gst_pad_set_getcaps_function:
941 * @pad: a real #GstPad.
942 * @getcaps: the #GstPadGetCapsFunction to set.
943 *
944 * Sets the given getcaps function for the pad. @getcaps should return the
945 * allowable caps for a pad in the context of the element's state, its link to
946 * other elements, and the devices or files it has opened. These caps must be a
947 * subset of the pad template caps. In the NULL state with no links, @getcaps
948 * should ideally return the same caps as the pad template. In rare
949 * circumstances, an object property can affect the caps returned by @getcaps,
950 * but this is discouraged.
951 *
952 * You do not need to call this function if @pad's allowed caps are always the
953 * same as the pad template caps.
954 *
955 * For most filters, the caps returned by @getcaps is directly affected by the
956 * allowed caps on other pads. For demuxers and decoders, the caps returned by
957 * the srcpad's getcaps function is directly related to the stream data. Again,
958 * @getcaps should return the most specific caps it reasonably can, since this
959 * helps with autoplugging. However, the returned caps should not depend on the
960 * stream type currently negotiated for @pad.
961 *
962 * Note that the return value from @getcaps is owned by the caller.
963 */
964void
965gst_pad_set_getcaps_function (GstPad * pad, GstPadGetCapsFunction getcaps)
966{
967  g_return_if_fail (GST_IS_REAL_PAD (pad));
968
969  GST_RPAD_GETCAPSFUNC (pad) = getcaps;
970  GST_CAT_DEBUG (GST_CAT_PADS, "getcapsfunc for %s:%s set to %s",
971      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (getcaps));
972}
973
974/**
975 * gst_pad_set_bufferalloc_function:
976 * @pad: a real sink #GstPad.
977 * @bufalloc: the #GstPadBufferAllocFunction to set.
978 *
979 * Sets the given bufferalloc function for the pad. Note that the
980 * bufferalloc function can only be set on sinkpads.
981 */
982void
983gst_pad_set_bufferalloc_function (GstPad * pad,
984    GstPadBufferAllocFunction bufalloc)
985{
986  g_return_if_fail (GST_IS_REAL_PAD (pad));
987  g_return_if_fail (GST_PAD_IS_SINK (pad));
988
989  GST_RPAD_BUFFERALLOCFUNC (pad) = bufalloc;
990  GST_CAT_DEBUG (GST_CAT_PADS, "bufferallocfunc for %s:%s set to %s",
991      GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (bufalloc));
992}
993
994/* FIXME 0.9: Do we actually want to allow the case where src and sink are
995   switched? */
996/**
997 * gst_pad_unlink:
998 * @srcpad: the source #GstPad to unlink.
999 * @sinkpad: the sink #GstPad to unlink.
1000 *
1001 * Unlinks the source pad from the sink pad. Will emit the "unlinked" signal on
1002 * both pads.
1003 */
1004void
1005gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
1006{
1007  GstRealPad *realsrc, *realsink;
1008  GstScheduler *src_sched, *sink_sched;
1009
1010  g_return_if_fail (GST_IS_PAD (srcpad));
1011  g_return_if_fail (GST_IS_PAD (sinkpad));
1012
1013  GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinking %s:%s(%p) and %s:%s(%p)",
1014      GST_DEBUG_PAD_NAME (srcpad), srcpad,
1015      GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
1016
1017  realsrc = GST_PAD_REALIZE (srcpad);
1018  realsink = GST_PAD_REALIZE (sinkpad);
1019
1020  g_return_if_fail (GST_RPAD_PEER (realsrc) != NULL);
1021  g_return_if_fail (GST_RPAD_PEER (realsink) == realsrc);
1022
1023  if ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SINK) &&
1024      (GST_RPAD_DIRECTION (realsink) == GST_PAD_SRC)) {
1025    GstRealPad *temppad;
1026
1027    temppad = realsrc;
1028    realsrc = realsink;
1029    realsink = temppad;
1030  }
1031  g_return_if_fail ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
1032      (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK));
1033
1034  if (GST_RPAD_UNLINKFUNC (realsrc)) {
1035    GST_RPAD_UNLINKFUNC (realsrc) (GST_PAD (realsrc));
1036  }
1037  if (GST_RPAD_UNLINKFUNC (realsink)) {
1038    GST_RPAD_UNLINKFUNC (realsink) (GST_PAD (realsink));
1039  }
1040
1041  /* get the schedulers before we unlink */
1042  src_sched = gst_pad_get_scheduler (GST_PAD (realsrc));
1043  sink_sched = gst_pad_get_scheduler (GST_PAD (realsink));
1044
1045  if (GST_RPAD_LINK (realsrc))
1046    gst_pad_link_free (GST_RPAD_LINK (realsrc));
1047
1048  /* first clear peers */
1049  GST_RPAD_PEER (realsrc) = NULL;
1050  GST_RPAD_PEER (realsink) = NULL;
1051  GST_RPAD_LINK (realsrc) = NULL;
1052  GST_RPAD_LINK (realsink) = NULL;
1053
1054  /* now tell the scheduler */
1055  if (src_sched && src_sched == sink_sched) {
1056    gst_scheduler_pad_unlink (src_sched, GST_PAD (realsrc), GST_PAD (realsink));
1057  }
1058
1059  /* hold a reference, as they can go away in the signal handlers */
1060  gst_object_ref (GST_OBJECT (realsrc));
1061  gst_object_ref (GST_OBJECT (realsink));
1062
1063  /* fire off a signal to each of the pads telling them
1064   * that they've been unlinked */
1065  g_signal_emit (G_OBJECT (realsrc), gst_real_pad_signals[REAL_UNLINKED],
1066      0, realsink);
1067  g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_UNLINKED],
1068      0, realsrc);
1069
1070  GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinked %s:%s and %s:%s",
1071      GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
1072
1073  gst_object_unref (GST_OBJECT (realsrc));
1074  gst_object_unref (GST_OBJECT (realsink));
1075}
1076
1077/**
1078 * gst_pad_is_linked:
1079 * @pad: pad to check
1080 *
1081 * Checks if a @pad is linked to another pad or not.
1082 *
1083 * Returns: TRUE if the pad is linked, FALSE otherwise.
1084 */
1085gboolean
1086gst_pad_is_linked (GstPad * pad)
1087{
1088  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
1089
1090  return GST_PAD_PEER (pad) != NULL;
1091}
1092
1093static gboolean
1094gst_pad_check_schedulers (GstRealPad * realsrc, GstRealPad * realsink)
1095{
1096  GstScheduler *src_sched, *sink_sched;
1097  gint num_decoupled = 0;
1098
1099  src_sched = gst_pad_get_scheduler (GST_PAD (realsrc));
1100  sink_sched = gst_pad_get_scheduler (GST_PAD (realsink));
1101
1102  if (src_sched && sink_sched) {
1103    if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsrc), GST_ELEMENT_DECOUPLED))
1104      num_decoupled++;
1105    if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsink), GST_ELEMENT_DECOUPLED))
1106      num_decoupled++;
1107
1108    if (src_sched != sink_sched && num_decoupled != 1) {
1109      return FALSE;
1110    }
1111  }
1112  return TRUE;
1113}
1114
1115#define GST_PAD_LINK_SRC(pad) ((GST_PAD_IS_SRC (pad)) ? (pad) : GST_PAD_PEER (pad))
1116#define GST_PAD_LINK_SINK(pad) ((GST_PAD_IS_SINK (pad)) ? (pad) : GST_PAD_PEER (pad))
1117
1118static GstPadLink *
1119gst_pad_link_new (void)
1120{
1121  GstPadLink *link;
1122
1123  link = g_new0 (GstPadLink, 1);
1124  link->sinknotify = TRUE;
1125  link->srcnotify = TRUE;
1126
1127  link->engaged = FALSE;
1128  return link;
1129}
1130
1131static void
1132gst_pad_link_free (GstPadLink * link)
1133{
1134  if (link->srccaps)
1135    gst_caps_free (link->srccaps);
1136  if (link->sinkcaps)
1137    gst_caps_free (link->sinkcaps);
1138  if (link->filtercaps)
1139    gst_caps_free (link->filtercaps);
1140  if (link->caps)
1141    gst_caps_free (link->caps);
1142  if (link->temp_store)
1143    gst_data_unref (link->temp_store);
1144#ifdef USE_POISONING
1145  memset (link, 0xff, sizeof (*link));
1146#endif
1147  g_free (link);
1148}
1149
1150static void
1151gst_pad_link_intersect (GstPadLink * link)
1152{
1153  GstCaps *pad_intersection;
1154
1155  if (link->caps)
1156    gst_caps_free (link->caps);
1157
1158  GST_DEBUG ("intersecting link from %s:%s to %s:%s",
1159      GST_DEBUG_PAD_NAME (link->srcpad), GST_DEBUG_PAD_NAME (link->sinkpad));
1160  GST_DEBUG ("... srccaps %" GST_PTR_FORMAT, link->srccaps);
1161  GST_DEBUG ("... sinkcaps %" GST_PTR_FORMAT, link->sinkcaps);
1162  GST_DEBUG ("... filtercaps %" GST_PTR_FORMAT, link->filtercaps);
1163
1164  pad_intersection = gst_caps_intersect (link->srccaps, link->sinkcaps);
1165
1166  if (link->filtercaps) {
1167    GST_DEBUG ("unfiltered intersection %" GST_PTR_FORMAT, pad_intersection);
1168    link->caps = gst_caps_intersect (pad_intersection, link->filtercaps);
1169    gst_caps_free (pad_intersection);
1170  } else {
1171    link->caps = pad_intersection;
1172  }
1173
1174  GST_DEBUG ("filtered intersection %" GST_PTR_FORMAT, link->caps);
1175}
1176
1177static gboolean
1178gst_pad_link_ready_for_negotiation (GstPadLink * link)
1179{
1180  GstElement *parent;
1181
1182  parent = GST_PAD_PARENT (link->srcpad);
1183  if (!parent || GST_STATE (parent) < GST_STATE_READY) {
1184    GST_DEBUG ("parent %s of pad %s:%s is not READY",
1185        GST_ELEMENT_NAME (parent), GST_DEBUG_PAD_NAME (link->srcpad));
1186    return FALSE;
1187  }
1188  parent = GST_PAD_PARENT (link->sinkpad);
1189  if (!parent || GST_STATE (parent) < GST_STATE_READY) {
1190    GST_DEBUG ("parent %s of pad %s:%s is not READY",
1191        GST_ELEMENT_NAME (parent), GST_DEBUG_PAD_NAME (link->sinkpad));
1192    return FALSE;
1193  }
1194
1195  return TRUE;
1196}
1197
1198static void
1199gst_pad_link_fixate (GstPadLink * link)
1200{
1201  GstCaps *caps;
1202  GstCaps *newcaps;
1203
1204  caps = link->caps;
1205
1206  g_return_if_fail (caps != NULL);
1207  g_return_if_fail (!gst_caps_is_empty (caps));
1208
1209  GST_DEBUG ("trying to fixate caps %" GST_PTR_FORMAT, caps);
1210
1211  gst_caps_do_simplify (caps);
1212  while (!gst_caps_is_fixed (caps)) {
1213    int i;
1214
1215    for (i = 0; i < 5; i++) {
1216      newcaps = NULL;
1217      switch (i) {
1218        case 0:
1219          g_signal_emit (G_OBJECT (link->srcpad),
1220              gst_real_pad_signals[REAL_FIXATE], 0, caps, &newcaps);
1221          GST_DEBUG ("app srcpad signal fixated to %" GST_PTR_FORMAT, newcaps);
1222          break;
1223        case 1:
1224          g_signal_emit (G_OBJECT (link->sinkpad),
1225              gst_real_pad_signals[REAL_FIXATE], 0, caps, &newcaps);
1226          GST_DEBUG ("app sinkpad signal fixated to %" GST_PTR_FORMAT, newcaps);
1227          break;
1228        case 2:
1229          if (GST_RPAD_FIXATEFUNC (link->srcpad)) {
1230            newcaps =
1231                GST_RPAD_FIXATEFUNC (link->srcpad) (GST_PAD (link->srcpad),
1232                caps);
1233            GST_DEBUG ("srcpad %s:%s fixated to %" GST_PTR_FORMAT,
1234                GST_DEBUG_PAD_NAME (link->srcpad), newcaps);
1235          } else
1236            GST_DEBUG ("srcpad %s:%s doesn't have a fixate function",
1237                GST_DEBUG_PAD_NAME (link->srcpad));
1238
1239          break;
1240        case 3:
1241          if (GST_RPAD_FIXATEFUNC (link->sinkpad)) {
1242            newcaps =
1243                GST_RPAD_FIXATEFUNC (link->sinkpad) (GST_PAD (link->sinkpad),
1244                caps);
1245            GST_DEBUG ("sinkpad %s:%s fixated to %" GST_PTR_FORMAT,
1246                GST_DEBUG_PAD_NAME (link->sinkpad), newcaps);
1247          } else
1248            GST_DEBUG ("sinkpad %s:%s doesn't have a fixate function",
1249                GST_DEBUG_PAD_NAME (link->sinkpad));
1250          break;
1251        case 4:
1252          newcaps = _gst_pad_default_fixate_func (GST_PAD (link->srcpad), caps);
1253          GST_DEBUG ("core fixated to %" GST_PTR_FORMAT, newcaps);
1254          break;
1255      }
1256      if (newcaps) {
1257        G_GNUC_UNUSED gboolean bad;
1258
1259        gst_caps_do_simplify (newcaps);
1260#ifndef G_DISABLE_CHECKS
1261        /* some mad checking for correctly working fixation functions */
1262
1263        if (i == 4) {
1264          /* we trust the default fixation function unconditionally */
1265          bad = FALSE;
1266        } else if (gst_caps_is_empty (newcaps)) {
1267          g_warning
1268              ("a fixation function did not fixate correctly, it returned empty caps");
1269          gst_caps_free (newcaps);
1270          continue;
1271        } else if (gst_caps_is_any (caps)) {
1272          bad = gst_caps_is_any (newcaps);
1273        } else {
1274          GstCaps *test = gst_caps_subtract (caps, newcaps);
1275
1276          bad = gst_caps_is_empty (test);
1277          gst_caps_free (test);
1278          /* simplifying is ok, too */
1279          if (bad)
1280            bad = (gst_caps_get_size (newcaps) >= gst_caps_get_size (caps));
1281        }
1282        if (bad) {
1283          gchar *newcaps_str = gst_caps_to_string (newcaps);
1284          gchar *caps_str = gst_caps_to_string (caps);
1285
1286          g_warning
1287              ("a fixation function did not fixate correctly, the returned caps %s are no true subset of %s.",
1288              newcaps_str, caps_str);
1289          g_free (newcaps_str);
1290          g_free (caps_str);
1291          gst_caps_free (newcaps);
1292        } else
1293#endif
1294        {
1295          gst_caps_free (caps);
1296          caps = newcaps;
1297          break;
1298        }
1299      }
1300    }
1301  }
1302
1303  link->caps = caps;
1304}
1305
1306static GstPadLinkReturn
1307gst_pad_link_call_link_functions (GstPadLink * link)
1308{
1309  GstPadLinkReturn res = GST_PAD_LINK_OK;
1310
1311  /* Detect recursion. */
1312  if (GST_PAD_IS_NEGOTIATING (link->srcpad) ||
1313      GST_PAD_IS_NEGOTIATING (link->sinkpad)) {
1314    GST_ERROR ("The link functions have recursed, please file a bug!");
1315    return GST_PAD_LINK_REFUSED;
1316  }
1317
1318  /* Both of the pads are in negotiation, so we set the NEGOTIATING flag on both
1319   * of them now to avoid recursion from either pad. */
1320  GST_FLAG_SET (link->srcpad, GST_PAD_NEGOTIATING);
1321  GST_FLAG_SET (link->sinkpad, GST_PAD_NEGOTIATING);
1322
1323  /* If this doesn't run, the status is left to the default OK value. */
1324  if (link->srcnotify && GST_RPAD_LINKFUNC (link->srcpad)) {
1325    /* call the link function */
1326    GST_DEBUG_OBJECT (link->srcpad,
1327        "calling link function with caps %" GST_PTR_FORMAT, link->caps);
1328    res = GST_RPAD_LINKFUNC (link->srcpad) (GST_PAD (link->srcpad), link->caps);
1329
1330    GST_DEBUG_OBJECT (link->srcpad, "got reply %d from link function", res);
1331
1332    if (GST_PAD_LINK_FAILED (res)) {
1333      GST_CAT_INFO_OBJECT (GST_CAT_CAPS, link->srcpad,
1334          "pad doesn't accept caps %" GST_PTR_FORMAT, link->caps);
1335    }
1336  }
1337
1338  if (GST_PAD_LINK_SUCCESSFUL (res) &&
1339      link->sinknotify && GST_RPAD_LINKFUNC (link->sinkpad)) {
1340    /* call the link function */
1341    GST_DEBUG_OBJECT (link->sinkpad,
1342        "calling link function with caps %" GST_PTR_FORMAT, link->caps);
1343    res = GST_RPAD_LINKFUNC (link->sinkpad) (GST_PAD (link->sinkpad),
1344        link->caps);
1345
1346    GST_DEBUG_OBJECT (link->sinkpad, "got reply %d from link function", res);
1347
1348    if (GST_PAD_LINK_FAILED (res)) {
1349      GST_CAT_INFO_OBJECT (GST_CAT_CAPS, link->sinkpad,
1350          "pad doesn't accept caps %" GST_PTR_FORMAT, link->caps);
1351    }
1352  }
1353
1354  GST_FLAG_UNSET (link->srcpad, GST_PAD_NEGOTIATING);
1355  GST_FLAG_UNSET (link->sinkpad, GST_PAD_NEGOTIATING);
1356  return res;
1357}
1358
1359static GstPadLinkReturn
1360gst_pad_link_negotiate (GstPadLink * link)
1361{
1362  GST_DEBUG ("negotiating link from pad %s:%s to pad %s:%s",
1363      GST_DEBUG_PAD_NAME (link->srcpad), GST_DEBUG_PAD_NAME (link->sinkpad));
1364
1365  gst_pad_link_intersect (link);
1366  if (gst_caps_is_empty (link->caps))
1367    return GST_PAD_LINK_REFUSED;
1368
1369  gst_pad_link_fixate (link);
1370  if (gst_caps_is_empty (link->caps))
1371    return GST_PAD_LINK_REFUSED;
1372
1373  if (!gst_pad_link_ready_for_negotiation (link)) {
1374    return GST_PAD_LINK_DELAYED;
1375  }
1376  GST_DEBUG ("calling link_functions between %s:%s and %s:%s with caps %"
1377      GST_PTR_FORMAT, GST_DEBUG_PAD_NAME (link->srcpad),
1378      GST_DEBUG_PAD_NAME (link->sinkpad), link->caps);
1379
1380  return gst_pad_link_call_link_functions (link);
1381}
1382
1383/**
1384 * gst_pad_link_try:
1385 * @link: link to try
1386 *
1387 * Tries to (re)link the pads with the given link. The function takes ownership
1388 * of the supplied link. If the function returns FALSE and an old link existed,
1389 * that link can be assumed to work unchanged.
1390 *
1391 * Returns: TRUE if the link succeeded, FALSE if not.
1392 */
1393static gboolean
1394gst_pad_link_try (GstPadLink * link)
1395{
1396  GstPad *srcpad, *sinkpad;
1397  GstPadLink *oldlink;
1398  GstPadLinkReturn ret;
1399
1400  /* we use assertions here, because this function is static */
1401  g_assert (link);
1402  srcpad = link->srcpad;
1403  g_assert (srcpad);
1404  sinkpad = link->sinkpad;
1405  g_assert (sinkpad);
1406  oldlink = GST_RPAD_LINK (srcpad);
1407  g_assert (oldlink == GST_RPAD_LINK (sinkpad));
1408
1409  GST_DEBUG ("negotiating given link");
1410  ret = gst_pad_link_negotiate (link);
1411  if (GST_PAD_LINK_FAILED (ret) && oldlink && oldlink->caps) {
1412    GST_DEBUG ("negotiating failed, but there was a valid old link");
1413    oldlink->srcnotify = link->srcnotify;
1414    oldlink->sinknotify = link->sinknotify;
1415    if (GST_PAD_LINK_FAILED (gst_pad_link_call_link_functions (oldlink))) {
1416      g_warning ("pads don't accept old caps. We assume they did though");
1417    }
1418  }
1419  if (ret == GST_PAD_LINK_REFUSED) {
1420    GST_DEBUG ("link refused, returning");
1421    gst_pad_link_free (link);
1422    return ret;
1423  }
1424  if (ret == GST_PAD_LINK_DELAYED) {
1425    GST_DEBUG ("link delayed, replacing link caps and returning");
1426    gst_caps_replace (&link->caps, NULL);
1427  }
1428
1429  GST_RPAD_PEER (srcpad) = GST_REAL_PAD (link->sinkpad);
1430  GST_RPAD_PEER (sinkpad) = GST_REAL_PAD (link->srcpad);
1431  if (oldlink) {
1432    GST_DEBUG ("copying stuff from oldlink");
1433    link->temp_store = oldlink->temp_store;
1434    GST_DEBUG ("moving old data temp store %p", link->temp_store);
1435    link->engaged = oldlink->engaged;
1436    oldlink->temp_store = NULL;
1437    gst_pad_link_free (oldlink);
1438  }
1439  GST_RPAD_LINK (srcpad) = link;
1440  GST_RPAD_LINK (sinkpad) = link;
1441  if (ret == GST_PAD_LINK_OK) {
1442    GST_DEBUG ("notifying caps after successful link");
1443    g_object_notify (G_OBJECT (srcpad), "caps");
1444    g_object_notify (G_OBJECT (sinkpad), "caps");
1445  }
1446
1447  return ret;
1448}
1449
1450/**
1451 * gst_pad_renegotiate:
1452 * @pad: a #GstPad
1453 *
1454 * Initiate caps negotiation on @pad. @pad must be linked.
1455 *
1456 * If @pad's parent is not at least in #GST_STATE_READY, returns
1457 * #GST_PAD_LINK_DELAYED.
1458 *
1459 * Otherwise caps are retrieved from both @pad and its peer by calling their
1460 * getcaps functions. They are then intersected, returning #GST_PAD_LINK_FAIL if
1461 * there is no intersection.
1462 *
1463 * The intersection is fixated if necessary, and then the link functions of @pad
1464 * and its peer are called.
1465 *
1466 * Returns: The return value of @pad's link function (see
1467 * gst_pad_set_link_function()), or #GST_PAD_LINK_OK if there is no link
1468 * function.
1469 *
1470 * The macros GST_PAD_LINK_SUCCESSFUL() and GST_PAD_LINK_FAILED() should be used
1471 * when you just need success/failure information.
1472 */
1473GstPadLinkReturn
1474gst_pad_renegotiate (GstPad * pad)
1475{
1476  GstPadLink *link;
1477
1478  g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_LINK_REFUSED);
1479  if (!GST_PAD_PEER (pad))
1480    return GST_PAD_LINK_OK;
1481
1482  link = gst_pad_link_new ();
1483
1484  link->srcpad = GST_PAD_LINK_SRC (pad);
1485  link->sinkpad = GST_PAD_LINK_SINK (pad);
1486
1487  if (!gst_pad_link_ready_for_negotiation (link)) {
1488    gst_pad_link_free (link);
1489    return GST_PAD_LINK_DELAYED;
1490  }
1491
1492  if (GST_REAL_PAD (pad)->link->filtercaps) {
1493    link->filtercaps = gst_caps_copy (GST_REAL_PAD (pad)->link->filtercaps);
1494  }
1495  link->srccaps = gst_pad_get_caps (link->srcpad);
1496  link->sinkcaps = gst_pad_get_caps (link->sinkpad);
1497
1498  return gst_pad_link_try (link);
1499}
1500
1501/**
1502 * gst_pad_try_set_caps:
1503 * @pad: a #GstPad
1504 * @caps: #GstCaps to set on @pad
1505 *
1506 * Try to set the caps on @pad. @caps must be fixed. If @pad is unlinked,
1507 * returns #GST_PAD_LINK_OK without doing anything. Otherwise, start caps
1508 * negotiation on @pad.
1509 *
1510 * Returns: The return value of @pad's link function (see
1511 * gst_pad_set_link_function()), or #GST_PAD_LINK_OK if there is no link
1512 * function.
1513 *
1514 * The macros GST_PAD_LINK_SUCCESSFUL() and GST_PAD_LINK_FAILED() should be used
1515 * when you just need success/failure information.
1516 */
1517GstPadLinkReturn
1518gst_pad_try_set_caps (GstPad * pad, const GstCaps * caps)
1519{
1520  GstPadLink *link;
1521  GstPadLink *oldlink;
1522  GstPadLinkReturn ret;
1523
1524  g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_PAD_LINK_REFUSED);
1525
1526  GST_LOG_OBJECT (pad, "Trying to set %" GST_PTR_FORMAT, caps);
1527
1528  if (GST_PAD_IS_NEGOTIATING (pad)) {
1529    GST_DEBUG_OBJECT (pad, "Detected a recursion, just returning OK");
1530    return GST_PAD_LINK_OK;
1531  }
1532
1533  GST_CAT_INFO_OBJECT (GST_CAT_CAPS, pad, "caps %" GST_PTR_FORMAT, caps);
1534  /* setting non-fixed caps on a pad is not allowed */
1535  if (!gst_caps_is_fixed (caps)) {
1536    GST_CAT_INFO (GST_CAT_CAPS,
1537        "trying to set unfixed caps on pad %s:%s, not allowed",
1538        GST_DEBUG_PAD_NAME (pad));
1539    g_warning ("trying to set non fixed caps on pad %s:%s, not allowed",
1540        GST_DEBUG_PAD_NAME (pad));
1541
1542    GST_DEBUG ("unfixed caps %" GST_PTR_FORMAT, caps);
1543    return GST_PAD_LINK_REFUSED;
1544  }
1545
1546  /* we allow setting caps on non-linked pads.  It's ignored */
1547  if (!GST_PAD_PEER (pad)) {
1548    GST_DEBUG ("unlinked pad %s:%s, returning OK", GST_DEBUG_PAD_NAME (pad));
1549    return GST_PAD_LINK_OK;
1550  }
1551
1552  /* we just checked that a peer exists */
1553  g_assert (GST_PAD_LINK_SRC (pad));
1554  g_assert (GST_PAD_LINK_SINK (pad));
1555
1556  /* if the desired caps are already there, it's trivially ok */
1557  if (GST_PAD_CAPS (pad) && gst_caps_is_equal (caps, GST_PAD_CAPS (pad))) {
1558    GST_DEBUG ("pad %s:%s already has these caps", GST_DEBUG_PAD_NAME (pad));
1559    return GST_PAD_LINK_OK;
1560  }
1561
1562  link = gst_pad_link_new ();
1563
1564  link->srcpad = GST_PAD_LINK_SRC (pad);
1565  link->sinkpad = GST_PAD_LINK_SINK (pad);
1566
1567  if (!gst_pad_link_ready_for_negotiation (link)) {
1568    GST_DEBUG ("link not ready for negotiating, delaying");
1569    gst_pad_link_free (link);
1570    return GST_PAD_LINK_DELAYED;
1571  }
1572
1573  oldlink = GST_REAL_PAD (pad)->link;
1574  if (oldlink && oldlink->filtercaps) {
1575    link->filtercaps = gst_caps_copy (oldlink->filtercaps);
1576  }
1577  if (link->srcpad == pad) {
1578    link->srccaps = gst_caps_copy (caps);
1579    link->sinkcaps = gst_pad_get_caps (link->sinkpad);
1580    link->srcnotify = FALSE;
1581  } else {
1582    link->srccaps = gst_pad_get_caps (link->srcpad);
1583    link->sinkcaps = gst_caps_copy (caps);
1584    link->sinknotify = FALSE;
1585  }
1586
1587  GST_DEBUG ("trying to link");
1588  ret = gst_pad_link_try (link);
1589
1590  return ret;
1591}
1592
1593/**
1594 * gst_pad_try_set_caps_nonfixed:
1595 * @pad: a real #GstPad
1596 * @caps: #GstCaps to set on @pad
1597 *
1598 * Like gst_pad_try_set_caps(), but allows non-fixed caps.
1599 *
1600 * Returns: a #GstPadLinkReturn, like gst_pad_try_set_caps().
1601 */
1602GstPadLinkReturn
1603gst_pad_try_set_caps_nonfixed (GstPad * pad, const GstCaps * caps)
1604{
1605  GstPadLink *link;
1606  GstPadLink *oldlink;
1607  GstPadLinkReturn ret;
1608
1609  g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_PAD_LINK_REFUSED);
1610  g_return_val_if_fail (!GST_PAD_IS_NEGOTIATING (pad), GST_PAD_LINK_REFUSED);
1611
1612  /* we allow setting caps on non-linked pads.  It's ignored */
1613  if (!GST_PAD_PEER (pad)) {
1614    return GST_PAD_LINK_OK;
1615  }
1616
1617  /* we just checked that a peer exists */
1618  g_assert (GST_PAD_LINK_SRC (pad));
1619  g_assert (GST_PAD_LINK_SINK (pad));
1620
1621  /* if the link is already negotiated and the caps are compatible
1622   * with what we're setting, it's trivially OK. */
1623  if (GST_PAD_CAPS (pad)) {
1624    GstCaps *intersection;
1625
1626    intersection = gst_caps_intersect (caps, GST_PAD_CAPS (pad));
1627    if (!gst_caps_is_empty (intersection)) {
1628      gst_caps_free (intersection);
1629      return GST_PAD_LINK_OK;
1630    }
1631    gst_caps_free (intersection);
1632  }
1633
1634  link = gst_pad_link_new ();
1635
1636  link->srcpad = GST_PAD_LINK_SRC (pad);
1637  link->sinkpad = GST_PAD_LINK_SINK (pad);
1638
1639  if (!gst_pad_link_ready_for_negotiation (link)) {
1640    gst_pad_link_free (link);
1641    return GST_PAD_LINK_DELAYED;
1642  }
1643
1644  oldlink = GST_REAL_PAD (pad)->link;
1645  if (oldlink && oldlink->filtercaps) {
1646    link->filtercaps = gst_caps_copy (oldlink->filtercaps);
1647  }
1648  if (link->srcpad == pad) {
1649    link->srccaps = gst_caps_copy (caps);
1650    link->sinkcaps = gst_pad_get_caps (link->sinkpad);
1651    link->srcnotify = FALSE;
1652  } else {
1653    link->srccaps = gst_pad_get_caps (link->srcpad);
1654    link->sinkcaps = gst_caps_copy (caps);
1655    link->sinknotify = FALSE;
1656  }
1657
1658  ret = gst_pad_link_try (link);
1659
1660  return ret;
1661}
1662
1663/**
1664 * gst_pad_can_link_filtered:
1665 * @srcpad: the source #GstPad to link.
1666 * @sinkpad: the sink #GstPad to link.
1667 * @filtercaps: the filter #GstCaps.
1668 *
1669 * Checks if the source pad and the sink pad can be linked when constrained
1670 * by the given filter caps. Both @srcpad and @sinkpad must be unlinked.
1671 *
1672 * Returns: TRUE if the pads can be linked, FALSE otherwise.
1673 */
1674gboolean
1675gst_pad_can_link_filtered (GstPad * srcpad, GstPad * sinkpad,
1676    const GstCaps * filtercaps)
1677{
1678  GstRealPad *realsrc, *realsink;
1679  GstPadLink *link;
1680
1681  /* FIXME This function is gross.  It's almost a direct copy of
1682   * gst_pad_link_filtered().  Any decent programmer would attempt
1683   * to merge the two functions, which I will do some day. --ds
1684   */
1685
1686  /* generic checks */
1687  g_return_val_if_fail (srcpad != NULL, FALSE);
1688  g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1689  g_return_val_if_fail (sinkpad != NULL, FALSE);
1690  g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1691
1692  GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
1693      GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
1694
1695  /* now we need to deal with the real/ghost stuff */
1696  realsrc = GST_PAD_REALIZE (srcpad);
1697  realsink = GST_PAD_REALIZE (sinkpad);
1698
1699  if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
1700    GST_CAT_INFO (GST_CAT_PADS, "*actually* linking %s:%s and %s:%s",
1701        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1702  }
1703  /* FIXME: shouldn't we convert this to g_return_val_if_fail? */
1704  if (GST_RPAD_PEER (realsrc) != NULL) {
1705    GST_CAT_INFO (GST_CAT_PADS, "Real source pad %s:%s has a peer, failed",
1706        GST_DEBUG_PAD_NAME (realsrc));
1707    return FALSE;
1708  }
1709  if (GST_RPAD_PEER (realsink) != NULL) {
1710    GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s has a peer, failed",
1711        GST_DEBUG_PAD_NAME (realsink));
1712    return FALSE;
1713  }
1714  if (GST_PAD_PARENT (realsrc) == NULL) {
1715    GST_CAT_INFO (GST_CAT_PADS, "Real src pad %s:%s has no parent, failed",
1716        GST_DEBUG_PAD_NAME (realsrc));
1717    return FALSE;
1718  }
1719  if (GST_PAD_PARENT (realsink) == NULL) {
1720    GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s has no parent, failed",
1721        GST_DEBUG_PAD_NAME (realsrc));
1722    return FALSE;
1723  }
1724
1725  if (!gst_pad_check_schedulers (realsrc, realsink)) {
1726    g_warning ("linking pads with different scheds requires "
1727        "exactly one decoupled element (such as queue)");
1728    return FALSE;
1729  }
1730
1731  g_return_val_if_fail (realsrc != NULL, GST_PAD_LINK_REFUSED);
1732  g_return_val_if_fail (realsink != NULL, GST_PAD_LINK_REFUSED);
1733
1734  link = gst_pad_link_new ();
1735
1736  if (GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) {
1737    link->srcpad = GST_PAD (realsrc);
1738    link->sinkpad = GST_PAD (realsink);
1739  } else {
1740    link->srcpad = GST_PAD (realsink);
1741    link->sinkpad = GST_PAD (realsrc);
1742  }
1743
1744  if (GST_RPAD_DIRECTION (link->srcpad) != GST_PAD_SRC) {
1745    GST_CAT_INFO (GST_CAT_PADS,
1746        "Real src pad %s:%s is not a source pad, failed",
1747        GST_DEBUG_PAD_NAME (link->srcpad));
1748    gst_pad_link_free (link);
1749    return FALSE;
1750  }
1751  if (GST_RPAD_DIRECTION (link->sinkpad) != GST_PAD_SINK) {
1752    GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s is not a sink pad, failed",
1753        GST_DEBUG_PAD_NAME (link->sinkpad));
1754    gst_pad_link_free (link);
1755    return FALSE;
1756  }
1757
1758  link->srccaps = gst_pad_get_caps (link->srcpad);
1759  link->sinkcaps = gst_pad_get_caps (link->sinkpad);
1760  if (filtercaps)
1761    link->filtercaps = gst_caps_copy (filtercaps);
1762
1763  gst_pad_link_intersect (link);
1764  if (gst_caps_is_empty (link->caps)) {
1765    gst_pad_link_free (link);
1766    return FALSE;
1767  }
1768
1769  gst_pad_link_free (link);
1770  return TRUE;
1771}
1772
1773/**
1774 * gst_pad_can_link:
1775 * @srcpad: the source #GstPad to link.
1776 * @sinkpad: the sink #GstPad to link.
1777 *
1778 * Checks if the source pad and the sink pad can be linked.
1779 *
1780 * Returns: TRUE if the pads can be linked, FALSE otherwise.
1781 */
1782gboolean
1783gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad)
1784{
1785  return gst_pad_can_link_filtered (srcpad, sinkpad, NULL);
1786}
1787
1788/**
1789 * gst_pad_link_filtered:
1790 * @srcpad: the source #GstPad to link.
1791 * @sinkpad: the sink #GstPad to link.
1792 * @filtercaps: the filter #GstCaps.
1793 *
1794 * Links the source pad and the sink pad, constrained
1795 * by the given filter caps.
1796 *
1797 * Returns: TRUE if the pads have been linked, FALSE otherwise.
1798 */
1799gboolean
1800gst_pad_link_filtered (GstPad * srcpad, GstPad * sinkpad,
1801    const GstCaps * filtercaps)
1802{
1803  GstRealPad *realsrc, *realsink;
1804  GstScheduler *src_sched, *sink_sched;
1805  GstPadLink *link;
1806
1807  /* generic checks */
1808  g_return_val_if_fail (srcpad != NULL, FALSE);
1809  g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1810  g_return_val_if_fail (sinkpad != NULL, FALSE);
1811  g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1812
1813  GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
1814      GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
1815
1816  /* now we need to deal with the real/ghost stuff */
1817  realsrc = GST_PAD_REALIZE (srcpad);
1818  realsink = GST_PAD_REALIZE (sinkpad);
1819
1820  if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
1821    GST_CAT_INFO (GST_CAT_PADS, "*actually* linking %s:%s and %s:%s",
1822        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
1823  }
1824  /* FIXME: shouldn't we convert this to g_return_val_if_fail? */
1825  if (GST_RPAD_PEER (realsrc) != NULL) {
1826    GST_CAT_INFO (GST_CAT_PADS, "Real source pad %s:%s has a peer, failed",
1827        GST_DEBUG_PAD_NAME (realsrc));
1828    return FALSE;
1829  }
1830  if (GST_RPAD_PEER (realsink) != NULL) {
1831    GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s has a peer, failed",
1832        GST_DEBUG_PAD_NAME (realsink));
1833    return FALSE;
1834  }
1835  if (GST_PAD_PARENT (realsrc) == NULL) {
1836    GST_CAT_INFO (GST_CAT_PADS, "Real src pad %s:%s has no parent, failed",
1837        GST_DEBUG_PAD_NAME (realsrc));
1838    return FALSE;
1839  }
1840  if (GST_PAD_PARENT (realsink) == NULL) {
1841    GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s has no parent, failed",
1842        GST_DEBUG_PAD_NAME (realsrc));
1843    return FALSE;
1844  }
1845
1846  if (!gst_pad_check_schedulers (realsrc, realsink)) {
1847    g_warning ("linking pads with different scheds requires "
1848        "exactly one decoupled element (such as queue)");
1849    return FALSE;
1850  }
1851
1852  g_return_val_if_fail (realsrc != NULL, GST_PAD_LINK_REFUSED);
1853  g_return_val_if_fail (realsink != NULL, GST_PAD_LINK_REFUSED);
1854
1855  link = gst_pad_link_new ();
1856
1857  if (GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) {
1858    link->srcpad = GST_PAD (realsrc);
1859    link->sinkpad = GST_PAD (realsink);
1860  } else {
1861    link->srcpad = GST_PAD (realsink);
1862    link->sinkpad = GST_PAD (realsrc);
1863  }
1864
1865  if (GST_RPAD_DIRECTION (link->srcpad) != GST_PAD_SRC) {
1866    GST_CAT_INFO (GST_CAT_PADS,
1867        "Real src pad %s:%s is not a source pad, failed",
1868        GST_DEBUG_PAD_NAME (link->srcpad));
1869    gst_pad_link_free (link);
1870    return FALSE;
1871  }
1872  if (GST_RPAD_DIRECTION (link->sinkpad) != GST_PAD_SINK) {
1873    GST_CAT_INFO (GST_CAT_PADS, "Real sink pad %s:%s is not a sink pad, failed",
1874        GST_DEBUG_PAD_NAME (link->sinkpad));
1875    gst_pad_link_free (link);
1876    return FALSE;
1877  }
1878
1879  link->srccaps = gst_pad_get_caps (link->srcpad);
1880  link->sinkcaps = gst_pad_get_caps (link->sinkpad);
1881  if (filtercaps)
1882    link->filtercaps = gst_caps_copy (filtercaps);
1883  if (gst_pad_link_try (link) == GST_PAD_LINK_REFUSED)
1884    return FALSE;
1885
1886  /* fire off a signal to each of the pads telling them
1887   * that they've been linked */
1888  g_signal_emit (G_OBJECT (link->srcpad), gst_real_pad_signals[REAL_LINKED],
1889      0, link->sinkpad);
1890  g_signal_emit (G_OBJECT (link->sinkpad), gst_real_pad_signals[REAL_LINKED],
1891      0, link->srcpad);
1892
1893  src_sched = gst_pad_get_scheduler (GST_PAD (link->srcpad));
1894  sink_sched = gst_pad_get_scheduler (GST_PAD (link->sinkpad));
1895
1896  /* now tell the scheduler */
1897  if (src_sched && src_sched == sink_sched) {
1898    gst_scheduler_pad_link (src_sched,
1899        GST_PAD (link->srcpad), GST_PAD (link->sinkpad));
1900  } else {
1901    GST_CAT_INFO (GST_CAT_PADS,
1902        "not telling link to scheduler %s:%s and %s:%s, %p %p",
1903        GST_DEBUG_PAD_NAME (link->srcpad), GST_DEBUG_PAD_NAME (link->sinkpad),
1904        src_sched, sink_sched);
1905  }
1906
1907  GST_CAT_INFO (GST_CAT_PADS, "linked %s:%s and %s:%s, successful",
1908      GST_DEBUG_PAD_NAME (link->srcpad), GST_DEBUG_PAD_NAME (link->sinkpad));
1909
1910  return TRUE;
1911}
1912
1913/**
1914 * gst_pad_link:
1915 * @srcpad: the source #GstPad to link.
1916 * @sinkpad: the sink #GstPad to link.
1917 *
1918 * Links the source pad to the sink pad.
1919 *
1920 * Returns: TRUE if the pad could be linked, FALSE otherwise.
1921 */
1922gboolean
1923gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
1924{
1925  return gst_pad_link_filtered (srcpad, sinkpad, NULL);
1926}
1927
1928/* FIXME 0.9: Remove this */
1929/**
1930 * gst_pad_set_parent:
1931 * @pad: a #GstPad to set the parent of.
1932 * @parent: the new parent #GstElement.
1933 *
1934 * Sets the parent object of a pad. Deprecated, use gst_object_set_parent()
1935 * instead.
1936 */
1937void
1938gst_pad_set_parent (GstPad * pad, GstElement * parent)
1939{
1940  g_return_if_fail (GST_IS_PAD (pad));
1941  g_return_if_fail (GST_PAD_PARENT (pad) == NULL);
1942  g_return_if_fail (GST_IS_ELEMENT (parent));
1943
1944  gst_object_set_parent (GST_OBJECT (pad), GST_OBJECT (parent));
1945}
1946
1947/* FIXME 0.9: Remove this */
1948/**
1949 * gst_pad_get_parent:
1950 * @pad: the #GstPad to get the parent of.
1951 *
1952 * Gets the parent object of this pad. Deprecated, use gst_object_get_parent()
1953 * instead.
1954 *
1955 * Returns: the parent #GstElement.
1956 */
1957GstElement *
1958gst_pad_get_parent (GstPad * pad)
1959{
1960  g_return_val_if_fail (pad != NULL, NULL);
1961  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1962
1963  return GST_PAD_PARENT (pad);
1964}
1965
1966static void
1967gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ)
1968{
1969  /* this function would need checks if it weren't static */
1970
1971  gst_object_replace ((GstObject **) & pad->padtemplate, (GstObject *) templ);
1972
1973  if (templ) {
1974    gst_object_sink (GST_OBJECT (templ));
1975    g_signal_emit (G_OBJECT (templ),
1976        gst_pad_template_signals[TEMPL_PAD_CREATED], 0, pad);
1977  }
1978}
1979
1980/**
1981 * gst_pad_get_pad_template:
1982 * @pad: a #GstPad.
1983 *
1984 * Gets the template for @pad.
1985 *
1986 * Returns: the #GstPadTemplate from which this pad was instantiated, or %NULL
1987 * if this pad has no template.
1988 */
1989GstPadTemplate *
1990gst_pad_get_pad_template (GstPad * pad)
1991{
1992  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1993
1994  return GST_PAD_PAD_TEMPLATE (pad);
1995}
1996
1997
1998/**
1999 * gst_pad_get_scheduler:
2000 * @pad: a #GstPad to get the scheduler of.
2001 *
2002 * Gets the scheduler of the pad. Since the pad does not
2003 * have a scheduler of its own, the scheduler of the parent
2004 * is taken. For decoupled pads, the scheduler of the peer
2005 * parent is taken.
2006 *
2007 * Returns: the #GstScheduler of the pad, or %NULL if there is no parent or the
2008 * parent is not yet in a managing bin.
2009 */
2010GstScheduler *
2011gst_pad_get_scheduler (GstPad * pad)
2012{
2013  GstScheduler *scheduler = NULL;
2014  GstElement *parent;
2015
2016  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2017
2018  parent = gst_pad_get_parent (pad);
2019  if (parent) {
2020    if (GST_FLAG_IS_SET (parent, GST_ELEMENT_DECOUPLED)) {
2021      GstRealPad *peer = GST_RPAD_PEER (pad);
2022
2023      if (peer) {
2024        scheduler =
2025            gst_element_get_scheduler (gst_pad_get_parent (GST_PAD (peer)));
2026      }
2027    } else {
2028      scheduler = gst_element_get_scheduler (parent);
2029    }
2030  }
2031
2032  return scheduler;
2033}
2034
2035/**
2036 * gst_pad_get_real_parent:
2037 * @pad: a #GstPad to get the real parent of.
2038 *
2039 * Gets the real parent object of this pad. If the pad
2040 * is a ghost pad, the actual owner of the real pad is
2041 * returned, as opposed to #gst_pad_get_parent().
2042 *
2043 * Returns: the parent #GstElement.
2044 */
2045GstElement *
2046gst_pad_get_real_parent (GstPad * pad)
2047{
2048  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2049
2050  return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad)));
2051}
2052
2053/* FIXME 0.9: Make static. */
2054/**
2055 * gst_pad_add_ghost_pad:
2056 * @pad: a #GstPad to attach the ghost pad to.
2057 * @ghostpad: the ghost #GstPad to to the pad.
2058 *
2059 * Adds a ghost pad to a pad. Private function, will be removed from the API in
2060 * 0.9.
2061 */
2062void
2063gst_pad_add_ghost_pad (GstPad * pad, GstPad * ghostpad)
2064{
2065  GstRealPad *realpad;
2066
2067  g_return_if_fail (GST_IS_PAD (pad));
2068  g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
2069
2070  /* if we're ghosting a ghost pad, drill down to find the real pad */
2071  realpad = (GstRealPad *) pad;
2072  while (GST_IS_GHOST_PAD (realpad))
2073    realpad = GST_GPAD_REALPAD (realpad);
2074  g_return_if_fail (GST_IS_REAL_PAD (realpad));
2075
2076  /* will ref the pad template */
2077  GST_GPAD_REALPAD (ghostpad) = realpad;
2078  realpad->ghostpads = g_list_prepend (realpad->ghostpads, ghostpad);
2079  gst_pad_set_pad_template (GST_PAD (ghostpad), GST_PAD_PAD_TEMPLATE (pad));
2080}
2081
2082/* FIXME 0.9: Make static. */
2083/**
2084 * gst_pad_remove_ghost_pad:
2085 * @pad: a #GstPad to remove the ghost pad from.
2086 * @ghostpad: the ghost #GstPad to remove from the pad.
2087 *
2088 * Removes a ghost pad from a pad. Private, will be removed from the API in 0.9.
2089 */
2090void
2091gst_pad_remove_ghost_pad (GstPad * pad, GstPad * ghostpad)
2092{
2093  GstRealPad *realpad;
2094
2095  g_return_if_fail (GST_IS_PAD (pad));
2096  g_return_if_fail (GST_IS_GHOST_PAD (ghostpad));
2097  realpad = GST_PAD_REALIZE (pad);
2098  g_return_if_fail (GST_GPAD_REALPAD (ghostpad) == realpad);
2099
2100  gst_pad_set_pad_template (GST_PAD (ghostpad), NULL);
2101  realpad->ghostpads = g_list_remove (realpad->ghostpads, ghostpad);
2102  GST_GPAD_REALPAD (ghostpad) = NULL;
2103}
2104
2105/**
2106 * gst_pad_get_ghost_pad_list:
2107 * @pad: a #GstPad to get the ghost pads of.
2108 *
2109 * Gets the ghost pads of this pad.
2110 *
2111 * Returns: a #GList of ghost pads.
2112 */
2113GList *
2114gst_pad_get_ghost_pad_list (GstPad * pad)
2115{
2116  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2117
2118  return GST_PAD_REALIZE (pad)->ghostpads;
2119}
2120
2121static gboolean
2122_gst_pad_default_fixate_value (const GValue * value, GValue * dest)
2123{
2124  GType type = G_VALUE_TYPE (value);
2125
2126  if (gst_value_is_fixed (value))
2127    return TRUE;
2128
2129  if (type == GST_TYPE_INT_RANGE) {
2130    g_value_init (dest, G_TYPE_INT);
2131    g_value_set_int (dest, gst_value_get_int_range_min (value));
2132  } else if (type == GST_TYPE_DOUBLE_RANGE) {
2133    g_value_init (dest, G_TYPE_DOUBLE);
2134    g_value_set_double (dest, gst_value_get_double_range_min (value));
2135  } else if (type == GST_TYPE_LIST) {
2136    gst_value_init_and_copy (dest, gst_value_list_get_value (value, 0));
2137  } else if (type == GST_TYPE_FIXED_LIST) {
2138    gint size, n;
2139    GValue dest_kid = { 0 };
2140    const GValue *kid;
2141
2142    /* check recursively */
2143    g_value_init (dest, GST_TYPE_FIXED_LIST);
2144    size = gst_value_list_get_size (value);
2145    for (n = 0; n < size; n++) {
2146      kid = gst_value_list_get_value (value, n);
2147      if (_gst_pad_default_fixate_value (kid, &dest_kid)) {
2148        gst_value_list_append_value (dest, kid);
2149      } else {
2150        gst_value_list_append_value (dest, &dest_kid);
2151        g_value_unset (&dest_kid);
2152      }
2153    }
2154  } else {
2155    g_critical ("Don't know how to fixate value type %s", g_type_name (type));
2156  }
2157
2158  return FALSE;
2159}
2160
2161static gboolean
2162_gst_pad_default_fixate_foreach (GQuark field_id, GValue * value, gpointer s)
2163{
2164  GstStructure *structure = (GstStructure *) s;
2165  GValue dest = { 0 };
2166
2167  if (_gst_pad_default_fixate_value (value, &dest))
2168    return TRUE;
2169  gst_structure_id_set_value (structure, field_id, &dest);
2170  g_value_unset (&dest);
2171
2172  return FALSE;
2173}
2174
2175static GstCaps *
2176_gst_pad_default_fixate_func (GstPad * pad, const GstCaps * caps)
2177{
2178  static GstStaticCaps octetcaps = GST_STATIC_CAPS ("application/octet-stream");
2179  GstStructure *structure;
2180  GstCaps *newcaps;
2181
2182  g_return_val_if_fail (pad != NULL, NULL);
2183  g_return_val_if_fail (caps != NULL, NULL);
2184  g_return_val_if_fail (!gst_caps_is_empty (caps), NULL);
2185
2186  if (gst_caps_is_any (caps)) {
2187    return gst_caps_copy (gst_static_caps_get (&octetcaps));
2188  }
2189
2190  if (caps->structs->len > 1) {
2191    return gst_caps_new_full (gst_structure_copy (gst_caps_get_structure (caps,
2192                0)), NULL);
2193  }
2194
2195  newcaps = gst_caps_copy (caps);
2196  structure = gst_caps_get_structure (newcaps, 0);
2197  gst_structure_foreach (structure, _gst_pad_default_fixate_foreach, structure);
2198
2199  return newcaps;
2200}
2201
2202/**
2203 * gst_pad_perform_negotiate:
2204 * @srcpad: the source #GstPad.
2205 * @sinkpad: the sink #GstPad.
2206 *
2207 * Tries to negotiate the pads. See gst_pad_renegotiate() for a brief
2208 * description of caps negotiation.
2209 *
2210 * Returns: TRUE if the pads were succesfully negotiated, FALSE otherwise.
2211 */
2212gboolean
2213gst_pad_perform_negotiate (GstPad * srcpad, GstPad * sinkpad)
2214{
2215  return GST_PAD_LINK_SUCCESSFUL (gst_pad_renegotiate (srcpad));
2216}
2217
2218static void
2219gst_pad_link_unnegotiate (GstPadLink * link)
2220{
2221  g_return_if_fail (link != NULL);
2222
2223  if (link->caps) {
2224    gst_caps_free (link->caps);
2225    link->caps = NULL;
2226    link->engaged = FALSE;
2227    if (GST_RPAD_LINK (link->srcpad) != link) {
2228      g_warning ("unnegotiating unset link");
2229    } else {
2230      g_object_notify (G_OBJECT (link->srcpad), "caps");
2231    }
2232    if (GST_RPAD_LINK (link->sinkpad) != link) {
2233      g_warning ("unnegotiating unset link");
2234    } else {
2235      g_object_notify (G_OBJECT (link->sinkpad), "caps");
2236    }
2237  }
2238}
2239
2240/**
2241 * gst_pad_unnegotiate:
2242 * @pad: pad to unnegotiate
2243 *
2244 * "Unnegotiates" a pad. The currently negotiated caps are cleared and the pad
2245 * needs renegotiation.
2246 */
2247void
2248gst_pad_unnegotiate (GstPad * pad)
2249{
2250  GstPadLink *link;
2251
2252  g_return_if_fail (GST_IS_PAD (pad));
2253
2254  link = GST_RPAD_LINK (GST_PAD_REALIZE (pad));
2255  if (link)
2256    gst_pad_link_unnegotiate (link);
2257}
2258
2259/* returning NULL indicates that the arguments are invalid */
2260static GstPadLink *
2261gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad,
2262    const GstCaps * filtercaps)
2263{
2264  GstRealPad *realsrc, *realsink;
2265  GstPadLink *link;
2266
2267  g_return_val_if_fail (GST_IS_PAD (srcpad), NULL);
2268  g_return_val_if_fail (GST_IS_PAD (sinkpad), NULL);
2269
2270  realsrc = GST_PAD_REALIZE (srcpad);
2271  realsink = GST_PAD_REALIZE (sinkpad);
2272
2273  if ((GST_PAD (realsrc) != srcpad) || (GST_PAD (realsink) != sinkpad)) {
2274    GST_CAT_DEBUG (GST_CAT_PADS, "*actually* linking %s:%s and %s:%s",
2275        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
2276  }
2277
2278  g_return_val_if_fail (GST_RPAD_PEER (realsrc) == NULL, NULL);
2279  g_return_val_if_fail (GST_RPAD_PEER (realsink) == NULL, NULL);
2280  g_return_val_if_fail (GST_PAD_PARENT (realsrc) != NULL, NULL);
2281  g_return_val_if_fail (GST_PAD_PARENT (realsink) != NULL, NULL);
2282
2283  if (!gst_pad_check_schedulers (realsrc, realsink)) {
2284    g_warning ("linking pads with different scheds requires "
2285        "exactly one decoupled element (such as queue)");
2286    return NULL;
2287  }
2288
2289  if (GST_RPAD_DIRECTION (realsrc) == GST_RPAD_DIRECTION (realsink)) {
2290    g_warning ("%s:%s and %s:%s are both %s pads, failed",
2291        GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink),
2292        GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC ? "src" : "sink");
2293    return NULL;
2294  }
2295
2296  link = gst_pad_link_new ();
2297
2298  if (GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) {
2299    link->srcpad = GST_PAD (realsrc);
2300    link->sinkpad = GST_PAD (realsink);
2301  } else {
2302    link->srcpad = GST_PAD (realsink);
2303    link->sinkpad = GST_PAD (realsrc);
2304  }
2305
2306  link->srccaps = gst_pad_get_caps (link->srcpad);
2307  link->sinkcaps = gst_pad_get_caps (link->sinkpad);
2308  if (filtercaps)
2309    link->filtercaps = gst_caps_copy (filtercaps);
2310
2311  return link;
2312}
2313
2314/**
2315 * gst_pad_try_relink_filtered:
2316 * @srcpad: the source #GstPad to relink.
2317 * @sinkpad: the sink #GstPad to relink.
2318 * @filtercaps: the #GstPad to use as a filter in the relink.
2319 *
2320 * Tries to relink the given source and sink pad, constrained by the given
2321 * capabilities.
2322 *
2323 * Returns: TRUE if the pads were succesfully renegotiated, FALSE otherwise.
2324 */
2325gboolean
2326gst_pad_try_relink_filtered (GstPad * srcpad, GstPad * sinkpad,
2327    const GstCaps * filtercaps)
2328{
2329  GstPadLink *link;
2330
2331  GST_INFO ("trying to relink %" GST_PTR_FORMAT " and %" GST_PTR_FORMAT
2332      " with filtercaps %" GST_PTR_FORMAT, srcpad, sinkpad);
2333
2334  link = gst_pad_link_prepare (srcpad, sinkpad, filtercaps);
2335  if (!link)
2336    return FALSE;
2337
2338  if (GST_RPAD_PEER (link->srcpad) != (GstRealPad *) link->sinkpad) {
2339    g_warning ("Pads %s:%s and %s:%s were never linked",
2340        GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
2341    gst_pad_link_free (link);
2342    return FALSE;
2343  }
2344
2345  if (GST_PAD_LINK_FAILED (gst_pad_link_try (link)))
2346    return FALSE;
2347
2348  return TRUE;
2349}
2350
2351/**
2352 * gst_pad_relink_filtered:
2353 * @srcpad: the source #GstPad to relink.
2354 * @sinkpad: the sink #GstPad to relink.
2355 * @filtercaps: the #GstPad to use as a filter in the relink.
2356 *
2357 * Relinks the given source and sink pad, constrained by the given
2358 * capabilities.  If the relink fails, the pads are unlinked
2359 * and FALSE is returned.
2360 *
2361 * Returns: TRUE if the pads were succesfully relinked, FALSE otherwise.
2362 */
2363gboolean
2364gst_pad_relink_filtered (GstPad * srcpad, GstPad * sinkpad,
2365    const GstCaps * filtercaps)
2366{
2367  if (gst_pad_try_relink_filtered (srcpad, sinkpad, filtercaps))
2368    return TRUE;
2369
2370  gst_pad_unlink (srcpad, sinkpad);
2371  return FALSE;
2372}
2373
2374/**
2375 * gst_pad_proxy_getcaps:
2376 * @pad: a #GstPad to proxy.
2377 *
2378 * Calls gst_pad_get_allowed_caps() for every other pad belonging to the
2379 * same element as @pad, and returns the intersection of the results.
2380 *
2381 * This function is useful as a default getcaps function for an element
2382 * that can handle any stream format, but requires all its pads to have
2383 * the same caps.  Two such elements are tee and aggregator.
2384 *
2385 * Returns: the intersection of the other pads' allowed caps.
2386 */
2387GstCaps *
2388gst_pad_proxy_getcaps (GstPad * pad)
2389{
2390  GstElement *element;
2391  const GList *pads;
2392  GstCaps *caps, *intersected;
2393
2394  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2395
2396  GST_DEBUG ("proxying getcaps for %s:%s", GST_DEBUG_PAD_NAME (pad));
2397
2398  element = gst_pad_get_parent (pad);
2399
2400  pads = gst_element_get_pad_list (element);
2401
2402  caps = gst_caps_new_any ();
2403  while (pads) {
2404    GstPad *otherpad = GST_PAD (pads->data);
2405    GstCaps *temp;
2406
2407    if (otherpad != pad) {
2408      GstCaps *allowed = gst_pad_get_allowed_caps (otherpad);
2409
2410      temp = gst_caps_intersect (caps, allowed);
2411      gst_caps_free (caps);
2412      gst_caps_free (allowed);
2413      caps = temp;
2414    }
2415
2416    pads = g_list_next (pads);
2417  }
2418
2419  intersected = gst_caps_intersect (caps, gst_pad_get_pad_template_caps (pad));
2420  gst_caps_free (caps);
2421  return intersected;
2422}
2423
2424/**
2425 * gst_pad_proxy_pad_link:
2426 * @pad: a #GstPad to proxy from
2427 * @caps: the #GstCaps to link with
2428 *
2429 * Calls gst_pad_try_set_caps() for every other pad belonging to the
2430 * same element as @pad.  If gst_pad_try_set_caps() fails on any pad,
2431 * the proxy link fails. May be used only during negotiation.
2432 *
2433 * Returns: GST_PAD_LINK_OK if sucessful
2434 */
2435GstPadLinkReturn
2436gst_pad_proxy_pad_link (GstPad * pad, const GstCaps * caps)
2437{
2438  GstElement *element;
2439  const GList *pads;
2440  GstPadLinkReturn ret;
2441
2442  g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_LINK_REFUSED);
2443  g_return_val_if_fail (caps != NULL, GST_PAD_LINK_REFUSED);
2444
2445  GST_DEBUG ("proxying pad link for %s:%s", GST_DEBUG_PAD_NAME (pad));
2446
2447  element = gst_pad_get_parent (pad);
2448
2449  pads = gst_element_get_pad_list (element);
2450
2451  while (pads) {
2452    GstPad *otherpad = GST_PAD (pads->data);
2453
2454    if (otherpad != pad) {
2455      ret = gst_pad_try_set_caps (otherpad, caps);
2456      if (GST_PAD_LINK_FAILED (ret)) {
2457        return ret;
2458      }
2459    }
2460    pads = g_list_next (pads);
2461  }
2462
2463  return GST_PAD_LINK_OK;
2464}
2465
2466/**
2467 * gst_pad_proxy_fixate:
2468 * @pad: a #GstPad to proxy.
2469 * @caps: the #GstCaps to fixate
2470 *
2471 * Implements a default fixate function based on the caps set on the other
2472 * pads in the element.  This function should only be used if every pad
2473 * has the same pad template caps.
2474 *
2475 * Returns: a fixated caps, or NULL if caps cannot be fixed
2476 */
2477GstCaps *
2478gst_pad_proxy_fixate (GstPad * pad, const GstCaps * caps)
2479{
2480  GstElement *element;
2481  const GList *pads;
2482  const GstCaps *othercaps;
2483
2484  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2485  g_return_val_if_fail (caps != NULL, NULL);
2486
2487  GST_DEBUG ("proxying fixate for %s:%s\n", GST_DEBUG_PAD_NAME (pad));
2488
2489  element = gst_pad_get_parent (pad);
2490
2491  pads = gst_element_get_pad_list (element);
2492
2493  while (pads) {
2494    GstPad *otherpad = GST_PAD (pads->data);
2495
2496    /* FIXME check that each pad has the same pad template caps */
2497
2498    if (otherpad != pad) {
2499      othercaps = gst_pad_get_negotiated_caps (otherpad);
2500
2501      if (othercaps && !gst_caps_is_subset (caps, othercaps)) {
2502        GstCaps *icaps;
2503
2504        icaps = gst_caps_intersect (othercaps, caps);
2505        if (!gst_caps_is_empty (icaps)) {
2506          return icaps;
2507        } else {
2508          gst_caps_free (icaps);
2509        }
2510      }
2511    }
2512    pads = g_list_next (pads);
2513  }
2514
2515  return NULL;
2516}
2517
2518/**
2519 * gst_pad_set_explicit_caps:
2520 * @pad: a #GstPad to set the explicit caps of
2521 * @caps: the #GstCaps to set
2522 *
2523 * If a pad has been told to use explicit caps, this function is used
2524 * to set the explicit caps.  If @caps is NULL, the explicit caps are
2525 * unset.
2526 *
2527 * This function calls gst_pad_try_set_caps() on the pad.  If that
2528 * call fails, GST_ELEMENT_ERROR() is called to indicate a negotiation
2529 * failure.
2530 *
2531 * Returns: TRUE if the caps were set correctly, otherwise FALSE
2532 */
2533gboolean
2534gst_pad_set_explicit_caps (GstPad * pad, const GstCaps * caps)
2535{
2536  GstPadLinkReturn link_ret;
2537
2538  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2539  g_return_val_if_fail (caps == NULL || gst_caps_is_fixed (caps), FALSE);
2540
2541  GST_CAT_DEBUG (GST_CAT_PADS,
2542      "setting explicit caps on %s:%s to %" GST_PTR_FORMAT,
2543      GST_DEBUG_PAD_NAME (pad), caps);
2544
2545  if (caps == NULL) {
2546    GST_CAT_DEBUG (GST_CAT_PADS, "caps is NULL");
2547    gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
2548    return TRUE;
2549  }
2550
2551  gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), gst_caps_copy (caps));
2552
2553  if (!GST_PAD_IS_LINKED (pad)) {
2554    GST_CAT_DEBUG (GST_CAT_PADS, "pad is not linked");
2555    return TRUE;
2556  }
2557  link_ret = gst_pad_try_set_caps (pad, caps);
2558  if (link_ret == GST_PAD_LINK_REFUSED) {
2559    gchar *caps_str = gst_caps_to_string (caps);
2560
2561    GST_ELEMENT_ERROR (gst_pad_get_parent (pad), CORE, PAD, (NULL),
2562        ("failed to negotiate (try_set_caps with \"%s\" returned REFUSED)",
2563            caps_str));
2564    g_free (caps_str);
2565    return FALSE;
2566  }
2567
2568  return TRUE;
2569}
2570
2571static GstCaps *
2572gst_pad_explicit_getcaps (GstPad * pad)
2573{
2574  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2575
2576  if (GST_RPAD_EXPLICIT_CAPS (pad) == NULL) {
2577    const GstCaps *caps = gst_pad_get_pad_template_caps (pad);
2578
2579    return gst_caps_copy (caps);
2580  }
2581  return gst_caps_copy (GST_RPAD_EXPLICIT_CAPS (pad));
2582}
2583
2584static GstPadLinkReturn
2585gst_pad_explicit_link (GstPad * pad, const GstCaps * caps)
2586{
2587  g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_LINK_REFUSED);
2588  g_return_val_if_fail (caps != NULL, GST_PAD_LINK_REFUSED);
2589
2590  if (GST_RPAD_EXPLICIT_CAPS (pad) == NULL) {
2591    return GST_PAD_LINK_DELAYED;
2592  }
2593
2594  return GST_PAD_LINK_OK;
2595}
2596
2597/**
2598 * gst_pad_use_explicit_caps:
2599 * @pad: a #GstPad to set to use explicit caps
2600 *
2601 * This function handles negotiation for pads that need to be set
2602 * to particular caps under complete control of the element, based
2603 * on some state in the element.  This is often the case with
2604 * decoders and other elements whose caps is determined by the data
2605 * stream.
2606 *
2607 * WARNING: This function is a hack and will be replaced with something
2608 * better in gstreamer-0.9.
2609 */
2610void
2611gst_pad_use_explicit_caps (GstPad * pad)
2612{
2613  g_return_if_fail (GST_IS_PAD (pad));
2614
2615  gst_pad_set_getcaps_function (pad, gst_pad_explicit_getcaps);
2616  gst_pad_set_link_function (pad, gst_pad_explicit_link);
2617  gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
2618}
2619
2620/**
2621 * gst_pad_proxy_link:
2622 * @pad: a #GstPad to proxy to.
2623 * @caps: the #GstCaps to use in proxying.
2624 *
2625 * Proxies the link function to the specified pad.
2626 *
2627 * Returns: TRUE if the peer pad accepted the caps, FALSE otherwise.
2628 */
2629GstPadLinkReturn
2630gst_pad_proxy_link (GstPad * pad, const GstCaps * caps)
2631{
2632  return gst_pad_try_set_caps (pad, caps);
2633}
2634
2635/**
2636 * gst_pad_is_negotiated:
2637 * @pad: a #GstPad to get the negotiation status of
2638 *
2639 * Returns: TRUE if the pad has successfully negotiated caps.
2640 */
2641gboolean
2642gst_pad_is_negotiated (GstPad * pad)
2643{
2644  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2645
2646  if (!(pad = (GstPad *) GST_PAD_REALIZE (pad)))
2647    return FALSE;
2648  if (!GST_RPAD_LINK (pad))
2649    return FALSE;
2650
2651  return (GST_RPAD_LINK (pad)->caps != NULL);
2652}
2653
2654/**
2655 * gst_pad_get_negotiated_caps:
2656 * @pad: a #GstPad to get the negotiated capabilites of
2657 *
2658 * Gets the currently negotiated caps of a pad.
2659 *
2660 * Returns: the currently negotiated caps of a pad, or NULL if the pad isn't
2661 *          negotiated.
2662 */
2663G_CONST_RETURN GstCaps *
2664gst_pad_get_negotiated_caps (GstPad * pad)
2665{
2666  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2667
2668  if (!(pad = (GstPad *) GST_PAD_REALIZE (pad)))
2669    return NULL;
2670  if (!GST_RPAD_LINK (pad))
2671    return NULL;
2672
2673  return GST_RPAD_LINK (pad)->caps;
2674}
2675
2676/**
2677 * gst_pad_get_caps:
2678 * @pad: a  #GstPad to get the capabilities of.
2679 *
2680 * Gets the capabilities of this pad.
2681 *
2682 * Returns: the #GstCaps of this pad. This function returns a new caps, so use
2683 * gst_caps_free to get rid of it.
2684 */
2685GstCaps *
2686gst_pad_get_caps (GstPad * pad)
2687{
2688  GstRealPad *realpad;
2689
2690  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2691
2692  realpad = GST_PAD_REALIZE (pad);
2693
2694  GST_CAT_DEBUG (GST_CAT_CAPS, "get pad caps of %s:%s (%p)",
2695      GST_DEBUG_PAD_NAME (realpad), realpad);
2696
2697  if (GST_PAD_IS_DISPATCHING (realpad))
2698    GST_CAT_DEBUG (GST_CAT_CAPS,
2699        "pad %s:%s is already dispatching -- looking for a template",
2700        GST_DEBUG_PAD_NAME (realpad));
2701
2702  if (GST_RPAD_GETCAPSFUNC (realpad) && !GST_PAD_IS_DISPATCHING (realpad)) {
2703    GstCaps *caps;
2704
2705    GST_CAT_DEBUG (GST_CAT_CAPS, "dispatching to pad getcaps function");
2706
2707    GST_FLAG_SET (realpad, GST_PAD_DISPATCHING);
2708    caps = GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD (realpad));
2709    GST_FLAG_UNSET (realpad, GST_PAD_DISPATCHING);
2710
2711    if (caps == NULL) {
2712      g_critical ("pad %s:%s returned NULL caps from getcaps function\n",
2713          GST_DEBUG_PAD_NAME (realpad));
2714    } else {
2715#ifndef G_DISABLE_ASSERT
2716      /* check that the returned caps are a real subset of the template caps */
2717      if (GST_PAD_PAD_TEMPLATE (realpad)) {
2718        const GstCaps *templ_caps =
2719            GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (realpad));
2720        if (!gst_caps_is_subset (caps, templ_caps)) {
2721          GstCaps *temp;
2722
2723          GST_CAT_ERROR_OBJECT (GST_CAT_CAPS, pad,
2724              "pad returned caps %" GST_PTR_FORMAT
2725              " which are not a real subset of its template caps %"
2726              GST_PTR_FORMAT, caps, templ_caps);
2727          g_warning
2728              ("pad %s:%s returned caps that are not a real subset of its template caps",
2729              GST_DEBUG_PAD_NAME (realpad));
2730          temp = gst_caps_intersect (templ_caps, caps);
2731          gst_caps_free (caps);
2732          caps = temp;
2733        }
2734      }
2735#endif
2736      return caps;
2737    }
2738  }
2739  if (GST_PAD_PAD_TEMPLATE (realpad)) {
2740    GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (realpad);
2741    const GstCaps *caps;
2742
2743    caps = GST_PAD_TEMPLATE_CAPS (templ);
2744    GST_CAT_DEBUG (GST_CAT_CAPS,
2745        "using pad template %p with caps %" GST_PTR_FORMAT, templ, caps);
2746
2747#if 0
2748    /* FIXME we should enable something like this someday, but this is
2749     * a bit buggy */
2750    if (!gst_caps_is_fixed (caps)) {
2751      g_warning
2752          ("pad %s:%s (%p) has no getcaps function and the pad template returns non-fixed caps.  Element is probably broken.\n",
2753          GST_DEBUG_PAD_NAME (realpad), realpad);
2754    }
2755#endif
2756
2757    return gst_caps_copy (GST_PAD_TEMPLATE_CAPS (templ));
2758  }
2759  GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps");
2760
2761#if 0
2762  /* FIXME enable */
2763  g_warning ("pad %s:%s (%p) has no pad template\n",
2764      GST_DEBUG_PAD_NAME (realpad), realpad);
2765#endif
2766
2767  return gst_caps_new_any ();
2768}
2769
2770/**
2771 * gst_pad_get_pad_template_caps:
2772 * @pad: a #GstPad to get the template capabilities from.
2773 *
2774 * Gets the capabilities for @pad's template.
2775 *
2776 * Returns: the #GstCaps of this pad template. If you intend to keep a reference
2777 * on the caps, make a copy (see gst_caps_copy ()).
2778 */
2779const GstCaps *
2780gst_pad_get_pad_template_caps (GstPad * pad)
2781{
2782  static GstStaticCaps anycaps = GST_STATIC_CAPS ("ANY");
2783
2784  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2785
2786  if (GST_PAD_PAD_TEMPLATE (pad))
2787    return GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
2788
2789#if 0
2790  /* FIXME this should be enabled some day */
2791  /* wingo: why? mail the list during 0.9 when you find this :) */
2792  g_warning ("pad %s:%s (%p) has no pad template\n",
2793      GST_DEBUG_PAD_NAME (realpad), realpad);
2794#endif
2795
2796  return gst_static_caps_get (&anycaps);
2797}
2798
2799/* FIXME 0.9: This function should probably die, or at least be renamed to
2800 * get_caps_by_format. */
2801/**
2802 * gst_pad_template_get_caps_by_name:
2803 * @templ: a #GstPadTemplate to get the capabilities of.
2804 * @name: the name of the capability to get.
2805 *
2806 * Gets the capability with the given name from @templ.
2807 *
2808 * Returns: the #GstCaps of this pad template, or NULL if not found. If you
2809 * intend to keep a reference on the caps, make a copy (see gst_caps_copy ()).
2810 */
2811const GstCaps *
2812gst_pad_template_get_caps_by_name (GstPadTemplate * templ, const gchar * name)
2813{
2814  GstCaps *caps;
2815
2816  g_return_val_if_fail (templ != NULL, NULL);
2817
2818  caps = GST_PAD_TEMPLATE_CAPS (templ);
2819  if (!caps)
2820    return NULL;
2821
2822  /* FIXME */
2823  return NULL;
2824}
2825
2826/* FIXME 0.9: What good is this if it only works for already-negotiated pads? */
2827/**
2828 * gst_pad_check_compatibility:
2829 * @srcpad: the source #GstPad to check.
2830 * @sinkpad: the sink #GstPad to check against.
2831 *
2832 * Checks if two pads have compatible capabilities. If neither one has yet been
2833 * negotiated, returns TRUE for no good reason.
2834 *
2835 * Returns: TRUE if they are compatible or if the capabilities could not be
2836 * checked, FALSE if the capabilities are not compatible.
2837 */
2838gboolean
2839gst_pad_check_compatibility (GstPad * srcpad, GstPad * sinkpad)
2840{
2841  g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
2842  g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
2843
2844  if (GST_PAD_CAPS (srcpad) && GST_PAD_CAPS (sinkpad)) {
2845    if (!gst_caps_is_always_compatible (GST_PAD_CAPS (srcpad),
2846            GST_PAD_CAPS (sinkpad))) {
2847      return FALSE;
2848    } else {
2849      return TRUE;
2850    }
2851  } else {
2852    GST_CAT_DEBUG (GST_CAT_PADS,
2853        "could not check capabilities of pads (%s:%s) and (%s:%s) %p %p",
2854        GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad),
2855        GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad));
2856    return TRUE;
2857  }
2858}
2859
2860/**
2861 * gst_pad_get_peer:
2862 * @pad: a #GstPad to get the peer of.
2863 *
2864 * Gets the peer of @pad.
2865 *
2866 * Returns: the peer #GstPad.
2867 */
2868GstPad *
2869gst_pad_get_peer (GstPad * pad)
2870{
2871  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2872
2873  return GST_PAD (GST_PAD_PEER (pad));
2874}
2875
2876/**
2877 * gst_pad_get_allowed_caps:
2878 * @pad: a real #GstPad.
2879 *
2880 * Gets the capabilities of the allowed media types that can flow through @pad.
2881 * The caller must free the resulting caps.
2882 *
2883 * Returns: the allowed #GstCaps of the pad link.  Free the caps when
2884 * you no longer need it.
2885 */
2886GstCaps *
2887gst_pad_get_allowed_caps (GstPad * pad)
2888{
2889  const GstCaps *mycaps;
2890  GstCaps *caps;
2891  GstCaps *peercaps;
2892  GstCaps *icaps;
2893  GstPadLink *link;
2894
2895  g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL);
2896
2897  GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: getting allowed caps",
2898      GST_DEBUG_PAD_NAME (pad));
2899
2900  mycaps = gst_pad_get_pad_template_caps (pad);
2901  if (GST_RPAD_PEER (pad) == NULL) {
2902    GST_CAT_DEBUG (GST_CAT_PROPERTIES, "%s:%s: no peer, returning template",
2903        GST_DEBUG_PAD_NAME (pad));
2904    return gst_caps_copy (mycaps);
2905  }
2906
2907  peercaps = gst_pad_get_caps (GST_PAD_PEER (pad));
2908  caps = gst_caps_intersect (mycaps, peercaps);
2909  gst_caps_free (peercaps);
2910
2911  link = GST_RPAD_LINK (pad);
2912  if (link->filtercaps) {
2913    icaps = gst_caps_intersect (caps, link->filtercaps);
2914    gst_caps_free (caps);
2915    GST_CAT_DEBUG (GST_CAT_PROPERTIES,
2916        "%s:%s: returning filtered intersection with peer",
2917        GST_DEBUG_PAD_NAME (pad));
2918    return icaps;
2919  } else {
2920    GST_CAT_DEBUG (GST_CAT_PROPERTIES,
2921        "%s:%s: returning unfiltered intersection with peer",
2922        GST_DEBUG_PAD_NAME (pad));
2923    return caps;
2924  }
2925}
2926
2927/**
2928 * gst_pad_caps_change_notify:
2929 * @pad: a #GstPad
2930 *
2931 * Called to indicate that the return value of @pad's getcaps function may have
2932 * changed, and that a renegotiation is suggested.
2933 */
2934void
2935gst_pad_caps_change_notify (GstPad * pad)
2936{
2937}
2938
2939/**
2940 * gst_pad_recover_caps_error:
2941 * @pad: a #GstPad that had a failed capsnego
2942 * @allowed: possible caps for the link
2943 *
2944 * Attempt to recover from a failed caps negotiation. This function
2945 * is typically called by a plugin that exhausted its list of caps
2946 * and wants the application to resolve the issue. The application
2947 * should connect to the pad's caps_nego_failed signal and should
2948 * resolve the issue by connecting another element for example.
2949 *
2950 * Returns: TRUE when the issue was resolved, dumps detailed information
2951 * on the console and returns FALSE otherwise.
2952 */
2953gboolean
2954gst_pad_recover_caps_error (GstPad * pad, const GstCaps * allowed)
2955{
2956  /* FIXME */
2957  return FALSE;
2958}
2959
2960/**
2961 * gst_pad_alloc_buffer:
2962 * @pad: a source #GstPad
2963 * @offset: the offset of the new buffer in the stream
2964 * @size: the size of the new buffer
2965 *
2966 * Allocates a new, empty buffer optimized to push to pad @pad.  This
2967 * function only works if @pad is a source pad.
2968 *
2969 * Returns: a new, empty #GstBuffer, or NULL if there is an error
2970 */
2971GstBuffer *
2972gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size)
2973{
2974  GstRealPad *peer;
2975
2976  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2977  g_return_val_if_fail (GST_PAD_IS_SRC (pad), NULL);
2978
2979  peer = GST_RPAD_PEER (pad);
2980
2981  if (peer && peer->bufferallocfunc) {
2982    GstBuffer *ret;
2983
2984    GST_CAT_DEBUG (GST_CAT_BUFFER, "(%s:%s): getting buffer",
2985        GST_DEBUG_PAD_NAME (pad));
2986    GST_CAT_DEBUG (GST_CAT_PADS,
2987        "calling bufferallocfunc &%s (@%p) of peer pad %s:%s",
2988        GST_DEBUG_FUNCPTR_NAME (peer->bufferallocfunc),
2989        &peer->bufferallocfunc, GST_DEBUG_PAD_NAME (((GstPad *) peer)));
2990
2991    ret = (peer->bufferallocfunc) (GST_PAD (peer), offset, size);
2992    if (ret)
2993      return ret;
2994  }
2995  return gst_buffer_new_and_alloc (size);
2996}
2997
2998static void
2999gst_real_pad_dispose (GObject * object)
3000{
3001  GstPad *pad = GST_PAD (object);
3002
3003  /* No linked pad can ever be disposed.
3004   * It has to have a parent to be linked
3005   * and a parent would hold a reference */
3006  /* FIXME: what about if g_object_dispose is explicitly called on the pad? Is
3007     that legal? otherwise we could assert GST_OBJECT_PARENT (pad) == NULL as
3008     well... */
3009  g_assert (GST_PAD_PEER (pad) == NULL);
3010
3011  GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "dispose %s:%s",
3012      GST_DEBUG_PAD_NAME (pad));
3013
3014  /* we destroy the ghostpads, because they are nothing without the real pad */
3015  if (GST_REAL_PAD (pad)->ghostpads) {
3016    GList *orig, *ghostpads;
3017
3018    orig = ghostpads = g_list_copy (GST_REAL_PAD (pad)->ghostpads);
3019
3020    while (ghostpads) {
3021      GstPad *ghostpad = GST_PAD (ghostpads->data);
3022
3023      if (GST_IS_ELEMENT (GST_OBJECT_PARENT (ghostpad))) {
3024        GstElement *parent = GST_ELEMENT (GST_OBJECT_PARENT (ghostpad));
3025
3026        GST_CAT_DEBUG (GST_CAT_REFCOUNTING,
3027            "removing ghost pad from element '%s'", GST_OBJECT_NAME (parent));
3028        gst_element_remove_pad (parent, ghostpad);
3029      } else {
3030        /* handle the case where we have some floating ghost pad that was never
3031           added to an element */
3032        g_object_set (ghostpad, "real-pad", NULL, NULL);
3033      }
3034      ghostpads = g_list_next (ghostpads);
3035    }
3036    g_list_free (orig);
3037    /* as the ghost pads are removed, they remove themselves from ->ghostpads.
3038       So it should be empty now. Let's assert that. */
3039    g_assert (GST_REAL_PAD (pad)->ghostpads == NULL);
3040  }
3041
3042  if (GST_IS_ELEMENT (GST_OBJECT_PARENT (pad))) {
3043    GST_CAT_DEBUG (GST_CAT_REFCOUNTING, "removing pad from element '%s'",
3044        GST_OBJECT_NAME (GST_OBJECT (GST_ELEMENT (GST_OBJECT_PARENT (pad)))));
3045
3046    gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad);
3047  }
3048
3049  if (GST_RPAD_EXPLICIT_CAPS (pad)) {
3050    GST_ERROR_OBJECT (pad, "still explicit caps %" GST_PTR_FORMAT " set",
3051        GST_RPAD_EXPLICIT_CAPS (pad));
3052    g_warning ("pad %p has still explicit caps set", pad);
3053    gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL);
3054  }
3055  G_OBJECT_CLASS (real_pad_parent_class)->dispose (object);
3056}
3057
3058
3059#ifndef GST_DISABLE_LOADSAVE
3060/* FIXME: why isn't this on a GstElement ? */
3061/**
3062 * gst_pad_load_and_link:
3063 * @self: an #xmlNodePtr to read the description from.
3064 * @parent: the #GstObject element that owns the pad.
3065 *
3066 * Reads the pad definition from the XML node and links the given pad
3067 * in the element to a pad of an element up in the hierarchy.
3068 */
3069void
3070gst_pad_load_and_link (xmlNodePtr self, GstObject * parent)
3071{
3072  xmlNodePtr field = self->xmlChildrenNode;
3073  GstPad *pad = NULL, *targetpad;
3074  gchar *peer = NULL;
3075  gchar **split;
3076  GstElement *target;
3077  GstObject *grandparent;
3078  gchar *name = NULL;
3079
3080  while (field) {
3081    if (!strcmp (field->name, "name")) {
3082      name = xmlNodeGetContent (field);
3083      pad = gst_element_get_pad (GST_ELEMENT (parent), name);
3084      g_free (name);
3085    } else if (!strcmp (field->name, "peer")) {
3086      peer = xmlNodeGetContent (field);
3087    }
3088    field = field->next;
3089  }
3090  g_return_if_fail (pad != NULL);
3091
3092  if (peer == NULL)
3093    return;
3094
3095  split = g_strsplit (peer, ".", 2);
3096
3097  if (split[0] == NULL || split[1] == NULL) {
3098    GST_CAT_DEBUG (GST_CAT_XML,
3099        "Could not parse peer '%s' for pad %s:%s, leaving unlinked",
3100        peer, GST_DEBUG_PAD_NAME (pad));
3101
3102    g_free (peer);
3103    return;
3104  }
3105  g_free (peer);
3106
3107  g_return_if_fail (split[0] != NULL);
3108  g_return_if_fail (split[1] != NULL);
3109
3110  grandparent = gst_object_get_parent (parent);
3111
3112  if (grandparent && GST_IS_BIN (grandparent)) {
3113    target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
3114  } else
3115    goto cleanup;
3116
3117  if (target == NULL)
3118    goto cleanup;
3119
3120  targetpad = gst_element_get_pad (target, split[1]);
3121
3122  if (targetpad == NULL)
3123    goto cleanup;
3124
3125  gst_pad_link (pad, targetpad);
3126
3127cleanup:
3128  g_strfreev (split);
3129}
3130
3131/**
3132 * gst_pad_save_thyself:
3133 * @pad: a #GstPad to save.
3134 * @parent: the parent #xmlNodePtr to save the description in.
3135 *
3136 * Saves the pad into an xml representation.
3137 *
3138 * Returns: the #xmlNodePtr representation of the pad.
3139 */
3140static xmlNodePtr
3141gst_pad_save_thyself (GstObject * object, xmlNodePtr parent)
3142{
3143  GstRealPad *realpad;
3144  GstPad *peer;
3145
3146  g_return_val_if_fail (GST_IS_REAL_PAD (object), NULL);
3147
3148  realpad = GST_REAL_PAD (object);
3149
3150  xmlNewChild (parent, NULL, "name", GST_PAD_NAME (realpad));
3151  if (GST_RPAD_PEER (realpad) != NULL) {
3152    gchar *content;
3153
3154    peer = GST_PAD (GST_RPAD_PEER (realpad));
3155    /* first check to see if the peer's parent's parent is the same */
3156    /* we just save it off */
3157    content = g_strdup_printf ("%s.%s",
3158        GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer));
3159    xmlNewChild (parent, NULL, "peer", content);
3160    g_free (content);
3161  } else
3162    xmlNewChild (parent, NULL, "peer", "");
3163
3164  return parent;
3165}
3166
3167/* FIXME: shouldn't it be gst_pad_ghost_* ?
3168 * dunno -- wingo 7 feb 2004
3169 */
3170/**
3171 * gst_ghost_pad_save_thyself:
3172 * @pad: a ghost #GstPad to save.
3173 * @parent: the parent #xmlNodePtr to save the description in.
3174 *
3175 * Saves the ghost pad into an xml representation.
3176 *
3177 * Returns: the #xmlNodePtr representation of the pad.
3178 */
3179xmlNodePtr
3180gst_ghost_pad_save_thyself (GstPad * pad, xmlNodePtr parent)
3181{
3182  xmlNodePtr self;
3183
3184  g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
3185
3186  self = xmlNewChild (parent, NULL, "ghostpad", NULL);
3187  xmlNewChild (self, NULL, "name", GST_PAD_NAME (pad));
3188  xmlNewChild (self, NULL, "parent", GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
3189
3190  /* FIXME FIXME FIXME! */
3191
3192  return self;
3193}
3194#endif /* GST_DISABLE_LOADSAVE */
3195
3196static GstData *
3197_invent_event (GstPad * pad, GstBuffer * buffer)
3198{
3199  GstEvent *event;
3200  GstEventType event_type;
3201  guint64 offset;
3202
3203  if (GST_BUFFER_OFFSET_IS_VALID (buffer))
3204    event_type = GST_FORMAT_DEFAULT;
3205  else
3206    event_type = GST_FORMAT_UNDEFINED;
3207
3208  offset = GST_BUFFER_OFFSET (buffer);
3209
3210  if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) {
3211    GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
3212
3213    event = gst_event_new_discontinuous (TRUE,
3214        GST_FORMAT_TIME, timestamp, event_type, offset, GST_FORMAT_UNDEFINED);
3215    GST_CAT_WARNING (GST_CAT_SCHEDULING,
3216        "needed to invent a DISCONT %p (time %" G_GUINT64_FORMAT
3217        ") for %s:%s => %s:%s", event, timestamp,
3218        GST_DEBUG_PAD_NAME (GST_PAD_PEER (pad)), GST_DEBUG_PAD_NAME (pad));
3219  } else {
3220    event = gst_event_new_discontinuous (TRUE,
3221        event_type, offset, GST_FORMAT_UNDEFINED);
3222    GST_CAT_WARNING (GST_CAT_SCHEDULING,
3223        "needed to invent a DISCONT %p (no time) for %s:%s => %s:%s", event,
3224        GST_DEBUG_PAD_NAME (GST_PAD_PEER (pad)), GST_DEBUG_PAD_NAME (pad));
3225  }
3226
3227  return GST_DATA (event);
3228}
3229
3230/**
3231 * gst_pad_push:
3232 * @pad: a source #GstPad.
3233 * @data: the #GstData to push.
3234 *
3235 * Pushes a buffer or an event to the peer of @pad. @pad must be linked. May
3236 * only be called by @pad's parent.
3237 */
3238void
3239gst_pad_push (GstPad * pad, GstData * data)
3240{
3241  GstRealPad *peer;
3242
3243  g_return_if_fail (GST_IS_PAD (pad));
3244  g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
3245  g_return_if_fail (!GST_FLAG_IS_SET (GST_PAD_REALIZE (pad),
3246          GST_RPAD_IN_GETFUNC));
3247  g_return_if_fail (data != NULL);
3248
3249  DEBUG_DATA (pad, data, "gst_pad_push");
3250
3251  if (!gst_probe_dispatcher_dispatch (&(GST_REAL_PAD (pad)->probedisp), &data)) {
3252    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3253        "not pushing data %p, blocked by probe", data);
3254    gst_data_unref (data);
3255    return;
3256  }
3257
3258  if (!GST_PAD_IS_LINKED (pad)) {
3259    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3260        "not pushing data %p as pad is unconnected", data);
3261    gst_data_unref (data);
3262    return;
3263  }
3264
3265  if (GST_IS_BUFFER (data) && !gst_pad_is_negotiated (pad)) {
3266    g_warning ("pushing data on non-negotiated pad %s:%s, not allowed.",
3267        GST_DEBUG_PAD_NAME (pad));
3268    gst_data_unref (data);
3269    return;
3270  }
3271
3272  GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing");
3273  peer = GST_RPAD_PEER (pad);
3274
3275  if (!peer) {
3276    g_warning ("push on pad %s:%s but it is unlinked",
3277        GST_DEBUG_PAD_NAME (pad));
3278  } else {
3279    if (!GST_IS_EVENT (data) && !GST_PAD_IS_ACTIVE (peer)) {
3280      g_warning ("push on peer of pad %s:%s but peer is not active",
3281          GST_DEBUG_PAD_NAME (pad));
3282      return;
3283    }
3284
3285    if (peer->chainhandler) {
3286      if (data) {
3287        if (!gst_probe_dispatcher_dispatch (&peer->probedisp, &data)) {
3288          GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3289              "not pushing data %p, blocked by probe", data);
3290          gst_data_unref (data);
3291          return;
3292        }
3293
3294        GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3295            "calling chainhandler &%s of peer pad %s:%s",
3296            GST_DEBUG_FUNCPTR_NAME (peer->chainhandler),
3297            GST_DEBUG_PAD_NAME (GST_PAD (peer)));
3298        (peer->chainhandler) (GST_PAD (peer), data);
3299        return;
3300      } else {
3301        g_warning ("trying to push a NULL buffer on pad %s:%s",
3302            GST_DEBUG_PAD_NAME (peer));
3303        return;
3304      }
3305    } else {
3306      g_warning ("internal error: push on pad %s:%s but it has no chainhandler",
3307          GST_DEBUG_PAD_NAME (peer));
3308    }
3309  }
3310  /* clean up the mess here */
3311  if (data != NULL)
3312    gst_data_unref (data);
3313}
3314
3315/**
3316 * gst_pad_pull:
3317 * @pad: a sink #GstPad.
3318 *
3319 * Pulls an event or a buffer from the peer pad. May only be called by @pad's
3320 * parent.
3321 *
3322 * Returns: a new #GstData from the peer pad.
3323 */
3324GstData *
3325gst_pad_pull (GstPad * pad)
3326{
3327  GstRealPad *peer;
3328  GstData *data;
3329
3330  g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK,
3331      GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)));
3332  g_return_val_if_fail (!GST_FLAG_IS_SET (GST_PAD_REALIZE (pad),
3333          GST_RPAD_IN_CHAINFUNC),
3334      GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)));
3335
3336  peer = GST_RPAD_PEER (pad);
3337
3338  if (!peer) {
3339    GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
3340        ("pull on pad %s:%s but it was unlinked", GST_DEBUG_PAD_NAME (pad)));
3341  } else {
3342  restart:
3343    if (peer->gethandler) {
3344      GstPadLink *link = GST_RPAD_LINK (pad);
3345
3346      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3347          "calling gethandler %s of peer pad %s:%s",
3348          GST_DEBUG_FUNCPTR_NAME (peer->gethandler), GST_DEBUG_PAD_NAME (peer));
3349
3350      if (link->temp_store) {
3351        g_assert (link->engaged);
3352        GST_DEBUG ("moving temp_store %p to data", link->temp_store);
3353        data = link->temp_store;
3354        link->temp_store = NULL;
3355      } else {
3356        data = (peer->gethandler) (GST_PAD (peer));
3357        /* refetch - we might have been relinked */
3358        link = GST_RPAD_LINK (pad);
3359        peer = GST_RPAD_PEER (pad);
3360      }
3361
3362      if (data) {
3363        if (!link->engaged) {
3364          g_assert (link->temp_store == NULL);
3365          if (GST_IS_BUFFER (data)) {
3366            GST_DEBUG ("moving data buffer %p back to temp_store", data);
3367            link->temp_store = data;
3368            link->engaged = TRUE;
3369            data = _invent_event (pad, GST_BUFFER (data));
3370          } else if (GST_IS_EVENT (data) &&
3371              GST_EVENT_TYPE (data) == GST_EVENT_DISCONTINUOUS &&
3372              GST_EVENT_DISCONT_NEW_MEDIA (data)) {
3373            link->engaged = TRUE;
3374            GST_CAT_LOG (GST_CAT_SCHEDULING,
3375                "link engaged by discont event %p for pad %s:%s", data,
3376                GST_DEBUG_PAD_NAME (pad));
3377          }
3378        }
3379        GST_DEBUG ("calling gst_probe_dispatcher_dispatch on data %p", data);
3380        if (!gst_probe_dispatcher_dispatch (&peer->probedisp, &data)) {
3381          GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
3382              "not returning pulled data %p, blocked by probe", data);
3383          gst_data_unref (data);
3384          goto restart;
3385        }
3386        DEBUG_DATA (pad, data, "gst_pad_pull returned");
3387        return data;
3388      }
3389
3390      /* no null buffers allowed */
3391      GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
3392          ("NULL buffer during pull on %s:%s", GST_DEBUG_PAD_NAME (pad)));
3393    } else {
3394      GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
3395          ("pull on pad %s:%s but the peer pad %s:%s has no gethandler",
3396              GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer)));
3397    }
3398  }
3399  data = GST_DATA (gst_event_new (GST_EVENT_INTERRUPT));
3400  DEBUG_DATA (pad, data, "gst_pad_pull returned created");
3401  return data;
3402}
3403
3404GstData *
3405gst_pad_collect_array (GstScheduler * scheduler, GstPad ** selected,
3406    GstPad ** padlist)
3407{
3408  GstSchedulerClass *klass = GST_SCHEDULER_GET_CLASS (scheduler);
3409
3410  if (!GST_FLAG_IS_SET (scheduler, GST_SCHEDULER_FLAG_NEW_API) ||
3411      !klass->pad_select) {
3412    /* better randomness? */
3413    if (selected)
3414      *selected = padlist[0];
3415    return gst_pad_pull (padlist[0]);
3416  } else {
3417    GstPad *select;
3418
3419    return klass->pad_select (scheduler, selected ? selected : &select,
3420        padlist);
3421  }
3422}
3423
3424/**
3425 * gst_pad_collectv:
3426 * @selected: set to the pad the buffer comes from if not NULL
3427 * @padlist: a #GList of sink pads.
3428 *
3429 * Waits for a buffer on any of the list of pads. Each #GstPad in @padlist must
3430 * belong to the same element and be owned by the caller.
3431 *
3432 * Returns: the #GstData that was available
3433 */
3434GstData *
3435gst_pad_collectv (GstPad ** selected, const GList * padlist)
3436{
3437  /* need to use alloca here because we must not leak data */
3438  GstPad **pads;
3439  GstPad *test;
3440  GstElement *element = NULL;
3441  int i = 0;
3442
3443  g_return_val_if_fail (padlist != NULL, NULL);
3444  pads = g_alloca (sizeof (gpointer) * (g_list_length ((GList *) padlist) + 1));
3445  for (; padlist; padlist = g_list_next (padlist)) {
3446    test = GST_PAD (padlist->data);
3447    g_return_val_if_fail (GST_IS_PAD (test), NULL);
3448    g_return_val_if_fail (GST_PAD_IS_SINK (test), NULL);
3449    if (element) {
3450      g_return_val_if_fail (element == gst_pad_get_parent (test), NULL);
3451    } else {
3452      element = gst_pad_get_parent (test);
3453    }
3454    pads[i++] = test;
3455  }
3456  pads[i] = NULL;
3457
3458  return gst_pad_collect_array (GST_ELEMENT_SCHED (element), selected, pads);
3459}
3460
3461/**
3462 * gst_pad_collect:
3463 * @selected: set to the pad the buffer comes from if not NULL
3464 * @pad: first pad
3465 * @...: more sink pads.
3466 *
3467 * Waits for a buffer on the given set of pads.
3468 *
3469 * Returns: the #GstData that was available.
3470 */
3471GstData *
3472gst_pad_collect (GstPad ** selected, GstPad * pad, ...)
3473{
3474  GstData *result;
3475  va_list var_args;
3476
3477  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
3478
3479  va_start (var_args, pad);
3480
3481  result = gst_pad_collect_valist (selected, pad, var_args);
3482
3483  va_end (var_args);
3484
3485  return result;
3486}
3487
3488/**
3489 * gst_pad_collect_valist:
3490 * @selected: set to the pad the buffer comes from if not NULL
3491 * @pad: first pad
3492 * @...: more sink pads.
3493 *
3494 * Waits for a buffer on the given set of pads.
3495 *
3496 * Returns: the #GstData that was available.
3497 */
3498GstData *
3499gst_pad_collect_valist (GstPad ** selected, GstPad * pad, va_list var_args)
3500{
3501  GstPad **padlist;
3502  GstElement *element = NULL;
3503  gint i = 0, maxlength;
3504
3505  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
3506
3507  element = gst_pad_get_parent (pad);
3508  maxlength = element->numsinkpads;
3509  /* can we make this list a bit smaller than this upper limit? */
3510  padlist = g_alloca (sizeof (gpointer) * (maxlength + 1));
3511  while (pad) {
3512    g_return_val_if_fail (i < maxlength, NULL);
3513    g_return_val_if_fail (element == gst_pad_get_parent (pad), NULL);
3514    padlist[i++] = pad;
3515    pad = va_arg (var_args, GstPad *);
3516  }
3517  padlist[i] = NULL;
3518  return gst_pad_collect_array (GST_ELEMENT_SCHED (element), selected, padlist);
3519}
3520
3521/**
3522 * gst_pad_selectv:
3523 * @padlist: a #GList of sink pads.
3524 *
3525 * Waits for a buffer on any of the list of pads. Each #GstPad in @padlist must
3526 * be owned by the calling code.
3527 *
3528 * Returns: the #GstPad that has a buffer available.
3529 * Use #gst_pad_pull() to get the buffer.
3530 */
3531GstPad *
3532gst_pad_selectv (GList * padlist)
3533{
3534  return NULL;
3535}
3536
3537/**
3538 * gst_pad_select_valist:
3539 * @pad: a first #GstPad to perform the select on.
3540 * @varargs: A va_list of more pads to select on.
3541 *
3542 * Waits for a buffer on the given set of pads.
3543 *
3544 * Returns: the #GstPad that has a buffer available.
3545 * Use #gst_pad_pull() to get the buffer.
3546 */
3547GstPad *
3548gst_pad_select_valist (GstPad * pad, va_list var_args)
3549{
3550  GstPad *result;
3551  GList *padlist = NULL;
3552
3553  if (pad == NULL)
3554    return NULL;
3555
3556  while (pad) {
3557    padlist = g_list_prepend (padlist, pad);
3558    pad = va_arg (var_args, GstPad *);
3559  }
3560  result = gst_pad_selectv (padlist);
3561  g_list_free (padlist);
3562
3563  return result;
3564}
3565
3566/**
3567 * gst_pad_select:
3568 * @pad: a first sink #GstPad to perform the select on.
3569 * @...: A NULL-terminated list of more pads to select on.
3570 *
3571 * Waits for a buffer on the given set of pads.
3572 *
3573 * Returns: the #GstPad that has a buffer available.
3574 * Use #gst_pad_pull() to get the buffer.
3575 */
3576GstPad *
3577gst_pad_select (GstPad * pad, ...)
3578{
3579  GstPad *result;
3580  va_list var_args;
3581
3582  if (pad == NULL)
3583    return NULL;
3584
3585  va_start (var_args, pad);
3586
3587  result = gst_pad_select_valist (pad, var_args);
3588
3589  va_end (var_args);
3590
3591  return result;
3592}
3593
3594/************************************************************************
3595 *
3596 * templates
3597 *
3598 */
3599static void gst_pad_template_class_init (GstPadTemplateClass * klass);
3600static void gst_pad_template_init (GstPadTemplate * templ);
3601static void gst_pad_template_dispose (GObject * object);
3602
3603GType
3604gst_pad_template_get_type (void)
3605{
3606  static GType padtemplate_type = 0;
3607
3608  if (!padtemplate_type) {
3609    static const GTypeInfo padtemplate_info = {
3610      sizeof (GstPadTemplateClass), NULL, NULL,
3611      (GClassInitFunc) gst_pad_template_class_init, NULL, NULL,
3612      sizeof (GstPadTemplate),
3613      0,
3614      (GInstanceInitFunc) gst_pad_template_init, NULL
3615    };
3616
3617    padtemplate_type =
3618        g_type_register_static (GST_TYPE_OBJECT, "GstPadTemplate",
3619        &padtemplate_info, 0);
3620  }
3621  return padtemplate_type;
3622}
3623
3624static void
3625gst_pad_template_class_init (GstPadTemplateClass * klass)
3626{
3627  GObjectClass *gobject_class;
3628  GstObjectClass *gstobject_class;
3629
3630  gobject_class = (GObjectClass *) klass;
3631  gstobject_class = (GstObjectClass *) klass;
3632
3633  padtemplate_parent_class = g_type_class_ref (GST_TYPE_OBJECT);
3634
3635  gst_pad_template_signals[TEMPL_PAD_CREATED] =
3636      g_signal_new ("pad-created", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
3637      G_STRUCT_OFFSET (GstPadTemplateClass, pad_created),
3638      NULL, NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
3639
3640  gobject_class->dispose = gst_pad_template_dispose;
3641
3642  gstobject_class->path_string_separator = "*";
3643}
3644
3645static void
3646gst_pad_template_init (GstPadTemplate * templ)
3647{
3648}
3649
3650static void
3651gst_pad_template_dispose (GObject * object)
3652{
3653  GstPadTemplate *templ = GST_PAD_TEMPLATE (object);
3654
3655  g_free (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ));
3656  if (GST_PAD_TEMPLATE_CAPS (templ)) {
3657    gst_caps_free (GST_PAD_TEMPLATE_CAPS (templ));
3658  }
3659
3660  G_OBJECT_CLASS (padtemplate_parent_class)->dispose (object);
3661}
3662
3663/* ALWAYS padtemplates cannot have conversion specifications, it doesn't make
3664 * sense.
3665 * SOMETIMES padtemplates can do whatever they want, they are provided by the
3666 * element.
3667 * REQUEST padtemplates can be reverse-parsed (the user asks for 'sink1', the
3668 * 'sink%d' template is automatically selected), so we need to restrict their
3669 * naming.
3670 */
3671static gboolean
3672name_is_valid (const gchar * name, GstPadPresence presence)
3673{
3674  const gchar *str;
3675
3676  if (presence == GST_PAD_ALWAYS) {
3677    if (strchr (name, '%')) {
3678      g_warning ("invalid name template %s: conversion specifications are not"
3679          " allowed for GST_PAD_ALWAYS padtemplates", name);
3680      return FALSE;
3681    }
3682  } else if (presence == GST_PAD_REQUEST) {
3683    if ((str = strchr (name, '%')) && strchr (str + 1, '%')) {
3684      g_warning ("invalid name template %s: only one conversion specification"
3685          " allowed in GST_PAD_REQUEST padtemplate", name);
3686      return FALSE;
3687    }
3688    if (str && (*(str + 1) != 's' && *(str + 1) != 'd')) {
3689      g_warning ("invalid name template %s: conversion specification must be of"
3690          " type '%%d' or '%%s' for GST_PAD_REQUEST padtemplate", name);
3691      return FALSE;
3692    }
3693    if (str && (*(str + 2) != '\0')) {
3694      g_warning ("invalid name template %s: conversion specification must"
3695          " appear at the end of the GST_PAD_REQUEST padtemplate name", name);
3696      return FALSE;
3697    }
3698  }
3699
3700  return TRUE;
3701}
3702
3703/**
3704 * gst_static_pad_template_get:
3705 * @pad_template: the static pad template
3706 *
3707 * Converts a #GstStaticPadTemplate into a #GstPadTemplate.
3708 *
3709 * Returns: a new #GstPadTemplate.
3710 */
3711GstPadTemplate *
3712gst_static_pad_template_get (GstStaticPadTemplate * pad_template)
3713{
3714  GstPadTemplate *new;
3715
3716  if (!name_is_valid (pad_template->name_template, pad_template->presence))
3717    return NULL;
3718
3719  new = g_object_new (gst_pad_template_get_type (),
3720      "name", pad_template->name_template, NULL);
3721
3722  GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = g_strdup (pad_template->name_template);
3723  GST_PAD_TEMPLATE_DIRECTION (new) = pad_template->direction;
3724  GST_PAD_TEMPLATE_PRESENCE (new) = pad_template->presence;
3725
3726  GST_PAD_TEMPLATE_CAPS (new) =
3727      gst_caps_copy (gst_static_caps_get (&pad_template->static_caps));
3728
3729  return new;
3730}
3731
3732/**
3733 * gst_pad_template_new:
3734 * @name_template: the name template.
3735 * @direction: the #GstPadDirection of the template.
3736 * @presence: the #GstPadPresence of the pad.
3737 * @caps: a #GstCaps set for the template. The caps are taken ownership of.
3738 *
3739 * Creates a new pad template with a name according to the given template
3740 * and with the given arguments. This functions takes ownership of the provided
3741 * caps, so be sure to not use them afterwards.
3742 *
3743 * Returns: a new #GstPadTemplate.
3744 */
3745GstPadTemplate *
3746gst_pad_template_new (const gchar * name_template,
3747    GstPadDirection direction, GstPadPresence presence, GstCaps * caps)
3748{
3749  GstPadTemplate *new;
3750
3751  g_return_val_if_fail (name_template != NULL, NULL);
3752  g_return_val_if_fail (caps != NULL, NULL);
3753  g_return_val_if_fail (direction == GST_PAD_SRC
3754      || direction == GST_PAD_SINK, NULL);
3755  g_return_val_if_fail (presence == GST_PAD_ALWAYS
3756      || presence == GST_PAD_SOMETIMES || presence == GST_PAD_REQUEST, NULL);
3757
3758  if (!name_is_valid (name_template, presence))
3759    return NULL;
3760
3761#if 0
3762#ifdef USE_POISONING
3763  if (caps) {
3764    GstCaps *newcaps = gst_caps_copy (caps);
3765
3766    gst_caps_free (caps);
3767    caps = newcaps;
3768  }
3769#endif
3770#endif
3771  new = g_object_new (gst_pad_template_get_type (),
3772      "name", name_template, NULL);
3773
3774  GST_PAD_TEMPLATE_NAME_TEMPLATE (new) = g_strdup (name_template);
3775  GST_PAD_TEMPLATE_DIRECTION (new) = direction;
3776  GST_PAD_TEMPLATE_PRESENCE (new) = presence;
3777  GST_PAD_TEMPLATE_CAPS (new) = caps;
3778
3779  return new;
3780}
3781
3782/**
3783 * gst_pad_template_get_caps:
3784 * @templ: a #GstPadTemplate to get capabilities of.
3785 *
3786 * Gets the capabilities of the pad template.
3787 *
3788 * Returns: the #GstCaps of the pad template. If you need to keep a reference to
3789 * the caps, make a copy (see gst_caps_copy ()).
3790 */
3791const GstCaps *
3792gst_pad_template_get_caps (GstPadTemplate * templ)
3793{
3794  g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
3795
3796  return GST_PAD_TEMPLATE_CAPS (templ);
3797}
3798
3799/**
3800 * gst_pad_set_element_private:
3801 * @pad: the #GstPad to set the private data of.
3802 * @priv: The private data to attach to the pad.
3803 *
3804 * Set the given private data gpointer on the pad.
3805 * This function can only be used by the element that owns the pad.
3806 */
3807void
3808gst_pad_set_element_private (GstPad * pad, gpointer priv)
3809{
3810  pad->element_private = priv;
3811}
3812
3813/**
3814 * gst_pad_get_element_private:
3815 * @pad: the #GstPad to get the private data of.
3816 *
3817 * Gets the private data of a pad.
3818 *
3819 * Returns: a #gpointer to the private data.
3820 */
3821gpointer
3822gst_pad_get_element_private (GstPad * pad)
3823{
3824  return pad->element_private;
3825}
3826
3827
3828/***** ghost pads *****/
3829GType _gst_ghost_pad_type = 0;
3830
3831static void gst_ghost_pad_class_init (GstGhostPadClass * klass);
3832static void gst_ghost_pad_init (GstGhostPad * pad);
3833static void gst_ghost_pad_dispose (GObject * object);
3834static void gst_ghost_pad_get_property (GObject * object, guint prop_id,
3835    GValue * value, GParamSpec * pspec);
3836static void gst_ghost_pad_set_property (GObject * object, guint prop_id,
3837    const GValue * value, GParamSpec * pspec);
3838
3839static GstPad *ghost_pad_parent_class = NULL;
3840
3841/* static guint gst_ghost_pad_signals[LAST_SIGNAL] = { 0 }; */
3842enum
3843{
3844  GPAD_ARG_0,
3845  GPAD_ARG_REAL_PAD
3846      /* fill me */
3847};
3848
3849GType
3850gst_ghost_pad_get_type (void)
3851{
3852  if (!_gst_ghost_pad_type) {
3853    static const GTypeInfo pad_info = {
3854      sizeof (GstGhostPadClass), NULL, NULL,
3855      (GClassInitFunc) gst_ghost_pad_class_init, NULL, NULL,
3856      sizeof (GstGhostPad),
3857      0,
3858      (GInstanceInitFunc) gst_ghost_pad_init,
3859      NULL
3860    };
3861
3862    _gst_ghost_pad_type = g_type_register_static (GST_TYPE_PAD, "GstGhostPad",
3863        &pad_info, 0);
3864  }
3865  return _gst_ghost_pad_type;
3866}
3867
3868static void
3869gst_ghost_pad_class_init (GstGhostPadClass * klass)
3870{
3871  GObjectClass *gobject_class;
3872
3873  gobject_class = (GObjectClass *) klass;
3874
3875  ghost_pad_parent_class = g_type_class_ref (GST_TYPE_PAD);
3876
3877  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_ghost_pad_dispose);
3878  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_ghost_pad_set_property);
3879  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_ghost_pad_get_property);
3880
3881  g_object_class_install_property (gobject_class, GPAD_ARG_REAL_PAD,
3882      g_param_spec_object ("real-pad", "Real pad",
3883          "The real pad for the ghost pad", GST_TYPE_PAD, G_PARAM_READWRITE));
3884}
3885
3886static void
3887gst_ghost_pad_init (GstGhostPad * pad)
3888{
3889  /* zeroed by glib */
3890}
3891
3892static void
3893gst_ghost_pad_dispose (GObject * object)
3894{
3895  g_object_set (object, "real-pad", NULL, NULL);
3896
3897  G_OBJECT_CLASS (ghost_pad_parent_class)->dispose (object);
3898}
3899
3900static void
3901gst_ghost_pad_set_property (GObject * object, guint prop_id,
3902    const GValue * value, GParamSpec * pspec)
3903{
3904  GstPad *ghostpad = (GstPad *) object;
3905  GstPad *oldrealpad = (GstPad *) GST_GPAD_REALPAD (ghostpad);
3906  GstPad *realpad = NULL;
3907
3908  switch (prop_id) {
3909    case GPAD_ARG_REAL_PAD:
3910      realpad = g_value_get_object (value);
3911
3912      if (oldrealpad) {
3913        if (realpad == oldrealpad)
3914          return;
3915        else
3916          gst_pad_remove_ghost_pad (oldrealpad, ghostpad);
3917      }
3918
3919      if (realpad)
3920        gst_pad_add_ghost_pad (realpad, ghostpad);
3921      break;
3922
3923    default:
3924      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3925      break;
3926  }
3927}
3928
3929static void
3930gst_ghost_pad_get_property (GObject * object, guint prop_id,
3931    GValue * value, GParamSpec * pspec)
3932{
3933  switch (prop_id) {
3934    case GPAD_ARG_REAL_PAD:
3935      g_value_set_object (value, GST_GPAD_REALPAD (object));
3936      break;
3937
3938    default:
3939      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3940      break;
3941  }
3942}
3943
3944/**
3945 * gst_ghost_pad_new:
3946 * @name: the name of the new ghost pad.
3947 * @pad: the #GstPad to create a ghost pad for.
3948 *
3949 * Creates a new ghost pad associated with @pad, and named @name. If @name is
3950 * %NULL, a guaranteed unique name (across all ghost pads) will be assigned.
3951 *
3952 * Returns: a new ghost #GstPad, or %NULL in case of an error.
3953 */
3954GstPad *
3955gst_ghost_pad_new (const gchar * name, GstPad * pad)
3956{
3957  GstPad *gpad;
3958
3959  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
3960
3961  gpad = g_object_new (GST_TYPE_GHOST_PAD, "name", name, "real-pad", pad, NULL);
3962
3963  GST_CAT_DEBUG (GST_CAT_PADS, "created ghost pad \"%s\" for pad %s:%s",
3964      GST_OBJECT_NAME (gpad), GST_DEBUG_PAD_NAME (pad));
3965
3966  return gpad;
3967}
3968
3969/**
3970 * gst_pad_get_internal_links_default:
3971 * @pad: the #GstPad to get the internal links of.
3972 *
3973 * Gets a list of pads to which the given pad is linked to
3974 * inside of the parent element.
3975 * This is the default handler, and thus returns a list of all of the
3976 * pads inside the parent element with opposite direction.
3977 * The caller must free this list after use.
3978 *
3979 * Returns: a newly allocated #GList of pads.
3980 */
3981GList *
3982gst_pad_get_internal_links_default (GstPad * pad)
3983{
3984  GList *res = NULL;
3985  GstElement *parent;
3986  GList *parent_pads;
3987  GstPadDirection direction;
3988  GstRealPad *rpad;
3989
3990  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
3991
3992  rpad = GST_PAD_REALIZE (pad);
3993  direction = rpad->direction;
3994
3995  parent = GST_PAD_PARENT (rpad);
3996  parent_pads = parent->pads;
3997
3998  while (parent_pads) {
3999    GstRealPad *parent_pad = GST_PAD_REALIZE (parent_pads->data);
4000
4001    if (parent_pad->direction != direction) {
4002      res = g_list_prepend (res, parent_pad);
4003    }
4004
4005    parent_pads = g_list_next (parent_pads);
4006  }
4007
4008  return res;
4009}
4010
4011/**
4012 * gst_pad_get_internal_links:
4013 * @pad: the #GstPad to get the internal links of.
4014 *
4015 * Gets a list of pads to which the given pad is linked to
4016 * inside of the parent element.
4017 * The caller must free this list after use.
4018 *
4019 * Returns: a newly allocated #GList of pads.
4020 */
4021GList *
4022gst_pad_get_internal_links (GstPad * pad)
4023{
4024  GList *res = NULL;
4025  GstRealPad *rpad;
4026
4027  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
4028
4029  rpad = GST_PAD_REALIZE (pad);
4030
4031  if (GST_RPAD_INTLINKFUNC (rpad))
4032    res = GST_RPAD_INTLINKFUNC (rpad) (GST_PAD (rpad));
4033
4034  return res;
4035}
4036
4037
4038static gboolean
4039gst_pad_event_default_dispatch (GstPad * pad, GstElement * element,
4040    GstEvent * event)
4041{
4042  GList *orig, *pads;
4043
4044  GST_INFO_OBJECT (pad, "Sending event %p to all internally linked pads",
4045      event);
4046
4047  orig = pads = gst_pad_get_internal_links (pad);
4048
4049  while (pads) {
4050    GstPad *eventpad = GST_PAD (pads->data);
4051
4052    pads = g_list_next (pads);
4053
4054    /* for all of the internally-linked pads that are actually linked */
4055    if (GST_PAD_IS_LINKED (eventpad)) {
4056      if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
4057        /* for each pad we send to, we should ref the event; it's up
4058         * to downstream to unref again when handled. */
4059        GST_LOG_OBJECT (pad, "Reffing and sending event %p to %s:%s", event,
4060            GST_DEBUG_PAD_NAME (eventpad));
4061        gst_event_ref (event);
4062        gst_pad_push (eventpad, GST_DATA (event));
4063      } else {
4064        GstPad *peerpad = GST_PAD (GST_RPAD_PEER (eventpad));
4065
4066        /* we only send the event on one pad, multi-sinkpad elements
4067         * should implement a handler */
4068        g_list_free (orig);
4069        GST_LOG_OBJECT (pad, "sending event %p to one sink pad %s:%s", event,
4070            GST_DEBUG_PAD_NAME (eventpad));
4071        return gst_pad_send_event (peerpad, event);
4072      }
4073    }
4074  }
4075  /* we handled the incoming event so we unref once */
4076  GST_LOG_OBJECT (pad, "handled event %p, unreffing", event);
4077  gst_event_unref (event);
4078  g_list_free (orig);
4079  return (GST_PAD_DIRECTION (pad) == GST_PAD_SINK);
4080}
4081
4082/**
4083 * gst_pad_event_default:
4084 * @pad: a #GstPad to call the default event handler on.
4085 * @event: the #GstEvent to handle.
4086 *
4087 * Invokes the default event handler for the given pad. End-of-stream and
4088 * discontinuity events are handled specially, and then the event is sent to all
4089 * pads internally linked to @pad. Note that if there are many possible sink
4090 * pads that are internally linked to @pad, only one will be sent an event.
4091 * Multi-sinkpad elements should implement custom event handlers.
4092 *
4093 * Returns: TRUE if the event was sent succesfully.
4094 */
4095gboolean
4096gst_pad_event_default (GstPad * pad, GstEvent * event)
4097{
4098  GstElement *element;
4099
4100  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4101  g_return_val_if_fail (event != NULL, FALSE);
4102
4103  element = GST_PAD_PARENT (pad);
4104
4105  switch (GST_EVENT_TYPE (event)) {
4106    case GST_EVENT_EOS:
4107      gst_pad_event_default_dispatch (pad, element, event);
4108      gst_element_set_eos (element);
4109      break;
4110    case GST_EVENT_DISCONTINUOUS:
4111    {
4112      guint64 time;
4113
4114      if (gst_element_requires_clock (element) && element->clock) {
4115        if (gst_event_discont_get_value (event, GST_FORMAT_TIME, &time)) {
4116          gst_element_set_time (element, time);
4117        } else {
4118          GstFormat format = GST_FORMAT_TIME;
4119          guint i;
4120
4121          for (i = 0; i < event->event_data.discont.noffsets; i++) {
4122            if (gst_pad_convert (pad,
4123                    event->event_data.discont.offsets[i].format,
4124                    event->event_data.discont.offsets[i].value, &format,
4125                    &time)) {
4126              gst_element_set_time (element, time);
4127            } else if (i == event->event_data.discont.noffsets) {
4128              g_warning
4129                  ("can't adjust clock to new time when time not provided");
4130            }
4131          }
4132        }
4133      }
4134    }
4135    default:
4136      return gst_pad_event_default_dispatch (pad, element, event);
4137  }
4138  return TRUE;
4139}
4140
4141/**
4142 * gst_pad_dispatcher:
4143 * @pad: a #GstPad to dispatch.
4144 * @dispatch: the #GstDispatcherFunction to call.
4145 * @data: gpointer user data passed to the dispatcher function.
4146 *
4147 * Invokes the given dispatcher function on all pads that are
4148 * internally linked to the given pad.
4149 * The GstPadDispatcherFunction should return TRUE when no further pads
4150 * need to be processed.
4151 *
4152 * Returns: TRUE if one of the dispatcher functions returned TRUE.
4153 */
4154gboolean
4155gst_pad_dispatcher (GstPad * pad, GstPadDispatcherFunction dispatch,
4156    gpointer data)
4157{
4158  gboolean res = FALSE;
4159  GList *int_pads, *orig;
4160
4161  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4162  g_return_val_if_fail (dispatch != NULL, FALSE);
4163
4164  orig = int_pads = gst_pad_get_internal_links (pad);
4165
4166  while (int_pads) {
4167    GstRealPad *int_rpad = GST_PAD_REALIZE (int_pads->data);
4168    GstRealPad *int_peer = GST_RPAD_PEER (int_rpad);
4169
4170    if (int_peer) {
4171      res = dispatch (GST_PAD (int_peer), data);
4172      if (res)
4173        break;
4174    }
4175    int_pads = g_list_next (int_pads);
4176  }
4177
4178  g_list_free (orig);
4179
4180  return res;
4181}
4182
4183/**
4184 * gst_pad_send_event:
4185 * @pad: a #GstPad to send the event to.
4186 * @event: the #GstEvent to send to the pad.
4187 *
4188 * Sends the event to the pad.
4189 *
4190 * Returns: TRUE if the event was handled.
4191 */
4192gboolean
4193gst_pad_send_event (GstPad * pad, GstEvent * event)
4194{
4195  gboolean success = FALSE;
4196  GstRealPad *rpad;
4197  GstElement *parent;
4198
4199  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4200  g_return_val_if_fail (event != NULL, FALSE);
4201  parent = gst_pad_get_parent (pad);
4202  g_return_val_if_fail (GST_STATE (parent) >= GST_STATE_PAUSED, FALSE);
4203
4204  rpad = GST_PAD_REALIZE (pad);
4205
4206
4207  if (GST_EVENT_SRC (event) == NULL)
4208    GST_EVENT_SRC (event) = gst_object_ref (GST_OBJECT (rpad));
4209
4210  GST_CAT_DEBUG (GST_CAT_EVENT, "have event type %d on pad %s:%s",
4211      GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (rpad));
4212
4213  if (GST_RPAD_EVENTHANDLER (rpad))
4214    success = GST_RPAD_EVENTHANDLER (rpad) (GST_PAD (rpad), event);
4215  else {
4216    g_warning ("pad %s:%s has no event handler", GST_DEBUG_PAD_NAME (rpad));
4217    gst_event_unref (event);
4218  }
4219
4220  return success;
4221}
4222
4223typedef struct
4224{
4225  GstFormat src_format;
4226  gint64 src_value;
4227  GstFormat *dest_format;
4228  gint64 *dest_value;
4229}
4230GstPadConvertData;
4231
4232static gboolean
4233gst_pad_convert_dispatcher (GstPad * pad, GstPadConvertData * data)
4234{
4235  return gst_pad_convert (pad, data->src_format, data->src_value,
4236      data->dest_format, data->dest_value);
4237}
4238
4239/**
4240 * gst_pad_convert_default:
4241 * @pad: a #GstPad to invoke the default converter on.
4242 * @src_format: the source #GstFormat.
4243 * @src_value: the source value.
4244 * @dest_format: a pointer to the destination #GstFormat.
4245 * @dest_value: a pointer to the destination value.
4246 *
4247 * Invokes the default converter on a pad.
4248 * This will forward the call to the pad obtained
4249 * using the internal link of
4250 * the element.
4251 *
4252 * Returns: TRUE if the conversion could be performed.
4253 */
4254gboolean
4255gst_pad_convert_default (GstPad * pad,
4256    GstFormat src_format, gint64 src_value,
4257    GstFormat * dest_format, gint64 * dest_value)
4258{
4259  GstPadConvertData data;
4260
4261  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4262  g_return_val_if_fail (dest_format != NULL, FALSE);
4263  g_return_val_if_fail (dest_value != NULL, FALSE);
4264
4265  data.src_format = src_format;
4266  data.src_value = src_value;
4267  data.dest_format = dest_format;
4268  data.dest_value = dest_value;
4269
4270  return gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
4271      gst_pad_convert_dispatcher, &data);
4272}
4273
4274/**
4275 * gst_pad_convert:
4276 * @pad: a #GstPad to invoke the default converter on.
4277 * @src_format: the source #GstFormat.
4278 * @src_value: the source value.
4279 * @dest_format: a pointer to the destination #GstFormat.
4280 * @dest_value: a pointer to the destination value.
4281 *
4282 * Invokes a conversion on the pad.
4283 *
4284 * Returns: TRUE if the conversion could be performed.
4285 */
4286gboolean
4287gst_pad_convert (GstPad * pad,
4288    GstFormat src_format, gint64 src_value,
4289    GstFormat * dest_format, gint64 * dest_value)
4290{
4291  GstRealPad *rpad;
4292
4293  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4294  g_return_val_if_fail (dest_format != NULL, FALSE);
4295  g_return_val_if_fail (dest_value != NULL, FALSE);
4296
4297  if (src_format == *dest_format) {
4298    *dest_value = src_value;
4299    return TRUE;
4300  }
4301
4302  rpad = GST_PAD_REALIZE (pad);
4303
4304  if (GST_RPAD_CONVERTFUNC (rpad)) {
4305    return GST_RPAD_CONVERTFUNC (rpad) (GST_PAD (rpad), src_format,
4306        src_value, dest_format, dest_value);
4307  }
4308
4309  return FALSE;
4310}
4311
4312typedef struct
4313{
4314  GstQueryType type;
4315  GstFormat *format;
4316  gint64 *value;
4317}
4318GstPadQueryData;
4319
4320static gboolean
4321gst_pad_query_dispatcher (GstPad * pad, GstPadQueryData * data)
4322{
4323  return gst_pad_query (pad, data->type, data->format, data->value);
4324}
4325
4326/**
4327 * gst_pad_query_default:
4328 * @pad: a #GstPad to invoke the default query on.
4329 * @type: the #GstQueryType of the query to perform.
4330 * @format: a pointer to the #GstFormat of the result.
4331 * @value: a pointer to the result.
4332 *
4333 * Invokes the default query function on a pad.
4334 *
4335 * Returns: TRUE if the query could be performed.
4336 */
4337gboolean
4338gst_pad_query_default (GstPad * pad, GstQueryType type,
4339    GstFormat * format, gint64 * value)
4340{
4341  GstPadQueryData data;
4342
4343  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4344  g_return_val_if_fail (format != NULL, FALSE);
4345  g_return_val_if_fail (value != NULL, FALSE);
4346
4347  data.type = type;
4348  data.format = format;
4349  data.value = value;
4350
4351  return gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
4352      gst_pad_query_dispatcher, &data);
4353}
4354
4355/**
4356 * gst_pad_query:
4357 * @pad: a #GstPad to invoke the default query on.
4358 * @type: the #GstQueryType of the query to perform.
4359 * @format: a pointer to the #GstFormat asked for.
4360 *          On return contains the #GstFormat used.
4361 * @value: a pointer to the result.
4362 *
4363 * Queries a pad for one of the available properties. The format will be
4364 * adjusted to the actual format used when specifying formats such as
4365 * GST_FORMAT_DEFAULT.
4366 * FIXME: Tell if the format can be adjusted when specifying a definite format.
4367 *
4368 * Returns: TRUE if the query could be performed.
4369 */
4370gboolean
4371gst_pad_query (GstPad * pad, GstQueryType type,
4372    GstFormat * format, gint64 * value)
4373{
4374  GstRealPad *rpad;
4375
4376  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
4377  g_return_val_if_fail (format != NULL, FALSE);
4378  g_return_val_if_fail (value != NULL, FALSE);
4379
4380  rpad = GST_PAD_REALIZE (pad);
4381
4382  g_return_val_if_fail (rpad, FALSE);
4383
4384  if (GST_RPAD_QUERYFUNC (rpad))
4385    return GST_RPAD_QUERYFUNC (rpad) (GST_PAD (rpad), type, format, value);
4386
4387  return FALSE;
4388}
4389
4390static gboolean
4391gst_pad_get_formats_dispatcher (GstPad * pad, const GstFormat ** data)
4392{
4393  *data = gst_pad_get_formats (pad);
4394
4395  return TRUE;
4396}
4397
4398/**
4399 * gst_pad_get_formats_default:
4400 * @pad: a #GstPad to query
4401 *
4402 * Invoke the default format dispatcher for the pad.
4403 *
4404 * Returns: An array of GstFormats ended with a 0 value.
4405 */
4406const GstFormat *
4407gst_pad_get_formats_default (GstPad * pad)
4408{
4409  GstFormat *result = NULL;
4410
4411  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
4412
4413  gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
4414      gst_pad_get_formats_dispatcher, &result);
4415
4416  return result;
4417}
4418
4419/**
4420 * gst_pad_get_formats:
4421 * @pad: a #GstPad to query
4422 *
4423 * Gets the list of supported formats from the pad.
4424 *
4425 * Returns: An array of GstFormats ended with a 0 value.
4426 */
4427const GstFormat *
4428gst_pad_get_formats (GstPad * pad)
4429{
4430  GstRealPad *rpad;
4431
4432  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
4433
4434  rpad = GST_PAD_REALIZE (pad);
4435
4436  if (GST_RPAD_FORMATSFUNC (rpad))
4437    return GST_RPAD_FORMATSFUNC (rpad) (GST_PAD (pad));
4438
4439  return NULL;
4440}
4441
4442#define CALL_CHAINFUNC(pad, data) G_STMT_START {\
4443  GstData *__temp = (data); \
4444  DEBUG_DATA (pad, __temp, "calling chain function with "); \
4445  if (GST_IS_EVENT (__temp) && \
4446      !GST_FLAG_IS_SET (gst_pad_get_parent (pad), GST_ELEMENT_EVENT_AWARE)) { \
4447    gst_pad_send_event (pad, GST_EVENT (__temp)); \
4448  } else { \
4449    GST_FLAG_SET (pad, GST_RPAD_IN_CHAINFUNC); \
4450    GST_RPAD_CHAINFUNC (pad) (pad, __temp); \
4451    GST_FLAG_UNSET (pad, GST_RPAD_IN_CHAINFUNC); \
4452  } \
4453}G_STMT_END
4454/**
4455 * gst_pad_call_chain_function:
4456 * @pad: sink pad to call chain function on
4457 * @data: data to call the chain function with
4458 *
4459 * Calls the chain function of the given pad while making sure the internal
4460 * consistency is kept. Use this function inside schedulers instead of calling
4461 * the chain function yourself.
4462 */
4463void
4464gst_pad_call_chain_function (GstPad * pad, GstData * data)
4465{
4466  GstPadLink *link;
4467
4468  g_return_if_fail (GST_IS_REAL_PAD (pad));
4469  g_return_if_fail (GST_PAD_IS_SINK (pad));
4470  g_return_if_fail (data != NULL);
4471  g_return_if_fail (GST_RPAD_CHAINFUNC (pad) != NULL);
4472  g_return_if_fail (GST_RPAD_LINK (pad) != NULL);
4473
4474  link = GST_RPAD_LINK (pad);
4475  if (!link->engaged) {
4476    g_assert (link->temp_store == NULL);
4477    if (GST_IS_BUFFER (data)) {
4478      GST_DEBUG ("moving data buffer %p back to temp_store", data);
4479      link->temp_store = data;
4480      link->engaged = TRUE;
4481      CALL_CHAINFUNC (pad, _invent_event (pad, GST_BUFFER (data)));
4482      link = GST_RPAD_LINK (pad);
4483      if (link->temp_store == NULL)     /* happens after relinking in chainfunc */
4484        return;
4485      g_assert (link->temp_store == data);
4486      link->temp_store = NULL;
4487    } else if (GST_IS_EVENT (data) &&
4488        GST_EVENT_TYPE (data) == GST_EVENT_DISCONTINUOUS &&
4489        GST_EVENT_DISCONT_NEW_MEDIA (data)) {
4490      link->engaged = TRUE;
4491      GST_CAT_LOG (GST_CAT_SCHEDULING,
4492          "link engaged by discont event %p for pad %s:%s", data,
4493          GST_DEBUG_PAD_NAME (pad));
4494    }
4495  }
4496  CALL_CHAINFUNC (pad, data);
4497}
4498
4499/**
4500 * gst_pad_call_get_function:
4501 * @pad: sink pad to call chain function on
4502 *
4503 * Calls the get function of the given pad while making sure the internal
4504 * consistency is kept. Use this function inside schedulers instead of calling
4505 * the get function yourself.
4506 *
4507 * Returns: the data provided by the pad or NULL if no data was available.
4508 */
4509GstData *
4510gst_pad_call_get_function (GstPad * pad)
4511{
4512  GstData *data;
4513
4514  g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL);
4515  g_return_val_if_fail (GST_PAD_IS_SRC (pad), NULL);
4516  g_return_val_if_fail (GST_RPAD_GETFUNC (pad) != NULL, NULL);
4517
4518  GST_FLAG_SET (pad, GST_RPAD_IN_GETFUNC);
4519  data = GST_RPAD_GETFUNC (pad) (pad);
4520  GST_FLAG_UNSET (pad, GST_RPAD_IN_GETFUNC);
4521  DEBUG_DATA (pad, data, "getfunction returned");
4522  return data;
4523}
Note: See TracBrowser for help on using the repository browser.