docs: improve API docs
[platform/upstream/gstreamer.git] / gst / gstpad.c
index ad44d83..2a0069b 100644 (file)
@@ -1375,6 +1375,14 @@ gst_pad_mark_reconfigure (GstPad * pad)
 }
 
 /**
+ * gst_pad_set_activate_function:
+ * @p: a #GstPad.
+ * @f: the #GstPadActivateFunction to set.
+ *
+ * Calls gst_pad_set_activate_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
  * gst_pad_set_activate_function_full:
  * @pad: a #GstPad.
  * @activate: the #GstPadActivateFunction to set.
@@ -1404,6 +1412,14 @@ gst_pad_set_activate_function_full (GstPad * pad,
 }
 
 /**
+ * gst_pad_set_activatemode_function:
+ * @p: a #GstPad.
+ * @f: the #GstPadActivateModeFunction to set.
+ *
+ * Calls gst_pad_set_activatemode_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
  * gst_pad_set_activatemode_function_full:
  * @pad: a #GstPad.
  * @activatemode: the #GstPadActivateModeFunction to set.
@@ -1431,6 +1447,14 @@ gst_pad_set_activatemode_function_full (GstPad * pad,
 }
 
 /**
+ * gst_pad_set_chain_function:
+ * @p: a sink #GstPad.
+ * @f: the #GstPadChainFunction to set.
+ *
+ * Calls gst_pad_set_chain_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
  * gst_pad_set_chain_function_full:
  * @pad: a sink #GstPad.
  * @chain: the #GstPadChainFunction to set.
@@ -1458,6 +1482,14 @@ gst_pad_set_chain_function_full (GstPad * pad, GstPadChainFunction chain,
 }
 
 /**
+ * gst_pad_set_chain_list_function:
+ * @p: a sink #GstPad.
+ * @f: the #GstPadChainListFunction to set.
+ *
+ * Calls gst_pad_set_chain_list_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
  * gst_pad_set_chain_list_function_full:
  * @pad: a sink #GstPad.
  * @chainlist: the #GstPadChainListFunction to set.
@@ -1489,6 +1521,14 @@ gst_pad_set_chain_list_function_full (GstPad * pad,
 }
 
 /**
+ * gst_pad_set_getrange_function:
+ * @p: a source #GstPad.
+ * @f: the #GstPadGetRangeFunction to set.
+ *
+ * Calls gst_pad_set_getrange_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
  * gst_pad_set_getrange_function_full:
  * @pad: a source #GstPad.
  * @get: the #GstPadGetRangeFunction to set.
@@ -1517,6 +1557,14 @@ gst_pad_set_getrange_function_full (GstPad * pad, GstPadGetRangeFunction get,
 }
 
 /**
+ * gst_pad_set_event_function:
+ * @p: a #GstPad of either direction.
+ * @f: the #GstPadEventFunction to set.
+ *
+ * Calls gst_pad_set_event_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
  * gst_pad_set_event_function_full:
  * @pad: a #GstPad of either direction.
  * @event: the #GstPadEventFunction to set.
@@ -1542,6 +1590,14 @@ gst_pad_set_event_function_full (GstPad * pad, GstPadEventFunction event,
 }
 
 /**
+ * gst_pad_set_query_function:
+ * @p: a #GstPad of either direction.
+ * @f: the #GstPadQueryFunction to set.
+ *
+ * Calls gst_pad_set_query_function_full() with NULL for the user_data and
+ * notify.
+ */
+/**
  * gst_pad_set_query_function_full:
  * @pad: a #GstPad of either direction.
  * @query: the #GstPadQueryFunction to set.
@@ -1567,6 +1623,14 @@ gst_pad_set_query_function_full (GstPad * pad, GstPadQueryFunction query,
 }
 
 /**
+ * gst_pad_set_iterate_internal_links_function:
+ * @p: a #GstPad of either direction.
+ * @f: the #GstPadIterIntLinkFunction to set.
+ *
+ * Calls gst_pad_set_iterate_internal_links_function_full() with NULL
+ * for the user_data and notify.
+ */
+/**
  * gst_pad_set_iterate_internal_links_function_full:
  * @pad: a #GstPad of either direction.
  * @iterintlink: the #GstPadIterIntLinkFunction to set.
@@ -1595,6 +1659,14 @@ gst_pad_set_iterate_internal_links_function_full (GstPad * pad,
 }
 
 /**
+ * gst_pad_set_link_function:
+ * @p: a #GstPad.
+ * @f: the #GstPadLinkFunction to set.
+ *
+ * Calls gst_pad_set_link_function_full() with NULL
+ * for the user_data and notify.
+ */
+/**
  * gst_pad_set_link_function_full:
  * @pad: a #GstPad.
  * @link: the #GstPadLinkFunction to set.
@@ -1630,6 +1702,14 @@ gst_pad_set_link_function_full (GstPad * pad, GstPadLinkFunction link,
 }
 
 /**
+ * gst_pad_set_unlink_function:
+ * @p: a #GstPad.
+ * @f: the #GstPadUnlinkFunction to set.
+ *
+ * Calls gst_pad_set_unlink_function_full() with NULL
+ * for the user_data and notify.
+ */
+/**
  * gst_pad_set_unlink_function_full:
  * @pad: a #GstPad.
  * @unlink: the #GstPadUnlinkFunction to set.
@@ -2637,12 +2717,6 @@ gst_pad_event_default (GstPad * pad, GstObject * parent, GstEvent * event)
   GST_LOG_OBJECT (pad, "default event handler");
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_EOS:
-    {
-      GST_DEBUG_OBJECT (pad, "pausing task because of eos");
-      gst_pad_pause_task (pad);
-      break;
-    }
     case GST_EVENT_CAPS:
       forward = GST_PAD_IS_PROXY_CAPS (pad);
       result = TRUE;
@@ -3185,9 +3259,10 @@ push_sticky (GstPad * pad, PadEvent * ev, gpointer user_data)
       break;
     case GST_FLOW_NOT_LINKED:
       /* not linked is not a problem, we are sticky so the event will be
-       * sent later */
+       * sent later but only for non-EOS events */
       GST_DEBUG_OBJECT (pad, "pad was not linked");
-      data->ret = GST_FLOW_OK;
+      if (GST_EVENT_TYPE (event) != GST_EVENT_EOS)
+        data->ret = GST_FLOW_OK;
       /* fallthrough */
     default:
       GST_DEBUG_OBJECT (pad, "mark pending events");
@@ -3222,22 +3297,11 @@ check_sticky (GstPad * pad)
      * event failed.
      */
     if (data.ret != GST_FLOW_OK && !data.was_eos) {
-      GArray *events = pad->priv->events;
-      gint i, len;
-
-      len = events->len;
-      for (i = 0; i < len; i++) {
-        PadEvent *ev = &g_array_index (events, PadEvent, i);
+      PadEvent *ev = find_event_by_type (pad, GST_EVENT_EOS, 0);
 
-        if (G_UNLIKELY (ev->event == NULL) || ev->received)
-          continue;
-
-        if (GST_EVENT_TYPE (ev->event) == GST_EVENT_EOS) {
-          gst_pad_push_event_unchecked (pad, gst_event_ref (ev->event),
-              GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM);
-
-          break;
-        }
+      if (ev && !ev->received) {
+        data.ret = gst_pad_push_event_unchecked (pad, gst_event_ref (ev->event),
+            GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM);
       }
     }
   }
@@ -3514,6 +3578,9 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data)
   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
     goto flushing;
 
+  if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+    goto eos;
+
   if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PUSH))
     goto wrong_mode;
 
@@ -3575,6 +3642,14 @@ flushing:
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     return GST_FLOW_FLUSHING;
   }
+eos:
+  {
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "chaining, but pad was EOS");
+    GST_OBJECT_UNLOCK (pad);
+    GST_PAD_STREAM_UNLOCK (pad);
+    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
+    return GST_FLOW_EOS;
+  }
 wrong_mode:
   {
     g_critical ("chain on pad %s:%s but it was not in push mode",
@@ -3723,6 +3798,9 @@ gst_pad_push_data (GstPad * pad, GstPadProbeType type, void *data)
   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
     goto flushing;
 
+  if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+    goto eos;
+
   if (G_UNLIKELY (GST_PAD_MODE (pad) != GST_PAD_MODE_PUSH))
     goto wrong_mode;
 
@@ -3768,6 +3846,13 @@ flushing:
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     return GST_FLOW_FLUSHING;
   }
+eos:
+  {
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing, but pad was EOS");
+    GST_OBJECT_UNLOCK (pad);
+    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
+    return GST_FLOW_EOS;
+  }
 wrong_mode:
   {
     g_critical ("pushing on pad %s:%s but it was not activated in push mode",
@@ -4330,6 +4415,7 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
       /* Remove sticky EOS events */
       GST_LOG_OBJECT (pad, "Removing pending EOS events");
       remove_event_by_type (pad, GST_EVENT_EOS);
+      GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
 
       type |= GST_PAD_PROBE_TYPE_EVENT_FLUSH;
       break;
@@ -4338,6 +4424,11 @@ gst_pad_push_event_unchecked (GstPad * pad, GstEvent * event,
       if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
         goto flushed;
 
+      /* No need to check for EOS here as either the caller (gst_pad_push_event())
+       * checked already or this is called as part of pushing sticky events,
+       * in which case we still want to forward the EOS event downstream.
+       */
+
       switch (GST_EVENT_TYPE (event)) {
         case GST_EVENT_SEGMENT:
           /* pass the adjusted segment event on. We need to do this even if
@@ -4419,6 +4510,11 @@ not_linked:
     GST_DEBUG_OBJECT (pad, "Dropping event because pad is not linked");
     GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_PENDING_EVENTS);
     gst_event_unref (event);
+
+    /* unlinked pads should not influence latency configuration */
+    if (event_type == GST_EVENT_LATENCY)
+      return GST_FLOW_OK;
+
     return GST_FLOW_NOT_LINKED;
   }
 idle_probe_stopped:
@@ -4447,7 +4543,7 @@ idle_probe_stopped:
 gboolean
 gst_pad_push_event (GstPad * pad, GstEvent * event)
 {
-  gboolean res;
+  gboolean res = FALSE;
   GstPadProbeType type;
   gboolean sticky, serialized;
 
@@ -4475,12 +4571,17 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
     if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
       goto flushed;
 
+    if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+      goto eos;
+
     /* srcpad sticky events are store immediately, the received flag is set
      * to FALSE and will be set to TRUE when we can successfully push the
      * event to the peer pad */
     if (gst_pad_store_sticky_event (pad, event, TRUE)) {
       GST_DEBUG_OBJECT (pad, "event %s updated", GST_EVENT_TYPE_NAME (event));
     }
+    if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
+      GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS);
   }
   if (GST_PAD_IS_SRC (pad) && (serialized || sticky)) {
     /* all serialized or sticky events on the srcpad trigger push of
@@ -4491,8 +4592,14 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
     /* other events are pushed right away */
     res = (gst_pad_push_event_unchecked (pad, event, type) == GST_FLOW_OK);
   } else {
+    /* Errors in sticky event pushing are no problem and ignored here
+     * as they will cause more meaningful errors during data flow.
+     * For EOS events, that are not followed by data flow, we still
+     * return FALSE here though.
+     */
+    if (GST_EVENT_TYPE (event) != GST_EVENT_EOS)
+      res = TRUE;
     gst_event_unref (event);
-    res = TRUE;
   }
   GST_OBJECT_UNLOCK (pad);
 
@@ -4519,13 +4626,20 @@ flushed:
     gst_event_unref (event);
     return FALSE;
   }
+eos:
+  {
+    GST_DEBUG_OBJECT (pad, "We're EOS");
+    GST_OBJECT_UNLOCK (pad);
+    gst_event_unref (event);
+    return FALSE;
+  }
 }
 
 /* Check if we can call the event function with the given event */
 static GstFlowReturn
 pre_eventfunc_check (GstPad * pad, GstEvent * event)
 {
-  GstCaps *caps, *templ;
+  GstCaps *caps;
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_CAPS:
@@ -4533,12 +4647,8 @@ pre_eventfunc_check (GstPad * pad, GstEvent * event)
       /* backwards compatibility mode for caps */
       gst_event_parse_caps (event, &caps);
 
-      /* See if pad accepts the caps */
-      templ = gst_pad_get_pad_template_caps (pad);
-      if (!gst_caps_is_subset (caps, templ))
+      if (!gst_pad_query_accept_caps (pad, caps))
         goto not_accepted;
-
-      gst_caps_unref (templ);
       break;
     }
     default:
@@ -4549,11 +4659,8 @@ pre_eventfunc_check (GstPad * pad, GstEvent * event)
   /* ERRORS */
 not_accepted:
   {
-    gst_caps_unref (templ);
     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
         "caps %" GST_PTR_FORMAT " not accepted", caps);
-    GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
-        "no intersection with template %" GST_PTR_FORMAT, templ);
     return GST_FLOW_NOT_NEGOTIATED;
   }
 }
@@ -4595,6 +4702,7 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
       /* Remove pending EOS events */
       GST_LOG_OBJECT (pad, "Removing pending EOS events");
       remove_event_by_type (pad, GST_EVENT_EOS);
+      GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_EOS);
 
       GST_OBJECT_UNLOCK (pad);
       /* grab stream lock */
@@ -4615,6 +4723,9 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
         goto flushing;
 
       if (serialized) {
+        if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+          goto eos;
+
         /* lock order: STREAM_LOCK, LOCK, recheck flushing. */
         GST_OBJECT_UNLOCK (pad);
         GST_PAD_STREAM_LOCK (pad);
@@ -4622,6 +4733,9 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
         GST_OBJECT_LOCK (pad);
         if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
           goto flushing;
+
+        if (G_UNLIKELY (GST_PAD_IS_EOS (pad)))
+          goto eos;
       }
 
       switch (GST_EVENT_TYPE (event)) {
@@ -4676,6 +4790,8 @@ gst_pad_send_event_unchecked (GstPad * pad, GstEvent * event,
       /* after the event function accepted the event, we can store the sticky
        * event on the pad */
       gst_pad_store_sticky_event (pad, event, FALSE);
+      if (event_type == GST_EVENT_EOS)
+        GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_EOS);
     }
     gst_event_unref (event);
   }
@@ -4696,6 +4812,16 @@ flushing:
     gst_event_unref (event);
     return GST_FLOW_FLUSHING;
   }
+eos:
+  {
+    GST_OBJECT_UNLOCK (pad);
+    if (need_unlock)
+      GST_PAD_STREAM_UNLOCK (pad);
+    GST_CAT_INFO_OBJECT (GST_CAT_EVENT, pad,
+        "Received event on EOS pad. Discarding");
+    gst_event_unref (event);
+    return GST_FLOW_EOS;
+  }
 probe_stopped:
   {
     GST_OBJECT_UNLOCK (pad);