gstreamer_core/gst/gstpad.c
changeset 0 0e761a78d257
child 7 567bb019e3e3
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     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  * SECTION:gstpad
       
    24  * @short_description: Object contained by elements that allows links to
       
    25  *                     other elements
       
    26  * @see_also: #GstPadTemplate, #GstElement, #GstEvent
       
    27  *
       
    28  * A #GstElement is linked to other elements via "pads", which are extremely
       
    29  * light-weight generic link points.
       
    30  * After two pads are retrieved from an element with gst_element_get_pad(),
       
    31  * the pads can be link with gst_pad_link(). (For quick links,
       
    32  * you can also use gst_element_link(), which will make the obvious
       
    33  * link for you if it's straightforward.)
       
    34  *
       
    35  * Pads are typically created from a #GstPadTemplate with
       
    36  * gst_pad_new_from_template().
       
    37  *
       
    38  * Pads have #GstCaps attached to it to describe the media type they are
       
    39  * capable of dealing with.  gst_pad_get_caps() and gst_pad_set_caps() are
       
    40  * used to manipulate the caps of the pads.
       
    41  * Pads created from a pad template cannot set capabilities that are
       
    42  * incompatible with the pad template capabilities.
       
    43  *
       
    44  * Pads without pad templates can be created with gst_pad_new(),
       
    45  * which takes a direction and a name as an argument.  If the name is NULL,
       
    46  * then a guaranteed unique name will be assigned to it.
       
    47  *
       
    48  * gst_pad_get_parent() will retrieve the #GstElement that owns the pad.
       
    49  *
       
    50  * A #GstElement creating a pad will typically use the various
       
    51  * gst_pad_set_*_function() calls to register callbacks for various events
       
    52  * on the pads.
       
    53  *
       
    54  * GstElements will use gst_pad_push() and gst_pad_pull_range() to push out
       
    55  * or pull in a buffer.
       
    56  *
       
    57  * To send a #GstEvent on a pad, use gst_pad_send_event() and
       
    58  * gst_pad_push_event().
       
    59  *
       
    60  * Last reviewed on 2006-07-06 (0.10.9)
       
    61  */
       
    62 
       
    63 #include "gst_private.h"
       
    64 
       
    65 #include "gstpad.h"
       
    66 #include "gstpadtemplate.h"
       
    67 #include "gstenumtypes.h"
       
    68 #include "gstmarshal.h"
       
    69 #include "gstutils.h"
       
    70 #include "gstinfo.h"
       
    71 #include "gsterror.h"
       
    72 #include "gstvalue.h"
       
    73 #include "glib-compat-private.h"
       
    74 
       
    75 #ifdef __SYMBIAN32__
       
    76 #include <glib_global.h>
       
    77 #endif
       
    78 
       
    79 GST_DEBUG_CATEGORY_STATIC (debug_dataflow);
       
    80 #define GST_CAT_DEFAULT GST_CAT_PADS
       
    81 
       
    82 /* Pad signals and args */
       
    83 enum
       
    84 {
       
    85   PAD_LINKED,
       
    86   PAD_UNLINKED,
       
    87   PAD_REQUEST_LINK,
       
    88   PAD_HAVE_DATA,
       
    89   /* FILL ME */
       
    90   LAST_SIGNAL
       
    91 };
       
    92 
       
    93 enum
       
    94 {
       
    95   PAD_PROP_0,
       
    96   PAD_PROP_CAPS,
       
    97   PAD_PROP_DIRECTION,
       
    98   PAD_PROP_TEMPLATE,
       
    99   /* FILL ME */
       
   100 };
       
   101 
       
   102 static void gst_pad_class_init (GstPadClass * klass);
       
   103 static void gst_pad_init (GstPad * pad);
       
   104 static void gst_pad_dispose (GObject * object);
       
   105 static void gst_pad_finalize (GObject * object);
       
   106 static void gst_pad_set_property (GObject * object, guint prop_id,
       
   107     const GValue * value, GParamSpec * pspec);
       
   108 static void gst_pad_get_property (GObject * object, guint prop_id,
       
   109     GValue * value, GParamSpec * pspec);
       
   110 
       
   111 static GstFlowReturn handle_pad_block (GstPad * pad);
       
   112 static GstCaps *gst_pad_get_caps_unlocked (GstPad * pad);
       
   113 static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ);
       
   114 static gboolean gst_pad_activate_default (GstPad * pad);
       
   115 static gboolean gst_pad_acceptcaps_default (GstPad * pad, GstCaps * caps);
       
   116 
       
   117 #ifndef GST_DISABLE_LOADSAVE
       
   118 static xmlNodePtr gst_pad_save_thyself (GstObject * object, xmlNodePtr parent);
       
   119 #endif
       
   120 
       
   121 static GstObjectClass *parent_class = NULL;
       
   122 static guint gst_pad_signals[LAST_SIGNAL] = { 0 };
       
   123 
       
   124 /* quarks for probe signals */
       
   125 static GQuark buffer_quark;
       
   126 static GQuark event_quark;
       
   127 
       
   128 typedef struct
       
   129 {
       
   130   const gint ret;
       
   131   const gchar *name;
       
   132   GQuark quark;
       
   133 } GstFlowQuarks;
       
   134 
       
   135 static GstFlowQuarks flow_quarks[] = {
       
   136   {GST_FLOW_CUSTOM_SUCCESS, "custom-success", 0},
       
   137   {GST_FLOW_RESEND, "resend", 0},
       
   138   {GST_FLOW_OK, "ok", 0},
       
   139   {GST_FLOW_NOT_LINKED, "not-linked", 0},
       
   140   {GST_FLOW_WRONG_STATE, "wrong-state", 0},
       
   141   {GST_FLOW_UNEXPECTED, "unexpected", 0},
       
   142   {GST_FLOW_NOT_NEGOTIATED, "not-negotiated", 0},
       
   143   {GST_FLOW_ERROR, "error", 0},
       
   144   {GST_FLOW_NOT_SUPPORTED, "not-supported", 0},
       
   145   {GST_FLOW_CUSTOM_ERROR, "custom-error", 0},
       
   146 
       
   147   {0, NULL, 0}
       
   148 };
       
   149 
       
   150 /**
       
   151  * gst_flow_get_name:
       
   152  * @ret: a #GstFlowReturn to get the name of.
       
   153  *
       
   154  * Gets a string representing the given flow return.
       
   155  *
       
   156  * Returns: a static string with the name of the flow return.
       
   157  */
       
   158 #ifdef __SYMBIAN32__
       
   159 EXPORT_C
       
   160 #endif
       
   161 
       
   162 G_CONST_RETURN gchar *
       
   163 gst_flow_get_name (GstFlowReturn ret)
       
   164 {
       
   165   gint i;
       
   166 
       
   167   ret = CLAMP (ret, GST_FLOW_CUSTOM_ERROR, GST_FLOW_CUSTOM_SUCCESS);
       
   168 
       
   169   for (i = 0; flow_quarks[i].name; i++) {
       
   170     if (ret == flow_quarks[i].ret)
       
   171       return flow_quarks[i].name;
       
   172   }
       
   173   return "unknown";
       
   174 }
       
   175 
       
   176 /**
       
   177  * gst_flow_to_quark:
       
   178  * @ret: a #GstFlowReturn to get the quark of.
       
   179  *
       
   180  * Get the unique quark for the given GstFlowReturn.
       
   181  *
       
   182  * Returns: the quark associated with the flow return or 0 if an
       
   183  * invalid return was specified.
       
   184  */
       
   185 #ifdef __SYMBIAN32__
       
   186 EXPORT_C
       
   187 #endif
       
   188 
       
   189 GQuark
       
   190 gst_flow_to_quark (GstFlowReturn ret)
       
   191 {
       
   192   gint i;
       
   193 
       
   194   ret = CLAMP (ret, GST_FLOW_CUSTOM_ERROR, GST_FLOW_CUSTOM_SUCCESS);
       
   195 
       
   196   for (i = 0; flow_quarks[i].name; i++) {
       
   197     if (ret == flow_quarks[i].ret)
       
   198       return flow_quarks[i].quark;
       
   199   }
       
   200   return 0;
       
   201 }
       
   202 #ifdef __SYMBIAN32__
       
   203 EXPORT_C
       
   204 #endif
       
   205 
       
   206 
       
   207 GType
       
   208 gst_pad_get_type (void)
       
   209 {
       
   210   static GType gst_pad_type = 0;
       
   211 
       
   212   if (G_UNLIKELY (gst_pad_type == 0)) {
       
   213     static const GTypeInfo pad_info = {
       
   214       sizeof (GstPadClass), NULL, NULL,
       
   215       (GClassInitFunc) gst_pad_class_init, NULL, NULL,
       
   216       sizeof (GstPad),
       
   217       0,
       
   218       (GInstanceInitFunc) gst_pad_init, NULL
       
   219     };
       
   220     gint i;
       
   221 
       
   222     gst_pad_type = g_type_register_static (GST_TYPE_OBJECT, "GstPad",
       
   223         &pad_info, 0);
       
   224 
       
   225     buffer_quark = g_quark_from_static_string ("buffer");
       
   226     event_quark = g_quark_from_static_string ("event");
       
   227 
       
   228     for (i = 0; flow_quarks[i].name; i++) {
       
   229       flow_quarks[i].quark = g_quark_from_static_string (flow_quarks[i].name);
       
   230     }
       
   231 
       
   232     GST_DEBUG_CATEGORY_INIT (debug_dataflow, "GST_DATAFLOW",
       
   233         GST_DEBUG_BOLD | GST_DEBUG_FG_GREEN, "dataflow inside pads");
       
   234   }
       
   235   return gst_pad_type;
       
   236 }
       
   237 
       
   238 static gboolean
       
   239 _gst_do_pass_data_accumulator (GSignalInvocationHint * ihint,
       
   240     GValue * return_accu, const GValue * handler_return, gpointer dummy)
       
   241 {
       
   242   gboolean ret = g_value_get_boolean (handler_return);
       
   243 
       
   244   GST_DEBUG ("accumulated %d", ret);
       
   245   g_value_set_boolean (return_accu, ret);
       
   246 
       
   247   return ret;
       
   248 }
       
   249 
       
   250 static gboolean
       
   251 default_have_data (GstPad * pad, GstMiniObject * o)
       
   252 {
       
   253   return TRUE;
       
   254 }
       
   255 
       
   256 static void
       
   257 gst_pad_class_init (GstPadClass * klass)
       
   258 {
       
   259   GObjectClass *gobject_class;
       
   260   GstObjectClass *gstobject_class;
       
   261 
       
   262   gobject_class = G_OBJECT_CLASS (klass);
       
   263   gstobject_class = GST_OBJECT_CLASS (klass);
       
   264 
       
   265   parent_class = g_type_class_peek_parent (klass);
       
   266 
       
   267   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose);
       
   268   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_pad_finalize);
       
   269   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_pad_set_property);
       
   270   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_pad_get_property);
       
   271 
       
   272   /**
       
   273    * GstPad::linked:
       
   274    * @pad: the pad that emitted the signal
       
   275    * @peer: the peer pad that has been connected
       
   276    *
       
   277    * Signals that a pad has been linked to the peer pad.
       
   278    */
       
   279   gst_pad_signals[PAD_LINKED] =
       
   280       g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       
   281       G_STRUCT_OFFSET (GstPadClass, linked), NULL, NULL,
       
   282       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
       
   283   /**
       
   284    * GstPad::unlinked:
       
   285    * @pad: the pad that emitted the signal
       
   286    * @peer: the peer pad that has been disconnected
       
   287    *
       
   288    * Signals that a pad has been unlinked from the peer pad.
       
   289    */
       
   290   gst_pad_signals[PAD_UNLINKED] =
       
   291       g_signal_new ("unlinked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       
   292       G_STRUCT_OFFSET (GstPadClass, unlinked), NULL, NULL,
       
   293       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
       
   294   /**
       
   295    * GstPad::request-link:
       
   296    * @pad: the pad that emitted the signal
       
   297    * @peer: the peer pad for which a connection is requested
       
   298    *
       
   299    * Signals that a pad connection has been requested.
       
   300    */
       
   301   gst_pad_signals[PAD_REQUEST_LINK] =
       
   302       g_signal_new ("request-link", G_TYPE_FROM_CLASS (klass),
       
   303       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPadClass, request_link), NULL,
       
   304       NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 0);
       
   305 
       
   306   /**
       
   307    * GstPad::have-data:
       
   308    * @pad: the pad that emitted the signal
       
   309    * @mini_obj: new data
       
   310    *
       
   311    * Signals that new data is available on the pad. This signal is used
       
   312    * internally for implementing pad probes.
       
   313    * See gst_pad_add_*_probe functions.
       
   314    *
       
   315    * Returns: %TRUE to keep the data, %FALSE to drop it
       
   316    */
       
   317   gst_pad_signals[PAD_HAVE_DATA] =
       
   318       g_signal_new ("have-data", G_TYPE_FROM_CLASS (klass),
       
   319       G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
       
   320       G_STRUCT_OFFSET (GstPadClass, have_data),
       
   321       _gst_do_pass_data_accumulator,
       
   322       NULL, gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1,
       
   323       GST_TYPE_MINI_OBJECT);
       
   324 
       
   325   g_object_class_install_property (gobject_class, PAD_PROP_CAPS,
       
   326       g_param_spec_boxed ("caps", "Caps", "The capabilities of the pad",
       
   327           GST_TYPE_CAPS, G_PARAM_READABLE));
       
   328   g_object_class_install_property (gobject_class, PAD_PROP_DIRECTION,
       
   329       g_param_spec_enum ("direction", "Direction", "The direction of the pad",
       
   330           GST_TYPE_PAD_DIRECTION, GST_PAD_UNKNOWN,
       
   331           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
       
   332   /* FIXME, Make G_PARAM_CONSTRUCT_ONLY when we fix ghostpads. */
       
   333   g_object_class_install_property (gobject_class, PAD_PROP_TEMPLATE,
       
   334       g_param_spec_object ("template", "Template",
       
   335           "The GstPadTemplate of this pad", GST_TYPE_PAD_TEMPLATE,
       
   336           G_PARAM_READWRITE));
       
   337 
       
   338 #ifndef GST_DISABLE_LOADSAVE
       
   339   gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_pad_save_thyself);
       
   340 #endif
       
   341   gstobject_class->path_string_separator = ".";
       
   342 
       
   343   klass->have_data = default_have_data;
       
   344 }
       
   345 
       
   346 static void
       
   347 gst_pad_init (GstPad * pad)
       
   348 {
       
   349   GST_PAD_DIRECTION (pad) = GST_PAD_UNKNOWN;
       
   350   GST_PAD_PEER (pad) = NULL;
       
   351 
       
   352   GST_PAD_CHAINFUNC (pad) = NULL;
       
   353 
       
   354   GST_PAD_LINKFUNC (pad) = NULL;
       
   355 
       
   356   GST_PAD_CAPS (pad) = NULL;
       
   357   GST_PAD_GETCAPSFUNC (pad) = NULL;
       
   358 
       
   359   GST_PAD_ACTIVATEFUNC (pad) = GST_DEBUG_FUNCPTR (gst_pad_activate_default);
       
   360   GST_PAD_EVENTFUNC (pad) = GST_DEBUG_FUNCPTR (gst_pad_event_default);
       
   361   GST_PAD_QUERYTYPEFUNC (pad) =
       
   362       GST_DEBUG_FUNCPTR (gst_pad_get_query_types_default);
       
   363   GST_PAD_QUERYFUNC (pad) = GST_DEBUG_FUNCPTR (gst_pad_query_default);
       
   364   GST_PAD_INTLINKFUNC (pad) =
       
   365       GST_DEBUG_FUNCPTR (gst_pad_get_internal_links_default);
       
   366   GST_PAD_ACCEPTCAPSFUNC (pad) = GST_DEBUG_FUNCPTR (gst_pad_acceptcaps_default);
       
   367 
       
   368   pad->do_buffer_signals = 0;
       
   369   pad->do_event_signals = 0;
       
   370 
       
   371   GST_PAD_SET_FLUSHING (pad);
       
   372 
       
   373   pad->preroll_lock = g_mutex_new ();
       
   374   pad->preroll_cond = g_cond_new ();
       
   375 
       
   376   pad->stream_rec_lock = g_new (GStaticRecMutex, 1);
       
   377   g_static_rec_mutex_init (pad->stream_rec_lock);
       
   378 
       
   379   pad->block_cond = g_cond_new ();
       
   380 }
       
   381 
       
   382 static void
       
   383 gst_pad_dispose (GObject * object)
       
   384 {
       
   385   GstPad *pad = GST_PAD (object);
       
   386   GstPad *peer;
       
   387 
       
   388   GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, pad, "dispose");
       
   389 
       
   390   /* unlink the peer pad */
       
   391   if ((peer = gst_pad_get_peer (pad))) {
       
   392     /* window for MT unsafeness, someone else could unlink here
       
   393      * and then we call unlink with wrong pads. The unlink
       
   394      * function would catch this and safely return failed. */
       
   395     if (GST_PAD_IS_SRC (pad))
       
   396       gst_pad_unlink (pad, peer);
       
   397     else
       
   398       gst_pad_unlink (peer, pad);
       
   399 
       
   400     gst_object_unref (peer);
       
   401   }
       
   402 
       
   403   /* clear the caps */
       
   404   gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
       
   405 
       
   406   gst_pad_set_pad_template (pad, NULL);
       
   407 
       
   408   G_OBJECT_CLASS (parent_class)->dispose (object);
       
   409 }
       
   410 
       
   411 static void
       
   412 gst_pad_finalize (GObject * object)
       
   413 {
       
   414   GstPad *pad = GST_PAD (object);
       
   415   GstTask *task;
       
   416 
       
   417   /* in case the task is still around, clean it up */
       
   418   if ((task = GST_PAD_TASK (pad))) {
       
   419     gst_task_join (task);
       
   420     GST_PAD_TASK (pad) = NULL;
       
   421     gst_object_unref (task);
       
   422   }
       
   423 
       
   424   if (pad->stream_rec_lock) {
       
   425     g_static_rec_mutex_free (pad->stream_rec_lock);
       
   426     g_free (pad->stream_rec_lock);
       
   427     pad->stream_rec_lock = NULL;
       
   428   }
       
   429   if (pad->preroll_lock) {
       
   430     g_mutex_free (pad->preroll_lock);
       
   431     g_cond_free (pad->preroll_cond);
       
   432     pad->preroll_lock = NULL;
       
   433     pad->preroll_cond = NULL;
       
   434   }
       
   435   if (pad->block_cond) {
       
   436     g_cond_free (pad->block_cond);
       
   437     pad->block_cond = NULL;
       
   438   }
       
   439 
       
   440   G_OBJECT_CLASS (parent_class)->finalize (object);
       
   441 }
       
   442 
       
   443 static void
       
   444 gst_pad_set_property (GObject * object, guint prop_id,
       
   445     const GValue * value, GParamSpec * pspec)
       
   446 {
       
   447   g_return_if_fail (GST_IS_PAD (object));
       
   448 
       
   449   switch (prop_id) {
       
   450     case PAD_PROP_DIRECTION:
       
   451       GST_PAD_DIRECTION (object) = g_value_get_enum (value);
       
   452       break;
       
   453     case PAD_PROP_TEMPLATE:
       
   454       gst_pad_set_pad_template (GST_PAD_CAST (object),
       
   455           (GstPadTemplate *) g_value_get_object (value));
       
   456       break;
       
   457     default:
       
   458       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   459       break;
       
   460   }
       
   461 }
       
   462 
       
   463 static void
       
   464 gst_pad_get_property (GObject * object, guint prop_id,
       
   465     GValue * value, GParamSpec * pspec)
       
   466 {
       
   467   g_return_if_fail (GST_IS_PAD (object));
       
   468 
       
   469   switch (prop_id) {
       
   470     case PAD_PROP_CAPS:
       
   471       GST_OBJECT_LOCK (object);
       
   472       g_value_set_boxed (value, GST_PAD_CAPS (object));
       
   473       GST_OBJECT_UNLOCK (object);
       
   474       break;
       
   475     case PAD_PROP_DIRECTION:
       
   476       g_value_set_enum (value, GST_PAD_DIRECTION (object));
       
   477       break;
       
   478     case PAD_PROP_TEMPLATE:
       
   479       g_value_set_object (value, GST_PAD_PAD_TEMPLATE (object));
       
   480       break;
       
   481     default:
       
   482       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       
   483       break;
       
   484   }
       
   485 }
       
   486 
       
   487 /**
       
   488  * gst_pad_new:
       
   489  * @name: the name of the new pad.
       
   490  * @direction: the #GstPadDirection of the pad.
       
   491  *
       
   492  * Creates a new pad with the given name in the given direction.
       
   493  * If name is NULL, a guaranteed unique name (across all pads)
       
   494  * will be assigned.
       
   495  * This function makes a copy of the name so you can safely free the name.
       
   496  *
       
   497  * Returns: a new #GstPad, or NULL in case of an error.
       
   498  *
       
   499  * MT safe.
       
   500  */
       
   501 #ifdef __SYMBIAN32__
       
   502 EXPORT_C
       
   503 #endif
       
   504 
       
   505 GstPad *
       
   506 gst_pad_new (const gchar * name, GstPadDirection direction)
       
   507 {
       
   508   return g_object_new (GST_TYPE_PAD,
       
   509       "name", name, "direction", direction, NULL);
       
   510 }
       
   511 
       
   512 /**
       
   513  * gst_pad_new_from_template:
       
   514  * @templ: the pad template to use
       
   515  * @name: the name of the element
       
   516  *
       
   517  * Creates a new pad with the given name from the given template.
       
   518  * If name is NULL, a guaranteed unique name (across all pads)
       
   519  * will be assigned.
       
   520  * This function makes a copy of the name so you can safely free the name.
       
   521  *
       
   522  * Returns: a new #GstPad, or NULL in case of an error.
       
   523  */
       
   524 #ifdef __SYMBIAN32__
       
   525 EXPORT_C
       
   526 #endif
       
   527 
       
   528 GstPad *
       
   529 gst_pad_new_from_template (GstPadTemplate * templ, const gchar * name)
       
   530 {
       
   531   g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
       
   532 
       
   533   return g_object_new (GST_TYPE_PAD,
       
   534       "name", name, "direction", templ->direction, "template", templ, NULL);
       
   535 }
       
   536 
       
   537 /**
       
   538  * gst_pad_new_from_static_template:
       
   539  * @templ: the #GstStaticPadTemplate to use
       
   540  * @name: the name of the element
       
   541  *
       
   542  * Creates a new pad with the given name from the given static template.
       
   543  * If name is NULL, a guaranteed unique name (across all pads)
       
   544  * will be assigned.
       
   545  * This function makes a copy of the name so you can safely free the name.
       
   546  *
       
   547  * Returns: a new #GstPad, or NULL in case of an error.
       
   548  */
       
   549 #ifdef __SYMBIAN32__
       
   550 EXPORT_C
       
   551 #endif
       
   552 
       
   553 GstPad *
       
   554 gst_pad_new_from_static_template (GstStaticPadTemplate * templ,
       
   555     const gchar * name)
       
   556 {
       
   557   GstPad *pad;
       
   558   GstPadTemplate *template;
       
   559 
       
   560   template = gst_static_pad_template_get (templ);
       
   561   pad = gst_pad_new_from_template (template, name);
       
   562   gst_object_unref (template);
       
   563   return pad;
       
   564 }
       
   565 
       
   566 /**
       
   567  * gst_pad_get_direction:
       
   568  * @pad: a #GstPad to get the direction of.
       
   569  *
       
   570  * Gets the direction of the pad. The direction of the pad is
       
   571  * decided at construction time so this function does not take
       
   572  * the LOCK.
       
   573  *
       
   574  * Returns: the #GstPadDirection of the pad.
       
   575  *
       
   576  * MT safe.
       
   577  */
       
   578 #ifdef __SYMBIAN32__
       
   579 EXPORT_C
       
   580 #endif
       
   581 
       
   582 GstPadDirection
       
   583 gst_pad_get_direction (GstPad * pad)
       
   584 {
       
   585   GstPadDirection result;
       
   586 
       
   587   /* PAD_UNKNOWN is a little silly but we need some sort of
       
   588    * error return value */
       
   589   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
       
   590 
       
   591   GST_OBJECT_LOCK (pad);
       
   592   result = GST_PAD_DIRECTION (pad);
       
   593   GST_OBJECT_UNLOCK (pad);
       
   594 
       
   595   return result;
       
   596 }
       
   597 
       
   598 static gboolean
       
   599 gst_pad_activate_default (GstPad * pad)
       
   600 {
       
   601   return gst_pad_activate_push (pad, TRUE);
       
   602 }
       
   603 
       
   604 static void
       
   605 pre_activate (GstPad * pad, GstActivateMode new_mode)
       
   606 {
       
   607   switch (new_mode) {
       
   608     case GST_ACTIVATE_PUSH:
       
   609     case GST_ACTIVATE_PULL:
       
   610       GST_OBJECT_LOCK (pad);
       
   611       GST_DEBUG_OBJECT (pad, "setting ACTIVATE_MODE %d, unset flushing",
       
   612           new_mode);
       
   613       GST_PAD_UNSET_FLUSHING (pad);
       
   614       GST_PAD_ACTIVATE_MODE (pad) = new_mode;
       
   615       GST_OBJECT_UNLOCK (pad);
       
   616       break;
       
   617     case GST_ACTIVATE_NONE:
       
   618       GST_OBJECT_LOCK (pad);
       
   619       GST_DEBUG_OBJECT (pad, "setting ACTIVATE_MODE NONE, set flushing");
       
   620       GST_PAD_SET_FLUSHING (pad);
       
   621       GST_PAD_ACTIVATE_MODE (pad) = new_mode;
       
   622       /* unlock blocked pads so element can resume and stop */
       
   623       GST_PAD_BLOCK_BROADCAST (pad);
       
   624       GST_OBJECT_UNLOCK (pad);
       
   625       break;
       
   626   }
       
   627 }
       
   628 
       
   629 static void
       
   630 post_activate (GstPad * pad, GstActivateMode new_mode)
       
   631 {
       
   632   switch (new_mode) {
       
   633     case GST_ACTIVATE_PUSH:
       
   634     case GST_ACTIVATE_PULL:
       
   635       /* nop */
       
   636       break;
       
   637     case GST_ACTIVATE_NONE:
       
   638       /* ensures that streaming stops */
       
   639       GST_PAD_STREAM_LOCK (pad);
       
   640       GST_DEBUG_OBJECT (pad, "stopped streaming");
       
   641       GST_PAD_STREAM_UNLOCK (pad);
       
   642       break;
       
   643   }
       
   644 }
       
   645 
       
   646 /**
       
   647  * gst_pad_set_active:
       
   648  * @pad: the #GstPad to activate or deactivate.
       
   649  * @active: whether or not the pad should be active.
       
   650  *
       
   651  * Activates or deactivates the given pad.
       
   652  * Normally called from within core state change functions.
       
   653  *
       
   654  * If @active, makes sure the pad is active. If it is already active, either in
       
   655  * push or pull mode, just return. Otherwise dispatches to the pad's activate
       
   656  * function to perform the actual activation.
       
   657  *
       
   658  * If not @active, checks the pad's current mode and calls
       
   659  * gst_pad_activate_push() or gst_pad_activate_pull(), as appropriate, with a
       
   660  * FALSE argument.
       
   661  *
       
   662  * Returns: #TRUE if the operation was successful.
       
   663  *
       
   664  * MT safe.
       
   665  */
       
   666 #ifdef __SYMBIAN32__
       
   667 EXPORT_C
       
   668 #endif
       
   669 
       
   670 gboolean
       
   671 gst_pad_set_active (GstPad * pad, gboolean active)
       
   672 {
       
   673   GstActivateMode old;
       
   674   gboolean ret = FALSE;
       
   675 
       
   676   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
   677 
       
   678   GST_OBJECT_LOCK (pad);
       
   679   old = GST_PAD_ACTIVATE_MODE (pad);
       
   680   GST_OBJECT_UNLOCK (pad);
       
   681 
       
   682   if (active) {
       
   683     switch (old) {
       
   684       case GST_ACTIVATE_PUSH:
       
   685         GST_DEBUG_OBJECT (pad, "activating pad from push");
       
   686         ret = TRUE;
       
   687         break;
       
   688       case GST_ACTIVATE_PULL:
       
   689         GST_DEBUG_OBJECT (pad, "activating pad from pull");
       
   690         ret = TRUE;
       
   691         break;
       
   692       case GST_ACTIVATE_NONE:
       
   693         GST_DEBUG_OBJECT (pad, "activating pad from none");
       
   694         ret = (GST_PAD_ACTIVATEFUNC (pad)) (pad);
       
   695         break;
       
   696     }
       
   697   } else {
       
   698     switch (old) {
       
   699       case GST_ACTIVATE_PUSH:
       
   700         GST_DEBUG_OBJECT (pad, "deactivating pad from push");
       
   701         ret = gst_pad_activate_push (pad, FALSE);
       
   702         break;
       
   703       case GST_ACTIVATE_PULL:
       
   704         GST_DEBUG_OBJECT (pad, "deactivating pad from pull");
       
   705         ret = gst_pad_activate_pull (pad, FALSE);
       
   706         break;
       
   707       case GST_ACTIVATE_NONE:
       
   708         GST_DEBUG_OBJECT (pad, "deactivating pad from none");
       
   709         ret = TRUE;
       
   710         break;
       
   711     }
       
   712   }
       
   713 
       
   714   if (!ret) {
       
   715     GST_OBJECT_LOCK (pad);
       
   716     if (!active) {
       
   717       g_critical ("Failed to deactivate pad %s:%s, very bad",
       
   718           GST_DEBUG_PAD_NAME (pad));
       
   719     } else {
       
   720       GST_WARNING_OBJECT (pad, "Failed to activate pad");
       
   721     }
       
   722     GST_OBJECT_UNLOCK (pad);
       
   723   }
       
   724 
       
   725   return ret;
       
   726 }
       
   727 
       
   728 /**
       
   729  * gst_pad_activate_pull:
       
   730  * @pad: the #GstPad to activate or deactivate.
       
   731  * @active: whether or not the pad should be active.
       
   732  *
       
   733  * Activates or deactivates the given pad in pull mode via dispatching to the
       
   734  * pad's activatepullfunc. For use from within pad activation functions only.
       
   735  * When called on sink pads, will first proxy the call to the peer pad, which
       
   736  * is expected to activate its internally linked pads from within its
       
   737  * activate_pull function.
       
   738  *
       
   739  * If you don't know what this is, you probably don't want to call it.
       
   740  *
       
   741  * Returns: TRUE if the operation was successful.
       
   742  *
       
   743  * MT safe.
       
   744  */
       
   745 #ifdef __SYMBIAN32__
       
   746 EXPORT_C
       
   747 #endif
       
   748 
       
   749 gboolean
       
   750 gst_pad_activate_pull (GstPad * pad, gboolean active)
       
   751 {
       
   752   GstActivateMode old, new;
       
   753   GstPad *peer;
       
   754 
       
   755   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
   756 
       
   757   GST_OBJECT_LOCK (pad);
       
   758   old = GST_PAD_ACTIVATE_MODE (pad);
       
   759   GST_OBJECT_UNLOCK (pad);
       
   760 
       
   761   if (active) {
       
   762     switch (old) {
       
   763       case GST_ACTIVATE_PULL:
       
   764         GST_DEBUG_OBJECT (pad, "activating pad from pull, was ok");
       
   765         goto was_ok;
       
   766       case GST_ACTIVATE_PUSH:
       
   767         GST_DEBUG_OBJECT (pad,
       
   768             "activating pad from push, deactivate push first");
       
   769         /* pad was activate in the wrong direction, deactivate it
       
   770          * and reactivate it in pull mode */
       
   771         if (G_UNLIKELY (!gst_pad_activate_push (pad, FALSE)))
       
   772           goto deactivate_failed;
       
   773         /* fallthrough, pad is deactivated now. */
       
   774       case GST_ACTIVATE_NONE:
       
   775         GST_DEBUG_OBJECT (pad, "activating pad from none");
       
   776         break;
       
   777     }
       
   778   } else {
       
   779     switch (old) {
       
   780       case GST_ACTIVATE_NONE:
       
   781         GST_DEBUG_OBJECT (pad, "deactivating pad from none, was ok");
       
   782         goto was_ok;
       
   783       case GST_ACTIVATE_PUSH:
       
   784         GST_DEBUG_OBJECT (pad, "deactivating pad from push, weird");
       
   785         /* pad was activated in the other direction, deactivate it
       
   786          * in push mode, this should not happen... */
       
   787         if (G_UNLIKELY (!gst_pad_activate_push (pad, FALSE)))
       
   788           goto deactivate_failed;
       
   789         /* everything is fine now */
       
   790         goto was_ok;
       
   791       case GST_ACTIVATE_PULL:
       
   792         GST_DEBUG_OBJECT (pad, "deactivating pad from pull");
       
   793         break;
       
   794     }
       
   795   }
       
   796 
       
   797   if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
       
   798     if ((peer = gst_pad_get_peer (pad))) {
       
   799       GST_DEBUG_OBJECT (pad, "calling peer");
       
   800       if (G_UNLIKELY (!gst_pad_activate_pull (peer, active)))
       
   801         goto peer_failed;
       
   802       gst_object_unref (peer);
       
   803     } else {
       
   804       goto not_linked;
       
   805     }
       
   806   } else {
       
   807     if (G_UNLIKELY (GST_PAD_GETRANGEFUNC (pad) == NULL))
       
   808       goto failure;             /* Can't activate pull on a src without a
       
   809                                    getrange function */
       
   810   }
       
   811 
       
   812   new = active ? GST_ACTIVATE_PULL : GST_ACTIVATE_NONE;
       
   813   pre_activate (pad, new);
       
   814 
       
   815   if (GST_PAD_ACTIVATEPULLFUNC (pad)) {
       
   816     if (G_UNLIKELY (!GST_PAD_ACTIVATEPULLFUNC (pad) (pad, active)))
       
   817       goto failure;
       
   818   } else {
       
   819     /* can happen for sinks of passthrough elements */
       
   820   }
       
   821 
       
   822   post_activate (pad, new);
       
   823 
       
   824   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "%s in pull mode",
       
   825       active ? "activated" : "deactivated");
       
   826 
       
   827   return TRUE;
       
   828 
       
   829 was_ok:
       
   830   {
       
   831     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "already %s in pull mode",
       
   832         active ? "activated" : "deactivated");
       
   833     return TRUE;
       
   834   }
       
   835 deactivate_failed:
       
   836   {
       
   837     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
       
   838         "failed to %s in switch to pull from mode %d",
       
   839         (active ? "activate" : "deactivate"), old);
       
   840     return FALSE;
       
   841   }
       
   842 peer_failed:
       
   843   {
       
   844     GST_OBJECT_LOCK (peer);
       
   845     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
       
   846         "activate_pull on peer (%s:%s) failed", GST_DEBUG_PAD_NAME (peer));
       
   847     GST_OBJECT_UNLOCK (peer);
       
   848     gst_object_unref (peer);
       
   849     return FALSE;
       
   850   }
       
   851 not_linked:
       
   852   {
       
   853     GST_CAT_INFO_OBJECT (GST_CAT_PADS, pad, "can't activate unlinked sink "
       
   854         "pad in pull mode");
       
   855     return FALSE;
       
   856   }
       
   857 failure:
       
   858   {
       
   859     GST_OBJECT_LOCK (pad);
       
   860     GST_CAT_INFO_OBJECT (GST_CAT_PADS, pad, "failed to %s in pull mode",
       
   861         active ? "activate" : "deactivate");
       
   862     GST_PAD_SET_FLUSHING (pad);
       
   863     GST_PAD_ACTIVATE_MODE (pad) = old;
       
   864     GST_OBJECT_UNLOCK (pad);
       
   865     return FALSE;
       
   866   }
       
   867 }
       
   868 
       
   869 /**
       
   870  * gst_pad_activate_push:
       
   871  * @pad: the #GstPad to activate or deactivate.
       
   872  * @active: whether the pad should be active or not.
       
   873  *
       
   874  * Activates or deactivates the given pad in push mode via dispatching to the
       
   875  * pad's activatepushfunc. For use from within pad activation functions only.
       
   876  *
       
   877  * If you don't know what this is, you probably don't want to call it.
       
   878  *
       
   879  * Returns: %TRUE if the operation was successful.
       
   880  *
       
   881  * MT safe.
       
   882  */
       
   883 #ifdef __SYMBIAN32__
       
   884 EXPORT_C
       
   885 #endif
       
   886 
       
   887 gboolean
       
   888 gst_pad_activate_push (GstPad * pad, gboolean active)
       
   889 {
       
   890   GstActivateMode old, new;
       
   891 
       
   892   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
   893   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "trying to set %s in push mode",
       
   894       active ? "activated" : "deactivated");
       
   895 
       
   896   GST_OBJECT_LOCK (pad);
       
   897   old = GST_PAD_ACTIVATE_MODE (pad);
       
   898   GST_OBJECT_UNLOCK (pad);
       
   899 
       
   900   if (active) {
       
   901     switch (old) {
       
   902       case GST_ACTIVATE_PUSH:
       
   903         GST_DEBUG_OBJECT (pad, "activating pad from push, was ok");
       
   904         goto was_ok;
       
   905       case GST_ACTIVATE_PULL:
       
   906         GST_DEBUG_OBJECT (pad,
       
   907             "activating pad from push, deactivating pull first");
       
   908         /* pad was activate in the wrong direction, deactivate it
       
   909          * an reactivate it in push mode */
       
   910         if (G_UNLIKELY (!gst_pad_activate_pull (pad, FALSE)))
       
   911           goto deactivate_failed;
       
   912         /* fallthrough, pad is deactivated now. */
       
   913       case GST_ACTIVATE_NONE:
       
   914         GST_DEBUG_OBJECT (pad, "activating pad from none");
       
   915         break;
       
   916     }
       
   917   } else {
       
   918     switch (old) {
       
   919       case GST_ACTIVATE_NONE:
       
   920         GST_DEBUG_OBJECT (pad, "deactivating pad from none, was ok");
       
   921         goto was_ok;
       
   922       case GST_ACTIVATE_PULL:
       
   923         GST_DEBUG_OBJECT (pad, "deactivating pad from pull, weird");
       
   924         /* pad was activated in the other direction, deactivate it
       
   925          * in pull mode, this should not happen... */
       
   926         if (G_UNLIKELY (!gst_pad_activate_pull (pad, FALSE)))
       
   927           goto deactivate_failed;
       
   928         /* everything is fine now */
       
   929         goto was_ok;
       
   930       case GST_ACTIVATE_PUSH:
       
   931         GST_DEBUG_OBJECT (pad, "deactivating pad from push");
       
   932         break;
       
   933     }
       
   934   }
       
   935 
       
   936   new = active ? GST_ACTIVATE_PUSH : GST_ACTIVATE_NONE;
       
   937   pre_activate (pad, new);
       
   938 
       
   939   if (GST_PAD_ACTIVATEPUSHFUNC (pad)) {
       
   940     if (G_UNLIKELY (!GST_PAD_ACTIVATEPUSHFUNC (pad) (pad, active))) {
       
   941       goto failure;
       
   942     }
       
   943   } else {
       
   944     /* quite ok, element relies on state change func to prepare itself */
       
   945   }
       
   946 
       
   947   post_activate (pad, new);
       
   948 
       
   949   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "%s in push mode",
       
   950       active ? "activated" : "deactivated");
       
   951   return TRUE;
       
   952 
       
   953 was_ok:
       
   954   {
       
   955     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "already %s in push mode",
       
   956         active ? "activated" : "deactivated");
       
   957     return TRUE;
       
   958   }
       
   959 deactivate_failed:
       
   960   {
       
   961     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
       
   962         "failed to %s in switch to push from mode %d",
       
   963         (active ? "activate" : "deactivate"), old);
       
   964     return FALSE;
       
   965   }
       
   966 failure:
       
   967   {
       
   968     GST_OBJECT_LOCK (pad);
       
   969     GST_CAT_INFO_OBJECT (GST_CAT_PADS, pad, "failed to %s in push mode",
       
   970         active ? "activate" : "deactivate");
       
   971     GST_PAD_SET_FLUSHING (pad);
       
   972     GST_PAD_ACTIVATE_MODE (pad) = old;
       
   973     GST_OBJECT_UNLOCK (pad);
       
   974     return FALSE;
       
   975   }
       
   976 }
       
   977 
       
   978 /**
       
   979  * gst_pad_is_active:
       
   980  * @pad: the #GstPad to query
       
   981  *
       
   982  * Query if a pad is active
       
   983  *
       
   984  * Returns: TRUE if the pad is active.
       
   985  *
       
   986  * MT safe.
       
   987  */
       
   988 #ifdef __SYMBIAN32__
       
   989 EXPORT_C
       
   990 #endif
       
   991 
       
   992 gboolean
       
   993 gst_pad_is_active (GstPad * pad)
       
   994 {
       
   995   gboolean result = FALSE;
       
   996 
       
   997   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
   998 
       
   999   GST_OBJECT_LOCK (pad);
       
  1000   result = GST_PAD_MODE_ACTIVATE (GST_PAD_ACTIVATE_MODE (pad));
       
  1001   GST_OBJECT_UNLOCK (pad);
       
  1002 
       
  1003   return result;
       
  1004 }
       
  1005 
       
  1006 /**
       
  1007  * gst_pad_set_blocked_async:
       
  1008  * @pad: the #GstPad to block or unblock
       
  1009  * @blocked: boolean indicating whether the pad should be blocked or unblocked
       
  1010  * @callback: #GstPadBlockCallback that will be called when the
       
  1011  *            operation succeeds
       
  1012  * @user_data: user data passed to the callback
       
  1013  *
       
  1014  * Blocks or unblocks the dataflow on a pad. The provided callback
       
  1015  * is called when the operation succeeds; this happens right before the next
       
  1016  * attempt at pushing a buffer on the pad.
       
  1017  *
       
  1018  * This can take a while as the pad can only become blocked when real dataflow
       
  1019  * is happening.
       
  1020  * When the pipeline is stalled, for example in PAUSED, this can
       
  1021  * take an indeterminate amount of time.
       
  1022  * You can pass NULL as the callback to make this call block. Be careful with
       
  1023  * this blocking call as it might not return for reasons stated above.
       
  1024  *
       
  1025  * Returns: TRUE if the pad could be blocked. This function can fail if the
       
  1026  * wrong parameters were passed or the pad was already in the requested state.
       
  1027  *
       
  1028  * MT safe.
       
  1029  */
       
  1030 #ifdef __SYMBIAN32__
       
  1031 EXPORT_C
       
  1032 #endif
       
  1033 
       
  1034 gboolean
       
  1035 gst_pad_set_blocked_async (GstPad * pad, gboolean blocked,
       
  1036     GstPadBlockCallback callback, gpointer user_data)
       
  1037 {
       
  1038   gboolean was_blocked = FALSE;
       
  1039 
       
  1040   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  1041 
       
  1042   GST_OBJECT_LOCK (pad);
       
  1043 
       
  1044   was_blocked = GST_PAD_IS_BLOCKED (pad);
       
  1045 
       
  1046   if (G_UNLIKELY (was_blocked == blocked))
       
  1047     goto had_right_state;
       
  1048 
       
  1049   if (blocked) {
       
  1050     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocking pad");
       
  1051 
       
  1052     GST_OBJECT_FLAG_SET (pad, GST_PAD_BLOCKED);
       
  1053     pad->block_callback = callback;
       
  1054     pad->block_data = user_data;
       
  1055     if (!callback) {
       
  1056       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "waiting for block");
       
  1057       GST_PAD_BLOCK_WAIT (pad);
       
  1058       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocked");
       
  1059     }
       
  1060   } else {
       
  1061     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "unblocking pad");
       
  1062 
       
  1063     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_BLOCKED);
       
  1064 
       
  1065     pad->block_callback = callback;
       
  1066     pad->block_data = user_data;
       
  1067 
       
  1068     GST_PAD_BLOCK_BROADCAST (pad);
       
  1069     if (!callback) {
       
  1070       /* no callback, wait for the unblock to happen */
       
  1071       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "waiting for unblock");
       
  1072       GST_PAD_BLOCK_WAIT (pad);
       
  1073       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "unblocked");
       
  1074     }
       
  1075   }
       
  1076   GST_OBJECT_UNLOCK (pad);
       
  1077 
       
  1078   return TRUE;
       
  1079 
       
  1080 had_right_state:
       
  1081   {
       
  1082     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  1083         "pad was in right state (%d)", was_blocked);
       
  1084     GST_OBJECT_UNLOCK (pad);
       
  1085 
       
  1086     return FALSE;
       
  1087   }
       
  1088 }
       
  1089 
       
  1090 /**
       
  1091  * gst_pad_set_blocked:
       
  1092  * @pad: the #GstPad to block or unblock
       
  1093  * @blocked: boolean indicating we should block or unblock
       
  1094  *
       
  1095  * Blocks or unblocks the dataflow on a pad. This function is
       
  1096  * a shortcut for gst_pad_set_blocked_async() with a NULL
       
  1097  * callback.
       
  1098  *
       
  1099  * Returns: TRUE if the pad could be blocked. This function can fail if the
       
  1100  * wrong parameters were passed or the pad was already in the requested state.
       
  1101  *
       
  1102  * MT safe.
       
  1103  */
       
  1104 #ifdef __SYMBIAN32__
       
  1105 EXPORT_C
       
  1106 #endif
       
  1107 
       
  1108 gboolean
       
  1109 gst_pad_set_blocked (GstPad * pad, gboolean blocked)
       
  1110 {
       
  1111   return gst_pad_set_blocked_async (pad, blocked, NULL, NULL);
       
  1112 }
       
  1113 
       
  1114 /**
       
  1115  * gst_pad_is_blocked:
       
  1116  * @pad: the #GstPad to query
       
  1117  *
       
  1118  * Checks if the pad is blocked or not. This function returns the
       
  1119  * last requested state of the pad. It is not certain that the pad
       
  1120  * is actually blocking at this point (see gst_pad_is_blocking()).
       
  1121  *
       
  1122  * Returns: TRUE if the pad is blocked.
       
  1123  *
       
  1124  * MT safe.
       
  1125  */
       
  1126 #ifdef __SYMBIAN32__
       
  1127 EXPORT_C
       
  1128 #endif
       
  1129 
       
  1130 gboolean
       
  1131 gst_pad_is_blocked (GstPad * pad)
       
  1132 {
       
  1133   gboolean result = FALSE;
       
  1134 
       
  1135   g_return_val_if_fail (GST_IS_PAD (pad), result);
       
  1136 
       
  1137   GST_OBJECT_LOCK (pad);
       
  1138   result = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_BLOCKED);
       
  1139   GST_OBJECT_UNLOCK (pad);
       
  1140 
       
  1141   return result;
       
  1142 }
       
  1143 
       
  1144 /**
       
  1145  * gst_pad_is_blocking:
       
  1146  * @pad: the #GstPad to query
       
  1147  *
       
  1148  * Checks if the pad is blocking or not. This is a guaranteed state
       
  1149  * of whether the pad is actually blocking on a #GstBuffer or a #GstEvent.
       
  1150  *
       
  1151  * Returns: TRUE if the pad is blocking.
       
  1152  *
       
  1153  * MT safe.
       
  1154  *
       
  1155  * Since: 0.10.11
       
  1156  */
       
  1157 #ifdef __SYMBIAN32__
       
  1158 EXPORT_C
       
  1159 #endif
       
  1160 
       
  1161 gboolean
       
  1162 gst_pad_is_blocking (GstPad * pad)
       
  1163 {
       
  1164   gboolean result = FALSE;
       
  1165 
       
  1166   g_return_val_if_fail (GST_IS_PAD (pad), result);
       
  1167 
       
  1168   GST_OBJECT_LOCK (pad);
       
  1169   /* the blocking flag is only valid if the pad is not flushing */
       
  1170   result = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_BLOCKING) &&
       
  1171       !GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLUSHING);
       
  1172   GST_OBJECT_UNLOCK (pad);
       
  1173 
       
  1174   return result;
       
  1175 }
       
  1176 
       
  1177 /**
       
  1178  * gst_pad_set_activate_function:
       
  1179  * @pad: a #GstPad.
       
  1180  * @activate: the #GstPadActivateFunction to set.
       
  1181  *
       
  1182  * Sets the given activate function for @pad. The activate function will
       
  1183  * dispatch to gst_pad_activate_push() or gst_pad_activate_pull() to perform
       
  1184  * the actual activation. Only makes sense to set on sink pads.
       
  1185  *
       
  1186  * Call this function if your sink pad can start a pull-based task.
       
  1187  */
       
  1188 #ifdef __SYMBIAN32__
       
  1189 EXPORT_C
       
  1190 #endif
       
  1191 
       
  1192 void
       
  1193 gst_pad_set_activate_function (GstPad * pad, GstPadActivateFunction activate)
       
  1194 {
       
  1195   g_return_if_fail (GST_IS_PAD (pad));
       
  1196 
       
  1197   GST_PAD_ACTIVATEFUNC (pad) = activate;
       
  1198   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "activatefunc set to %s",
       
  1199       GST_DEBUG_FUNCPTR_NAME (activate));
       
  1200 }
       
  1201 
       
  1202 /**
       
  1203  * gst_pad_set_activatepull_function:
       
  1204  * @pad: a #GstPad.
       
  1205  * @activatepull: the #GstPadActivateModeFunction to set.
       
  1206  *
       
  1207  * Sets the given activate_pull function for the pad. An activate_pull function
       
  1208  * prepares the element and any upstream connections for pulling. See XXX
       
  1209  * part-activation.txt for details.
       
  1210  */
       
  1211 #ifdef __SYMBIAN32__
       
  1212 EXPORT_C
       
  1213 #endif
       
  1214 
       
  1215 void
       
  1216 gst_pad_set_activatepull_function (GstPad * pad,
       
  1217     GstPadActivateModeFunction activatepull)
       
  1218 {
       
  1219   g_return_if_fail (GST_IS_PAD (pad));
       
  1220 
       
  1221   GST_PAD_ACTIVATEPULLFUNC (pad) = activatepull;
       
  1222   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "activatepullfunc set to %s",
       
  1223       GST_DEBUG_FUNCPTR_NAME (activatepull));
       
  1224 }
       
  1225 
       
  1226 /**
       
  1227  * gst_pad_set_activatepush_function:
       
  1228  * @pad: a #GstPad.
       
  1229  * @activatepush: the #GstPadActivateModeFunction to set.
       
  1230  *
       
  1231  * Sets the given activate_push function for the pad. An activate_push function
       
  1232  * prepares the element for pushing. See XXX part-activation.txt for details.
       
  1233  */
       
  1234 #ifdef __SYMBIAN32__
       
  1235 EXPORT_C
       
  1236 #endif
       
  1237 
       
  1238 void
       
  1239 gst_pad_set_activatepush_function (GstPad * pad,
       
  1240     GstPadActivateModeFunction activatepush)
       
  1241 {
       
  1242   g_return_if_fail (GST_IS_PAD (pad));
       
  1243 
       
  1244   GST_PAD_ACTIVATEPUSHFUNC (pad) = activatepush;
       
  1245   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "activatepushfunc set to %s",
       
  1246       GST_DEBUG_FUNCPTR_NAME (activatepush));
       
  1247 }
       
  1248 
       
  1249 /**
       
  1250  * gst_pad_set_chain_function:
       
  1251  * @pad: a sink #GstPad.
       
  1252  * @chain: the #GstPadChainFunction to set.
       
  1253  *
       
  1254  * Sets the given chain function for the pad. The chain function is called to
       
  1255  * process a #GstBuffer input buffer. see #GstPadChainFunction for more details.
       
  1256  */
       
  1257 #ifdef __SYMBIAN32__
       
  1258 EXPORT_C
       
  1259 #endif
       
  1260 
       
  1261 void
       
  1262 gst_pad_set_chain_function (GstPad * pad, GstPadChainFunction chain)
       
  1263 {
       
  1264   g_return_if_fail (GST_IS_PAD (pad));
       
  1265   g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK);
       
  1266 
       
  1267   GST_PAD_CHAINFUNC (pad) = chain;
       
  1268   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "chainfunc set to %s",
       
  1269       GST_DEBUG_FUNCPTR_NAME (chain));
       
  1270 }
       
  1271 
       
  1272 /**
       
  1273  * gst_pad_set_getrange_function:
       
  1274  * @pad: a source #GstPad.
       
  1275  * @get: the #GstPadGetRangeFunction to set.
       
  1276  *
       
  1277  * Sets the given getrange function for the pad. The getrange function is
       
  1278  * called to produce a new #GstBuffer to start the processing pipeline. see
       
  1279  * #GstPadGetRangeFunction for a description of the getrange function.
       
  1280  */
       
  1281 #ifdef __SYMBIAN32__
       
  1282 EXPORT_C
       
  1283 #endif
       
  1284 
       
  1285 void
       
  1286 gst_pad_set_getrange_function (GstPad * pad, GstPadGetRangeFunction get)
       
  1287 {
       
  1288   g_return_if_fail (GST_IS_PAD (pad));
       
  1289   g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
       
  1290 
       
  1291   GST_PAD_GETRANGEFUNC (pad) = get;
       
  1292 
       
  1293   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "getrangefunc set to %s",
       
  1294       GST_DEBUG_FUNCPTR_NAME (get));
       
  1295 }
       
  1296 
       
  1297 /**
       
  1298  * gst_pad_set_checkgetrange_function:
       
  1299  * @pad: a source #GstPad.
       
  1300  * @check: the #GstPadCheckGetRangeFunction to set.
       
  1301  *
       
  1302  * Sets the given checkgetrange function for the pad. Implement this function
       
  1303  * on a pad if you dynamically support getrange based scheduling on the pad.
       
  1304  */
       
  1305 #ifdef __SYMBIAN32__
       
  1306 EXPORT_C
       
  1307 #endif
       
  1308 
       
  1309 void
       
  1310 gst_pad_set_checkgetrange_function (GstPad * pad,
       
  1311     GstPadCheckGetRangeFunction check)
       
  1312 {
       
  1313   g_return_if_fail (GST_IS_PAD (pad));
       
  1314   g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
       
  1315 
       
  1316   GST_PAD_CHECKGETRANGEFUNC (pad) = check;
       
  1317 
       
  1318   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "checkgetrangefunc set to %s",
       
  1319       GST_DEBUG_FUNCPTR_NAME (check));
       
  1320 }
       
  1321 
       
  1322 /**
       
  1323  * gst_pad_set_event_function:
       
  1324  * @pad: a #GstPad of either direction.
       
  1325  * @event: the #GstPadEventFunction to set.
       
  1326  *
       
  1327  * Sets the given event handler for the pad.
       
  1328  */
       
  1329 #ifdef __SYMBIAN32__
       
  1330 EXPORT_C
       
  1331 #endif
       
  1332 
       
  1333 void
       
  1334 gst_pad_set_event_function (GstPad * pad, GstPadEventFunction event)
       
  1335 {
       
  1336   g_return_if_fail (GST_IS_PAD (pad));
       
  1337 
       
  1338   GST_PAD_EVENTFUNC (pad) = event;
       
  1339 
       
  1340   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "eventfunc for set to %s",
       
  1341       GST_DEBUG_FUNCPTR_NAME (event));
       
  1342 }
       
  1343 
       
  1344 /**
       
  1345  * gst_pad_set_query_function:
       
  1346  * @pad: a #GstPad of either direction.
       
  1347  * @query: the #GstPadQueryFunction to set.
       
  1348  *
       
  1349  * Set the given query function for the pad.
       
  1350  */
       
  1351 #ifdef __SYMBIAN32__
       
  1352 EXPORT_C
       
  1353 #endif
       
  1354 
       
  1355 void
       
  1356 gst_pad_set_query_function (GstPad * pad, GstPadQueryFunction query)
       
  1357 {
       
  1358   g_return_if_fail (GST_IS_PAD (pad));
       
  1359 
       
  1360   GST_PAD_QUERYFUNC (pad) = query;
       
  1361 
       
  1362   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "queryfunc set to %s",
       
  1363       GST_DEBUG_FUNCPTR_NAME (query));
       
  1364 }
       
  1365 
       
  1366 /**
       
  1367  * gst_pad_set_query_type_function:
       
  1368  * @pad: a #GstPad of either direction.
       
  1369  * @type_func: the #GstPadQueryTypeFunction to set.
       
  1370  *
       
  1371  * Set the given query type function for the pad.
       
  1372  */
       
  1373 #ifdef __SYMBIAN32__
       
  1374 EXPORT_C
       
  1375 #endif
       
  1376 
       
  1377 void
       
  1378 gst_pad_set_query_type_function (GstPad * pad,
       
  1379     GstPadQueryTypeFunction type_func)
       
  1380 {
       
  1381   g_return_if_fail (GST_IS_PAD (pad));
       
  1382 
       
  1383   GST_PAD_QUERYTYPEFUNC (pad) = type_func;
       
  1384 
       
  1385   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "querytypefunc set to %s",
       
  1386       GST_DEBUG_FUNCPTR_NAME (type_func));
       
  1387 }
       
  1388 
       
  1389 /**
       
  1390  * gst_pad_get_query_types:
       
  1391  * @pad: a #GstPad.
       
  1392  *
       
  1393  * Get an array of supported queries that can be performed
       
  1394  * on this pad.
       
  1395  *
       
  1396  * Returns: a zero-terminated array of #GstQueryType.
       
  1397  */
       
  1398 #ifdef __SYMBIAN32__
       
  1399 EXPORT_C
       
  1400 #endif
       
  1401 
       
  1402 const GstQueryType *
       
  1403 gst_pad_get_query_types (GstPad * pad)
       
  1404 {
       
  1405   GstPadQueryTypeFunction func;
       
  1406 
       
  1407   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  1408 
       
  1409   if (G_UNLIKELY ((func = GST_PAD_QUERYTYPEFUNC (pad)) == NULL))
       
  1410     goto no_func;
       
  1411 
       
  1412   return func (pad);
       
  1413 
       
  1414 no_func:
       
  1415   {
       
  1416     return NULL;
       
  1417   }
       
  1418 }
       
  1419 
       
  1420 static gboolean
       
  1421 gst_pad_get_query_types_dispatcher (GstPad * pad, const GstQueryType ** data)
       
  1422 {
       
  1423   *data = gst_pad_get_query_types (pad);
       
  1424 
       
  1425   return TRUE;
       
  1426 }
       
  1427 
       
  1428 /**
       
  1429  * gst_pad_get_query_types_default:
       
  1430  * @pad: a #GstPad.
       
  1431  *
       
  1432  * Invoke the default dispatcher for the query types on
       
  1433  * the pad.
       
  1434  *
       
  1435  * Returns: an zero-terminated array of #GstQueryType, or NULL if none of the
       
  1436  * internally-linked pads has a query types function.
       
  1437  */
       
  1438 #ifdef __SYMBIAN32__
       
  1439 EXPORT_C
       
  1440 #endif
       
  1441 
       
  1442 const GstQueryType *
       
  1443 gst_pad_get_query_types_default (GstPad * pad)
       
  1444 {
       
  1445   GstQueryType *result = NULL;
       
  1446 
       
  1447   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  1448 
       
  1449   gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
       
  1450       gst_pad_get_query_types_dispatcher, &result);
       
  1451 
       
  1452   return result;
       
  1453 }
       
  1454 
       
  1455 /**
       
  1456  * gst_pad_set_internal_link_function:
       
  1457  * @pad: a #GstPad of either direction.
       
  1458  * @intlink: the #GstPadIntLinkFunction to set.
       
  1459  *
       
  1460  * Sets the given internal link function for the pad.
       
  1461  */
       
  1462 #ifdef __SYMBIAN32__
       
  1463 EXPORT_C
       
  1464 #endif
       
  1465 
       
  1466 void
       
  1467 gst_pad_set_internal_link_function (GstPad * pad, GstPadIntLinkFunction intlink)
       
  1468 {
       
  1469   g_return_if_fail (GST_IS_PAD (pad));
       
  1470 
       
  1471   GST_PAD_INTLINKFUNC (pad) = intlink;
       
  1472   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "internal link set to %s",
       
  1473       GST_DEBUG_FUNCPTR_NAME (intlink));
       
  1474 }
       
  1475 
       
  1476 /**
       
  1477  * gst_pad_set_link_function:
       
  1478  * @pad: a #GstPad.
       
  1479  * @link: the #GstPadLinkFunction to set.
       
  1480  *
       
  1481  * Sets the given link function for the pad. It will be called when
       
  1482  * the pad is linked with another pad.
       
  1483  *
       
  1484  * The return value #GST_PAD_LINK_OK should be used when the connection can be
       
  1485  * made.
       
  1486  *
       
  1487  * The return value #GST_PAD_LINK_REFUSED should be used when the connection
       
  1488  * cannot be made for some reason.
       
  1489  *
       
  1490  * If @link is installed on a source pad, it should call the #GstPadLinkFunction
       
  1491  * of the peer sink pad, if present.
       
  1492  */
       
  1493 #ifdef __SYMBIAN32__
       
  1494 EXPORT_C
       
  1495 #endif
       
  1496 
       
  1497 void
       
  1498 gst_pad_set_link_function (GstPad * pad, GstPadLinkFunction link)
       
  1499 {
       
  1500   g_return_if_fail (GST_IS_PAD (pad));
       
  1501 
       
  1502   GST_PAD_LINKFUNC (pad) = link;
       
  1503   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "linkfunc set to %s",
       
  1504       GST_DEBUG_FUNCPTR_NAME (link));
       
  1505 }
       
  1506 
       
  1507 /**
       
  1508  * gst_pad_set_unlink_function:
       
  1509  * @pad: a #GstPad.
       
  1510  * @unlink: the #GstPadUnlinkFunction to set.
       
  1511  *
       
  1512  * Sets the given unlink function for the pad. It will be called
       
  1513  * when the pad is unlinked.
       
  1514  */
       
  1515 #ifdef __SYMBIAN32__
       
  1516 EXPORT_C
       
  1517 #endif
       
  1518 
       
  1519 void
       
  1520 gst_pad_set_unlink_function (GstPad * pad, GstPadUnlinkFunction unlink)
       
  1521 {
       
  1522   g_return_if_fail (GST_IS_PAD (pad));
       
  1523 
       
  1524   GST_PAD_UNLINKFUNC (pad) = unlink;
       
  1525   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "unlinkfunc set to %s",
       
  1526       GST_DEBUG_FUNCPTR_NAME (unlink));
       
  1527 }
       
  1528 
       
  1529 /**
       
  1530  * gst_pad_set_getcaps_function:
       
  1531  * @pad: a #GstPad.
       
  1532  * @getcaps: the #GstPadGetCapsFunction to set.
       
  1533  *
       
  1534  * Sets the given getcaps function for the pad. @getcaps should return the
       
  1535  * allowable caps for a pad in the context of the element's state, its link to
       
  1536  * other elements, and the devices or files it has opened. These caps must be a
       
  1537  * subset of the pad template caps. In the NULL state with no links, @getcaps
       
  1538  * should ideally return the same caps as the pad template. In rare
       
  1539  * circumstances, an object property can affect the caps returned by @getcaps,
       
  1540  * but this is discouraged.
       
  1541  *
       
  1542  * You do not need to call this function if @pad's allowed caps are always the
       
  1543  * same as the pad template caps. This can only be true if the padtemplate
       
  1544  * has fixed simple caps.
       
  1545  *
       
  1546  * For most filters, the caps returned by @getcaps is directly affected by the
       
  1547  * allowed caps on other pads. For demuxers and decoders, the caps returned by
       
  1548  * the srcpad's getcaps function is directly related to the stream data. Again,
       
  1549  * @getcaps should return the most specific caps it reasonably can, since this
       
  1550  * helps with autoplugging.
       
  1551  *
       
  1552  * Note that the return value from @getcaps is owned by the caller, so the
       
  1553  * caller should unref the caps after usage.
       
  1554  */
       
  1555 #ifdef __SYMBIAN32__
       
  1556 EXPORT_C
       
  1557 #endif
       
  1558 
       
  1559 void
       
  1560 gst_pad_set_getcaps_function (GstPad * pad, GstPadGetCapsFunction getcaps)
       
  1561 {
       
  1562   g_return_if_fail (GST_IS_PAD (pad));
       
  1563 
       
  1564   GST_PAD_GETCAPSFUNC (pad) = getcaps;
       
  1565   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "getcapsfunc set to %s",
       
  1566       GST_DEBUG_FUNCPTR_NAME (getcaps));
       
  1567 }
       
  1568 
       
  1569 /**
       
  1570  * gst_pad_set_acceptcaps_function:
       
  1571  * @pad: a #GstPad.
       
  1572  * @acceptcaps: the #GstPadAcceptCapsFunction to set.
       
  1573  *
       
  1574  * Sets the given acceptcaps function for the pad.  The acceptcaps function
       
  1575  * will be called to check if the pad can accept the given caps. Setting the
       
  1576  * acceptcaps function to NULL restores the default behaviour of allowing
       
  1577  * any caps that matches the caps from gst_pad_get_caps.
       
  1578  */
       
  1579 #ifdef __SYMBIAN32__
       
  1580 EXPORT_C
       
  1581 #endif
       
  1582 
       
  1583 void
       
  1584 gst_pad_set_acceptcaps_function (GstPad * pad,
       
  1585     GstPadAcceptCapsFunction acceptcaps)
       
  1586 {
       
  1587   g_return_if_fail (GST_IS_PAD (pad));
       
  1588 
       
  1589   GST_PAD_ACCEPTCAPSFUNC (pad) = acceptcaps;
       
  1590   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "acceptcapsfunc set to %s",
       
  1591       GST_DEBUG_FUNCPTR_NAME (acceptcaps));
       
  1592 }
       
  1593 
       
  1594 /**
       
  1595  * gst_pad_set_fixatecaps_function:
       
  1596  * @pad: a #GstPad.
       
  1597  * @fixatecaps: the #GstPadFixateCapsFunction to set.
       
  1598  *
       
  1599  * Sets the given fixatecaps function for the pad.  The fixatecaps function
       
  1600  * will be called whenever the default values for a GstCaps needs to be
       
  1601  * filled in.
       
  1602  */
       
  1603 #ifdef __SYMBIAN32__
       
  1604 EXPORT_C
       
  1605 #endif
       
  1606 
       
  1607 void
       
  1608 gst_pad_set_fixatecaps_function (GstPad * pad,
       
  1609     GstPadFixateCapsFunction fixatecaps)
       
  1610 {
       
  1611   g_return_if_fail (GST_IS_PAD (pad));
       
  1612 
       
  1613   GST_PAD_FIXATECAPSFUNC (pad) = fixatecaps;
       
  1614   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "fixatecapsfunc set to %s",
       
  1615       GST_DEBUG_FUNCPTR_NAME (fixatecaps));
       
  1616 }
       
  1617 
       
  1618 /**
       
  1619  * gst_pad_set_setcaps_function:
       
  1620  * @pad: a #GstPad.
       
  1621  * @setcaps: the #GstPadSetCapsFunction to set.
       
  1622  *
       
  1623  * Sets the given setcaps function for the pad.  The setcaps function
       
  1624  * will be called whenever a buffer with a new media type is pushed or
       
  1625  * pulled from the pad. The pad/element needs to update its internal
       
  1626  * structures to process the new media type. If this new type is not
       
  1627  * acceptable, the setcaps function should return FALSE.
       
  1628  */
       
  1629 #ifdef __SYMBIAN32__
       
  1630 EXPORT_C
       
  1631 #endif
       
  1632 
       
  1633 void
       
  1634 gst_pad_set_setcaps_function (GstPad * pad, GstPadSetCapsFunction setcaps)
       
  1635 {
       
  1636   g_return_if_fail (GST_IS_PAD (pad));
       
  1637 
       
  1638   GST_PAD_SETCAPSFUNC (pad) = setcaps;
       
  1639   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "setcapsfunc set to %s",
       
  1640       GST_DEBUG_FUNCPTR_NAME (setcaps));
       
  1641 }
       
  1642 
       
  1643 /**
       
  1644  * gst_pad_set_bufferalloc_function:
       
  1645  * @pad: a sink #GstPad.
       
  1646  * @bufalloc: the #GstPadBufferAllocFunction to set.
       
  1647  *
       
  1648  * Sets the given bufferalloc function for the pad. Note that the
       
  1649  * bufferalloc function can only be set on sinkpads.
       
  1650  */
       
  1651 #ifdef __SYMBIAN32__
       
  1652 EXPORT_C
       
  1653 #endif
       
  1654 
       
  1655 void
       
  1656 gst_pad_set_bufferalloc_function (GstPad * pad,
       
  1657     GstPadBufferAllocFunction bufalloc)
       
  1658 {
       
  1659   g_return_if_fail (GST_IS_PAD (pad));
       
  1660   g_return_if_fail (GST_PAD_IS_SINK (pad));
       
  1661 
       
  1662   GST_PAD_BUFFERALLOCFUNC (pad) = bufalloc;
       
  1663   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "bufferallocfunc set to %s",
       
  1664       GST_DEBUG_FUNCPTR_NAME (bufalloc));
       
  1665 }
       
  1666 
       
  1667 /**
       
  1668  * gst_pad_unlink:
       
  1669  * @srcpad: the source #GstPad to unlink.
       
  1670  * @sinkpad: the sink #GstPad to unlink.
       
  1671  *
       
  1672  * Unlinks the source pad from the sink pad. Will emit the #GstPad::unlinked
       
  1673  * signal on both pads.
       
  1674  *
       
  1675  * Returns: TRUE if the pads were unlinked. This function returns FALSE if
       
  1676  * the pads were not linked together.
       
  1677  *
       
  1678  * MT safe.
       
  1679  */
       
  1680 #ifdef __SYMBIAN32__
       
  1681 EXPORT_C
       
  1682 #endif
       
  1683 
       
  1684 gboolean
       
  1685 gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
       
  1686 {
       
  1687   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
       
  1688   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
       
  1689 
       
  1690   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinking %s:%s(%p) and %s:%s(%p)",
       
  1691       GST_DEBUG_PAD_NAME (srcpad), srcpad,
       
  1692       GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
       
  1693 
       
  1694   GST_OBJECT_LOCK (srcpad);
       
  1695 
       
  1696   if (G_UNLIKELY (GST_PAD_DIRECTION (srcpad) != GST_PAD_SRC))
       
  1697     goto not_srcpad;
       
  1698 
       
  1699   GST_OBJECT_LOCK (sinkpad);
       
  1700 
       
  1701   if (G_UNLIKELY (GST_PAD_DIRECTION (sinkpad) != GST_PAD_SINK))
       
  1702     goto not_sinkpad;
       
  1703 
       
  1704   if (G_UNLIKELY (GST_PAD_PEER (srcpad) != sinkpad))
       
  1705     goto not_linked_together;
       
  1706 
       
  1707   if (GST_PAD_UNLINKFUNC (srcpad)) {
       
  1708     GST_PAD_UNLINKFUNC (srcpad) (srcpad);
       
  1709   }
       
  1710   if (GST_PAD_UNLINKFUNC (sinkpad)) {
       
  1711     GST_PAD_UNLINKFUNC (sinkpad) (sinkpad);
       
  1712   }
       
  1713 
       
  1714   /* first clear peers */
       
  1715   GST_PAD_PEER (srcpad) = NULL;
       
  1716   GST_PAD_PEER (sinkpad) = NULL;
       
  1717 
       
  1718   GST_OBJECT_UNLOCK (sinkpad);
       
  1719   GST_OBJECT_UNLOCK (srcpad);
       
  1720 
       
  1721   /* fire off a signal to each of the pads telling them
       
  1722    * that they've been unlinked */
       
  1723   g_signal_emit (G_OBJECT (srcpad), gst_pad_signals[PAD_UNLINKED], 0, sinkpad);
       
  1724   g_signal_emit (G_OBJECT (sinkpad), gst_pad_signals[PAD_UNLINKED], 0, srcpad);
       
  1725 
       
  1726   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinked %s:%s and %s:%s",
       
  1727       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
       
  1728 
       
  1729   return TRUE;
       
  1730 
       
  1731 not_srcpad:
       
  1732   {
       
  1733     g_critical ("pad %s is not a source pad", GST_PAD_NAME (srcpad));
       
  1734     GST_OBJECT_UNLOCK (srcpad);
       
  1735     return FALSE;
       
  1736   }
       
  1737 not_sinkpad:
       
  1738   {
       
  1739     g_critical ("pad %s is not a sink pad", GST_PAD_NAME (sinkpad));
       
  1740     GST_OBJECT_UNLOCK (sinkpad);
       
  1741     GST_OBJECT_UNLOCK (srcpad);
       
  1742     return FALSE;
       
  1743   }
       
  1744 not_linked_together:
       
  1745   {
       
  1746     /* we do not emit a warning in this case because unlinking cannot
       
  1747      * be made MT safe.*/
       
  1748     GST_OBJECT_UNLOCK (sinkpad);
       
  1749     GST_OBJECT_UNLOCK (srcpad);
       
  1750     return FALSE;
       
  1751   }
       
  1752 }
       
  1753 
       
  1754 /**
       
  1755  * gst_pad_is_linked:
       
  1756  * @pad: pad to check
       
  1757  *
       
  1758  * Checks if a @pad is linked to another pad or not.
       
  1759  *
       
  1760  * Returns: TRUE if the pad is linked, FALSE otherwise.
       
  1761  *
       
  1762  * MT safe.
       
  1763  */
       
  1764 #ifdef __SYMBIAN32__
       
  1765 EXPORT_C
       
  1766 #endif
       
  1767 
       
  1768 gboolean
       
  1769 gst_pad_is_linked (GstPad * pad)
       
  1770 {
       
  1771   gboolean result;
       
  1772 
       
  1773   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  1774 
       
  1775   GST_OBJECT_LOCK (pad);
       
  1776   result = (GST_PAD_PEER (pad) != NULL);
       
  1777   GST_OBJECT_UNLOCK (pad);
       
  1778 
       
  1779   return result;
       
  1780 }
       
  1781 
       
  1782 /* get the caps from both pads and see if the intersection
       
  1783  * is not empty.
       
  1784  *
       
  1785  * This function should be called with the pad LOCK on both
       
  1786  * pads
       
  1787  */
       
  1788 static gboolean
       
  1789 gst_pad_link_check_compatible_unlocked (GstPad * src, GstPad * sink)
       
  1790 {
       
  1791   GstCaps *srccaps;
       
  1792   GstCaps *sinkcaps;
       
  1793   GstCaps *icaps;
       
  1794 
       
  1795   srccaps = gst_pad_get_caps_unlocked (src);
       
  1796   sinkcaps = gst_pad_get_caps_unlocked (sink);
       
  1797 
       
  1798   GST_CAT_DEBUG (GST_CAT_CAPS, "src caps %" GST_PTR_FORMAT, srccaps);
       
  1799   GST_CAT_DEBUG (GST_CAT_CAPS, "sink caps %" GST_PTR_FORMAT, sinkcaps);
       
  1800 
       
  1801   /* if we have caps on both pads we can check the intersection. If one
       
  1802    * of the caps is NULL, we return TRUE. */
       
  1803   if (srccaps == NULL || sinkcaps == NULL)
       
  1804     goto done;
       
  1805 
       
  1806   icaps = gst_caps_intersect (srccaps, sinkcaps);
       
  1807   gst_caps_unref (srccaps);
       
  1808   gst_caps_unref (sinkcaps);
       
  1809 
       
  1810   if (icaps == NULL)
       
  1811     goto was_null;
       
  1812 
       
  1813   GST_CAT_DEBUG (GST_CAT_CAPS,
       
  1814       "intersection caps %p %" GST_PTR_FORMAT, icaps, icaps);
       
  1815 
       
  1816   if (gst_caps_is_empty (icaps))
       
  1817     goto was_empty;
       
  1818 
       
  1819   gst_caps_unref (icaps);
       
  1820 
       
  1821 done:
       
  1822   return TRUE;
       
  1823 
       
  1824   /* incompatible cases */
       
  1825 was_null:
       
  1826   {
       
  1827     GST_CAT_DEBUG (GST_CAT_CAPS, "intersection gave NULL");
       
  1828     return FALSE;
       
  1829   }
       
  1830 was_empty:
       
  1831   {
       
  1832     GST_CAT_DEBUG (GST_CAT_CAPS, "intersection is EMPTY");
       
  1833     gst_caps_unref (icaps);
       
  1834     return FALSE;
       
  1835   }
       
  1836 }
       
  1837 
       
  1838 /* check if the grandparents of both pads are the same.
       
  1839  * This check is required so that we don't try to link
       
  1840  * pads from elements in different bins without ghostpads.
       
  1841  *
       
  1842  * The LOCK should be held on both pads
       
  1843  */
       
  1844 static gboolean
       
  1845 gst_pad_link_check_hierarchy (GstPad * src, GstPad * sink)
       
  1846 {
       
  1847   GstObject *psrc, *psink;
       
  1848 
       
  1849   psrc = GST_OBJECT_PARENT (src);
       
  1850   psink = GST_OBJECT_PARENT (sink);
       
  1851 
       
  1852   /* if one of the pads has no parent, we allow the link */
       
  1853   if (G_UNLIKELY (psrc == NULL || psink == NULL))
       
  1854     goto no_parent;
       
  1855 
       
  1856   /* only care about parents that are elements */
       
  1857   if (G_UNLIKELY (!GST_IS_ELEMENT (psrc) || !GST_IS_ELEMENT (psink)))
       
  1858     goto no_element_parent;
       
  1859 
       
  1860   /* if the parents are the same, we have a loop */
       
  1861   if (G_UNLIKELY (psrc == psink))
       
  1862     goto same_parents;
       
  1863 
       
  1864   /* if they both have a parent, we check the grandparents. We can not lock
       
  1865    * the parent because we hold on the child (pad) and the locking order is
       
  1866    * parent >> child. */
       
  1867   psrc = GST_OBJECT_PARENT (psrc);
       
  1868   psink = GST_OBJECT_PARENT (psink);
       
  1869 
       
  1870   /* if they have grandparents but they are not the same */
       
  1871   if (G_UNLIKELY (psrc != psink))
       
  1872     goto wrong_grandparents;
       
  1873 
       
  1874   return TRUE;
       
  1875 
       
  1876   /* ERRORS */
       
  1877 no_parent:
       
  1878   {
       
  1879     GST_CAT_DEBUG (GST_CAT_CAPS,
       
  1880         "one of the pads has no parent %" GST_PTR_FORMAT " and %"
       
  1881         GST_PTR_FORMAT, psrc, psink);
       
  1882     return TRUE;
       
  1883   }
       
  1884 no_element_parent:
       
  1885   {
       
  1886     GST_CAT_DEBUG (GST_CAT_CAPS,
       
  1887         "one of the pads has no element parent %" GST_PTR_FORMAT " and %"
       
  1888         GST_PTR_FORMAT, psrc, psink);
       
  1889     return TRUE;
       
  1890   }
       
  1891 same_parents:
       
  1892   {
       
  1893     GST_CAT_DEBUG (GST_CAT_CAPS, "pads have same parent %" GST_PTR_FORMAT,
       
  1894         psrc);
       
  1895     return FALSE;
       
  1896   }
       
  1897 wrong_grandparents:
       
  1898   {
       
  1899     GST_CAT_DEBUG (GST_CAT_CAPS,
       
  1900         "pads have different grandparents %" GST_PTR_FORMAT " and %"
       
  1901         GST_PTR_FORMAT, psrc, psink);
       
  1902     return FALSE;
       
  1903   }
       
  1904 }
       
  1905 
       
  1906 /* FIXME leftover from an attempt at refactoring... */
       
  1907 /* call with the two pads unlocked, when this function returns GST_PAD_LINK_OK,
       
  1908  * the two pads will be locked in the srcpad, sinkpad order. */
       
  1909 static GstPadLinkReturn
       
  1910 gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad)
       
  1911 {
       
  1912   /* generic checks */
       
  1913   g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED);
       
  1914   g_return_val_if_fail (GST_IS_PAD (sinkpad), GST_PAD_LINK_REFUSED);
       
  1915 
       
  1916   GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
       
  1917       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
       
  1918 
       
  1919   GST_OBJECT_LOCK (srcpad);
       
  1920 
       
  1921   if (G_UNLIKELY (GST_PAD_DIRECTION (srcpad) != GST_PAD_SRC))
       
  1922     goto not_srcpad;
       
  1923 
       
  1924   if (G_UNLIKELY (GST_PAD_PEER (srcpad) != NULL))
       
  1925     goto src_was_linked;
       
  1926 
       
  1927   GST_OBJECT_LOCK (sinkpad);
       
  1928 
       
  1929   if (G_UNLIKELY (GST_PAD_DIRECTION (sinkpad) != GST_PAD_SINK))
       
  1930     goto not_sinkpad;
       
  1931 
       
  1932   if (G_UNLIKELY (GST_PAD_PEER (sinkpad) != NULL))
       
  1933     goto sink_was_linked;
       
  1934 
       
  1935   /* check hierarchy, pads can only be linked if the grandparents
       
  1936    * are the same. */
       
  1937   if (!gst_pad_link_check_hierarchy (srcpad, sinkpad))
       
  1938     goto wrong_hierarchy;
       
  1939 
       
  1940   /* check pad caps for non-empty intersection */
       
  1941   if (!gst_pad_link_check_compatible_unlocked (srcpad, sinkpad))
       
  1942     goto no_format;
       
  1943 
       
  1944   /* FIXME check pad scheduling for non-empty intersection */
       
  1945 
       
  1946   return GST_PAD_LINK_OK;
       
  1947 
       
  1948 not_srcpad:
       
  1949   {
       
  1950     g_critical ("pad %s is not a source pad", GST_PAD_NAME (srcpad));
       
  1951     GST_OBJECT_UNLOCK (srcpad);
       
  1952     return GST_PAD_LINK_WRONG_DIRECTION;
       
  1953   }
       
  1954 src_was_linked:
       
  1955   {
       
  1956     GST_CAT_INFO (GST_CAT_PADS, "src %s:%s was already linked to %s:%s",
       
  1957         GST_DEBUG_PAD_NAME (srcpad),
       
  1958         GST_DEBUG_PAD_NAME (GST_PAD_PEER (srcpad)));
       
  1959     /* we do not emit a warning in this case because unlinking cannot
       
  1960      * be made MT safe.*/
       
  1961     GST_OBJECT_UNLOCK (srcpad);
       
  1962     return GST_PAD_LINK_WAS_LINKED;
       
  1963   }
       
  1964 not_sinkpad:
       
  1965   {
       
  1966     g_critical ("pad %s is not a sink pad", GST_PAD_NAME (sinkpad));
       
  1967     GST_OBJECT_UNLOCK (sinkpad);
       
  1968     GST_OBJECT_UNLOCK (srcpad);
       
  1969     return GST_PAD_LINK_WRONG_DIRECTION;
       
  1970   }
       
  1971 sink_was_linked:
       
  1972   {
       
  1973     GST_CAT_INFO (GST_CAT_PADS, "sink %s:%s was already linked to %s:%s",
       
  1974         GST_DEBUG_PAD_NAME (sinkpad),
       
  1975         GST_DEBUG_PAD_NAME (GST_PAD_PEER (sinkpad)));
       
  1976     /* we do not emit a warning in this case because unlinking cannot
       
  1977      * be made MT safe.*/
       
  1978     GST_OBJECT_UNLOCK (sinkpad);
       
  1979     GST_OBJECT_UNLOCK (srcpad);
       
  1980     return GST_PAD_LINK_WAS_LINKED;
       
  1981   }
       
  1982 wrong_hierarchy:
       
  1983   {
       
  1984     GST_CAT_INFO (GST_CAT_PADS, "pads have wrong hierarchy");
       
  1985     GST_OBJECT_UNLOCK (sinkpad);
       
  1986     GST_OBJECT_UNLOCK (srcpad);
       
  1987     return GST_PAD_LINK_WRONG_HIERARCHY;
       
  1988   }
       
  1989 no_format:
       
  1990   {
       
  1991     GST_CAT_INFO (GST_CAT_PADS, "caps are incompatible");
       
  1992     GST_OBJECT_UNLOCK (sinkpad);
       
  1993     GST_OBJECT_UNLOCK (srcpad);
       
  1994     return GST_PAD_LINK_NOFORMAT;
       
  1995   }
       
  1996 }
       
  1997 
       
  1998 /**
       
  1999  * gst_pad_link:
       
  2000  * @srcpad: the source #GstPad to link.
       
  2001  * @sinkpad: the sink #GstPad to link.
       
  2002  *
       
  2003  * Links the source pad and the sink pad.
       
  2004  *
       
  2005  * Returns: A result code indicating if the connection worked or
       
  2006  *          what went wrong.
       
  2007  *
       
  2008  * MT Safe.
       
  2009  */
       
  2010 #ifdef __SYMBIAN32__
       
  2011 EXPORT_C
       
  2012 #endif
       
  2013 
       
  2014 GstPadLinkReturn
       
  2015 gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
       
  2016 {
       
  2017   GstPadLinkReturn result;
       
  2018 
       
  2019   /* prepare will also lock the two pads */
       
  2020   result = gst_pad_link_prepare (srcpad, sinkpad);
       
  2021 
       
  2022   if (result != GST_PAD_LINK_OK)
       
  2023     goto prepare_failed;
       
  2024 
       
  2025   /* must set peers before calling the link function */
       
  2026   GST_PAD_PEER (srcpad) = sinkpad;
       
  2027   GST_PAD_PEER (sinkpad) = srcpad;
       
  2028 
       
  2029   GST_OBJECT_UNLOCK (sinkpad);
       
  2030   GST_OBJECT_UNLOCK (srcpad);
       
  2031 
       
  2032   /* FIXME released the locks here, concurrent thread might link
       
  2033    * something else. */
       
  2034   if (GST_PAD_LINKFUNC (srcpad)) {
       
  2035     /* this one will call the peer link function */
       
  2036     result = GST_PAD_LINKFUNC (srcpad) (srcpad, sinkpad);
       
  2037   } else if (GST_PAD_LINKFUNC (sinkpad)) {
       
  2038     /* if no source link function, we need to call the sink link
       
  2039      * function ourselves. */
       
  2040     result = GST_PAD_LINKFUNC (sinkpad) (sinkpad, srcpad);
       
  2041   } else {
       
  2042     result = GST_PAD_LINK_OK;
       
  2043   }
       
  2044 
       
  2045   GST_OBJECT_LOCK (srcpad);
       
  2046   GST_OBJECT_LOCK (sinkpad);
       
  2047 
       
  2048   if (result == GST_PAD_LINK_OK) {
       
  2049     GST_OBJECT_UNLOCK (sinkpad);
       
  2050     GST_OBJECT_UNLOCK (srcpad);
       
  2051 
       
  2052     /* fire off a signal to each of the pads telling them
       
  2053      * that they've been linked */
       
  2054     g_signal_emit (G_OBJECT (srcpad), gst_pad_signals[PAD_LINKED], 0, sinkpad);
       
  2055     g_signal_emit (G_OBJECT (sinkpad), gst_pad_signals[PAD_LINKED], 0, srcpad);
       
  2056 
       
  2057     GST_CAT_INFO (GST_CAT_PADS, "linked %s:%s and %s:%s, successful",
       
  2058         GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
       
  2059   } else {
       
  2060     GST_CAT_INFO (GST_CAT_PADS, "link between %s:%s and %s:%s failed",
       
  2061         GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
       
  2062 
       
  2063     GST_PAD_PEER (srcpad) = NULL;
       
  2064     GST_PAD_PEER (sinkpad) = NULL;
       
  2065 
       
  2066     GST_OBJECT_UNLOCK (sinkpad);
       
  2067     GST_OBJECT_UNLOCK (srcpad);
       
  2068   }
       
  2069   return result;
       
  2070 
       
  2071 prepare_failed:
       
  2072   {
       
  2073     return result;
       
  2074   }
       
  2075 }
       
  2076 
       
  2077 static void
       
  2078 gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ)
       
  2079 {
       
  2080   GstPadTemplate **template_p;
       
  2081 
       
  2082   /* this function would need checks if it weren't static */
       
  2083 
       
  2084   GST_OBJECT_LOCK (pad);
       
  2085   template_p = &pad->padtemplate;
       
  2086   gst_object_replace ((GstObject **) template_p, (GstObject *) templ);
       
  2087   GST_OBJECT_UNLOCK (pad);
       
  2088 
       
  2089   if (templ)
       
  2090     gst_pad_template_pad_created (templ, pad);
       
  2091 }
       
  2092 
       
  2093 /**
       
  2094  * gst_pad_get_pad_template:
       
  2095  * @pad: a #GstPad.
       
  2096  *
       
  2097  * Gets the template for @pad.
       
  2098  *
       
  2099  * Returns: the #GstPadTemplate from which this pad was instantiated, or %NULL
       
  2100  * if this pad has no template.
       
  2101  *
       
  2102  * FIXME: currently returns an unrefcounted padtemplate.
       
  2103  */
       
  2104 #ifdef __SYMBIAN32__
       
  2105 EXPORT_C
       
  2106 #endif
       
  2107 
       
  2108 GstPadTemplate *
       
  2109 gst_pad_get_pad_template (GstPad * pad)
       
  2110 {
       
  2111   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  2112 
       
  2113   return GST_PAD_PAD_TEMPLATE (pad);
       
  2114 }
       
  2115 
       
  2116 
       
  2117 /* should be called with the pad LOCK held */
       
  2118 /* refs the caps, so caller is responsible for getting it unreffed */
       
  2119 static GstCaps *
       
  2120 gst_pad_get_caps_unlocked (GstPad * pad)
       
  2121 {
       
  2122   GstCaps *result = NULL;
       
  2123   GstPadTemplate *templ;
       
  2124 
       
  2125   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps");
       
  2126 
       
  2127   if (GST_PAD_GETCAPSFUNC (pad)) {
       
  2128     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
       
  2129         "dispatching to pad getcaps function");
       
  2130 
       
  2131     GST_OBJECT_FLAG_SET (pad, GST_PAD_IN_GETCAPS);
       
  2132     GST_OBJECT_UNLOCK (pad);
       
  2133     result = GST_PAD_GETCAPSFUNC (pad) (pad);
       
  2134     GST_OBJECT_LOCK (pad);
       
  2135     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_IN_GETCAPS);
       
  2136 
       
  2137     if (result == NULL) {
       
  2138       g_critical ("pad %s:%s returned NULL caps from getcaps function",
       
  2139           GST_DEBUG_PAD_NAME (pad));
       
  2140     } else {
       
  2141       GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
       
  2142           "pad getcaps returned %" GST_PTR_FORMAT, result);
       
  2143 #ifndef G_DISABLE_ASSERT
       
  2144       /* check that the returned caps are a real subset of the template caps */
       
  2145       if (GST_PAD_PAD_TEMPLATE (pad)) {
       
  2146         const GstCaps *templ_caps =
       
  2147             GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
       
  2148         if (!gst_caps_is_subset (result, templ_caps)) {
       
  2149           GstCaps *temp;
       
  2150 
       
  2151           GST_CAT_ERROR_OBJECT (GST_CAT_CAPS, pad,
       
  2152               "pad returned caps %" GST_PTR_FORMAT
       
  2153               " which are not a real subset of its template caps %"
       
  2154               GST_PTR_FORMAT, result, templ_caps);
       
  2155           g_warning
       
  2156               ("pad %s:%s returned caps which are not a real "
       
  2157               "subset of its template caps", GST_DEBUG_PAD_NAME (pad));
       
  2158           temp = gst_caps_intersect (templ_caps, result);
       
  2159           gst_caps_unref (result);
       
  2160           result = temp;
       
  2161         }
       
  2162       }
       
  2163 #endif
       
  2164       goto done;
       
  2165     }
       
  2166   }
       
  2167   if ((templ = GST_PAD_PAD_TEMPLATE (pad))) {
       
  2168     result = GST_PAD_TEMPLATE_CAPS (templ);
       
  2169     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
       
  2170         "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
       
  2171         result);
       
  2172 
       
  2173     result = gst_caps_ref (result);
       
  2174     goto done;
       
  2175   }
       
  2176   if ((result = GST_PAD_CAPS (pad))) {
       
  2177     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
       
  2178         "using pad caps %p %" GST_PTR_FORMAT, result, result);
       
  2179 
       
  2180     result = gst_caps_ref (result);
       
  2181     goto done;
       
  2182   }
       
  2183 
       
  2184   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "pad has no caps");
       
  2185   result = gst_caps_new_empty ();
       
  2186 
       
  2187 done:
       
  2188   return result;
       
  2189 }
       
  2190 
       
  2191 /**
       
  2192  * gst_pad_get_caps:
       
  2193  * @pad: a  #GstPad to get the capabilities of.
       
  2194  *
       
  2195  * Gets the capabilities this pad can produce or consume.
       
  2196  * Note that this method doesn't necessarily return the caps set by
       
  2197  * gst_pad_set_caps() - use #GST_PAD_CAPS for that instead.
       
  2198  * gst_pad_get_caps returns all possible caps a pad can operate with, using
       
  2199  * the pad's get_caps function;
       
  2200  * this returns the pad template caps if not explicitly set.
       
  2201  *
       
  2202  * Returns: a newly allocated copy of the #GstCaps of this pad.
       
  2203  *
       
  2204  * MT safe.
       
  2205  */
       
  2206 #ifdef __SYMBIAN32__
       
  2207 EXPORT_C
       
  2208 #endif
       
  2209 
       
  2210 GstCaps *
       
  2211 gst_pad_get_caps (GstPad * pad)
       
  2212 {
       
  2213   GstCaps *result = NULL;
       
  2214 
       
  2215   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  2216 
       
  2217   GST_OBJECT_LOCK (pad);
       
  2218 
       
  2219   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps");
       
  2220 
       
  2221   result = gst_pad_get_caps_unlocked (pad);
       
  2222 
       
  2223   /* be sure that we have a copy */
       
  2224   if (result)
       
  2225     result = gst_caps_make_writable (result);
       
  2226 
       
  2227   GST_OBJECT_UNLOCK (pad);
       
  2228 
       
  2229   return result;
       
  2230 }
       
  2231 
       
  2232 /**
       
  2233  * gst_pad_peer_get_caps:
       
  2234  * @pad: a  #GstPad to get the peer capabilities of.
       
  2235  *
       
  2236  * Gets the capabilities of the peer connected to this pad.
       
  2237  *
       
  2238  * Returns: the #GstCaps of the peer pad. This function returns a new caps, so
       
  2239  * use gst_caps_unref to get rid of it. this function returns NULL if there is
       
  2240  * no peer pad.
       
  2241  */
       
  2242 #ifdef __SYMBIAN32__
       
  2243 EXPORT_C
       
  2244 #endif
       
  2245 
       
  2246 GstCaps *
       
  2247 gst_pad_peer_get_caps (GstPad * pad)
       
  2248 {
       
  2249   GstPad *peerpad;
       
  2250   GstCaps *result = NULL;
       
  2251 
       
  2252   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  2253 
       
  2254   GST_OBJECT_LOCK (pad);
       
  2255 
       
  2256   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get peer caps");
       
  2257 
       
  2258   peerpad = GST_PAD_PEER (pad);
       
  2259   if (G_UNLIKELY (peerpad == NULL))
       
  2260     goto no_peer;
       
  2261 
       
  2262   gst_object_ref (peerpad);
       
  2263   GST_OBJECT_UNLOCK (pad);
       
  2264 
       
  2265   result = gst_pad_get_caps (peerpad);
       
  2266 
       
  2267   gst_object_unref (peerpad);
       
  2268 
       
  2269   return result;
       
  2270 
       
  2271 no_peer:
       
  2272   {
       
  2273     GST_OBJECT_UNLOCK (pad);
       
  2274     return NULL;
       
  2275   }
       
  2276 }
       
  2277 
       
  2278 static gboolean
       
  2279 fixate_value (GValue * dest, const GValue * src)
       
  2280 {
       
  2281   if (G_VALUE_TYPE (src) == GST_TYPE_INT_RANGE) {
       
  2282     g_value_init (dest, G_TYPE_INT);
       
  2283     g_value_set_int (dest, gst_value_get_int_range_min (src));
       
  2284   } else if (G_VALUE_TYPE (src) == GST_TYPE_DOUBLE_RANGE) {
       
  2285     g_value_init (dest, G_TYPE_DOUBLE);
       
  2286     g_value_set_double (dest, gst_value_get_double_range_min (src));
       
  2287   } else if (G_VALUE_TYPE (src) == GST_TYPE_FRACTION_RANGE) {
       
  2288     gst_value_init_and_copy (dest, gst_value_get_fraction_range_min (src));
       
  2289   } else if (G_VALUE_TYPE (src) == GST_TYPE_LIST) {
       
  2290     GValue temp = { 0 };
       
  2291 
       
  2292     /* list could be empty */
       
  2293     if (gst_value_list_get_size (src) <= 0)
       
  2294       return FALSE;
       
  2295 
       
  2296     gst_value_init_and_copy (&temp, gst_value_list_get_value (src, 0));
       
  2297 
       
  2298     if (!fixate_value (dest, &temp))
       
  2299       gst_value_init_and_copy (dest, &temp);
       
  2300     g_value_unset (&temp);
       
  2301   } else if (G_VALUE_TYPE (src) == GST_TYPE_ARRAY) {
       
  2302     gboolean res = FALSE;
       
  2303     guint n;
       
  2304 
       
  2305     g_value_init (dest, GST_TYPE_ARRAY);
       
  2306     for (n = 0; n < gst_value_array_get_size (src); n++) {
       
  2307       GValue kid = { 0 };
       
  2308       const GValue *orig_kid = gst_value_array_get_value (src, n);
       
  2309 
       
  2310       if (!fixate_value (&kid, orig_kid))
       
  2311         gst_value_init_and_copy (&kid, orig_kid);
       
  2312       else
       
  2313         res = TRUE;
       
  2314       gst_value_array_append_value (dest, &kid);
       
  2315       g_value_unset (&kid);
       
  2316     }
       
  2317 
       
  2318     if (!res)
       
  2319       g_value_unset (dest);
       
  2320 
       
  2321     return res;
       
  2322   } else {
       
  2323     return FALSE;
       
  2324   }
       
  2325 
       
  2326   return TRUE;
       
  2327 }
       
  2328 
       
  2329 static gboolean
       
  2330 gst_pad_default_fixate (GQuark field_id, const GValue * value, gpointer data)
       
  2331 {
       
  2332   GstStructure *s = data;
       
  2333   GValue v = { 0 };
       
  2334 
       
  2335   if (fixate_value (&v, value)) {
       
  2336     gst_structure_id_set_value (s, field_id, &v);
       
  2337     g_value_unset (&v);
       
  2338   }
       
  2339 
       
  2340   return TRUE;
       
  2341 }
       
  2342 
       
  2343 /**
       
  2344  * gst_pad_fixate_caps:
       
  2345  * @pad: a  #GstPad to fixate
       
  2346  * @caps: the  #GstCaps to fixate
       
  2347  *
       
  2348  * Fixate a caps on the given pad. Modifies the caps in place, so you should
       
  2349  * make sure that the caps are actually writable (see gst_caps_make_writable()).
       
  2350  */
       
  2351 #ifdef __SYMBIAN32__
       
  2352 EXPORT_C
       
  2353 #endif
       
  2354 
       
  2355 void
       
  2356 gst_pad_fixate_caps (GstPad * pad, GstCaps * caps)
       
  2357 {
       
  2358   GstPadFixateCapsFunction fixatefunc;
       
  2359   guint n;
       
  2360 
       
  2361   g_return_if_fail (GST_IS_PAD (pad));
       
  2362   g_return_if_fail (caps != NULL);
       
  2363 
       
  2364   if (gst_caps_is_fixed (caps))
       
  2365     return;
       
  2366 
       
  2367   fixatefunc = GST_PAD_FIXATECAPSFUNC (pad);
       
  2368   if (fixatefunc) {
       
  2369     fixatefunc (pad, caps);
       
  2370   }
       
  2371 
       
  2372   /* default fixation */
       
  2373   for (n = 0; n < gst_caps_get_size (caps); n++) {
       
  2374     GstStructure *s = gst_caps_get_structure (caps, n);
       
  2375 
       
  2376     gst_structure_foreach (s, gst_pad_default_fixate, s);
       
  2377   }
       
  2378 }
       
  2379 
       
  2380 /* Default accept caps implementation just checks against
       
  2381  * against the allowed caps for the pad */
       
  2382 static gboolean
       
  2383 gst_pad_acceptcaps_default (GstPad * pad, GstCaps * caps)
       
  2384 {
       
  2385   /* get the caps and see if it intersects to something
       
  2386    * not empty */
       
  2387   GstCaps *intersect;
       
  2388   GstCaps *allowed;
       
  2389   gboolean result = FALSE;
       
  2390 
       
  2391   GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps);
       
  2392 
       
  2393   allowed = gst_pad_get_caps (pad);
       
  2394   if (!allowed)
       
  2395     goto nothing_allowed;
       
  2396 
       
  2397   GST_DEBUG_OBJECT (pad, "allowed caps %" GST_PTR_FORMAT, allowed);
       
  2398 
       
  2399   intersect = gst_caps_intersect (allowed, caps);
       
  2400 
       
  2401   GST_DEBUG_OBJECT (pad, "intersection %" GST_PTR_FORMAT, intersect);
       
  2402 
       
  2403   result = !gst_caps_is_empty (intersect);
       
  2404   if (!result)
       
  2405     GST_DEBUG_OBJECT (pad, "intersection gave empty caps");
       
  2406 
       
  2407   gst_caps_unref (allowed);
       
  2408   gst_caps_unref (intersect);
       
  2409 
       
  2410   return result;
       
  2411 
       
  2412   /* ERRORS */
       
  2413 nothing_allowed:
       
  2414   {
       
  2415     GST_DEBUG_OBJECT (pad, "no caps allowed on the pad");
       
  2416     return FALSE;
       
  2417   }
       
  2418 }
       
  2419 
       
  2420 /**
       
  2421  * gst_pad_accept_caps:
       
  2422  * @pad: a #GstPad to check
       
  2423  * @caps: a #GstCaps to check on the pad
       
  2424  *
       
  2425  * Check if the given pad accepts the caps.
       
  2426  *
       
  2427  * Returns: TRUE if the pad can accept the caps.
       
  2428  */
       
  2429 #ifdef __SYMBIAN32__
       
  2430 EXPORT_C
       
  2431 #endif
       
  2432 
       
  2433 gboolean
       
  2434 gst_pad_accept_caps (GstPad * pad, GstCaps * caps)
       
  2435 {
       
  2436   gboolean result;
       
  2437   GstPadAcceptCapsFunction acceptfunc;
       
  2438   GstCaps *existing = NULL;
       
  2439 
       
  2440   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  2441 
       
  2442   /* any pad can be unnegotiated */
       
  2443   if (caps == NULL)
       
  2444     return TRUE;
       
  2445 
       
  2446   /* lock for checking the existing caps */
       
  2447   GST_OBJECT_LOCK (pad);
       
  2448   acceptfunc = GST_PAD_ACCEPTCAPSFUNC (pad);
       
  2449   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "accept caps of %p", caps);
       
  2450   /* The current caps on a pad are trivially acceptable */
       
  2451   if (G_LIKELY ((existing = GST_PAD_CAPS (pad)))) {
       
  2452     if (caps == existing || gst_caps_is_equal (caps, existing))
       
  2453       goto is_same_caps;
       
  2454   }
       
  2455   GST_OBJECT_UNLOCK (pad);
       
  2456 
       
  2457   if (G_LIKELY (acceptfunc)) {
       
  2458     /* we can call the function */
       
  2459     result = acceptfunc (pad, caps);
       
  2460     GST_DEBUG_OBJECT (pad, "acceptfunc returned %d", result);
       
  2461   } else {
       
  2462     /* Only null if the element explicitly unset it */
       
  2463     result = gst_pad_acceptcaps_default (pad, caps);
       
  2464     GST_DEBUG_OBJECT (pad, "default acceptcaps returned %d", result);
       
  2465   }
       
  2466   return result;
       
  2467 
       
  2468 is_same_caps:
       
  2469   {
       
  2470     GST_DEBUG_OBJECT (pad, "pad had same caps");
       
  2471     GST_OBJECT_UNLOCK (pad);
       
  2472     return TRUE;
       
  2473   }
       
  2474 }
       
  2475 
       
  2476 /**
       
  2477  * gst_pad_peer_accept_caps:
       
  2478  * @pad: a  #GstPad to check the peer of
       
  2479  * @caps: a #GstCaps to check on the pad
       
  2480  *
       
  2481  * Check if the peer of @pad accepts @caps. If @pad has no peer, this function
       
  2482  * returns TRUE.
       
  2483  *
       
  2484  * Returns: TRUE if the peer of @pad can accept the caps or @pad has no peer.
       
  2485  */
       
  2486 #ifdef __SYMBIAN32__
       
  2487 EXPORT_C
       
  2488 #endif
       
  2489 
       
  2490 gboolean
       
  2491 gst_pad_peer_accept_caps (GstPad * pad, GstCaps * caps)
       
  2492 {
       
  2493   GstPad *peerpad;
       
  2494   gboolean result;
       
  2495 
       
  2496   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  2497 
       
  2498   GST_OBJECT_LOCK (pad);
       
  2499 
       
  2500   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "peer accept caps of (%p)", pad);
       
  2501 
       
  2502   peerpad = GST_PAD_PEER (pad);
       
  2503   if (G_UNLIKELY (peerpad == NULL))
       
  2504     goto no_peer;
       
  2505 
       
  2506   result = gst_pad_accept_caps (peerpad, caps);
       
  2507   GST_OBJECT_UNLOCK (pad);
       
  2508 
       
  2509   return result;
       
  2510 
       
  2511 no_peer:
       
  2512   {
       
  2513     GST_OBJECT_UNLOCK (pad);
       
  2514     return TRUE;
       
  2515   }
       
  2516 }
       
  2517 
       
  2518 /**
       
  2519  * gst_pad_set_caps:
       
  2520  * @pad: a  #GstPad to set the capabilities of.
       
  2521  * @caps: a #GstCaps to set.
       
  2522  *
       
  2523  * Sets the capabilities of this pad. The caps must be fixed. Any previous
       
  2524  * caps on the pad will be unreffed. This function refs the caps so you should
       
  2525  * unref if as soon as you don't need it anymore.
       
  2526  * It is possible to set NULL caps, which will make the pad unnegotiated
       
  2527  * again.
       
  2528  *
       
  2529  * Returns: TRUE if the caps could be set. FALSE if the caps were not fixed
       
  2530  * or bad parameters were provided to this function.
       
  2531  *
       
  2532  * MT safe.
       
  2533  */
       
  2534 #ifdef __SYMBIAN32__
       
  2535 EXPORT_C
       
  2536 #endif
       
  2537 
       
  2538 gboolean
       
  2539 gst_pad_set_caps (GstPad * pad, GstCaps * caps)
       
  2540 {
       
  2541   GstPadSetCapsFunction setcaps;
       
  2542   GstCaps *existing;
       
  2543 
       
  2544   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  2545   g_return_val_if_fail (caps == NULL || gst_caps_is_fixed (caps), FALSE);
       
  2546 
       
  2547   GST_OBJECT_LOCK (pad);
       
  2548   existing = GST_PAD_CAPS (pad);
       
  2549   if (existing == caps)
       
  2550     goto was_ok;
       
  2551 
       
  2552   if (gst_caps_is_equal (caps, existing))
       
  2553     goto setting_same_caps;
       
  2554 
       
  2555   setcaps = GST_PAD_SETCAPSFUNC (pad);
       
  2556 
       
  2557   /* call setcaps function to configure the pad only if the
       
  2558    * caps is not NULL */
       
  2559   if (setcaps != NULL && caps) {
       
  2560     if (!GST_PAD_IS_IN_SETCAPS (pad)) {
       
  2561       GST_OBJECT_FLAG_SET (pad, GST_PAD_IN_SETCAPS);
       
  2562       GST_OBJECT_UNLOCK (pad);
       
  2563       if (!setcaps (pad, caps))
       
  2564         goto could_not_set;
       
  2565       GST_OBJECT_LOCK (pad);
       
  2566       GST_OBJECT_FLAG_UNSET (pad, GST_PAD_IN_SETCAPS);
       
  2567     } else {
       
  2568       GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "pad was dispatching");
       
  2569     }
       
  2570   }
       
  2571 
       
  2572   gst_caps_replace (&GST_PAD_CAPS (pad), caps);
       
  2573   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "caps %" GST_PTR_FORMAT, caps);
       
  2574   GST_OBJECT_UNLOCK (pad);
       
  2575 
       
  2576   g_object_notify (G_OBJECT (pad), "caps");
       
  2577 
       
  2578   return TRUE;
       
  2579 
       
  2580 was_ok:
       
  2581   {
       
  2582     GST_OBJECT_UNLOCK (pad);
       
  2583     return TRUE;
       
  2584   }
       
  2585 setting_same_caps:
       
  2586   {
       
  2587     gst_caps_replace (&GST_PAD_CAPS (pad), caps);
       
  2588     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
       
  2589         "caps %" GST_PTR_FORMAT " same as existing, updating ptr only", caps);
       
  2590     GST_OBJECT_UNLOCK (pad);
       
  2591     return TRUE;
       
  2592   }
       
  2593 
       
  2594   /* ERRORS */
       
  2595 could_not_set:
       
  2596   {
       
  2597     GST_OBJECT_LOCK (pad);
       
  2598     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_IN_SETCAPS);
       
  2599     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
       
  2600         "caps %" GST_PTR_FORMAT " could not be set", caps);
       
  2601     GST_OBJECT_UNLOCK (pad);
       
  2602 
       
  2603     return FALSE;
       
  2604   }
       
  2605 }
       
  2606 
       
  2607 static gboolean
       
  2608 gst_pad_configure_sink (GstPad * pad, GstCaps * caps)
       
  2609 {
       
  2610   gboolean res;
       
  2611 
       
  2612   /* See if pad accepts the caps */
       
  2613   if (!gst_pad_accept_caps (pad, caps))
       
  2614     goto not_accepted;
       
  2615 
       
  2616   /* set caps on pad if call succeeds */
       
  2617   res = gst_pad_set_caps (pad, caps);
       
  2618   /* no need to unref the caps here, set_caps takes a ref and
       
  2619    * our ref goes away when we leave this function. */
       
  2620 
       
  2621   return res;
       
  2622 
       
  2623 not_accepted:
       
  2624   {
       
  2625     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
       
  2626         "caps %" GST_PTR_FORMAT " not accepted", caps);
       
  2627     return FALSE;
       
  2628   }
       
  2629 }
       
  2630 
       
  2631 /* returns TRUE if the src pad could be configured to accept the given caps */
       
  2632 static gboolean
       
  2633 gst_pad_configure_src (GstPad * pad, GstCaps * caps, gboolean dosetcaps)
       
  2634 {
       
  2635   gboolean res;
       
  2636 
       
  2637   /* See if pad accepts the caps */
       
  2638   if (!gst_pad_accept_caps (pad, caps))
       
  2639     goto not_accepted;
       
  2640 
       
  2641   if (dosetcaps)
       
  2642     res = gst_pad_set_caps (pad, caps);
       
  2643   else
       
  2644     res = TRUE;
       
  2645 
       
  2646   return res;
       
  2647 
       
  2648 not_accepted:
       
  2649   {
       
  2650     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
       
  2651         "caps %" GST_PTR_FORMAT " not accepted", caps);
       
  2652     return FALSE;
       
  2653   }
       
  2654 }
       
  2655 
       
  2656 /**
       
  2657  * gst_pad_get_pad_template_caps:
       
  2658  * @pad: a #GstPad to get the template capabilities from.
       
  2659  *
       
  2660  * Gets the capabilities for @pad's template.
       
  2661  *
       
  2662  * Returns: the #GstCaps of this pad template. If you intend to keep a
       
  2663  * reference on the caps, make a copy (see gst_caps_copy ()).
       
  2664  */
       
  2665 #ifdef __SYMBIAN32__
       
  2666 EXPORT_C
       
  2667 #endif
       
  2668 
       
  2669 const GstCaps *
       
  2670 gst_pad_get_pad_template_caps (GstPad * pad)
       
  2671 {
       
  2672   static GstStaticCaps anycaps = GST_STATIC_CAPS ("ANY");
       
  2673 
       
  2674   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  2675 
       
  2676   if (GST_PAD_PAD_TEMPLATE (pad))
       
  2677     return GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
       
  2678 
       
  2679   return gst_static_caps_get (&anycaps);
       
  2680 }
       
  2681 
       
  2682 /**
       
  2683  * gst_pad_get_peer:
       
  2684  * @pad: a #GstPad to get the peer of.
       
  2685  *
       
  2686  * Gets the peer of @pad. This function refs the peer pad so
       
  2687  * you need to unref it after use.
       
  2688  *
       
  2689  * Returns: the peer #GstPad. Unref after usage.
       
  2690  *
       
  2691  * MT safe.
       
  2692  */
       
  2693 #ifdef __SYMBIAN32__
       
  2694 EXPORT_C
       
  2695 #endif
       
  2696 
       
  2697 GstPad *
       
  2698 gst_pad_get_peer (GstPad * pad)
       
  2699 {
       
  2700   GstPad *result;
       
  2701 
       
  2702   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  2703 
       
  2704   GST_OBJECT_LOCK (pad);
       
  2705   result = GST_PAD_PEER (pad);
       
  2706   if (result)
       
  2707     gst_object_ref (result);
       
  2708   GST_OBJECT_UNLOCK (pad);
       
  2709 
       
  2710   return result;
       
  2711 }
       
  2712 
       
  2713 /**
       
  2714  * gst_pad_get_allowed_caps:
       
  2715  * @pad: a #GstPad.
       
  2716  *
       
  2717  * Gets the capabilities of the allowed media types that can flow through
       
  2718  * @pad and its peer.
       
  2719  *
       
  2720  * The allowed capabilities is calculated as the intersection of the results of
       
  2721  * calling gst_pad_get_caps() on @pad and its peer. The caller owns a reference
       
  2722  * on the resulting caps.
       
  2723  *
       
  2724  * Returns: the allowed #GstCaps of the pad link. Unref the caps when you no
       
  2725  * longer need it. This function returns NULL when @pad has no peer.
       
  2726  *
       
  2727  * MT safe.
       
  2728  */
       
  2729 #ifdef __SYMBIAN32__
       
  2730 EXPORT_C
       
  2731 #endif
       
  2732 
       
  2733 GstCaps *
       
  2734 gst_pad_get_allowed_caps (GstPad * pad)
       
  2735 {
       
  2736   GstCaps *mycaps;
       
  2737   GstCaps *caps;
       
  2738   GstCaps *peercaps;
       
  2739   GstPad *peer;
       
  2740 
       
  2741   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  2742 
       
  2743   GST_OBJECT_LOCK (pad);
       
  2744 
       
  2745   peer = GST_PAD_PEER (pad);
       
  2746   if (G_UNLIKELY (peer == NULL))
       
  2747     goto no_peer;
       
  2748 
       
  2749   GST_CAT_DEBUG_OBJECT (GST_CAT_PROPERTIES, pad, "getting allowed caps");
       
  2750 
       
  2751   gst_object_ref (peer);
       
  2752   GST_OBJECT_UNLOCK (pad);
       
  2753   mycaps = gst_pad_get_caps (pad);
       
  2754 
       
  2755   peercaps = gst_pad_get_caps (peer);
       
  2756   gst_object_unref (peer);
       
  2757 
       
  2758   caps = gst_caps_intersect (mycaps, peercaps);
       
  2759   gst_caps_unref (peercaps);
       
  2760   gst_caps_unref (mycaps);
       
  2761 
       
  2762   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "allowed caps %" GST_PTR_FORMAT,
       
  2763       caps);
       
  2764 
       
  2765   return caps;
       
  2766 
       
  2767 no_peer:
       
  2768   {
       
  2769     GST_CAT_DEBUG_OBJECT (GST_CAT_PROPERTIES, pad, "no peer");
       
  2770     GST_OBJECT_UNLOCK (pad);
       
  2771 
       
  2772     return NULL;
       
  2773   }
       
  2774 }
       
  2775 
       
  2776 /**
       
  2777  * gst_pad_get_negotiated_caps:
       
  2778  * @pad: a #GstPad.
       
  2779  *
       
  2780  * Gets the capabilities of the media type that currently flows through @pad
       
  2781  * and its peer.
       
  2782  *
       
  2783  * This function can be used on both src and sinkpads. Note that srcpads are
       
  2784  * always negotiated before sinkpads so it is possible that the negotiated caps
       
  2785  * on the srcpad do not match the negotiated caps of the peer.
       
  2786  *
       
  2787  * Returns: the negotiated #GstCaps of the pad link.  Unref the caps when
       
  2788  * you no longer need it. This function returns NULL when the @pad has no
       
  2789  * peer or is not negotiated yet.
       
  2790  *
       
  2791  * MT safe.
       
  2792  */
       
  2793 #ifdef __SYMBIAN32__
       
  2794 EXPORT_C
       
  2795 #endif
       
  2796 
       
  2797 GstCaps *
       
  2798 gst_pad_get_negotiated_caps (GstPad * pad)
       
  2799 {
       
  2800   GstCaps *caps;
       
  2801   GstPad *peer;
       
  2802 
       
  2803   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  2804 
       
  2805   GST_OBJECT_LOCK (pad);
       
  2806 
       
  2807   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
       
  2808     goto no_peer;
       
  2809 
       
  2810   GST_CAT_DEBUG_OBJECT (GST_CAT_PROPERTIES, pad, "getting negotiated caps");
       
  2811 
       
  2812   caps = GST_PAD_CAPS (pad);
       
  2813   if (caps)
       
  2814     gst_caps_ref (caps);
       
  2815   GST_OBJECT_UNLOCK (pad);
       
  2816 
       
  2817   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "negotiated caps %" GST_PTR_FORMAT,
       
  2818       caps);
       
  2819 
       
  2820   return caps;
       
  2821 
       
  2822 no_peer:
       
  2823   {
       
  2824     GST_CAT_DEBUG_OBJECT (GST_CAT_PROPERTIES, pad, "no peer");
       
  2825     GST_OBJECT_UNLOCK (pad);
       
  2826 
       
  2827     return NULL;
       
  2828   }
       
  2829 }
       
  2830 
       
  2831 /* calls the buffer_alloc function on the given pad */
       
  2832 static GstFlowReturn
       
  2833 gst_pad_buffer_alloc_unchecked (GstPad * pad, guint64 offset, gint size,
       
  2834     GstCaps * caps, GstBuffer ** buf)
       
  2835 {
       
  2836   GstFlowReturn ret;
       
  2837   GstPadBufferAllocFunction bufferallocfunc;
       
  2838 
       
  2839   GST_OBJECT_LOCK (pad);
       
  2840   /* when the pad is flushing we cannot give a buffer */
       
  2841   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
       
  2842     goto flushing;
       
  2843 
       
  2844   bufferallocfunc = pad->bufferallocfunc;
       
  2845 
       
  2846   if (offset == GST_BUFFER_OFFSET_NONE) {
       
  2847     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
       
  2848         "calling bufferallocfunc &%s (@%p) for size %d offset NONE",
       
  2849         GST_DEBUG_FUNCPTR_NAME (bufferallocfunc), bufferallocfunc, size);
       
  2850   } else {
       
  2851     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
       
  2852         "calling bufferallocfunc &%s (@%p) of for size %d offset %"
       
  2853         G_GUINT64_FORMAT, GST_DEBUG_FUNCPTR_NAME (bufferallocfunc),
       
  2854         bufferallocfunc, size, offset);
       
  2855   }
       
  2856   GST_OBJECT_UNLOCK (pad);
       
  2857 
       
  2858   /* G_LIKELY for now since most elements don't implement a buffer alloc
       
  2859    * function and there is no default alloc proxy function as this is usually
       
  2860    * not possible. */
       
  2861   if (G_LIKELY (bufferallocfunc == NULL))
       
  2862     goto fallback;
       
  2863 
       
  2864   ret = bufferallocfunc (pad, offset, size, caps, buf);
       
  2865   if (G_UNLIKELY (ret != GST_FLOW_OK))
       
  2866     goto error;
       
  2867   /* no error, but NULL buffer means fallback to the default */
       
  2868   if (G_UNLIKELY (*buf == NULL))
       
  2869     goto fallback;
       
  2870 
       
  2871   /* If the buffer alloc function didn't set up the caps like it should,
       
  2872    * do it for it */
       
  2873   if (G_UNLIKELY (caps && (GST_BUFFER_CAPS (*buf) == NULL))) {
       
  2874     GST_WARNING_OBJECT (pad,
       
  2875         "Buffer allocation function did not set caps. Setting");
       
  2876     gst_buffer_set_caps (*buf, caps);
       
  2877   }
       
  2878   return ret;
       
  2879 
       
  2880 flushing:
       
  2881   {
       
  2882     /* pad was flushing */
       
  2883     GST_OBJECT_UNLOCK (pad);
       
  2884     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "pad was flushing");
       
  2885     return GST_FLOW_WRONG_STATE;
       
  2886   }
       
  2887 error:
       
  2888   {
       
  2889     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
       
  2890         "alloc function returned error (%d) %s", ret, gst_flow_get_name (ret));
       
  2891     return ret;
       
  2892   }
       
  2893 fallback:
       
  2894   {
       
  2895     /* fallback case, allocate a buffer of our own, add pad caps. */
       
  2896     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "fallback buffer alloc");
       
  2897 
       
  2898     *buf = gst_buffer_new_and_alloc (size);
       
  2899     GST_BUFFER_OFFSET (*buf) = offset;
       
  2900     gst_buffer_set_caps (*buf, caps);
       
  2901 
       
  2902     return GST_FLOW_OK;
       
  2903   }
       
  2904 }
       
  2905 
       
  2906 static GstFlowReturn
       
  2907 gst_pad_alloc_buffer_full (GstPad * pad, guint64 offset, gint size,
       
  2908     GstCaps * caps, GstBuffer ** buf, gboolean setcaps)
       
  2909 {
       
  2910   GstPad *peer;
       
  2911   GstFlowReturn ret;
       
  2912   gboolean caps_changed;
       
  2913 
       
  2914   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
       
  2915   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
       
  2916   g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
       
  2917 
       
  2918   GST_DEBUG_OBJECT (pad, "offset %" G_GUINT64_FORMAT ", size %d", offset, size);
       
  2919 
       
  2920   GST_OBJECT_LOCK (pad);
       
  2921   while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
       
  2922     if ((ret = handle_pad_block (pad)) != GST_FLOW_OK)
       
  2923       goto flushed;
       
  2924 
       
  2925   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
       
  2926     goto no_peer;
       
  2927 
       
  2928   gst_object_ref (peer);
       
  2929   GST_OBJECT_UNLOCK (pad);
       
  2930 
       
  2931   ret = gst_pad_buffer_alloc_unchecked (peer, offset, size, caps, buf);
       
  2932   gst_object_unref (peer);
       
  2933 
       
  2934   if (G_UNLIKELY (ret != GST_FLOW_OK))
       
  2935     goto peer_error;
       
  2936 
       
  2937   /* FIXME, move capnego this into a base class? */
       
  2938   caps = GST_BUFFER_CAPS (*buf);
       
  2939 
       
  2940   /* Lock for checking caps, pretty pointless as the _pad_push() function might
       
  2941    * change it concurrently, one of the problems with automatic caps setting in
       
  2942    * pad_alloc_and_set_caps. Worst case, if does a check too much, but only
       
  2943    * when there is heavy renegotiation going on in both directions. */
       
  2944   GST_OBJECT_LOCK (pad);
       
  2945   caps_changed = caps && caps != GST_PAD_CAPS (pad);
       
  2946   GST_OBJECT_UNLOCK (pad);
       
  2947 
       
  2948   /* we got a new datatype on the pad, see if it can handle it */
       
  2949   if (G_UNLIKELY (caps_changed)) {
       
  2950     GST_DEBUG_OBJECT (pad,
       
  2951         "caps changed from %" GST_PTR_FORMAT " to %p %" GST_PTR_FORMAT,
       
  2952         GST_PAD_CAPS (pad), caps, caps);
       
  2953     if (G_UNLIKELY (!gst_pad_configure_src (pad, caps, setcaps)))
       
  2954       goto not_negotiated;
       
  2955   }
       
  2956   return ret;
       
  2957 
       
  2958 flushed:
       
  2959   {
       
  2960     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "pad block stopped by flush");
       
  2961     GST_OBJECT_UNLOCK (pad);
       
  2962     return ret;
       
  2963   }
       
  2964 no_peer:
       
  2965   {
       
  2966     /* pad has no peer */
       
  2967     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
       
  2968         "called bufferallocfunc but had no peer");
       
  2969     GST_OBJECT_UNLOCK (pad);
       
  2970     return GST_FLOW_NOT_LINKED;
       
  2971   }
       
  2972 peer_error:
       
  2973   {
       
  2974     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  2975         "alloc function returned error %s", gst_flow_get_name (ret));
       
  2976     return ret;
       
  2977   }
       
  2978 not_negotiated:
       
  2979   {
       
  2980     gst_buffer_unref (*buf);
       
  2981     *buf = NULL;
       
  2982     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  2983         "alloc function returned unacceptable buffer");
       
  2984     return GST_FLOW_NOT_NEGOTIATED;
       
  2985   }
       
  2986 }
       
  2987 
       
  2988 /**
       
  2989  * gst_pad_alloc_buffer:
       
  2990  * @pad: a source #GstPad
       
  2991  * @offset: the offset of the new buffer in the stream
       
  2992  * @size: the size of the new buffer
       
  2993  * @caps: the caps of the new buffer
       
  2994  * @buf: a newly allocated buffer
       
  2995  *
       
  2996  * Allocates a new, empty buffer optimized to push to pad @pad.  This
       
  2997  * function only works if @pad is a source pad and has a peer.
       
  2998  *
       
  2999  * A new, empty #GstBuffer will be put in the @buf argument.
       
  3000  * You need to check the caps of the buffer after performing this
       
  3001  * function and renegotiate to the format if needed.
       
  3002  *
       
  3003  * Returns: a result code indicating success of the operation. Any
       
  3004  * result code other than #GST_FLOW_OK is an error and @buf should
       
  3005  * not be used.
       
  3006  * An error can occur if the pad is not connected or when the downstream
       
  3007  * peer elements cannot provide an acceptable buffer.
       
  3008  *
       
  3009  * MT safe.
       
  3010  */
       
  3011 #ifdef __SYMBIAN32__
       
  3012 EXPORT_C
       
  3013 #endif
       
  3014 
       
  3015 GstFlowReturn
       
  3016 gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps,
       
  3017     GstBuffer ** buf)
       
  3018 {
       
  3019   return gst_pad_alloc_buffer_full (pad, offset, size, caps, buf, FALSE);
       
  3020 }
       
  3021 
       
  3022 /**
       
  3023  * gst_pad_alloc_buffer_and_set_caps:
       
  3024  * @pad: a source #GstPad
       
  3025  * @offset: the offset of the new buffer in the stream
       
  3026  * @size: the size of the new buffer
       
  3027  * @caps: the caps of the new buffer
       
  3028  * @buf: a newly allocated buffer
       
  3029  *
       
  3030  * In addition to the function gst_pad_alloc_buffer(), this function
       
  3031  * automatically calls gst_pad_set_caps() when the caps of the
       
  3032  * newly allocated buffer are different from the @pad caps.
       
  3033  *
       
  3034  * Returns: a result code indicating success of the operation. Any
       
  3035  * result code other than #GST_FLOW_OK is an error and @buf should
       
  3036  * not be used.
       
  3037  * An error can occur if the pad is not connected or when the downstream
       
  3038  * peer elements cannot provide an acceptable buffer.
       
  3039  *
       
  3040  * MT safe.
       
  3041  */
       
  3042 #ifdef __SYMBIAN32__
       
  3043 EXPORT_C
       
  3044 #endif
       
  3045 
       
  3046 GstFlowReturn
       
  3047 gst_pad_alloc_buffer_and_set_caps (GstPad * pad, guint64 offset, gint size,
       
  3048     GstCaps * caps, GstBuffer ** buf)
       
  3049 {
       
  3050   return gst_pad_alloc_buffer_full (pad, offset, size, caps, buf, TRUE);
       
  3051 }
       
  3052 
       
  3053 /**
       
  3054  * gst_pad_get_internal_links_default:
       
  3055  * @pad: the #GstPad to get the internal links of.
       
  3056  *
       
  3057  * Gets a list of pads to which the given pad is linked to
       
  3058  * inside of the parent element.
       
  3059  * This is the default handler, and thus returns a list of all of the
       
  3060  * pads inside the parent element with opposite direction.
       
  3061  * The caller must free this list after use.
       
  3062  *
       
  3063  * Returns: a newly allocated #GList of pads, or NULL if the pad has no parent.
       
  3064  *
       
  3065  * Not MT safe.
       
  3066  */
       
  3067 #ifdef __SYMBIAN32__
       
  3068 EXPORT_C
       
  3069 #endif
       
  3070 
       
  3071 GList *
       
  3072 gst_pad_get_internal_links_default (GstPad * pad)
       
  3073 {
       
  3074   GList *res = NULL;
       
  3075   GstElement *parent;
       
  3076   GList *parent_pads;
       
  3077   GstPadDirection direction;
       
  3078 
       
  3079   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  3080 
       
  3081   direction = pad->direction;
       
  3082 
       
  3083   parent = GST_PAD_PARENT (pad);
       
  3084   if (!parent)
       
  3085     goto no_parent;
       
  3086 
       
  3087   parent_pads = parent->pads;
       
  3088 
       
  3089   while (parent_pads) {
       
  3090     GstPad *parent_pad = GST_PAD_CAST (parent_pads->data);
       
  3091 
       
  3092     if (parent_pad->direction != direction) {
       
  3093       GST_DEBUG_OBJECT (pad, "adding pad %s:%s",
       
  3094           GST_DEBUG_PAD_NAME (parent_pad));
       
  3095       res = g_list_prepend (res, parent_pad);
       
  3096     }
       
  3097     parent_pads = g_list_next (parent_pads);
       
  3098   }
       
  3099   return res;
       
  3100 
       
  3101 no_parent:
       
  3102   {
       
  3103     GST_DEBUG_OBJECT (pad, "no parent");
       
  3104     return NULL;
       
  3105   }
       
  3106 }
       
  3107 
       
  3108 /**
       
  3109  * gst_pad_get_internal_links:
       
  3110  * @pad: the #GstPad to get the internal links of.
       
  3111  *
       
  3112  * Gets a list of pads to which the given pad is linked to
       
  3113  * inside of the parent element.
       
  3114  * The caller must free this list after use.
       
  3115  *
       
  3116  * Returns: a newly allocated #GList of pads.
       
  3117  *
       
  3118  * Not MT safe.
       
  3119  */
       
  3120 #ifdef __SYMBIAN32__
       
  3121 EXPORT_C
       
  3122 #endif
       
  3123 
       
  3124 GList *
       
  3125 gst_pad_get_internal_links (GstPad * pad)
       
  3126 {
       
  3127   GList *res = NULL;
       
  3128 
       
  3129   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  3130 
       
  3131   if (GST_PAD_INTLINKFUNC (pad))
       
  3132     res = GST_PAD_INTLINKFUNC (pad) (pad);
       
  3133 
       
  3134   return res;
       
  3135 }
       
  3136 
       
  3137 
       
  3138 static gboolean
       
  3139 gst_pad_event_default_dispatch (GstPad * pad, GstEvent * event)
       
  3140 {
       
  3141   GList *orig, *pads;
       
  3142   gboolean result;
       
  3143 
       
  3144   GST_INFO_OBJECT (pad, "Sending event %p (%s) to all internally linked pads",
       
  3145       event, GST_EVENT_TYPE_NAME (event));
       
  3146 
       
  3147   result = (GST_PAD_DIRECTION (pad) == GST_PAD_SINK);
       
  3148 
       
  3149   orig = pads = gst_pad_get_internal_links (pad);
       
  3150 
       
  3151   while (pads) {
       
  3152     GstPad *eventpad = GST_PAD_CAST (pads->data);
       
  3153 
       
  3154     pads = g_list_next (pads);
       
  3155 
       
  3156     if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
       
  3157       /* for each pad we send to, we should ref the event; it's up
       
  3158        * to downstream to unref again when handled. */
       
  3159       GST_LOG_OBJECT (pad, "Reffing and sending event %p (%s) to %s:%s",
       
  3160           event, GST_EVENT_TYPE_NAME (event), GST_DEBUG_PAD_NAME (eventpad));
       
  3161       gst_event_ref (event);
       
  3162       gst_pad_push_event (eventpad, event);
       
  3163     } else {
       
  3164       /* we only send the event on one pad, multi-sinkpad elements
       
  3165        * should implement a handler */
       
  3166       GST_LOG_OBJECT (pad, "sending event %p (%s) to one sink pad %s:%s",
       
  3167           event, GST_EVENT_TYPE_NAME (event), GST_DEBUG_PAD_NAME (eventpad));
       
  3168       result = gst_pad_push_event (eventpad, event);
       
  3169       goto done;
       
  3170     }
       
  3171   }
       
  3172   /* we handled the incoming event so we unref once */
       
  3173   GST_LOG_OBJECT (pad, "handled event %p, unreffing", event);
       
  3174   gst_event_unref (event);
       
  3175 
       
  3176 done:
       
  3177   g_list_free (orig);
       
  3178 
       
  3179   return result;
       
  3180 }
       
  3181 
       
  3182 /**
       
  3183  * gst_pad_event_default:
       
  3184  * @pad: a #GstPad to call the default event handler on.
       
  3185  * @event: the #GstEvent to handle.
       
  3186  *
       
  3187  * Invokes the default event handler for the given pad. End-of-stream and
       
  3188  * discontinuity events are handled specially, and then the event is sent to all
       
  3189  * pads internally linked to @pad. Note that if there are many possible sink
       
  3190  * pads that are internally linked to @pad, only one will be sent an event.
       
  3191  * Multi-sinkpad elements should implement custom event handlers.
       
  3192  *
       
  3193  * Returns: TRUE if the event was sent succesfully.
       
  3194  */
       
  3195 #ifdef __SYMBIAN32__
       
  3196 EXPORT_C
       
  3197 #endif
       
  3198 
       
  3199 gboolean
       
  3200 gst_pad_event_default (GstPad * pad, GstEvent * event)
       
  3201 {
       
  3202   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  3203   g_return_val_if_fail (event != NULL, FALSE);
       
  3204 
       
  3205   switch (GST_EVENT_TYPE (event)) {
       
  3206     case GST_EVENT_EOS:
       
  3207     {
       
  3208       GST_DEBUG_OBJECT (pad, "pausing task because of eos");
       
  3209       gst_pad_pause_task (pad);
       
  3210     }
       
  3211       /* fall thru */
       
  3212     default:
       
  3213       break;
       
  3214   }
       
  3215 
       
  3216   return gst_pad_event_default_dispatch (pad, event);
       
  3217 }
       
  3218 
       
  3219 /**
       
  3220  * gst_pad_dispatcher:
       
  3221  * @pad: a #GstPad to dispatch.
       
  3222  * @dispatch: the #GstDispatcherFunction to call.
       
  3223  * @data: gpointer user data passed to the dispatcher function.
       
  3224  *
       
  3225  * Invokes the given dispatcher function on each respective peer of
       
  3226  * all pads that are internally linked to the given pad.
       
  3227  * The GstPadDispatcherFunction should return TRUE when no further pads
       
  3228  * need to be processed.
       
  3229  *
       
  3230  * Returns: TRUE if one of the dispatcher functions returned TRUE.
       
  3231  */
       
  3232 #ifdef __SYMBIAN32__
       
  3233 EXPORT_C
       
  3234 #endif
       
  3235 
       
  3236 gboolean
       
  3237 gst_pad_dispatcher (GstPad * pad, GstPadDispatcherFunction dispatch,
       
  3238     gpointer data)
       
  3239 {
       
  3240   gboolean res = FALSE;
       
  3241   GList *int_pads, *orig;
       
  3242 
       
  3243   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  3244   g_return_val_if_fail (dispatch != NULL, FALSE);
       
  3245 
       
  3246   orig = int_pads = gst_pad_get_internal_links (pad);
       
  3247 
       
  3248   while (int_pads) {
       
  3249     GstPad *int_pad = GST_PAD_CAST (int_pads->data);
       
  3250     GstPad *int_peer = gst_pad_get_peer (int_pad);
       
  3251 
       
  3252     if (int_peer) {
       
  3253       GST_DEBUG_OBJECT (int_pad, "dispatching to peer %s:%s",
       
  3254           GST_DEBUG_PAD_NAME (int_peer));
       
  3255       res = dispatch (int_peer, data);
       
  3256       gst_object_unref (int_peer);
       
  3257       if (res)
       
  3258         break;
       
  3259     } else {
       
  3260       GST_DEBUG_OBJECT (int_pad, "no peer");
       
  3261     }
       
  3262     int_pads = g_list_next (int_pads);
       
  3263   }
       
  3264   g_list_free (orig);
       
  3265   GST_DEBUG_OBJECT (pad, "done, result %d", res);
       
  3266 
       
  3267   return res;
       
  3268 }
       
  3269 
       
  3270 /**
       
  3271  * gst_pad_query:
       
  3272  * @pad: a #GstPad to invoke the default query on.
       
  3273  * @query: the #GstQuery to perform.
       
  3274  *
       
  3275  * Dispatches a query to a pad. The query should have been allocated by the
       
  3276  * caller via one of the type-specific allocation functions in gstquery.h. The
       
  3277  * element is responsible for filling the query with an appropriate response,
       
  3278  * which should then be parsed with a type-specific query parsing function.
       
  3279  *
       
  3280  * Again, the caller is responsible for both the allocation and deallocation of
       
  3281  * the query structure.
       
  3282  *
       
  3283  * Returns: TRUE if the query could be performed.
       
  3284  */
       
  3285 #ifdef __SYMBIAN32__
       
  3286 EXPORT_C
       
  3287 #endif
       
  3288 
       
  3289 gboolean
       
  3290 gst_pad_query (GstPad * pad, GstQuery * query)
       
  3291 {
       
  3292   GstPadQueryFunction func;
       
  3293 
       
  3294   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  3295   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
       
  3296 
       
  3297   GST_DEBUG_OBJECT (pad, "sending query %p", query);
       
  3298 
       
  3299   if ((func = GST_PAD_QUERYFUNC (pad)) == NULL)
       
  3300     goto no_func;
       
  3301 
       
  3302   return func (pad, query);
       
  3303 
       
  3304 no_func:
       
  3305   {
       
  3306     GST_DEBUG_OBJECT (pad, "had no query function");
       
  3307     return FALSE;
       
  3308   }
       
  3309 }
       
  3310 
       
  3311 /**
       
  3312  * gst_pad_peer_query:
       
  3313  * @pad: a #GstPad to invoke the peer query on.
       
  3314  * @query: the #GstQuery to perform.
       
  3315  *
       
  3316  * Performs gst_pad_query() on the peer of @pad.
       
  3317  *
       
  3318  * The caller is responsible for both the allocation and deallocation of
       
  3319  * the query structure.
       
  3320  *
       
  3321  * Returns: TRUE if the query could be performed. This function returns %FALSE
       
  3322  * if @pad has no peer.
       
  3323  *
       
  3324  * Since: 0.10.15
       
  3325  */
       
  3326 #ifdef __SYMBIAN32__
       
  3327 EXPORT_C
       
  3328 #endif
       
  3329 
       
  3330 gboolean
       
  3331 gst_pad_peer_query (GstPad * pad, GstQuery * query)
       
  3332 {
       
  3333   GstPad *peerpad;
       
  3334   gboolean result;
       
  3335 
       
  3336   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  3337   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
       
  3338 
       
  3339   GST_OBJECT_LOCK (pad);
       
  3340 
       
  3341   GST_DEBUG_OBJECT (pad, "peer query");
       
  3342 
       
  3343   peerpad = GST_PAD_PEER (pad);
       
  3344   if (G_UNLIKELY (peerpad == NULL))
       
  3345     goto no_peer;
       
  3346 
       
  3347   gst_object_ref (peerpad);
       
  3348   GST_OBJECT_UNLOCK (pad);
       
  3349 
       
  3350   result = gst_pad_query (peerpad, query);
       
  3351 
       
  3352   gst_object_unref (peerpad);
       
  3353 
       
  3354   return result;
       
  3355 
       
  3356   /* ERRORS */
       
  3357 no_peer:
       
  3358   {
       
  3359     GST_WARNING_OBJECT (pad, "pad has no peer");
       
  3360     GST_OBJECT_UNLOCK (pad);
       
  3361     return FALSE;
       
  3362   }
       
  3363 }
       
  3364 
       
  3365 /**
       
  3366  * gst_pad_query_default:
       
  3367  * @pad: a #GstPad to call the default query handler on.
       
  3368  * @query: the #GstQuery to handle.
       
  3369  *
       
  3370  * Invokes the default query handler for the given pad.
       
  3371  * The query is sent to all pads internally linked to @pad. Note that
       
  3372  * if there are many possible sink pads that are internally linked to
       
  3373  * @pad, only one will be sent the query.
       
  3374  * Multi-sinkpad elements should implement custom query handlers.
       
  3375  *
       
  3376  * Returns: TRUE if the query was performed succesfully.
       
  3377  */
       
  3378 #ifdef __SYMBIAN32__
       
  3379 EXPORT_C
       
  3380 #endif
       
  3381 
       
  3382 gboolean
       
  3383 gst_pad_query_default (GstPad * pad, GstQuery * query)
       
  3384 {
       
  3385   switch (GST_QUERY_TYPE (query)) {
       
  3386     case GST_QUERY_POSITION:
       
  3387     case GST_QUERY_SEEKING:
       
  3388     case GST_QUERY_FORMATS:
       
  3389     case GST_QUERY_LATENCY:
       
  3390     case GST_QUERY_JITTER:
       
  3391     case GST_QUERY_RATE:
       
  3392     case GST_QUERY_CONVERT:
       
  3393     default:
       
  3394       return gst_pad_dispatcher
       
  3395           (pad, (GstPadDispatcherFunction) gst_pad_query, query);
       
  3396   }
       
  3397 }
       
  3398 
       
  3399 #ifndef GST_DISABLE_LOADSAVE
       
  3400 /* FIXME: why isn't this on a GstElement ? */
       
  3401 /**
       
  3402  * gst_pad_load_and_link:
       
  3403  * @self: an #xmlNodePtr to read the description from.
       
  3404  * @parent: the #GstObject element that owns the pad.
       
  3405  *
       
  3406  * Reads the pad definition from the XML node and links the given pad
       
  3407  * in the element to a pad of an element up in the hierarchy.
       
  3408  */
       
  3409 void
       
  3410 gst_pad_load_and_link (xmlNodePtr self, GstObject * parent)
       
  3411 {
       
  3412   xmlNodePtr field = self->xmlChildrenNode;
       
  3413   GstPad *pad = NULL, *targetpad;
       
  3414   gchar *peer = NULL;
       
  3415   gchar **split;
       
  3416   GstElement *target;
       
  3417   GstObject *grandparent;
       
  3418   gchar *name = NULL;
       
  3419 
       
  3420   while (field) {
       
  3421     if (!strcmp ((char *) field->name, "name")) {
       
  3422       name = (gchar *) xmlNodeGetContent (field);
       
  3423       pad = gst_element_get_pad (GST_ELEMENT (parent), name);
       
  3424       g_free (name);
       
  3425     } else if (!strcmp ((char *) field->name, "peer")) {
       
  3426       peer = (gchar *) xmlNodeGetContent (field);
       
  3427     }
       
  3428     field = field->next;
       
  3429   }
       
  3430   g_return_if_fail (pad != NULL);
       
  3431 
       
  3432   if (peer == NULL)
       
  3433     return;
       
  3434 
       
  3435   split = g_strsplit (peer, ".", 2);
       
  3436 
       
  3437   if (split[0] == NULL || split[1] == NULL) {
       
  3438     GST_CAT_DEBUG_OBJECT (GST_CAT_XML, pad,
       
  3439         "Could not parse peer '%s', leaving unlinked", peer);
       
  3440 
       
  3441     g_free (peer);
       
  3442     return;
       
  3443   }
       
  3444   g_free (peer);
       
  3445 
       
  3446   g_return_if_fail (split[0] != NULL);
       
  3447   g_return_if_fail (split[1] != NULL);
       
  3448 
       
  3449   grandparent = gst_object_get_parent (parent);
       
  3450 
       
  3451   if (grandparent && GST_IS_BIN (grandparent)) {
       
  3452     target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
       
  3453   } else
       
  3454     goto cleanup;
       
  3455 
       
  3456   if (target == NULL)
       
  3457     goto cleanup;
       
  3458 
       
  3459   targetpad = gst_element_get_pad (target, split[1]);
       
  3460 
       
  3461   if (targetpad == NULL)
       
  3462     goto cleanup;
       
  3463 
       
  3464   gst_pad_link (pad, targetpad);
       
  3465 
       
  3466 cleanup:
       
  3467   g_strfreev (split);
       
  3468 }
       
  3469 
       
  3470 /**
       
  3471  * gst_pad_save_thyself:
       
  3472  * @pad: a #GstPad to save.
       
  3473  * @parent: the parent #xmlNodePtr to save the description in.
       
  3474  *
       
  3475  * Saves the pad into an xml representation.
       
  3476  *
       
  3477  * Returns: the #xmlNodePtr representation of the pad.
       
  3478  */
       
  3479 static xmlNodePtr
       
  3480 gst_pad_save_thyself (GstObject * object, xmlNodePtr parent)
       
  3481 {
       
  3482   GstPad *pad;
       
  3483   GstPad *peer;
       
  3484 
       
  3485   g_return_val_if_fail (GST_IS_PAD (object), NULL);
       
  3486 
       
  3487   pad = GST_PAD (object);
       
  3488 
       
  3489   xmlNewChild (parent, NULL, (xmlChar *) "name",
       
  3490       (xmlChar *) GST_PAD_NAME (pad));
       
  3491 
       
  3492   if (GST_PAD_IS_SRC (pad)) {
       
  3493     xmlNewChild (parent, NULL, (xmlChar *) "direction", (xmlChar *) "source");
       
  3494   } else if (GST_PAD_IS_SINK (pad)) {
       
  3495     xmlNewChild (parent, NULL, (xmlChar *) "direction", (xmlChar *) "sink");
       
  3496   } else {
       
  3497     xmlNewChild (parent, NULL, (xmlChar *) "direction", (xmlChar *) "unknown");
       
  3498   }
       
  3499 
       
  3500   if (GST_PAD_PEER (pad) != NULL) {
       
  3501     gchar *content;
       
  3502 
       
  3503     peer = GST_PAD_PEER (pad);
       
  3504     /* first check to see if the peer's parent's parent is the same */
       
  3505     /* we just save it off */
       
  3506     content = g_strdup_printf ("%s.%s",
       
  3507         GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer));
       
  3508     xmlNewChild (parent, NULL, (xmlChar *) "peer", (xmlChar *) content);
       
  3509     g_free (content);
       
  3510   } else
       
  3511     xmlNewChild (parent, NULL, (xmlChar *) "peer", NULL);
       
  3512 
       
  3513   return parent;
       
  3514 }
       
  3515 
       
  3516 #if 0
       
  3517 /**
       
  3518  * gst_ghost_pad_save_thyself:
       
  3519  * @pad: a ghost #GstPad to save.
       
  3520  * @parent: the parent #xmlNodePtr to save the description in.
       
  3521  *
       
  3522  * Saves the ghost pad into an xml representation.
       
  3523  *
       
  3524  * Returns: the #xmlNodePtr representation of the pad.
       
  3525  */
       
  3526 xmlNodePtr
       
  3527 gst_ghost_pad_save_thyself (GstPad * pad, xmlNodePtr parent)
       
  3528 {
       
  3529   xmlNodePtr self;
       
  3530 
       
  3531   g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
       
  3532 
       
  3533   self = xmlNewChild (parent, NULL, (xmlChar *) "ghostpad", NULL);
       
  3534   xmlNewChild (self, NULL, (xmlChar *) "name", (xmlChar *) GST_PAD_NAME (pad));
       
  3535   xmlNewChild (self, NULL, (xmlChar *) "parent",
       
  3536       (xmlChar *) GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
       
  3537 
       
  3538   /* FIXME FIXME FIXME! */
       
  3539 
       
  3540   return self;
       
  3541 }
       
  3542 #endif /* 0 */
       
  3543 #endif /* GST_DISABLE_LOADSAVE */
       
  3544 
       
  3545 /*
       
  3546  * should be called with pad OBJECT_LOCK and STREAM_LOCK held.
       
  3547  * GST_PAD_IS_BLOCKED (pad) == TRUE when this function is
       
  3548  * called.
       
  3549  *
       
  3550  * This function performs the pad blocking when an event, buffer push
       
  3551  * or buffer_alloc is performed on a _SRC_ pad. It blocks the
       
  3552  * streaming thread after informing the pad has been blocked.
       
  3553  *
       
  3554  * An application can with this method wait and block any streaming
       
  3555  * thread and perform operations such as seeking or linking.
       
  3556  *
       
  3557  * Two methods are available for notifying the application of the
       
  3558  * block:
       
  3559  * - the callback method, which happens in the STREAMING thread with
       
  3560  *   the STREAM_LOCK held. With this method, the most useful way of
       
  3561  *   dealing with the callback is to post a message to the main thread
       
  3562  *   where the pad block can then be handled outside of the streaming
       
  3563  *   thread. With the last method one can perform all operations such
       
  3564  *   as doing a state change, linking, unblocking, seeking etc on the
       
  3565  *   pad.
       
  3566  * - the GCond signal method, which makes any thread unblock when
       
  3567  *   the pad block happens.
       
  3568  *
       
  3569  * During the actual blocking state, the GST_PAD_BLOCKING flag is set.
       
  3570  * The GST_PAD_BLOCKING flag is unset when the pad was unblocked.
       
  3571  *
       
  3572  * MT safe.
       
  3573  */
       
  3574 static GstFlowReturn
       
  3575 handle_pad_block (GstPad * pad)
       
  3576 {
       
  3577   GstPadBlockCallback callback;
       
  3578   gpointer user_data;
       
  3579   GstFlowReturn ret = GST_FLOW_OK;
       
  3580 
       
  3581   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "signal block taken");
       
  3582 
       
  3583   /* flushing, don't bother trying to block and return WRONG_STATE
       
  3584    * right away */
       
  3585   if (GST_PAD_IS_FLUSHING (pad))
       
  3586     goto flushingnonref;
       
  3587 
       
  3588   /* we grab an extra ref for the callbacks, this is probably not
       
  3589    * needed (callback code does not have a ref and cannot unref). I
       
  3590    * think this was done to make it possible to unref the element in
       
  3591    * the callback, which is in the end totally impossible as it
       
  3592    * requires grabbing the STREAM_LOCK and OBJECT_LOCK which are
       
  3593    * all taken when calling this function. */
       
  3594   gst_object_ref (pad);
       
  3595 
       
  3596   /* we either have a callback installed to notify the block or
       
  3597    * some other thread is doing a GCond wait. */
       
  3598   callback = pad->block_callback;
       
  3599   if (callback) {
       
  3600     /* there is a callback installed, call it. We release the
       
  3601      * lock so that the callback can do something usefull with the
       
  3602      * pad */
       
  3603     user_data = pad->block_data;
       
  3604     GST_OBJECT_UNLOCK (pad);
       
  3605     callback (pad, TRUE, user_data);
       
  3606     GST_OBJECT_LOCK (pad);
       
  3607 
       
  3608     /* we released the lock, recheck flushing */
       
  3609     if (GST_PAD_IS_FLUSHING (pad))
       
  3610       goto flushing;
       
  3611   } else {
       
  3612     /* no callback, signal the thread that is doing a GCond wait
       
  3613      * if any. */
       
  3614     GST_PAD_BLOCK_BROADCAST (pad);
       
  3615   }
       
  3616 
       
  3617   /* OBJECT_LOCK could have been released when we did the callback, which
       
  3618    * then could have made the pad unblock so we need to check the blocking
       
  3619    * condition again.   */
       
  3620   while (GST_PAD_IS_BLOCKED (pad)) {
       
  3621     /* now we block the streaming thread. It can be unlocked when we
       
  3622      * deactivate the pad (which will also set the FLUSHING flag) or
       
  3623      * when the pad is unblocked. A flushing event will also unblock
       
  3624      * the pad after setting the FLUSHING flag. */
       
  3625     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  3626         "Waiting to be unblocked or set flushing");
       
  3627     GST_OBJECT_FLAG_SET (pad, GST_PAD_BLOCKING);
       
  3628     GST_PAD_BLOCK_WAIT (pad);
       
  3629     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_BLOCKING);
       
  3630 
       
  3631     /* see if we got unblocked by a flush or not */
       
  3632     if (GST_PAD_IS_FLUSHING (pad))
       
  3633       goto flushing;
       
  3634   }
       
  3635 
       
  3636   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "got unblocked");
       
  3637 
       
  3638   /* when we get here, the pad is unblocked again and we perform
       
  3639    * the needed unblock code. */
       
  3640   callback = pad->block_callback;
       
  3641   if (callback) {
       
  3642     /* we need to call the callback */
       
  3643     user_data = pad->block_data;
       
  3644     GST_OBJECT_UNLOCK (pad);
       
  3645     callback (pad, FALSE, user_data);
       
  3646     GST_OBJECT_LOCK (pad);
       
  3647   } else {
       
  3648     /* we need to signal the thread waiting on the GCond */
       
  3649     GST_PAD_BLOCK_BROADCAST (pad);
       
  3650   }
       
  3651 
       
  3652   gst_object_unref (pad);
       
  3653 
       
  3654   return ret;
       
  3655 
       
  3656 flushingnonref:
       
  3657   {
       
  3658     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pad was flushing");
       
  3659     return GST_FLOW_WRONG_STATE;
       
  3660   }
       
  3661 flushing:
       
  3662   {
       
  3663     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pad became flushing");
       
  3664     gst_object_unref (pad);
       
  3665     return GST_FLOW_WRONG_STATE;
       
  3666   }
       
  3667 }
       
  3668 
       
  3669 /**********************************************************************
       
  3670  * Data passing functions
       
  3671  */
       
  3672 
       
  3673 static gboolean
       
  3674 gst_pad_emit_have_data_signal (GstPad * pad, GstMiniObject * obj)
       
  3675 {
       
  3676   GValue ret = { 0 };
       
  3677   GValue args[2] = { {0}, {0} };
       
  3678   gboolean res;
       
  3679   GQuark detail;
       
  3680 
       
  3681   /* init */
       
  3682   g_value_init (&ret, G_TYPE_BOOLEAN);
       
  3683   g_value_set_boolean (&ret, TRUE);
       
  3684   g_value_init (&args[0], GST_TYPE_PAD);
       
  3685   g_value_set_object (&args[0], pad);
       
  3686   g_value_init (&args[1], GST_TYPE_MINI_OBJECT);
       
  3687   gst_value_set_mini_object (&args[1], obj);
       
  3688 
       
  3689   if (GST_IS_EVENT (obj))
       
  3690     detail = event_quark;
       
  3691   else
       
  3692     detail = buffer_quark;
       
  3693 
       
  3694   /* actually emit */
       
  3695   g_signal_emitv (args, gst_pad_signals[PAD_HAVE_DATA], detail, &ret);
       
  3696   res = g_value_get_boolean (&ret);
       
  3697 
       
  3698   /* clean up */
       
  3699   g_value_unset (&ret);
       
  3700   g_value_unset (&args[0]);
       
  3701   g_value_unset (&args[1]);
       
  3702 
       
  3703   return res;
       
  3704 }
       
  3705 
       
  3706 /* this is the chain function that does not perform the additional argument
       
  3707  * checking for that little extra speed.
       
  3708  */
       
  3709 static inline GstFlowReturn
       
  3710 gst_pad_chain_unchecked (GstPad * pad, GstBuffer * buffer)
       
  3711 {
       
  3712   GstCaps *caps;
       
  3713   gboolean caps_changed;
       
  3714   GstPadChainFunction chainfunc;
       
  3715   GstFlowReturn ret;
       
  3716   gboolean emit_signal;
       
  3717 
       
  3718   GST_PAD_STREAM_LOCK (pad);
       
  3719 
       
  3720   GST_OBJECT_LOCK (pad);
       
  3721   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
       
  3722     goto flushing;
       
  3723 
       
  3724   caps = GST_BUFFER_CAPS (buffer);
       
  3725   caps_changed = caps && caps != GST_PAD_CAPS (pad);
       
  3726 
       
  3727   emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
       
  3728   GST_OBJECT_UNLOCK (pad);
       
  3729 
       
  3730   /* see if the signal should be emited, we emit before caps nego as
       
  3731    * we might drop the buffer and do capsnego for nothing. */
       
  3732   if (G_UNLIKELY (emit_signal)) {
       
  3733     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (buffer)))
       
  3734       goto dropping;
       
  3735   }
       
  3736 
       
  3737   /* we got a new datatype on the pad, see if it can handle it */
       
  3738   if (G_UNLIKELY (caps_changed)) {
       
  3739     GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
       
  3740     if (G_UNLIKELY (!gst_pad_configure_sink (pad, caps)))
       
  3741       goto not_negotiated;
       
  3742   }
       
  3743 
       
  3744   /* NOTE: we read the chainfunc unlocked.
       
  3745    * we cannot hold the lock for the pad so we might send
       
  3746    * the data to the wrong function. This is not really a
       
  3747    * problem since functions are assigned at creation time
       
  3748    * and don't change that often... */
       
  3749   if (G_UNLIKELY ((chainfunc = GST_PAD_CHAINFUNC (pad)) == NULL))
       
  3750     goto no_function;
       
  3751 
       
  3752   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  3753       "calling chainfunction &%s", GST_DEBUG_FUNCPTR_NAME (chainfunc));
       
  3754 
       
  3755   ret = chainfunc (pad, buffer);
       
  3756 
       
  3757   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  3758       "called chainfunction &%s, returned %s",
       
  3759       GST_DEBUG_FUNCPTR_NAME (chainfunc), gst_flow_get_name (ret));
       
  3760 
       
  3761   GST_PAD_STREAM_UNLOCK (pad);
       
  3762 
       
  3763   return ret;
       
  3764 
       
  3765   /* ERRORS */
       
  3766 flushing:
       
  3767   {
       
  3768     gst_buffer_unref (buffer);
       
  3769     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  3770         "pushing, but pad was flushing");
       
  3771     GST_OBJECT_UNLOCK (pad);
       
  3772     GST_PAD_STREAM_UNLOCK (pad);
       
  3773     return GST_FLOW_WRONG_STATE;
       
  3774   }
       
  3775 dropping:
       
  3776   {
       
  3777     gst_buffer_unref (buffer);
       
  3778     GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
       
  3779     GST_PAD_STREAM_UNLOCK (pad);
       
  3780     return GST_FLOW_OK;
       
  3781   }
       
  3782 not_negotiated:
       
  3783   {
       
  3784     gst_buffer_unref (buffer);
       
  3785     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  3786         "pushing buffer but pad did not accept");
       
  3787     GST_PAD_STREAM_UNLOCK (pad);
       
  3788     return GST_FLOW_NOT_NEGOTIATED;
       
  3789   }
       
  3790 no_function:
       
  3791   {
       
  3792     gst_buffer_unref (buffer);
       
  3793     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  3794         "pushing, but not chainhandler");
       
  3795     GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
       
  3796         ("push on pad %s:%s but it has no chainfunction",
       
  3797             GST_DEBUG_PAD_NAME (pad)));
       
  3798     GST_PAD_STREAM_UNLOCK (pad);
       
  3799     return GST_FLOW_NOT_SUPPORTED;
       
  3800   }
       
  3801 }
       
  3802 
       
  3803 /**
       
  3804  * gst_pad_chain:
       
  3805  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
       
  3806  * @buffer: the #GstBuffer to send, return GST_FLOW_ERROR if not.
       
  3807  *
       
  3808  * Chain a buffer to @pad.
       
  3809  *
       
  3810  * The function returns #GST_FLOW_WRONG_STATE if the pad was flushing.
       
  3811  *
       
  3812  * If the caps on @buffer are different from the current caps on @pad, this
       
  3813  * function will call any setcaps function (see gst_pad_set_setcaps_function())
       
  3814  * installed on @pad. If the new caps are not acceptable for @pad, this
       
  3815  * function returns #GST_FLOW_NOT_NEGOTIATED.
       
  3816  *
       
  3817  * The function proceeds calling the chain function installed on @pad (see
       
  3818  * gst_pad_set_chain_function()) and the return value of that function is
       
  3819  * returned to the caller. #GST_FLOW_NOT_SUPPORTED is returned if @pad has no
       
  3820  * chain function.
       
  3821  *
       
  3822  * In all cases, success or failure, the caller loses its reference to @buffer
       
  3823  * after calling this function.
       
  3824  *
       
  3825  * Returns: a #GstFlowReturn from the pad.
       
  3826  *
       
  3827  * MT safe.
       
  3828  */
       
  3829 #ifdef __SYMBIAN32__
       
  3830 EXPORT_C
       
  3831 #endif
       
  3832 
       
  3833 GstFlowReturn
       
  3834 gst_pad_chain (GstPad * pad, GstBuffer * buffer)
       
  3835 {
       
  3836   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
       
  3837   g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK,
       
  3838       GST_FLOW_ERROR);
       
  3839   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
       
  3840 
       
  3841   return gst_pad_chain_unchecked (pad, buffer);
       
  3842 }
       
  3843 
       
  3844 /**
       
  3845  * gst_pad_push:
       
  3846  * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not.
       
  3847  * @buffer: the #GstBuffer to push returns GST_FLOW_ERROR if not.
       
  3848  *
       
  3849  * Pushes a buffer to the peer of @pad.
       
  3850  *
       
  3851  * This function will call an installed pad block before triggering any
       
  3852  * installed pad probes.
       
  3853  *
       
  3854  * If the caps on @buffer are different from the currently configured caps on
       
  3855  * @pad, this function will call any installed setcaps function on @pad (see
       
  3856  * gst_pad_set_setcaps_function()). In case of failure to renegotiate the new
       
  3857  * format, this function returns #GST_FLOW_NOT_NEGOTIATED.
       
  3858  *
       
  3859  * The function proceeds calling gst_pad_chain() on the peer pad and returns
       
  3860  * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
       
  3861  * be returned.
       
  3862  *
       
  3863  * In all cases, success or failure, the caller loses its reference to @buffer
       
  3864  * after calling this function.
       
  3865  *
       
  3866  * Returns: a #GstFlowReturn from the peer pad.
       
  3867  *
       
  3868  * MT safe.
       
  3869  */
       
  3870 #ifdef __SYMBIAN32__
       
  3871 EXPORT_C
       
  3872 #endif
       
  3873 GstFlowReturn
       
  3874 gst_pad_push (GstPad * pad, GstBuffer * buffer)
       
  3875 {
       
  3876   GstPad *peer;
       
  3877   GstFlowReturn ret;
       
  3878 
       
  3879   GstCaps *caps;
       
  3880   gboolean caps_changed;
       
  3881 
       
  3882   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
       
  3883   g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC, GST_FLOW_ERROR);
       
  3884   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
       
  3885 
       
  3886   GST_OBJECT_LOCK (pad);
       
  3887 
       
  3888   /* FIXME: this check can go away; pad_set_blocked could be implemented with
       
  3889    * probes completely or probes with an extended pad block. */
       
  3890   while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
       
  3891     if ((ret = handle_pad_block (pad)) != GST_FLOW_OK)
       
  3892       goto flushed;
       
  3893 
       
  3894   /* we emit signals on the pad arg, the peer will have a chance to
       
  3895    * emit in the _chain() function */
       
  3896   if (G_UNLIKELY (GST_PAD_DO_BUFFER_SIGNALS (pad) > 0)) {
       
  3897     /* unlock before emitting */
       
  3898     GST_OBJECT_UNLOCK (pad);
       
  3899 
       
  3900     /* if the signal handler returned FALSE, it means we should just drop the
       
  3901      * buffer */
       
  3902     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (buffer)))
       
  3903       goto dropped;
       
  3904 
       
  3905     GST_OBJECT_LOCK (pad);
       
  3906   }
       
  3907 
       
  3908   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
       
  3909     goto not_linked;
       
  3910 
       
  3911   /* take ref to peer pad before releasing the lock */
       
  3912   gst_object_ref (peer);
       
  3913 
       
  3914   /* Before pushing the buffer to the peer pad, ensure that caps
       
  3915    * are set on this pad */
       
  3916   caps = GST_BUFFER_CAPS (buffer);
       
  3917   caps_changed = caps && caps != GST_PAD_CAPS (pad);
       
  3918 
       
  3919   GST_OBJECT_UNLOCK (pad);
       
  3920 
       
  3921   /* we got a new datatype from the pad, it had better handle it */
       
  3922   if (G_UNLIKELY (caps_changed)) {
       
  3923     GST_DEBUG_OBJECT (pad,
       
  3924         "caps changed from %" GST_PTR_FORMAT " to %p %" GST_PTR_FORMAT,
       
  3925         GST_PAD_CAPS (pad), caps, caps);
       
  3926     if (G_UNLIKELY (!gst_pad_configure_src (pad, caps, TRUE)))
       
  3927       goto not_negotiated;
       
  3928   }
       
  3929 
       
  3930   ret = gst_pad_chain_unchecked (peer, buffer);
       
  3931 
       
  3932   gst_object_unref (peer);
       
  3933 
       
  3934   return ret;
       
  3935 
       
  3936   /* ERROR recovery here */
       
  3937 flushed:
       
  3938   {
       
  3939     gst_buffer_unref (buffer);
       
  3940     GST_DEBUG_OBJECT (pad, "pad block stopped by flush");
       
  3941     GST_OBJECT_UNLOCK (pad);
       
  3942     return ret;
       
  3943   }
       
  3944 dropped:
       
  3945   {
       
  3946     gst_buffer_unref (buffer);
       
  3947     GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
       
  3948     return GST_FLOW_OK;
       
  3949   }
       
  3950 not_linked:
       
  3951   {
       
  3952     gst_buffer_unref (buffer);
       
  3953     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  3954         "pushing, but it was not linked");
       
  3955     GST_OBJECT_UNLOCK (pad);
       
  3956     return GST_FLOW_NOT_LINKED;
       
  3957   }
       
  3958 not_negotiated:
       
  3959   {
       
  3960     gst_buffer_unref (buffer);
       
  3961     gst_object_unref (peer);
       
  3962     GST_CAT_DEBUG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  3963         "element pushed buffer then refused to accept the caps");
       
  3964     return GST_FLOW_NOT_NEGOTIATED;
       
  3965   }
       
  3966 }
       
  3967 
       
  3968 /**
       
  3969  * gst_pad_check_pull_range:
       
  3970  * @pad: a sink #GstPad.
       
  3971  *
       
  3972  * Checks if a gst_pad_pull_range() can be performed on the peer
       
  3973  * source pad. This function is used by plugins that want to check
       
  3974  * if they can use random access on the peer source pad.
       
  3975  *
       
  3976  * The peer sourcepad can implement a custom #GstPadCheckGetRangeFunction
       
  3977  * if it needs to perform some logic to determine if pull_range is
       
  3978  * possible.
       
  3979  *
       
  3980  * Returns: a gboolean with the result.
       
  3981  *
       
  3982  * MT safe.
       
  3983  */
       
  3984 #ifdef __SYMBIAN32__
       
  3985 EXPORT_C
       
  3986 #endif
       
  3987 
       
  3988 gboolean
       
  3989 gst_pad_check_pull_range (GstPad * pad)
       
  3990 {
       
  3991   GstPad *peer;
       
  3992   gboolean ret;
       
  3993   GstPadCheckGetRangeFunction checkgetrangefunc;
       
  3994 
       
  3995   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  3996 
       
  3997   GST_OBJECT_LOCK (pad);
       
  3998   if (GST_PAD_DIRECTION (pad) != GST_PAD_SINK)
       
  3999     goto wrong_direction;
       
  4000 
       
  4001   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
       
  4002     goto not_connected;
       
  4003 
       
  4004   gst_object_ref (peer);
       
  4005   GST_OBJECT_UNLOCK (pad);
       
  4006 
       
  4007   /* see note in above function */
       
  4008   if (G_LIKELY ((checkgetrangefunc = peer->checkgetrangefunc) == NULL)) {
       
  4009     /* FIXME, kindoff ghetto */
       
  4010     ret = GST_PAD_GETRANGEFUNC (peer) != NULL;
       
  4011     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4012         "no checkgetrangefunc, assuming %d", ret);
       
  4013   } else {
       
  4014     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4015         "calling checkgetrangefunc %s of peer pad %s:%s",
       
  4016         GST_DEBUG_FUNCPTR_NAME (checkgetrangefunc), GST_DEBUG_PAD_NAME (peer));
       
  4017 
       
  4018     ret = checkgetrangefunc (peer);
       
  4019   }
       
  4020 
       
  4021   gst_object_unref (peer);
       
  4022 
       
  4023   return ret;
       
  4024 
       
  4025   /* ERROR recovery here */
       
  4026 wrong_direction:
       
  4027   {
       
  4028     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4029         "checking pull range, but pad must be a sinkpad");
       
  4030     GST_OBJECT_UNLOCK (pad);
       
  4031     return FALSE;
       
  4032   }
       
  4033 not_connected:
       
  4034   {
       
  4035     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4036         "checking pull range, but it was not linked");
       
  4037     GST_OBJECT_UNLOCK (pad);
       
  4038     return FALSE;
       
  4039   }
       
  4040 }
       
  4041 
       
  4042 /**
       
  4043  * gst_pad_get_range:
       
  4044  * @pad: a src #GstPad, returns #GST_FLOW_ERROR if not.
       
  4045  * @offset: The start offset of the buffer
       
  4046  * @size: The length of the buffer
       
  4047  * @buffer: a pointer to hold the #GstBuffer, returns #GST_FLOW_ERROR if %NULL.
       
  4048  *
       
  4049  * When @pad is flushing this function returns #GST_FLOW_WRONG_STATE
       
  4050  * immediatly.
       
  4051  *
       
  4052  * Calls the getrange function of @pad, see #GstPadGetRangeFunction for a
       
  4053  * description of a getrange function. If @pad has no getrange function
       
  4054  * installed (see gst_pad_set_getrange_function()) this function returns
       
  4055  * #GST_FLOW_NOT_SUPPORTED.
       
  4056  *
       
  4057  * @buffer's caps must either be unset or the same as what is already
       
  4058  * configured on @pad. Renegotiation within a running pull-mode pipeline is not
       
  4059  * supported.
       
  4060  *
       
  4061  * This is a lowlevel function. Usualy gst_pad_pull_range() is used.
       
  4062  *
       
  4063  * Returns: a #GstFlowReturn from the pad.
       
  4064  *
       
  4065  * MT safe.
       
  4066  */
       
  4067 #ifdef __SYMBIAN32__
       
  4068 EXPORT_C
       
  4069 #endif
       
  4070 
       
  4071 GstFlowReturn
       
  4072 gst_pad_get_range (GstPad * pad, guint64 offset, guint size,
       
  4073     GstBuffer ** buffer)
       
  4074 {
       
  4075   GstFlowReturn ret;
       
  4076   GstPadGetRangeFunction getrangefunc;
       
  4077   gboolean emit_signal;
       
  4078 
       
  4079   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
       
  4080   g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC, GST_FLOW_ERROR);
       
  4081   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
       
  4082 
       
  4083   GST_PAD_STREAM_LOCK (pad);
       
  4084 
       
  4085   GST_OBJECT_LOCK (pad);
       
  4086   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
       
  4087     goto flushing;
       
  4088 
       
  4089   emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
       
  4090   GST_OBJECT_UNLOCK (pad);
       
  4091 
       
  4092   if (G_UNLIKELY ((getrangefunc = GST_PAD_GETRANGEFUNC (pad)) == NULL))
       
  4093     goto no_function;
       
  4094 
       
  4095   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4096       "calling getrangefunc %s, offset %"
       
  4097       G_GUINT64_FORMAT ", size %u",
       
  4098       GST_DEBUG_FUNCPTR_NAME (getrangefunc), offset, size);
       
  4099 
       
  4100   ret = getrangefunc (pad, offset, size, buffer);
       
  4101 
       
  4102   /* can only fire the signal if we have a valid buffer */
       
  4103   if (G_UNLIKELY (emit_signal) && (ret == GST_FLOW_OK)) {
       
  4104     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (*buffer)))
       
  4105       goto dropping;
       
  4106   }
       
  4107 
       
  4108   GST_PAD_STREAM_UNLOCK (pad);
       
  4109 
       
  4110   if (G_LIKELY (ret == GST_FLOW_OK)) {
       
  4111     GstCaps *caps;
       
  4112     gboolean caps_changed;
       
  4113 
       
  4114     GST_OBJECT_LOCK (pad);
       
  4115     /* Before pushing the buffer to the peer pad, ensure that caps
       
  4116      * are set on this pad */
       
  4117     caps = GST_BUFFER_CAPS (*buffer);
       
  4118     caps_changed = caps && caps != GST_PAD_CAPS (pad);
       
  4119     GST_OBJECT_UNLOCK (pad);
       
  4120 
       
  4121     /* we got a new datatype from the pad not supported in a running pull-mode
       
  4122      * pipeline */
       
  4123     if (G_UNLIKELY (caps_changed))
       
  4124       goto not_negotiated;
       
  4125   }
       
  4126 
       
  4127   return ret;
       
  4128 
       
  4129   /* ERRORS */
       
  4130 flushing:
       
  4131   {
       
  4132     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4133         "pulling range, but pad was flushing");
       
  4134     GST_OBJECT_UNLOCK (pad);
       
  4135     GST_PAD_STREAM_UNLOCK (pad);
       
  4136     return GST_FLOW_WRONG_STATE;
       
  4137   }
       
  4138 no_function:
       
  4139   {
       
  4140     GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
       
  4141         ("pullrange on pad %s:%s but it has no getrangefunction",
       
  4142             GST_DEBUG_PAD_NAME (pad)));
       
  4143     GST_PAD_STREAM_UNLOCK (pad);
       
  4144     return GST_FLOW_NOT_SUPPORTED;
       
  4145   }
       
  4146 dropping:
       
  4147   {
       
  4148     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4149         "Dropping data after FALSE probe return");
       
  4150     GST_PAD_STREAM_UNLOCK (pad);
       
  4151     gst_buffer_unref (*buffer);
       
  4152     *buffer = NULL;
       
  4153     return GST_FLOW_UNEXPECTED;
       
  4154   }
       
  4155 not_negotiated:
       
  4156   {
       
  4157     /* ideally we want to use the commented-out code, but currently demuxers
       
  4158      * and typefind do not follow part-negotiation.txt. When switching into
       
  4159      * pull mode, typefind should probably return the found caps from
       
  4160      * getcaps(), and demuxers should do the setcaps(). */
       
  4161 
       
  4162 #if 0
       
  4163     gst_buffer_unref (*buffer);
       
  4164     *buffer = NULL;
       
  4165     GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4166         "getrange returned buffer of different caps");
       
  4167     return GST_FLOW_NOT_NEGOTIATED;
       
  4168 #endif
       
  4169     GST_CAT_DEBUG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4170         "getrange returned buffer of different caps");
       
  4171     return ret;
       
  4172   }
       
  4173 }
       
  4174 
       
  4175 
       
  4176 /**
       
  4177  * gst_pad_pull_range:
       
  4178  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
       
  4179  * @offset: The start offset of the buffer
       
  4180  * @size: The length of the buffer
       
  4181  * @buffer: a pointer to hold the #GstBuffer, returns GST_FLOW_ERROR if %NULL.
       
  4182  *
       
  4183  * Pulls a @buffer from the peer pad.
       
  4184  *
       
  4185  * This function will first trigger the pad block signal if it was
       
  4186  * installed.
       
  4187  *
       
  4188  * When @pad is not linked #GST_FLOW_NOT_LINKED is returned else this
       
  4189  * function returns the result of gst_pad_get_range() on the peer pad.
       
  4190  * See gst_pad_get_range() for a list of return values and for the
       
  4191  * semantics of the arguments of this function.
       
  4192  *
       
  4193  * @buffer's caps must either be unset or the same as what is already
       
  4194  * configured on @pad. Renegotiation within a running pull-mode pipeline is not
       
  4195  * supported.
       
  4196  *
       
  4197  * Returns: a #GstFlowReturn from the peer pad.
       
  4198  * When this function returns #GST_FLOW_OK, @buffer will contain a valid
       
  4199  * #GstBuffer that should be freed with gst_buffer_unref() after usage.
       
  4200  * @buffer may not be used or freed when any other return value than
       
  4201  * #GST_FLOW_OK is returned.
       
  4202  *
       
  4203  * MT safe.
       
  4204  */
       
  4205 #ifdef __SYMBIAN32__
       
  4206 EXPORT_C
       
  4207 #endif
       
  4208 
       
  4209 GstFlowReturn
       
  4210 gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
       
  4211     GstBuffer ** buffer)
       
  4212 {
       
  4213   GstPad *peer;
       
  4214   GstFlowReturn ret;
       
  4215   gboolean emit_signal;
       
  4216 
       
  4217   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
       
  4218   g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK,
       
  4219       GST_FLOW_ERROR);
       
  4220   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
       
  4221 
       
  4222   GST_OBJECT_LOCK (pad);
       
  4223 
       
  4224   while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
       
  4225     handle_pad_block (pad);
       
  4226 
       
  4227   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
       
  4228     goto not_connected;
       
  4229 
       
  4230   /* signal emision for the pad, peer has chance to emit when
       
  4231    * we call _get_range() */
       
  4232   emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
       
  4233 
       
  4234   gst_object_ref (peer);
       
  4235   GST_OBJECT_UNLOCK (pad);
       
  4236 
       
  4237   ret = gst_pad_get_range (peer, offset, size, buffer);
       
  4238 
       
  4239   gst_object_unref (peer);
       
  4240 
       
  4241   /* can only fire the signal if we have a valid buffer */
       
  4242   if (G_UNLIKELY (emit_signal) && (ret == GST_FLOW_OK)) {
       
  4243     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (*buffer)))
       
  4244       goto dropping;
       
  4245   }
       
  4246 
       
  4247   if (G_LIKELY (ret == GST_FLOW_OK)) {
       
  4248     GstCaps *caps;
       
  4249     gboolean caps_changed;
       
  4250 
       
  4251     GST_OBJECT_LOCK (pad);
       
  4252     /* Before pushing the buffer to the peer pad, ensure that caps
       
  4253      * are set on this pad */
       
  4254     caps = GST_BUFFER_CAPS (*buffer);
       
  4255     caps_changed = caps && caps != GST_PAD_CAPS (pad);
       
  4256     GST_OBJECT_UNLOCK (pad);
       
  4257 
       
  4258     /* we got a new datatype on the pad, see if it can handle it */
       
  4259     if (G_UNLIKELY (caps_changed))
       
  4260       goto not_negotiated;
       
  4261   }
       
  4262 
       
  4263   return ret;
       
  4264 
       
  4265   /* ERROR recovery here */
       
  4266 not_connected:
       
  4267   {
       
  4268     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4269         "pulling range, but it was not linked");
       
  4270     GST_OBJECT_UNLOCK (pad);
       
  4271     return GST_FLOW_NOT_LINKED;
       
  4272   }
       
  4273 dropping:
       
  4274   {
       
  4275     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4276         "Dropping data after FALSE probe return");
       
  4277     gst_buffer_unref (*buffer);
       
  4278     *buffer = NULL;
       
  4279     return GST_FLOW_UNEXPECTED;
       
  4280   }
       
  4281 not_negotiated:
       
  4282   {
       
  4283     /* ideally we want to use the commented-out code, but currently demuxers
       
  4284      * and typefind do not follow part-negotiation.txt. When switching into
       
  4285      * pull mode, typefind should probably return the found caps from
       
  4286      * getcaps(), and demuxers should do the setcaps(). */
       
  4287 
       
  4288 #if 0
       
  4289     gst_buffer_unref (*buffer);
       
  4290     *buffer = NULL;
       
  4291     GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4292         "pullrange returned buffer of different caps");
       
  4293     return GST_FLOW_NOT_NEGOTIATED;
       
  4294 #endif
       
  4295     GST_CAT_DEBUG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4296         "pullrange returned buffer of different caps");
       
  4297     return ret;
       
  4298   }
       
  4299 }
       
  4300 
       
  4301 /**
       
  4302  * gst_pad_push_event:
       
  4303  * @pad: a #GstPad to push the event to.
       
  4304  * @event: the #GstEvent to send to the pad.
       
  4305  *
       
  4306  * Sends the event to the peer of the given pad. This function is
       
  4307  * mainly used by elements to send events to their peer
       
  4308  * elements.
       
  4309  *
       
  4310  * This function takes owership of the provided event so you should
       
  4311  * gst_event_ref() it if you want to reuse the event after this call.
       
  4312  *
       
  4313  * Returns: TRUE if the event was handled.
       
  4314  *
       
  4315  * MT safe.
       
  4316  */
       
  4317 #ifdef __SYMBIAN32__
       
  4318 EXPORT_C
       
  4319 #endif
       
  4320 
       
  4321 gboolean
       
  4322 gst_pad_push_event (GstPad * pad, GstEvent * event)
       
  4323 {
       
  4324   GstPad *peerpad;
       
  4325   gboolean result;
       
  4326 
       
  4327   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  4328   g_return_val_if_fail (event != NULL, FALSE);
       
  4329   g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
       
  4330 
       
  4331   GST_LOG_OBJECT (pad, "event: %s", GST_EVENT_TYPE_NAME (event));
       
  4332 
       
  4333   GST_OBJECT_LOCK (pad);
       
  4334 
       
  4335   /* Two checks to be made:
       
  4336    * . (un)set the FLUSHING flag for flushing events,
       
  4337    * . handle pad blocking */
       
  4338   switch (GST_EVENT_TYPE (event)) {
       
  4339     case GST_EVENT_FLUSH_START:
       
  4340       GST_PAD_SET_FLUSHING (pad);
       
  4341 
       
  4342       if (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) {
       
  4343         /* flush start will have set the FLUSHING flag and will then
       
  4344          * unlock all threads doing a GCond wait on the blocking pad. This
       
  4345          * will typically unblock the STREAMING thread blocked on a pad. */
       
  4346         GST_LOG_OBJECT (pad, "Pad is blocked, not forwarding flush-start, "
       
  4347             "doing block signal.");
       
  4348         GST_PAD_BLOCK_BROADCAST (pad);
       
  4349         goto flushed;
       
  4350       }
       
  4351       break;
       
  4352     case GST_EVENT_FLUSH_STOP:
       
  4353       GST_PAD_UNSET_FLUSHING (pad);
       
  4354 
       
  4355       /* if we are blocked, flush away the FLUSH_STOP event */
       
  4356       if (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) {
       
  4357         GST_LOG_OBJECT (pad, "Pad is blocked, not forwarding flush-stop");
       
  4358         goto flushed;
       
  4359       }
       
  4360       break;
       
  4361     default:
       
  4362       while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) {
       
  4363         /* block the event as long as the pad is blocked */
       
  4364         if (handle_pad_block (pad) != GST_FLOW_OK)
       
  4365           goto flushed;
       
  4366       }
       
  4367       break;
       
  4368   }
       
  4369 
       
  4370   if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
       
  4371     GST_OBJECT_UNLOCK (pad);
       
  4372 
       
  4373     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (event)))
       
  4374       goto dropping;
       
  4375 
       
  4376     GST_OBJECT_LOCK (pad);
       
  4377   }
       
  4378   peerpad = GST_PAD_PEER (pad);
       
  4379   if (peerpad == NULL)
       
  4380     goto not_linked;
       
  4381 
       
  4382   GST_LOG_OBJECT (pad, "sending event %s to peerpad %" GST_PTR_FORMAT,
       
  4383       GST_EVENT_TYPE_NAME (event), peerpad);
       
  4384   gst_object_ref (peerpad);
       
  4385   GST_OBJECT_UNLOCK (pad);
       
  4386 
       
  4387   result = gst_pad_send_event (peerpad, event);
       
  4388 
       
  4389   /* Note: we gave away ownership of the event at this point */
       
  4390   GST_LOG_OBJECT (pad, "sent event to peerpad %" GST_PTR_FORMAT ", result %d",
       
  4391       peerpad, result);
       
  4392   gst_object_unref (peerpad);
       
  4393 
       
  4394   return result;
       
  4395 
       
  4396   /* ERROR handling */
       
  4397 dropping:
       
  4398   {
       
  4399     GST_DEBUG_OBJECT (pad, "Dropping event after FALSE probe return");
       
  4400     gst_event_unref (event);
       
  4401     return FALSE;
       
  4402   }
       
  4403 not_linked:
       
  4404   {
       
  4405     GST_DEBUG_OBJECT (pad, "Dropping event because pad is not linked");
       
  4406     gst_event_unref (event);
       
  4407     GST_OBJECT_UNLOCK (pad);
       
  4408     return FALSE;
       
  4409   }
       
  4410 flushed:
       
  4411   {
       
  4412     GST_DEBUG_OBJECT (pad,
       
  4413         "Not forwarding event since we're flushing and blocking");
       
  4414     gst_event_unref (event);
       
  4415     GST_OBJECT_UNLOCK (pad);
       
  4416     return TRUE;
       
  4417   }
       
  4418 }
       
  4419 
       
  4420 /**
       
  4421  * gst_pad_send_event:
       
  4422  * @pad: a #GstPad to send the event to.
       
  4423  * @event: the #GstEvent to send to the pad.
       
  4424  *
       
  4425  * Sends the event to the pad. This function can be used
       
  4426  * by applications to send events in the pipeline.
       
  4427  *
       
  4428  * If @pad is a source pad, @event should be an upstream event. If @pad is a
       
  4429  * sink pad, @event should be a downstream event. For example, you would not
       
  4430  * send a #GST_EVENT_EOS on a src pad; EOS events only propagate downstream.
       
  4431  * Furthermore, some downstream events have to be serialized with data flow,
       
  4432  * like EOS, while some can travel out-of-band, like #GST_EVENT_FLUSH_START. If
       
  4433  * the event needs to be serialized with data flow, this function will take the
       
  4434  * pad's stream lock while calling its event function.
       
  4435  *
       
  4436  * To find out whether an event type is upstream, downstream, or downstream and
       
  4437  * serialized, see #GstEventTypeFlags, gst_event_type_get_flags(),
       
  4438  * #GST_EVENT_IS_UPSTREAM, #GST_EVENT_IS_DOWNSTREAM, and
       
  4439  * #GST_EVENT_IS_SERIALIZED. Note that in practice that an application or
       
  4440  * plugin doesn't need to bother itself with this information; the core handles
       
  4441  * all necessary locks and checks.
       
  4442  *
       
  4443  * This function takes owership of the provided event so you should
       
  4444  * gst_event_ref() it if you want to reuse the event after this call.
       
  4445  *
       
  4446  * Returns: TRUE if the event was handled.
       
  4447  */
       
  4448 #ifdef __SYMBIAN32__
       
  4449 EXPORT_C
       
  4450 #endif
       
  4451 
       
  4452 gboolean
       
  4453 gst_pad_send_event (GstPad * pad, GstEvent * event)
       
  4454 {
       
  4455   gboolean result = FALSE;
       
  4456   GstPadEventFunction eventfunc;
       
  4457   gboolean serialized, need_unlock = FALSE;
       
  4458 
       
  4459   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  4460   g_return_val_if_fail (event != NULL, FALSE);
       
  4461 
       
  4462   GST_OBJECT_LOCK (pad);
       
  4463   if (GST_PAD_IS_SINK (pad)) {
       
  4464     if (G_UNLIKELY (!GST_EVENT_IS_DOWNSTREAM (event)))
       
  4465       goto wrong_direction;
       
  4466     serialized = GST_EVENT_IS_SERIALIZED (event);
       
  4467   } else if (GST_PAD_IS_SRC (pad)) {
       
  4468     if (G_UNLIKELY (!GST_EVENT_IS_UPSTREAM (event)))
       
  4469       goto wrong_direction;
       
  4470     /* events on srcpad never are serialized */
       
  4471     serialized = FALSE;
       
  4472   } else
       
  4473     goto unknown_direction;
       
  4474 
       
  4475   if (G_UNLIKELY (GST_EVENT_SRC (event) == NULL)) {
       
  4476     GST_LOG_OBJECT (pad, "event had no source, setting pad as event source");
       
  4477     GST_EVENT_SRC (event) = gst_object_ref (pad);
       
  4478   }
       
  4479 
       
  4480   /* pad signals */
       
  4481   if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
       
  4482     GST_OBJECT_UNLOCK (pad);
       
  4483 
       
  4484     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (event)))
       
  4485       goto dropping;
       
  4486 
       
  4487     GST_OBJECT_LOCK (pad);
       
  4488   }
       
  4489 
       
  4490   switch (GST_EVENT_TYPE (event)) {
       
  4491     case GST_EVENT_FLUSH_START:
       
  4492       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad,
       
  4493           "have event type %d (FLUSH_START)", GST_EVENT_TYPE (event));
       
  4494 
       
  4495       /* can't even accept a flush begin event when flushing */
       
  4496       if (GST_PAD_IS_FLUSHING (pad))
       
  4497         goto flushing;
       
  4498       GST_PAD_SET_FLUSHING (pad);
       
  4499       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "set flush flag");
       
  4500       break;
       
  4501     case GST_EVENT_FLUSH_STOP:
       
  4502       GST_PAD_UNSET_FLUSHING (pad);
       
  4503       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "cleared flush flag");
       
  4504       GST_OBJECT_UNLOCK (pad);
       
  4505       /* grab stream lock */
       
  4506       GST_PAD_STREAM_LOCK (pad);
       
  4507       need_unlock = TRUE;
       
  4508       GST_OBJECT_LOCK (pad);
       
  4509       break;
       
  4510     default:
       
  4511       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "have event type %s",
       
  4512           GST_EVENT_TYPE_NAME (event));
       
  4513 
       
  4514       /* make this a little faster, no point in grabbing the lock
       
  4515        * if the pad is allready flushing. */
       
  4516       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
       
  4517         goto flushing;
       
  4518 
       
  4519       if (serialized) {
       
  4520         /* lock order: STREAM_LOCK, LOCK, recheck flushing. */
       
  4521         GST_OBJECT_UNLOCK (pad);
       
  4522         GST_PAD_STREAM_LOCK (pad);
       
  4523         need_unlock = TRUE;
       
  4524         GST_OBJECT_LOCK (pad);
       
  4525         if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
       
  4526           goto flushing;
       
  4527       }
       
  4528       break;
       
  4529   }
       
  4530   if (G_UNLIKELY ((eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL))
       
  4531     goto no_function;
       
  4532 
       
  4533   GST_OBJECT_UNLOCK (pad);
       
  4534 
       
  4535   result = eventfunc (pad, event);
       
  4536 
       
  4537   if (need_unlock)
       
  4538     GST_PAD_STREAM_UNLOCK (pad);
       
  4539 
       
  4540   GST_DEBUG_OBJECT (pad, "sent event, result %d", result);
       
  4541 
       
  4542   return result;
       
  4543 
       
  4544   /* ERROR handling */
       
  4545 wrong_direction:
       
  4546   {
       
  4547     g_warning ("pad %s:%s sending %s event in wrong direction",
       
  4548         GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event));
       
  4549     GST_OBJECT_UNLOCK (pad);
       
  4550     gst_event_unref (event);
       
  4551     return FALSE;
       
  4552   }
       
  4553 unknown_direction:
       
  4554   {
       
  4555     g_warning ("pad %s:%s has invalid direction", GST_DEBUG_PAD_NAME (pad));
       
  4556     GST_OBJECT_UNLOCK (pad);
       
  4557     gst_event_unref (event);
       
  4558     return FALSE;
       
  4559   }
       
  4560 no_function:
       
  4561   {
       
  4562     g_warning ("pad %s:%s has no event handler, file a bug.",
       
  4563         GST_DEBUG_PAD_NAME (pad));
       
  4564     GST_OBJECT_UNLOCK (pad);
       
  4565     if (need_unlock)
       
  4566       GST_PAD_STREAM_UNLOCK (pad);
       
  4567     gst_event_unref (event);
       
  4568     return FALSE;
       
  4569   }
       
  4570 flushing:
       
  4571   {
       
  4572     GST_OBJECT_UNLOCK (pad);
       
  4573     if (need_unlock)
       
  4574       GST_PAD_STREAM_UNLOCK (pad);
       
  4575     GST_CAT_INFO_OBJECT (GST_CAT_EVENT, pad,
       
  4576         "Received event on flushing pad. Discarding");
       
  4577     gst_event_unref (event);
       
  4578     return FALSE;
       
  4579   }
       
  4580 dropping:
       
  4581   {
       
  4582     GST_DEBUG_OBJECT (pad, "Dropping event after FALSE probe return");
       
  4583     gst_event_unref (event);
       
  4584     return FALSE;
       
  4585   }
       
  4586 }
       
  4587 
       
  4588 /**
       
  4589  * gst_pad_set_element_private:
       
  4590  * @pad: the #GstPad to set the private data of.
       
  4591  * @priv: The private data to attach to the pad.
       
  4592  *
       
  4593  * Set the given private data gpointer on the pad.
       
  4594  * This function can only be used by the element that owns the pad.
       
  4595  * No locking is performed in this function.
       
  4596  */
       
  4597 #ifdef __SYMBIAN32__
       
  4598 EXPORT_C
       
  4599 #endif
       
  4600 
       
  4601 void
       
  4602 gst_pad_set_element_private (GstPad * pad, gpointer priv)
       
  4603 {
       
  4604   pad->element_private = priv;
       
  4605 }
       
  4606 
       
  4607 /**
       
  4608  * gst_pad_get_element_private:
       
  4609  * @pad: the #GstPad to get the private data of.
       
  4610  *
       
  4611  * Gets the private data of a pad.
       
  4612  * No locking is performed in this function.
       
  4613  *
       
  4614  * Returns: a #gpointer to the private data.
       
  4615  */
       
  4616 #ifdef __SYMBIAN32__
       
  4617 EXPORT_C
       
  4618 #endif
       
  4619 
       
  4620 gpointer
       
  4621 gst_pad_get_element_private (GstPad * pad)
       
  4622 {
       
  4623   return pad->element_private;
       
  4624 }
       
  4625 
       
  4626 /**
       
  4627  * gst_pad_start_task:
       
  4628  * @pad: the #GstPad to start the task of
       
  4629  * @func: the task function to call
       
  4630  * @data: data passed to the task function
       
  4631  *
       
  4632  * Starts a task that repeatedly calls @func with @data. This function
       
  4633  * is mostly used in pad activation functions to start the dataflow.
       
  4634  * The #GST_PAD_STREAM_LOCK of @pad will automatically be acquired
       
  4635  * before @func is called.
       
  4636  *
       
  4637  * Returns: a %TRUE if the task could be started.
       
  4638  */
       
  4639 #ifdef __SYMBIAN32__
       
  4640 EXPORT_C
       
  4641 #endif
       
  4642 
       
  4643 gboolean
       
  4644 gst_pad_start_task (GstPad * pad, GstTaskFunction func, gpointer data)
       
  4645 {
       
  4646   GstTask *task;
       
  4647 
       
  4648   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  4649   g_return_val_if_fail (func != NULL, FALSE);
       
  4650 
       
  4651   GST_DEBUG_OBJECT (pad, "start task");
       
  4652 
       
  4653   GST_OBJECT_LOCK (pad);
       
  4654   task = GST_PAD_TASK (pad);
       
  4655   if (task == NULL) {
       
  4656     task = gst_task_create (func, data);
       
  4657     gst_task_set_lock (task, GST_PAD_GET_STREAM_LOCK (pad));
       
  4658     GST_PAD_TASK (pad) = task;
       
  4659     GST_DEBUG_OBJECT (pad, "created task");
       
  4660   }
       
  4661   gst_task_start (task);
       
  4662   GST_OBJECT_UNLOCK (pad);
       
  4663 
       
  4664   return TRUE;
       
  4665 }
       
  4666 
       
  4667 /**
       
  4668  * gst_pad_pause_task:
       
  4669  * @pad: the #GstPad to pause the task of
       
  4670  *
       
  4671  * Pause the task of @pad. This function will also wait until the
       
  4672  * function executed by the task is finished if this function is not
       
  4673  * called from the task function.
       
  4674  *
       
  4675  * Returns: a TRUE if the task could be paused or FALSE when the pad
       
  4676  * has no task.
       
  4677  */
       
  4678 #ifdef __SYMBIAN32__
       
  4679 EXPORT_C
       
  4680 #endif
       
  4681 
       
  4682 gboolean
       
  4683 gst_pad_pause_task (GstPad * pad)
       
  4684 {
       
  4685   GstTask *task;
       
  4686 
       
  4687   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  4688 
       
  4689   GST_DEBUG_OBJECT (pad, "pause task");
       
  4690 
       
  4691   GST_OBJECT_LOCK (pad);
       
  4692   task = GST_PAD_TASK (pad);
       
  4693   if (task == NULL)
       
  4694     goto no_task;
       
  4695   gst_task_pause (task);
       
  4696   GST_OBJECT_UNLOCK (pad);
       
  4697 
       
  4698   /* wait for task function to finish, this lock is recursive so it does nothing
       
  4699    * when the pause is called from the task itself */
       
  4700   GST_PAD_STREAM_LOCK (pad);
       
  4701   GST_PAD_STREAM_UNLOCK (pad);
       
  4702 
       
  4703   return TRUE;
       
  4704 
       
  4705 no_task:
       
  4706   {
       
  4707     GST_DEBUG_OBJECT (pad, "pad has no task");
       
  4708     GST_OBJECT_UNLOCK (pad);
       
  4709     return FALSE;
       
  4710   }
       
  4711 }
       
  4712 
       
  4713 /**
       
  4714  * gst_pad_stop_task:
       
  4715  * @pad: the #GstPad to stop the task of
       
  4716  *
       
  4717  * Stop the task of @pad. This function will also make sure that the
       
  4718  * function executed by the task will effectively stop if not called
       
  4719  * from the GstTaskFunction.
       
  4720  *
       
  4721  * This function will deadlock if called from the GstTaskFunction of
       
  4722  * the task. Use gst_task_pause() instead.
       
  4723  *
       
  4724  * Regardless of whether the pad has a task, the stream lock is acquired and
       
  4725  * released so as to ensure that streaming through this pad has finished.
       
  4726  *
       
  4727  * Returns: a TRUE if the task could be stopped or FALSE on error.
       
  4728  */
       
  4729 #ifdef __SYMBIAN32__
       
  4730 EXPORT_C
       
  4731 #endif
       
  4732 
       
  4733 gboolean
       
  4734 gst_pad_stop_task (GstPad * pad)
       
  4735 {
       
  4736   GstTask *task;
       
  4737 
       
  4738   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
       
  4739 
       
  4740   GST_DEBUG_OBJECT (pad, "stop task");
       
  4741 
       
  4742   GST_OBJECT_LOCK (pad);
       
  4743   task = GST_PAD_TASK (pad);
       
  4744   if (task == NULL)
       
  4745     goto no_task;
       
  4746   GST_PAD_TASK (pad) = NULL;
       
  4747   gst_task_stop (task);
       
  4748   GST_OBJECT_UNLOCK (pad);
       
  4749 
       
  4750   GST_PAD_STREAM_LOCK (pad);
       
  4751   GST_PAD_STREAM_UNLOCK (pad);
       
  4752 
       
  4753   if (!gst_task_join (task))
       
  4754     goto join_failed;
       
  4755 
       
  4756   gst_object_unref (task);
       
  4757 
       
  4758   return TRUE;
       
  4759 
       
  4760 no_task:
       
  4761   {
       
  4762     GST_DEBUG_OBJECT (pad, "no task");
       
  4763     GST_OBJECT_UNLOCK (pad);
       
  4764 
       
  4765     GST_PAD_STREAM_LOCK (pad);
       
  4766     GST_PAD_STREAM_UNLOCK (pad);
       
  4767 
       
  4768     /* this is not an error */
       
  4769     return TRUE;
       
  4770   }
       
  4771 join_failed:
       
  4772   {
       
  4773     /* this is bad, possibly the application tried to join the task from
       
  4774      * the task's thread. We install the task again so that it will be stopped
       
  4775      * again from the right thread next time hopefully. */
       
  4776     GST_OBJECT_LOCK (pad);
       
  4777     GST_DEBUG_OBJECT (pad, "join failed");
       
  4778     /* we can only install this task if there was no other task */
       
  4779     if (GST_PAD_TASK (pad) == NULL)
       
  4780       GST_PAD_TASK (pad) = task;
       
  4781     GST_OBJECT_UNLOCK (pad);
       
  4782 
       
  4783     return FALSE;
       
  4784   }
       
  4785 }