tee: Make sure to give pads the name that was requested
authorSebastian Dröge <sebastian@centricular.com>
Tue, 14 Jan 2014 15:45:53 +0000 (16:45 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Tue, 14 Jan 2014 15:45:53 +0000 (16:45 +0100)
Also check for uniqueness and make sure we create a new
pad index properly if some were requested with names but
the new one is not.

plugins/elements/gsttee.c
plugins/elements/gsttee.h

index d45b483..308d4e3 100644 (file)
@@ -51,6 +51,7 @@
 #include "gst/glib-compat-private.h"
 
 #include <string.h>
+#include <stdio.h>
 
 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
@@ -131,6 +132,7 @@ struct _GstTeePad
 {
   GstPad parent;
 
+  guint index;
   gboolean pushed;
   GstFlowReturn result;
   gboolean removed;
@@ -214,6 +216,8 @@ gst_tee_finalize (GObject * object)
 
   tee = GST_TEE (object);
 
+  g_hash_table_unref (tee->pad_indexes);
+
   g_free (tee->last_message);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -294,6 +298,8 @@ gst_tee_init (GstTee * tee)
   GST_OBJECT_FLAG_SET (tee->sinkpad, GST_PAD_FLAG_PROXY_CAPS);
   gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad);
 
+  tee->pad_indexes = g_hash_table_new (NULL, NULL);
+
   tee->last_message = NULL;
 }
 
@@ -315,24 +321,48 @@ forward_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
 
 static GstPad *
 gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ,
-    const gchar * unused, const GstCaps * caps)
+    const gchar * name_templ, const GstCaps * caps)
 {
   gchar *name;
   GstPad *srcpad;
   GstTee *tee;
   GstPadMode mode;
   gboolean res;
+  guint index = 0;
 
   tee = GST_TEE (element);
 
   GST_DEBUG_OBJECT (tee, "requesting pad");
 
   GST_OBJECT_LOCK (tee);
-  name = g_strdup_printf ("src_%u", tee->pad_counter++);
+
+  if (name_templ) {
+    sscanf (name_templ, "src_%u", &index);
+    GST_LOG_OBJECT (element, "name: %s (index %d)", name_templ, index);
+    if (g_hash_table_contains (tee->pad_indexes, GUINT_TO_POINTER (index))) {
+      GST_ERROR_OBJECT (element, "pad name %s is not unique", name_templ);
+      GST_OBJECT_UNLOCK (tee);
+      return NULL;
+    }
+    if (index >= tee->next_pad_index)
+      tee->next_pad_index = index + 1;
+  } else {
+    index = tee->next_pad_index;
+
+    while (g_hash_table_contains (tee->pad_indexes, GUINT_TO_POINTER (index)))
+      index++;
+
+    tee->next_pad_index = index + 1;
+  }
+
+  g_hash_table_insert (tee->pad_indexes, GUINT_TO_POINTER (index), NULL);
+
+  name = g_strdup_printf ("src_%u", index);
 
   srcpad = GST_PAD_CAST (g_object_new (GST_TYPE_TEE_PAD,
           "name", name, "direction", templ->direction, "template", templ,
           NULL));
+  GST_TEE_PAD_CAST (srcpad)->index = index;
   g_free (name);
 
   mode = tee->sink_mode;
@@ -391,12 +421,14 @@ gst_tee_release_pad (GstElement * element, GstPad * pad)
 {
   GstTee *tee;
   gboolean changed = FALSE;
+  guint index;
 
   tee = GST_TEE (element);
 
   GST_DEBUG_OBJECT (tee, "releasing pad");
 
   GST_OBJECT_LOCK (tee);
+  index = GST_TEE_PAD_CAST (pad)->index;
   /* mark the pad as removed so that future pad_alloc fails with NOT_LINKED. */
   GST_TEE_PAD_CAST (pad)->removed = TRUE;
   if (tee->allocpad == pad) {
@@ -415,6 +447,10 @@ gst_tee_release_pad (GstElement * element, GstPad * pad)
   if (changed) {
     gst_tee_notify_alloc_pad (tee);
   }
+
+  GST_OBJECT_LOCK (tee);
+  g_hash_table_remove (tee->pad_indexes, GUINT_TO_POINTER (index));
+  GST_OBJECT_UNLOCK (tee);
 }
 
 static void
index 3f408cb..ed488ae 100644 (file)
@@ -68,7 +68,9 @@ struct _GstTee {
   /*< private >*/
   GstPad         *sinkpad;
   GstPad         *allocpad;
-  guint           pad_counter;
+
+  GHashTable     *pad_indexes;
+  guint           next_pad_index;
 
   gboolean        has_chain;
   gboolean        silent;