diff --git a/spa/include/spa/pod/builder.h b/spa/include/spa/pod/builder.h index 27a3611a6..d1801832c 100644 --- a/spa/include/spa/pod/builder.h +++ b/spa/include/spa/pod/builder.h @@ -486,7 +486,7 @@ spa_pod_builder_control(struct spa_pod_builder *builder, uint32_t offset, uint32 return spa_pod_builder_raw(builder, &p, sizeof(p)); } -SPA_API_POD_BUILDER uint32_t spa_choice_from_id(char id) +SPA_API_POD_BUILDER uint32_t spa_choice_from_id_flags(char id, uint32_t *flags) { switch (id) { case 'r': @@ -495,6 +495,9 @@ SPA_API_POD_BUILDER uint32_t spa_choice_from_id(char id) return SPA_CHOICE_Step; case 'e': return SPA_CHOICE_Enum; + case 'F': + *flags |= SPA_POD_PROP_FLAG_DROP; + SPA_FALLTHROUGH; case 'f': return SPA_CHOICE_Flags; case 'n': @@ -502,6 +505,11 @@ SPA_API_POD_BUILDER uint32_t spa_choice_from_id(char id) return SPA_CHOICE_None; } } +SPA_API_POD_BUILDER uint32_t spa_choice_from_id(char id) +{ + uint32_t flags = 0; + return spa_choice_from_id_flags(id, &flags); +} #define SPA_POD_BUILDER_COLLECT(builder,type,args) \ do { \ @@ -621,43 +629,46 @@ spa_pod_builder_addv(struct spa_pod_builder *builder, va_list args) int n_values = 1; struct spa_pod_frame f; bool choice; + uint32_t key = 0, flags = 0, offset = 0, type = 0, ctype = 0; switch (ftype) { case SPA_TYPE_Object: - { - uint32_t key = va_arg(args, uint32_t), flags = 0; + key = va_arg(args, uint32_t); if (key == 0) goto exit; if (key == SPA_ID_INVALID) { key = va_arg(args, uint32_t); flags = va_arg(args, uint32_t); } - spa_pod_builder_prop(builder, key, flags); break; - } case SPA_TYPE_Sequence: - { - uint32_t offset = va_arg(args, uint32_t); - uint32_t type = va_arg(args, uint32_t); + offset = va_arg(args, uint32_t); + type = va_arg(args, uint32_t); if (type == 0) goto exit; - spa_pod_builder_control(builder, offset, type); - SPA_FALLTHROUGH - } - default: break; } + + if ((format = va_arg(args, const char *)) == NULL) break; choice = *format == '?'; if (choice) { - uint32_t type = spa_choice_from_id(*++format); + ctype = spa_choice_from_id_flags(*++format, &flags); if (*format != '\0') format++; - - spa_pod_builder_push_choice(builder, &f, type, 0); - + } + switch (ftype) { + case SPA_TYPE_Object: + spa_pod_builder_prop(builder, key, flags); + break; + case SPA_TYPE_Sequence: + spa_pod_builder_control(builder, offset, type); + break; + } + if (choice) { + spa_pod_builder_push_choice(builder, &f, ctype, 0); n_values = va_arg(args, int); } while (n_values-- > 0) diff --git a/spa/include/spa/pod/vararg.h b/spa/include/spa/pod/vararg.h index b2e5ec8eb..8e9137df1 100644 --- a/spa/include/spa/pod/vararg.h +++ b/spa/include/spa/pod/vararg.h @@ -30,6 +30,7 @@ extern "C" { #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_FLAGS(flags) 1, (flags) +#define SPA_CHOICE_FEATURES(features) 1, (features) #define SPA_CHOICE_BOOL(def) 3,(def),(def),!(def) #define SPA_POD_Bool(val) "b", val @@ -43,12 +44,14 @@ extern "C" { #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_FLAGS_Int(flags) "?fi", SPA_CHOICE_FLAGS(flags) +#define SPA_POD_CHOICE_FEATURES_Int(features) "?Fi", SPA_CHOICE_FEATURES(features) #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_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_FLAGS_Long(flags) "?fl", SPA_CHOICE_FLAGS(flags) +#define SPA_POD_CHOICE_FEATURES_LONG(features) "?Fl", SPA_CHOICE_FEATURES(features) #define SPA_POD_Float(val) "f", val #define SPA_POD_CHOICE_ENUM_Float(n_vals,...) "?ef", SPA_CHOICE_ENUM(n_vals, __VA_ARGS__)