diff --git a/spa/include/spa/pod-builder.h b/spa/include/spa/pod-builder.h index a5bfc8b99..03f9cfcde 100644 --- a/spa/include/spa/pod-builder.h +++ b/spa/include/spa/pod-builder.h @@ -161,6 +161,13 @@ spa_pod_builder_bool (SpaPODBuilder *builder, bool val) return spa_pod_builder_primitive (builder, &p.pod); } +static inline off_t +spa_pod_builder_uri (SpaPODBuilder *builder, uint32_t val) +{ + const SpaPODURI p = { { sizeof (uint32_t), SPA_POD_TYPE_URI }, val }; + return spa_pod_builder_primitive (builder, &p.pod); +} + static inline off_t spa_pod_builder_int (SpaPODBuilder *builder, int32_t val) { @@ -294,6 +301,9 @@ spa_pod_builder_propv (SpaPODBuilder *builder, case SPA_POD_TYPE_BOOL: spa_pod_builder_bool (builder, va_arg (args, int)); break; + case SPA_POD_TYPE_URI: + spa_pod_builder_uri (builder, va_arg (args, int32_t)); + break; case SPA_POD_TYPE_INT: spa_pod_builder_int (builder, va_arg (args, int32_t)); break; diff --git a/spa/include/spa/pod.h b/spa/include/spa/pod.h index 9e6a647a7..c5aa02774 100644 --- a/spa/include/spa/pod.h +++ b/spa/include/spa/pod.h @@ -35,6 +35,7 @@ extern "C" { typedef enum { SPA_POD_TYPE_INVALID = 0, SPA_POD_TYPE_BOOL, + SPA_POD_TYPE_URI, SPA_POD_TYPE_INT, SPA_POD_TYPE_LONG, SPA_POD_TYPE_FLOAT, @@ -64,13 +65,13 @@ typedef struct { #define SPA_POD_BODY(pod) SPA_MEMBER((pod),sizeof(SpaPOD),void) #define SPA_POD_BODY_CONST(pod) SPA_MEMBER((pod),sizeof(SpaPOD),const void) - typedef struct { SpaPOD pod; int32_t value; } SpaPODInt; typedef SpaPODInt SpaPODBool; +typedef SpaPODInt SpaPODURI; typedef struct { SpaPOD pod; diff --git a/spa/lib/debug.c b/spa/lib/debug.c index e209653fc..3a7ec9d45 100644 --- a/spa/lib/debug.c +++ b/spa/lib/debug.c @@ -319,6 +319,7 @@ struct pod_type_name { { "invalid", "*Invalid*" }, { "bool", "Bool" }, { "int", "Int" }, + { "uri", "URI" }, { "long", "Long" }, { "float", "Float" }, { "double", "Double" }, @@ -343,6 +344,9 @@ print_pod_value (uint32_t size, uint32_t type, void *body, int prefix) case SPA_POD_TYPE_INT: printf ("%-*sInt %d\n", prefix, "", *(int32_t *) body); break; + case SPA_POD_TYPE_URI: + printf ("%-*sURI %d\n", prefix, "", *(int32_t *) body); + break; case SPA_POD_TYPE_LONG: printf ("%-*sLong %"PRIi64"\n", prefix, "", *(int64_t *) body); break; @@ -440,6 +444,9 @@ print_format_value (uint32_t size, uint32_t type, void *body) case SPA_POD_TYPE_INT: fprintf (stderr, "%"PRIi32, *(int32_t *) body); break; + case SPA_POD_TYPE_URI: + fprintf (stderr, "%"PRIi32, *(int32_t *) body); + break; case SPA_POD_TYPE_LONG: fprintf (stderr, "%"PRIi64, *(int64_t *) body); break; diff --git a/spa/lib/props.c b/spa/lib/props.c index 3e6d170be..741a0859b 100644 --- a/spa/lib/props.c +++ b/spa/lib/props.c @@ -116,7 +116,6 @@ compare_value (SpaPODType type, const void *r1, const void *r2) case SPA_POD_TYPE_BOOL: return *(int32_t*)r1 == *(uint32_t*)r2; case SPA_POD_TYPE_INT: - printf ("%d <> %d\n", *(int32_t*)r1, *(int32_t*)r2); return *(int32_t*)r1 - *(int32_t*)r2; case SPA_POD_TYPE_LONG: return *(int64_t*)r1 - *(int64_t*)r2; @@ -138,13 +137,36 @@ compare_value (SpaPODType type, const void *r1, const void *r2) return 1; } case SPA_POD_TYPE_FRACTION: - break; + { + const SpaFraction *f1 = (SpaFraction*)r1, + *f2 = (SpaFraction*)r2; + uint64_t n1, n2; + n1 = ((int64_t) f1->num) * f2->denom; + n2 = ((int64_t) f2->num) * f1->denom; + if (n1 < n2) + return -1; + else if (n1 > n2) + return 1; + else + return 0; + } default: break; } return 0; } +static inline SpaPODProp * +find_prop (const SpaPOD *pod, uint32_t size, uint32_t key) +{ + const SpaPOD *res; + SPA_POD_FOREACH (pod, size, res) { + if (res->type == SPA_POD_TYPE_PROP && ((SpaPODProp*)res)->body.key == key) + return (SpaPODProp *)res; + } + return NULL; +} + SpaResult spa_props_filter (SpaPODBuilder *b, const SpaPOD *props, @@ -167,7 +189,7 @@ spa_props_filter (SpaPODBuilder *b, p1 = (SpaPODProp *) pr; - if (filter == NULL || (p2 = spa_pod_contents_find_prop (filter, 0, p1->body.key)) == NULL) { + if (filter == NULL || (p2 = find_prop (filter, filter_size, p1->body.key)) == NULL) { /* no filter, copy the complete property */ spa_pod_builder_raw (b, p1, SPA_POD_SIZE (p1), true); continue; @@ -184,8 +206,8 @@ spa_props_filter (SpaPODBuilder *b, np = SPA_POD_BUILDER_DEREF (b, spa_pod_builder_push_prop (b, &f, p1->body.key, SPA_POD_PROP_FLAG_READWRITE), SpaPODProp); - /* size and type */ - spa_pod_builder_raw (b, &p1->body.value, sizeof (p1->body.value), false); + /* default value */ + spa_pod_builder_raw (b, &p1->body.value, sizeof (p1->body.value) + p1->body.value.size, false); alt1 = SPA_MEMBER (p1, sizeof (SpaPODProp), void); nalt1 = SPA_POD_PROP_N_VALUES (p1); @@ -248,11 +270,10 @@ spa_props_filter (SpaPODBuilder *b, np->body.flags |= SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET; } - if (rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_STEP) - return SPA_RESULT_NOT_IMPLEMENTED; - - if (rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_FLAGS) + if ((rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_STEP) || + (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_STEP)) { return SPA_RESULT_NOT_IMPLEMENTED; + } if ((rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_NONE) || (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_ENUM)) { @@ -287,15 +308,19 @@ spa_props_filter (SpaPODBuilder *b, spa_pod_builder_raw (b, alt1, p1->body.value.size, false); else spa_pod_builder_raw (b, alt2, p2->body.value.size, false); + + np->body.flags |= SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET; } + + if (rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_FLAGS) + return SPA_RESULT_NOT_IMPLEMENTED; + if (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_STEP) return SPA_RESULT_NOT_IMPLEMENTED; if (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_FLAGS) return SPA_RESULT_NOT_IMPLEMENTED; - if (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_STEP) - return SPA_RESULT_NOT_IMPLEMENTED; if (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_FLAGS) return SPA_RESULT_NOT_IMPLEMENTED;