mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 11:55:39 +00:00
element: Allow multiple conversion specifiers for request pads
This allows pad template names like "src_%u_%u", but it does not allow multiple specifiers of string type %s as that would lead to ambiguities. https://bugzilla.gnome.org/show_bug.cgi?id=761225
This commit is contained in:
parent
83cac0f7b6
commit
f80dfc9b06
4 changed files with 466 additions and 98 deletions
200
gst/gstelement.c
200
gst/gstelement.c
|
@ -920,6 +920,119 @@ gst_element_get_static_pad (GstElement * element, const gchar * name)
|
|||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_element_is_valid_request_template_name (const gchar * templ_name,
|
||||
const gchar * name)
|
||||
{
|
||||
gchar *endptr;
|
||||
const gchar *templ_name_ptr, *name_ptr;
|
||||
gboolean next_specifier;
|
||||
guint templ_postfix_len = 0, name_postfix_len = 0;
|
||||
|
||||
g_return_val_if_fail (templ_name != NULL, FALSE);
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
/* Is this the template name? */
|
||||
if (strcmp (templ_name, name) == 0)
|
||||
return TRUE;
|
||||
|
||||
/* otherwise check all the specifiers */
|
||||
do {
|
||||
/* Because of sanity checks in gst_pad_template_new(), we know that %s
|
||||
* and %d and %u, occurring at the template_name */
|
||||
templ_name_ptr = strchr (templ_name, '%');
|
||||
|
||||
/* check characters ahead of the specifier */
|
||||
if (!templ_name_ptr || strlen (name) <= templ_name_ptr - templ_name
|
||||
|| strncmp (templ_name, name, templ_name_ptr - templ_name) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* %s is not allowed for multiple specifiers, just a single specifier can be
|
||||
* accepted in gst_pad_template_new() and can not be mixed with other
|
||||
* specifier '%u' and '%d' */
|
||||
if (*(templ_name_ptr + 1) == 's' && g_strcmp0 (templ_name, name) == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
name_ptr = name + (templ_name_ptr - templ_name);
|
||||
|
||||
/* search next specifier, each of specifier should be separated by '_' */
|
||||
templ_name = strchr (templ_name_ptr, '_');
|
||||
name = strchr (name_ptr, '_');
|
||||
|
||||
/* don't match the number of specifiers */
|
||||
if ((templ_name && !name) || (!templ_name && name))
|
||||
return FALSE;
|
||||
|
||||
if (templ_name && name)
|
||||
next_specifier = TRUE;
|
||||
else
|
||||
next_specifier = FALSE;
|
||||
|
||||
/* check characters followed by the specifier */
|
||||
if (*(templ_name_ptr + 2) != '\0' && *(templ_name_ptr + 2) != '_') {
|
||||
if (next_specifier) {
|
||||
templ_postfix_len = templ_name - (templ_name_ptr + 2);
|
||||
name_postfix_len = name - name_ptr;
|
||||
} else {
|
||||
templ_postfix_len = strlen (templ_name_ptr + 2);
|
||||
name_postfix_len = strlen (name_ptr);
|
||||
}
|
||||
|
||||
if (strncmp (templ_name_ptr + 2,
|
||||
name_ptr + name_postfix_len - templ_postfix_len,
|
||||
templ_postfix_len) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* verify the specifier */
|
||||
if (*(name_ptr) == '%') {
|
||||
guint len;
|
||||
|
||||
len = (next_specifier) ? name - name_ptr : strlen (name_ptr);
|
||||
|
||||
if (strncmp (name_ptr, templ_name_ptr, len) != 0)
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
const gchar *specifier;
|
||||
gchar *target = NULL;
|
||||
|
||||
/* extract specifier when it has postfix characters */
|
||||
if (name_postfix_len > templ_postfix_len) {
|
||||
target = g_strndup (name_ptr, name_postfix_len - templ_postfix_len);
|
||||
}
|
||||
specifier = target ? target : name_ptr;
|
||||
|
||||
if (*(templ_name_ptr + 1) == 'd') {
|
||||
gint64 tmp;
|
||||
|
||||
/* it's an int */
|
||||
tmp = g_ascii_strtoll (specifier, &endptr, 10);
|
||||
if (tmp < G_MININT || tmp > G_MAXINT || (*endptr != '\0'
|
||||
&& *endptr != '_'))
|
||||
return FALSE;
|
||||
} else if (*(templ_name_ptr + 1) == 'u') {
|
||||
guint64 tmp;
|
||||
|
||||
/* it's an int */
|
||||
tmp = g_ascii_strtoull (specifier, &endptr, 10);
|
||||
if (tmp > G_MAXUINT || (*endptr != '\0' && *endptr != '_'))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (target);
|
||||
}
|
||||
|
||||
templ_name++;
|
||||
name++;
|
||||
} while (next_specifier);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstPad *
|
||||
_gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
|
||||
const gchar * name, const GstCaps * caps)
|
||||
|
@ -934,38 +1047,8 @@ _gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
|
|||
if (name) {
|
||||
GstPad *pad;
|
||||
|
||||
/* Is this the template name? */
|
||||
if (strstr (name, "%") || !strchr (templ->name_template, '%')) {
|
||||
g_return_val_if_fail (strcmp (name, templ->name_template) == 0, NULL);
|
||||
} else {
|
||||
const gchar *str, *data;
|
||||
gchar *endptr;
|
||||
|
||||
/* Otherwise check if it's a valid name for the name template */
|
||||
str = strchr (templ->name_template, '%');
|
||||
g_return_val_if_fail (str != NULL, NULL);
|
||||
g_return_val_if_fail (strncmp (templ->name_template, name,
|
||||
str - templ->name_template) == 0, NULL);
|
||||
g_return_val_if_fail (strlen (name) > str - templ->name_template, NULL);
|
||||
|
||||
data = name + (str - templ->name_template);
|
||||
|
||||
/* Can either be %s or %d or %u, do sanity checking for %d */
|
||||
if (*(str + 1) == 'd') {
|
||||
gint64 tmp;
|
||||
|
||||
/* it's an int */
|
||||
tmp = g_ascii_strtoll (data, &endptr, 10);
|
||||
g_return_val_if_fail (tmp >= G_MININT && tmp <= G_MAXINT
|
||||
&& *endptr == '\0', NULL);
|
||||
} else if (*(str + 1) == 'u') {
|
||||
guint64 tmp;
|
||||
|
||||
/* it's an int */
|
||||
tmp = g_ascii_strtoull (data, &endptr, 10);
|
||||
g_return_val_if_fail (tmp <= G_MAXUINT && *endptr == '\0', NULL);
|
||||
}
|
||||
}
|
||||
g_return_val_if_fail (gst_element_is_valid_request_template_name
|
||||
(templ->name_template, name), NULL);
|
||||
|
||||
pad = gst_element_get_static_pad (element, name);
|
||||
if (pad) {
|
||||
|
@ -1011,8 +1094,6 @@ gst_element_get_request_pad (GstElement * element, const gchar * name)
|
|||
const gchar *req_name = NULL;
|
||||
gboolean templ_found = FALSE;
|
||||
GList *list;
|
||||
const gchar *data;
|
||||
gchar *str, *endptr = NULL;
|
||||
GstElementClass *class;
|
||||
|
||||
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
|
||||
|
@ -1020,13 +1101,10 @@ gst_element_get_request_pad (GstElement * element, const gchar * name)
|
|||
|
||||
class = GST_ELEMENT_GET_CLASS (element);
|
||||
|
||||
/* if the name contains a %, we assume it's the complete template name. Get
|
||||
* the template and try to get a pad */
|
||||
if (strstr (name, "%")) {
|
||||
templ = gst_element_class_get_request_pad_template (class, name);
|
||||
req_name = NULL;
|
||||
if (templ)
|
||||
templ_found = TRUE;
|
||||
templ = gst_element_class_get_request_pad_template (class, name);
|
||||
if (templ) {
|
||||
req_name = strstr (name, "%") ? NULL : name;
|
||||
templ_found = TRUE;
|
||||
} else {
|
||||
/* there is no % in the name, try to find a matching template */
|
||||
list = class->padtemplates;
|
||||
|
@ -1035,48 +1113,12 @@ gst_element_get_request_pad (GstElement * element, const gchar * name)
|
|||
if (templ->presence == GST_PAD_REQUEST) {
|
||||
GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
|
||||
templ->name_template);
|
||||
/* see if we find an exact match */
|
||||
if (strcmp (name, templ->name_template) == 0) {
|
||||
if (gst_element_is_valid_request_template_name (templ->name_template,
|
||||
name)) {
|
||||
templ_found = TRUE;
|
||||
req_name = name;
|
||||
break;
|
||||
}
|
||||
/* Because of sanity checks in gst_pad_template_new(), we know that %s
|
||||
and %d and %u, occurring at the end of the name_template, are the only
|
||||
possibilities. */
|
||||
else if ((str = strchr (templ->name_template, '%'))
|
||||
&& strncmp (templ->name_template, name,
|
||||
str - templ->name_template) == 0
|
||||
&& strlen (name) > str - templ->name_template) {
|
||||
data = name + (str - templ->name_template);
|
||||
if (*(str + 1) == 'd') {
|
||||
glong tmp;
|
||||
|
||||
/* it's an int */
|
||||
tmp = strtol (data, &endptr, 10);
|
||||
if (tmp != G_MINLONG && tmp != G_MAXLONG && endptr &&
|
||||
*endptr == '\0') {
|
||||
templ_found = TRUE;
|
||||
req_name = name;
|
||||
break;
|
||||
}
|
||||
} else if (*(str + 1) == 'u') {
|
||||
gulong tmp;
|
||||
|
||||
/* it's an int */
|
||||
tmp = strtoul (data, &endptr, 10);
|
||||
if (tmp != G_MAXULONG && endptr && *endptr == '\0') {
|
||||
templ_found = TRUE;
|
||||
req_name = name;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* it's a string */
|
||||
templ_found = TRUE;
|
||||
req_name = name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
|
|
|
@ -221,14 +221,14 @@ gst_pad_template_dispose (GObject * object)
|
|||
* since it doesn't make sense.
|
||||
* SOMETIMES padtemplates can do whatever they want, they are provided by the
|
||||
* element.
|
||||
* REQUEST padtemplates can be reverse-parsed (the user asks for 'sink1', the
|
||||
* 'sink%d' template is automatically selected), so we need to restrict their
|
||||
* naming.
|
||||
* REQUEST padtemplates can have multiple specifiers in case of %d and %u, like
|
||||
* src_%u_%u, but %s only can be used once in the template.
|
||||
*/
|
||||
static gboolean
|
||||
name_is_valid (const gchar * name, GstPadPresence presence)
|
||||
{
|
||||
const gchar *str;
|
||||
const gchar *str, *underscore = NULL;
|
||||
gboolean has_s = FALSE;
|
||||
|
||||
if (presence == GST_PAD_ALWAYS) {
|
||||
if (strchr (name, '%')) {
|
||||
|
@ -237,20 +237,38 @@ name_is_valid (const gchar * name, GstPadPresence presence)
|
|||
return FALSE;
|
||||
}
|
||||
} else if (presence == GST_PAD_REQUEST) {
|
||||
if ((str = strchr (name, '%')) && strchr (str + 1, '%')) {
|
||||
g_warning ("invalid name template %s: only one conversion specification"
|
||||
" allowed in GST_PAD_REQUEST padtemplate", name);
|
||||
return FALSE;
|
||||
}
|
||||
if (str && (*(str + 1) != 's' && *(str + 1) != 'd' && *(str + 1) != 'u')) {
|
||||
g_warning ("invalid name template %s: conversion specification must be of"
|
||||
" type '%%d', '%%u' or '%%s' for GST_PAD_REQUEST padtemplate", name);
|
||||
return FALSE;
|
||||
}
|
||||
if (str && (*(str + 2) != '\0')) {
|
||||
g_warning ("invalid name template %s: conversion specification must"
|
||||
" appear at the end of the GST_PAD_REQUEST padtemplate name", name);
|
||||
return FALSE;
|
||||
str = strchr (name, '%');
|
||||
|
||||
while (str) {
|
||||
if (*(str + 1) != 's' && *(str + 1) != 'd' && *(str + 1) != 'u') {
|
||||
g_warning
|
||||
("invalid name template %s: conversion specification must be of"
|
||||
" type '%%d', '%%u' or '%%s' for GST_PAD_REQUEST padtemplate",
|
||||
name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*(str + 1) == 's' && (*(str + 2) != '\0' || has_s)) {
|
||||
g_warning
|
||||
("invalid name template %s: conversion specification of type '%%s'"
|
||||
"only can be used once in the GST_PAD_REQUEST padtemplate at the "
|
||||
"very end and not allowed any other characters with '%%s'", name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (*(str + 1) == 's') {
|
||||
has_s = TRUE;
|
||||
}
|
||||
|
||||
underscore = strchr (str, '_');
|
||||
str = strchr (str + 1, '%');
|
||||
|
||||
if (str && (!underscore || (underscore && str < underscore))) {
|
||||
g_warning
|
||||
("invalid name template %s: each of conversion specifications "
|
||||
"must be separated by an underscore", name);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,12 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/check/gstcheck.h>
|
||||
#include <gst/gstelement.h>
|
||||
|
||||
GST_START_TEST (test_add_remove_pad)
|
||||
{
|
||||
|
@ -477,6 +481,309 @@ GST_START_TEST (test_property_notify_message)
|
|||
gst_element_remove_property_notify_watch (pipeline, deep_watch_id1);
|
||||
gst_element_remove_property_notify_watch (pipeline, deep_watch_id2);
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
|
||||
gst_object_unref (pipeline);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
typedef struct _GstTestElement3
|
||||
{
|
||||
GstElement parent;
|
||||
|
||||
} GstTestElement3;
|
||||
|
||||
typedef struct _GstTestElement3Class
|
||||
{
|
||||
GstElementClass parent;
|
||||
|
||||
} GstTestElement3Class;
|
||||
|
||||
static GstPad *
|
||||
gst_test_element3_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
||||
const gchar * name, const GstCaps * caps)
|
||||
{
|
||||
GstPad *pad;
|
||||
gchar *str;
|
||||
gchar *pad_name;
|
||||
gint n_conversion = 0;
|
||||
static gint i = 0;
|
||||
|
||||
str = templ->name_template;
|
||||
while ((str = strchr (str, '%'))) {
|
||||
n_conversion++;
|
||||
str++;
|
||||
}
|
||||
|
||||
if (strcmp (templ->name_template, "src_%ublah_blah%ublah") == 0)
|
||||
pad_name = g_strdup_printf ("src_%ublah_blah_%ublah", i, i + 1);
|
||||
else if (n_conversion == 1) {
|
||||
pad_name = g_strdup_printf ("src_%u", i);
|
||||
} else if (n_conversion == 2) {
|
||||
pad_name = g_strdup_printf ("src_%u_%u", i, i + 1);
|
||||
} else if (n_conversion == 3) {
|
||||
pad_name = g_strdup_printf ("src_%u_%u_%u", i, i + 1, i + 2);
|
||||
} else {
|
||||
pad_name = g_strdup (name);
|
||||
}
|
||||
|
||||
pad = gst_pad_new_from_template (templ, pad_name);
|
||||
|
||||
gst_element_add_pad (element, pad);
|
||||
|
||||
i++;
|
||||
g_free (pad_name);
|
||||
|
||||
return pad;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_test_element3_release_pad (GstElement * element, GstPad * pad)
|
||||
{
|
||||
gst_element_remove_pad (element, pad);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_test_element3_init (GstTestElement3 * test)
|
||||
{
|
||||
GstPadTemplate *pad_template;
|
||||
GstPad *sinkpad;
|
||||
|
||||
pad_template =
|
||||
gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (test), "sink");
|
||||
g_return_if_fail (pad_template != NULL);
|
||||
sinkpad = gst_pad_new_from_template (pad_template, "sink");
|
||||
|
||||
gst_element_add_pad (GST_ELEMENT (test), sinkpad);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_test_element3_class_init (GstTestElement3Class * klass)
|
||||
{
|
||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||
|
||||
gst_element_class_set_metadata (element_class, "Test element 3",
|
||||
"Element", "For testing request pad template", "Foo Bar <foo@bar.com>");
|
||||
|
||||
element_class->request_new_pad =
|
||||
GST_DEBUG_FUNCPTR (gst_test_element3_request_new_pad);
|
||||
element_class->release_pad =
|
||||
GST_DEBUG_FUNCPTR (gst_test_element3_release_pad);
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("src_%u", GST_PAD_SRC, GST_PAD_REQUEST,
|
||||
GST_CAPS_ANY));
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("src_%u_%u", GST_PAD_SRC, GST_PAD_REQUEST,
|
||||
GST_CAPS_ANY));
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("src_%u_%u_%u", GST_PAD_SRC, GST_PAD_REQUEST,
|
||||
GST_CAPS_ANY));
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("src_%ublah_blah%ublah", GST_PAD_SRC,
|
||||
GST_PAD_REQUEST, GST_CAPS_ANY));
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("src_%d", GST_PAD_SRC, GST_PAD_REQUEST,
|
||||
GST_CAPS_ANY));
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("src_%d_%d", GST_PAD_SRC, GST_PAD_REQUEST,
|
||||
GST_CAPS_ANY));
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("src_%d_%d_%d", GST_PAD_SRC, GST_PAD_REQUEST,
|
||||
GST_CAPS_ANY));
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("src_%s", GST_PAD_SRC, GST_PAD_REQUEST,
|
||||
GST_CAPS_ANY));
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("src_%u_%s", GST_PAD_SRC, GST_PAD_REQUEST,
|
||||
GST_CAPS_ANY));
|
||||
|
||||
gst_element_class_add_pad_template (element_class,
|
||||
gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
|
||||
GST_CAPS_ANY));
|
||||
}
|
||||
|
||||
static GType
|
||||
gst_test_element3_get_type (void)
|
||||
{
|
||||
static GType gst_test_element3_type = G_TYPE_NONE;
|
||||
|
||||
if (gst_test_element3_type == G_TYPE_NONE) {
|
||||
static const GTypeInfo gst_test_element3_info = {
|
||||
sizeof (GstTestElement3Class),
|
||||
NULL, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
(GClassInitFunc) gst_test_element3_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstTestElement3),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_test_element3_init,
|
||||
NULL
|
||||
};
|
||||
|
||||
gst_test_element3_type =
|
||||
g_type_register_static (gst_element_get_type (), "GstTestElement3",
|
||||
&gst_test_element3_info, 0);
|
||||
}
|
||||
return gst_test_element3_type;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_test_element3_plugin_init (GstPlugin * plugin)
|
||||
{
|
||||
gst_element_register (plugin, "test3", GST_RANK_NONE,
|
||||
gst_test_element3_get_type ());
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_START_TEST (test_request_pad_templates)
|
||||
{
|
||||
GstTestElement3 *test;
|
||||
GstElement *pipeline, *sink;
|
||||
GstPad *pad;
|
||||
GHashTable *padnames;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
const gchar *pad_name, *templ_name;
|
||||
GSList *padname_blacklists = NULL, *item;
|
||||
GError *err = NULL;
|
||||
|
||||
padnames = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
g_hash_table_insert (padnames, (gpointer) "src_0", (gpointer) "src_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%u", (gpointer) "src_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%u_%u",
|
||||
(gpointer) "src_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_0_%u", (gpointer) "src_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%u_0", (gpointer) "src_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_0_1", (gpointer) "src_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%u_%u_%u",
|
||||
(gpointer) "src_%u_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_0_%u_%u",
|
||||
(gpointer) "src_%u_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_0_1_%u",
|
||||
(gpointer) "src_%u_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_0_1_2",
|
||||
(gpointer) "src_%u_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%u_0_%u",
|
||||
(gpointer) "src_%u_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%u_0_1",
|
||||
(gpointer) "src_%u_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%u_%u_0",
|
||||
(gpointer) "src_%u_%u_%u");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%ublah_blah%ublah",
|
||||
(gpointer) "src_%ublah_blah%ublah");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%d", (gpointer) "src_%d");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%d_%d",
|
||||
(gpointer) "src_%d_%d");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_1_%d", (gpointer) "src_%d_%d");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%d_%d_%d",
|
||||
(gpointer) "src_%d_%d_%d");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_1_2_%d",
|
||||
(gpointer) "src_%d_%d_%d");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_1_%d_2",
|
||||
(gpointer) "src_%d_%d_%d");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%d_2_1",
|
||||
(gpointer) "src_%d_%d_%d");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%d_%d_1",
|
||||
(gpointer) "src_%d_%d_%d");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%d_1_%d",
|
||||
(gpointer) "src_%d_%d_%d");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_1_%d_%d",
|
||||
(gpointer) "src_%d_%d_%d");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%s", (gpointer) "src_%s");
|
||||
g_hash_table_insert (padnames, (gpointer) "src_%u_%s",
|
||||
(gpointer) "src_%u_%s");
|
||||
|
||||
padname_blacklists =
|
||||
g_slist_append (padname_blacklists, (gpointer) "src_%u%u");
|
||||
padname_blacklists =
|
||||
g_slist_append (padname_blacklists, (gpointer) "src_%u_%d");
|
||||
padname_blacklists =
|
||||
g_slist_append (padname_blacklists, (gpointer) "src_%u_%u_");
|
||||
padname_blacklists =
|
||||
g_slist_append (padname_blacklists, (gpointer) "src_%u_%s_%s");
|
||||
padname_blacklists =
|
||||
g_slist_append (padname_blacklists, (gpointer) "src_%s_%u");
|
||||
padname_blacklists =
|
||||
g_slist_append (padname_blacklists, (gpointer) "src_%s_%s");
|
||||
padname_blacklists =
|
||||
g_slist_append (padname_blacklists, (gpointer) "src_%s_%s_%s");
|
||||
padname_blacklists =
|
||||
g_slist_append (padname_blacklists, (gpointer) "src_%s_blah");
|
||||
|
||||
test = g_object_new (gst_test_element3_get_type (), NULL);
|
||||
|
||||
/* check available request pad names */
|
||||
g_hash_table_iter_init (&iter, padnames);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
||||
pad_name = (const gchar *) key;
|
||||
templ_name = (const gchar *) value;
|
||||
|
||||
pad = gst_element_get_request_pad (GST_ELEMENT (test), pad_name);
|
||||
fail_unless (pad != NULL);
|
||||
gst_element_release_request_pad (GST_ELEMENT (test), pad);
|
||||
gst_object_unref (pad);
|
||||
|
||||
pad = gst_element_request_pad (GST_ELEMENT (test),
|
||||
gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (test),
|
||||
templ_name), pad_name, NULL);
|
||||
fail_unless (pad != NULL);
|
||||
gst_element_release_request_pad (GST_ELEMENT (test), pad);
|
||||
gst_object_unref (pad);
|
||||
}
|
||||
|
||||
item = padname_blacklists;
|
||||
|
||||
/* check invalid request pad name */
|
||||
while (item) {
|
||||
pad_name = (const gchar *) (item->data);
|
||||
item = g_slist_next (item);
|
||||
pad = gst_element_get_request_pad (GST_ELEMENT (test), pad_name);
|
||||
fail_unless (pad == NULL);
|
||||
}
|
||||
|
||||
/* check it working with some APIs
|
||||
* gst_element_link/link_pads */
|
||||
sink = gst_element_factory_make ("fakesink", "sink");
|
||||
|
||||
fail_unless (gst_element_link (GST_ELEMENT (test), sink));
|
||||
gst_element_unlink (GST_ELEMENT (test), sink);
|
||||
|
||||
fail_unless (gst_element_link_pads (GST_ELEMENT (test), "src_%u_%u", sink,
|
||||
"sink"));
|
||||
gst_element_unlink (GST_ELEMENT (test), sink);
|
||||
|
||||
g_object_unref (test);
|
||||
g_object_unref (sink);
|
||||
|
||||
/* gst_parse_launch */
|
||||
gst_plugin_register_static (GST_VERSION_MAJOR,
|
||||
GST_VERSION_MINOR,
|
||||
"test3",
|
||||
"request pad template test",
|
||||
gst_test_element3_plugin_init,
|
||||
VERSION, GST_LICENSE, PACKAGE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
|
||||
|
||||
pipeline =
|
||||
gst_parse_launch ("fakesrc ! test3 name=t ! fakesink t. ! fakesink",
|
||||
&err);
|
||||
fail_unless (pipeline && err == NULL);
|
||||
|
||||
if (err) {
|
||||
g_error_free (err);
|
||||
}
|
||||
g_slist_free (padname_blacklists);
|
||||
g_hash_table_unref (padnames);
|
||||
gst_object_unref (pipeline);
|
||||
}
|
||||
|
||||
|
@ -496,6 +803,7 @@ gst_element_suite (void)
|
|||
tcase_add_test (tc_chain, test_link_no_pads);
|
||||
tcase_add_test (tc_chain, test_pad_templates);
|
||||
tcase_add_test (tc_chain, test_property_notify_message);
|
||||
tcase_add_test (tc_chain, test_request_pad_templates);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -584,7 +584,7 @@ GST_START_TEST (test_name_is_valid)
|
|||
ASSERT_WARNING (name_is_valid ("src%s%s", GST_PAD_REQUEST));
|
||||
ASSERT_WARNING (name_is_valid ("src%c", GST_PAD_REQUEST));
|
||||
ASSERT_WARNING (name_is_valid ("src%", GST_PAD_REQUEST));
|
||||
ASSERT_WARNING (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
|
||||
fail_unless (name_is_valid ("src%dsrc", GST_PAD_REQUEST));
|
||||
|
||||
fail_unless (name_is_valid ("src", GST_PAD_SOMETIMES));
|
||||
fail_unless (name_is_valid ("src%c", GST_PAD_SOMETIMES));
|
||||
|
|
Loading…
Reference in a new issue