gst: Don't pass miniobjects to GST_DEBUG_OBJECT() and similar macros
[platform/upstream/gstreamer.git] / gst / gstghostpad.c
index fc59af1..ffbe650 100644 (file)
@@ -24,6 +24,7 @@
 
 /**
  * SECTION:gstghostpad
+ * @title: GstGhostPad
  * @short_description: Pseudo link pads
  * @see_also: #GstPad
  *
@@ -40,8 +41,6 @@
  * association later on.
  *
  * Note that GhostPads add overhead to the data processing of a pipeline.
- *
- * Last reviewed on 2005-11-18 (0.9.5)
  */
 
 #include "gst_private.h"
@@ -70,19 +69,19 @@ struct _GstProxyPadPrivate
   GstPad *internal;
 };
 
-G_DEFINE_TYPE (GstProxyPad, gst_proxy_pad, GST_TYPE_PAD);
+G_DEFINE_TYPE_WITH_PRIVATE (GstProxyPad, gst_proxy_pad, GST_TYPE_PAD);
 
 static GstPad *gst_proxy_pad_get_target (GstPad * pad);
 
 /**
  * gst_proxy_pad_iterate_internal_links_default:
  * @pad: the #GstPad to get the internal links of.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
  *
  * Invoke the default iterate internal links function of the proxy pad.
  *
- * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
- * returned pad with gst_object_unref().
+ * Returns: (nullable): a #GstIterator of #GstPad, or %NULL if @pad
+ * has no parent. Unref each returned pad with gst_object_unref().
  */
 GstIterator *
 gst_proxy_pad_iterate_internal_links_default (GstPad * pad, GstObject * parent)
@@ -106,7 +105,7 @@ gst_proxy_pad_iterate_internal_links_default (GstPad * pad, GstObject * parent)
 /**
  * gst_proxy_pad_chain_default:
  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
  * @buffer: (transfer full): the #GstBuffer to send, return GST_FLOW_ERROR
  *     if not.
  *
@@ -134,7 +133,7 @@ gst_proxy_pad_chain_default (GstPad * pad, GstObject * parent,
 /**
  * gst_proxy_pad_chain_list_default:
  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
  * @list: (transfer full): the #GstBufferList to send, return GST_FLOW_ERROR
  *     if not.
  *
@@ -195,9 +194,7 @@ gst_proxy_pad_get_target (GstPad * pad)
   GstPad *target;
 
   GST_OBJECT_LOCK (pad);
-  target = GST_PROXY_PAD_TARGET (pad);
-  if (target)
-    gst_object_ref (target);
+  target = gst_pad_get_peer (GST_PROXY_PAD_INTERNAL (pad));
   GST_OBJECT_UNLOCK (pad);
 
   return target;
@@ -212,8 +209,8 @@ gst_proxy_pad_get_target (GstPad * pad)
  * The internal pad of a #GstGhostPad is the internally used
  * pad of opposite direction, which is used to link to the target.
  *
- * Returns: (transfer full): the target #GstProxyPad, can be NULL.
- * Unref target pad after usage.
+ * Returns: (transfer full) (nullable): the target #GstProxyPad, can
+ * be %NULL.  Unref target pad after usage.
  */
 GstProxyPad *
 gst_proxy_pad_get_internal (GstProxyPad * pad)
@@ -234,8 +231,6 @@ gst_proxy_pad_get_internal (GstProxyPad * pad)
 static void
 gst_proxy_pad_class_init (GstProxyPadClass * klass)
 {
-  g_type_class_add_private (klass, sizeof (GstProxyPadPrivate));
-
   /* Register common function pointer descriptions */
   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_iterate_internal_links_default);
   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_default);
@@ -248,8 +243,7 @@ gst_proxy_pad_init (GstProxyPad * ppad)
 {
   GstPad *pad = (GstPad *) ppad;
 
-  GST_PROXY_PAD_PRIVATE (ppad) = G_TYPE_INSTANCE_GET_PRIVATE (ppad,
-      GST_TYPE_PROXY_PAD, GstProxyPadPrivate);
+  GST_PROXY_PAD_PRIVATE (ppad) = gst_proxy_pad_get_instance_private (ppad);
 
   gst_pad_set_iterate_internal_links_function (pad,
       gst_proxy_pad_iterate_internal_links_default);
@@ -273,7 +267,7 @@ struct _GstGhostPadPrivate
   gboolean constructed;
 };
 
-G_DEFINE_TYPE (GstGhostPad, gst_ghost_pad, GST_TYPE_PROXY_PAD);
+G_DEFINE_TYPE_WITH_PRIVATE (GstGhostPad, gst_ghost_pad, GST_TYPE_PROXY_PAD);
 
 static void gst_ghost_pad_dispose (GObject * object);
 
@@ -322,10 +316,13 @@ gst_ghost_pad_internal_activate_pull_default (GstPad * pad, GstObject * parent,
     GST_LOG_OBJECT (pad, "activating peer");
     ret = gst_pad_activate_mode (other, GST_PAD_MODE_PULL, active);
     gst_object_unref (other);
-  } else {
+  } else if (active) {
     /* this is failure, we can't activate pull if there is no peer */
     GST_LOG_OBJECT (pad, "not src and no peer, failing");
     ret = FALSE;
+  } else {
+    GST_LOG_OBJECT (pad, "deactivating pull, with no peer - allowing");
+    ret = TRUE;
   }
 
   return ret;
@@ -334,7 +331,7 @@ gst_ghost_pad_internal_activate_pull_default (GstPad * pad, GstObject * parent,
 /**
  * gst_ghost_pad_internal_activate_mode_default:
  * @pad: the #GstPad to activate or deactivate.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
  * @mode: the requested activation mode
  * @active: whether the pad should be active or not.
  *
@@ -410,10 +407,13 @@ gst_ghost_pad_activate_pull_default (GstPad * pad, GstObject * parent,
     GST_LOG_OBJECT (pad, "activating peer");
     ret = gst_pad_activate_mode (other, GST_PAD_MODE_PULL, active);
     gst_object_unref (other);
-  } else {
-    /* no peer, we fail */
-    GST_LOG_OBJECT (pad, "pad not src and no peer, failing");
+  } else if (active) {
+    /* this is failure, we can't activate pull if there is no peer */
+    GST_LOG_OBJECT (pad, "not src and no peer, failing");
     ret = FALSE;
+  } else {
+    GST_LOG_OBJECT (pad, "deactivating pull, with no peer - allowing");
+    ret = TRUE;
   }
 
   return ret;
@@ -422,7 +422,7 @@ gst_ghost_pad_activate_pull_default (GstPad * pad, GstObject * parent,
 /**
  * gst_ghost_pad_activate_mode_default:
  * @pad: the #GstPad to activate or deactivate.
- * @parent: (allow-none): the parent of @pad or NULL
+ * @parent: (allow-none): the parent of @pad or %NULL
  * @mode: the requested activation mode
  * @active: whether the pad should be active or not.
  *
@@ -458,8 +458,6 @@ gst_ghost_pad_class_init (GstGhostPadClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
 
-  g_type_class_add_private (klass, sizeof (GstGhostPadPrivate));
-
   gobject_class->dispose = gst_ghost_pad_dispose;
 
   GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_pull_default);
@@ -469,8 +467,7 @@ gst_ghost_pad_class_init (GstGhostPadClass * klass)
 static void
 gst_ghost_pad_init (GstGhostPad * pad)
 {
-  GST_GHOST_PAD_PRIVATE (pad) = G_TYPE_INSTANCE_GET_PRIVATE (pad,
-      GST_TYPE_GHOST_PAD, GstGhostPadPrivate);
+  GST_GHOST_PAD_PRIVATE (pad) = gst_ghost_pad_get_instance_private (pad);
 
   gst_pad_set_activatemode_function (GST_PAD_CAST (pad),
       gst_ghost_pad_activate_mode_default);
@@ -503,13 +500,16 @@ gst_ghost_pad_dispose (GObject * object)
 
   GST_OBJECT_LOCK (pad);
   internal = GST_PROXY_PAD_INTERNAL (pad);
+  if (internal) {
+    gst_pad_set_activatemode_function (internal, NULL);
 
-  gst_pad_set_activatemode_function (internal, NULL);
+    GST_PROXY_PAD_INTERNAL (pad) = NULL;
+    GST_PROXY_PAD_INTERNAL (internal) = NULL;
 
-  /* disposes of the internal pad, since the ghostpad is the only possible object
-   * that has a refcount on the internal pad. */
-  gst_object_unparent (GST_OBJECT_CAST (internal));
-  GST_PROXY_PAD_INTERNAL (pad) = NULL;
+    /* disposes of the internal pad, since the ghostpad is the only possible object
+     * that has a refcount on the internal pad. */
+    gst_object_unparent (GST_OBJECT_CAST (internal));
+  }
 
   GST_OBJECT_UNLOCK (pad);
 
@@ -537,8 +537,7 @@ gst_ghost_pad_construct (GstGhostPad * gpad)
   GstPad *pad, *internal;
 
   g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
-  g_return_val_if_fail (GST_GHOST_PAD_PRIVATE (gpad)->constructed == FALSE,
-      FALSE);
+  g_return_val_if_fail (!GST_GHOST_PAD_PRIVATE (gpad)->constructed, FALSE);
 
   g_object_get (gpad, "direction", &dir, "template", &templ, NULL);
 
@@ -613,7 +612,6 @@ parent_failed:
     g_critical ("Could not set internal pad %s:%s",
         GST_DEBUG_PAD_NAME (internal));
     GST_OBJECT_UNLOCK (pad);
-    gst_object_unref (internal);
     return FALSE;
   }
 }
@@ -623,12 +621,17 @@ gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir,
     GstPadTemplate * templ)
 {
   GstGhostPad *ret;
-
   g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL);
 
   /* OBJECT CREATION */
   if (templ) {
-    ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name,
+    GType pad_type =
+        GST_PAD_TEMPLATE_GTYPE (templ) ==
+        G_TYPE_NONE ? GST_TYPE_GHOST_PAD : GST_PAD_TEMPLATE_GTYPE (templ);
+
+    g_return_val_if_fail (g_type_is_a (pad_type, GST_TYPE_GHOST_PAD), NULL);
+
+    ret = g_object_new (pad_type, "name", name,
         "direction", dir, "template", templ, NULL);
   } else {
     ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name,
@@ -648,7 +651,7 @@ construct_failed:
 
 /**
  * gst_ghost_pad_new_no_target:
- * @name: (allow-none): the name of the new pad, or NULL to assign a default name.
+ * @name: (allow-none): the name of the new pad, or %NULL to assign a default name.
  * @dir: the direction of the ghostpad
  *
  * Create a new ghostpad without a target with the given direction.
@@ -657,7 +660,8 @@ construct_failed:
  *
  * The created ghostpad will not have a padtemplate.
  *
- * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer floating) (nullable): a new #GstPad, or %NULL in
+ * case of an error.
  */
 GstPad *
 gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
@@ -675,7 +679,7 @@ gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
 
 /**
  * gst_ghost_pad_new:
- * @name: (allow-none): the name of the new pad, or NULL to assign a default name
+ * @name: (allow-none): the name of the new pad, or %NULL to assign a default name
  * @target: (transfer none): the pad to ghost.
  *
  * Create a new ghostpad with @target as the target. The direction will be taken
@@ -683,7 +687,8 @@ gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
  *
  * Will ref the target.
  *
- * Returns: (transfer floating): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer floating) (nullable): a new #GstPad, or %NULL in
+ * case of an error.
  */
 GstPad *
 gst_ghost_pad_new (const gchar * name, GstPad * target)
@@ -714,7 +719,7 @@ set_target_failed:
 
 /**
  * gst_ghost_pad_new_from_template:
- * @name: (allow-none): the name of the new pad, or NULL to assign a default name.
+ * @name: (allow-none): the name of the new pad, or %NULL to assign a default name.
  * @target: (transfer none): the pad to ghost.
  * @templ: (transfer none): the #GstPadTemplate to use on the ghostpad.
  *
@@ -723,7 +728,8 @@ set_target_failed:
  *
  * Will ref the target.
  *
- * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer floating) (nullable): a new #GstPad, or %NULL in
+ * case of an error.
  */
 
 GstPad *
@@ -759,13 +765,14 @@ set_target_failed:
 
 /**
  * gst_ghost_pad_new_no_target_from_template:
- * @name: (allow-none): the name of the new pad, or NULL to assign a default name
+ * @name: (allow-none): the name of the new pad, or %NULL to assign a default name
  * @templ: (transfer none): the #GstPadTemplate to create the ghostpad from.
  *
  * Create a new ghostpad based on @templ, without setting a target. The
  * direction will be taken from the @templ.
  *
- * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
+ * Returns: (transfer floating) (nullable): a new #GstPad, or %NULL in
+ * case of an error.
  */
 GstPad *
 gst_ghost_pad_new_no_target_from_template (const gchar * name,
@@ -787,8 +794,9 @@ gst_ghost_pad_new_no_target_from_template (const gchar * name,
  *
  * Get the target pad of @gpad. Unref target pad after usage.
  *
- * Returns: (transfer full): the target #GstPad, can be NULL if the ghostpad
- * has no target set. Unref target pad after usage.
+ * Returns: (transfer full) (nullable): the target #GstPad, can be
+ * %NULL if the ghostpad has no target set. Unref target pad after
+ * usage.
  */
 GstPad *
 gst_ghost_pad_get_target (GstGhostPad * gpad)
@@ -804,26 +812,6 @@ gst_ghost_pad_get_target (GstGhostPad * gpad)
   return ret;
 }
 
-static gboolean
-clear_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
-{
-  GST_DEBUG_OBJECT (pad, "clearing sticky event %" GST_PTR_FORMAT, *event);
-  gst_event_unref (*event);
-  *event = NULL;
-  return TRUE;
-}
-
-static gboolean
-copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
-{
-  GstPad *internal = GST_PAD_CAST (user_data);
-
-  GST_DEBUG_OBJECT (internal, "store sticky event %" GST_PTR_FORMAT, *event);
-  gst_pad_store_sticky_event (internal, *event);
-
-  return TRUE;
-}
-
 /**
  * gst_ghost_pad_set_target:
  * @gpad: the #GstGhostPad
@@ -831,10 +819,10 @@ copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
  *
  * Set the new target of the ghostpad @gpad. Any existing target
  * is unlinked and links to the new target are established. if @newtarget is
- * NULL the target will be cleared.
+ * %NULL the target will be cleared.
  *
- * Returns: (transfer full): TRUE if the new target could be set. This function
- *     can return FALSE when the internal pads could not be linked.
+ * Returns: %TRUE if the new target could be set. This function
+ *     can return %FALSE when the internal pads could not be linked.
  */
 gboolean
 gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
@@ -845,18 +833,24 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
 
   g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
   g_return_val_if_fail (GST_PAD_CAST (gpad) != newtarget, FALSE);
-  g_return_val_if_fail (newtarget != GST_PROXY_PAD_INTERNAL (gpad), FALSE);
 
   GST_OBJECT_LOCK (gpad);
   internal = GST_PROXY_PAD_INTERNAL (gpad);
 
+  if (newtarget == internal) {
+    GST_OBJECT_UNLOCK (gpad);
+    GST_WARNING_OBJECT (gpad, "Target has already been set to %s:%s",
+        GST_DEBUG_PAD_NAME (newtarget));
+    return TRUE;
+  }
+
   if (newtarget)
     GST_DEBUG_OBJECT (gpad, "set target %s:%s", GST_DEBUG_PAD_NAME (newtarget));
   else
     GST_DEBUG_OBJECT (gpad, "clearing target");
 
   /* clear old target */
-  if ((oldtarget = GST_PROXY_PAD_TARGET (gpad))) {
+  if ((oldtarget = gst_pad_get_peer (internal))) {
     GST_OBJECT_UNLOCK (gpad);
 
     /* unlink internal pad */
@@ -865,13 +859,7 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
     else
       gst_pad_unlink (oldtarget, internal);
 
-    if (GST_PAD_IS_SRC (gpad)) {
-      /* only clear the events on the SRC ghostpad. We don't clear sink
-       * ghostpads, they got their events from downstream and we want to
-       * set the same events on the target later. */
-      gst_pad_sticky_events_foreach (GST_PAD_CAST (gpad), clear_sticky_events,
-          NULL);
-    }
+    gst_object_unref (oldtarget);
   } else {
     GST_OBJECT_UNLOCK (gpad);
   }
@@ -890,13 +878,6 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
 
     if (lret != GST_PAD_LINK_OK)
       goto link_failed;
-
-    if (GST_PAD_IS_SRC (gpad)) {
-      /* only copy the events to the SRC ghostpad. We don't copy to sink
-       * ghostpads, they got their events from downstream and we don't want
-       * to overwrite those with events from this new target. */
-      gst_pad_sticky_events_foreach (newtarget, copy_sticky_events, gpad);
-    }
   }
 
   return TRUE;
@@ -904,8 +885,8 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
   /* ERRORS */
 link_failed:
   {
-    GST_WARNING_OBJECT (gpad, "could not link internal and target, reason:%d",
-        lret);
+    GST_WARNING_OBJECT (gpad, "could not link internal and target, reason:%s",
+        gst_pad_link_get_name (lret));
     return FALSE;
   }
 }