* Boston, MA 02111-1307, USA.
*/
+//#define DEBUG_ENABLED
+
#include <stdarg.h>
#include <gst/gstcapsprivate.h>
+static gboolean gst_caps_entry_check_compatibility (GstCapsEntry *entry1, GstCapsEntry *entry2);
+
+
void
_gst_caps_initialize (void)
{
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;
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.int_range_data.min,
entry->data.int_range_data.max);
break;
- case GST_CAPS_INT32_ID_NUM:
- g_print("gstcaps: int32 %d\n", entry->data.int_data);
+ case GST_CAPS_FOURCC_ID_NUM:
+ g_print("gstcaps: fourcc 0x%08x (%4.4s)\n", entry->data.fourcc_data, &entry->data.fourcc_data);
break;
case GST_CAPS_BOOL_ID_NUM:
g_print("gstcaps: boolean %d\n", entry->data.bool_data);
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)
{
- g_print ("compare: %s %s\n", g_quark_to_string (entry1->propid),
- g_quark_to_string (entry2->propid));
+ 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;
}
/**
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);
sourcelist = fromcaps->properties;
sinklist = tocaps->properties;
- while (sourcelist && sinklist) {
+ while (sourcelist && sinklist && compatible) {
GstCapsEntry *entry1;
GstCapsEntry *entry2;
entry2 = (GstCapsEntry *)sinklist->data;
while (entry1->propid < entry2->propid) {
- g_print ("source is more specific in \"%s\"\n", g_quark_to_string (entry1->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) {
- g_print ("source has missing property \"%s\"\n", g_quark_to_string (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;
}
- gst_caps_entry_check_compatibility (entry1, entry2);
+ compatible &= gst_caps_entry_check_compatibility (entry1, entry2);
sourcelist = g_slist_next (sourcelist);
sinklist = g_slist_next (sinklist);
if (missing)
return FALSE;
- return TRUE;
+ return compatible;
}
/**
GST_CAPS_LIST_ID_NUM,
GST_CAPS_INT_ID_NUM,
GST_CAPS_INT_RANGE_ID_NUM,
- GST_CAPS_INT32_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_INT32_ID GINT_TO_POINTER(GST_CAPS_INT32_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_INT32(a) GST_CAPS_INT_ID,(GINT_TO_POINTER(a))
+#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))