gstreamer_core/gst/gstpad.c
changeset 16 8e837d1bf446
parent 0 0e761a78d257
child 30 7e817e7e631c
equal deleted inserted replaced
15:4b0c6ed43234 16:8e837d1bf446
    97   PAD_PROP_DIRECTION,
    97   PAD_PROP_DIRECTION,
    98   PAD_PROP_TEMPLATE,
    98   PAD_PROP_TEMPLATE,
    99   /* FILL ME */
    99   /* FILL ME */
   100 };
   100 };
   101 
   101 
   102 static void gst_pad_class_init (GstPadClass * klass);
   102 #define GST_PAD_GET_PRIVATE(obj)  \
   103 static void gst_pad_init (GstPad * pad);
   103    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_PAD, GstPadPrivate))
       
   104 
       
   105 #define GST_PAD_CHAINLISTFUNC(pad) ((pad)->abidata.ABI.priv->chainlistfunc)
       
   106 
       
   107 struct _GstPadPrivate
       
   108 {
       
   109   GstPadChainListFunction chainlistfunc;
       
   110 };
       
   111 
   104 static void gst_pad_dispose (GObject * object);
   112 static void gst_pad_dispose (GObject * object);
   105 static void gst_pad_finalize (GObject * object);
   113 static void gst_pad_finalize (GObject * object);
   106 static void gst_pad_set_property (GObject * object, guint prop_id,
   114 static void gst_pad_set_property (GObject * object, guint prop_id,
   107     const GValue * value, GParamSpec * pspec);
   115     const GValue * value, GParamSpec * pspec);
   108 static void gst_pad_get_property (GObject * object, guint prop_id,
   116 static void gst_pad_get_property (GObject * object, guint prop_id,
   140   {GST_FLOW_WRONG_STATE, "wrong-state", 0},
   148   {GST_FLOW_WRONG_STATE, "wrong-state", 0},
   141   {GST_FLOW_UNEXPECTED, "unexpected", 0},
   149   {GST_FLOW_UNEXPECTED, "unexpected", 0},
   142   {GST_FLOW_NOT_NEGOTIATED, "not-negotiated", 0},
   150   {GST_FLOW_NOT_NEGOTIATED, "not-negotiated", 0},
   143   {GST_FLOW_ERROR, "error", 0},
   151   {GST_FLOW_ERROR, "error", 0},
   144   {GST_FLOW_NOT_SUPPORTED, "not-supported", 0},
   152   {GST_FLOW_NOT_SUPPORTED, "not-supported", 0},
   145   {GST_FLOW_CUSTOM_ERROR, "custom-error", 0},
   153   {GST_FLOW_CUSTOM_ERROR, "custom-error", 0}
   146 
       
   147   {0, NULL, 0}
       
   148 };
   154 };
   149 
   155 
   150 /**
   156 /**
   151  * gst_flow_get_name:
   157  * gst_flow_get_name:
   152  * @ret: a #GstFlowReturn to get the name of.
   158  * @ret: a #GstFlowReturn to get the name of.
   164 {
   170 {
   165   gint i;
   171   gint i;
   166 
   172 
   167   ret = CLAMP (ret, GST_FLOW_CUSTOM_ERROR, GST_FLOW_CUSTOM_SUCCESS);
   173   ret = CLAMP (ret, GST_FLOW_CUSTOM_ERROR, GST_FLOW_CUSTOM_SUCCESS);
   168 
   174 
   169   for (i = 0; flow_quarks[i].name; i++) {
   175   for (i = 0; i < G_N_ELEMENTS (flow_quarks); i++) {
   170     if (ret == flow_quarks[i].ret)
   176     if (ret == flow_quarks[i].ret)
   171       return flow_quarks[i].name;
   177       return flow_quarks[i].name;
   172   }
   178   }
   173   return "unknown";
   179   return "unknown";
   174 }
   180 }
   191 {
   197 {
   192   gint i;
   198   gint i;
   193 
   199 
   194   ret = CLAMP (ret, GST_FLOW_CUSTOM_ERROR, GST_FLOW_CUSTOM_SUCCESS);
   200   ret = CLAMP (ret, GST_FLOW_CUSTOM_ERROR, GST_FLOW_CUSTOM_SUCCESS);
   195 
   201 
   196   for (i = 0; flow_quarks[i].name; i++) {
   202   for (i = 0; i < G_N_ELEMENTS (flow_quarks); i++) {
   197     if (ret == flow_quarks[i].ret)
   203     if (ret == flow_quarks[i].ret)
   198       return flow_quarks[i].quark;
   204       return flow_quarks[i].quark;
   199   }
   205   }
   200   return 0;
   206   return 0;
   201 }
   207 }
   202 #ifdef __SYMBIAN32__
   208 
   203 EXPORT_C
   209 #define _do_init \
   204 #endif
   210 { \
   205 
   211   gint i; \
   206 
   212   \
   207 GType
   213   buffer_quark = g_quark_from_static_string ("buffer"); \
   208 gst_pad_get_type (void)
   214   event_quark = g_quark_from_static_string ("event"); \
   209 {
   215   \
   210   static GType gst_pad_type = 0;
   216   for (i = 0; i < G_N_ELEMENTS (flow_quarks); i++) {			\
   211 
   217     flow_quarks[i].quark = g_quark_from_static_string (flow_quarks[i].name); \
   212   if (G_UNLIKELY (gst_pad_type == 0)) {
   218   } \
   213     static const GTypeInfo pad_info = {
   219   \
   214       sizeof (GstPadClass), NULL, NULL,
   220   GST_DEBUG_CATEGORY_INIT (debug_dataflow, "GST_DATAFLOW", \
   215       (GClassInitFunc) gst_pad_class_init, NULL, NULL,
   221       GST_DEBUG_BOLD | GST_DEBUG_FG_GREEN, "dataflow inside pads"); \
   216       sizeof (GstPad),
   222 }
   217       0,
   223 
   218       (GInstanceInitFunc) gst_pad_init, NULL
   224 G_DEFINE_TYPE_WITH_CODE (GstPad, gst_pad, GST_TYPE_OBJECT, _do_init);
   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 
   225 
   238 static gboolean
   226 static gboolean
   239 _gst_do_pass_data_accumulator (GSignalInvocationHint * ihint,
   227 _gst_do_pass_data_accumulator (GSignalInvocationHint * ihint,
   240     GValue * return_accu, const GValue * handler_return, gpointer dummy)
   228     GValue * return_accu, const GValue * handler_return, gpointer dummy)
   241 {
   229 {
   259   GObjectClass *gobject_class;
   247   GObjectClass *gobject_class;
   260   GstObjectClass *gstobject_class;
   248   GstObjectClass *gstobject_class;
   261 
   249 
   262   gobject_class = G_OBJECT_CLASS (klass);
   250   gobject_class = G_OBJECT_CLASS (klass);
   263   gstobject_class = GST_OBJECT_CLASS (klass);
   251   gstobject_class = GST_OBJECT_CLASS (klass);
       
   252 
       
   253   g_type_class_add_private (klass, sizeof (GstPadPrivate));
   264 
   254 
   265   parent_class = g_type_class_peek_parent (klass);
   255   parent_class = g_type_class_peek_parent (klass);
   266 
   256 
   267   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose);
   257   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pad_dispose);
   268   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_pad_finalize);
   258   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_pad_finalize);
   322       NULL, gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1,
   312       NULL, gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1,
   323       GST_TYPE_MINI_OBJECT);
   313       GST_TYPE_MINI_OBJECT);
   324 
   314 
   325   g_object_class_install_property (gobject_class, PAD_PROP_CAPS,
   315   g_object_class_install_property (gobject_class, PAD_PROP_CAPS,
   326       g_param_spec_boxed ("caps", "Caps", "The capabilities of the pad",
   316       g_param_spec_boxed ("caps", "Caps", "The capabilities of the pad",
   327           GST_TYPE_CAPS, G_PARAM_READABLE));
   317           GST_TYPE_CAPS, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   328   g_object_class_install_property (gobject_class, PAD_PROP_DIRECTION,
   318   g_object_class_install_property (gobject_class, PAD_PROP_DIRECTION,
   329       g_param_spec_enum ("direction", "Direction", "The direction of the pad",
   319       g_param_spec_enum ("direction", "Direction", "The direction of the pad",
   330           GST_TYPE_PAD_DIRECTION, GST_PAD_UNKNOWN,
   320           GST_TYPE_PAD_DIRECTION, GST_PAD_UNKNOWN,
   331           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
   321           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
   332   /* FIXME, Make G_PARAM_CONSTRUCT_ONLY when we fix ghostpads. */
   322   /* FIXME, Make G_PARAM_CONSTRUCT_ONLY when we fix ghostpads. */
   333   g_object_class_install_property (gobject_class, PAD_PROP_TEMPLATE,
   323   g_object_class_install_property (gobject_class, PAD_PROP_TEMPLATE,
   334       g_param_spec_object ("template", "Template",
   324       g_param_spec_object ("template", "Template",
   335           "The GstPadTemplate of this pad", GST_TYPE_PAD_TEMPLATE,
   325           "The GstPadTemplate of this pad", GST_TYPE_PAD_TEMPLATE,
   336           G_PARAM_READWRITE));
   326           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   337 
   327 
   338 #ifndef GST_DISABLE_LOADSAVE
   328 #ifndef GST_DISABLE_LOADSAVE
   339   gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_pad_save_thyself);
   329   gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_pad_save_thyself);
   340 #endif
   330 #endif
   341   gstobject_class->path_string_separator = ".";
   331   gstobject_class->path_string_separator = ".";
   344 }
   334 }
   345 
   335 
   346 static void
   336 static void
   347 gst_pad_init (GstPad * pad)
   337 gst_pad_init (GstPad * pad)
   348 {
   338 {
       
   339   pad->abidata.ABI.priv = GST_PAD_GET_PRIVATE (pad);
       
   340 
   349   GST_PAD_DIRECTION (pad) = GST_PAD_UNKNOWN;
   341   GST_PAD_DIRECTION (pad) = GST_PAD_UNKNOWN;
   350   GST_PAD_PEER (pad) = NULL;
   342   GST_PAD_PEER (pad) = NULL;
   351 
   343 
   352   GST_PAD_CHAINFUNC (pad) = NULL;
   344   GST_PAD_CHAINFUNC (pad) = NULL;
   353 
   345 
   361   GST_PAD_QUERYTYPEFUNC (pad) =
   353   GST_PAD_QUERYTYPEFUNC (pad) =
   362       GST_DEBUG_FUNCPTR (gst_pad_get_query_types_default);
   354       GST_DEBUG_FUNCPTR (gst_pad_get_query_types_default);
   363   GST_PAD_QUERYFUNC (pad) = GST_DEBUG_FUNCPTR (gst_pad_query_default);
   355   GST_PAD_QUERYFUNC (pad) = GST_DEBUG_FUNCPTR (gst_pad_query_default);
   364   GST_PAD_INTLINKFUNC (pad) =
   356   GST_PAD_INTLINKFUNC (pad) =
   365       GST_DEBUG_FUNCPTR (gst_pad_get_internal_links_default);
   357       GST_DEBUG_FUNCPTR (gst_pad_get_internal_links_default);
       
   358   GST_PAD_ITERINTLINKFUNC (pad) =
       
   359       GST_DEBUG_FUNCPTR (gst_pad_iterate_internal_links_default);
       
   360 
   366   GST_PAD_ACCEPTCAPSFUNC (pad) = GST_DEBUG_FUNCPTR (gst_pad_acceptcaps_default);
   361   GST_PAD_ACCEPTCAPSFUNC (pad) = GST_DEBUG_FUNCPTR (gst_pad_acceptcaps_default);
   367 
   362 
   368   pad->do_buffer_signals = 0;
   363   pad->do_buffer_signals = 0;
   369   pad->do_event_signals = 0;
   364   pad->do_event_signals = 0;
   370 
   365 
   402 
   397 
   403   /* clear the caps */
   398   /* clear the caps */
   404   gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
   399   gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
   405 
   400 
   406   gst_pad_set_pad_template (pad, NULL);
   401   gst_pad_set_pad_template (pad, NULL);
       
   402 
       
   403   if (pad->block_destroy_data && pad->block_data) {
       
   404     pad->block_destroy_data (pad->block_data);
       
   405     pad->block_data = NULL;
       
   406   }
   407 
   407 
   408   G_OBJECT_CLASS (parent_class)->dispose (object);
   408   G_OBJECT_CLASS (parent_class)->dispose (object);
   409 }
   409 }
   410 
   410 
   411 static void
   411 static void
   586 
   586 
   587   /* PAD_UNKNOWN is a little silly but we need some sort of
   587   /* PAD_UNKNOWN is a little silly but we need some sort of
   588    * error return value */
   588    * error return value */
   589   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
   589   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_UNKNOWN);
   590 
   590 
   591   GST_OBJECT_LOCK (pad);
       
   592   result = GST_PAD_DIRECTION (pad);
   591   result = GST_PAD_DIRECTION (pad);
   593   GST_OBJECT_UNLOCK (pad);
       
   594 
   592 
   595   return result;
   593   return result;
   596 }
   594 }
   597 
   595 
   598 static gboolean
   596 static gboolean
   799       GST_DEBUG_OBJECT (pad, "calling peer");
   797       GST_DEBUG_OBJECT (pad, "calling peer");
   800       if (G_UNLIKELY (!gst_pad_activate_pull (peer, active)))
   798       if (G_UNLIKELY (!gst_pad_activate_pull (peer, active)))
   801         goto peer_failed;
   799         goto peer_failed;
   802       gst_object_unref (peer);
   800       gst_object_unref (peer);
   803     } else {
   801     } else {
   804       goto not_linked;
   802       /* there is no peer, this is only fatal when we activate. When we
       
   803        * deactivate, we must assume the application has unlinked the peer and
       
   804        * will deactivate it eventually. */
       
   805       if (active)
       
   806         goto not_linked;
       
   807       else
       
   808         GST_DEBUG_OBJECT (pad, "deactivating unlinked pad");
   805     }
   809     }
   806   } else {
   810   } else {
   807     if (G_UNLIKELY (GST_PAD_GETRANGEFUNC (pad) == NULL))
   811     if (G_UNLIKELY (GST_PAD_GETRANGEFUNC (pad) == NULL))
   808       goto failure;             /* Can't activate pull on a src without a
   812       goto failure;             /* Can't activate pull on a src without a
   809                                    getrange function */
   813                                    getrange function */
  1002 
  1006 
  1003   return result;
  1007   return result;
  1004 }
  1008 }
  1005 
  1009 
  1006 /**
  1010 /**
  1007  * gst_pad_set_blocked_async:
  1011  * gst_pad_set_blocked_async_full:
  1008  * @pad: the #GstPad to block or unblock
  1012  * @pad: the #GstPad to block or unblock
  1009  * @blocked: boolean indicating whether the pad should be blocked or unblocked
  1013  * @blocked: boolean indicating whether the pad should be blocked or unblocked
  1010  * @callback: #GstPadBlockCallback that will be called when the
  1014  * @callback: #GstPadBlockCallback that will be called when the
  1011  *            operation succeeds
  1015  *            operation succeeds
  1012  * @user_data: user data passed to the callback
  1016  * @user_data: user data passed to the callback
       
  1017  * @destroy_data: #GDestroyNotify for user_data
  1013  *
  1018  *
  1014  * Blocks or unblocks the dataflow on a pad. The provided callback
  1019  * Blocks or unblocks the dataflow on a pad. The provided callback
  1015  * is called when the operation succeeds; this happens right before the next
  1020  * is called when the operation succeeds; this happens right before the next
  1016  * attempt at pushing a buffer on the pad.
  1021  * attempt at pushing a buffer on the pad.
  1017  *
  1022  *
  1024  *
  1029  *
  1025  * Returns: TRUE if the pad could be blocked. This function can fail if the
  1030  * 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.
  1031  * wrong parameters were passed or the pad was already in the requested state.
  1027  *
  1032  *
  1028  * MT safe.
  1033  * MT safe.
       
  1034  *
       
  1035  * Since: 0.10.23
  1029  */
  1036  */
  1030 #ifdef __SYMBIAN32__
  1037 #ifdef __SYMBIAN32__
  1031 EXPORT_C
  1038 EXPORT_C
  1032 #endif
  1039 #endif
  1033 
  1040 
  1034 gboolean
  1041 gboolean
  1035 gst_pad_set_blocked_async (GstPad * pad, gboolean blocked,
  1042 gst_pad_set_blocked_async_full (GstPad * pad, gboolean blocked,
  1036     GstPadBlockCallback callback, gpointer user_data)
  1043     GstPadBlockCallback callback, gpointer user_data,
       
  1044     GDestroyNotify destroy_data)
  1037 {
  1045 {
  1038   gboolean was_blocked = FALSE;
  1046   gboolean was_blocked = FALSE;
  1039 
  1047 
  1040   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  1048   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  1041 
  1049 
  1048 
  1056 
  1049   if (blocked) {
  1057   if (blocked) {
  1050     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocking pad");
  1058     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocking pad");
  1051 
  1059 
  1052     GST_OBJECT_FLAG_SET (pad, GST_PAD_BLOCKED);
  1060     GST_OBJECT_FLAG_SET (pad, GST_PAD_BLOCKED);
       
  1061 
       
  1062     if (pad->block_destroy_data && pad->block_data &&
       
  1063         pad->block_data != user_data)
       
  1064       pad->block_destroy_data (pad->block_data);
       
  1065 
  1053     pad->block_callback = callback;
  1066     pad->block_callback = callback;
  1054     pad->block_data = user_data;
  1067     pad->block_data = user_data;
       
  1068     pad->block_destroy_data = destroy_data;
       
  1069     pad->abidata.ABI.block_callback_called = FALSE;
  1055     if (!callback) {
  1070     if (!callback) {
  1056       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "waiting for block");
  1071       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "waiting for block");
  1057       GST_PAD_BLOCK_WAIT (pad);
  1072       GST_PAD_BLOCK_WAIT (pad);
  1058       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocked");
  1073       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocked");
  1059     }
  1074     }
  1060   } else {
  1075   } else {
  1061     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "unblocking pad");
  1076     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "unblocking pad");
  1062 
  1077 
  1063     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_BLOCKED);
  1078     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_BLOCKED);
  1064 
  1079 
       
  1080     if (pad->block_destroy_data && pad->block_data &&
       
  1081         pad->block_data != user_data)
       
  1082       pad->block_destroy_data (pad->block_data);
       
  1083 
  1065     pad->block_callback = callback;
  1084     pad->block_callback = callback;
  1066     pad->block_data = user_data;
  1085     pad->block_data = user_data;
       
  1086     pad->block_destroy_data = destroy_data;
       
  1087     pad->abidata.ABI.block_callback_called = FALSE;
  1067 
  1088 
  1068     GST_PAD_BLOCK_BROADCAST (pad);
  1089     GST_PAD_BLOCK_BROADCAST (pad);
  1069     if (!callback) {
  1090     if (!callback) {
  1070       /* no callback, wait for the unblock to happen */
  1091       /* no callback, wait for the unblock to happen */
  1071       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "waiting for unblock");
  1092       GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "waiting for unblock");
  1086     return FALSE;
  1107     return FALSE;
  1087   }
  1108   }
  1088 }
  1109 }
  1089 
  1110 
  1090 /**
  1111 /**
       
  1112  * gst_pad_set_blocked_async:
       
  1113  * @pad: the #GstPad to block or unblock
       
  1114  * @blocked: boolean indicating whether the pad should be blocked or unblocked
       
  1115  * @callback: #GstPadBlockCallback that will be called when the
       
  1116  *            operation succeeds
       
  1117  * @user_data: user data passed to the callback
       
  1118  *
       
  1119  * Blocks or unblocks the dataflow on a pad. The provided callback
       
  1120  * is called when the operation succeeds; this happens right before the next
       
  1121  * attempt at pushing a buffer on the pad.
       
  1122  *
       
  1123  * This can take a while as the pad can only become blocked when real dataflow
       
  1124  * is happening.
       
  1125  * When the pipeline is stalled, for example in PAUSED, this can
       
  1126  * take an indeterminate amount of time.
       
  1127  * You can pass NULL as the callback to make this call block. Be careful with
       
  1128  * this blocking call as it might not return for reasons stated above.
       
  1129  *
       
  1130  * Returns: TRUE if the pad could be blocked. This function can fail if the
       
  1131  * wrong parameters were passed or the pad was already in the requested state.
       
  1132  *
       
  1133  * MT safe.
       
  1134  */
       
  1135 #ifdef __SYMBIAN32__
       
  1136 EXPORT_C
       
  1137 #endif
       
  1138 
       
  1139 gboolean
       
  1140 gst_pad_set_blocked_async (GstPad * pad, gboolean blocked,
       
  1141     GstPadBlockCallback callback, gpointer user_data)
       
  1142 {
       
  1143   return gst_pad_set_blocked_async_full (pad, blocked,
       
  1144       callback, user_data, NULL);
       
  1145 }
       
  1146 
       
  1147 /**
  1091  * gst_pad_set_blocked:
  1148  * gst_pad_set_blocked:
  1092  * @pad: the #GstPad to block or unblock
  1149  * @pad: the #GstPad to block or unblock
  1093  * @blocked: boolean indicating we should block or unblock
  1150  * @blocked: boolean indicating we should block or unblock
  1094  *
  1151  *
  1095  * Blocks or unblocks the dataflow on a pad. This function is
  1152  * Blocks or unblocks the dataflow on a pad. This function is
  1260 
  1317 
  1261 void
  1318 void
  1262 gst_pad_set_chain_function (GstPad * pad, GstPadChainFunction chain)
  1319 gst_pad_set_chain_function (GstPad * pad, GstPadChainFunction chain)
  1263 {
  1320 {
  1264   g_return_if_fail (GST_IS_PAD (pad));
  1321   g_return_if_fail (GST_IS_PAD (pad));
  1265   g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK);
  1322   g_return_if_fail (GST_PAD_IS_SINK (pad));
  1266 
  1323 
  1267   GST_PAD_CHAINFUNC (pad) = chain;
  1324   GST_PAD_CHAINFUNC (pad) = chain;
  1268   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "chainfunc set to %s",
  1325   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "chainfunc set to %s",
  1269       GST_DEBUG_FUNCPTR_NAME (chain));
  1326       GST_DEBUG_FUNCPTR_NAME (chain));
  1270 }
  1327 }
  1271 
  1328 
  1272 /**
  1329 /**
       
  1330  * gst_pad_set_chain_list_function:
       
  1331  * @pad: a sink #GstPad.
       
  1332  * @chainlist: the #GstPadChainListFunction to set.
       
  1333  *
       
  1334  * Sets the given chain list function for the pad. The chainlist function is
       
  1335  * called to process a #GstBufferList input buffer list. See
       
  1336  * #GstPadChainListFunction for more details.
       
  1337  *
       
  1338  * Since: 0.10.24
       
  1339  */
       
  1340 #ifdef __SYMBIAN32__
       
  1341 EXPORT_C
       
  1342 #endif
       
  1343 
       
  1344 void
       
  1345 gst_pad_set_chain_list_function (GstPad * pad,
       
  1346     GstPadChainListFunction chainlist)
       
  1347 {
       
  1348   g_return_if_fail (GST_IS_PAD (pad));
       
  1349   g_return_if_fail (GST_PAD_IS_SINK (pad));
       
  1350 
       
  1351   GST_PAD_CHAINLISTFUNC (pad) = chainlist;
       
  1352   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "chainlistfunc set to %s",
       
  1353       GST_DEBUG_FUNCPTR_NAME (chainlist));
       
  1354 }
       
  1355 
       
  1356 /**
  1273  * gst_pad_set_getrange_function:
  1357  * gst_pad_set_getrange_function:
  1274  * @pad: a source #GstPad.
  1358  * @pad: a source #GstPad.
  1275  * @get: the #GstPadGetRangeFunction to set.
  1359  * @get: the #GstPadGetRangeFunction to set.
  1276  *
  1360  *
  1277  * Sets the given getrange function for the pad. The getrange function is
  1361  * Sets the given getrange function for the pad. The getrange function is
  1284 
  1368 
  1285 void
  1369 void
  1286 gst_pad_set_getrange_function (GstPad * pad, GstPadGetRangeFunction get)
  1370 gst_pad_set_getrange_function (GstPad * pad, GstPadGetRangeFunction get)
  1287 {
  1371 {
  1288   g_return_if_fail (GST_IS_PAD (pad));
  1372   g_return_if_fail (GST_IS_PAD (pad));
  1289   g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
  1373   g_return_if_fail (GST_PAD_IS_SRC (pad));
  1290 
  1374 
  1291   GST_PAD_GETRANGEFUNC (pad) = get;
  1375   GST_PAD_GETRANGEFUNC (pad) = get;
  1292 
  1376 
  1293   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "getrangefunc set to %s",
  1377   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "getrangefunc set to %s",
  1294       GST_DEBUG_FUNCPTR_NAME (get));
  1378       GST_DEBUG_FUNCPTR_NAME (get));
  1309 void
  1393 void
  1310 gst_pad_set_checkgetrange_function (GstPad * pad,
  1394 gst_pad_set_checkgetrange_function (GstPad * pad,
  1311     GstPadCheckGetRangeFunction check)
  1395     GstPadCheckGetRangeFunction check)
  1312 {
  1396 {
  1313   g_return_if_fail (GST_IS_PAD (pad));
  1397   g_return_if_fail (GST_IS_PAD (pad));
  1314   g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
  1398   g_return_if_fail (GST_PAD_IS_SRC (pad));
  1315 
  1399 
  1316   GST_PAD_CHECKGETRANGEFUNC (pad) = check;
  1400   GST_PAD_CHECKGETRANGEFUNC (pad) = check;
  1317 
  1401 
  1318   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "checkgetrangefunc set to %s",
  1402   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "checkgetrangefunc set to %s",
  1319       GST_DEBUG_FUNCPTR_NAME (check));
  1403       GST_DEBUG_FUNCPTR_NAME (check));
  1451 
  1535 
  1452   return result;
  1536   return result;
  1453 }
  1537 }
  1454 
  1538 
  1455 /**
  1539 /**
       
  1540  * gst_pad_set_iterate_internal_links_function:
       
  1541  * @pad: a #GstPad of either direction.
       
  1542  * @iterintlink: the #GstPadIterIntLinkFunction to set.
       
  1543  *
       
  1544  * Sets the given internal link iterator function for the pad.
       
  1545  *
       
  1546  * Since: 0.10.21
       
  1547  */
       
  1548 #ifdef __SYMBIAN32__
       
  1549 EXPORT_C
       
  1550 #endif
       
  1551 
       
  1552 void
       
  1553 gst_pad_set_iterate_internal_links_function (GstPad * pad,
       
  1554     GstPadIterIntLinkFunction iterintlink)
       
  1555 {
       
  1556   g_return_if_fail (GST_IS_PAD (pad));
       
  1557 
       
  1558   GST_PAD_ITERINTLINKFUNC (pad) = iterintlink;
       
  1559   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "internal link iterator set to %s",
       
  1560       GST_DEBUG_FUNCPTR_NAME (iterintlink));
       
  1561 }
       
  1562 
       
  1563 /**
  1456  * gst_pad_set_internal_link_function:
  1564  * gst_pad_set_internal_link_function:
  1457  * @pad: a #GstPad of either direction.
  1565  * @pad: a #GstPad of either direction.
  1458  * @intlink: the #GstPadIntLinkFunction to set.
  1566  * @intlink: the #GstPadIntLinkFunction to set.
  1459  *
  1567  *
  1460  * Sets the given internal link function for the pad.
  1568  * Sets the given internal link function for the pad.
  1461  */
  1569  *
       
  1570  * Deprecated: Use the thread-safe gst_pad_set_iterate_internal_links_function()
       
  1571  */
       
  1572 #ifndef GST_REMOVE_DEPRECATED
  1462 #ifdef __SYMBIAN32__
  1573 #ifdef __SYMBIAN32__
  1463 EXPORT_C
  1574 EXPORT_C
  1464 #endif
  1575 #endif
  1465 
  1576 
  1466 void
  1577 void
  1470 
  1581 
  1471   GST_PAD_INTLINKFUNC (pad) = intlink;
  1582   GST_PAD_INTLINKFUNC (pad) = intlink;
  1472   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "internal link set to %s",
  1583   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "internal link set to %s",
  1473       GST_DEBUG_FUNCPTR_NAME (intlink));
  1584       GST_DEBUG_FUNCPTR_NAME (intlink));
  1474 }
  1585 }
       
  1586 #endif /* GST_REMOVE_DEPRECATED */
  1475 
  1587 
  1476 /**
  1588 /**
  1477  * gst_pad_set_link_function:
  1589  * gst_pad_set_link_function:
  1478  * @pad: a #GstPad.
  1590  * @pad: a #GstPad.
  1479  * @link: the #GstPadLinkFunction to set.
  1591  * @link: the #GstPadLinkFunction to set.
  1682 #endif
  1794 #endif
  1683 
  1795 
  1684 gboolean
  1796 gboolean
  1685 gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
  1797 gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
  1686 {
  1798 {
       
  1799   gboolean result = FALSE;
       
  1800   GstElement *parent = NULL;
       
  1801 
  1687   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
  1802   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
       
  1803   g_return_val_if_fail (GST_PAD_IS_SRC (srcpad), FALSE);
  1688   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
  1804   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
       
  1805   g_return_val_if_fail (GST_PAD_IS_SINK (sinkpad), FALSE);
  1689 
  1806 
  1690   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinking %s:%s(%p) and %s:%s(%p)",
  1807   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinking %s:%s(%p) and %s:%s(%p)",
  1691       GST_DEBUG_PAD_NAME (srcpad), srcpad,
  1808       GST_DEBUG_PAD_NAME (srcpad), srcpad,
  1692       GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
  1809       GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
  1693 
  1810 
       
  1811   /* We need to notify the parent before taking any pad locks as the bin in
       
  1812    * question might be waiting for a lock on the pad while holding its lock
       
  1813    * that our message will try to take. */
       
  1814   if ((parent = GST_ELEMENT_CAST (gst_pad_get_parent (srcpad)))) {
       
  1815     if (GST_IS_ELEMENT (parent)) {
       
  1816       gst_element_post_message (parent,
       
  1817           gst_message_new_structure_change (GST_OBJECT_CAST (srcpad),
       
  1818               GST_STRUCTURE_CHANGE_TYPE_PAD_UNLINK, parent, TRUE));
       
  1819     } else {
       
  1820       gst_object_unref (parent);
       
  1821       parent = NULL;
       
  1822     }
       
  1823   }
       
  1824 
  1694   GST_OBJECT_LOCK (srcpad);
  1825   GST_OBJECT_LOCK (srcpad);
  1695 
  1826 
  1696   if (G_UNLIKELY (GST_PAD_DIRECTION (srcpad) != GST_PAD_SRC))
       
  1697     goto not_srcpad;
       
  1698 
       
  1699   GST_OBJECT_LOCK (sinkpad);
  1827   GST_OBJECT_LOCK (sinkpad);
  1700 
       
  1701   if (G_UNLIKELY (GST_PAD_DIRECTION (sinkpad) != GST_PAD_SINK))
       
  1702     goto not_sinkpad;
       
  1703 
  1828 
  1704   if (G_UNLIKELY (GST_PAD_PEER (srcpad) != sinkpad))
  1829   if (G_UNLIKELY (GST_PAD_PEER (srcpad) != sinkpad))
  1705     goto not_linked_together;
  1830     goto not_linked_together;
  1706 
  1831 
  1707   if (GST_PAD_UNLINKFUNC (srcpad)) {
  1832   if (GST_PAD_UNLINKFUNC (srcpad)) {
  1724   g_signal_emit (G_OBJECT (sinkpad), gst_pad_signals[PAD_UNLINKED], 0, srcpad);
  1849   g_signal_emit (G_OBJECT (sinkpad), gst_pad_signals[PAD_UNLINKED], 0, srcpad);
  1725 
  1850 
  1726   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinked %s:%s and %s:%s",
  1851   GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "unlinked %s:%s and %s:%s",
  1727       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
  1852       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
  1728 
  1853 
  1729   return TRUE;
  1854   result = TRUE;
  1730 
  1855 
  1731 not_srcpad:
  1856 done:
  1732   {
  1857   if (parent != NULL) {
  1733     g_critical ("pad %s is not a source pad", GST_PAD_NAME (srcpad));
  1858     gst_element_post_message (parent,
  1734     GST_OBJECT_UNLOCK (srcpad);
  1859         gst_message_new_structure_change (GST_OBJECT_CAST (srcpad),
  1735     return FALSE;
  1860             GST_STRUCTURE_CHANGE_TYPE_PAD_UNLINK, parent, FALSE));
  1736   }
  1861     gst_object_unref (parent);
  1737 not_sinkpad:
  1862   }
  1738   {
  1863   return result;
  1739     g_critical ("pad %s is not a sink pad", GST_PAD_NAME (sinkpad));
  1864 
  1740     GST_OBJECT_UNLOCK (sinkpad);
  1865   /* ERRORS */
  1741     GST_OBJECT_UNLOCK (srcpad);
       
  1742     return FALSE;
       
  1743   }
       
  1744 not_linked_together:
  1866 not_linked_together:
  1745   {
  1867   {
  1746     /* we do not emit a warning in this case because unlinking cannot
  1868     /* we do not emit a warning in this case because unlinking cannot
  1747      * be made MT safe.*/
  1869      * be made MT safe.*/
  1748     GST_OBJECT_UNLOCK (sinkpad);
  1870     GST_OBJECT_UNLOCK (sinkpad);
  1749     GST_OBJECT_UNLOCK (srcpad);
  1871     GST_OBJECT_UNLOCK (srcpad);
  1750     return FALSE;
  1872     goto done;
  1751   }
  1873   }
  1752 }
  1874 }
  1753 
  1875 
  1754 /**
  1876 /**
  1755  * gst_pad_is_linked:
  1877  * gst_pad_is_linked:
  1798   GST_CAT_DEBUG (GST_CAT_CAPS, "src caps %" GST_PTR_FORMAT, srccaps);
  1920   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);
  1921   GST_CAT_DEBUG (GST_CAT_CAPS, "sink caps %" GST_PTR_FORMAT, sinkcaps);
  1800 
  1922 
  1801   /* if we have caps on both pads we can check the intersection. If one
  1923   /* if we have caps on both pads we can check the intersection. If one
  1802    * of the caps is NULL, we return TRUE. */
  1924    * of the caps is NULL, we return TRUE. */
  1803   if (srccaps == NULL || sinkcaps == NULL)
  1925   if (G_UNLIKELY (srccaps == NULL || sinkcaps == NULL)) {
       
  1926     if (srccaps)
       
  1927       gst_caps_unref (srccaps);
       
  1928     if (sinkcaps)
       
  1929       gst_caps_unref (sinkcaps);
  1804     goto done;
  1930     goto done;
       
  1931   }
  1805 
  1932 
  1806   icaps = gst_caps_intersect (srccaps, sinkcaps);
  1933   icaps = gst_caps_intersect (srccaps, sinkcaps);
  1807   gst_caps_unref (srccaps);
  1934   gst_caps_unref (srccaps);
  1808   gst_caps_unref (sinkcaps);
  1935   gst_caps_unref (sinkcaps);
  1809 
  1936 
  1907 /* call with the two pads unlocked, when this function returns GST_PAD_LINK_OK,
  2034 /* 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. */
  2035  * the two pads will be locked in the srcpad, sinkpad order. */
  1909 static GstPadLinkReturn
  2036 static GstPadLinkReturn
  1910 gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad)
  2037 gst_pad_link_prepare (GstPad * srcpad, GstPad * sinkpad)
  1911 {
  2038 {
  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",
  2039   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));
  2040       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
  1918 
  2041 
  1919   GST_OBJECT_LOCK (srcpad);
  2042   GST_OBJECT_LOCK (srcpad);
  1920 
  2043 
  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))
  2044   if (G_UNLIKELY (GST_PAD_PEER (srcpad) != NULL))
  1925     goto src_was_linked;
  2045     goto src_was_linked;
  1926 
  2046 
  1927   GST_OBJECT_LOCK (sinkpad);
  2047   GST_OBJECT_LOCK (sinkpad);
  1928 
       
  1929   if (G_UNLIKELY (GST_PAD_DIRECTION (sinkpad) != GST_PAD_SINK))
       
  1930     goto not_sinkpad;
       
  1931 
  2048 
  1932   if (G_UNLIKELY (GST_PAD_PEER (sinkpad) != NULL))
  2049   if (G_UNLIKELY (GST_PAD_PEER (sinkpad) != NULL))
  1933     goto sink_was_linked;
  2050     goto sink_was_linked;
  1934 
  2051 
  1935   /* check hierarchy, pads can only be linked if the grandparents
  2052   /* check hierarchy, pads can only be linked if the grandparents
  1943 
  2060 
  1944   /* FIXME check pad scheduling for non-empty intersection */
  2061   /* FIXME check pad scheduling for non-empty intersection */
  1945 
  2062 
  1946   return GST_PAD_LINK_OK;
  2063   return GST_PAD_LINK_OK;
  1947 
  2064 
  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:
  2065 src_was_linked:
  1955   {
  2066   {
  1956     GST_CAT_INFO (GST_CAT_PADS, "src %s:%s was already linked to %s:%s",
  2067     GST_CAT_INFO (GST_CAT_PADS, "src %s:%s was already linked to %s:%s",
  1957         GST_DEBUG_PAD_NAME (srcpad),
  2068         GST_DEBUG_PAD_NAME (srcpad),
  1958         GST_DEBUG_PAD_NAME (GST_PAD_PEER (srcpad)));
  2069         GST_DEBUG_PAD_NAME (GST_PAD_PEER (srcpad)));
  1959     /* we do not emit a warning in this case because unlinking cannot
  2070     /* we do not emit a warning in this case because unlinking cannot
  1960      * be made MT safe.*/
  2071      * be made MT safe.*/
  1961     GST_OBJECT_UNLOCK (srcpad);
  2072     GST_OBJECT_UNLOCK (srcpad);
  1962     return GST_PAD_LINK_WAS_LINKED;
  2073     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   }
  2074   }
  1971 sink_was_linked:
  2075 sink_was_linked:
  1972   {
  2076   {
  1973     GST_CAT_INFO (GST_CAT_PADS, "sink %s:%s was already linked to %s:%s",
  2077     GST_CAT_INFO (GST_CAT_PADS, "sink %s:%s was already linked to %s:%s",
  1974         GST_DEBUG_PAD_NAME (sinkpad),
  2078         GST_DEBUG_PAD_NAME (sinkpad),
  1994     return GST_PAD_LINK_NOFORMAT;
  2098     return GST_PAD_LINK_NOFORMAT;
  1995   }
  2099   }
  1996 }
  2100 }
  1997 
  2101 
  1998 /**
  2102 /**
       
  2103  * gst_pad_can_link:
       
  2104  * @srcpad: the source #GstPad.
       
  2105  * @sinkpad: the sink #GstPad.
       
  2106  *
       
  2107  * Checks if the source pad and the sink pad are compatible so they can be
       
  2108  * linked. 
       
  2109  *
       
  2110  * Returns: TRUE if the pads can be linked.
       
  2111  */
       
  2112 #ifdef __SYMBIAN32__
       
  2113 EXPORT_C
       
  2114 #endif
       
  2115 
       
  2116 gboolean
       
  2117 gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad)
       
  2118 {
       
  2119   GstPadLinkReturn result;
       
  2120 
       
  2121   /* generic checks */
       
  2122   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
       
  2123   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
       
  2124 
       
  2125   GST_CAT_INFO (GST_CAT_PADS, "check if %s:%s can link with %s:%s",
       
  2126       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
       
  2127 
       
  2128   /* gst_pad_link_prepare does everything for us, we only release the locks
       
  2129    * on the pads that it gets us. If this function returns !OK the locks are not
       
  2130    * taken anymore. */
       
  2131   result = gst_pad_link_prepare (srcpad, sinkpad);
       
  2132   if (result != GST_PAD_LINK_OK)
       
  2133     goto done;
       
  2134 
       
  2135   GST_OBJECT_UNLOCK (srcpad);
       
  2136   GST_OBJECT_UNLOCK (sinkpad);
       
  2137 
       
  2138 done:
       
  2139   return result == GST_PAD_LINK_OK;
       
  2140 }
       
  2141 
       
  2142 /**
  1999  * gst_pad_link:
  2143  * gst_pad_link:
  2000  * @srcpad: the source #GstPad to link.
  2144  * @srcpad: the source #GstPad to link.
  2001  * @sinkpad: the sink #GstPad to link.
  2145  * @sinkpad: the sink #GstPad to link.
  2002  *
  2146  *
  2003  * Links the source pad and the sink pad.
  2147  * Links the source pad and the sink pad.
  2013 
  2157 
  2014 GstPadLinkReturn
  2158 GstPadLinkReturn
  2015 gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
  2159 gst_pad_link (GstPad * srcpad, GstPad * sinkpad)
  2016 {
  2160 {
  2017   GstPadLinkReturn result;
  2161   GstPadLinkReturn result;
       
  2162   GstElement *parent;
       
  2163 
       
  2164   g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED);
       
  2165   g_return_val_if_fail (GST_PAD_IS_SRC (srcpad), GST_PAD_LINK_WRONG_DIRECTION);
       
  2166   g_return_val_if_fail (GST_IS_PAD (sinkpad), GST_PAD_LINK_REFUSED);
       
  2167   g_return_val_if_fail (GST_PAD_IS_SINK (sinkpad),
       
  2168       GST_PAD_LINK_WRONG_DIRECTION);
       
  2169 
       
  2170   /* Notify the parent early. See gst_pad_unlink for details. */
       
  2171   if ((parent = GST_ELEMENT_CAST (gst_pad_get_parent (srcpad)))) {
       
  2172     if (GST_IS_ELEMENT (parent)) {
       
  2173       gst_element_post_message (parent,
       
  2174           gst_message_new_structure_change (GST_OBJECT_CAST (srcpad),
       
  2175               GST_STRUCTURE_CHANGE_TYPE_PAD_LINK, parent, TRUE));
       
  2176     } else {
       
  2177       gst_object_unref (parent);
       
  2178       parent = NULL;
       
  2179     }
       
  2180   }
  2018 
  2181 
  2019   /* prepare will also lock the two pads */
  2182   /* prepare will also lock the two pads */
  2020   result = gst_pad_link_prepare (srcpad, sinkpad);
  2183   result = gst_pad_link_prepare (srcpad, sinkpad);
  2021 
  2184 
  2022   if (result != GST_PAD_LINK_OK)
  2185   if (result != GST_PAD_LINK_OK)
  2023     goto prepare_failed;
  2186     goto done;
  2024 
  2187 
  2025   /* must set peers before calling the link function */
  2188   /* must set peers before calling the link function */
  2026   GST_PAD_PEER (srcpad) = sinkpad;
  2189   GST_PAD_PEER (srcpad) = sinkpad;
  2027   GST_PAD_PEER (sinkpad) = srcpad;
  2190   GST_PAD_PEER (sinkpad) = srcpad;
  2028 
  2191 
  2064     GST_PAD_PEER (sinkpad) = NULL;
  2227     GST_PAD_PEER (sinkpad) = NULL;
  2065 
  2228 
  2066     GST_OBJECT_UNLOCK (sinkpad);
  2229     GST_OBJECT_UNLOCK (sinkpad);
  2067     GST_OBJECT_UNLOCK (srcpad);
  2230     GST_OBJECT_UNLOCK (srcpad);
  2068   }
  2231   }
       
  2232 
       
  2233 done:
       
  2234   if (parent) {
       
  2235     gst_element_post_message (parent,
       
  2236         gst_message_new_structure_change (GST_OBJECT_CAST (srcpad),
       
  2237             GST_STRUCTURE_CHANGE_TYPE_PAD_LINK, parent, FALSE));
       
  2238     gst_object_unref (parent);
       
  2239   }
       
  2240 
  2069   return result;
  2241   return result;
  2070 
       
  2071 prepare_failed:
       
  2072   {
       
  2073     return result;
       
  2074   }
       
  2075 }
  2242 }
  2076 
  2243 
  2077 static void
  2244 static void
  2078 gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ)
  2245 gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ)
  2079 {
  2246 {
  2192  * gst_pad_get_caps:
  2359  * gst_pad_get_caps:
  2193  * @pad: a  #GstPad to get the capabilities of.
  2360  * @pad: a  #GstPad to get the capabilities of.
  2194  *
  2361  *
  2195  * Gets the capabilities this pad can produce or consume.
  2362  * Gets the capabilities this pad can produce or consume.
  2196  * Note that this method doesn't necessarily return the caps set by
  2363  * Note that this method doesn't necessarily return the caps set by
  2197  * gst_pad_set_caps() - use #GST_PAD_CAPS for that instead.
  2364  * 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
  2365  * gst_pad_get_caps returns all possible caps a pad can operate with, using
  2199  * the pad's get_caps function;
  2366  * the pad's get_caps function;
  2200  * this returns the pad template caps if not explicitly set.
  2367  * this returns the pad template caps if not explicitly set.
  2201  *
  2368  *
  2202  * Returns: a newly allocated copy of the #GstCaps of this pad.
  2369  * Returns: a newly allocated copy of the #GstCaps of this pad.
  2298     if (!fixate_value (dest, &temp))
  2465     if (!fixate_value (dest, &temp))
  2299       gst_value_init_and_copy (dest, &temp);
  2466       gst_value_init_and_copy (dest, &temp);
  2300     g_value_unset (&temp);
  2467     g_value_unset (&temp);
  2301   } else if (G_VALUE_TYPE (src) == GST_TYPE_ARRAY) {
  2468   } else if (G_VALUE_TYPE (src) == GST_TYPE_ARRAY) {
  2302     gboolean res = FALSE;
  2469     gboolean res = FALSE;
  2303     guint n;
  2470     guint n, len;
  2304 
  2471 
       
  2472     len = gst_value_array_get_size (src);
  2305     g_value_init (dest, GST_TYPE_ARRAY);
  2473     g_value_init (dest, GST_TYPE_ARRAY);
  2306     for (n = 0; n < gst_value_array_get_size (src); n++) {
  2474     for (n = 0; n < len; n++) {
  2307       GValue kid = { 0 };
  2475       GValue kid = { 0 };
  2308       const GValue *orig_kid = gst_value_array_get_value (src, n);
  2476       const GValue *orig_kid = gst_value_array_get_value (src, n);
  2309 
  2477 
  2310       if (!fixate_value (&kid, orig_kid))
  2478       if (!fixate_value (&kid, orig_kid))
  2311         gst_value_init_and_copy (&kid, orig_kid);
  2479         gst_value_init_and_copy (&kid, orig_kid);
  2354 
  2522 
  2355 void
  2523 void
  2356 gst_pad_fixate_caps (GstPad * pad, GstCaps * caps)
  2524 gst_pad_fixate_caps (GstPad * pad, GstCaps * caps)
  2357 {
  2525 {
  2358   GstPadFixateCapsFunction fixatefunc;
  2526   GstPadFixateCapsFunction fixatefunc;
  2359   guint n;
  2527   guint n, len;
  2360 
  2528 
  2361   g_return_if_fail (GST_IS_PAD (pad));
  2529   g_return_if_fail (GST_IS_PAD (pad));
  2362   g_return_if_fail (caps != NULL);
  2530   g_return_if_fail (caps != NULL);
  2363 
  2531 
  2364   if (gst_caps_is_fixed (caps))
  2532   if (gst_caps_is_fixed (caps))
  2368   if (fixatefunc) {
  2536   if (fixatefunc) {
  2369     fixatefunc (pad, caps);
  2537     fixatefunc (pad, caps);
  2370   }
  2538   }
  2371 
  2539 
  2372   /* default fixation */
  2540   /* default fixation */
  2373   for (n = 0; n < gst_caps_get_size (caps); n++) {
  2541   len = gst_caps_get_size (caps);
       
  2542   for (n = 0; n < len; n++) {
  2374     GstStructure *s = gst_caps_get_structure (caps, n);
  2543     GstStructure *s = gst_caps_get_structure (caps, n);
  2375 
  2544 
  2376     gst_structure_foreach (s, gst_pad_default_fixate, s);
  2545     gst_structure_foreach (s, gst_pad_default_fixate, s);
  2377   }
  2546   }
  2378 }
  2547 }
  2399   intersect = gst_caps_intersect (allowed, caps);
  2568   intersect = gst_caps_intersect (allowed, caps);
  2400 
  2569 
  2401   GST_DEBUG_OBJECT (pad, "intersection %" GST_PTR_FORMAT, intersect);
  2570   GST_DEBUG_OBJECT (pad, "intersection %" GST_PTR_FORMAT, intersect);
  2402 
  2571 
  2403   result = !gst_caps_is_empty (intersect);
  2572   result = !gst_caps_is_empty (intersect);
  2404   if (!result)
       
  2405     GST_DEBUG_OBJECT (pad, "intersection gave empty caps");
       
  2406 
  2573 
  2407   gst_caps_unref (allowed);
  2574   gst_caps_unref (allowed);
  2408   gst_caps_unref (intersect);
  2575   gst_caps_unref (intersect);
  2409 
  2576 
  2410   return result;
  2577   return result;
  2443   if (caps == NULL)
  2610   if (caps == NULL)
  2444     return TRUE;
  2611     return TRUE;
  2445 
  2612 
  2446   /* lock for checking the existing caps */
  2613   /* lock for checking the existing caps */
  2447   GST_OBJECT_LOCK (pad);
  2614   GST_OBJECT_LOCK (pad);
  2448   acceptfunc = GST_PAD_ACCEPTCAPSFUNC (pad);
       
  2449   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "accept caps of %p", caps);
  2615   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "accept caps of %p", caps);
  2450   /* The current caps on a pad are trivially acceptable */
  2616   /* The current caps on a pad are trivially acceptable */
  2451   if (G_LIKELY ((existing = GST_PAD_CAPS (pad)))) {
  2617   if (G_LIKELY ((existing = GST_PAD_CAPS (pad)))) {
  2452     if (caps == existing || gst_caps_is_equal (caps, existing))
  2618     if (caps == existing || gst_caps_is_equal (caps, existing))
  2453       goto is_same_caps;
  2619       goto is_same_caps;
  2454   }
  2620   }
       
  2621   acceptfunc = GST_PAD_ACCEPTCAPSFUNC (pad);
  2455   GST_OBJECT_UNLOCK (pad);
  2622   GST_OBJECT_UNLOCK (pad);
  2456 
  2623 
  2457   if (G_LIKELY (acceptfunc)) {
  2624   if (G_LIKELY (acceptfunc)) {
  2458     /* we can call the function */
  2625     /* we can call the function */
  2459     result = acceptfunc (pad, caps);
  2626     result = acceptfunc (pad, caps);
  2501 
  2668 
  2502   peerpad = GST_PAD_PEER (pad);
  2669   peerpad = GST_PAD_PEER (pad);
  2503   if (G_UNLIKELY (peerpad == NULL))
  2670   if (G_UNLIKELY (peerpad == NULL))
  2504     goto no_peer;
  2671     goto no_peer;
  2505 
  2672 
       
  2673   gst_object_ref (peerpad);
       
  2674   /* release lock before calling external methods but keep ref to pad */
       
  2675   GST_OBJECT_UNLOCK (pad);
       
  2676 
  2506   result = gst_pad_accept_caps (peerpad, caps);
  2677   result = gst_pad_accept_caps (peerpad, caps);
  2507   GST_OBJECT_UNLOCK (pad);
  2678 
       
  2679   gst_object_unref (peerpad);
  2508 
  2680 
  2509   return result;
  2681   return result;
  2510 
  2682 
  2511 no_peer:
  2683 no_peer:
  2512   {
  2684   {
  2632 static gboolean
  2804 static gboolean
  2633 gst_pad_configure_src (GstPad * pad, GstCaps * caps, gboolean dosetcaps)
  2805 gst_pad_configure_src (GstPad * pad, GstCaps * caps, gboolean dosetcaps)
  2634 {
  2806 {
  2635   gboolean res;
  2807   gboolean res;
  2636 
  2808 
  2637   /* See if pad accepts the caps */
  2809   if (dosetcaps) {
  2638   if (!gst_pad_accept_caps (pad, caps))
  2810     /* See if pad accepts the caps */
  2639     goto not_accepted;
  2811     if (!gst_pad_accept_caps (pad, caps))
  2640 
  2812       goto not_accepted;
  2641   if (dosetcaps)
  2813 
  2642     res = gst_pad_set_caps (pad, caps);
  2814     res = gst_pad_set_caps (pad, caps);
  2643   else
  2815   } else {
  2644     res = TRUE;
  2816     res = TRUE;
  2645 
  2817   }
  2646   return res;
  2818   return res;
  2647 
  2819 
  2648 not_accepted:
  2820 not_accepted:
  2649   {
  2821   {
  2650     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
  2822     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
  2860    * not possible. */
  3032    * not possible. */
  2861   if (G_LIKELY (bufferallocfunc == NULL))
  3033   if (G_LIKELY (bufferallocfunc == NULL))
  2862     goto fallback;
  3034     goto fallback;
  2863 
  3035 
  2864   ret = bufferallocfunc (pad, offset, size, caps, buf);
  3036   ret = bufferallocfunc (pad, offset, size, caps, buf);
       
  3037 
  2865   if (G_UNLIKELY (ret != GST_FLOW_OK))
  3038   if (G_UNLIKELY (ret != GST_FLOW_OK))
  2866     goto error;
  3039     goto error;
       
  3040 
  2867   /* no error, but NULL buffer means fallback to the default */
  3041   /* no error, but NULL buffer means fallback to the default */
  2868   if (G_UNLIKELY (*buf == NULL))
  3042   if (G_UNLIKELY (*buf == NULL))
  2869     goto fallback;
  3043     goto fallback;
  2870 
  3044 
  2871   /* If the buffer alloc function didn't set up the caps like it should,
  3045   /* If the buffer alloc function didn't set up the caps like it should,
  2893 fallback:
  3067 fallback:
  2894   {
  3068   {
  2895     /* fallback case, allocate a buffer of our own, add pad caps. */
  3069     /* fallback case, allocate a buffer of our own, add pad caps. */
  2896     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "fallback buffer alloc");
  3070     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "fallback buffer alloc");
  2897 
  3071 
  2898     *buf = gst_buffer_new_and_alloc (size);
  3072     if ((*buf = gst_buffer_try_new_and_alloc (size))) {
  2899     GST_BUFFER_OFFSET (*buf) = offset;
  3073       GST_BUFFER_OFFSET (*buf) = offset;
  2900     gst_buffer_set_caps (*buf, caps);
  3074       gst_buffer_set_caps (*buf, caps);
  2901 
  3075       return GST_FLOW_OK;
  2902     return GST_FLOW_OK;
  3076     } else {
  2903   }
  3077       GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
  2904 }
  3078           "out of memory allocating %d bytes", size);
  2905 
  3079       return GST_FLOW_ERROR;
       
  3080     }
       
  3081   }
       
  3082 }
       
  3083 
       
  3084 /* FIXME 0.11: size should be unsigned */
  2906 static GstFlowReturn
  3085 static GstFlowReturn
  2907 gst_pad_alloc_buffer_full (GstPad * pad, guint64 offset, gint size,
  3086 gst_pad_alloc_buffer_full (GstPad * pad, guint64 offset, gint size,
  2908     GstCaps * caps, GstBuffer ** buf, gboolean setcaps)
  3087     GstCaps * caps, GstBuffer ** buf, gboolean setcaps)
  2909 {
  3088 {
  2910   GstPad *peer;
  3089   GstPad *peer;
  2911   GstFlowReturn ret;
  3090   GstFlowReturn ret;
       
  3091   GstCaps *newcaps;
  2912   gboolean caps_changed;
  3092   gboolean caps_changed;
  2913 
  3093 
  2914   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
  3094   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);
  3095   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
  2916   g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
  3096   g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
  2917 
  3097   g_return_val_if_fail (size >= 0, GST_FLOW_ERROR);
  2918   GST_DEBUG_OBJECT (pad, "offset %" G_GUINT64_FORMAT ", size %d", offset, size);
  3098 
       
  3099   GST_DEBUG_OBJECT (pad, "offset %" G_GUINT64_FORMAT ", size %d, caps %"
       
  3100       GST_PTR_FORMAT, offset, size, caps);
  2919 
  3101 
  2920   GST_OBJECT_LOCK (pad);
  3102   GST_OBJECT_LOCK (pad);
  2921   while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
  3103   while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
  2922     if ((ret = handle_pad_block (pad)) != GST_FLOW_OK)
  3104     if ((ret = handle_pad_block (pad)) != GST_FLOW_OK)
  2923       goto flushed;
  3105       goto flushed;
  2933 
  3115 
  2934   if (G_UNLIKELY (ret != GST_FLOW_OK))
  3116   if (G_UNLIKELY (ret != GST_FLOW_OK))
  2935     goto peer_error;
  3117     goto peer_error;
  2936 
  3118 
  2937   /* FIXME, move capnego this into a base class? */
  3119   /* FIXME, move capnego this into a base class? */
  2938   caps = GST_BUFFER_CAPS (*buf);
  3120   newcaps = GST_BUFFER_CAPS (*buf);
  2939 
  3121 
  2940   /* Lock for checking caps, pretty pointless as the _pad_push() function might
  3122   /* 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
  3123    * 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
  3124    * 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. */
  3125    * when there is heavy renegotiation going on in both directions. */
  2944   GST_OBJECT_LOCK (pad);
  3126   GST_OBJECT_LOCK (pad);
  2945   caps_changed = caps && caps != GST_PAD_CAPS (pad);
  3127   caps_changed = newcaps && newcaps != GST_PAD_CAPS (pad);
  2946   GST_OBJECT_UNLOCK (pad);
  3128   GST_OBJECT_UNLOCK (pad);
  2947 
  3129 
  2948   /* we got a new datatype on the pad, see if it can handle it */
  3130   /* we got a new datatype on the pad, see if it can handle it */
  2949   if (G_UNLIKELY (caps_changed)) {
  3131   if (G_UNLIKELY (caps_changed)) {
  2950     GST_DEBUG_OBJECT (pad,
  3132     GST_DEBUG_OBJECT (pad,
  2951         "caps changed from %" GST_PTR_FORMAT " to %p %" GST_PTR_FORMAT,
  3133         "caps changed from %" GST_PTR_FORMAT " to %p %" GST_PTR_FORMAT,
  2952         GST_PAD_CAPS (pad), caps, caps);
  3134         GST_PAD_CAPS (pad), newcaps, newcaps);
  2953     if (G_UNLIKELY (!gst_pad_configure_src (pad, caps, setcaps)))
  3135     if (G_UNLIKELY (!gst_pad_configure_src (pad, newcaps, setcaps)))
  2954       goto not_negotiated;
  3136       goto not_negotiated;
  2955   }
  3137   }
       
  3138 
       
  3139   /* sanity check (only if caps are the same) */
       
  3140   if (G_LIKELY (newcaps == caps) && G_UNLIKELY (GST_BUFFER_SIZE (*buf) < size))
       
  3141     goto wrong_size_fallback;
       
  3142 
  2956   return ret;
  3143   return ret;
  2957 
  3144 
  2958 flushed:
  3145 flushed:
  2959   {
  3146   {
  2960     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "pad block stopped by flush");
  3147     GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "pad block stopped by flush");
  2980     gst_buffer_unref (*buf);
  3167     gst_buffer_unref (*buf);
  2981     *buf = NULL;
  3168     *buf = NULL;
  2982     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  3169     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  2983         "alloc function returned unacceptable buffer");
  3170         "alloc function returned unacceptable buffer");
  2984     return GST_FLOW_NOT_NEGOTIATED;
  3171     return GST_FLOW_NOT_NEGOTIATED;
       
  3172   }
       
  3173 wrong_size_fallback:
       
  3174   {
       
  3175     GST_CAT_ERROR_OBJECT (GST_CAT_PADS, pad, "buffer returned by alloc "
       
  3176         "function is too small (%u < %d), doing fallback buffer alloc",
       
  3177         GST_BUFFER_SIZE (*buf), size);
       
  3178 
       
  3179     gst_buffer_unref (*buf);
       
  3180 
       
  3181     if ((*buf = gst_buffer_try_new_and_alloc (size))) {
       
  3182       GST_BUFFER_OFFSET (*buf) = offset;
       
  3183       gst_buffer_set_caps (*buf, caps);
       
  3184       return GST_FLOW_OK;
       
  3185     } else {
       
  3186       GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
       
  3187           "out of memory allocating %d bytes", size);
       
  3188       return GST_FLOW_ERROR;
       
  3189     }
  2985   }
  3190   }
  2986 }
  3191 }
  2987 
  3192 
  2988 /**
  3193 /**
  2989  * gst_pad_alloc_buffer:
  3194  * gst_pad_alloc_buffer:
  2996  * Allocates a new, empty buffer optimized to push to pad @pad.  This
  3201  * 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.
  3202  * function only works if @pad is a source pad and has a peer.
  2998  *
  3203  *
  2999  * A new, empty #GstBuffer will be put in the @buf argument.
  3204  * A new, empty #GstBuffer will be put in the @buf argument.
  3000  * You need to check the caps of the buffer after performing this
  3205  * You need to check the caps of the buffer after performing this
  3001  * function and renegotiate to the format if needed.
  3206  * function and renegotiate to the format if needed. If the caps changed, it is
       
  3207  * possible that the buffer returned in @buf is not of the right size for the
       
  3208  * new format, @buf needs to be unreffed and reallocated if this is the case.
  3002  *
  3209  *
  3003  * Returns: a result code indicating success of the operation. Any
  3210  * Returns: a result code indicating success of the operation. Any
  3004  * result code other than #GST_FLOW_OK is an error and @buf should
  3211  * result code other than #GST_FLOW_OK is an error and @buf should
  3005  * not be used.
  3212  * not be used.
  3006  * An error can occur if the pad is not connected or when the downstream
  3213  * An error can occur if the pad is not connected or when the downstream
  3007  * peer elements cannot provide an acceptable buffer.
  3214  * peer elements cannot provide an acceptable buffer.
  3008  *
  3215  *
  3009  * MT safe.
  3216  * MT safe.
  3010  */
  3217  */
       
  3218 
       
  3219 /* FIXME 0.11: size should be unsigned */
  3011 #ifdef __SYMBIAN32__
  3220 #ifdef __SYMBIAN32__
  3012 EXPORT_C
  3221 EXPORT_C
  3013 #endif
  3222 #endif
  3014 
  3223 
  3015 GstFlowReturn
  3224 GstFlowReturn
  3029  *
  3238  *
  3030  * In addition to the function gst_pad_alloc_buffer(), this function
  3239  * In addition to the function gst_pad_alloc_buffer(), this function
  3031  * automatically calls gst_pad_set_caps() when the caps of the
  3240  * automatically calls gst_pad_set_caps() when the caps of the
  3032  * newly allocated buffer are different from the @pad caps.
  3241  * newly allocated buffer are different from the @pad caps.
  3033  *
  3242  *
       
  3243  * After a renegotiation, the size of the new buffer returned in @buf could
       
  3244  * be of the wrong size for the new format and must be unreffed an reallocated
       
  3245  * in that case.
       
  3246  *
  3034  * Returns: a result code indicating success of the operation. Any
  3247  * Returns: a result code indicating success of the operation. Any
  3035  * result code other than #GST_FLOW_OK is an error and @buf should
  3248  * result code other than #GST_FLOW_OK is an error and @buf should
  3036  * not be used.
  3249  * not be used.
  3037  * An error can occur if the pad is not connected or when the downstream
  3250  * An error can occur if the pad is not connected or when the downstream
  3038  * peer elements cannot provide an acceptable buffer.
  3251  * peer elements cannot provide an acceptable buffer.
  3039  *
  3252  *
  3040  * MT safe.
  3253  * MT safe.
  3041  */
  3254  */
       
  3255 
       
  3256 /* FIXME 0.11: size should be unsigned */
  3042 #ifdef __SYMBIAN32__
  3257 #ifdef __SYMBIAN32__
  3043 EXPORT_C
  3258 EXPORT_C
  3044 #endif
  3259 #endif
  3045 
  3260 
  3046 GstFlowReturn
  3261 GstFlowReturn
  3047 gst_pad_alloc_buffer_and_set_caps (GstPad * pad, guint64 offset, gint size,
  3262 gst_pad_alloc_buffer_and_set_caps (GstPad * pad, guint64 offset, gint size,
  3048     GstCaps * caps, GstBuffer ** buf)
  3263     GstCaps * caps, GstBuffer ** buf)
  3049 {
  3264 {
  3050   return gst_pad_alloc_buffer_full (pad, offset, size, caps, buf, TRUE);
  3265   return gst_pad_alloc_buffer_full (pad, offset, size, caps, buf, TRUE);
  3051 }
  3266 }
       
  3267 
       
  3268 
       
  3269 #ifndef GST_REMOVE_DEPRECATED
       
  3270 typedef struct
       
  3271 {
       
  3272   GList *list;
       
  3273   guint32 cookie;
       
  3274 } IntLinkIterData;
       
  3275 
       
  3276 static void
       
  3277 int_link_iter_data_free (IntLinkIterData * data)
       
  3278 {
       
  3279   g_list_free (data->list);
       
  3280   g_free (data);
       
  3281 }
       
  3282 #endif
       
  3283 
       
  3284 static GstIteratorItem
       
  3285 iterate_pad (GstIterator * it, GstPad * pad)
       
  3286 {
       
  3287   gst_object_ref (pad);
       
  3288   return GST_ITERATOR_ITEM_PASS;
       
  3289 }
       
  3290 
       
  3291 /**
       
  3292  * gst_pad_iterate_internal_links_default:
       
  3293  * @pad: the #GstPad to get the internal links of.
       
  3294  *
       
  3295  * Iterate the list of pads to which the given pad is linked to inside of
       
  3296  * the parent element.
       
  3297  * This is the default handler, and thus returns an iterator of all of the
       
  3298  * pads inside the parent element with opposite direction.
       
  3299  *
       
  3300  * The caller must free this iterator after use with gst_iterator_free().
       
  3301  *
       
  3302  * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
       
  3303  * returned pad with gst_object_unref().
       
  3304  *
       
  3305  * Since: 0.10.21
       
  3306  */
       
  3307 #ifdef __SYMBIAN32__
       
  3308 EXPORT_C
       
  3309 #endif
       
  3310 
       
  3311 GstIterator *
       
  3312 gst_pad_iterate_internal_links_default (GstPad * pad)
       
  3313 {
       
  3314   GstIterator *res;
       
  3315   GList **padlist;
       
  3316   guint32 *cookie;
       
  3317   GMutex *lock;
       
  3318   gpointer owner;
       
  3319   GstIteratorDisposeFunction dispose;
       
  3320 
       
  3321   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  3322 
       
  3323 #ifndef GST_REMOVE_DEPRECATED
       
  3324   /* when we get here, the default handler for the iterate links is called,
       
  3325    * which means that the user has not installed a custom one. We first check if
       
  3326    * there is maybe a custom legacy function we can call. */
       
  3327   if (GST_PAD_INTLINKFUNC (pad) &&
       
  3328       GST_PAD_INTLINKFUNC (pad) != gst_pad_get_internal_links_default) {
       
  3329     IntLinkIterData *data;
       
  3330 
       
  3331     /* make an iterator for the list. We can't protect the list with a
       
  3332      * cookie. If we would take the cookie of the parent element, we need to
       
  3333      * have a parent, which is not required for GST_PAD_INTLINKFUNC(). We could
       
  3334      * cache the per-pad list and invalidate the list when a new call to
       
  3335      * INTLINKFUNC() returned a different list but then this would only work if
       
  3336      * two concurrent iterators were used and the last iterator would still be
       
  3337      * thread-unsafe. Just don't use this method anymore. */
       
  3338     data = g_new0 (IntLinkIterData, 1);
       
  3339     data->list = GST_PAD_INTLINKFUNC (pad) (pad);
       
  3340     data->cookie = 0;
       
  3341 
       
  3342     GST_WARNING_OBJECT (pad, "Making unsafe iterator");
       
  3343 
       
  3344     cookie = &data->cookie;
       
  3345     padlist = &data->list;
       
  3346     owner = data;
       
  3347     dispose = (GstIteratorDisposeFunction) int_link_iter_data_free;
       
  3348     /* reuse the pad lock, it's all we have here */
       
  3349     lock = GST_OBJECT_GET_LOCK (pad);
       
  3350   } else
       
  3351 #endif
       
  3352   {
       
  3353     GstElement *parent;
       
  3354 
       
  3355     GST_OBJECT_LOCK (pad);
       
  3356     parent = GST_PAD_PARENT (pad);
       
  3357     if (!parent || !GST_IS_ELEMENT (parent))
       
  3358       goto no_parent;
       
  3359 
       
  3360     gst_object_ref (parent);
       
  3361     GST_OBJECT_UNLOCK (pad);
       
  3362 
       
  3363     if (pad->direction == GST_PAD_SRC)
       
  3364       padlist = &parent->sinkpads;
       
  3365     else
       
  3366       padlist = &parent->srcpads;
       
  3367 
       
  3368     GST_DEBUG_OBJECT (pad, "Making iterator");
       
  3369 
       
  3370     cookie = &parent->pads_cookie;
       
  3371     owner = parent;
       
  3372     dispose = (GstIteratorDisposeFunction) gst_object_unref;
       
  3373     lock = GST_OBJECT_GET_LOCK (parent);
       
  3374   }
       
  3375 
       
  3376   res = gst_iterator_new_list (GST_TYPE_PAD,
       
  3377       lock, cookie, padlist, owner, (GstIteratorItemFunction) iterate_pad,
       
  3378       dispose);
       
  3379 
       
  3380   return res;
       
  3381 
       
  3382   /* ERRORS */
       
  3383 no_parent:
       
  3384   {
       
  3385     GST_OBJECT_UNLOCK (pad);
       
  3386     GST_DEBUG_OBJECT (pad, "no parent element");
       
  3387     return NULL;
       
  3388   }
       
  3389 }
       
  3390 
       
  3391 /**
       
  3392  * gst_pad_iterate_internal_links:
       
  3393  * @pad: the GstPad to get the internal links of.
       
  3394  *
       
  3395  * Gets an iterator for the pads to which the given pad is linked to inside
       
  3396  * of the parent element.
       
  3397  *
       
  3398  * Each #GstPad element yielded by the iterator will have its refcount increased,
       
  3399  * so unref after use.
       
  3400  *
       
  3401  * Returns: a new #GstIterator of #GstPad or %NULL when the pad does not have an
       
  3402  * iterator function configured. Use gst_iterator_free() after usage.
       
  3403  *
       
  3404  * Since: 0.10.21
       
  3405  */
       
  3406 #ifdef __SYMBIAN32__
       
  3407 EXPORT_C
       
  3408 #endif
       
  3409 
       
  3410 GstIterator *
       
  3411 gst_pad_iterate_internal_links (GstPad * pad)
       
  3412 {
       
  3413   GstIterator *res = NULL;
       
  3414 
       
  3415   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
       
  3416 
       
  3417   if (GST_PAD_ITERINTLINKFUNC (pad))
       
  3418     res = GST_PAD_ITERINTLINKFUNC (pad) (pad);
       
  3419 
       
  3420   return res;
       
  3421 }
       
  3422 
       
  3423 #ifndef GST_REMOVE_DEPRECATED
       
  3424 static void
       
  3425 add_unref_pad_to_list (GstPad * pad, GList * list)
       
  3426 {
       
  3427   list = g_list_prepend (list, pad);
       
  3428   gst_object_unref (pad);
       
  3429 }
       
  3430 #endif
  3052 
  3431 
  3053 /**
  3432 /**
  3054  * gst_pad_get_internal_links_default:
  3433  * gst_pad_get_internal_links_default:
  3055  * @pad: the #GstPad to get the internal links of.
  3434  * @pad: the #GstPad to get the internal links of.
  3056  *
  3435  *
  3057  * Gets a list of pads to which the given pad is linked to
  3436  * Gets a list of pads to which the given pad is linked to
  3058  * inside of the parent element.
  3437  * inside of the parent element.
  3059  * This is the default handler, and thus returns a list of all of the
  3438  * This is the default handler, and thus returns a list of all of the
  3060  * pads inside the parent element with opposite direction.
  3439  * pads inside the parent element with opposite direction.
  3061  * The caller must free this list after use.
  3440  *
       
  3441  * The caller must free this list after use with g_list_free().
  3062  *
  3442  *
  3063  * Returns: a newly allocated #GList of pads, or NULL if the pad has no parent.
  3443  * Returns: a newly allocated #GList of pads, or NULL if the pad has no parent.
  3064  *
  3444  *
  3065  * Not MT safe.
  3445  * Not MT safe.
  3066  */
  3446  *
  3067 #ifdef __SYMBIAN32__
  3447  * Deprecated: This function does not ref the pads in the list so that they
  3068 EXPORT_C
  3448  * could become invalid by the time the application accesses them. It's also
  3069 #endif
  3449  * possible that the list changes while handling the pads, which the caller of
  3070 
  3450  * this function is unable to know. Use the thread-safe 
       
  3451  * gst_pad_iterate_internal_links_default() instead.
       
  3452  */
       
  3453 #ifndef GST_REMOVE_DEPRECATED
       
  3454 #ifdef __SYMBIAN32__
       
  3455 EXPORT_C
       
  3456 #endif
  3071 GList *
  3457 GList *
  3072 gst_pad_get_internal_links_default (GstPad * pad)
  3458 gst_pad_get_internal_links_default (GstPad * pad)
  3073 {
  3459 {
  3074   GList *res = NULL;
  3460   GList *res = NULL;
  3075   GstElement *parent;
  3461   GstElement *parent;
  3076   GList *parent_pads;
       
  3077   GstPadDirection direction;
       
  3078 
  3462 
  3079   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
  3463   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
  3080 
  3464 
  3081   direction = pad->direction;
  3465   GST_WARNING_OBJECT (pad, "Unsafe internal links used");
  3082 
  3466 
  3083   parent = GST_PAD_PARENT (pad);
  3467   /* when we get here, the default handler for get_internal_links is called,
  3084   if (!parent)
  3468    * which means that the user has not installed a custom one. We first check if
  3085     goto no_parent;
  3469    * there is maybe a custom iterate function we can call. */
  3086 
  3470   if (GST_PAD_ITERINTLINKFUNC (pad) &&
  3087   parent_pads = parent->pads;
  3471       GST_PAD_ITERINTLINKFUNC (pad) != gst_pad_iterate_internal_links_default) {
  3088 
  3472     GstIterator *it;
  3089   while (parent_pads) {
  3473     GstIteratorResult ires;
  3090     GstPad *parent_pad = GST_PAD_CAST (parent_pads->data);
  3474     gboolean done = FALSE;
  3091 
  3475 
  3092     if (parent_pad->direction != direction) {
  3476     it = gst_pad_iterate_internal_links (pad);
  3093       GST_DEBUG_OBJECT (pad, "adding pad %s:%s",
  3477     /* loop over the iterator and put all elements into a list, we also
  3094           GST_DEBUG_PAD_NAME (parent_pad));
  3478      * immediatly unref them, which is bad. */
  3095       res = g_list_prepend (res, parent_pad);
  3479     do {
  3096     }
  3480       ires = gst_iterator_foreach (it, (GFunc) add_unref_pad_to_list, res);
  3097     parent_pads = g_list_next (parent_pads);
  3481       switch (ires) {
  3098   }
  3482         case GST_ITERATOR_OK:
       
  3483         case GST_ITERATOR_DONE:
       
  3484         case GST_ITERATOR_ERROR:
       
  3485           done = TRUE;
       
  3486           break;
       
  3487         case GST_ITERATOR_RESYNC:
       
  3488           /* restart, discard previous list */
       
  3489           gst_iterator_resync (it);
       
  3490           g_list_free (res);
       
  3491           res = NULL;
       
  3492           break;
       
  3493       }
       
  3494     } while (!done);
       
  3495 
       
  3496     gst_iterator_free (it);
       
  3497   } else {
       
  3498     /* lock pad, check and ref parent */
       
  3499     GST_OBJECT_LOCK (pad);
       
  3500     parent = GST_PAD_PARENT (pad);
       
  3501     if (!parent || !GST_IS_ELEMENT (parent))
       
  3502       goto no_parent;
       
  3503 
       
  3504     parent = gst_object_ref (parent);
       
  3505     GST_OBJECT_UNLOCK (pad);
       
  3506 
       
  3507     /* now lock the parent while we copy the pads */
       
  3508     GST_OBJECT_LOCK (parent);
       
  3509     if (pad->direction == GST_PAD_SRC)
       
  3510       res = g_list_copy (parent->sinkpads);
       
  3511     else
       
  3512       res = g_list_copy (parent->srcpads);
       
  3513     GST_OBJECT_UNLOCK (parent);
       
  3514 
       
  3515     gst_object_unref (parent);
       
  3516   }
       
  3517 
       
  3518   /* At this point pads can be changed and unreffed. Nothing we can do about it
       
  3519    * because for compatibility reasons this function cannot ref the pads or
       
  3520    * notify the app that the list changed. */
       
  3521 
  3099   return res;
  3522   return res;
  3100 
  3523 
  3101 no_parent:
  3524 no_parent:
  3102   {
  3525   {
  3103     GST_DEBUG_OBJECT (pad, "no parent");
  3526     GST_DEBUG_OBJECT (pad, "no parent");
       
  3527     GST_OBJECT_UNLOCK (pad);
  3104     return NULL;
  3528     return NULL;
  3105   }
  3529   }
  3106 }
  3530 }
       
  3531 #endif /* GST_REMOVE_DEPRECATED */
  3107 
  3532 
  3108 /**
  3533 /**
  3109  * gst_pad_get_internal_links:
  3534  * gst_pad_get_internal_links:
  3110  * @pad: the #GstPad to get the internal links of.
  3535  * @pad: the #GstPad to get the internal links of.
  3111  *
  3536  *
  3112  * Gets a list of pads to which the given pad is linked to
  3537  * Gets a list of pads to which the given pad is linked to
  3113  * inside of the parent element.
  3538  * inside of the parent element.
  3114  * The caller must free this list after use.
  3539  * The caller must free this list after use.
  3115  *
  3540  *
  3116  * Returns: a newly allocated #GList of pads.
       
  3117  *
       
  3118  * Not MT safe.
  3541  * Not MT safe.
  3119  */
  3542  *
  3120 #ifdef __SYMBIAN32__
  3543  * Returns: a newly allocated #GList of pads, free with g_list_free().
  3121 EXPORT_C
  3544  * 
  3122 #endif
  3545  * Deprecated: This function does not ref the pads in the list so that they
  3123 
  3546  * could become invalid by the time the application accesses them. It's also
       
  3547  * possible that the list changes while handling the pads, which the caller of
       
  3548  * this function is unable to know. Use the thread-safe 
       
  3549  * gst_pad_iterate_internal_links() instead.
       
  3550  */
       
  3551 #ifndef GST_REMOVE_DEPRECATED
       
  3552 #ifdef __SYMBIAN32__
       
  3553 EXPORT_C
       
  3554 #endif
  3124 GList *
  3555 GList *
  3125 gst_pad_get_internal_links (GstPad * pad)
  3556 gst_pad_get_internal_links (GstPad * pad)
  3126 {
  3557 {
  3127   GList *res = NULL;
  3558   GList *res = NULL;
  3128 
  3559 
  3129   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
  3560   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
  3130 
  3561 
       
  3562   GST_WARNING_OBJECT (pad, "Calling unsafe internal links");
       
  3563 
  3131   if (GST_PAD_INTLINKFUNC (pad))
  3564   if (GST_PAD_INTLINKFUNC (pad))
  3132     res = GST_PAD_INTLINKFUNC (pad) (pad);
  3565     res = GST_PAD_INTLINKFUNC (pad) (pad);
  3133 
  3566 
  3134   return res;
  3567   return res;
  3135 }
  3568 }
  3136 
  3569 #endif /* GST_REMOVE_DEPRECATED */
  3137 
  3570 
  3138 static gboolean
  3571 static gboolean
  3139 gst_pad_event_default_dispatch (GstPad * pad, GstEvent * event)
  3572 gst_pad_event_default_dispatch (GstPad * pad, GstEvent * event)
  3140 {
  3573 {
  3141   GList *orig, *pads;
  3574   gboolean result = FALSE;
  3142   gboolean result;
  3575   GstIterator *iter;
       
  3576   gboolean done = FALSE;
       
  3577   gpointer item;
       
  3578   GstPad *eventpad;
       
  3579   GList *pushed_pads = NULL;
  3143 
  3580 
  3144   GST_INFO_OBJECT (pad, "Sending event %p (%s) to all internally linked pads",
  3581   GST_INFO_OBJECT (pad, "Sending event %p (%s) to all internally linked pads",
  3145       event, GST_EVENT_TYPE_NAME (event));
  3582       event, GST_EVENT_TYPE_NAME (event));
  3146 
  3583 
  3147   result = (GST_PAD_DIRECTION (pad) == GST_PAD_SINK);
  3584   iter = gst_pad_iterate_internal_links (pad);
  3148 
  3585 
  3149   orig = pads = gst_pad_get_internal_links (pad);
  3586   if (!iter)
  3150 
  3587     goto no_iter;
  3151   while (pads) {
  3588 
  3152     GstPad *eventpad = GST_PAD_CAST (pads->data);
  3589   while (!done) {
  3153 
  3590     switch (gst_iterator_next (iter, &item)) {
  3154     pads = g_list_next (pads);
  3591       case GST_ITERATOR_OK:
  3155 
  3592         eventpad = GST_PAD (item);
  3156     if (GST_PAD_DIRECTION (eventpad) == GST_PAD_SRC) {
  3593 
  3157       /* for each pad we send to, we should ref the event; it's up
  3594         /* if already pushed,  skip */
  3158        * to downstream to unref again when handled. */
  3595         if (g_list_find (pushed_pads, eventpad)) {
  3159       GST_LOG_OBJECT (pad, "Reffing and sending event %p (%s) to %s:%s",
  3596           gst_object_unref (item);
  3160           event, GST_EVENT_TYPE_NAME (event), GST_DEBUG_PAD_NAME (eventpad));
  3597           break;
  3161       gst_event_ref (event);
  3598         }
  3162       gst_pad_push_event (eventpad, event);
  3599 
  3163     } else {
  3600         if (GST_PAD_IS_SRC (eventpad)) {
  3164       /* we only send the event on one pad, multi-sinkpad elements
  3601           /* for each pad we send to, we should ref the event; it's up
  3165        * should implement a handler */
  3602            * to downstream to unref again when handled. */
  3166       GST_LOG_OBJECT (pad, "sending event %p (%s) to one sink pad %s:%s",
  3603           GST_LOG_OBJECT (pad, "Reffing and sending event %p (%s) to %s:%s",
  3167           event, GST_EVENT_TYPE_NAME (event), GST_DEBUG_PAD_NAME (eventpad));
  3604               event, GST_EVENT_TYPE_NAME (event),
  3168       result = gst_pad_push_event (eventpad, event);
  3605               GST_DEBUG_PAD_NAME (eventpad));
  3169       goto done;
  3606           gst_event_ref (event);
       
  3607           result |= gst_pad_push_event (eventpad, event);
       
  3608         } else {
       
  3609           /* we only send the event on one pad, multi-sinkpad elements
       
  3610            * should implement a handler */
       
  3611           GST_LOG_OBJECT (pad, "sending event %p (%s) to one sink pad %s:%s",
       
  3612               event, GST_EVENT_TYPE_NAME (event),
       
  3613               GST_DEBUG_PAD_NAME (eventpad));
       
  3614           result = gst_pad_push_event (eventpad, event);
       
  3615           done = TRUE;
       
  3616           event = NULL;
       
  3617         }
       
  3618 
       
  3619         pushed_pads = g_list_prepend (pushed_pads, eventpad);
       
  3620 
       
  3621         gst_object_unref (item);
       
  3622         break;
       
  3623       case GST_ITERATOR_RESYNC:
       
  3624         /* FIXME, if we want to reset the result value we need to remember which
       
  3625          * pads pushed with which result */
       
  3626         gst_iterator_resync (iter);
       
  3627         break;
       
  3628       case GST_ITERATOR_ERROR:
       
  3629         GST_ERROR_OBJECT (pad, "Could not iterate over internally linked pads");
       
  3630         done = TRUE;
       
  3631         break;
       
  3632       case GST_ITERATOR_DONE:
       
  3633         done = TRUE;
       
  3634         break;
  3170     }
  3635     }
  3171   }
  3636   }
       
  3637   gst_iterator_free (iter);
       
  3638 
       
  3639 no_iter:
       
  3640 
       
  3641   /* If this is a sinkpad and we don't have pads to send the event to, we
       
  3642    * return TRUE. This is so that when using the default handler on a sink
       
  3643    * element, we don't fail to push it. */
       
  3644   if (!pushed_pads)
       
  3645     result = GST_PAD_IS_SINK (pad);
       
  3646 
       
  3647   g_list_free (pushed_pads);
       
  3648 
  3172   /* we handled the incoming event so we unref once */
  3649   /* we handled the incoming event so we unref once */
  3173   GST_LOG_OBJECT (pad, "handled event %p, unreffing", event);
  3650   if (event) {
  3174   gst_event_unref (event);
  3651     GST_LOG_OBJECT (pad, "handled event %p, unreffing", event);
  3175 
  3652     gst_event_unref (event);
  3176 done:
  3653   }
  3177   g_list_free (orig);
       
  3178 
  3654 
  3179   return result;
  3655   return result;
  3180 }
  3656 }
  3181 
  3657 
  3182 /**
  3658 /**
  3199 gboolean
  3675 gboolean
  3200 gst_pad_event_default (GstPad * pad, GstEvent * event)
  3676 gst_pad_event_default (GstPad * pad, GstEvent * event)
  3201 {
  3677 {
  3202   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  3678   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  3203   g_return_val_if_fail (event != NULL, FALSE);
  3679   g_return_val_if_fail (event != NULL, FALSE);
       
  3680 
       
  3681   GST_LOG_OBJECT (pad, "default event handler");
  3204 
  3682 
  3205   switch (GST_EVENT_TYPE (event)) {
  3683   switch (GST_EVENT_TYPE (event)) {
  3206     case GST_EVENT_EOS:
  3684     case GST_EVENT_EOS:
  3207     {
  3685     {
  3208       GST_DEBUG_OBJECT (pad, "pausing task because of eos");
  3686       GST_DEBUG_OBJECT (pad, "pausing task because of eos");
  3236 gboolean
  3714 gboolean
  3237 gst_pad_dispatcher (GstPad * pad, GstPadDispatcherFunction dispatch,
  3715 gst_pad_dispatcher (GstPad * pad, GstPadDispatcherFunction dispatch,
  3238     gpointer data)
  3716     gpointer data)
  3239 {
  3717 {
  3240   gboolean res = FALSE;
  3718   gboolean res = FALSE;
  3241   GList *int_pads, *orig;
  3719   GstIterator *iter = NULL;
       
  3720   gboolean done = FALSE;
       
  3721   gpointer item;
  3242 
  3722 
  3243   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  3723   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  3244   g_return_val_if_fail (dispatch != NULL, FALSE);
  3724   g_return_val_if_fail (dispatch != NULL, FALSE);
  3245 
  3725 
  3246   orig = int_pads = gst_pad_get_internal_links (pad);
  3726   iter = gst_pad_iterate_internal_links (pad);
  3247 
  3727 
  3248   while (int_pads) {
  3728   if (!iter)
  3249     GstPad *int_pad = GST_PAD_CAST (int_pads->data);
  3729     goto no_iter;
  3250     GstPad *int_peer = gst_pad_get_peer (int_pad);
  3730 
  3251 
  3731   while (!done) {
  3252     if (int_peer) {
  3732     switch (gst_iterator_next (iter, &item)) {
  3253       GST_DEBUG_OBJECT (int_pad, "dispatching to peer %s:%s",
  3733       case GST_ITERATOR_OK:
  3254           GST_DEBUG_PAD_NAME (int_peer));
  3734       {
  3255       res = dispatch (int_peer, data);
  3735         GstPad *int_pad = GST_PAD_CAST (item);
  3256       gst_object_unref (int_peer);
  3736         GstPad *int_peer = gst_pad_get_peer (int_pad);
  3257       if (res)
  3737 
       
  3738         if (int_peer) {
       
  3739           GST_DEBUG_OBJECT (int_pad, "dispatching to peer %s:%s",
       
  3740               GST_DEBUG_PAD_NAME (int_peer));
       
  3741           done = res = dispatch (int_peer, data);
       
  3742           gst_object_unref (int_peer);
       
  3743         } else {
       
  3744           GST_DEBUG_OBJECT (int_pad, "no peer");
       
  3745         }
       
  3746       }
       
  3747         gst_object_unref (item);
  3258         break;
  3748         break;
  3259     } else {
  3749       case GST_ITERATOR_RESYNC:
  3260       GST_DEBUG_OBJECT (int_pad, "no peer");
  3750         gst_iterator_resync (iter);
       
  3751         break;
       
  3752       case GST_ITERATOR_ERROR:
       
  3753         done = TRUE;
       
  3754         GST_ERROR_OBJECT (pad, "Could not iterate internally linked pads");
       
  3755         break;
       
  3756       case GST_ITERATOR_DONE:
       
  3757         done = TRUE;
       
  3758         break;
  3261     }
  3759     }
  3262     int_pads = g_list_next (int_pads);
  3760   }
  3263   }
  3761   gst_iterator_free (iter);
  3264   g_list_free (orig);
  3762 
  3265   GST_DEBUG_OBJECT (pad, "done, result %d", res);
  3763   GST_DEBUG_OBJECT (pad, "done, result %d", res);
       
  3764 
       
  3765 no_iter:
  3266 
  3766 
  3267   return res;
  3767   return res;
  3268 }
  3768 }
  3269 
  3769 
  3270 /**
  3770 /**
  3409 void
  3909 void
  3410 gst_pad_load_and_link (xmlNodePtr self, GstObject * parent)
  3910 gst_pad_load_and_link (xmlNodePtr self, GstObject * parent)
  3411 {
  3911 {
  3412   xmlNodePtr field = self->xmlChildrenNode;
  3912   xmlNodePtr field = self->xmlChildrenNode;
  3413   GstPad *pad = NULL, *targetpad;
  3913   GstPad *pad = NULL, *targetpad;
       
  3914   GstPadTemplate *tmpl;
  3414   gchar *peer = NULL;
  3915   gchar *peer = NULL;
  3415   gchar **split;
  3916   gchar **split;
  3416   GstElement *target;
  3917   GstElement *target;
  3417   GstObject *grandparent;
  3918   GstObject *grandparent;
  3418   gchar *name = NULL;
  3919   gchar *name = NULL;
  3419 
  3920 
  3420   while (field) {
  3921   while (field) {
  3421     if (!strcmp ((char *) field->name, "name")) {
  3922     if (!strcmp ((char *) field->name, "name")) {
  3422       name = (gchar *) xmlNodeGetContent (field);
  3923       name = (gchar *) xmlNodeGetContent (field);
  3423       pad = gst_element_get_pad (GST_ELEMENT (parent), name);
  3924       pad = gst_element_get_static_pad (GST_ELEMENT (parent), name);
       
  3925       if ((!pad) || ((tmpl = gst_pad_get_pad_template (pad))
       
  3926               && (GST_PAD_REQUEST == GST_PAD_TEMPLATE_PRESENCE (tmpl))))
       
  3927         pad = gst_element_get_request_pad (GST_ELEMENT (parent), name);
  3424       g_free (name);
  3928       g_free (name);
  3425     } else if (!strcmp ((char *) field->name, "peer")) {
  3929     } else if (!strcmp ((char *) field->name, "peer")) {
  3426       peer = (gchar *) xmlNodeGetContent (field);
  3930       peer = (gchar *) xmlNodeGetContent (field);
  3427     }
  3931     }
  3428     field = field->next;
  3932     field = field->next;
  3454     goto cleanup;
  3958     goto cleanup;
  3455 
  3959 
  3456   if (target == NULL)
  3960   if (target == NULL)
  3457     goto cleanup;
  3961     goto cleanup;
  3458 
  3962 
  3459   targetpad = gst_element_get_pad (target, split[1]);
  3963   targetpad = gst_element_get_static_pad (target, split[1]);
       
  3964   if (!pad)
       
  3965     targetpad = gst_element_get_request_pad (target, split[1]);
  3460 
  3966 
  3461   if (targetpad == NULL)
  3967   if (targetpad == NULL)
  3462     goto cleanup;
  3968     goto cleanup;
  3463 
  3969 
  3464   gst_pad_link (pad, targetpad);
  3970   if (gst_pad_get_direction (pad) == GST_PAD_SRC)
       
  3971     gst_pad_link (pad, targetpad);
       
  3972   else
       
  3973     gst_pad_link (targetpad, pad);
  3465 
  3974 
  3466 cleanup:
  3975 cleanup:
  3467   g_strfreev (split);
  3976   g_strfreev (split);
  3468 }
  3977 }
  3469 
  3978 
  3591    * the callback, which is in the end totally impossible as it
  4100    * the callback, which is in the end totally impossible as it
  3592    * requires grabbing the STREAM_LOCK and OBJECT_LOCK which are
  4101    * requires grabbing the STREAM_LOCK and OBJECT_LOCK which are
  3593    * all taken when calling this function. */
  4102    * all taken when calling this function. */
  3594   gst_object_ref (pad);
  4103   gst_object_ref (pad);
  3595 
  4104 
  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)) {
  4105   while (GST_PAD_IS_BLOCKED (pad)) {
       
  4106     do {
       
  4107       /* we either have a callback installed to notify the block or
       
  4108        * some other thread is doing a GCond wait. */
       
  4109       callback = pad->block_callback;
       
  4110       pad->abidata.ABI.block_callback_called = TRUE;
       
  4111       if (callback) {
       
  4112         /* there is a callback installed, call it. We release the
       
  4113          * lock so that the callback can do something usefull with the
       
  4114          * pad */
       
  4115         user_data = pad->block_data;
       
  4116         GST_OBJECT_UNLOCK (pad);
       
  4117         callback (pad, TRUE, user_data);
       
  4118         GST_OBJECT_LOCK (pad);
       
  4119 
       
  4120         /* we released the lock, recheck flushing */
       
  4121         if (GST_PAD_IS_FLUSHING (pad))
       
  4122           goto flushing;
       
  4123       } else {
       
  4124         /* no callback, signal the thread that is doing a GCond wait
       
  4125          * if any. */
       
  4126         GST_PAD_BLOCK_BROADCAST (pad);
       
  4127       }
       
  4128     } while (pad->abidata.ABI.block_callback_called == FALSE
       
  4129         && GST_PAD_IS_BLOCKED (pad));
       
  4130 
       
  4131     /* OBJECT_LOCK could have been released when we did the callback, which
       
  4132      * then could have made the pad unblock so we need to check the blocking
       
  4133      * condition again.   */
       
  4134     if (!GST_PAD_IS_BLOCKED (pad))
       
  4135       break;
       
  4136 
  3621     /* now we block the streaming thread. It can be unlocked when we
  4137     /* now we block the streaming thread. It can be unlocked when we
  3622      * deactivate the pad (which will also set the FLUSHING flag) or
  4138      * deactivate the pad (which will also set the FLUSHING flag) or
  3623      * when the pad is unblocked. A flushing event will also unblock
  4139      * when the pad is unblocked. A flushing event will also unblock
  3624      * the pad after setting the FLUSHING flag. */
  4140      * the pad after setting the FLUSHING flag. */
  3625     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  4141     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  3701   g_value_unset (&args[1]);
  4217   g_value_unset (&args[1]);
  3702 
  4218 
  3703   return res;
  4219   return res;
  3704 }
  4220 }
  3705 
  4221 
       
  4222 static void
       
  4223 gst_pad_data_unref (gboolean is_buffer, void *data)
       
  4224 {
       
  4225   if (G_LIKELY (is_buffer)) {
       
  4226     gst_buffer_unref (data);
       
  4227   } else {
       
  4228     gst_buffer_list_unref (data);
       
  4229   }
       
  4230 }
       
  4231 
       
  4232 static GstCaps *
       
  4233 gst_pad_data_get_caps (gboolean is_buffer, void *data)
       
  4234 {
       
  4235   GstCaps *caps;
       
  4236 
       
  4237   if (G_LIKELY (is_buffer)) {
       
  4238     caps = GST_BUFFER_CAPS (data);
       
  4239   } else {
       
  4240     GstBuffer *buf;
       
  4241 
       
  4242     if ((buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (data), 0, 0)))
       
  4243       caps = GST_BUFFER_CAPS (buf);
       
  4244     else
       
  4245       caps = NULL;
       
  4246   }
       
  4247   return caps;
       
  4248 }
       
  4249 
  3706 /* this is the chain function that does not perform the additional argument
  4250 /* this is the chain function that does not perform the additional argument
  3707  * checking for that little extra speed.
  4251  * checking for that little extra speed.
  3708  */
  4252  */
  3709 static inline GstFlowReturn
  4253 static inline GstFlowReturn
  3710 gst_pad_chain_unchecked (GstPad * pad, GstBuffer * buffer)
  4254 gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data)
  3711 {
  4255 {
  3712   GstCaps *caps;
  4256   GstCaps *caps;
  3713   gboolean caps_changed;
  4257   gboolean caps_changed;
  3714   GstPadChainFunction chainfunc;
       
  3715   GstFlowReturn ret;
  4258   GstFlowReturn ret;
  3716   gboolean emit_signal;
  4259   gboolean emit_signal;
  3717 
  4260 
  3718   GST_PAD_STREAM_LOCK (pad);
  4261   GST_PAD_STREAM_LOCK (pad);
  3719 
  4262 
  3720   GST_OBJECT_LOCK (pad);
  4263   GST_OBJECT_LOCK (pad);
  3721   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
  4264   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
  3722     goto flushing;
  4265     goto flushing;
  3723 
  4266 
  3724   caps = GST_BUFFER_CAPS (buffer);
  4267   caps = gst_pad_data_get_caps (is_buffer, data);
  3725   caps_changed = caps && caps != GST_PAD_CAPS (pad);
  4268   caps_changed = caps && caps != GST_PAD_CAPS (pad);
  3726 
  4269 
  3727   emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
  4270   emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
  3728   GST_OBJECT_UNLOCK (pad);
  4271   GST_OBJECT_UNLOCK (pad);
  3729 
  4272 
  3730   /* see if the signal should be emited, we emit before caps nego as
  4273   /* see if the signal should be emited, we emit before caps nego as
  3731    * we might drop the buffer and do capsnego for nothing. */
  4274    * we might drop the buffer and do capsnego for nothing. */
  3732   if (G_UNLIKELY (emit_signal)) {
  4275   if (G_UNLIKELY (emit_signal)) {
  3733     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (buffer)))
  4276     if (G_LIKELY (is_buffer)) {
  3734       goto dropping;
  4277       if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (data)))
       
  4278         goto dropping;
       
  4279     } else {
       
  4280       /* chain all groups in the buffer list one by one to avoid problems with
       
  4281        * buffer probes that push buffers or events */
       
  4282       goto chain_groups;
       
  4283     }
  3735   }
  4284   }
  3736 
  4285 
  3737   /* we got a new datatype on the pad, see if it can handle it */
  4286   /* we got a new datatype on the pad, see if it can handle it */
  3738   if (G_UNLIKELY (caps_changed)) {
  4287   if (G_UNLIKELY (caps_changed)) {
  3739     GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
  4288     GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
  3744   /* NOTE: we read the chainfunc unlocked.
  4293   /* NOTE: we read the chainfunc unlocked.
  3745    * we cannot hold the lock for the pad so we might send
  4294    * we cannot hold the lock for the pad so we might send
  3746    * the data to the wrong function. This is not really a
  4295    * the data to the wrong function. This is not really a
  3747    * problem since functions are assigned at creation time
  4296    * problem since functions are assigned at creation time
  3748    * and don't change that often... */
  4297    * and don't change that often... */
  3749   if (G_UNLIKELY ((chainfunc = GST_PAD_CHAINFUNC (pad)) == NULL))
  4298   if (G_LIKELY (is_buffer)) {
  3750     goto no_function;
  4299     GstPadChainFunction chainfunc;
  3751 
  4300 
  3752   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  4301     if (G_UNLIKELY ((chainfunc = GST_PAD_CHAINFUNC (pad)) == NULL))
  3753       "calling chainfunction &%s", GST_DEBUG_FUNCPTR_NAME (chainfunc));
  4302       goto no_function;
  3754 
  4303 
  3755   ret = chainfunc (pad, buffer);
  4304     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  3756 
  4305         "calling chainfunction &%s", GST_DEBUG_FUNCPTR_NAME (chainfunc));
  3757   GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  4306 
  3758       "called chainfunction &%s, returned %s",
  4307     ret = chainfunc (pad, GST_BUFFER_CAST (data));
  3759       GST_DEBUG_FUNCPTR_NAME (chainfunc), gst_flow_get_name (ret));
  4308 
       
  4309     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4310         "called chainfunction &%s, returned %s",
       
  4311         GST_DEBUG_FUNCPTR_NAME (chainfunc), gst_flow_get_name (ret));
       
  4312   } else {
       
  4313     GstPadChainListFunction chainlistfunc;
       
  4314 
       
  4315     if (G_UNLIKELY ((chainlistfunc = GST_PAD_CHAINLISTFUNC (pad)) == NULL))
       
  4316       goto chain_groups;
       
  4317 
       
  4318     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4319         "calling chainlistfunction &%s",
       
  4320         GST_DEBUG_FUNCPTR_NAME (chainlistfunc));
       
  4321 
       
  4322     ret = chainlistfunc (pad, GST_BUFFER_LIST_CAST (data));
       
  4323 
       
  4324     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4325         "called chainlistfunction &%s, returned %s",
       
  4326         GST_DEBUG_FUNCPTR_NAME (chainlistfunc), gst_flow_get_name (ret));
       
  4327   }
  3760 
  4328 
  3761   GST_PAD_STREAM_UNLOCK (pad);
  4329   GST_PAD_STREAM_UNLOCK (pad);
  3762 
  4330 
  3763   return ret;
  4331   return ret;
       
  4332 
       
  4333 chain_groups:
       
  4334   {
       
  4335     GstBufferList *list;
       
  4336     GstBufferListIterator *it;
       
  4337     GstBuffer *group;
       
  4338 
       
  4339     GST_PAD_STREAM_UNLOCK (pad);
       
  4340 
       
  4341     GST_INFO_OBJECT (pad, "chaining each group in list as a merged buffer");
       
  4342 
       
  4343     list = GST_BUFFER_LIST_CAST (data);
       
  4344     it = gst_buffer_list_iterate (list);
       
  4345 
       
  4346     ret = GST_FLOW_OK;
       
  4347     if (gst_buffer_list_iterator_next_group (it)) {
       
  4348       do {
       
  4349         group = gst_buffer_list_iterator_merge_group (it);
       
  4350         if (group == NULL) {
       
  4351           group = gst_buffer_new ();
       
  4352           GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining empty group");
       
  4353         } else {
       
  4354           GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining group");
       
  4355         }
       
  4356         ret = gst_pad_chain_data_unchecked (pad, TRUE, group);
       
  4357       } while (ret == GST_FLOW_OK && gst_buffer_list_iterator_next_group (it));
       
  4358     } else {
       
  4359       GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining empty group");
       
  4360       ret = gst_pad_chain_data_unchecked (pad, TRUE, gst_buffer_new ());
       
  4361     }
       
  4362 
       
  4363     gst_buffer_list_iterator_free (it);
       
  4364     gst_buffer_list_unref (list);
       
  4365 
       
  4366     return ret;
       
  4367   }
  3764 
  4368 
  3765   /* ERRORS */
  4369   /* ERRORS */
  3766 flushing:
  4370 flushing:
  3767   {
  4371   {
  3768     gst_buffer_unref (buffer);
  4372     gst_pad_data_unref (is_buffer, data);
  3769     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  4373     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  3770         "pushing, but pad was flushing");
  4374         "pushing, but pad was flushing");
  3771     GST_OBJECT_UNLOCK (pad);
  4375     GST_OBJECT_UNLOCK (pad);
  3772     GST_PAD_STREAM_UNLOCK (pad);
  4376     GST_PAD_STREAM_UNLOCK (pad);
  3773     return GST_FLOW_WRONG_STATE;
  4377     return GST_FLOW_WRONG_STATE;
  3774   }
  4378   }
  3775 dropping:
  4379 dropping:
  3776   {
  4380   {
  3777     gst_buffer_unref (buffer);
  4381     gst_pad_data_unref (is_buffer, data);
  3778     GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
  4382     GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
  3779     GST_PAD_STREAM_UNLOCK (pad);
  4383     GST_PAD_STREAM_UNLOCK (pad);
  3780     return GST_FLOW_OK;
  4384     return GST_FLOW_OK;
  3781   }
  4385   }
  3782 not_negotiated:
  4386 not_negotiated:
  3783   {
  4387   {
  3784     gst_buffer_unref (buffer);
  4388     gst_pad_data_unref (is_buffer, data);
  3785     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  4389     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  3786         "pushing buffer but pad did not accept");
  4390         "pushing data but pad did not accept");
  3787     GST_PAD_STREAM_UNLOCK (pad);
  4391     GST_PAD_STREAM_UNLOCK (pad);
  3788     return GST_FLOW_NOT_NEGOTIATED;
  4392     return GST_FLOW_NOT_NEGOTIATED;
  3789   }
  4393   }
  3790 no_function:
  4394 no_function:
  3791   {
  4395   {
  3792     gst_buffer_unref (buffer);
  4396     gst_pad_data_unref (is_buffer, data);
  3793     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  4397     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  3794         "pushing, but not chainhandler");
  4398         "pushing, but not chainhandler");
  3795     GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
  4399     GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
  3796         ("push on pad %s:%s but it has no chainfunction",
  4400         ("push on pad %s:%s but it has no chainfunction",
  3797             GST_DEBUG_PAD_NAME (pad)));
  4401             GST_DEBUG_PAD_NAME (pad)));
  3832 
  4436 
  3833 GstFlowReturn
  4437 GstFlowReturn
  3834 gst_pad_chain (GstPad * pad, GstBuffer * buffer)
  4438 gst_pad_chain (GstPad * pad, GstBuffer * buffer)
  3835 {
  4439 {
  3836   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
  4440   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,
  4441   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
  3838       GST_FLOW_ERROR);
       
  3839   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
  4442   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
  3840 
  4443 
  3841   return gst_pad_chain_unchecked (pad, buffer);
  4444   return gst_pad_chain_data_unchecked (pad, TRUE, buffer);
  3842 }
  4445 }
  3843 
  4446 
  3844 /**
  4447 /**
  3845  * gst_pad_push:
  4448  * gst_pad_chain_list:
  3846  * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not.
  4449  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
  3847  * @buffer: the #GstBuffer to push returns GST_FLOW_ERROR if not.
  4450  * @list: the #GstBufferList to send, return GST_FLOW_ERROR if not.
  3848  *
  4451  *
  3849  * Pushes a buffer to the peer of @pad.
  4452  * Chain a bufferlist to @pad.
  3850  *
  4453  *
  3851  * This function will call an installed pad block before triggering any
  4454  * The function returns #GST_FLOW_WRONG_STATE if the pad was flushing.
  3852  * installed pad probes.
  4455  *
  3853  *
  4456  * If the caps on the first buffer of @list are different from the current
  3854  * If the caps on @buffer are different from the currently configured caps on
  4457  * caps on @pad, this function will call any setcaps function
  3855  * @pad, this function will call any installed setcaps function on @pad (see
  4458  * (see gst_pad_set_setcaps_function()) installed on @pad. If the new caps
  3856  * gst_pad_set_setcaps_function()). In case of failure to renegotiate the new
  4459  * are not acceptable for @pad, this function returns #GST_FLOW_NOT_NEGOTIATED.
  3857  * format, this function returns #GST_FLOW_NOT_NEGOTIATED.
  4460  *
  3858  *
  4461  * The function proceeds calling the chainlist function installed on @pad (see
  3859  * The function proceeds calling gst_pad_chain() on the peer pad and returns
  4462  * gst_pad_set_chain_list_function()) and the return value of that function is
  3860  * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
  4463  * returned to the caller. #GST_FLOW_NOT_SUPPORTED is returned if @pad has no
  3861  * be returned.
  4464  * chainlist function.
  3862  *
  4465  *
  3863  * In all cases, success or failure, the caller loses its reference to @buffer
  4466  * In all cases, success or failure, the caller loses its reference to @list
  3864  * after calling this function.
  4467  * after calling this function.
  3865  *
  4468  *
  3866  * Returns: a #GstFlowReturn from the peer pad.
       
  3867  *
       
  3868  * MT safe.
  4469  * MT safe.
  3869  */
  4470  *
  3870 #ifdef __SYMBIAN32__
  4471  * Returns: a #GstFlowReturn from the pad.
  3871 EXPORT_C
  4472  *
  3872 #endif
  4473  * Since: 0.10.24
       
  4474  */
       
  4475 #ifdef __SYMBIAN32__
       
  4476 EXPORT_C
       
  4477 #endif
       
  4478 
  3873 GstFlowReturn
  4479 GstFlowReturn
  3874 gst_pad_push (GstPad * pad, GstBuffer * buffer)
  4480 gst_pad_chain_list (GstPad * pad, GstBufferList * list)
       
  4481 {
       
  4482   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
       
  4483   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
       
  4484   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
       
  4485 
       
  4486   return gst_pad_chain_data_unchecked (pad, FALSE, list);
       
  4487 }
       
  4488 
       
  4489 static GstFlowReturn
       
  4490 gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data)
  3875 {
  4491 {
  3876   GstPad *peer;
  4492   GstPad *peer;
  3877   GstFlowReturn ret;
  4493   GstFlowReturn ret;
  3878 
       
  3879   GstCaps *caps;
  4494   GstCaps *caps;
  3880   gboolean caps_changed;
  4495   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 
  4496 
  3886   GST_OBJECT_LOCK (pad);
  4497   GST_OBJECT_LOCK (pad);
  3887 
  4498 
  3888   /* FIXME: this check can go away; pad_set_blocked could be implemented with
  4499   /* FIXME: this check can go away; pad_set_blocked could be implemented with
  3889    * probes completely or probes with an extended pad block. */
  4500    * probes completely or probes with an extended pad block. */
  3895    * emit in the _chain() function */
  4506    * emit in the _chain() function */
  3896   if (G_UNLIKELY (GST_PAD_DO_BUFFER_SIGNALS (pad) > 0)) {
  4507   if (G_UNLIKELY (GST_PAD_DO_BUFFER_SIGNALS (pad) > 0)) {
  3897     /* unlock before emitting */
  4508     /* unlock before emitting */
  3898     GST_OBJECT_UNLOCK (pad);
  4509     GST_OBJECT_UNLOCK (pad);
  3899 
  4510 
  3900     /* if the signal handler returned FALSE, it means we should just drop the
  4511     if (G_LIKELY (is_buffer)) {
  3901      * buffer */
  4512       /* if the signal handler returned FALSE, it means we should just drop the
  3902     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (buffer)))
  4513        * buffer */
  3903       goto dropped;
  4514       if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (data)))
  3904 
  4515         goto dropped;
       
  4516     } else {
       
  4517       /* push all buffers in the list */
       
  4518       goto push_groups;
       
  4519     }
  3905     GST_OBJECT_LOCK (pad);
  4520     GST_OBJECT_LOCK (pad);
  3906   }
  4521   }
  3907 
  4522 
  3908   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
  4523   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
  3909     goto not_linked;
  4524     goto not_linked;
  3910 
  4525 
       
  4526   /* Before pushing the buffer to the peer pad, ensure that caps
       
  4527    * are set on this pad */
       
  4528   caps = gst_pad_data_get_caps (is_buffer, data);
       
  4529   caps_changed = caps && caps != GST_PAD_CAPS (pad);
       
  4530 
  3911   /* take ref to peer pad before releasing the lock */
  4531   /* take ref to peer pad before releasing the lock */
  3912   gst_object_ref (peer);
  4532   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 
  4533 
  3919   GST_OBJECT_UNLOCK (pad);
  4534   GST_OBJECT_UNLOCK (pad);
  3920 
  4535 
  3921   /* we got a new datatype from the pad, it had better handle it */
  4536   /* we got a new datatype from the pad, it had better handle it */
  3922   if (G_UNLIKELY (caps_changed)) {
  4537   if (G_UNLIKELY (caps_changed)) {
  3925         GST_PAD_CAPS (pad), caps, caps);
  4540         GST_PAD_CAPS (pad), caps, caps);
  3926     if (G_UNLIKELY (!gst_pad_configure_src (pad, caps, TRUE)))
  4541     if (G_UNLIKELY (!gst_pad_configure_src (pad, caps, TRUE)))
  3927       goto not_negotiated;
  4542       goto not_negotiated;
  3928   }
  4543   }
  3929 
  4544 
  3930   ret = gst_pad_chain_unchecked (peer, buffer);
  4545   ret = gst_pad_chain_data_unchecked (peer, is_buffer, data);
  3931 
  4546 
  3932   gst_object_unref (peer);
  4547   gst_object_unref (peer);
  3933 
  4548 
  3934   return ret;
  4549   return ret;
       
  4550 
       
  4551 push_groups:
       
  4552   {
       
  4553     GstBufferList *list;
       
  4554     GstBufferListIterator *it;
       
  4555     GstBuffer *group;
       
  4556 
       
  4557     GST_INFO_OBJECT (pad, "pushing each group in list as a merged buffer");
       
  4558 
       
  4559     list = GST_BUFFER_LIST_CAST (data);
       
  4560     it = gst_buffer_list_iterate (list);
       
  4561 
       
  4562     ret = GST_FLOW_OK;
       
  4563     if (gst_buffer_list_iterator_next_group (it)) {
       
  4564       do {
       
  4565         group = gst_buffer_list_iterator_merge_group (it);
       
  4566         if (group == NULL) {
       
  4567           group = gst_buffer_new ();
       
  4568           GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "pushing empty group");
       
  4569         } else {
       
  4570           GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "pushing group");
       
  4571         }
       
  4572         ret = gst_pad_push_data (pad, TRUE, group);
       
  4573       } while (ret == GST_FLOW_OK && gst_buffer_list_iterator_next_group (it));
       
  4574     } else {
       
  4575       GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "pushing empty group");
       
  4576       ret = gst_pad_push_data (pad, TRUE, gst_buffer_new ());
       
  4577     }
       
  4578 
       
  4579     gst_buffer_list_iterator_free (it);
       
  4580     gst_buffer_list_unref (list);
       
  4581 
       
  4582     return ret;
       
  4583   }
  3935 
  4584 
  3936   /* ERROR recovery here */
  4585   /* ERROR recovery here */
  3937 flushed:
  4586 flushed:
  3938   {
  4587   {
  3939     gst_buffer_unref (buffer);
  4588     gst_pad_data_unref (is_buffer, data);
  3940     GST_DEBUG_OBJECT (pad, "pad block stopped by flush");
  4589     GST_DEBUG_OBJECT (pad, "pad block stopped by flush");
  3941     GST_OBJECT_UNLOCK (pad);
  4590     GST_OBJECT_UNLOCK (pad);
  3942     return ret;
  4591     return ret;
  3943   }
  4592   }
  3944 dropped:
  4593 dropped:
  3945   {
  4594   {
  3946     gst_buffer_unref (buffer);
  4595     gst_pad_data_unref (is_buffer, data);
  3947     GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
  4596     GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
  3948     return GST_FLOW_OK;
  4597     return GST_FLOW_OK;
  3949   }
  4598   }
  3950 not_linked:
  4599 not_linked:
  3951   {
  4600   {
  3952     gst_buffer_unref (buffer);
  4601     gst_pad_data_unref (is_buffer, data);
  3953     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  4602     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  3954         "pushing, but it was not linked");
  4603         "pushing, but it was not linked");
  3955     GST_OBJECT_UNLOCK (pad);
  4604     GST_OBJECT_UNLOCK (pad);
  3956     return GST_FLOW_NOT_LINKED;
  4605     return GST_FLOW_NOT_LINKED;
  3957   }
  4606   }
  3958 not_negotiated:
  4607 not_negotiated:
  3959   {
  4608   {
  3960     gst_buffer_unref (buffer);
  4609     gst_pad_data_unref (is_buffer, data);
  3961     gst_object_unref (peer);
  4610     gst_object_unref (peer);
  3962     GST_CAT_DEBUG_OBJECT (GST_CAT_SCHEDULING, pad,
  4611     GST_CAT_DEBUG_OBJECT (GST_CAT_SCHEDULING, pad,
  3963         "element pushed buffer then refused to accept the caps");
  4612         "element pushed data then refused to accept the caps");
  3964     return GST_FLOW_NOT_NEGOTIATED;
  4613     return GST_FLOW_NOT_NEGOTIATED;
  3965   }
  4614   }
       
  4615 }
       
  4616 
       
  4617 /**
       
  4618  * gst_pad_push:
       
  4619  * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not.
       
  4620  * @buffer: the #GstBuffer to push returns GST_FLOW_ERROR if not.
       
  4621  *
       
  4622  * Pushes a buffer to the peer of @pad.
       
  4623  *
       
  4624  * This function will call an installed pad block before triggering any
       
  4625  * installed pad probes.
       
  4626  *
       
  4627  * If the caps on @buffer are different from the currently configured caps on
       
  4628  * @pad, this function will call any installed setcaps function on @pad (see
       
  4629  * gst_pad_set_setcaps_function()). In case of failure to renegotiate the new
       
  4630  * format, this function returns #GST_FLOW_NOT_NEGOTIATED.
       
  4631  *
       
  4632  * The function proceeds calling gst_pad_chain() on the peer pad and returns
       
  4633  * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
       
  4634  * be returned.
       
  4635  *
       
  4636  * In all cases, success or failure, the caller loses its reference to @buffer
       
  4637  * after calling this function.
       
  4638  *
       
  4639  * Returns: a #GstFlowReturn from the peer pad.
       
  4640  *
       
  4641  * MT safe.
       
  4642  */
       
  4643 #ifdef __SYMBIAN32__
       
  4644 EXPORT_C
       
  4645 #endif
       
  4646 
       
  4647 GstFlowReturn
       
  4648 gst_pad_push (GstPad * pad, GstBuffer * buffer)
       
  4649 {
       
  4650   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
       
  4651   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
       
  4652   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
       
  4653 
       
  4654   return gst_pad_push_data (pad, TRUE, buffer);
       
  4655 }
       
  4656 
       
  4657 /**
       
  4658  * gst_pad_push_list:
       
  4659  * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not.
       
  4660  * @list: the #GstBufferList to push returns GST_FLOW_ERROR if not.
       
  4661  *
       
  4662  * Pushes a buffer list to the peer of @pad.
       
  4663  *
       
  4664  * This function will call an installed pad block before triggering any
       
  4665  * installed pad probes.
       
  4666  *
       
  4667  * If the caps on the first buffer in the first group of @list are different
       
  4668  * from the currently configured caps on @pad, this function will call any
       
  4669  * installed setcaps function on @pad (see gst_pad_set_setcaps_function()). In
       
  4670  * case of failure to renegotiate the new format, this function returns
       
  4671  * #GST_FLOW_NOT_NEGOTIATED.
       
  4672  *
       
  4673  * If there are any probes installed on @pad every group of the buffer list
       
  4674  * will be merged into a normal #GstBuffer and pushed via gst_pad_push and the
       
  4675  * buffer list will be unreffed.
       
  4676  *
       
  4677  * The function proceeds calling the chain function on the peer pad and returns
       
  4678  * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
       
  4679  * be returned. If the peer pad does not have any installed chainlist function
       
  4680  * every group buffer of the list will be merged into a normal #GstBuffer and
       
  4681  * chained via gst_pad_chain().
       
  4682  *
       
  4683  * In all cases, success or failure, the caller loses its reference to @list
       
  4684  * after calling this function.
       
  4685  *
       
  4686  * Returns: a #GstFlowReturn from the peer pad.
       
  4687  *
       
  4688  * MT safe.
       
  4689  *
       
  4690  * Since: 0.10.24
       
  4691  */
       
  4692 #ifdef __SYMBIAN32__
       
  4693 EXPORT_C
       
  4694 #endif
       
  4695 
       
  4696 GstFlowReturn
       
  4697 gst_pad_push_list (GstPad * pad, GstBufferList * list)
       
  4698 {
       
  4699   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
       
  4700   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
       
  4701   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
       
  4702 
       
  4703   return gst_pad_push_data (pad, FALSE, list);
  3966 }
  4704 }
  3967 
  4705 
  3968 /**
  4706 /**
  3969  * gst_pad_check_pull_range:
  4707  * gst_pad_check_pull_range:
  3970  * @pad: a sink #GstPad.
  4708  * @pad: a sink #GstPad.
  3993   GstPadCheckGetRangeFunction checkgetrangefunc;
  4731   GstPadCheckGetRangeFunction checkgetrangefunc;
  3994 
  4732 
  3995   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  4733   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  3996 
  4734 
  3997   GST_OBJECT_LOCK (pad);
  4735   GST_OBJECT_LOCK (pad);
  3998   if (GST_PAD_DIRECTION (pad) != GST_PAD_SINK)
  4736   if (!GST_PAD_IS_SINK (pad))
  3999     goto wrong_direction;
  4737     goto wrong_direction;
  4000 
  4738 
  4001   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
  4739   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
  4002     goto not_connected;
  4740     goto not_connected;
  4003 
  4741 
  4052  * Calls the getrange function of @pad, see #GstPadGetRangeFunction for a
  4790  * Calls the getrange function of @pad, see #GstPadGetRangeFunction for a
  4053  * description of a getrange function. If @pad has no getrange function
  4791  * description of a getrange function. If @pad has no getrange function
  4054  * installed (see gst_pad_set_getrange_function()) this function returns
  4792  * installed (see gst_pad_set_getrange_function()) this function returns
  4055  * #GST_FLOW_NOT_SUPPORTED.
  4793  * #GST_FLOW_NOT_SUPPORTED.
  4056  *
  4794  *
  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.
  4795  * This is a lowlevel function. Usualy gst_pad_pull_range() is used.
  4062  *
  4796  *
  4063  * Returns: a #GstFlowReturn from the pad.
  4797  * Returns: a #GstFlowReturn from the pad.
  4064  *
  4798  *
  4065  * MT safe.
  4799  * MT safe.
  4073     GstBuffer ** buffer)
  4807     GstBuffer ** buffer)
  4074 {
  4808 {
  4075   GstFlowReturn ret;
  4809   GstFlowReturn ret;
  4076   GstPadGetRangeFunction getrangefunc;
  4810   GstPadGetRangeFunction getrangefunc;
  4077   gboolean emit_signal;
  4811   gboolean emit_signal;
       
  4812   GstCaps *caps;
       
  4813   gboolean caps_changed;
  4078 
  4814 
  4079   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
  4815   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);
  4816   g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
  4081   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
  4817   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
  4082 
  4818 
  4083   GST_PAD_STREAM_LOCK (pad);
  4819   GST_PAD_STREAM_LOCK (pad);
  4084 
  4820 
  4085   GST_OBJECT_LOCK (pad);
  4821   GST_OBJECT_LOCK (pad);
  4105       goto dropping;
  4841       goto dropping;
  4106   }
  4842   }
  4107 
  4843 
  4108   GST_PAD_STREAM_UNLOCK (pad);
  4844   GST_PAD_STREAM_UNLOCK (pad);
  4109 
  4845 
  4110   if (G_LIKELY (ret == GST_FLOW_OK)) {
  4846   if (G_UNLIKELY (ret != GST_FLOW_OK))
  4111     GstCaps *caps;
  4847     goto get_range_failed;
  4112     gboolean caps_changed;
  4848 
  4113 
  4849   GST_OBJECT_LOCK (pad);
  4114     GST_OBJECT_LOCK (pad);
  4850   /* Before pushing the buffer to the peer pad, ensure that caps
  4115     /* Before pushing the buffer to the peer pad, ensure that caps
  4851    * are set on this pad */
  4116      * are set on this pad */
  4852   caps = GST_BUFFER_CAPS (*buffer);
  4117     caps = GST_BUFFER_CAPS (*buffer);
  4853   caps_changed = caps && caps != GST_PAD_CAPS (pad);
  4118     caps_changed = caps && caps != GST_PAD_CAPS (pad);
  4854   GST_OBJECT_UNLOCK (pad);
  4119     GST_OBJECT_UNLOCK (pad);
  4855 
  4120 
  4856   if (G_UNLIKELY (caps_changed)) {
  4121     /* we got a new datatype from the pad not supported in a running pull-mode
  4857     GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
  4122      * pipeline */
  4858     /* this should usually work because the element produced the buffer */
  4123     if (G_UNLIKELY (caps_changed))
  4859     if (G_UNLIKELY (!gst_pad_configure_src (pad, caps, TRUE)))
  4124       goto not_negotiated;
  4860       goto not_negotiated;
  4125   }
  4861   }
  4126 
       
  4127   return ret;
  4862   return ret;
  4128 
  4863 
  4129   /* ERRORS */
  4864   /* ERRORS */
  4130 flushing:
  4865 flushing:
  4131   {
  4866   {
  4150     GST_PAD_STREAM_UNLOCK (pad);
  4885     GST_PAD_STREAM_UNLOCK (pad);
  4151     gst_buffer_unref (*buffer);
  4886     gst_buffer_unref (*buffer);
  4152     *buffer = NULL;
  4887     *buffer = NULL;
  4153     return GST_FLOW_UNEXPECTED;
  4888     return GST_FLOW_UNEXPECTED;
  4154   }
  4889   }
       
  4890 get_range_failed:
       
  4891   {
       
  4892     *buffer = NULL;
       
  4893     GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
       
  4894         "getrange failed %s", gst_flow_get_name (ret));
       
  4895     return ret;
       
  4896   }
  4155 not_negotiated:
  4897 not_negotiated:
  4156   {
  4898   {
  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);
  4899     gst_buffer_unref (*buffer);
  4164     *buffer = NULL;
  4900     *buffer = NULL;
  4165     GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
  4901     GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
  4166         "getrange returned buffer of different caps");
  4902         "getrange returned buffer of unaccaptable caps");
  4167     return GST_FLOW_NOT_NEGOTIATED;
  4903     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   }
  4904   }
  4173 }
  4905 }
  4174 
  4906 
  4175 
  4907 
  4176 /**
  4908 /**
  4211     GstBuffer ** buffer)
  4943     GstBuffer ** buffer)
  4212 {
  4944 {
  4213   GstPad *peer;
  4945   GstPad *peer;
  4214   GstFlowReturn ret;
  4946   GstFlowReturn ret;
  4215   gboolean emit_signal;
  4947   gboolean emit_signal;
       
  4948   GstCaps *caps;
       
  4949   gboolean caps_changed;
  4216 
  4950 
  4217   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
  4951   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,
  4952   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
  4219       GST_FLOW_ERROR);
       
  4220   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
  4953   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
  4221 
  4954 
  4222   GST_OBJECT_LOCK (pad);
  4955   GST_OBJECT_LOCK (pad);
  4223 
  4956 
  4224   while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
  4957   while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
  4236 
  4969 
  4237   ret = gst_pad_get_range (peer, offset, size, buffer);
  4970   ret = gst_pad_get_range (peer, offset, size, buffer);
  4238 
  4971 
  4239   gst_object_unref (peer);
  4972   gst_object_unref (peer);
  4240 
  4973 
       
  4974   if (G_UNLIKELY (ret != GST_FLOW_OK))
       
  4975     goto pull_range_failed;
       
  4976 
  4241   /* can only fire the signal if we have a valid buffer */
  4977   /* can only fire the signal if we have a valid buffer */
  4242   if (G_UNLIKELY (emit_signal) && (ret == GST_FLOW_OK)) {
  4978   if (G_UNLIKELY (emit_signal)) {
  4243     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (*buffer)))
  4979     if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (*buffer)))
  4244       goto dropping;
  4980       goto dropping;
  4245   }
  4981   }
  4246 
  4982 
  4247   if (G_LIKELY (ret == GST_FLOW_OK)) {
  4983   GST_OBJECT_LOCK (pad);
  4248     GstCaps *caps;
  4984   /* Before pushing the buffer to the peer pad, ensure that caps
  4249     gboolean caps_changed;
  4985    * are set on this pad */
  4250 
  4986   caps = GST_BUFFER_CAPS (*buffer);
  4251     GST_OBJECT_LOCK (pad);
  4987   caps_changed = caps && caps != GST_PAD_CAPS (pad);
  4252     /* Before pushing the buffer to the peer pad, ensure that caps
  4988   GST_OBJECT_UNLOCK (pad);
  4253      * are set on this pad */
  4989 
  4254     caps = GST_BUFFER_CAPS (*buffer);
  4990   /* we got a new datatype on the pad, see if it can handle it */
  4255     caps_changed = caps && caps != GST_PAD_CAPS (pad);
  4991   if (G_UNLIKELY (caps_changed)) {
  4256     GST_OBJECT_UNLOCK (pad);
  4992     GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
  4257 
  4993     if (G_UNLIKELY (!gst_pad_configure_sink (pad, caps)))
  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;
  4994       goto not_negotiated;
  4261   }
  4995   }
  4262 
       
  4263   return ret;
  4996   return ret;
  4264 
  4997 
  4265   /* ERROR recovery here */
  4998   /* ERROR recovery here */
  4266 not_connected:
  4999 not_connected:
  4267   {
  5000   {
  4268     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  5001     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  4269         "pulling range, but it was not linked");
  5002         "pulling range, but it was not linked");
  4270     GST_OBJECT_UNLOCK (pad);
  5003     GST_OBJECT_UNLOCK (pad);
  4271     return GST_FLOW_NOT_LINKED;
  5004     return GST_FLOW_NOT_LINKED;
       
  5005   }
       
  5006 pull_range_failed:
       
  5007   {
       
  5008     *buffer = NULL;
       
  5009     GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
       
  5010         "pullrange failed %s", gst_flow_get_name (ret));
       
  5011     return ret;
  4272   }
  5012   }
  4273 dropping:
  5013 dropping:
  4274   {
  5014   {
  4275     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  5015     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
  4276         "Dropping data after FALSE probe return");
  5016         "Dropping data after FALSE probe return");
  4278     *buffer = NULL;
  5018     *buffer = NULL;
  4279     return GST_FLOW_UNEXPECTED;
  5019     return GST_FLOW_UNEXPECTED;
  4280   }
  5020   }
  4281 not_negotiated:
  5021 not_negotiated:
  4282   {
  5022   {
  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);
  5023     gst_buffer_unref (*buffer);
  4290     *buffer = NULL;
  5024     *buffer = NULL;
  4291     GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
  5025     GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
  4292         "pullrange returned buffer of different caps");
  5026         "pullrange returned buffer of different caps");
  4293     return GST_FLOW_NOT_NEGOTIATED;
  5027     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   }
  5028   }
  4299 }
  5029 }
  4300 
  5030 
  4301 /**
  5031 /**
  4302  * gst_pad_push_event:
  5032  * gst_pad_push_event:
  4621 gst_pad_get_element_private (GstPad * pad)
  5351 gst_pad_get_element_private (GstPad * pad)
  4622 {
  5352 {
  4623   return pad->element_private;
  5353   return pad->element_private;
  4624 }
  5354 }
  4625 
  5355 
       
  5356 static void
       
  5357 do_stream_status (GstPad * pad, GstStreamStatusType type,
       
  5358     GThread * thread, GstTask * task)
       
  5359 {
       
  5360   GstElement *parent;
       
  5361 
       
  5362   GST_DEBUG_OBJECT (pad, "doing stream-status %d", type);
       
  5363 
       
  5364   if ((parent = GST_ELEMENT_CAST (gst_pad_get_parent (pad)))) {
       
  5365     if (GST_IS_ELEMENT (parent)) {
       
  5366       GstMessage *message;
       
  5367       GValue value = { 0 };
       
  5368 
       
  5369       message = gst_message_new_stream_status (GST_OBJECT_CAST (pad),
       
  5370           type, parent);
       
  5371 
       
  5372       g_value_init (&value, GST_TYPE_TASK);
       
  5373       g_value_set_object (&value, task);
       
  5374       gst_message_set_stream_status_object (message, &value);
       
  5375       g_value_unset (&value);
       
  5376 
       
  5377       GST_DEBUG_OBJECT (pad, "posting stream-status %d", type);
       
  5378       gst_element_post_message (parent, message);
       
  5379     }
       
  5380     gst_object_unref (parent);
       
  5381   }
       
  5382 }
       
  5383 
       
  5384 static void
       
  5385 pad_enter_thread (GstTask * task, GThread * thread, gpointer user_data)
       
  5386 {
       
  5387   do_stream_status (GST_PAD_CAST (user_data), GST_STREAM_STATUS_TYPE_ENTER,
       
  5388       thread, task);
       
  5389 }
       
  5390 
       
  5391 static void
       
  5392 pad_leave_thread (GstTask * task, GThread * thread, gpointer user_data)
       
  5393 {
       
  5394   do_stream_status (GST_PAD_CAST (user_data), GST_STREAM_STATUS_TYPE_LEAVE,
       
  5395       thread, task);
       
  5396 }
       
  5397 
       
  5398 static GstTaskThreadCallbacks thr_callbacks = {
       
  5399   pad_enter_thread,
       
  5400   pad_leave_thread,
       
  5401 };
       
  5402 
  4626 /**
  5403 /**
  4627  * gst_pad_start_task:
  5404  * gst_pad_start_task:
  4628  * @pad: the #GstPad to start the task of
  5405  * @pad: the #GstPad to start the task of
  4629  * @func: the task function to call
  5406  * @func: the task function to call
  4630  * @data: data passed to the task function
  5407  * @data: data passed to the task function
  4642 
  5419 
  4643 gboolean
  5420 gboolean
  4644 gst_pad_start_task (GstPad * pad, GstTaskFunction func, gpointer data)
  5421 gst_pad_start_task (GstPad * pad, GstTaskFunction func, gpointer data)
  4645 {
  5422 {
  4646   GstTask *task;
  5423   GstTask *task;
       
  5424   gboolean res;
  4647 
  5425 
  4648   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  5426   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  4649   g_return_val_if_fail (func != NULL, FALSE);
  5427   g_return_val_if_fail (func != NULL, FALSE);
  4650 
  5428 
  4651   GST_DEBUG_OBJECT (pad, "start task");
  5429   GST_DEBUG_OBJECT (pad, "start task");
  4653   GST_OBJECT_LOCK (pad);
  5431   GST_OBJECT_LOCK (pad);
  4654   task = GST_PAD_TASK (pad);
  5432   task = GST_PAD_TASK (pad);
  4655   if (task == NULL) {
  5433   if (task == NULL) {
  4656     task = gst_task_create (func, data);
  5434     task = gst_task_create (func, data);
  4657     gst_task_set_lock (task, GST_PAD_GET_STREAM_LOCK (pad));
  5435     gst_task_set_lock (task, GST_PAD_GET_STREAM_LOCK (pad));
       
  5436     gst_task_set_thread_callbacks (task, &thr_callbacks, pad, NULL);
       
  5437     GST_DEBUG_OBJECT (pad, "created task");
  4658     GST_PAD_TASK (pad) = task;
  5438     GST_PAD_TASK (pad) = task;
  4659     GST_DEBUG_OBJECT (pad, "created task");
  5439     gst_object_ref (task);
  4660   }
  5440     /* release lock to post the message */
  4661   gst_task_start (task);
  5441     GST_OBJECT_UNLOCK (pad);
       
  5442 
       
  5443     do_stream_status (pad, GST_STREAM_STATUS_TYPE_CREATE, NULL, task);
       
  5444 
       
  5445     gst_object_unref (task);
       
  5446 
       
  5447     GST_OBJECT_LOCK (pad);
       
  5448     /* nobody else is supposed to have changed the pad now */
       
  5449     if (GST_PAD_TASK (pad) != task)
       
  5450       goto concurrent_stop;
       
  5451   }
       
  5452   res = gst_task_set_state (task, GST_TASK_STARTED);
  4662   GST_OBJECT_UNLOCK (pad);
  5453   GST_OBJECT_UNLOCK (pad);
  4663 
  5454 
  4664   return TRUE;
  5455   return res;
       
  5456 
       
  5457   /* ERRORS */
       
  5458 concurrent_stop:
       
  5459   {
       
  5460     GST_OBJECT_UNLOCK (pad);
       
  5461     return TRUE;
       
  5462   }
  4665 }
  5463 }
  4666 
  5464 
  4667 /**
  5465 /**
  4668  * gst_pad_pause_task:
  5466  * gst_pad_pause_task:
  4669  * @pad: the #GstPad to pause the task of
  5467  * @pad: the #GstPad to pause the task of
  4681 
  5479 
  4682 gboolean
  5480 gboolean
  4683 gst_pad_pause_task (GstPad * pad)
  5481 gst_pad_pause_task (GstPad * pad)
  4684 {
  5482 {
  4685   GstTask *task;
  5483   GstTask *task;
       
  5484   gboolean res;
  4686 
  5485 
  4687   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  5486   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  4688 
  5487 
  4689   GST_DEBUG_OBJECT (pad, "pause task");
  5488   GST_DEBUG_OBJECT (pad, "pause task");
  4690 
  5489 
  4691   GST_OBJECT_LOCK (pad);
  5490   GST_OBJECT_LOCK (pad);
  4692   task = GST_PAD_TASK (pad);
  5491   task = GST_PAD_TASK (pad);
  4693   if (task == NULL)
  5492   if (task == NULL)
  4694     goto no_task;
  5493     goto no_task;
  4695   gst_task_pause (task);
  5494   res = gst_task_set_state (task, GST_TASK_PAUSED);
  4696   GST_OBJECT_UNLOCK (pad);
  5495   GST_OBJECT_UNLOCK (pad);
  4697 
  5496 
  4698   /* wait for task function to finish, this lock is recursive so it does nothing
  5497   /* wait for task function to finish, this lock is recursive so it does nothing
  4699    * when the pause is called from the task itself */
  5498    * when the pause is called from the task itself */
  4700   GST_PAD_STREAM_LOCK (pad);
  5499   GST_PAD_STREAM_LOCK (pad);
  4701   GST_PAD_STREAM_UNLOCK (pad);
  5500   GST_PAD_STREAM_UNLOCK (pad);
  4702 
  5501 
  4703   return TRUE;
  5502   return res;
  4704 
  5503 
  4705 no_task:
  5504 no_task:
  4706   {
  5505   {
  4707     GST_DEBUG_OBJECT (pad, "pad has no task");
  5506     GST_DEBUG_OBJECT (pad, "pad has no task");
  4708     GST_OBJECT_UNLOCK (pad);
  5507     GST_OBJECT_UNLOCK (pad);
  4732 
  5531 
  4733 gboolean
  5532 gboolean
  4734 gst_pad_stop_task (GstPad * pad)
  5533 gst_pad_stop_task (GstPad * pad)
  4735 {
  5534 {
  4736   GstTask *task;
  5535   GstTask *task;
       
  5536   gboolean res;
  4737 
  5537 
  4738   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  5538   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  4739 
  5539 
  4740   GST_DEBUG_OBJECT (pad, "stop task");
  5540   GST_DEBUG_OBJECT (pad, "stop task");
  4741 
  5541 
  4742   GST_OBJECT_LOCK (pad);
  5542   GST_OBJECT_LOCK (pad);
  4743   task = GST_PAD_TASK (pad);
  5543   task = GST_PAD_TASK (pad);
  4744   if (task == NULL)
  5544   if (task == NULL)
  4745     goto no_task;
  5545     goto no_task;
  4746   GST_PAD_TASK (pad) = NULL;
  5546   GST_PAD_TASK (pad) = NULL;
  4747   gst_task_stop (task);
  5547   res = gst_task_set_state (task, GST_TASK_STOPPED);
  4748   GST_OBJECT_UNLOCK (pad);
  5548   GST_OBJECT_UNLOCK (pad);
  4749 
  5549 
  4750   GST_PAD_STREAM_LOCK (pad);
  5550   GST_PAD_STREAM_LOCK (pad);
  4751   GST_PAD_STREAM_UNLOCK (pad);
  5551   GST_PAD_STREAM_UNLOCK (pad);
  4752 
  5552 
  4753   if (!gst_task_join (task))
  5553   if (!gst_task_join (task))
  4754     goto join_failed;
  5554     goto join_failed;
  4755 
  5555 
  4756   gst_object_unref (task);
  5556   gst_object_unref (task);
  4757 
  5557 
  4758   return TRUE;
  5558   return res;
  4759 
  5559 
  4760 no_task:
  5560 no_task:
  4761   {
  5561   {
  4762     GST_DEBUG_OBJECT (pad, "no task");
  5562     GST_DEBUG_OBJECT (pad, "no task");
  4763     GST_OBJECT_UNLOCK (pad);
  5563     GST_OBJECT_UNLOCK (pad);