From eaa6e55855b9631ed06a6c323763c8bdd67e2fa7 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 7 Dec 2000 18:37:56 +0000 Subject: [PATCH] separated the properties from the capabilities as we might use the properties for metadata too. Original commit message from CVS: separated the properties from the capabilities as we might use the properties for metadata too. --- gst/Makefile.am | 2 + gst/gst.h | 1 + gst/gstcaps.c | 331 +---------------- gst/gstcaps.h | 29 +- gst/gstprops.c | 385 ++++++++++++++++++++ gst/gstprops.h | 67 ++++ gst/{gstcapsprivate.h => gstpropsprivate.h} | 14 +- 7 files changed, 470 insertions(+), 359 deletions(-) create mode 100644 gst/gstprops.c create mode 100644 gst/gstprops.h rename gst/{gstcapsprivate.h => gstpropsprivate.h} (84%) diff --git a/gst/Makefile.am b/gst/Makefile.am index 386f552059..ecbab0ea63 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -38,6 +38,7 @@ libgst_la_SOURCES = \ gstconnection.c \ gsttype.c \ gstcaps.c \ + gstprops.c \ gstplugin.c \ gstutils.c \ gsttrace.c \ @@ -67,6 +68,7 @@ libgstinclude_HEADERS = \ gstconnection.h \ gsttype.h \ gstcaps.h \ + gstprops.h \ gstplugin.h \ gstutils.h \ gsttrace.h \ diff --git a/gst/gst.h b/gst/gst.h index 709eebc762..c005dcf860 100644 --- a/gst/gst.h +++ b/gst/gst.h @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include diff --git a/gst/gstcaps.c b/gst/gstcaps.c index 58a0bc834a..2e8a4e9911 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -20,70 +20,12 @@ //#define DEBUG_ENABLED #include -#include - -static gboolean gst_caps_entry_check_compatibility (GstCapsEntry *entry1, GstCapsEntry *entry2); - +#include void _gst_caps_initialize (void) { } - -static GstCapsEntry * -gst_caps_create_entry (GstCapsFactory factory, gint *skipped) -{ - GstCapsFactoryEntry tag; - GstCapsEntry *entry; - guint i=0; - - entry = g_new0 (GstCapsEntry, 1); - - tag = factory[i++]; - switch (GPOINTER_TO_INT (tag)) { - case GST_CAPS_INT_ID: - entry->capstype = GST_CAPS_INT_ID_NUM; - entry->data.int_data = GPOINTER_TO_INT (factory[i++]); - break; - case GST_CAPS_INT_RANGE_ID: - entry->capstype = GST_CAPS_INT_RANGE_ID_NUM; - entry->data.int_range_data.min = GPOINTER_TO_INT (factory[i++]); - entry->data.int_range_data.max = GPOINTER_TO_INT (factory[i++]); - break; - case GST_CAPS_FOURCC_ID: - entry->capstype = GST_CAPS_FOURCC_ID_NUM; - entry->data.fourcc_data = GPOINTER_TO_INT (factory[i++]); - break; - case GST_CAPS_LIST_ID: - g_print("gstcaps: list not allowed in list\n"); - break; - case GST_CAPS_BOOL_ID: - entry->capstype = GST_CAPS_BOOL_ID_NUM; - entry->data.bool_data = GPOINTER_TO_INT (factory[i++]); - break; - default: - g_print("gstcaps: unknown caps id found\n"); - g_free (entry); - entry = NULL; - break; - } - - *skipped = i; - - return entry; -} - - -static gint -caps_compare_func (gconstpointer a, - gconstpointer b) -{ - GstCapsEntry *entry1 = (GstCapsEntry *)a; - GstCapsEntry *entry2 = (GstCapsEntry *)b; - - return (entry1->propid - entry2->propid); -} - /** * gst_caps_register: * @factory: the factory to register @@ -99,7 +41,6 @@ gst_caps_register (GstCapsFactory factory) gint i = 0; guint16 typeid; GstCaps *caps; - gint skipped; g_return_val_if_fail (factory != NULL, NULL); @@ -122,110 +63,11 @@ gst_caps_register (GstCapsFactory factory) g_return_val_if_fail (caps != NULL, NULL); caps->id = typeid; - caps->properties = NULL; - - tag = factory[i++]; - - while (tag) { - GQuark quark; - GstCapsEntry *entry; - - quark = g_quark_from_string ((gchar *)tag); - - tag = factory[i]; - switch (GPOINTER_TO_INT (tag)) { - case GST_CAPS_LIST_ID: - { - GstCapsEntry *list_entry; - - entry = g_new0 (GstCapsEntry, 1); - entry->propid = quark; - entry->capstype = GST_CAPS_LIST_ID_NUM; - entry->data.list_data.entries = NULL; - - i++; // skip list tag - tag = factory[i]; - while (tag) { - list_entry = gst_caps_create_entry (&factory[i], &skipped); - list_entry->propid = quark; - i += skipped; - tag = factory[i]; - entry->data.list_data.entries = g_list_prepend (entry->data.list_data.entries, list_entry); - } - entry->data.list_data.entries = g_list_reverse (entry->data.list_data.entries); - i++; //skip NULL (list end) - break; - } - default: - { - entry = gst_caps_create_entry (&factory[i], &skipped); - entry->propid = quark; - i += skipped; - break; - } - } - caps->properties = g_slist_insert_sorted (caps->properties, entry, caps_compare_func); - - tag = factory[i++]; - } + caps->properties = gst_props_register (&factory[i]); return caps; } -static void -gst_caps_dump_entry_func (GstCapsEntry *entry) -{ - switch (entry->capstype) { - case GST_CAPS_INT_ID_NUM: - g_print("gstcaps: int %d\n", entry->data.int_data); - break; - case GST_CAPS_INT_RANGE_ID_NUM: - g_print("gstcaps: int range %d %d\n", - entry->data.int_range_data.min, - entry->data.int_range_data.max); - break; - case GST_CAPS_FOURCC_ID_NUM: - g_print("gstcaps: fourcc 0x%08x (%4.4s)\n", entry->data.fourcc_data, (gchar *)&entry->data.fourcc_data); - break; - case GST_CAPS_BOOL_ID_NUM: - g_print("gstcaps: boolean %d\n", entry->data.bool_data); - break; - default: - g_print("gstcaps: **illegal entry**\n"); - break; - } -} - -static void -gst_caps_dump_list_func (gpointer entry, - gpointer list_entry) -{ - gst_caps_dump_entry_func ((GstCapsEntry *)entry); -} - -static void -gst_caps_dump_func (gpointer data, - gpointer user_data) -{ - GstCapsEntry *entry; - - entry = (GstCapsEntry *)data; - - g_print("gstcaps: property type \"%s\"\n", g_quark_to_string (entry->propid)); - - switch (entry->capstype) { - case GST_CAPS_LIST_ID_NUM: - { - g_print("gstcaps: list type (\n"); - g_list_foreach (entry->data.list_data.entries, gst_caps_dump_list_func, entry); - g_print("gstcaps: )\n"); - break; - } - default: - gst_caps_dump_entry_func (entry); - break; - } -} /** * gst_caps_dump: @@ -240,105 +82,11 @@ gst_caps_dump (GstCaps *caps) g_print("gstcaps: {\ngstcaps: mime type \"%d\"\n", caps->id); - g_slist_foreach (caps->properties, gst_caps_dump_func, caps); + gst_props_dump (caps->properties); + g_print("gstcaps: }\n"); } -/* entry2 is always a list, entry1 never is */ -static gboolean -gst_caps_entry_check_list_compatibility (GstCapsEntry *entry1, GstCapsEntry *entry2) -{ - GList *entrylist = entry2->data.list_data.entries; - gboolean found = FALSE; - - while (entrylist && !found) { - GstCapsEntry *entry = (GstCapsEntry *) entrylist->data; - - found |= gst_caps_entry_check_compatibility (entry1, entry); - - entrylist = g_list_next (entrylist); - } - - return found; -} - -static gboolean -gst_caps_entry_check_compatibility (GstCapsEntry *entry1, GstCapsEntry *entry2) -{ - DEBUG ("compare: %s %s\n", g_quark_to_string (entry1->propid), - g_quark_to_string (entry2->propid)); - switch (entry1->capstype) { - case GST_CAPS_LIST_ID_NUM: - { - GList *entrylist = entry1->data.list_data.entries; - gboolean valid = TRUE; // innocent until proven guilty - - while (entrylist && valid) { - GstCapsEntry *entry = (GstCapsEntry *) entrylist->data; - - valid &= gst_caps_entry_check_compatibility (entry, entry2); - - entrylist = g_list_next (entrylist); - } - - return valid; - } - case GST_CAPS_INT_RANGE_ID_NUM: - switch (entry2->capstype) { - // a - b <---> a - c - case GST_CAPS_INT_RANGE_ID_NUM: - return (entry2->data.int_range_data.min <= entry1->data.int_range_data.min && - entry2->data.int_range_data.max >= entry1->data.int_range_data.max); - case GST_CAPS_LIST_ID_NUM: - return gst_caps_entry_check_list_compatibility (entry1, entry2); - default: - return FALSE; - } - break; - case GST_CAPS_FOURCC_ID_NUM: - switch (entry2->capstype) { - // b <---> a - case GST_CAPS_FOURCC_ID_NUM: - return (entry2->data.fourcc_data == entry1->data.fourcc_data); - // b <---> a,b,c - case GST_CAPS_LIST_ID_NUM: - return gst_caps_entry_check_list_compatibility (entry1, entry2); - default: - return FALSE; - } - break; - case GST_CAPS_INT_ID_NUM: - switch (entry2->capstype) { - // b <---> a - d - case GST_CAPS_INT_RANGE_ID_NUM: - return (entry2->data.int_range_data.min <= entry1->data.int_data && - entry2->data.int_range_data.max >= entry1->data.int_data); - // b <---> a - case GST_CAPS_INT_ID_NUM: - return (entry2->data.int_data == entry1->data.int_data); - // b <---> a,b,c - case GST_CAPS_LIST_ID_NUM: - return gst_caps_entry_check_list_compatibility (entry1, entry2); - default: - return FALSE; - } - break; - case GST_CAPS_BOOL_ID_NUM: - switch (entry2->capstype) { - // t <---> t - case GST_CAPS_BOOL_ID_NUM: - return (entry2->data.bool_data == entry1->data.bool_data); - case GST_CAPS_LIST_ID_NUM: - return gst_caps_entry_check_list_compatibility (entry1, entry2); - default: - return FALSE; - } - default: - break; - } - - return FALSE; -} /** * gst_caps_check_compatibility: @@ -352,81 +100,12 @@ gst_caps_entry_check_compatibility (GstCapsEntry *entry1, GstCapsEntry *entry2) gboolean gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps) { - GSList *sourcelist; - GSList *sinklist; - gint missing = 0; - gint more = 0; - gboolean compatible = TRUE; - g_return_val_if_fail (fromcaps != NULL, FALSE); g_return_val_if_fail (tocaps != NULL, FALSE); if (fromcaps->id != tocaps->id) return FALSE; - sourcelist = fromcaps->properties; - sinklist = tocaps->properties; - - while (sourcelist && sinklist && compatible) { - GstCapsEntry *entry1; - GstCapsEntry *entry2; - - entry1 = (GstCapsEntry *)sourcelist->data; - entry2 = (GstCapsEntry *)sinklist->data; - - while (entry1->propid < entry2->propid) { - DEBUG ("source is more specific in \"%s\"\n", g_quark_to_string (entry1->propid)); - more++; - sourcelist = g_slist_next (sourcelist); - if (sourcelist) entry1 = (GstCapsEntry *)sourcelist->data; - else goto end; - } - while (entry1->propid > entry2->propid) { - DEBUG ("source has missing property \"%s\"\n", g_quark_to_string (entry2->propid)); - missing++; - sinklist = g_slist_next (sinklist); - if (sinklist) entry2 = (GstCapsEntry *)sinklist->data; - else goto end; - } - - compatible &= gst_caps_entry_check_compatibility (entry1, entry2); - - sourcelist = g_slist_next (sourcelist); - sinklist = g_slist_next (sinklist); - } -end: - - if (missing) - return FALSE; - - return compatible; + return gst_props_check_compatibility (fromcaps->properties, tocaps->properties); } -/** - * gst_caps_register_va: - * @factory: the factories to register - * - * Register the given factories. - * - * Returns: A list of the registered factories - */ -GList * -gst_caps_register_va (GstCapsFactory factory, ...) -{ - va_list var_args; - GstCapsFactoryEntry *current_factory; - - va_start (var_args, factory); - - current_factory = (GstCapsFactoryEntry *) factory; - - while (current_factory) { - gst_caps_register (current_factory); - - current_factory = va_arg (var_args, GstCapsFactoryEntry *); - } - - va_end(var_args); - - return NULL; -} diff --git a/gst/gstcaps.h b/gst/gstcaps.h index 20c4b6de59..b499105f12 100644 --- a/gst/gstcaps.h +++ b/gst/gstcaps.h @@ -21,47 +21,24 @@ #ifndef __GST_CAPS_H__ #define __GST_CAPS_H__ -#include +#include +#include typedef struct _GstCaps GstCaps; typedef gpointer GstCapsFactoryEntry; typedef GstCapsFactoryEntry GstCapsFactory[]; typedef GstCapsFactory *GstCapsListFactory[]; -typedef enum { - GST_CAPS_END_ID_NUM = 0, - GST_CAPS_LIST_ID_NUM, - GST_CAPS_INT_ID_NUM, - GST_CAPS_INT_RANGE_ID_NUM, - GST_CAPS_FOURCC_ID_NUM, - GST_CAPS_BOOL_ID_NUM, -} GstCapsId; - -#define GST_CAPS_LIST_ID GINT_TO_POINTER(GST_CAPS_LIST_ID_NUM) -#define GST_CAPS_INT_ID GINT_TO_POINTER(GST_CAPS_INT_ID_NUM) -#define GST_CAPS_INT_RANGE_ID GINT_TO_POINTER(GST_CAPS_INT_RANGE_ID_NUM) -#define GST_CAPS_FOURCC_ID GINT_TO_POINTER(GST_CAPS_FOURCC_ID_NUM) -#define GST_CAPS_BOOL_ID GINT_TO_POINTER(GST_CAPS_BOOL_ID_NUM) - -#define GST_CAPS_LIST(a...) GST_CAPS_LIST_ID,##a,NULL -#define GST_CAPS_INT(a) GST_CAPS_INT_ID,(GINT_TO_POINTER(a)) -#define GST_CAPS_INT_RANGE(a,b) GST_CAPS_INT_RANGE_ID,(GINT_TO_POINTER(a)),(GINT_TO_POINTER(b)) -#define GST_CAPS_FOURCC(a,b,c,d) GST_CAPS_FOURCC_ID,(GINT_TO_POINTER((a)|(b)<<8|(c)<<16|(d)<<24)) -#define GST_CAPS_FOURCC_INT(a) GST_CAPS_FOURCC_ID,(GINT_TO_POINTER(a)) -#define GST_CAPS_BOOLEAN(a) GST_CAPS_BOOL_ID,(GINT_TO_POINTER(a)) - - struct _GstCaps { guint16 id; /* type id (major type) */ - GSList *properties; /* properties for this capability */ + GstProps *properties; /* properties for this capability */ }; /* initialize the subsystem */ void _gst_caps_initialize (void); GstCaps* gst_caps_register (GstCapsFactory factory); -GList* gst_caps_register_va (GstCapsFactory factory,...); void gst_caps_dump (GstCaps *caps); diff --git a/gst/gstprops.c b/gst/gstprops.c new file mode 100644 index 0000000000..a3a37eb67f --- /dev/null +++ b/gst/gstprops.c @@ -0,0 +1,385 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +//#define DEBUG_ENABLED + +#include +#include +#include + +static gboolean gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2); + + +void +_gst_props_initialize (void) +{ +} + +static GstPropsEntry * +gst_props_create_entry (GstPropsFactory factory, gint *skipped) +{ + GstPropsFactoryEntry tag; + GstPropsEntry *entry; + guint i=0; + + entry = g_new0 (GstPropsEntry, 1); + + tag = factory[i++]; + switch (GPOINTER_TO_INT (tag)) { + case GST_PROPS_INT_ID: + entry->propstype = GST_PROPS_INT_ID_NUM; + entry->data.int_data = GPOINTER_TO_INT (factory[i++]); + break; + case GST_PROPS_INT_RANGE_ID: + entry->propstype = GST_PROPS_INT_RANGE_ID_NUM; + entry->data.int_range_data.min = GPOINTER_TO_INT (factory[i++]); + entry->data.int_range_data.max = GPOINTER_TO_INT (factory[i++]); + break; + case GST_PROPS_FOURCC_ID: + entry->propstype = GST_PROPS_FOURCC_ID_NUM; + entry->data.fourcc_data = GPOINTER_TO_INT (factory[i++]); + break; + case GST_PROPS_LIST_ID: + g_print("gstprops: list not allowed in list\n"); + break; + case GST_PROPS_BOOL_ID: + entry->propstype = GST_PROPS_BOOL_ID_NUM; + entry->data.bool_data = GPOINTER_TO_INT (factory[i++]); + break; + default: + g_print("gstprops: unknown props id found\n"); + g_free (entry); + entry = NULL; + break; + } + + *skipped = i; + + return entry; +} + + +static gint +props_compare_func (gconstpointer a, + gconstpointer b) +{ + GstPropsEntry *entry1 = (GstPropsEntry *)a; + GstPropsEntry *entry2 = (GstPropsEntry *)b; + + return (entry1->propid - entry2->propid); +} + +/** + * gst_props_register: + * @factory: the factory to register + * + * Register the factory. + * + * Returns: The registered capability + */ +GstProps * +gst_props_register (GstPropsFactory factory) +{ + GstPropsFactoryEntry tag; + gint i = 0; + GstProps *props; + gint skipped; + + g_return_val_if_fail (factory != NULL, NULL); + + props = g_new0 (GstProps, 1); + g_return_val_if_fail (props != NULL, NULL); + + props->properties = NULL; + + tag = factory[i++]; + + while (tag) { + GQuark quark; + GstPropsEntry *entry; + + quark = g_quark_from_string ((gchar *)tag); + + tag = factory[i]; + switch (GPOINTER_TO_INT (tag)) { + case GST_PROPS_LIST_ID: + { + GstPropsEntry *list_entry; + + entry = g_new0 (GstPropsEntry, 1); + entry->propid = quark; + entry->propstype = GST_PROPS_LIST_ID_NUM; + entry->data.list_data.entries = NULL; + + i++; // skip list tag + tag = factory[i]; + while (tag) { + list_entry = gst_props_create_entry (&factory[i], &skipped); + list_entry->propid = quark; + i += skipped; + tag = factory[i]; + entry->data.list_data.entries = g_list_prepend (entry->data.list_data.entries, list_entry); + } + entry->data.list_data.entries = g_list_reverse (entry->data.list_data.entries); + i++; //skip NULL (list end) + break; + } + default: + { + entry = gst_props_create_entry (&factory[i], &skipped); + entry->propid = quark; + i += skipped; + break; + } + } + props->properties = g_slist_insert_sorted (props->properties, entry, props_compare_func); + + tag = factory[i++]; + } + + return props; +} + +static void +gst_props_dump_entry_func (GstPropsEntry *entry) +{ + switch (entry->propstype) { + case GST_PROPS_INT_ID_NUM: + g_print("gstprops: int %d\n", entry->data.int_data); + break; + case GST_PROPS_INT_RANGE_ID_NUM: + g_print("gstprops: int range %d %d\n", + entry->data.int_range_data.min, + entry->data.int_range_data.max); + break; + case GST_PROPS_FOURCC_ID_NUM: + g_print("gstprops: fourcc 0x%08x (%4.4s)\n", entry->data.fourcc_data, (gchar *)&entry->data.fourcc_data); + break; + case GST_PROPS_BOOL_ID_NUM: + g_print("gstprops: boolean %d\n", entry->data.bool_data); + break; + default: + g_print("gstprops: **illegal entry**\n"); + break; + } +} + +static void +gst_props_dump_list_func (gpointer entry, + gpointer list_entry) +{ + gst_props_dump_entry_func ((GstPropsEntry *)entry); +} + +static void +gst_props_dump_func (gpointer data, + gpointer user_data) +{ + GstPropsEntry *entry; + + entry = (GstPropsEntry *)data; + + g_print("gstprops: property type \"%s\"\n", g_quark_to_string (entry->propid)); + + switch (entry->propstype) { + case GST_PROPS_LIST_ID_NUM: + { + g_print("gstprops: list type (\n"); + g_list_foreach (entry->data.list_data.entries, gst_props_dump_list_func, entry); + g_print("gstprops: )\n"); + break; + } + default: + gst_props_dump_entry_func (entry); + break; + } +} + +/** + * gst_props_dump: + * @props: the capability to dump + * + * Dumps the contents of the capabilty one the console + */ +void +gst_props_dump (GstProps *props) +{ + g_return_if_fail (props != NULL); + + g_print("gstprops: {\n"); + + g_slist_foreach (props->properties, gst_props_dump_func, props); + g_print("gstprops: }\n"); +} + +/* entry2 is always a list, entry1 never is */ +static gboolean +gst_props_entry_check_list_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2) +{ + GList *entrylist = entry2->data.list_data.entries; + gboolean found = FALSE; + + while (entrylist && !found) { + GstPropsEntry *entry = (GstPropsEntry *) entrylist->data; + + found |= gst_props_entry_check_compatibility (entry1, entry); + + entrylist = g_list_next (entrylist); + } + + return found; +} + +static gboolean +gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2) +{ + DEBUG ("compare: %s %s\n", g_quark_to_string (entry1->propid), + g_quark_to_string (entry2->propid)); + switch (entry1->propstype) { + case GST_PROPS_LIST_ID_NUM: + { + GList *entrylist = entry1->data.list_data.entries; + gboolean valid = TRUE; // innocent until proven guilty + + while (entrylist && valid) { + GstPropsEntry *entry = (GstPropsEntry *) entrylist->data; + + valid &= gst_props_entry_check_compatibility (entry, entry2); + + entrylist = g_list_next (entrylist); + } + + return valid; + } + case GST_PROPS_INT_RANGE_ID_NUM: + switch (entry2->propstype) { + // a - b <---> a - c + case GST_PROPS_INT_RANGE_ID_NUM: + return (entry2->data.int_range_data.min <= entry1->data.int_range_data.min && + entry2->data.int_range_data.max >= entry1->data.int_range_data.max); + case GST_PROPS_LIST_ID_NUM: + return gst_props_entry_check_list_compatibility (entry1, entry2); + default: + return FALSE; + } + break; + case GST_PROPS_FOURCC_ID_NUM: + switch (entry2->propstype) { + // b <---> a + case GST_PROPS_FOURCC_ID_NUM: + return (entry2->data.fourcc_data == entry1->data.fourcc_data); + // b <---> a,b,c + case GST_PROPS_LIST_ID_NUM: + return gst_props_entry_check_list_compatibility (entry1, entry2); + default: + return FALSE; + } + break; + case GST_PROPS_INT_ID_NUM: + switch (entry2->propstype) { + // b <---> a - d + case GST_PROPS_INT_RANGE_ID_NUM: + return (entry2->data.int_range_data.min <= entry1->data.int_data && + entry2->data.int_range_data.max >= entry1->data.int_data); + // b <---> a + case GST_PROPS_INT_ID_NUM: + return (entry2->data.int_data == entry1->data.int_data); + // b <---> a,b,c + case GST_PROPS_LIST_ID_NUM: + return gst_props_entry_check_list_compatibility (entry1, entry2); + default: + return FALSE; + } + break; + case GST_PROPS_BOOL_ID_NUM: + switch (entry2->propstype) { + // t <---> t + case GST_PROPS_BOOL_ID_NUM: + return (entry2->data.bool_data == entry1->data.bool_data); + case GST_PROPS_LIST_ID_NUM: + return gst_props_entry_check_list_compatibility (entry1, entry2); + default: + return FALSE; + } + default: + break; + } + + return FALSE; +} + +/** + * gst_props_check_compatibility: + * @fromprops: a capabilty + * @toprops: a capabilty + * + * Checks whether two capabilities are compatible + * + * Returns: true if compatible, false otherwise + */ +gboolean +gst_props_check_compatibility (GstProps *fromprops, GstProps *toprops) +{ + GSList *sourcelist; + GSList *sinklist; + gint missing = 0; + gint more = 0; + gboolean compatible = TRUE; + + g_return_val_if_fail (fromprops != NULL, FALSE); + g_return_val_if_fail (toprops != NULL, FALSE); + + sourcelist = fromprops->properties; + sinklist = toprops->properties; + + while (sourcelist && sinklist && compatible) { + GstPropsEntry *entry1; + GstPropsEntry *entry2; + + entry1 = (GstPropsEntry *)sourcelist->data; + entry2 = (GstPropsEntry *)sinklist->data; + + while (entry1->propid < entry2->propid) { + DEBUG ("source is more specific in \"%s\"\n", g_quark_to_string (entry1->propid)); + more++; + sourcelist = g_slist_next (sourcelist); + if (sourcelist) entry1 = (GstPropsEntry *)sourcelist->data; + else goto end; + } + while (entry1->propid > entry2->propid) { + DEBUG ("source has missing property \"%s\"\n", g_quark_to_string (entry2->propid)); + missing++; + sinklist = g_slist_next (sinklist); + if (sinklist) entry2 = (GstPropsEntry *)sinklist->data; + else goto end; + } + + compatible &= gst_props_entry_check_compatibility (entry1, entry2); + + sourcelist = g_slist_next (sourcelist); + sinklist = g_slist_next (sinklist); + } +end: + + if (missing) + return FALSE; + + return compatible; +} + diff --git a/gst/gstprops.h b/gst/gstprops.h new file mode 100644 index 0000000000..7b81f1b64e --- /dev/null +++ b/gst/gstprops.h @@ -0,0 +1,67 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#ifndef __GST_PROPS_H__ +#define __GST_PROPS_H__ + +#include + +typedef struct _GstProps GstProps; +typedef gpointer GstPropsFactoryEntry; +typedef GstPropsFactoryEntry GstPropsFactory[]; +typedef GstPropsFactory *GstPropsListFactory[]; + +typedef enum { + GST_PROPS_END_ID_NUM = 0, + GST_PROPS_LIST_ID_NUM, + GST_PROPS_INT_ID_NUM, + GST_PROPS_INT_RANGE_ID_NUM, + GST_PROPS_FOURCC_ID_NUM, + GST_PROPS_BOOL_ID_NUM, +} GstPropsId; + +#define GST_PROPS_LIST_ID GINT_TO_POINTER(GST_PROPS_LIST_ID_NUM) +#define GST_PROPS_INT_ID GINT_TO_POINTER(GST_PROPS_INT_ID_NUM) +#define GST_PROPS_INT_RANGE_ID GINT_TO_POINTER(GST_PROPS_INT_RANGE_ID_NUM) +#define GST_PROPS_FOURCC_ID GINT_TO_POINTER(GST_PROPS_FOURCC_ID_NUM) +#define GST_PROPS_BOOL_ID GINT_TO_POINTER(GST_PROPS_BOOL_ID_NUM) + +#define GST_PROPS_LIST(a...) GST_PROPS_LIST_ID,##a,NULL +#define GST_PROPS_INT(a) GST_PROPS_INT_ID,(GINT_TO_POINTER(a)) +#define GST_PROPS_INT_RANGE(a,b) GST_PROPS_INT_RANGE_ID,(GINT_TO_POINTER(a)),(GINT_TO_POINTER(b)) +#define GST_PROPS_FOURCC(a,b,c,d) GST_PROPS_FOURCC_ID,(GINT_TO_POINTER((a)|(b)<<8|(c)<<16|(d)<<24)) +#define GST_PROPS_FOURCC_INT(a) GST_PROPS_FOURCC_ID,(GINT_TO_POINTER(a)) +#define GST_PROPS_BOOLEAN(a) GST_PROPS_BOOL_ID,(GINT_TO_POINTER(a)) + + +struct _GstProps { + GSList *properties; /* properties for this capability */ +}; + +/* initialize the subsystem */ +void _gst_props_initialize (void); + +GstProps* gst_props_register (GstPropsFactory factory); + +void gst_props_dump (GstProps *props); + +gboolean gst_props_check_compatibility (GstProps *props1, GstProps *props2); + +#endif /* __GST_PROPS_H__ */ diff --git a/gst/gstcapsprivate.h b/gst/gstpropsprivate.h similarity index 84% rename from gst/gstcapsprivate.h rename to gst/gstpropsprivate.h index 978e4e6f92..ebdec45c83 100644 --- a/gst/gstcapsprivate.h +++ b/gst/gstpropsprivate.h @@ -18,16 +18,16 @@ */ -#ifndef __GST_CAPS_PRIV_H__ -#define __GST_CAPS_PRIV_H__ +#ifndef __GST_PROPS_PRIV_H__ +#define __GST_PROPS_PRIV_H__ -#include +#include -typedef struct _GstCapsEntry GstCapsEntry; +typedef struct _GstPropsEntry GstPropsEntry; -struct _GstCapsEntry { +struct _GstPropsEntry { GQuark propid; - GstCapsId capstype; + GstPropsId propstype; union { /* flat values */ @@ -46,4 +46,4 @@ struct _GstCapsEntry { } data; }; -#endif /* __GST_CAPS_PRIV_H__ */ +#endif /* __GST_PROPS_PRIV_H__ */ -- 2.34.1