pod: add support for flags filter

Add macro to make flags choice from int and long.
Implement the filter for flags by or-ing the flags.
This commit is contained in:
Wim Taymans 2020-03-09 12:47:33 +01:00
parent 6c911993fb
commit 387fcfdc8a
2 changed files with 40 additions and 10 deletions

View file

@ -60,6 +60,7 @@ static inline int spa_pod_choice_fix_default(struct spa_pod_choice *choice)
memcpy(val, alt, size); memcpy(val, alt, size);
} }
break; break;
case SPA_CHOICE_Flags:
case SPA_CHOICE_Enum: case SPA_CHOICE_Enum:
{ {
void *best = NULL; void *best = NULL;
@ -80,12 +81,37 @@ static inline int spa_pod_choice_fix_default(struct spa_pod_choice *choice)
choice->body.type = SPA_CHOICE_None; choice->body.type = SPA_CHOICE_None;
break; break;
} }
case SPA_CHOICE_Flags:
break;
} }
return 0; return 0;
} }
static inline int spa_pod_filter_flags_value(struct spa_pod_builder *b,
uint32_t type, const void *r1, const void *r2, uint32_t size)
{
switch (type) {
case SPA_TYPE_Int:
{
int32_t val = (*(int32_t *) r1) & (*(int32_t *) r2);
if (val == 0)
return 0;
spa_pod_builder_int(b, val);
break;
}
case SPA_TYPE_Long:
{
int64_t val = (*(int64_t *) r1) & (*(int64_t *) r2);
if (val == 0)
return 0;
spa_pod_builder_long(b, val);
break;
}
default:
return -ENOTSUP;
}
return 1;
}
static inline int static inline int
spa_pod_filter_prop(struct spa_pod_builder *b, spa_pod_filter_prop(struct spa_pod_builder *b,
const struct spa_pod_prop *p1, const struct spa_pod_prop *p1,
@ -110,14 +136,14 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
if (type != v2->type || size != v2->size || p1->key != p2->key) if (type != v2->type || size != v2->size || p1->key != p2->key)
return -EINVAL; return -EINVAL;
if (p1c == SPA_CHOICE_None) { if (p1c == SPA_CHOICE_None || p1c == SPA_CHOICE_Flags) {
nalt1 = 1; nalt1 = 1;
} else { } else {
alt1 = SPA_MEMBER(alt1, size, void); alt1 = SPA_MEMBER(alt1, size, void);
nalt1--; nalt1--;
} }
if (p2c == SPA_CHOICE_None) { if (p2c == SPA_CHOICE_None || p2c == SPA_CHOICE_Flags) {
nalt2 = 1; nalt2 = 1;
} else { } else {
alt2 = SPA_MEMBER(alt2, size, void); alt2 = SPA_MEMBER(alt2, size, void);
@ -211,8 +237,13 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
nc->body.type = SPA_CHOICE_Range; nc->body.type = SPA_CHOICE_Range;
} }
if (p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_Flags) if ((p1c == SPA_CHOICE_None && p2c == SPA_CHOICE_Flags) ||
return -ENOTSUP; (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_None) ||
(p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Flags)) {
if (spa_pod_filter_flags_value(b, type, alt1, alt2, size) != 1)
return -EINVAL;
nc->body.type = SPA_CHOICE_Flags;
}
if (p1c == SPA_CHOICE_Range && p2c == SPA_CHOICE_Flags) if (p1c == SPA_CHOICE_Range && p2c == SPA_CHOICE_Flags)
return -ENOTSUP; return -ENOTSUP;
@ -227,16 +258,12 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
if (p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_Flags) if (p1c == SPA_CHOICE_Step && p2c == SPA_CHOICE_Flags)
return -ENOTSUP; return -ENOTSUP;
if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_None)
return -ENOTSUP;
if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Range) if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Range)
return -ENOTSUP; return -ENOTSUP;
if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Step) if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Step)
return -ENOTSUP; return -ENOTSUP;
if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Enum) if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Enum)
return -ENOTSUP; return -ENOTSUP;
if (p1c == SPA_CHOICE_Flags && p2c == SPA_CHOICE_Flags)
return -ENOTSUP;
spa_pod_builder_pop(b, &f); spa_pod_builder_pop(b, &f);
spa_pod_choice_fix_default(nc); spa_pod_choice_fix_default(nc);

View file

@ -42,6 +42,7 @@ extern "C" {
#define SPA_CHOICE_RANGE(def,min,max) 3,(def),(min),(max) #define SPA_CHOICE_RANGE(def,min,max) 3,(def),(min),(max)
#define SPA_CHOICE_STEP(def,min,max,step) 4,(def),(min),(max),(step) #define SPA_CHOICE_STEP(def,min,max,step) 4,(def),(min),(max),(step)
#define SPA_CHOICE_ENUM(n_vals,...) (n_vals),##__VA_ARGS__ #define SPA_CHOICE_ENUM(n_vals,...) (n_vals),##__VA_ARGS__
#define SPA_CHOICE_FLAGS(flags) 1, (flags)
#define SPA_CHOICE_BOOL(def) 3,(def),(def),!(def) #define SPA_CHOICE_BOOL(def) 3,(def),(def),!(def)
#define SPA_POD_Bool(val) "b", val #define SPA_POD_Bool(val) "b", val
@ -54,11 +55,13 @@ extern "C" {
#define SPA_POD_CHOICE_ENUM_Int(n_vals,...) "?ei", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__) #define SPA_POD_CHOICE_ENUM_Int(n_vals,...) "?ei", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__)
#define SPA_POD_CHOICE_RANGE_Int(def,min,max) "?ri", SPA_CHOICE_RANGE(def, min, max) #define SPA_POD_CHOICE_RANGE_Int(def,min,max) "?ri", SPA_CHOICE_RANGE(def, min, max)
#define SPA_POD_CHOICE_STEP_Int(def,min,max,step) "?si", SPA_CHOICE_STEP(def, min, max, step) #define SPA_POD_CHOICE_STEP_Int(def,min,max,step) "?si", SPA_CHOICE_STEP(def, min, max, step)
#define SPA_POD_CHOICE_FLAGS_Int(flags) "?fi", SPA_CHOICE_FLAGS(flags)
#define SPA_POD_Long(val) "l", val #define SPA_POD_Long(val) "l", val
#define SPA_POD_CHOICE_ENUM_Long(n_vals,...) "?el", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__) #define SPA_POD_CHOICE_ENUM_Long(n_vals,...) "?el", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__)
#define SPA_POD_CHOICE_RANGE_Long(def,min,max) "?rl", SPA_CHOICE_RANGE(def, min, max) #define SPA_POD_CHOICE_RANGE_Long(def,min,max) "?rl", SPA_CHOICE_RANGE(def, min, max)
#define SPA_POD_CHOICE_STEP_Long(def,min,max,step) "?sl", SPA_CHOICE_STEP(def, min, max, step) #define SPA_POD_CHOICE_STEP_Long(def,min,max,step) "?sl", SPA_CHOICE_STEP(def, min, max, step)
#define SPA_POD_CHOICE_FLAGS_Long(flags) "?fl", SPA_CHOICE_FLAGS(flags)
#define SPA_POD_Float(val) "f", val #define SPA_POD_Float(val) "f", val
#define SPA_POD_CHOICE_ENUM_Float(n_vals,...) "?ef", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__) #define SPA_POD_CHOICE_ENUM_Float(n_vals,...) "?ef", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__)