mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 23:58:17 +00:00
tee: Make sure to give pads the name that was requested
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.
This commit is contained in:
parent
f15f4ec8aa
commit
24a3102b21
2 changed files with 41 additions and 3 deletions
|
@ -51,6 +51,7 @@
|
||||||
#include "gst/glib-compat-private.h"
|
#include "gst/glib-compat-private.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
|
@ -131,6 +132,7 @@ struct _GstTeePad
|
||||||
{
|
{
|
||||||
GstPad parent;
|
GstPad parent;
|
||||||
|
|
||||||
|
guint index;
|
||||||
gboolean pushed;
|
gboolean pushed;
|
||||||
GstFlowReturn result;
|
GstFlowReturn result;
|
||||||
gboolean removed;
|
gboolean removed;
|
||||||
|
@ -214,6 +216,8 @@ gst_tee_finalize (GObject * object)
|
||||||
|
|
||||||
tee = GST_TEE (object);
|
tee = GST_TEE (object);
|
||||||
|
|
||||||
|
g_hash_table_unref (tee->pad_indexes);
|
||||||
|
|
||||||
g_free (tee->last_message);
|
g_free (tee->last_message);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
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_OBJECT_FLAG_SET (tee->sinkpad, GST_PAD_FLAG_PROXY_CAPS);
|
||||||
gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad);
|
||||||
|
|
||||||
|
tee->pad_indexes = g_hash_table_new (NULL, NULL);
|
||||||
|
|
||||||
tee->last_message = NULL;
|
tee->last_message = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,24 +321,48 @@ forward_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
|
||||||
|
|
||||||
static GstPad *
|
static GstPad *
|
||||||
gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
||||||
const gchar * unused, const GstCaps * caps)
|
const gchar * name_templ, const GstCaps * caps)
|
||||||
{
|
{
|
||||||
gchar *name;
|
gchar *name;
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
GstTee *tee;
|
GstTee *tee;
|
||||||
GstPadMode mode;
|
GstPadMode mode;
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
guint index = 0;
|
||||||
|
|
||||||
tee = GST_TEE (element);
|
tee = GST_TEE (element);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (tee, "requesting pad");
|
GST_DEBUG_OBJECT (tee, "requesting pad");
|
||||||
|
|
||||||
GST_OBJECT_LOCK (tee);
|
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,
|
srcpad = GST_PAD_CAST (g_object_new (GST_TYPE_TEE_PAD,
|
||||||
"name", name, "direction", templ->direction, "template", templ,
|
"name", name, "direction", templ->direction, "template", templ,
|
||||||
NULL));
|
NULL));
|
||||||
|
GST_TEE_PAD_CAST (srcpad)->index = index;
|
||||||
g_free (name);
|
g_free (name);
|
||||||
|
|
||||||
mode = tee->sink_mode;
|
mode = tee->sink_mode;
|
||||||
|
@ -391,12 +421,14 @@ gst_tee_release_pad (GstElement * element, GstPad * pad)
|
||||||
{
|
{
|
||||||
GstTee *tee;
|
GstTee *tee;
|
||||||
gboolean changed = FALSE;
|
gboolean changed = FALSE;
|
||||||
|
guint index;
|
||||||
|
|
||||||
tee = GST_TEE (element);
|
tee = GST_TEE (element);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (tee, "releasing pad");
|
GST_DEBUG_OBJECT (tee, "releasing pad");
|
||||||
|
|
||||||
GST_OBJECT_LOCK (tee);
|
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. */
|
/* mark the pad as removed so that future pad_alloc fails with NOT_LINKED. */
|
||||||
GST_TEE_PAD_CAST (pad)->removed = TRUE;
|
GST_TEE_PAD_CAST (pad)->removed = TRUE;
|
||||||
if (tee->allocpad == pad) {
|
if (tee->allocpad == pad) {
|
||||||
|
@ -415,6 +447,10 @@ gst_tee_release_pad (GstElement * element, GstPad * pad)
|
||||||
if (changed) {
|
if (changed) {
|
||||||
gst_tee_notify_alloc_pad (tee);
|
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
|
static void
|
||||||
|
|
|
@ -68,7 +68,9 @@ struct _GstTee {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GstPad *sinkpad;
|
GstPad *sinkpad;
|
||||||
GstPad *allocpad;
|
GstPad *allocpad;
|
||||||
guint pad_counter;
|
|
||||||
|
GHashTable *pad_indexes;
|
||||||
|
guint next_pad_index;
|
||||||
|
|
||||||
gboolean has_chain;
|
gboolean has_chain;
|
||||||
gboolean silent;
|
gboolean silent;
|
||||||
|
|
Loading…
Reference in a new issue