element: Enforce that elements created by gst_element_factory_create/make() are floating
[platform/upstream/gstreamer.git] / gst / gstelement.c
index 28ff49d..64aa39a 100644 (file)
@@ -403,7 +403,7 @@ gst_element_set_clock_func (GstElement * element, GstClock * clock)
 /**
  * gst_element_set_clock:
  * @element: a #GstElement to set the clock for.
- * @clock: the #GstClock to set for the element.
+ * @clock: (transfer none) (allow-none): the #GstClock to set for the element.
  *
  * Sets the clock for the element. This function increases the
  * refcount on the clock. Any previously set clock on the object
@@ -444,7 +444,7 @@ gst_element_set_clock (GstElement * element, GstClock * clock)
  * Elements in a pipeline will only have their clock set when the
  * pipeline is in the PLAYING state.
  *
- * Returns: (transfer full): the #GstClock of the element. unref after usage.
+ * Returns: (transfer full) (nullable): the #GstClock of the element. unref after usage.
  *
  * MT safe.
  */
@@ -640,9 +640,8 @@ gst_element_get_index (GstElement * element)
  * Adds a pad (link point) to @element. @pad's parent will be set to @element;
  * see gst_object_set_parent() for refcounting information.
  *
- * Pads are not automatically activated so elements should perform the needed
- * steps to activate the pad in case this pad is added in the PAUSED or PLAYING
- * state. See gst_pad_set_active() for more information about activating pads.
+ * Pads are automatically activated when added in the PAUSED or PLAYING
+ * state.
  *
  * The pad and the element should be unlocked when calling this function.
  *
@@ -685,9 +684,6 @@ gst_element_add_pad (GstElement * element, GstPad * pad)
   /* check for active pads */
   if (!active && (GST_STATE (element) > GST_STATE_READY ||
           GST_STATE_NEXT (element) == GST_STATE_PAUSED)) {
-    g_warning ("adding inactive pad '%s' to running element '%s', you need to "
-        "use gst_pad_set_active(pad,TRUE) before adding it.",
-        GST_STR_NULL (pad_name), GST_ELEMENT_NAME (element));
     gst_pad_set_active (pad, TRUE);
   }
 
@@ -751,7 +747,7 @@ no_direction:
 /**
  * gst_element_remove_pad:
  * @element: a #GstElement to remove pad from.
- * @pad: (transfer full): the #GstPad to remove from the element.
+ * @pad: (transfer none): the #GstPad to remove from the element.
  *
  * Removes @pad from @element. @pad will be destroyed if it has not been
  * referenced elsewhere using gst_object_unparent().
@@ -1247,6 +1243,121 @@ gst_element_iterate_sink_pads (GstElement * element)
   return gst_element_iterate_pad_list (element, &element->sinkpads);
 }
 
+static gboolean
+gst_element_do_foreach_pad (GstElement * element,
+    GstElementForeachPadFunc func, gpointer user_data,
+    GList ** p_pads, guint16 * p_npads)
+{
+  gboolean ret = TRUE;
+  GstPad **pads;
+  guint n_pads, i;
+  GList *l;
+
+  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
+  g_return_val_if_fail (func != NULL, FALSE);
+
+  GST_OBJECT_LOCK (element);
+  n_pads = *p_npads;
+  pads = g_newa (GstPad *, n_pads + 1);
+  for (l = *p_pads, i = 0; l != NULL; l = l->next) {
+    g_assert (i < n_pads);
+    pads[i++] = gst_object_ref (l->data);
+  }
+  GST_OBJECT_UNLOCK (element);
+
+  if (n_pads == 0)
+    return FALSE;
+
+  for (i = 0; i < n_pads; ++i) {
+    ret = func (element, pads[i], user_data);
+    if (!ret)
+      break;
+  }
+
+  for (i = 0; i < n_pads; ++i)
+    gst_object_unref (pads[i]);
+
+  return ret;
+}
+
+/**
+ * gst_element_foreach_sink_pad:
+ * @element: a #GstElement to iterate sink pads of
+ * @func: (scope call): function to call for each sink pad
+ * @user_data: (closure): user data passed to @func
+ *
+ * Call @func with @user_data for each of @element's sink pads. @func will be
+ * called exactly once for each sink pad that exists at the time of this call,
+ * unless one of the calls to @func returns %FALSE in which case we will stop
+ * iterating pads and return early. If new sink pads are added or sink pads
+ * are removed while the sink pads are being iterated, this will not be taken
+ * into account until next time this function is used.
+ *
+ * Returns: %FALSE if @element had no sink pads or if one of the calls to @func
+ *   returned %FALSE.
+ *
+ * Since: 1.14
+ */
+gboolean
+gst_element_foreach_sink_pad (GstElement * element,
+    GstElementForeachPadFunc func, gpointer user_data)
+{
+  return gst_element_do_foreach_pad (element, func, user_data,
+      &element->sinkpads, &element->numsinkpads);
+}
+
+/**
+ * gst_element_foreach_src_pad:
+ * @element: a #GstElement to iterate source pads of
+ * @func: (scope call): function to call for each source pad
+ * @user_data: (closure): user data passed to @func
+ *
+ * Call @func with @user_data for each of @element's source pads. @func will be
+ * called exactly once for each source pad that exists at the time of this call,
+ * unless one of the calls to @func returns %FALSE in which case we will stop
+ * iterating pads and return early. If new source pads are added or source pads
+ * are removed while the source pads are being iterated, this will not be taken
+ * into account until next time this function is used.
+ *
+ * Returns: %FALSE if @element had no source pads or if one of the calls
+ *   to @func returned %FALSE.
+ *
+ * Since: 1.14
+ */
+gboolean
+gst_element_foreach_src_pad (GstElement * element,
+    GstElementForeachPadFunc func, gpointer user_data)
+{
+  return gst_element_do_foreach_pad (element, func, user_data,
+      &element->srcpads, &element->numsrcpads);
+}
+
+/**
+ * gst_element_foreach_pad:
+ * @element: a #GstElement to iterate pads of
+ * @func: (scope call): function to call for each pad
+ * @user_data: (closure): user data passed to @func
+ *
+ * Call @func with @user_data for each of @element's pads. @func will be called
+ * exactly once for each pad that exists at the time of this call, unless
+ * one of the calls to @func returns %FALSE in which case we will stop
+ * iterating pads and return early. If new pads are added or pads are removed
+ * while pads are being iterated, this will not be taken into account until
+ * next time this function is used.
+ *
+ * Returns: %FALSE if @element had no pads or if one of the calls to @func
+ *   returned %FALSE.
+ *
+ * Since: 1.14
+ */
+gboolean
+gst_element_foreach_pad (GstElement * element, GstElementForeachPadFunc func,
+    gpointer user_data)
+{
+  return gst_element_do_foreach_pad (element, func, user_data,
+      &element->pads, &element->numpads);
+}
+
 /**
  * gst_element_class_add_pad_template:
  * @klass: the #GstElementClass to add the pad template to.
@@ -1312,6 +1423,28 @@ gst_element_class_add_static_pad_template (GstElementClass * klass,
 }
 
 /**
+ * gst_element_class_add_static_pad_template_with_gtype:
+ * @klass: the #GstElementClass to add the pad template to.
+ * @static_templ: #GstStaticPadTemplate to add as pad template to the element class.
+ * @pad_type: The #GType of the pad to create
+ *
+ * Adds a pad template to an element class based on the static pad template
+ * @templ. This is mainly used in the _class_init functions of element
+ * implementations. If a pad template with the same name already exists,
+ * the old one is replaced by the new one.
+ *
+ * Since: 1.14
+ */
+void
+gst_element_class_add_static_pad_template_with_gtype (GstElementClass * klass,
+    GstStaticPadTemplate * static_templ, GType pad_type)
+{
+  gst_element_class_add_pad_template (klass,
+      gst_pad_template_new_from_static_pad_template_with_gtype (static_templ,
+          pad_type));
+}
+
+/**
  * gst_element_class_add_metadata:
  * @klass: class to set metadata for
  * @key: the key to set
@@ -1462,6 +1595,26 @@ gst_element_class_get_metadata (GstElementClass * klass, const gchar * key)
 }
 
 /**
+ * gst_element_get_metadata:
+ * @element: class to get metadata for
+ * @key: the key to get
+ *
+ * Get metadata with @key in @klass.
+ *
+ * Returns: the metadata for @key.
+ *
+ * Since: 1.14
+ */
+const gchar *
+gst_element_get_metadata (GstElement * element, const gchar * key)
+{
+  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  return gst_element_class_get_metadata (GST_ELEMENT_GET_CLASS (element), key);
+}
+
+/**
  * gst_element_class_get_pad_template_list:
  * @element_class: a #GstElementClass to get pad templates of.
  *
@@ -1483,6 +1636,27 @@ gst_element_class_get_pad_template_list (GstElementClass * element_class)
 }
 
 /**
+ * gst_element_get_pad_template_list:
+ * @element: a #GstElement to get pad templates of.
+ *
+ * Retrieves a list of the pad templates associated with @element. The
+ * list must not be modified by the calling code.
+ *
+ * Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
+ *     pad templates.
+ *
+ * Since: 1.14
+ */
+GList *
+gst_element_get_pad_template_list (GstElement * element)
+{
+  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+
+  return
+      gst_element_class_get_pad_template_list (GST_ELEMENT_GET_CLASS (element));
+}
+
+/**
  * gst_element_class_get_pad_template:
  * @element_class: a #GstElementClass to get the pad template of.
  * @name: the name of the #GstPadTemplate to get.
@@ -1519,6 +1693,29 @@ gst_element_class_get_pad_template (GstElementClass *
   return NULL;
 }
 
+/**
+ * gst_element_get_pad_template:
+ * @element: a #GstElement to get the pad template of.
+ * @name: the name of the #GstPadTemplate to get.
+ *
+ * Retrieves a padtemplate from @element with the given name.
+ *
+ * Returns: (transfer none) (nullable): the #GstPadTemplate with the
+ *     given name, or %NULL if none was found. No unreferencing is
+ *     necessary.
+ *
+ * Since: 1.14
+ */
+GstPadTemplate *
+gst_element_get_pad_template (GstElement * element, const gchar * name)
+{
+  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+
+  return gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (element),
+      name);
+}
+
 static GstPadTemplate *
 gst_element_class_get_request_pad_template (GstElementClass *
     element_class, const gchar * name)
@@ -1533,7 +1730,7 @@ gst_element_class_get_request_pad_template (GstElementClass *
 }
 
 /* get a random pad on element of the given direction.
- * The pad is random in a sense that it is the first pad that is (optionaly) linked.
+ * The pad is random in a sense that it is the first pad that is (optionally) linked.
  */
 static GstPad *
 gst_element_get_random_pad (GstElement * element,
@@ -2044,6 +2241,10 @@ gst_element_is_locked_state (GstElement * element)
  * Locks the state of an element, so state changes of the parent don't affect
  * this element anymore.
  *
+ * Note that this is racy if the state lock of the parent bin is not taken.
+ * The parent bin might've just checked the flag in another thread and as the
+ * next step proceed to change the child element's state.
+ *
  * MT safe.
  *
  * Returns: %TRUE if the state was changed, %FALSE if bad parameters were given
@@ -2247,7 +2448,7 @@ interrupted:
     if (pending)
       *pending = GST_STATE_VOID_PENDING;
 
-    GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interruped");
+    GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interrupted");
 
     GST_OBJECT_UNLOCK (element);
 
@@ -2785,14 +2986,14 @@ gst_element_change_state (GstElement * element, GstStateChange transition)
     case GST_STATE_CHANGE_SUCCESS:
       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
           "element changed state SUCCESS");
-      /* we can commit the state now which will proceeed to
+      /* we can commit the state now which will proceed to
        * the next state */
       ret = gst_element_continue_state (element, ret);
       break;
     case GST_STATE_CHANGE_NO_PREROLL:
       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
           "element changed state NO_PREROLL");
-      /* we can commit the state now which will proceeed to
+      /* we can commit the state now which will proceed to
        * the next state */
       ret = gst_element_continue_state (element, ret);
       break;
@@ -3025,8 +3226,8 @@ was_ok:
  *
  * Retrieves the factory that was used to create this element.
  *
- * Returns: (transfer none): the #GstElementFactory used for creating this
- *     element. no refcounting is needed.
+ * Returns: (transfer none) (nullable): the #GstElementFactory used for creating this
+ *     element or %NULL if element has not been registered (static element). no refcounting is needed.
  */
 GstElementFactory *
 gst_element_get_factory (GstElement * element)
@@ -3153,7 +3354,7 @@ gst_element_set_bus_func (GstElement * element, GstBus * bus)
 /**
  * gst_element_set_bus:
  * @element: a #GstElement to set the bus of.
- * @bus: (transfer none): the #GstBus to set.
+ * @bus: (transfer none) (allow-none): the #GstBus to set.
  *
  * Sets the bus of the element. Increases the refcount on the bus.
  * For internal use only, unless you're testing elements.
@@ -3180,7 +3381,8 @@ gst_element_set_bus (GstElement * element, GstBus * bus)
  * Returns the bus of the element. Note that only a #GstPipeline will provide a
  * bus for the application.
  *
- * Returns: (transfer full): the element's #GstBus. unref after usage.
+ * Returns: (transfer full) (nullable): the element's #GstBus. unref after
+ * usage.
  *
  * MT safe.
  */
@@ -3304,7 +3506,7 @@ _match_context_type (GstContext * c1, const gchar * context_type)
  *
  * Gets the context with @context_type set on the element or NULL.
  *
- * Returns: (transfer full): A #GstContext or NULL
+ * Returns: (transfer full) (nullable): A #GstContext or NULL
  *
  * Since: 1.8
  */