diff --git a/spa/include/spa/audio/format-utils.h b/spa/include/spa/audio/format-utils.h index d95808c81..015611e55 100644 --- a/spa/include/spa/audio/format-utils.h +++ b/spa/include/spa/audio/format-utils.h @@ -50,18 +50,19 @@ spa_type_format_audio_map(struct spa_type_map *map, struct spa_type_format_audio } } -static inline bool +static inline int spa_format_audio_raw_parse(const struct spa_format *format, struct spa_audio_info_raw *info, struct spa_type_format_audio *type) { - spa_format_query(format, - type->format, SPA_POD_TYPE_ID, &info->format, - type->flags, SPA_POD_TYPE_INT, &info->flags, - type->layout, SPA_POD_TYPE_INT, &info->layout, - type->rate, SPA_POD_TYPE_INT, &info->rate, - type->channels, SPA_POD_TYPE_INT, &info->channels, - type->channel_mask, SPA_POD_TYPE_INT, &info->channel_mask, 0); - return true; + struct spa_pod_parser prs; + spa_pod_parser_pod(&prs, &format->pod); + return spa_pod_parser_get(&prs, + ":",type->format, "I", &info->format, + ":",type->rate, "i", &info->rate, + ":",type->channels, "i", &info->channels, + ":",type->flags, "?i", &info->flags, + ":",type->layout, "?i", &info->layout, + ":",type->channel_mask, "?i", &info->channel_mask, NULL); } #ifdef __cplusplus diff --git a/spa/include/spa/defs.h b/spa/include/spa/defs.h index 6616914c6..c725ffdf9 100644 --- a/spa/include/spa/defs.h +++ b/spa/include/spa/defs.h @@ -71,6 +71,7 @@ enum spa_result { SPA_RESULT_OUT_OF_BUFFERS = -35, SPA_RESULT_INCOMPATIBLE_PROPS = -36, SPA_RESULT_INCOMPATIBLE_VERSION = -37, + SPA_RESULT_NOT_FOUND = -38, }; #define SPA_ASYNC_BIT (1 << 30) @@ -89,11 +90,14 @@ enum spa_direction { SPA_DIRECTION_OUTPUT = 1, }; +#define SPA_RECTANGLE(width,height) (struct spa_rectangle){ width, height } + struct spa_rectangle { uint32_t width; uint32_t height; }; +#define SPA_FRACTION(num,denom) (struct spa_fraction){ num, denom } struct spa_fraction { uint32_t num; uint32_t denom; diff --git a/spa/include/spa/format-builder.h b/spa/include/spa/format-builder.h index 1585a49df..3a92a0041 100644 --- a/spa/include/spa/format-builder.h +++ b/spa/include/spa/format-builder.h @@ -48,11 +48,11 @@ spa_pod_builder_push_format(struct spa_pod_builder *builder, spa_pod_builder_raw(builder, &p, sizeof(p))); } -#define spa_pod_builder_format(b,f,format_type,media_type,media_subtype,...) \ - spa_pod_builder_object(b, f, 0, format_type, \ - SPA_POD_TYPE_ID,media_type, \ - SPA_POD_TYPE_ID,media_subtype, \ - ## __VA_ARGS__) +#define spa_pod_builder_format(b,format_type,media_type,media_subtype,...) \ + spa_pod_builder_object(b, 0, format_type, \ + "I",media_type, \ + "I",media_subtype, \ + ##__VA_ARGS__) #ifdef __cplusplus } /* extern "C" */ diff --git a/spa/include/spa/format-utils.h b/spa/include/spa/format-utils.h index 74144da7c..12f1c24f1 100644 --- a/spa/include/spa/format-utils.h +++ b/spa/include/spa/format-utils.h @@ -27,7 +27,7 @@ extern "C" { #include #include -#include +#include #include struct spa_type_media_type { @@ -149,22 +149,17 @@ spa_type_media_subtype_audio_map(struct spa_type_map *map, #define SPA_FORMAT_MEDIA_TYPE(f) SPA_POD_VALUE(struct spa_pod_id, &f->body.media_type) #define SPA_FORMAT_MEDIA_SUBTYPE(f) SPA_POD_VALUE(struct spa_pod_id, &f->body.media_subtype) -static inline struct spa_pod_prop *spa_format_find_prop(const struct spa_format *format, - uint32_t key) +#define spa_format_parse(format,...) \ +({ \ + struct spa_pod_parser __p; \ + const struct spa_format *__format = format; \ + spa_pod_parser_pod(&__p, &__format->pod); \ + spa_pod_parser_get(&__p, "<", ##__VA_ARGS__, NULL); \ +}) + +static inline struct spa_pod_prop *spa_format_find_prop(const struct spa_format *format, uint32_t key) { - return spa_pod_contents_find_prop(&format->pod, sizeof(struct spa_format), key); -} - -static inline uint32_t spa_format_query(const struct spa_format *format, uint32_t key, ...) -{ - uint32_t count; - va_list args; - - va_start(args, key); - count = spa_pod_contents_queryv(&format->pod, sizeof(struct spa_format), key, args); - va_end(args); - - return count; + return spa_pod_contents_find_prop(&format->pod, sizeof(struct spa_format), key); } static inline int spa_format_fixate(struct spa_format *format) diff --git a/spa/include/spa/hook.h b/spa/include/spa/hook.h index 96248a21f..bf5b91274 100644 --- a/spa/include/spa/hook.h +++ b/spa/include/spa/hook.h @@ -91,7 +91,7 @@ static inline void spa_hook_remove(struct spa_hook *hook) break; \ } \ } \ -}); +}) #define spa_hook_list_call(l,t,m,...) spa_hook_list_do_call(l,NULL,t,m,false,##__VA_ARGS__) #define spa_hook_list_call_once(l,t,m,...) spa_hook_list_do_call(l,NULL,t,m,true,##__VA_ARGS__) diff --git a/spa/include/spa/json-builder.h b/spa/include/spa/json-builder.h new file mode 100644 index 000000000..abc29ac49 --- /dev/null +++ b/spa/include/spa/json-builder.h @@ -0,0 +1,67 @@ +/* Spa + * Copyright (C) 2017 Wim Taymans + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __SPA_JSON_BUILDER_H__ +#define __SPA_JSON_BUILDER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +struct spa_json_builder { + char *data; + int size; + int offset; + int (*printf) (void *user_data, const char *format, va_list args); + void *user_data; +}; + +static inline int spa_json_builder_printf(struct spa_json_builder *builder, + const char *format, ...) +{ + va_list args; + int res; + + va_start(args, format); + if (builder->printf) + res = builder->printf(builder->user_data, format, args); + else { + int size = builder->size; + int offset = builder->offset; + int remain = SPA_MAX(0, size - offset); + + res = vsnprintf(&builder->data[offset], remain, format, args); + builder->offset += res; + if (builder->offset > size) + res = -1; + } + va_end(args); + + return res; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __SPA_JSON_BUILDER_H__ */ diff --git a/spa/include/spa/json.h b/spa/include/spa/json.h new file mode 100644 index 000000000..7e1a3f1e2 --- /dev/null +++ b/spa/include/spa/json.h @@ -0,0 +1,510 @@ +/* Spa + * Copyright (C) 2017 Wim Taymans + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __SPA_JSON_H__ +#define __SPA_JSON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +struct spa_json_iter { + const char *start; + const char *cur; + const char *end; + int state; + int depth; +}; + +struct spa_json_chunk { + const char *value; + int len; +}; + +static inline int +spa_json_chunk_extract(struct spa_json_chunk *chunk, const char *template, ...); + +enum spa_json_type { + SPA_JSON_TYPE_ANY = '-', + SPA_JSON_TYPE_CHUNK = 'c', + SPA_JSON_TYPE_INT = 'i', + SPA_JSON_TYPE_LONG = 'l', + SPA_JSON_TYPE_FLOAT = 'f', + SPA_JSON_TYPE_DOUBLE = 'd', + SPA_JSON_TYPE_STRING = 's', + SPA_JSON_TYPE_BOOL = 'b', + SPA_JSON_TYPE_RECTANGLE = 'R', + SPA_JSON_TYPE_FRACTION = 'F', + SPA_JSON_TYPE_OBJECT = 'o', + SPA_JSON_TYPE_ARRAY = 'a' +}; + +static inline bool spa_json_chunk_is_type(struct spa_json_chunk *chunk, + enum spa_json_type type) +{ + switch (type) { + case SPA_JSON_TYPE_ANY: + case SPA_JSON_TYPE_CHUNK: + return true; + case SPA_JSON_TYPE_INT: + case SPA_JSON_TYPE_LONG: + case SPA_JSON_TYPE_FLOAT: + case SPA_JSON_TYPE_DOUBLE: + return (chunk->value[0] >= '0' && chunk->value[0] <= '9') || + chunk->value[0] == '-' ; + case SPA_JSON_TYPE_STRING: + return chunk->value[0] == '\"'; + case SPA_JSON_TYPE_BOOL: + return chunk->value[0] == 't' || chunk->value[0] == 'f'; + case SPA_JSON_TYPE_RECTANGLE: + case SPA_JSON_TYPE_FRACTION: + case SPA_JSON_TYPE_ARRAY: + return chunk->value[0] == '['; + case SPA_JSON_TYPE_OBJECT: + return chunk->value[0] == '{'; + } + return false; +} + +static inline int spa_json_chunk_to_int(struct spa_json_chunk *chunk) { + return atoi(chunk->value); +} +static inline int64_t spa_json_chunk_to_long(struct spa_json_chunk *chunk) { + return atol(chunk->value); +} +static inline int64_t spa_json_chunk_to_float(struct spa_json_chunk *chunk) { + return strtof(chunk->value, NULL); +} +static inline int64_t spa_json_chunk_to_double(struct spa_json_chunk *chunk) { + return strtod(chunk->value, NULL); +} +static inline bool spa_json_chunk_to_bool(struct spa_json_chunk *chunk) { + return chunk->value[0] == 't'; +} +static inline int spa_json_chunk_to_rectangle(struct spa_json_chunk *chunk, + struct spa_rectangle *rect) { + return spa_json_chunk_extract(chunk, "[ #pi, #pi ]", &rect->width, &rect->height); +} +static inline int spa_json_chunk_to_fraction(struct spa_json_chunk *chunk, + struct spa_fraction *frac) { + return spa_json_chunk_extract(chunk, "[ #pi, #pi ]", &frac->num, &frac->denom); +} + +static inline void +spa_json_iter_init (struct spa_json_iter *iter, const char *data, size_t size) +{ + iter->start = iter->cur = data; + iter->end = size == -1 ? NULL : data + size; + iter->state = 0; + iter->depth = 0; +} + +static inline bool +spa_json_iter_chunk(struct spa_json_iter *iter, struct spa_json_chunk *chunk) +{ + if (!spa_json_chunk_is_type(chunk, SPA_JSON_TYPE_OBJECT) && + !spa_json_chunk_is_type(chunk, SPA_JSON_TYPE_ARRAY)) + return false; + + spa_json_iter_init (iter, chunk->value, -1); + iter->cur++; + return true; +} + +static inline int +spa_json_iter_next_chunk(struct spa_json_iter *iter, struct spa_json_chunk *chunk) +{ + int utf8_remain = 0; + + for (;iter->end == NULL || iter->cur < iter->end; iter->cur++) { + unsigned char cur = (unsigned char) *iter->cur; +again: + switch (iter->state) { + case 0: /* scanning for objects */ + switch (cur) { + case '\t': case ' ': case '\r': case '\n': case ':': case ',': + continue; + case '"': + chunk->value = iter->cur; + iter->state = 2; + continue; + case '[': case '{': + chunk->value = iter->cur; + if (++iter->depth > 1) + continue; + iter->cur++; + return chunk->len = 1; + case '}': case ']': + if (iter->depth == 0) + return 0; + --iter->depth; + continue; + case '-': case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9': case '#': + chunk->value = iter->cur; + iter->state = 1; + continue; + case '\0': + return 0; + } + return -1; + case 1: /* token */ + switch (cur) { + case '\t': case ' ': case '\r': case '\n': case ':': case ',': + case ']': case '}': + iter->state = 0; + if (iter->depth > 0) + goto again; + return chunk->len = iter->cur - chunk->value; + default: + if (cur >= 32 && cur <= 126) + continue; + } + return -1; + case 2: /* string */ + switch (cur) { + case '\\': + iter->state = 4; + continue; + case '"': + iter->state = 0; + if (iter->depth > 0) + continue; + iter->cur++; + return chunk->len = iter->cur - chunk->value; + case 240 ... 247: + utf8_remain++; + case 224 ... 239: + utf8_remain++; + case 192 ... 223: + utf8_remain++; + iter->state = 3; + continue; + default: + if (cur >= 32 && cur <= 126) + continue; + } + return -1; + case 3: /* utf chars */ + switch (cur) { + case 128 ... 191: + if (--utf8_remain == 0) + iter->state = 2; + continue; + } + return -1; + case 4: /* inside escape chars */ + switch (cur) { + case '"': case '\\': case '/': case 'b': case 'f': case 'n': case 'r': + case 't': case 'u': + iter->state = 2; + continue; + } + return -1; + } + } + return iter->depth == 0 ? 0 : -1; +} + +static inline void +spa_json_chunk_print(struct spa_json_chunk *chunk, int prefix) +{ + struct spa_json_iter iter; + if (spa_json_iter_chunk(&iter, chunk)) { + struct spa_json_chunk chunk2 = { NULL, }; + + printf ("%-*s%c\n", prefix, "", chunk->value[0]); + while (spa_json_iter_next_chunk(&iter, &chunk2) > 0) + spa_json_chunk_print(&chunk2, prefix + 2); + printf ("%-*s%c\n", prefix, "", iter.cur[0]); + } else { + printf ("%-*s%.*s\n", prefix, "", chunk->len, chunk->value); + } +} + + +static inline int spa_json_iter_find_key(struct spa_json_iter *iter, const char *key) +{ + struct spa_json_chunk ch = { NULL, }; + int res; + + iter->cur = iter->start + 1; + iter->depth = 0; + iter->state = 0; + + while (true) { + /* read key */ + if ((res = spa_json_iter_next_chunk(iter, &ch)) <= 0) + return res; + + if (spa_json_chunk_is_type(&ch, SPA_JSON_TYPE_STRING) && + strncmp(key, ch.value, ch.len) == 0) + return 1; + } + return 0; +} + +enum spa_json_prop_range { + SPA_JSON_PROP_RANGE_NONE = '-', + SPA_JSON_PROP_RANGE_MIN_MAX = 'r', + SPA_JSON_PROP_RANGE_STEP = 's', + SPA_JSON_PROP_RANGE_ENUM = 'e', + SPA_JSON_PROP_RANGE_FLAGS = 'f' +}; + +enum spa_json_prop_flags { + SPA_JSON_PROP_FLAG_UNSET = (1 << 0), + SPA_JSON_PROP_FLAG_OPTIONAL = (1 << 1), + SPA_JSON_PROP_FLAG_READONLY = (1 << 2), + SPA_JSON_PROP_FLAG_DEPRECATED = (1 << 3), +}; + +struct spa_json_prop { + enum spa_json_type type; + enum spa_json_prop_range range; + enum spa_json_prop_flags flags; + struct spa_json_chunk value; + struct spa_json_chunk alternatives; +}; + +static inline int +spa_json_chunk_parse_prop(struct spa_json_chunk *chunk, char type, + struct spa_json_prop *prop) +{ + if (spa_json_chunk_is_type(chunk, SPA_JSON_TYPE_ARRAY)) { + struct spa_json_chunk flags; + int res; + char ch; + + /* [, , [,...]] */ + if ((res = spa_json_chunk_extract(chunk, + "[ #&cs, #&c-, #&ca ]", + &flags, &prop->value, &prop->alternatives)) < 3) { + printf("can't parse prop chunk %d\n", res); + return -1; + } + + /* skip \" */ + flags.value++; + prop->type = *flags.value++; + if (type != SPA_JSON_TYPE_ANY && type != SPA_JSON_TYPE_CHUNK && prop->type != type) { + printf("prop chunk of wrong type %d %d\n", prop->type, type); + return -1; + } + prop->range = *flags.value++; + /* flags */ + prop->flags = 0; + while ((ch = *flags.value++) != '\"') { + switch (ch) { + case 'u': + prop->flags |= SPA_JSON_PROP_FLAG_UNSET; + break; + case 'o': + prop->flags |= SPA_JSON_PROP_FLAG_OPTIONAL; + break; + case 'r': + prop->flags |= SPA_JSON_PROP_FLAG_READONLY; + break; + case 'd': + prop->flags |= SPA_JSON_PROP_FLAG_DEPRECATED; + break; + } + } + } + else { + /* */ + prop->type = type; + prop->range = SPA_JSON_PROP_RANGE_NONE; + prop->flags = 0; + prop->value = *chunk; + prop->alternatives = *chunk; + } + return 0; +} + +/** + * #[*] + * + * * = skip assignment + * is: + * & -> pointer to type + * p -> property, fixed value store in pointer to type + * P -> property, stored in pointer to struct spa_json_prop + * + * + * - -> any + * c -> store as chunk if of type + * s -> string + * i -> int + * l -> long + * f -> float + * d -> double + * b -> bool + * R -> rectangle + * F -> fraction + * a -> array + * o -> object + */ +static inline int +spa_json_chunk_extract(struct spa_json_chunk *chunk, + const char *template, ...) +{ + struct spa_json_iter templ[16], it[16]; + struct spa_json_chunk tch = { NULL, }, ch = { NULL, }; + struct spa_json_prop prop; + const char *match; + int collected = 0, res, level = 0; + va_list args; + bool store; + + va_start(args, template); + + spa_json_iter_init(&it[0], chunk->value, chunk->len); + spa_json_iter_init (&templ[0], template, -1); + + while (true) { + res = spa_json_iter_next_chunk(&templ[level], &tch); + if (res == 0) { + if (--level == 0) + break; + continue; + } else if (res < 0) { + return res; + } + + switch (tch.value[0]) { + case '[': case '{': + if (spa_json_iter_next_chunk(&it[level], &ch) <= 0 || + ch.value[0] != tch.value[0]) + return -1; + if (++level == 16) + return -2; + spa_json_iter_chunk(&it[level], &ch); + spa_json_iter_chunk(&templ[level], &tch); + break; + case '"': + case '-': case '0' ... '9': + case 't': case 'f': + case 'n': + if (templ[level].start[0] == '{') { + if (spa_json_iter_find_key(&it[level], tch.value) <= 0) + continue; + } else if (spa_json_iter_next_chunk(&it[level], &ch) <= 0 || + ch.len != tch.len || + strncmp(ch.value, tch.value, ch.len) != 0) + return -1; + break; + case '#': + match = tch.value + 1; + if (spa_json_iter_next_chunk(&it[level], &ch) <= 0) + return -1; + + store = (match[0] != '*'); + if (!store) + match++; + + switch (match[0]) { + case 'p': + case 'P': + if (spa_json_chunk_parse_prop(&ch, match[1], &prop) < 0) + goto skip; + + if (match[0] == 'P') { + if (store) + *va_arg(args, struct spa_json_prop *) = prop; + collected++; + break; + } + else { + if (prop.flags & SPA_JSON_PROP_FLAG_UNSET) + goto skip; + + ch = prop.value; + } + /* fallthrough */ + case '&': + if (!spa_json_chunk_is_type(&ch, match[1] == SPA_JSON_TYPE_CHUNK ? + match[2] : match[1])) { +skip: + if (store) + va_arg(args, void *); + break; + } + if (!store) + break; + + collected++; + + switch (match[1]) { + case SPA_JSON_TYPE_CHUNK: + *va_arg(args, struct spa_json_chunk *) = ch; + break; + case SPA_JSON_TYPE_INT: + *va_arg(args, int *) = spa_json_chunk_to_int(&ch); + break; + case SPA_JSON_TYPE_LONG: + *va_arg(args, int64_t *) = spa_json_chunk_to_long(&ch); + break; + case SPA_JSON_TYPE_FLOAT: + *va_arg(args, float *) = spa_json_chunk_to_float(&ch); + break; + case SPA_JSON_TYPE_DOUBLE: + *va_arg(args, double *) = spa_json_chunk_to_double(&ch); + break; + case SPA_JSON_TYPE_BOOL: + *va_arg(args, bool *) = spa_json_chunk_to_bool(&ch); + break; + case SPA_JSON_TYPE_RECTANGLE: + spa_json_chunk_to_rectangle(&ch, + va_arg(args, struct spa_rectangle *)); + break; + case SPA_JSON_TYPE_FRACTION: + spa_json_chunk_to_fraction(&ch, + va_arg(args, struct spa_fraction *)); + break; + default: + printf("ignoring invalid #p type %c\n", match[1]); + va_arg(args, void *); + collected--; + continue; + } + break; + default: + printf("ignoring unknown match type %c\n", *match); + break; + } + break; + default: + printf("invalid char %c\n", tch.value[0]); + return -2; + } + } + va_end(args); + + return collected; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __SPA_JSON_H__ */ diff --git a/spa/include/spa/param.h b/spa/include/spa/param.h index 538b0d4b2..91d86e289 100644 --- a/spa/include/spa/param.h +++ b/spa/include/spa/param.h @@ -35,18 +35,27 @@ struct spa_param { struct spa_pod_object object; }; -static inline uint32_t spa_param_query(const struct spa_param *param, uint32_t key, ...) +static inline uint32_t +spa_pod_builder_push_param(struct spa_pod_builder *builder, + struct spa_pod_frame *frame, + uint32_t param_type) { - uint32_t count; - va_list args; - - va_start(args, key); - count = spa_pod_contents_queryv(¶m->object.pod, sizeof(struct spa_param), key, args); - va_end(args); - - return count; + return spa_pod_builder_push_object(builder, frame, 0, param_type); } +#define spa_pod_builder_param(b,param_type,...) \ + spa_pod_builder_object(b, 0, param_type, \ + ##__VA_ARGS__) + + +#define spa_param_parse(param,...) \ +({ \ + struct spa_pod_parser __p; \ + const struct spa_param *__param = param; \ + spa_pod_parser_pod(&__p, &__param->object.pod); \ + spa_pod_parser_get(&__p, "<", ##__VA_ARGS__, NULL); \ +}) + #define SPA_PARAM_BODY_FOREACH(body, size, iter) \ for ((iter) = SPA_MEMBER((body), sizeof(struct spa_pod_object_body), struct spa_pod_prop); \ (iter) < SPA_MEMBER((body), (size), struct spa_pod_prop); \ diff --git a/spa/include/spa/pod-builder.h b/spa/include/spa/pod-builder.h index f3d2443ac..ce18a6318 100644 --- a/spa/include/spa/pod-builder.h +++ b/spa/include/spa/pod-builder.h @@ -27,6 +27,10 @@ extern "C" { #include #include +#ifndef SPA_POD_MAX_LEVEL +#define SPA_POD_MAX_LEVEL 16 +#endif + struct spa_pod_frame { struct spa_pod_frame *parent; struct spa_pod pod; @@ -42,6 +46,8 @@ struct spa_pod_builder { uint32_t size); bool in_array; bool first; + struct spa_pod_frame frame[SPA_POD_MAX_LEVEL]; + int depth; }; #define SPA_POD_BUILDER_INIT(buffer,size) { buffer, size, } @@ -54,6 +60,7 @@ static inline void spa_pod_builder_init(struct spa_pod_builder *builder, void *d builder->size = size; builder->offset = 0; builder->stack = NULL; + builder->depth = 0; } static inline uint32_t @@ -144,6 +151,14 @@ spa_pod_builder_primitive(struct spa_pod_builder *builder, const struct spa_pod return ref; } +#define SPA_POD_NONE_INIT() { 0, SPA_POD_TYPE_NONE } + +static inline uint32_t spa_pod_builder_none(struct spa_pod_builder *builder) +{ + const struct spa_pod p = SPA_POD_NONE_INIT(); + return spa_pod_builder_primitive(builder, &p); +} + #define SPA_POD_BOOL_INIT(val) { { sizeof(uint32_t), SPA_POD_TYPE_BOOL }, val ? 1 : 0 } static inline uint32_t spa_pod_builder_bool(struct spa_pod_builder *builder, bool val) @@ -194,12 +209,24 @@ static inline uint32_t spa_pod_builder_double(struct spa_pod_builder *builder, d #define SPA_POD_STRING_INIT(len) { { len, SPA_POD_TYPE_STRING } } +static inline uint32_t +spa_pod_builder_write_string(struct spa_pod_builder *builder, const char *str, uint32_t len) +{ + uint32_t ref = 0; + if (spa_pod_builder_raw(builder, str, len) == -1) + ref = -1; + if (spa_pod_builder_raw(builder, "", 1) == -1) + ref = -1; + spa_pod_builder_pad(builder, builder->offset); + return ref; +} + static inline uint32_t spa_pod_builder_string_len(struct spa_pod_builder *builder, const char *str, uint32_t len) { - const struct spa_pod_string p = SPA_POD_STRING_INIT(len); + const struct spa_pod_string p = SPA_POD_STRING_INIT(len+1); uint32_t ref = spa_pod_builder_raw(builder, &p, sizeof(p)); - if (spa_pod_builder_raw_padded(builder, str, len) == -1) + if (spa_pod_builder_write_string(builder, str, len) == -1) ref = -1; return ref; } @@ -207,7 +234,7 @@ spa_pod_builder_string_len(struct spa_pod_builder *builder, const char *str, uin static inline uint32_t spa_pod_builder_string(struct spa_pod_builder *builder, const char *str) { uint32_t len = str ? strlen(str) : 0; - return spa_pod_builder_string_len(builder, str ? str : "", len + 1); + return spa_pod_builder_string_len(builder, str ? str : "", len); } #define SPA_POD_BYTES_INIT(len) { { len, SPA_POD_TYPE_BYTES } } @@ -231,6 +258,14 @@ spa_pod_builder_pointer(struct spa_pod_builder *builder, uint32_t type, void *va return spa_pod_builder_primitive(builder, &p.pod); } +#define SPA_POD_FD_INIT(fd) { { sizeof(int), SPA_POD_TYPE_FD }, fd } + +static inline uint32_t spa_pod_builder_fd(struct spa_pod_builder *builder, int fd) +{ + const struct spa_pod_fd p = SPA_POD_FD_INIT(fd); + return spa_pod_builder_primitive(builder, &p.pod); +} + #define SPA_POD_RECTANGLE_INIT(width,height) { { sizeof(struct spa_rectangle), SPA_POD_TYPE_RECTANGLE }, { width, height } } static inline uint32_t @@ -311,238 +346,227 @@ spa_pod_builder_push_prop(struct spa_pod_builder *builder, sizeof(p) - sizeof(struct spa_pod))); } -static inline void -spa_pod_builder_addv(struct spa_pod_builder *builder, uint32_t type, va_list args) +static inline uint32_t spa_pod_range_from_id(char id) { - uint32_t n_values = 0; - union { - struct spa_pod pod; - struct spa_pod_bool bool_pod; - struct spa_pod_id id_pod; - struct spa_pod_int int_pod; - struct spa_pod_long long_pod; - struct spa_pod_float float_pod; - struct spa_pod_double double_pod; - struct spa_pod_string string_pod; - struct spa_pod_bytes bytes_pod; - struct spa_pod_pointer pointer_pod; - struct spa_pod_rectangle rectangle_pod; - struct spa_pod_fraction fraction_pod; - struct spa_pod_array array_pod; - struct spa_pod_struct struct_pod; - struct spa_pod_object object_pod; - struct spa_pod_prop prop_pod; - } head; - uint32_t head_size; - const void *body; - uint32_t body_size; - static const uint64_t zeroes = 0; - - while (type != SPA_POD_TYPE_INVALID) { - struct spa_pod_frame *f = NULL; - const void *data[3]; - uint32_t size[3], ref, i, n_sizes = 0; - - switch (type) { - case SPA_POD_TYPE_NONE: - break; - case SPA_POD_TYPE_BOOL: - case SPA_POD_TYPE_ID: - case SPA_POD_TYPE_INT: - head.int_pod.pod.type = type; - head.int_pod.pod.size = body_size = sizeof(uint32_t); - head.int_pod.value = va_arg(args, int); - head_size = sizeof(struct spa_pod); - body = &head.int_pod.value; - goto primitive; - case SPA_POD_TYPE_LONG: - head.long_pod.pod.type = SPA_POD_TYPE_LONG; - head.long_pod.pod.size = body_size = sizeof(uint32_t); - head.long_pod.value = va_arg(args, int64_t); - head_size = sizeof(struct spa_pod); - body = &head.long_pod.value; - goto primitive; - case SPA_POD_TYPE_FLOAT: - head.float_pod.pod.type = SPA_POD_TYPE_FLOAT; - head.float_pod.pod.size = body_size = sizeof(float); - head.float_pod.value = va_arg(args, double); - head_size = sizeof(struct spa_pod); - body = &head.float_pod.value; - goto primitive; - case SPA_POD_TYPE_DOUBLE: - head.double_pod.pod.type = SPA_POD_TYPE_DOUBLE; - head.double_pod.pod.size = body_size = sizeof(double); - head.double_pod.value = va_arg(args, double); - head_size = sizeof(struct spa_pod); - body = &head.double_pod.value; - goto primitive; - case SPA_POD_TYPE_STRING: - body = va_arg(args, const char *); - body_size = body ? strlen(body) + 1 : (body = "", 1); - head.string_pod.pod.type = SPA_POD_TYPE_STRING; - head.string_pod.pod.size = body_size; - head_size = sizeof(struct spa_pod); - goto primitive; - case -SPA_POD_TYPE_STRING: - body = va_arg(args, const char *); - body_size = va_arg(args, uint32_t); - head.string_pod.pod.type = SPA_POD_TYPE_STRING; - head.string_pod.pod.size = body_size; - head_size = sizeof(struct spa_pod); - goto primitive; - case SPA_POD_TYPE_BYTES: - body = va_arg(args, void *); - body_size = va_arg(args, uint32_t); - head.bytes_pod.pod.type = SPA_POD_TYPE_BYTES; - head.bytes_pod.pod.size = body_size; - head_size = sizeof(struct spa_pod); - goto primitive; - case SPA_POD_TYPE_POINTER: - head.pointer_pod.pod.type = SPA_POD_TYPE_POINTER; - head.pointer_pod.pod.size = body_size = sizeof(struct spa_pod_pointer_body); - head.pointer_pod.body.type = va_arg(args, uint32_t); - head.pointer_pod.body.value = va_arg(args, void *); - head_size = sizeof(struct spa_pod); - body = &head.pointer_pod.body; - goto primitive; - case SPA_POD_TYPE_RECTANGLE: - head.rectangle_pod.pod.type = SPA_POD_TYPE_RECTANGLE; - head.rectangle_pod.pod.size = body_size = sizeof(struct spa_rectangle); - head.rectangle_pod.value.width = va_arg(args, uint32_t); - head.rectangle_pod.value.height = va_arg(args, uint32_t); - head_size = sizeof(struct spa_pod); - body = &head.rectangle_pod.value; - goto primitive; - case -SPA_POD_TYPE_RECTANGLE: - head.rectangle_pod.pod.type = SPA_POD_TYPE_RECTANGLE; - head.rectangle_pod.pod.size = body_size = sizeof(struct spa_rectangle); - head.rectangle_pod.value = *va_arg(args, struct spa_rectangle *); - head_size = sizeof(struct spa_pod); - body = &head.rectangle_pod.value; - goto primitive; - case SPA_POD_TYPE_FRACTION: - head.fraction_pod.pod.type = SPA_POD_TYPE_FRACTION; - head.fraction_pod.pod.size = body_size = sizeof(struct spa_fraction); - head.fraction_pod.value.num = va_arg(args, uint32_t); - head.fraction_pod.value.denom = va_arg(args, uint32_t); - head_size = sizeof(struct spa_pod); - body = &head.fraction_pod.value; - goto primitive; - case -SPA_POD_TYPE_FRACTION: - head.fraction_pod.pod.type = SPA_POD_TYPE_FRACTION; - head.fraction_pod.pod.size = body_size = sizeof(struct spa_fraction); - head.fraction_pod.value = *va_arg(args, struct spa_fraction *); - head_size = sizeof(struct spa_pod); - body = &head.fraction_pod.value; - goto primitive; - case SPA_POD_TYPE_BITMASK: - break; - case SPA_POD_TYPE_ARRAY: - f = va_arg(args, struct spa_pod_frame *); - type = va_arg(args, uint32_t); - n_values = va_arg(args, uint32_t); - head.array_pod.pod.type = SPA_POD_TYPE_ARRAY; - head.array_pod.pod.size = 0; - head_size = sizeof(struct spa_pod); - body = NULL; - goto primitive; - case SPA_POD_TYPE_STRUCT: - f = va_arg(args, struct spa_pod_frame *); - head.struct_pod.pod.type = SPA_POD_TYPE_STRUCT; - head.struct_pod.pod.size = 0; - head_size = sizeof(struct spa_pod); - body = NULL; - goto primitive; - case SPA_POD_TYPE_OBJECT: - f = va_arg(args, struct spa_pod_frame *); - head.object_pod.pod.type = SPA_POD_TYPE_OBJECT; - head.object_pod.pod.size = sizeof(struct spa_pod_object_body); - head.object_pod.body.id = va_arg(args, uint32_t); - head.object_pod.body.type = va_arg(args, uint32_t); - head_size = sizeof(struct spa_pod_object); - body = NULL; - goto primitive; - case SPA_POD_TYPE_PROP: - f = va_arg(args, struct spa_pod_frame *); - head.prop_pod.pod.type = SPA_POD_TYPE_PROP; - head.prop_pod.pod.size = - sizeof(struct spa_pod_prop_body) - sizeof(struct spa_pod); - head.prop_pod.body.key = va_arg(args, uint32_t); - head.prop_pod.body.flags = va_arg(args, uint32_t); - head_size = sizeof(struct spa_pod_prop) - sizeof(struct spa_pod); - body = NULL; - type = va_arg(args, uint32_t); - n_values = va_arg(args, uint32_t); - goto primitive; - case -SPA_POD_TYPE_ARRAY: - case -SPA_POD_TYPE_STRUCT: - case -SPA_POD_TYPE_OBJECT: - case -SPA_POD_TYPE_PROP: - f = va_arg(args, struct spa_pod_frame *); - spa_pod_builder_pop(builder, f); - break; - case SPA_POD_TYPE_POD: - if ((body = va_arg(args, void *)) == NULL) { - head.pod.type = SPA_POD_TYPE_NONE; - head.pod.size = 0; - body = &head; - } - body_size = SPA_POD_SIZE(body); - goto extra; - } - if (0) { - primitive: - if (!builder->in_array || builder->first) { - data[n_sizes] = &head; - size[n_sizes++] = head_size; - builder->first = false; - } - if (body) { - extra: - data[n_sizes] = body; - size[n_sizes++] = body_size; - if (!builder->in_array) { - data[n_sizes] = &zeroes; - size[n_sizes++] = SPA_ROUND_UP_N(body_size, 8) - body_size; - } - } - for (i = 0; i < n_sizes; i++) { - ref = spa_pod_builder_raw(builder, data[i], size[i]); - if (f && i == 0) - spa_pod_builder_push(builder, f, data[i], ref); - } - } - if (n_values > 0) - n_values--; - else - type = va_arg(args, uint32_t); + switch (id) { + case 'r': + return SPA_POD_PROP_RANGE_MIN_MAX; + case 's': + return SPA_POD_PROP_RANGE_STEP; + case 'e': + return SPA_POD_PROP_RANGE_ENUM; + case 'f': + return SPA_POD_PROP_RANGE_FLAGS; + default: + return SPA_POD_PROP_RANGE_NONE; } } -static inline void spa_pod_builder_add(struct spa_pod_builder *builder, uint32_t type, ...) +static inline uint32_t spa_pod_flag_from_id(char id) { - va_list args; - - va_start(args, type); - spa_pod_builder_addv(builder, type, args); - va_end(args); + switch (id) { + case 'u': + return SPA_POD_PROP_FLAG_UNSET; + case 'o': + return SPA_POD_PROP_FLAG_OPTIONAL; + case 'r': + return SPA_POD_PROP_FLAG_READONLY; + case 'd': + return SPA_POD_PROP_FLAG_DEPRECATED; + default: + return 0; + } } -#define SPA_POD_OBJECT(f,id,type,...) \ - SPA_POD_TYPE_OBJECT, f, id, type, __VA_ARGS__, -SPA_POD_TYPE_OBJECT, f +#define SPA_POD_BUILDER_COLLECT(builder,type,args) \ +do { \ + switch (type) { \ + case 'b': \ + spa_pod_builder_bool(builder, va_arg(args, int)); \ + break; \ + case 'I': \ + spa_pod_builder_id(builder, va_arg(args, uint32_t)); \ + break; \ + case 'i': \ + spa_pod_builder_int(builder, va_arg(args, int)); \ + break; \ + case 'l': \ + spa_pod_builder_long(builder, va_arg(args, int64_t)); \ + break; \ + case 'f': \ + spa_pod_builder_float(builder, va_arg(args, double)); \ + break; \ + case 'd': \ + spa_pod_builder_double(builder, va_arg(args, double)); \ + break; \ + case 's': \ + { \ + char *strval = va_arg(args, char *) ? : ""; \ + size_t len = strlen(strval); \ + spa_pod_builder_string_len(builder, strval, len); \ + break; \ + } \ + case 'S': \ + { \ + char *strval = va_arg(args, char *); \ + size_t len = va_arg(args, int); \ + spa_pod_builder_string_len(builder, strval, len); \ + break; \ + } \ + case 'z': \ + { \ + void *ptr = va_arg(args, void *); \ + int len = va_arg(args, int); \ + spa_pod_builder_bytes(builder, ptr, len); \ + break; \ + } \ + case 'R': \ + { \ + struct spa_rectangle *rectval = \ + va_arg(args, struct spa_rectangle *); \ + spa_pod_builder_rectangle(builder, \ + rectval->width, rectval->height); \ + break; \ + } \ + case 'F': \ + { \ + struct spa_fraction *fracval = \ + va_arg(args, struct spa_fraction *); \ + spa_pod_builder_fraction(builder, fracval->num, fracval->denom);\ + break; \ + } \ + case 'a': \ + { \ + int child_size = va_arg(args, int); \ + int child_type = va_arg(args, int); \ + int n_elems = va_arg(args, int); \ + void *elems = va_arg(args, void *); \ + spa_pod_builder_array(builder, child_size, \ + child_type, n_elems, elems); \ + break; \ + } \ + case 'p': \ + { \ + int t = va_arg(args, uint32_t); \ + spa_pod_builder_pointer(builder, t, va_arg(args, void *)); \ + break; \ + } \ + case 'h': \ + spa_pod_builder_fd(builder, va_arg(args, int)); \ + break; \ + case 'P': \ + { \ + struct spa_pod *pod = va_arg(args, struct spa_pod *); \ + if (pod == NULL) \ + spa_pod_builder_none(builder); \ + else \ + spa_pod_builder_primitive(builder, pod); \ + break; \ + } \ + } \ +} while(false) -#define SPA_POD_STRUCT(f,...) \ - SPA_POD_TYPE_STRUCT, f, __VA_ARGS__, -SPA_POD_TYPE_STRUCT, f +static inline void * +spa_pod_builder_addv(struct spa_pod_builder *builder, + const char *format, va_list args) +{ + while (format) { + switch (*format) { + case '<': + { + uint32_t id = va_arg(args, uint32_t); + uint32_t type = va_arg(args, uint32_t); + spa_pod_builder_push_object(builder, &builder->frame[builder->depth++], id, type); + break; + } + case '[': + spa_pod_builder_push_struct(builder, &builder->frame[builder->depth++]); + break; + case '(': + spa_pod_builder_push_array(builder, &builder->frame[builder->depth++]); + break; + case ':': + { + const char *spec; + char type; + int n_values; + uint32_t key, flags; -#define SPA_POD_PROP(f,key,flags,type,...) \ - SPA_POD_TYPE_PROP, f, key, flags, type, __VA_ARGS__, -SPA_POD_TYPE_PROP, f + key = va_arg(args, uint32_t); + format = spec = va_arg(args, const char *); + type = *spec; + if (*spec != '\0') + spec++; + flags = spa_pod_range_from_id(*spec); + if (*spec != '\0') + spec++; + for (;*spec;spec++) + flags |= spa_pod_flag_from_id(*spec); + spa_pod_builder_push_prop(builder, &builder->frame[builder->depth++], key, flags); -#define spa_pod_builder_object(b,f,id,type,...) \ - spa_pod_builder_add(b, SPA_POD_OBJECT(f,id,type,__VA_ARGS__), 0) + if (type == '{' || type == '[') + continue; -#define spa_pod_builder_struct(b,f,...) \ - spa_pod_builder_add(b, SPA_POD_STRUCT(f,__VA_ARGS__), 0) + n_values = -1; + while (n_values-- != 0) { + SPA_POD_BUILDER_COLLECT(builder, type, args); + + if ((flags & SPA_POD_PROP_RANGE_MASK) == 0) + break; + + if (n_values == -2) + n_values = va_arg(args, int); + } + spa_pod_builder_pop(builder, &builder->frame[--builder->depth]); + break; + } + case ']': case ')': case '>': + spa_pod_builder_pop(builder, &builder->frame[--builder->depth]); + if (builder->depth > 0 && + builder->frame[builder->depth-1].pod.type == SPA_POD_TYPE_PROP) + spa_pod_builder_pop(builder, &builder->frame[--builder->depth]); + break; + case ' ': case '\n': case '\t': case '\r': + break; + case '\0': + format = va_arg(args, const char *); + continue; + default: + SPA_POD_BUILDER_COLLECT(builder,*format,args); + break;; + } + format++; + } + return SPA_POD_BUILDER_DEREF(builder, builder->frame[builder->depth].ref, void); +} + +static inline void *spa_pod_builder_add(struct spa_pod_builder *builder, const char *format, ...) +{ + void *res; + va_list args; + + va_start(args, format); + res = spa_pod_builder_addv(builder, format, args); + va_end(args); + + return res; +} + +#define SPA_POD_OBJECT(id,type,...) \ + "<", id, type, ##__VA_ARGS__, ">" + +#define SPA_POD_STRUCT(...) \ + "[", ##__VA_ARGS__, "]" + +#define SPA_POD_PROP(key,spec,type,value,...) \ + ":", key, spec, value, ##__VA_ARGS__ + +#define spa_pod_builder_object(b,id,type,...) \ + spa_pod_builder_add(b, SPA_POD_OBJECT(id,type,##__VA_ARGS__), NULL) + +#define spa_pod_builder_struct(b,...) \ + spa_pod_builder_add(b, SPA_POD_STRUCT(__VA_ARGS__), NULL) #ifdef __cplusplus } /* extern "C" */ diff --git a/spa/include/spa/pod-iter.h b/spa/include/spa/pod-iter.h index 80ffbbaa8..4df69e339 100644 --- a/spa/include/spa/pod-iter.h +++ b/spa/include/spa/pod-iter.h @@ -35,102 +35,27 @@ struct spa_pod_iter { uint32_t offset; }; -static inline void spa_pod_iter_contents(struct spa_pod_iter *iter, const void *data, uint32_t size) +static inline void spa_pod_iter_init(struct spa_pod_iter *iter, const void *data, uint32_t size, uint32_t offset) { iter->data = data; iter->size = size; - iter->offset = 0; + iter->offset = offset; } -static inline bool spa_pod_iter_struct(struct spa_pod_iter *iter, const void *data, uint32_t size) +static inline struct spa_pod *spa_pod_iter_current(struct spa_pod_iter *iter) { - if (data == NULL || size < 8 || SPA_POD_SIZE(data) > size - || SPA_POD_TYPE(data) != SPA_POD_TYPE_STRUCT) - return false; - - spa_pod_iter_contents(iter, SPA_POD_CONTENTS(struct spa_pod_struct, data), - SPA_POD_CONTENTS_SIZE(struct spa_pod_struct, data)); - return true; -} - -static inline bool spa_pod_iter_object(struct spa_pod_iter *iter, const void *data, uint32_t size) -{ - if (data == NULL || SPA_POD_SIZE(data) > size || SPA_POD_TYPE(data) != SPA_POD_TYPE_OBJECT) - return false; - - spa_pod_iter_contents(iter, SPA_POD_CONTENTS(struct spa_pod_object, data), - SPA_POD_CONTENTS_SIZE(struct spa_pod_object, data)); - return true; -} - -static inline bool spa_pod_iter_pod(struct spa_pod_iter *iter, struct spa_pod *pod) -{ - void *data; - uint32_t size; - - switch (SPA_POD_TYPE(pod)) { - case SPA_POD_TYPE_STRUCT: - data = SPA_POD_CONTENTS(struct spa_pod_struct, pod); - size = SPA_POD_CONTENTS_SIZE(struct spa_pod_struct, pod); - break; - case SPA_POD_TYPE_OBJECT: - data = SPA_POD_CONTENTS(struct spa_pod_object, pod); - size = SPA_POD_CONTENTS_SIZE(struct spa_pod_object, pod); - break; - default: - spa_pod_iter_contents(iter, NULL, 0); - return false; + if (iter->offset + 8 <= iter->size) { + struct spa_pod *pod = SPA_MEMBER(iter->data, iter->offset, struct spa_pod); + if (SPA_POD_SIZE(pod) <= iter->size) + return pod; } - spa_pod_iter_contents(iter, data, size); - return true; + return NULL; } -static inline bool spa_pod_iter_has_next(struct spa_pod_iter *iter) +static inline void spa_pod_iter_advance(struct spa_pod_iter *iter, struct spa_pod *current) { - return (iter->offset + 8 <= iter->size && - SPA_POD_SIZE(SPA_MEMBER(iter->data, iter->offset, struct spa_pod)) <= iter->size); -} - -static inline struct spa_pod *spa_pod_iter_next(struct spa_pod_iter *iter) -{ - struct spa_pod *res = SPA_MEMBER(iter->data, iter->offset, struct spa_pod); - iter->offset += SPA_ROUND_UP_N(SPA_POD_SIZE(res), 8); - return res; -} - -static inline struct spa_pod *spa_pod_iter_first(struct spa_pod_iter *iter, struct spa_pod *pod) -{ - if (!spa_pod_iter_pod(iter, pod) || !spa_pod_iter_has_next(iter)) - return NULL; - return spa_pod_iter_next(iter); -} - -static inline bool spa_pod_iter_getv(struct spa_pod_iter *iter, uint32_t type, va_list args) -{ - bool res = true; - - while (type && (res = spa_pod_iter_has_next(iter))) { - struct spa_pod *pod = spa_pod_iter_next(iter); - - SPA_POD_COLLECT(pod, type, args, error); - - type = va_arg(args, uint32_t); - } - return res; - error: - return false; -} - -static inline bool spa_pod_iter_get(struct spa_pod_iter *iter, uint32_t type, ...) -{ - va_list args; - bool res; - - va_start(args, type); - res = spa_pod_iter_getv(iter, type, args); - va_end(args); - - return res; + if (current) + iter->offset += SPA_ROUND_UP_N(SPA_POD_SIZE(current), 8); } #ifdef __cplusplus diff --git a/spa/include/spa/pod-parser.h b/spa/include/spa/pod-parser.h new file mode 100644 index 000000000..654904ce9 --- /dev/null +++ b/spa/include/spa/pod-parser.h @@ -0,0 +1,313 @@ +/* Spa + * Copyright (C) 2017 Wim Taymans + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef __SPA_POD_PARSER_H__ +#define __SPA_POD_PARSER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#ifndef SPA_POD_MAX_LEVEL +#define SPA_POD_MAX_LEVEL 16 +#endif + +struct spa_pod_parser { + struct spa_pod_iter iter[SPA_POD_MAX_LEVEL]; + int depth; +}; + +static inline void spa_pod_parser_init(struct spa_pod_parser *parser, + const void *data, uint32_t size, uint32_t offset) +{ + parser->depth = 0; + spa_pod_iter_init(&parser->iter[0], data, size, offset); +} + +static inline void spa_pod_parser_pod(struct spa_pod_parser *parser, + const struct spa_pod *pod) +{ + spa_pod_parser_init(parser, pod, SPA_POD_SIZE(pod), 0); +} + +static inline bool spa_pod_parser_can_collect(struct spa_pod *pod, char type) +{ + if (type == 'P') + return true; + + switch (SPA_POD_TYPE(pod)) { + case SPA_POD_TYPE_NONE: + return type == 'T' || type == 'O' || type == 'V'; + case SPA_POD_TYPE_BOOL: + return type == 'b'; + case SPA_POD_TYPE_ID: + return type == 'I'; + case SPA_POD_TYPE_INT: + return type == 'i'; + case SPA_POD_TYPE_LONG: + return type == 'l'; + case SPA_POD_TYPE_FLOAT: + return type == 'f'; + case SPA_POD_TYPE_DOUBLE: + return type == 'd'; + case SPA_POD_TYPE_STRING: + return type == 's' || type == 'S'; + case SPA_POD_TYPE_BYTES: + return type == 'z'; + case SPA_POD_TYPE_RECTANGLE: + return type == 'R'; + case SPA_POD_TYPE_FRACTION: + return type == 'F'; + case SPA_POD_TYPE_BITMAP: + return type == 'B'; + case SPA_POD_TYPE_ARRAY: + return type == 'a'; + case SPA_POD_TYPE_STRUCT: + return type == 'T'; + case SPA_POD_TYPE_OBJECT: + return type == 'O'; + case SPA_POD_TYPE_POINTER: + return type == 'p'; + case SPA_POD_TYPE_FD: + return type == 'h'; + case SPA_POD_TYPE_PROP: + return type == 'V'; + default: + return false; + } +} + +#define SPA_POD_PARSER_COLLECT(pod,type,args) \ +do { \ + switch (type) { \ + case 'b': \ + *va_arg(args, int*) = SPA_POD_VALUE(struct spa_pod_bool, pod); \ + break; \ + case 'I': \ + case 'i': \ + *va_arg(args, int32_t*) = SPA_POD_VALUE(struct spa_pod_int, pod); \ + break; \ + case 'l': \ + *va_arg(args, int64_t*) = SPA_POD_VALUE(struct spa_pod_long, pod); \ + break; \ + case 'f': \ + *va_arg(args, float*) = SPA_POD_VALUE(struct spa_pod_float, pod); \ + break; \ + case 'd': \ + *va_arg(args, double*) = SPA_POD_VALUE(struct spa_pod_double, pod); \ + break; \ + case 's': \ + *va_arg(args, char**) = SPA_POD_CONTENTS(struct spa_pod_string, pod); \ + break; \ + case 'S': \ + { \ + char *dest = va_arg(args, char*); \ + uint32_t maxlen = va_arg(args, uint32_t); \ + strncpy(dest, SPA_POD_CONTENTS(struct spa_pod_string, pod), maxlen-1); \ + break; \ + } \ + case 'z': \ + *(va_arg(args, void **)) = SPA_POD_CONTENTS(struct spa_pod_bytes, pod); \ + *(va_arg(args, uint32_t *)) = SPA_POD_BODY_SIZE(pod); \ + break; \ + case 'R': \ + *va_arg(args, struct spa_rectangle*) = \ + SPA_POD_VALUE(struct spa_pod_rectangle, pod); \ + break; \ + case 'F': \ + *va_arg(args, struct spa_fraction*) = \ + SPA_POD_VALUE(struct spa_pod_fraction, pod); \ + break; \ + case 'B': \ + *va_arg(args, uint32_t **) = \ + SPA_POD_CONTENTS(struct spa_pod_bitmap, pod); \ + break; \ + case 'p': \ + { \ + struct spa_pod_pointer_body *b = SPA_POD_BODY(pod); \ + *(va_arg(args, void **)) = b->value; \ + break; \ + } \ + case 'h': \ + *va_arg(args, int*) = SPA_POD_VALUE(struct spa_pod_fd, pod); \ + break; \ + case 'V': \ + case 'P': \ + case 'O': \ + case 'T': \ + *va_arg(args, struct spa_pod**) = \ + (pod == NULL || (SPA_POD_TYPE(pod) == SPA_POD_TYPE_NONE) \ + ? NULL : pod); \ + break; \ + default: \ + break; \ + } \ +} while(false) + +#define SPA_POD_PARSER_SKIP(type,args) \ +do { \ + switch (type) { \ + case 'S': \ + va_arg(args, void*); \ + va_arg(args, uint32_t); \ + break; \ + case 'z': \ + va_arg(args, void**); \ + case 'b': \ + case 'I': \ + case 'i': \ + case 'l': \ + case 'f': \ + case 'd': \ + case 's': \ + case 'R': \ + case 'F': \ + case 'B': \ + case 'p': \ + case 'h': \ + case 'V': \ + case 'P': \ + case 'T': \ + case 'O': \ + va_arg(args, void*); \ + break; \ + } \ +} while(false) + +static inline int spa_pod_parser_getv(struct spa_pod_parser *parser, + const char *format, va_list args) +{ + struct spa_pod *pod = NULL, *current; + struct spa_pod_prop *prop = NULL; + bool required = true, suppress = false, skip = false; + struct spa_pod_iter *it = &parser->iter[parser->depth]; + + current = pod = spa_pod_iter_current(it); + + while (format) { + switch (*format) { + case '<': + if (pod == NULL || SPA_POD_TYPE(pod) != SPA_POD_TYPE_OBJECT) + return SPA_RESULT_ERROR; + it = &parser->iter[++parser->depth]; + spa_pod_iter_init(it, pod, SPA_POD_SIZE(pod), sizeof(struct spa_pod_object)); + goto read_pod; + case '[': + if (pod == NULL || SPA_POD_TYPE(pod) != SPA_POD_TYPE_STRUCT) + return SPA_RESULT_ERROR; + it = &parser->iter[++parser->depth]; + spa_pod_iter_init(it, pod, SPA_POD_SIZE(pod), sizeof(struct spa_pod_struct)); + goto read_pod; + case ']': case '>': + if (current != NULL) + return SPA_RESULT_ERROR; + if (--parser->depth < 0) + return SPA_RESULT_INVALID_ARGUMENTS; + + it = &parser->iter[parser->depth]; + current = spa_pod_iter_current(it); + spa_pod_iter_advance(it, current); + goto read_pod; + case '\0': + format = va_arg(args, char *); + continue; + case ' ': case '\n': case '\t': case '\r': + break; + case '?': + required = false; + break; + case '*': + suppress = true; + break; + case ':': + { + uint32_t key = va_arg(args, uint32_t); + const struct spa_pod *obj = parser->iter[parser->depth].data; + + if (SPA_POD_TYPE(obj) == SPA_POD_TYPE_OBJECT) + prop = spa_pod_object_find_prop((struct spa_pod_object*)obj, key); + else if (SPA_POD_TYPE(obj) == SPA_POD_TYPE_STRUCT) + prop = spa_pod_struct_find_prop((struct spa_pod_struct*)obj, key); + else + prop = NULL; + + if (prop != NULL && (prop->body.flags & SPA_POD_PROP_FLAG_UNSET) == 0) + pod = &prop->body.value; + else + pod = NULL; + + it->offset = it->size; + current = NULL; + required = true; + break; + } + case 'V': + pod = (struct spa_pod *) prop; + if (pod == NULL && required) + return SPA_RESULT_NOT_FOUND; + goto collect; + default: + if (pod == NULL || !spa_pod_parser_can_collect(pod, *format)) { + if (required) + return SPA_RESULT_NOT_FOUND; + skip = true; + } + collect: + if (suppress) + suppress = false; + else if (skip) + SPA_POD_PARSER_SKIP(*format, args); + else + SPA_POD_PARSER_COLLECT(pod, *format, args); + + spa_pod_iter_advance(it, current); + + required = true; + skip = false; + read_pod: + pod = current = spa_pod_iter_current(it); + break; + } + format++; + } + return 0; +} + +static inline int spa_pod_parser_get(struct spa_pod_parser *parser, + const char *format, ...) +{ + int res; + va_list args; + + va_start(args, format); + res = spa_pod_parser_getv(parser, format, args); + va_end(args); + + return res; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __SPA_POD_PARSER_H__ */ diff --git a/spa/include/spa/pod-utils.h b/spa/include/spa/pod-utils.h index d7e2202c5..56442c422 100644 --- a/spa/include/spa/pod-utils.h +++ b/spa/include/spa/pod-utils.h @@ -92,154 +92,19 @@ static inline struct spa_pod_prop *spa_pod_object_find_prop(const struct spa_pod return spa_pod_contents_find_prop(&obj->pod, sizeof(struct spa_pod_object), key); } -#define SPA_POD_COLLECT(pod,type,args,error) \ -do { \ - if (type == SPA_POD_TYPE_POD) { \ - *(va_arg(args, struct spa_pod **)) = pod; \ - } else if ((pod)->type == SPA_POD_TYPE_NONE) { \ - switch (type) { \ - case -SPA_POD_TYPE_ARRAY: \ - case -SPA_POD_TYPE_STRUCT: \ - case -SPA_POD_TYPE_OBJECT: \ - case -SPA_POD_TYPE_PROP: \ - *(va_arg(args, struct spa_pod **)) = NULL; \ - break; \ - default: \ - goto error; \ - } \ - } else if ((pod)->type == type || (pod)->type == -type) { \ - switch (type) { \ - case SPA_POD_TYPE_BOOL: \ - case SPA_POD_TYPE_ID: \ - case SPA_POD_TYPE_INT: \ - *(va_arg(args, int32_t*)) = SPA_POD_VALUE(struct spa_pod_int, pod); \ - break; \ - case SPA_POD_TYPE_LONG: \ - *(va_arg(args, int64_t*)) = SPA_POD_VALUE(struct spa_pod_long, pod); \ - break; \ - case SPA_POD_TYPE_FLOAT: \ - *(va_arg(args, float*)) = SPA_POD_VALUE(struct spa_pod_float, pod); \ - break; \ - case SPA_POD_TYPE_DOUBLE: \ - *(va_arg(args, double*)) = SPA_POD_VALUE(struct spa_pod_double, pod); \ - break; \ - case SPA_POD_TYPE_STRING: \ - *(va_arg(args, char **)) = SPA_POD_CONTENTS(struct spa_pod_string, pod); \ - break; \ - case -SPA_POD_TYPE_STRING: \ - { \ - char *dest = va_arg(args, char *); \ - uint32_t maxlen = va_arg(args, uint32_t); \ - strncpy(dest, SPA_POD_CONTENTS(struct spa_pod_string, pod), maxlen-1); \ - break; \ - } \ - case SPA_POD_TYPE_BYTES: \ - *(va_arg(args, void **)) = SPA_POD_CONTENTS(struct spa_pod_bytes, pod); \ - *(va_arg(args, uint32_t *)) = SPA_POD_BODY_SIZE(pod); \ - break; \ - case SPA_POD_TYPE_POINTER: \ - { \ - struct spa_pod_pointer_body *b = SPA_POD_BODY(pod); \ - *(va_arg(args, void **)) = b->value; \ - break; \ - } \ - case SPA_POD_TYPE_RECTANGLE: \ - *(va_arg(args, struct spa_rectangle *)) = \ - SPA_POD_VALUE(struct spa_pod_rectangle, pod); \ - break; \ - case SPA_POD_TYPE_FRACTION: \ - *(va_arg(args, struct spa_fraction *)) = \ - SPA_POD_VALUE(struct spa_pod_fraction, pod); \ - break; \ - case SPA_POD_TYPE_BITMASK: \ - *(va_arg(args, uint32_t **)) = SPA_POD_CONTENTS(struct spa_pod, pod); \ - break; \ - case SPA_POD_TYPE_ARRAY: \ - case SPA_POD_TYPE_STRUCT: \ - case SPA_POD_TYPE_OBJECT: \ - case SPA_POD_TYPE_PROP: \ - case -SPA_POD_TYPE_ARRAY: \ - case -SPA_POD_TYPE_STRUCT: \ - case -SPA_POD_TYPE_OBJECT: \ - case -SPA_POD_TYPE_PROP: \ - *(va_arg(args, struct spa_pod **)) = pod; \ - break; \ - default: \ - goto error; \ - } \ - } else \ - goto error; \ -} while (false); - -#define SPA_POD_COLLECT_SKIP(type,args) \ - switch (type) { \ - case SPA_POD_TYPE_BYTES: \ - case SPA_POD_TYPE_POINTER: \ - va_arg (args, void*); \ - /* fallthrough */ \ - case SPA_POD_TYPE_BOOL: \ - case SPA_POD_TYPE_ID: \ - case SPA_POD_TYPE_INT: \ - case SPA_POD_TYPE_LONG: \ - case SPA_POD_TYPE_FLOAT: \ - case SPA_POD_TYPE_DOUBLE: \ - case SPA_POD_TYPE_STRING: \ - case -SPA_POD_TYPE_STRING: \ - case SPA_POD_TYPE_RECTANGLE: \ - case SPA_POD_TYPE_FRACTION: \ - case SPA_POD_TYPE_BITMASK: \ - case SPA_POD_TYPE_ARRAY: \ - case SPA_POD_TYPE_STRUCT: \ - case SPA_POD_TYPE_OBJECT: \ - case SPA_POD_TYPE_PROP: \ - case SPA_POD_TYPE_POD: \ - case -SPA_POD_TYPE_ARRAY: \ - case -SPA_POD_TYPE_STRUCT: \ - case -SPA_POD_TYPE_OBJECT: \ - case -SPA_POD_TYPE_PROP: \ - va_arg(args, void*); \ - default: \ - break; \ - } - -static inline uint32_t -spa_pod_contents_queryv(const struct spa_pod *pod, uint32_t offset, uint32_t key, va_list args) +static inline struct spa_pod_prop *spa_pod_struct_find_prop(const struct spa_pod_struct *obj, + uint32_t key) { - uint32_t count = 0; - - while (key) { - uint32_t type; - struct spa_pod_prop *prop = spa_pod_contents_find_prop(pod, offset, key); - - type = va_arg(args, uint32_t); - - if (prop && prop->body.key == key && !(prop->body.flags & SPA_POD_PROP_FLAG_UNSET)) { - SPA_POD_COLLECT(&prop->body.value, type, args, next); - count++; - } else { - SPA_POD_COLLECT_SKIP(type, args); - } - next: - key = va_arg(args, uint32_t); - } - return count; + return spa_pod_contents_find_prop(&obj->pod, sizeof(struct spa_pod_struct), key); } -static inline uint32_t -spa_pod_contents_query(const struct spa_pod *pod, uint32_t offset, uint32_t key, ...) -{ - va_list args; - uint32_t count; - - va_start(args, key); - count = spa_pod_contents_queryv(pod, offset, key, args); - va_end(args); - - return count; -} - -#define spa_pod_object_query(object,key, ...) \ - spa_pod_contents_query(&(object)->pod, sizeof(struct spa_pod_object), key, __VA_ARGS__) +#define spa_pod_object_parse(object,...) \ +({ \ + struct spa_pod_parser __p; \ + const struct spa_pod_object *__obj = object; \ + spa_pod_parser_pod(&__p, &__obj->pod); \ + spa_pod_parser_get(&__p, "<", ##__VA_ARGS__, NULL); \ +}) #ifdef __cplusplus } /* extern "C" */ diff --git a/spa/include/spa/pod.h b/spa/include/spa/pod.h index 10883e1ae..04039a1c2 100644 --- a/spa/include/spa/pod.h +++ b/spa/include/spa/pod.h @@ -43,23 +43,33 @@ extern "C" { enum spa_pod_type { SPA_POD_TYPE_INVALID = 0, SPA_POD_TYPE_NONE = 1, + SPA_POD_TYPE_BOOL, + SPA_POD_TYPE_ID, SPA_POD_TYPE_INT, SPA_POD_TYPE_LONG, SPA_POD_TYPE_FLOAT, SPA_POD_TYPE_DOUBLE, + SPA_POD_TYPE_STRING, SPA_POD_TYPE_BYTES, - SPA_POD_TYPE_POINTER, + SPA_POD_TYPE_RECTANGLE, SPA_POD_TYPE_FRACTION, - SPA_POD_TYPE_BITMASK, + SPA_POD_TYPE_BITMAP, + SPA_POD_TYPE_ARRAY, SPA_POD_TYPE_STRUCT, SPA_POD_TYPE_OBJECT, + + SPA_POD_TYPE_POINTER, + SPA_POD_TYPE_FD, + SPA_POD_TYPE_PROP, SPA_POD_TYPE_POD, + + SPA_POD_TYPE_CUSTOM_START = 64, }; struct spa_pod { @@ -67,12 +77,6 @@ struct spa_pod { uint32_t type; /* one of spa_pod_type */ }; -struct spa_pod_int { - struct spa_pod pod; - int32_t value; - int32_t __padding; -}; - struct spa_pod_bool { struct spa_pod pod; int32_t value; @@ -85,6 +89,12 @@ struct spa_pod_id { int32_t __padding; }; +struct spa_pod_int { + struct spa_pod pod; + int32_t value; + int32_t __padding; +}; + struct spa_pod_long { struct spa_pod pod; int64_t value; @@ -110,16 +120,6 @@ struct spa_pod_bytes { /* value here */ }; -struct spa_pod_pointer_body { - uint32_t type; - void *value; -}; - -struct spa_pod_pointer { - struct spa_pod pod; - struct spa_pod_pointer_body body; -}; - struct spa_pod_rectangle { struct spa_pod pod; struct spa_rectangle value; @@ -150,6 +150,32 @@ struct spa_pod_struct { /* one or more spa_pod follow */ }; +struct spa_pod_object_body { + uint32_t id; + uint32_t type; + /* contents follow, series of spa_pod */ +}; + +struct spa_pod_object { + struct spa_pod pod; + struct spa_pod_object_body body; +}; + +struct spa_pod_pointer_body { + uint32_t type; + void *value; +}; + +struct spa_pod_pointer { + struct spa_pod pod; + struct spa_pod_pointer_body body; +}; + +struct spa_pod_fd { + struct spa_pod pod; + int value; +}; + struct spa_pod_prop_body { uint32_t key; #define SPA_POD_PROP_RANGE_NONE 0 @@ -173,17 +199,6 @@ struct spa_pod_prop { struct spa_pod_prop_body body; }; -struct spa_pod_object_body { - uint32_t id; - uint32_t type; - /* contents follow, series of spa_pod_prop */ -}; - -struct spa_pod_object { - struct spa_pod pod; - struct spa_pod_object_body body; -}; - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/spa/include/spa/props.h b/spa/include/spa/props.h index f961e9d96..c068663b6 100644 --- a/spa/include/spa/props.h +++ b/spa/include/spa/props.h @@ -26,6 +26,7 @@ extern "C" { #include #include +#include struct spa_props { struct spa_pod_object object; @@ -58,20 +59,16 @@ spa_pod_builder_push_props(struct spa_pod_builder *builder, return spa_pod_builder_push_object(builder, frame, 0, props_type); } -#define spa_pod_builder_props(b,f,props_type,...) \ - spa_pod_builder_object(b, f, 0, props_type,__VA_ARGS__) +#define spa_pod_builder_props(b,props_type,...) \ + spa_pod_builder_object(b, 0, props_type,##__VA_ARGS__) -static inline uint32_t spa_props_query(const struct spa_props *props, uint32_t key, ...) -{ - uint32_t count; - va_list args; - - va_start(args, key); - count = spa_pod_contents_queryv(&props->object.pod, sizeof(struct spa_props), key, args); - va_end(args); - - return count; -} +#define spa_props_parse(props,...) \ +({ \ + struct spa_pod_parser __p; \ + const struct spa_props *__props = props; \ + spa_pod_parser_pod(&__p, &__props->object.pod); \ + spa_pod_parser_get(&__p, "<", ##__VA_ARGS__, NULL); \ +}) #ifdef __cplusplus } /* extern "C" */ diff --git a/spa/include/spa/video/format-utils.h b/spa/include/spa/video/format-utils.h index 831492293..e0f51f596 100644 --- a/spa/include/spa/video/format-utils.h +++ b/spa/include/spa/video/format-utils.h @@ -74,50 +74,53 @@ spa_type_format_video_map(struct spa_type_map *map, struct spa_type_format_video } } -static inline bool +static inline int spa_format_video_raw_parse(const struct spa_format *format, struct spa_video_info_raw *info, struct spa_type_format_video *type) { - spa_format_query(format, - type->format, SPA_POD_TYPE_ID, &info->format, - type->size, SPA_POD_TYPE_RECTANGLE, &info->size, - type->framerate, SPA_POD_TYPE_FRACTION, &info->framerate, - type->max_framerate, SPA_POD_TYPE_FRACTION, &info->max_framerate, - type->views, SPA_POD_TYPE_INT, &info->views, - type->interlace_mode, SPA_POD_TYPE_INT, &info->interlace_mode, - type->pixel_aspect_ratio, SPA_POD_TYPE_FRACTION, &info->pixel_aspect_ratio, - type->multiview_mode, SPA_POD_TYPE_INT, &info->multiview_mode, - type->multiview_flags, SPA_POD_TYPE_INT, &info->multiview_flags, - type->chroma_site, SPA_POD_TYPE_INT, &info->chroma_site, - type->color_range, SPA_POD_TYPE_INT, &info->color_range, - type->color_matrix, SPA_POD_TYPE_INT, &info->color_matrix, - type->transfer_function, SPA_POD_TYPE_INT, &info->transfer_function, - type->color_primaries, SPA_POD_TYPE_INT, &info->color_primaries, 0); - return true; + struct spa_pod_parser prs; + spa_pod_parser_pod(&prs, &format->pod); + return spa_pod_parser_get(&prs, + ":",type->format, "I", &info->format, + ":",type->size, "R", &info->size, + ":",type->framerate, "F", &info->framerate, + ":",type->max_framerate, "?F", &info->max_framerate, + ":",type->views, "?i", &info->views, + ":",type->interlace_mode, "?i", &info->interlace_mode, + ":",type->pixel_aspect_ratio, "?F", &info->pixel_aspect_ratio, + ":",type->multiview_mode, "?i", &info->multiview_mode, + ":",type->multiview_flags, "?i", &info->multiview_flags, + ":",type->chroma_site, "?i", &info->chroma_site, + ":",type->color_range, "?i", &info->color_range, + ":",type->color_matrix, "?i", &info->color_matrix, + ":",type->transfer_function, "?i", &info->transfer_function, + ":",type->color_primaries, "?i", &info->color_primaries, NULL); } -static inline bool +static inline int spa_format_video_h264_parse(const struct spa_format *format, struct spa_video_info_h264 *info, struct spa_type_format_video *type) { - spa_format_query(format, - type->size, SPA_POD_TYPE_RECTANGLE, &info->size, - type->framerate, SPA_POD_TYPE_FRACTION, &info->framerate, - type->max_framerate, SPA_POD_TYPE_FRACTION, &info->max_framerate, - type->stream_format, SPA_POD_TYPE_INT, &info->stream_format, - type->alignment, SPA_POD_TYPE_INT, &info->alignment, 0); - return true; + struct spa_pod_parser prs; + spa_pod_parser_pod(&prs, &format->pod); + return spa_pod_parser_get(&prs, + ":",type->size, "?R", &info->size, + ":",type->framerate, "?F", &info->framerate, + ":",type->max_framerate, "?F", &info->max_framerate, + ":",type->stream_format, "?i", &info->stream_format, + ":",type->alignment, "?i", &info->alignment, NULL); } -static inline bool +static inline int spa_format_video_mjpg_parse(const struct spa_format *format, struct spa_video_info_mjpg *info, struct spa_type_format_video *type) { - spa_format_query(format, - type->size, SPA_POD_TYPE_RECTANGLE, &info->size, - type->framerate, SPA_POD_TYPE_FRACTION, &info->framerate, - type->max_framerate, SPA_POD_TYPE_FRACTION, &info->max_framerate, 0); - return true; + struct spa_pod_parser prs; + spa_pod_parser_pod(&prs, &format->pod); + return spa_pod_parser_get(&prs, + ":",type->size, "?R", &info->size, + ":",type->framerate, "?F", &info->framerate, + ":",type->max_framerate, "?F", &info->max_framerate, NULL); } #ifdef __cplusplus diff --git a/spa/lib/debug.c b/spa/lib/debug.c index 654182648..cc137c36f 100644 --- a/spa/lib/debug.c +++ b/spa/lib/debug.c @@ -151,25 +151,26 @@ int spa_debug_param(const struct spa_param *param) } static const char *pod_type_names[] = { - "invalid", - "none", - "bool", - "id", - "int", - "long", - "float", - "double", - "string", - "bytes", - "pointer", - "rectangle", - "fraction", - "bitmask", - "array", - "struct", - "object", - "prop", - "pod" + [SPA_POD_TYPE_INVALID] = "invalid", + [SPA_POD_TYPE_NONE] = "none", + [SPA_POD_TYPE_BOOL] = "bool", + [SPA_POD_TYPE_ID] = "id", + [SPA_POD_TYPE_INT] = "int", + [SPA_POD_TYPE_LONG] = "long", + [SPA_POD_TYPE_FLOAT] = "float", + [SPA_POD_TYPE_DOUBLE] = "double", + [SPA_POD_TYPE_STRING] = "string", + [SPA_POD_TYPE_BYTES] = "bytes", + [SPA_POD_TYPE_RECTANGLE] = "rectangle", + [SPA_POD_TYPE_FRACTION] = "fraction", + [SPA_POD_TYPE_BITMAP] = "bitmap", + [SPA_POD_TYPE_ARRAY] = "array", + [SPA_POD_TYPE_STRUCT] = "struct", + [SPA_POD_TYPE_OBJECT] = "object", + [SPA_POD_TYPE_POINTER] = "pointer", + [SPA_POD_TYPE_FD] = "fd", + [SPA_POD_TYPE_PROP] = "prop", + [SPA_POD_TYPE_POD] = "pod" }; static void @@ -198,11 +199,14 @@ print_pod_value(uint32_t size, uint32_t type, void *body, int prefix) case SPA_POD_TYPE_STRING: printf("%-*sString \"%s\"\n", prefix, "", (char *) body); break; + case SPA_POD_TYPE_FD: + printf("%-*sFd %d\n", prefix, "", *(int *) body); + break; case SPA_POD_TYPE_POINTER: { struct spa_pod_pointer_body *b = body; printf("%-*sPointer %s %p\n", prefix, "", - spa_type_map_get_type(map, b->type), b->value); + map ? spa_type_map_get_type(map, b->type) : "*no map*", b->value); break; } case SPA_POD_TYPE_RECTANGLE: @@ -217,8 +221,8 @@ print_pod_value(uint32_t size, uint32_t type, void *body, int prefix) printf("%-*sFraction %d/%d\n", prefix, "", f->num, f->denom); break; } - case SPA_POD_TYPE_BITMASK: - printf("%-*sBitmask\n", prefix, ""); + case SPA_POD_TYPE_BITMAP: + printf("%-*sBitmap\n", prefix, ""); break; case SPA_POD_TYPE_ARRAY: { @@ -245,7 +249,7 @@ print_pod_value(uint32_t size, uint32_t type, void *body, int prefix) struct spa_pod *p; printf("%-*sObject: size %d, id %d, type %s\n", prefix, "", size, b->id, - spa_type_map_get_type(map, b->type)); + map ? spa_type_map_get_type(map, b->type) : "*no map*"); SPA_POD_OBJECT_BODY_FOREACH(b, size, p) print_pod_value(p->size, p->type, SPA_POD_BODY(p), prefix + 2); break; @@ -257,7 +261,7 @@ print_pod_value(uint32_t size, uint32_t type, void *body, int prefix) int i; printf("%-*sProp: key %s, flags %d\n", prefix, "", - spa_type_map_get_type(map, b->key), b->flags); + map ? spa_type_map_get_type(map, b->key) : "*no map*", b->flags); if (b->flags & SPA_POD_PROP_FLAG_UNSET) printf("%-*sUnset (Default):\n", prefix + 2, ""); else @@ -303,7 +307,7 @@ print_format_value(uint32_t size, uint32_t type, void *body) break; case SPA_POD_TYPE_ID: { - const char *str = spa_type_map_get_type(map, *(int32_t *) body); + const char *str = map ? spa_type_map_get_type(map, *(int32_t *) body) : NULL; if (str) { const char *h = rindex(str, ':'); if (h) @@ -341,8 +345,8 @@ print_format_value(uint32_t size, uint32_t type, void *body) fprintf(stderr, "%" PRIu32 "/%" PRIu32, f->num, f->denom); break; } - case SPA_POD_TYPE_BITMASK: - fprintf(stderr, "Bitmask"); + case SPA_POD_TYPE_BITMAP: + fprintf(stderr, "Bitmap"); break; case SPA_POD_TYPE_BYTES: fprintf(stderr, "Bytes"); diff --git a/spa/plugins/alsa/alsa-monitor.c b/spa/plugins/alsa/alsa-monitor.c index b86d3bc8f..2b7250a6b 100644 --- a/spa/plugins/alsa/alsa-monitor.c +++ b/spa/plugins/alsa/alsa-monitor.c @@ -112,8 +112,8 @@ fill_item(struct impl *this, snd_ctl_card_info_t *card_info, snd_pcm_info_t *dev const char *str, *name, *klass = NULL; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(this->item_buffer, sizeof(this->item_buffer)); const struct spa_handle_factory *factory = NULL; - struct spa_pod_frame f[3]; char card_name[64]; + struct type *t = &this->type; switch (snd_pcm_info_get_stream(dev_info)) { case SND_PCM_STREAM_PLAYBACK: @@ -141,62 +141,56 @@ fill_item(struct impl *this, snd_ctl_card_info_t *card_info, snd_pcm_info_t *dev snprintf(card_name, 64, "%s,%d", this->card_name, snd_pcm_info_get_device(dev_info)); spa_pod_builder_add(&b, - SPA_POD_TYPE_OBJECT, &f[0], 0, this->type.monitor.MonitorItem, - SPA_POD_PROP(&f[1], this->type.monitor.id, 0, SPA_POD_TYPE_STRING, 1, - name), - SPA_POD_PROP(&f[1], this->type.monitor.flags, 0, SPA_POD_TYPE_INT, 1, - 0), - SPA_POD_PROP(&f[1], this->type.monitor.state, 0, SPA_POD_TYPE_INT, 1, - SPA_MONITOR_ITEM_STATE_AVAILABLE), - SPA_POD_PROP(&f[1], this->type.monitor.name, 0, SPA_POD_TYPE_STRING, 1, - name), - SPA_POD_PROP(&f[1], this->type.monitor.klass, 0, SPA_POD_TYPE_STRING, 1, - klass), - SPA_POD_PROP(&f[1], this->type.monitor.factory, 0, SPA_POD_TYPE_POINTER, 1, - this->type.handle_factory, factory), 0); + "<", 0, t->monitor.MonitorItem, + ":", t->monitor.id, "s", name, + ":", t->monitor.flags, "i", 0, + ":", t->monitor.state, "i", SPA_MONITOR_ITEM_STATE_AVAILABLE, + ":", t->monitor.name, "s", name, + ":", t->monitor.klass, "s", klass, + ":", t->monitor.factory, "p", t->handle_factory, factory, NULL); spa_pod_builder_add(&b, - SPA_POD_TYPE_PROP, &f[1], this->type.monitor.info, 0, - SPA_POD_TYPE_STRUCT, 1, &f[2], 0); + ":", t->monitor.info, "[", NULL); spa_pod_builder_add(&b, - SPA_POD_TYPE_STRING, "alsa.card", SPA_POD_TYPE_STRING, card_name, - SPA_POD_TYPE_STRING, "alsa.card.id", SPA_POD_TYPE_STRING, snd_ctl_card_info_get_id(card_info), - SPA_POD_TYPE_STRING, "alsa.card.components", SPA_POD_TYPE_STRING, snd_ctl_card_info_get_components(card_info), - SPA_POD_TYPE_STRING, "alsa.card.driver", SPA_POD_TYPE_STRING, snd_ctl_card_info_get_driver(card_info), - SPA_POD_TYPE_STRING, "alsa.card.name", SPA_POD_TYPE_STRING, snd_ctl_card_info_get_name(card_info), - SPA_POD_TYPE_STRING, "alsa.card.longname", SPA_POD_TYPE_STRING, snd_ctl_card_info_get_longname(card_info), - SPA_POD_TYPE_STRING, "alsa.card.mixername", SPA_POD_TYPE_STRING, snd_ctl_card_info_get_mixername(card_info), - SPA_POD_TYPE_STRING, "udev-probed", SPA_POD_TYPE_STRING, "1", - SPA_POD_TYPE_STRING, "device.api", SPA_POD_TYPE_STRING, "alsa", - SPA_POD_TYPE_STRING, "alsa.pcm.id", SPA_POD_TYPE_STRING, snd_pcm_info_get_id(dev_info), - SPA_POD_TYPE_STRING, "alsa.pcm.name", SPA_POD_TYPE_STRING, snd_pcm_info_get_name(dev_info), - SPA_POD_TYPE_STRING, "alsa.pcm.subname", SPA_POD_TYPE_STRING, snd_pcm_info_get_subdevice_name(dev_info), 0); + "s", "alsa.card", "s", card_name, + "s", "alsa.card.id", "s", snd_ctl_card_info_get_id(card_info), + "s", "alsa.card.components", "s", snd_ctl_card_info_get_components(card_info), + "s", "alsa.card.driver", "s", snd_ctl_card_info_get_driver(card_info), + "s", "alsa.card.name", "s", snd_ctl_card_info_get_name(card_info), + "s", "alsa.card.longname", "s", snd_ctl_card_info_get_longname(card_info), + "s", "alsa.card.mixername", "s", snd_ctl_card_info_get_mixername(card_info), + "s", "udev-probed", "s", "1", + "s", "device.api", "s", "alsa", + "s", "alsa.pcm.id", "s", snd_pcm_info_get_id(dev_info), + "s", "alsa.pcm.name", "s", snd_pcm_info_get_name(dev_info), + "s", "alsa.pcm.subname", "s", snd_pcm_info_get_subdevice_name(dev_info), + NULL); if ((str = udev_device_get_property_value(dev, "SOUND_CLASS")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.class", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.class", "s", str, NULL); } str = udev_device_get_property_value(dev, "ID_PATH"); if (!(str && *str)) str = udev_device_get_syspath(dev); if (str && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.bus_path", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.bus_path", "s", str, 0); } if ((str = udev_device_get_syspath(dev)) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "sysfs.path", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "sysfs.path", "s", str, 0); } if ((str = udev_device_get_property_value(dev, "ID_ID")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "udev.id", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "udev.id", "s", str, 0); } if ((str = udev_device_get_property_value(dev, "ID_BUS")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.bus", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.bus", "s", str, 0); } if ((str = udev_device_get_property_value(dev, "SUBSYSTEM")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.subsystem", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.subsystem", "s", str, 0); } if ((str = udev_device_get_property_value(dev, "ID_VENDOR_ID")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.vendor.id", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.vendor.id", "s", str, 0); } str = udev_device_get_property_value(dev, "ID_VENDOR_FROM_DATABASE"); if (!(str && *str)) { @@ -206,26 +200,20 @@ fill_item(struct impl *this, snd_ctl_card_info_t *card_info, snd_pcm_info_t *dev } } if (str && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.vendor.name", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.vendor.name", "s", str, 0); } if ((str = udev_device_get_property_value(dev, "ID_MODEL_ID")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.product.id", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.product.id", "s", str, 0); } - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.product.name", SPA_POD_TYPE_STRING, name, 0); + spa_pod_builder_add(&b, "s", "device.product.name", "s", name, 0); if ((str = udev_device_get_property_value(dev, "ID_SERIAL")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.serial", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.serial", "s", str, 0); } if ((str = udev_device_get_property_value(dev, "SOUND_FORM_FACTOR")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.form_factor", SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.form_factor", "s", str, 0); } - - spa_pod_builder_add(&b, - -SPA_POD_TYPE_STRUCT, &f[2], - -SPA_POD_TYPE_PROP, &f[1], - -SPA_POD_TYPE_OBJECT, &f[0], 0); - - this->item = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_monitor_item); + this->item = spa_pod_builder_add(&b, "]>", NULL); return 0; } @@ -342,14 +330,12 @@ static void impl_on_fd_events(struct spa_source *source) while (true) { uint8_t buffer[4096]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); - struct spa_pod_frame f[1]; struct spa_event *event; if (get_next_device(this, dev) < 0) break; - spa_pod_builder_object(&b, &f[0], 0, type, SPA_POD_TYPE_POD, this->item); - event = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_event); + event = spa_pod_builder_object(&b, 0, type, "P", this->item); this->callbacks->event(this->callbacks_data, event); } close_card(this); diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c index 8dbe136d0..9d2a338ae 100644 --- a/spa/plugins/alsa/alsa-sink.c +++ b/spa/plugins/alsa/alsa-sink.c @@ -44,7 +44,6 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props) { struct state *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS); @@ -53,17 +52,13 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props) spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer)); - spa_pod_builder_props(&b, &f[0], this->type.props, - PROP(&f[1], this->type.prop_device, -SPA_POD_TYPE_STRING, - this->props.device, sizeof(this->props.device)), - PROP(&f[1], this->type.prop_device_name, -SPA_POD_TYPE_STRING, - this->props.device_name, sizeof(this->props.device_name)), - PROP(&f[1], this->type.prop_card_name, -SPA_POD_TYPE_STRING, - this->props.card_name, sizeof(this->props.card_name)), - PROP_MM(&f[1], this->type.prop_min_latency, SPA_POD_TYPE_INT, - this->props.min_latency, - 1, INT32_MAX)); - *props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + *props = spa_pod_builder_props(&b, + this->type.props, + ":", this->type.prop_device, "S", this->props.device, sizeof(this->props.device), + ":", this->type.prop_device_name, "S", this->props.device_name, sizeof(this->props.device_name), + ":", this->type.prop_card_name, "S", this->props.card_name, sizeof(this->props.card_name), + ":", this->type.prop_min_latency, "ir", this->props.min_latency, + 2, 1, INT32_MAX); return SPA_RESULT_OK; } @@ -80,10 +75,9 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr reset_props(&this->props); return SPA_RESULT_OK; } else { - spa_props_query(props, - this->type.prop_device, -SPA_POD_TYPE_STRING, - this->props.device, sizeof(this->props.device), - this->type.prop_min_latency, SPA_POD_TYPE_INT, &this->props.min_latency, 0); + spa_props_parse(props, + ":", this->type.prop_device, "?S", this->props.device, sizeof(this->props.device), + ":", this->type.prop_min_latency, "?i", &this->props.min_latency, NULL); } return SPA_RESULT_OK; } @@ -273,7 +267,7 @@ impl_node_port_set_format(struct spa_node *node, info.media_subtype != this->type.media_subtype.raw) return SPA_RESULT_INVALID_MEDIA_TYPE; - if (!spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio)) + if (spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio) < 0) return SPA_RESULT_INVALID_MEDIA_TYPE; if (spa_alsa_set_format(this, &info, flags) < 0) @@ -299,12 +293,13 @@ impl_node_port_get_format(struct spa_node *node, { struct state *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct state, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -312,16 +307,12 @@ impl_node_port_get_format(struct spa_node *node, return SPA_RESULT_NO_FORMAT; spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer)); - spa_pod_builder_format(&b, &f[0], this->type.format, - this->type.media_type.audio, - this->type.media_subtype.raw, - PROP(&f[1], this->type.format_audio.format, SPA_POD_TYPE_ID, - this->current_format.info.raw.format), - PROP(&f[1], this->type.format_audio.rate, SPA_POD_TYPE_INT, - this->current_format.info.raw.rate), - PROP(&f[1], this->type.format_audio.channels, SPA_POD_TYPE_INT, - this->current_format.info.raw.channels)); - *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = spa_pod_builder_format(&b, + t->format, + t->media_type.audio, t->media_subtype.raw, + ":", t->format_audio.format, "I", this->current_format.info.raw.format, + ":", t->format_audio.rate, "i", this->current_format.info.raw.rate, + ":", t->format_audio.channels, "i", this->current_format.info.raw.channels); return SPA_RESULT_OK; } @@ -354,12 +345,13 @@ impl_node_port_enum_params(struct spa_node *node, struct state *this; struct spa_pod_builder b = { NULL }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct state, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -367,48 +359,40 @@ impl_node_port_enum_params(struct spa_node *node, switch (index) { case 0: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_buffers.Buffers, - PROP_U_MM(&f[1], this->type.param_alloc_buffers.size, SPA_POD_TYPE_INT, - this->props.min_latency * this->frame_size, - this->props.min_latency * this->frame_size, INT32_MAX), - PROP(&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, - 0), - PROP_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 2, 2, 32), - PROP(&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, - 16)); + *param = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "iru", this->props.min_latency * this->frame_size, + 2, this->props.min_latency * this->frame_size, + INT32_MAX, + ":", t->param_alloc_buffers.stride, "i", 0, + ":", t->param_alloc_buffers.buffers, "ir", 2, + 2, 2, 32, + ":", t->param_alloc_buffers.align, "i", 16); break; case 1: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_meta_enable.MetaEnable, - PROP(&f[1], this->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - this->type.meta.Header), - PROP(&f[1], this->type.param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); + *param = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); break; case 2: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_meta_enable.MetaEnable, - PROP(&f[1], this->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - this->type.meta.Ringbuffer), - PROP(&f[1], this->type.param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_ringbuffer)), - PROP(&f[1], this->type.param_alloc_meta_enable.ringbufferSize, SPA_POD_TYPE_INT, - this->period_frames * this->frame_size * 32), - PROP(&f[1], this->type.param_alloc_meta_enable.ringbufferStride, SPA_POD_TYPE_INT, - 0), - PROP(&f[1], this->type.param_alloc_meta_enable.ringbufferBlocks, SPA_POD_TYPE_INT, - 1), - PROP(&f[1], this->type.param_alloc_meta_enable.ringbufferAlign, SPA_POD_TYPE_INT, - 16)); + *param = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_ringbuffer), + ":", t->param_alloc_meta_enable.ringbufferSize, "i", this->period_frames * + this->frame_size * 32, + ":", t->param_alloc_meta_enable.ringbufferStride, "i", 0, + ":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1, + ":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16); break; default: return SPA_RESULT_NOT_IMPLEMENTED; } - *param = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); - return SPA_RESULT_OK; } diff --git a/spa/plugins/alsa/alsa-source.c b/spa/plugins/alsa/alsa-source.c index bc80f58ab..e401c7a1f 100644 --- a/spa/plugins/alsa/alsa-source.c +++ b/spa/plugins/alsa/alsa-source.c @@ -45,7 +45,6 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props) { struct state *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS); @@ -54,17 +53,13 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props) spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer)); - spa_pod_builder_props(&b, &f[0], this->type.props, - PROP(&f[1], this->type.prop_device, -SPA_POD_TYPE_STRING, - this->props.device, sizeof(this->props.device)), - PROP(&f[1], this->type.prop_device_name, -SPA_POD_TYPE_STRING, - this->props.device_name, sizeof(this->props.device_name)), - PROP(&f[1], this->type. prop_card_name, -SPA_POD_TYPE_STRING, - this->props.card_name, sizeof(this->props.card_name)), - PROP_MM(&f[1], this->type.prop_min_latency, SPA_POD_TYPE_INT, - this->props.min_latency, 1, INT32_MAX)); - - *props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + *props = spa_pod_builder_props(&b, + this->type.props, + ":", this->type.prop_device, "S", this->props.device, sizeof(this->props.device), + ":", this->type.prop_device_name, "S", this->props.device_name, sizeof(this->props.device_name), + ":", this->type.prop_card_name, "S", this->props.card_name, sizeof(this->props.card_name), + ":", this->type.prop_min_latency, "ir", this->props.min_latency, + 2, 1, INT32_MAX); return SPA_RESULT_OK; } @@ -81,10 +76,9 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr reset_props(&this->props); return SPA_RESULT_OK; } else { - spa_props_query(props, - this->type.prop_device, -SPA_POD_TYPE_STRING, - this->props.device, sizeof(this->props.device), - this->type.prop_min_latency, SPA_POD_TYPE_INT, &this->props.min_latency, 0); + spa_props_parse(props, + ":", this->type.prop_device, "?S", this->props.device, sizeof(this->props.device), + ":", this->type.prop_min_latency, "?i", &this->props.min_latency, NULL); } return SPA_RESULT_OK; @@ -300,7 +294,7 @@ impl_node_port_set_format(struct spa_node *node, info.media_subtype != this->type.media_subtype.raw) return SPA_RESULT_INVALID_MEDIA_TYPE; - if (!spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio)) + if (spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio) < 0) return SPA_RESULT_INVALID_MEDIA_TYPE; if (spa_alsa_set_format(this, &info, flags) < 0) @@ -324,12 +318,13 @@ impl_node_port_get_format(struct spa_node *node, { struct state *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct state, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -337,16 +332,12 @@ impl_node_port_get_format(struct spa_node *node, return SPA_RESULT_NO_FORMAT; spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer)); - spa_pod_builder_format(&b, &f[0], this->type.format, - this->type.media_type.audio, - this->type.media_subtype.raw, - PROP(&f[1], this->type.format_audio.format, SPA_POD_TYPE_ID, - this->current_format.info.raw.format), - PROP(&f[1], this->type.format_audio.rate, SPA_POD_TYPE_INT, - this->current_format.info.raw.rate), - PROP(&f[1], this->type.format_audio.channels, SPA_POD_TYPE_INT, - this->current_format.info.raw.channels)); - *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = spa_pod_builder_format(&b, + t->format, + t->media_type.audio, t->media_subtype.raw, + ":", t->format_audio.format, "I", this->current_format.info.raw.format, + ":", t->format_audio.rate, "i", this->current_format.info.raw.rate, + ":", t->format_audio.channels, "i", this->current_format.info.raw.channels); return SPA_RESULT_OK; } @@ -375,12 +366,13 @@ impl_node_port_enum_params(struct spa_node *node, { struct state *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct state, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -388,32 +380,26 @@ impl_node_port_enum_params(struct spa_node *node, switch (index) { case 0: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_buffers.Buffers, - PROP(&f[1], this->type.param_alloc_buffers.size, SPA_POD_TYPE_INT - , this->props.min_latency * this->frame_size), - PROP(&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, - 0), - PROP_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 32, - 1, 32), - PROP(&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, - 16)); + *param = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "i", this->props.min_latency * this->frame_size, + ":", t->param_alloc_buffers.stride, "i", 0, + ":", t->param_alloc_buffers.buffers, "i", 2, + 2, 1, 32, + ":", t->param_alloc_buffers.align, "i", 16); break; case 1: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_meta_enable.MetaEnable, - PROP(&f[1], this->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - this->type.meta.Header), - PROP(&f[1], this->type.param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); + *param = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); break; default: return SPA_RESULT_NOT_IMPLEMENTED; } - *param = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); - return SPA_RESULT_OK; } diff --git a/spa/plugins/alsa/alsa-utils.h b/spa/plugins/alsa/alsa-utils.h index 162196c96..23e7e1143 100644 --- a/spa/plugins/alsa/alsa-utils.h +++ b/spa/plugins/alsa/alsa-utils.h @@ -161,19 +161,6 @@ struct state { int64_t last_monotonic; }; -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) -#define PROP_U_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) - int spa_alsa_enum_format(struct state *state, struct spa_format **format, const struct spa_format *filter, uint32_t index); diff --git a/spa/plugins/audiomixer/audiomixer.c b/spa/plugins/audiomixer/audiomixer.c index bd98ddefb..d8e87f05e 100644 --- a/spa/plugins/audiomixer/audiomixer.c +++ b/spa/plugins/audiomixer/audiomixer.c @@ -122,19 +122,6 @@ struct impl { #define GET_OUT_PORT(this,p) (&this->out_ports[p]) #define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p)) -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) -#define PROP_U_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) - static int impl_node_get_props(struct spa_node *node, struct spa_props **props) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -310,13 +297,14 @@ impl_node_port_enum_formats(struct spa_node *node, struct spa_format *fmt; uint8_t buffer[256]; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; uint32_t count, match; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -327,24 +315,20 @@ impl_node_port_enum_formats(struct spa_node *node, switch (count++) { case 0: - spa_pod_builder_format(&b, &f[0], this->type.format, - this->type.media_type.audio, - this->type.media_subtype.raw, - PROP_U_EN(&f[1], this->type.format_audio.format, SPA_POD_TYPE_ID, 3, - this->type.audio_format.S16, - this->type.audio_format.S16, - this->type.audio_format.F32), - PROP_U_MM(&f[1], this->type.format_audio.rate, SPA_POD_TYPE_INT, - 44100, - 1, INT32_MAX), - PROP_U_MM(&f[1], this->type.format_audio.channels, SPA_POD_TYPE_INT, - 2, - 1, INT32_MAX)); + fmt = spa_pod_builder_format(&b, + t->format, + t->media_type.audio, t->media_subtype.raw, + ":", t->format_audio.format, "Ieu", t->audio_format.S16, + 2, t->audio_format.S16, + t->audio_format.F32, + ":", t->format_audio.rate, "iru", 44100, + 2, 1, INT32_MAX, + ":", t->format_audio.channels, "iru", 2, + 2, 1, INT32_MAX); break; default: return SPA_RESULT_ENUM_END; } - fmt = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer)); @@ -375,10 +359,12 @@ impl_node_port_set_format(struct spa_node *node, { struct impl *this; struct port *port; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -396,11 +382,11 @@ impl_node_port_set_format(struct spa_node *node, SPA_FORMAT_MEDIA_SUBTYPE(format), }; - if (info.media_type != this->type.media_type.audio || - info.media_subtype != this->type.media_subtype.raw) + if (info.media_type != t->media_type.audio || + info.media_subtype != t->media_subtype.raw) return SPA_RESULT_INVALID_MEDIA_TYPE; - if (!spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio)) + if (spa_format_audio_raw_parse(format, &info.info.raw, &t->format_audio) < 0) return SPA_RESULT_INVALID_MEDIA_TYPE; if (this->have_format) { @@ -409,11 +395,11 @@ impl_node_port_set_format(struct spa_node *node, } else { this->have_format = true; this->format = info; - if (info.info.raw.format == this->type.audio_format.S16) { + if (info.info.raw.format == t->audio_format.S16) { this->copy = this->ops.copy[CONV_S16_S16]; this->add = this->ops.add[CONV_S16_S16]; } - else if (info.info.raw.format == this->type.audio_format.F32) { + else if (info.info.raw.format == t->audio_format.F32) { this->copy = this->ops.copy[CONV_F32_F32]; this->add = this->ops.add[CONV_F32_F32]; } @@ -437,12 +423,13 @@ impl_node_port_get_format(struct spa_node *node, struct impl *this; struct port *port; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -452,16 +439,12 @@ impl_node_port_get_format(struct spa_node *node, return SPA_RESULT_NO_FORMAT; spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer)); - spa_pod_builder_format(&b, &f[0], this->type.format, - this->type.media_type.audio, - this->type.media_subtype.raw, - PROP(&f[1], this->type.format_audio.format, SPA_POD_TYPE_ID, - this->format.info.raw.format), - PROP(&f[1], this->type.format_audio.rate, SPA_POD_TYPE_INT, - this->format.info.raw.rate), - PROP(&f[1], this->type.format_audio.channels, SPA_POD_TYPE_INT, - this->format.info.raw.channels)); - *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = spa_pod_builder_format(&b, + t->format, + t->media_type.audio, t->media_subtype.raw, + ":", t->format_audio.format, "I", this->format.info.raw.format, + ":", t->format_audio.rate, "i", this->format.info.raw.rate, + ":", t->format_audio.channels, "i", this->format.info.raw.channels); return SPA_RESULT_OK; } @@ -517,10 +500,12 @@ impl_node_port_use_buffers(struct spa_node *node, struct impl *this; struct port *port; uint32_t i; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -537,11 +522,11 @@ impl_node_port_use_buffers(struct spa_node *node, b = &port->buffers[i]; b->outbuf = buffers[i]; b->outstanding = direction == SPA_DIRECTION_INPUT ? true : false; - b->h = spa_buffer_find_meta(buffers[i], this->type.meta.Header); + b->h = spa_buffer_find_meta(buffers[i], t->meta.Header); - if (!((d[0].type == this->type.data.MemPtr || - d[0].type == this->type.data.MemFd || - d[0].type == this->type.data.DmaBuf) && d[0].data != NULL)) { + if (!((d[0].type == t->data.MemPtr || + d[0].type == t->data.MemFd || + d[0].type == t->data.DmaBuf) && d[0].data != NULL)) { spa_log_error(this->log, NAME " %p: invalid memory on buffer %p", this, buffers[i]); return SPA_RESULT_ERROR; diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index 2b05767b0..48f16fe84 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -169,46 +169,28 @@ static void reset_props(struct impl *this, struct props *props) props->volume = DEFAULT_VOLUME; } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) -#define PROP_U_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) - static int impl_node_get_props(struct spa_node *node, struct spa_props **props) { struct impl *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer)); - spa_pod_builder_props(&b, &f[0], this->type.props, - PROP(&f[1], this->type.prop_live, SPA_POD_TYPE_BOOL, - this->props.live), - PROP_EN(&f[1], this->type.prop_wave, SPA_POD_TYPE_ID, 3, - this->props.wave, - this->type.wave_sine, - this->type.wave_square), - PROP_MM(&f[1], this->type.prop_freq, SPA_POD_TYPE_DOUBLE, - this->props.freq, - 0.0, 50000000.0), - PROP_MM(&f[1], this->type.prop_volume, SPA_POD_TYPE_DOUBLE, - this->props.volume, - 0.0, 10.0)); - - *props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + *props = spa_pod_builder_props(&b, t->props, + ":", t->prop_live, "b", this->props.live, + ":", t->prop_wave, "Ie", this->props.wave, + 2, t->wave_sine, + t->wave_square, + ":", t->prop_freq, "dr", this->props.freq, + 2, 0.0, 50000000.0, + ":", t->prop_volume, "dr", this->props.volume, + 2, 0.0, 10.0); return SPA_RESULT_OK; } @@ -216,20 +198,22 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props) static int impl_node_set_props(struct spa_node *node, const struct spa_props *props) { struct impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; if (props == NULL) { reset_props(this, &this->props); } else { - spa_props_query(props, - this->type.prop_live, SPA_POD_TYPE_BOOL, &this->props.live, - this->type.prop_wave, SPA_POD_TYPE_ID, &this->props.wave, - this->type.prop_freq, SPA_POD_TYPE_DOUBLE, &this->props.freq, - this->type.prop_volume, SPA_POD_TYPE_DOUBLE, &this->props.volume, - 0); + spa_props_parse(props, + ":",t->prop_live, "?b", &this->props.live, + ":",t->prop_wave, "?I", &this->props.wave, + ":",t->prop_freq, "?d", &this->props.freq, + ":",t->prop_volume, "?d", &this->props.volume, + NULL); } if (this->props.live) @@ -483,13 +467,14 @@ impl_node_port_enum_formats(struct spa_node *node, struct spa_format *fmt; uint8_t buffer[256]; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; uint32_t count, match; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -500,26 +485,22 @@ impl_node_port_enum_formats(struct spa_node *node, switch (count++) { case 0: - spa_pod_builder_format(&b, &f[0], this->type.format, - this->type.media_type.audio, - this->type.media_subtype.raw, - PROP_U_EN(&f[1], this->type.format_audio.format, SPA_POD_TYPE_ID, 5, - this->type.audio_format.S16, - this->type.audio_format.S16, - this->type.audio_format.S32, - this->type.audio_format.F32, - this->type.audio_format.F64), - PROP_U_MM(&f[1], this->type.format_audio.rate, SPA_POD_TYPE_INT, - 44100, - 1, INT32_MAX), - PROP_U_MM(&f[1], this->type.format_audio.channels, SPA_POD_TYPE_INT, - 2, - 1, INT32_MAX)); + fmt = spa_pod_builder_format(&b, t->format, + t->media_type.audio, + t->media_subtype.raw, + ":", t->format_audio.format, "Ieu", t->audio_format.S16, + 4, t->audio_format.S16, + t->audio_format.S32, + t->audio_format.F32, + t->audio_format.F64, + ":", t->format_audio.rate, "iru", 44100, + 2, 1, INT32_MAX, + ":", t->format_audio.channels, "iru", 2, + 2, 1, INT32_MAX); break; default: return SPA_RESULT_ENUM_END; } - fmt = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer)); @@ -551,10 +532,12 @@ impl_node_port_set_format(struct spa_node *node, const struct spa_format *format) { struct impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -568,20 +551,20 @@ impl_node_port_set_format(struct spa_node *node, int idx; int sizes[4] = { 2, 4, 4, 8 }; - if (info.media_type != this->type.media_type.audio || - info.media_subtype != this->type.media_subtype.raw) + if (info.media_type != t->media_type.audio || + info.media_subtype != t->media_subtype.raw) return SPA_RESULT_INVALID_MEDIA_TYPE; - if (!spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio)) + if (spa_format_audio_raw_parse(format, &info.info.raw, &t->format_audio) < 0) return SPA_RESULT_INVALID_MEDIA_TYPE; - if (info.info.raw.format == this->type.audio_format.S16) + if (info.info.raw.format == t->audio_format.S16) idx = 0; - else if (info.info.raw.format == this->type.audio_format.S32) + else if (info.info.raw.format == t->audio_format.S32) idx = 1; - else if (info.info.raw.format == this->type.audio_format.F32) + else if (info.info.raw.format == t->audio_format.F32) idx = 2; - else if (info.info.raw.format == this->type.audio_format.F64) + else if (info.info.raw.format == t->audio_format.F64) idx = 3; else return SPA_RESULT_INVALID_MEDIA_TYPE; @@ -607,12 +590,13 @@ impl_node_port_get_format(struct spa_node *node, { struct impl *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -620,17 +604,11 @@ impl_node_port_get_format(struct spa_node *node, return SPA_RESULT_NO_FORMAT; spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer)); - spa_pod_builder_format(&b, &f[0], this->type.format, - this->type.media_type.audio, - this->type.media_subtype.raw, - PROP(&f[1], this->type.format_audio.format, SPA_POD_TYPE_ID, - this->current_format.info.raw.format), - PROP(&f[1], this->type.format_audio.rate, SPA_POD_TYPE_INT, - this->current_format.info.raw.rate), - PROP(&f[1], this->type.format_audio.channels, SPA_POD_TYPE_INT, - this->current_format.info.raw.channels)); - - *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = spa_pod_builder_format(&b, t->format, + t->media_type.audio, t->media_subtype.raw, + ":", t->format_audio.format, "I", this->current_format.info.raw.format, + ":", t->format_audio.rate, "i", this->current_format.info.raw.rate, + ":", t->format_audio.channels, "i", this->current_format.info.raw.channels); return SPA_RESULT_OK; } @@ -664,12 +642,13 @@ impl_node_port_enum_params(struct spa_node *node, { struct impl *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -677,30 +656,28 @@ impl_node_port_enum_params(struct spa_node *node, switch (index) { case 0: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_buffers.Buffers, - PROP_U_MM(&f[1], this->type.param_alloc_buffers.size, SPA_POD_TYPE_INT, - 1024 * this->bpf, - 16 * this->bpf, - INT32_MAX / this->bpf), - PROP (&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, 0), - PROP_U_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, 2, 1, 32), - PROP (&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, 16)); + *param = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf, + 2, 16 * this->bpf, + INT32_MAX / this->bpf, + ":", t->param_alloc_buffers.stride, "i", 0, + ":", t->param_alloc_buffers.buffers, "iru", 2, + 2, 1, 32, + ":", t->param_alloc_buffers.align, "i", 16); break; case 1: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_meta_enable.MetaEnable, - PROP(&f[1], this->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - this->type.meta.Header), - PROP(&f[1], this->type.param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); + *param = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); break; default: return SPA_RESULT_NOT_IMPLEMENTED; } - *param = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); - return SPA_RESULT_OK; } diff --git a/spa/plugins/ffmpeg/ffmpeg-dec.c b/spa/plugins/ffmpeg/ffmpeg-dec.c index af9b74cd0..8376f9922 100644 --- a/spa/plugins/ffmpeg/ffmpeg-dec.c +++ b/spa/plugins/ffmpeg/ffmpeg-dec.c @@ -244,7 +244,7 @@ spa_ffmpeg_dec_node_port_set_format(struct spa_node *node, info.media_subtype != this->type.media_subtype.raw) return SPA_RESULT_INVALID_MEDIA_TYPE; - if (!spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video)) + if (spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video) < 0) return SPA_RESULT_INVALID_MEDIA_TYPE; if (!(flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY)) { diff --git a/spa/plugins/ffmpeg/ffmpeg-enc.c b/spa/plugins/ffmpeg/ffmpeg-enc.c index ab962c06e..4e1735633 100644 --- a/spa/plugins/ffmpeg/ffmpeg-enc.c +++ b/spa/plugins/ffmpeg/ffmpeg-enc.c @@ -248,7 +248,7 @@ spa_ffmpeg_enc_node_port_set_format(struct spa_node *node, info.media_subtype != this->type.media_subtype.raw) return SPA_RESULT_INVALID_MEDIA_TYPE; - if (!spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video)) + if (spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video) < 0) return SPA_RESULT_INVALID_MEDIA_TYPE; if (!(flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY)) { diff --git a/spa/plugins/test/fakesink.c b/spa/plugins/test/fakesink.c index 315ca9ca5..07207b2e9 100644 --- a/spa/plugins/test/fakesink.c +++ b/spa/plugins/test/fakesink.c @@ -125,24 +125,10 @@ static void reset_props(struct impl *this, struct props *props) props->live = DEFAULT_LIVE; } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key, SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) -#define PROP_U_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) - static int impl_node_get_props(struct spa_node *node, struct spa_props **props) { struct impl *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS); @@ -150,10 +136,9 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props) this = SPA_CONTAINER_OF(node, struct impl, node); spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer)); - spa_pod_builder_props(&b, &f[0], this->type.props, - PROP(&f[1], this->type.prop_live, SPA_POD_TYPE_BOOL, - this->props.live)); - *props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + *props = spa_pod_builder_props(&b, + this->type.props, + ":", this->type.prop_live, "b", this->props.live); return SPA_RESULT_OK; } @@ -169,8 +154,8 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr if (props == NULL) { reset_props(this, &this->props); } else { - spa_props_query(props, - this->type.prop_live, SPA_POD_TYPE_BOOL, &this->props.live, 0); + spa_props_parse(props, + ":", this->type.prop_live, "?b", &this->props.live, NULL); } if (this->props.live) @@ -497,12 +482,13 @@ impl_node_port_enum_params(struct spa_node *node, { struct impl *this; struct spa_pod_builder b = { NULL }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -510,30 +496,25 @@ impl_node_port_enum_params(struct spa_node *node, switch (index) { case 0: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_buffers.Buffers, - PROP(&f[1], this->type.param_alloc_buffers.size, SPA_POD_TYPE_INT, - 128), - PROP(&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, - 1), - PROP_U_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 32, - 2, 32), - PROP(&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, - 16)); + *param = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "i", 128, + ":", t->param_alloc_buffers.stride, "i", 1, + ":", t->param_alloc_buffers.buffers, "ir", 2, + 2, 1, 32, + ":", t->param_alloc_buffers.align, "i", 16); break; case 1: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_meta_enable.MetaEnable, - PROP(&f[1], this->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - this->type.meta.Header), - PROP(&f[1], this->type.param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); + *param = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); break; default: return SPA_RESULT_NOT_IMPLEMENTED; } - *param = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); return SPA_RESULT_OK; } diff --git a/spa/plugins/test/fakesrc.c b/spa/plugins/test/fakesrc.c index 8662bc369..81544eec0 100644 --- a/spa/plugins/test/fakesrc.c +++ b/spa/plugins/test/fakesrc.c @@ -131,39 +131,24 @@ static void reset_props(struct impl *this, struct props *props) props->pattern = DEFAULT_PATTERN; } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key, SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) -#define PROP_U_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) - static int impl_node_get_props(struct spa_node *node, struct spa_props **props) { struct impl *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer)); - spa_pod_builder_props(&b, &f[0], this->type.props, - PROP(&f[1], this->type.prop_live, SPA_POD_TYPE_BOOL, - this->props.live), - PROP_EN(&f[1], this->type.prop_pattern, SPA_POD_TYPE_ID, 1, - this->props.pattern, - this->props.pattern)); - - *props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + *props = spa_pod_builder_props(&b, + t->props, + ":", t->prop_live, "b", this->props.live, + ":", t->prop_pattern, "Ie", this->props.pattern, + 1, this->props.pattern); return SPA_RESULT_OK; } @@ -171,17 +156,19 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props) static int impl_node_set_props(struct spa_node *node, const struct spa_props *props) { struct impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; if (props == NULL) { reset_props(this, &this->props); } else { - spa_props_query(props, - this->type.prop_live, SPA_POD_TYPE_BOOL, &this->props.live, - this->type.prop_pattern, SPA_POD_TYPE_ID, &this->props.pattern, 0); + spa_props_parse(props, + ":", t->prop_live, "?b", &this->props.live, + ":", t->prop_pattern, "?I", &this->props.pattern, NULL); } if (this->props.live) @@ -514,12 +501,13 @@ impl_node_port_enum_params(struct spa_node *node, { struct impl *this; struct spa_pod_builder b = { NULL }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -527,30 +515,25 @@ impl_node_port_enum_params(struct spa_node *node, switch (index) { case 0: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_buffers.Buffers, - PROP(&f[1], this->type.param_alloc_buffers.size, SPA_POD_TYPE_INT, - 128), - PROP(&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, - 1), - PROP_U_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 32, - 2, 32), - PROP(&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, - 16)); + *param = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "i", 128, + ":", t->param_alloc_buffers.stride, "i", 1, + ":", t->param_alloc_buffers.buffers, "ir", 32, + 2, 2, 32, + ":", t->param_alloc_buffers.align, "i", 16); break; case 1: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_meta_enable.MetaEnable, - PROP(&f[1], this->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - this->type.meta.Header), - PROP(&f[1], this->type.param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); + *param = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); break; default: return SPA_RESULT_NOT_IMPLEMENTED; } - *param = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); return SPA_RESULT_OK; } diff --git a/spa/plugins/v4l2/v4l2-monitor.c b/spa/plugins/v4l2/v4l2-monitor.c index a50f6e543..34e4eaa27 100644 --- a/spa/plugins/v4l2/v4l2-monitor.c +++ b/spa/plugins/v4l2/v4l2-monitor.c @@ -89,7 +89,7 @@ static void fill_item(struct impl *this, struct item *item, struct udev_device * { const char *str, *name; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[3]; + struct type *t = &this->type; if (item->udevice) udev_device_unref(item->udevice); @@ -112,59 +112,43 @@ static void fill_item(struct impl *this, struct item *item, struct udev_device * spa_pod_builder_init(&b, this->item_buffer, sizeof(this->item_buffer)); - spa_pod_builder_push_object(&b, &f[0], 0, this->type.monitor.MonitorItem); + spa_pod_builder_add(&b, + "<", 0, t->monitor.MonitorItem, + ":", t->monitor.id, "s", udev_device_get_syspath(item->udevice), + ":", t->monitor.flags, "i", 0, + ":", t->monitor.state, "i", SPA_MONITOR_ITEM_STATE_AVAILABLE, + ":", t->monitor.name, "s", name, + ":", t->monitor.klass, "s", "Video/Source", + ":", t->monitor.factory, "p", t->handle_factory, &spa_v4l2_source_factory, + ":", t->monitor.info, "[", + NULL); spa_pod_builder_add(&b, - SPA_POD_PROP(&f[1], this->type.monitor.id, 0, SPA_POD_TYPE_STRING, 1, - udev_device_get_syspath(item->udevice)), - SPA_POD_PROP(&f[1], this->type.monitor.flags, 0, SPA_POD_TYPE_INT, 1, - 0), - SPA_POD_PROP(&f[1], this->type.monitor.state, 0, SPA_POD_TYPE_INT, 1, - SPA_MONITOR_ITEM_STATE_AVAILABLE), - SPA_POD_PROP(&f[1], this->type.monitor.name, 0, SPA_POD_TYPE_STRING, 1, - name), - SPA_POD_PROP(&f[1], this->type.monitor.klass, 0, SPA_POD_TYPE_STRING, 1, - "Video/Source"), - SPA_POD_PROP(&f[1], this->type.monitor.factory, 0, SPA_POD_TYPE_POINTER, 1, - this->type.handle_factory, &spa_v4l2_source_factory), - 0); - spa_pod_builder_add(&b, - SPA_POD_TYPE_PROP, &f[1], this->type.monitor.info, 0, - SPA_POD_TYPE_STRUCT, 1, &f[2], 0); - - - spa_pod_builder_add(&b, - SPA_POD_TYPE_STRING, "udev-probed", SPA_POD_TYPE_STRING, "1", - SPA_POD_TYPE_STRING, "device.api", SPA_POD_TYPE_STRING, "v4l2", - SPA_POD_TYPE_STRING, "device.path", SPA_POD_TYPE_STRING, - udev_device_get_devnode(item->udevice), 0); + "s", "udev-probed", "s", "1", + "s", "device.api", "s", "v4l2", + "s", "device.path", "s", udev_device_get_devnode(item->udevice), + NULL); str = udev_device_get_property_value(item->udevice, "ID_PATH"); if (!(str && *str)) str = udev_device_get_syspath(item->udevice); if (str && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.bus_path", SPA_POD_TYPE_STRING, - str, 0); + spa_pod_builder_add(&b, "s", "device.bus_path", "s", str, 0); } if ((str = udev_device_get_syspath(item->udevice)) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "sysfs.path", SPA_POD_TYPE_STRING, - str, 0); + spa_pod_builder_add(&b, "s", "sysfs.path", "s", str, 0); } if ((str = udev_device_get_property_value(item->udevice, "ID_ID")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "udev.id", SPA_POD_TYPE_STRING, - str, 0); + spa_pod_builder_add(&b, "s", "udev.id", "s", str, 0); } if ((str = udev_device_get_property_value(item->udevice, "ID_BUS")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.bus", SPA_POD_TYPE_STRING, - str, 0); + spa_pod_builder_add(&b, "s", "device.bus", "s", str, 0); } if ((str = udev_device_get_property_value(item->udevice, "SUBSYSTEM")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.subsystem", - SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.subsystem", "s", str, 0); } if ((str = udev_device_get_property_value(item->udevice, "ID_VENDOR_ID")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.vendor.id", - SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.vendor.id", "s", str, 0); } str = udev_device_get_property_value(item->udevice, "ID_VENDOR_FROM_DATABASE"); if (!(str && *str)) { @@ -174,29 +158,20 @@ static void fill_item(struct impl *this, struct item *item, struct udev_device * } } if (str && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.vendor.name", - SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.vendor.name", "s", str, 0); } if ((str = udev_device_get_property_value(item->udevice, "ID_MODEL_ID")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.product.id", - SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.product.id", "s", str, 0); } - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.product.name", SPA_POD_TYPE_STRING, - name, 0); + spa_pod_builder_add(&b, "s", "device.product.name", "s", name, 0); if ((str = udev_device_get_property_value(item->udevice, "ID_SERIAL")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.serial", SPA_POD_TYPE_STRING, - str, 0); + spa_pod_builder_add(&b, "s", "device.serial", "s", str, 0); } if ((str = udev_device_get_property_value(item->udevice, "ID_V4L_CAPABILITIES")) && *str) { - spa_pod_builder_add(&b, SPA_POD_TYPE_STRING, "device.capabilities", - SPA_POD_TYPE_STRING, str, 0); + spa_pod_builder_add(&b, "s", "device.capabilities", "s", str, 0); } - spa_pod_builder_add(&b, -SPA_POD_TYPE_STRUCT, &f[2], -SPA_POD_TYPE_PROP, &f[1], 0); - - spa_pod_builder_pop(&b, &f[0]); - - item->item = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_monitor_item); + item->item = spa_pod_builder_add(&b, "]>", NULL); } static void impl_on_fd_events(struct spa_source *source) @@ -207,7 +182,6 @@ static void impl_on_fd_events(struct spa_source *source) const char *action; uint32_t type; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[1]; uint8_t buffer[4096]; dev = udev_monitor_receive_device(this->umonitor); @@ -228,9 +202,8 @@ static void impl_on_fd_events(struct spa_source *source) return; spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_object(&b, &f[0], 0, type, SPA_POD_TYPE_POD, this->uitem.item); + event = spa_pod_builder_object(&b, 0, type, "P", this->uitem.item); - event = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_event); this->callbacks->event(this->callbacks_data, event); } diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c index fb4044e66..1a354a11b 100644 --- a/spa/plugins/v4l2/v4l2-source.c +++ b/spa/plugins/v4l2/v4l2-source.c @@ -166,42 +166,25 @@ struct impl { #define CHECK_PORT(this,direction,port_id) ((direction) == SPA_DIRECTION_OUTPUT && (port_id) == 0) -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_R(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READONLY,type,1,__VA_ARGS__) -#define PROP_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) -#define PROP_U_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) #include "v4l2-utils.c" static int impl_node_get_props(struct spa_node *node, struct spa_props **props) { struct impl *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer)); - spa_pod_builder_props(&b, &f[0], this->type.props, - PROP(&f[1], this->type.prop_device, -SPA_POD_TYPE_STRING, - this->props.device, sizeof(this->props.device)), - PROP_R(&f[1], this->type.prop_device_name, -SPA_POD_TYPE_STRING, - this->props.device_name, sizeof(this->props.device_name)), - PROP_R(&f[1], this->type.prop_device_fd, SPA_POD_TYPE_INT, - this->props.device_fd)); - *props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + *props = spa_pod_builder_props(&b, t->props, + ":", t->prop_device, "S", this->props.device, sizeof(this->props.device), + ":", t->prop_device_name, "S-r", this->props.device_name, sizeof(this->props.device_name), + ":", t->prop_device_fd, "i-r", this->props.device_fd); return SPA_RESULT_OK; } @@ -209,18 +192,20 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props) static int impl_node_set_props(struct spa_node *node, const struct spa_props *props) { struct impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; if (props == NULL) { reset_props(&this->props); return SPA_RESULT_OK; - } else { - spa_props_query(props, this->type.prop_device, -SPA_POD_TYPE_STRING, - this->props.device, sizeof(this->props.device), 0); } + spa_props_parse(props, + ":", t->prop_device, "?S", this->props.device, sizeof(this->props.device), NULL); + return SPA_RESULT_OK; } @@ -456,10 +441,12 @@ static int impl_node_port_set_format(struct spa_node *node, struct impl *this; struct port *state; struct spa_video_info info; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -475,13 +462,13 @@ static int impl_node_port_set_format(struct spa_node *node, info.media_type = SPA_FORMAT_MEDIA_TYPE(format); info.media_subtype = SPA_FORMAT_MEDIA_SUBTYPE(format); - if (info.media_type != this->type.media_type.video) { + if (info.media_type != t->media_type.video) { spa_log_error(this->log, "media type must be video"); return SPA_RESULT_INVALID_MEDIA_TYPE; } - if (info.media_subtype == this->type.media_subtype.raw) { - if (!spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video)) { + if (info.media_subtype == t->media_subtype.raw) { + if (spa_format_video_raw_parse(format, &info.info.raw, &t->format_video) < 0) { spa_log_error(this->log, "can't parse video raw"); return SPA_RESULT_INVALID_MEDIA_TYPE; } @@ -492,8 +479,8 @@ static int impl_node_port_set_format(struct spa_node *node, info.info.raw.size.width == state->current_format.info.raw.size.width && info.info.raw.size.height == state->current_format.info.raw.size.height) return SPA_RESULT_OK; - } else if (info.media_subtype == this->type.media_subtype_video.mjpg) { - if (!spa_format_video_mjpg_parse(format, &info.info.mjpg, &this->type.format_video)) + } else if (info.media_subtype == t->media_subtype_video.mjpg) { + if (spa_format_video_mjpg_parse(format, &info.info.mjpg, &t->format_video) < 0) return SPA_RESULT_INVALID_MEDIA_TYPE; if (state->have_format && info.media_type == state->current_format.media_type && @@ -501,8 +488,8 @@ static int impl_node_port_set_format(struct spa_node *node, info.info.mjpg.size.width == state->current_format.info.mjpg.size.width && info.info.mjpg.size.height == state->current_format.info.mjpg.size.height) return SPA_RESULT_OK; - } else if (info.media_subtype == this->type.media_subtype_video.h264) { - if (!spa_format_video_h264_parse(format, &info.info.h264, &this->type.format_video)) + } else if (info.media_subtype == t->media_subtype_video.h264) { + if (spa_format_video_h264_parse(format, &info.info.h264, &t->format_video) < 0) return SPA_RESULT_INVALID_MEDIA_TYPE; if (state->have_format && info.media_type == state->current_format.media_type && @@ -537,12 +524,14 @@ static int impl_node_port_get_format(struct spa_node *node, struct impl *this; struct port *state; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct spa_pod_frame f[1]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -554,36 +543,28 @@ static int impl_node_port_get_format(struct spa_node *node, b.data = state->format_buffer; b.size = sizeof(state->format_buffer); - spa_pod_builder_push_format(&b, &f[0], this->type.format, + spa_pod_builder_push_format(&b, &f[0], t->format, state->current_format.media_type, state->current_format.media_subtype); - if (state->current_format.media_subtype == this->type.media_subtype.raw) { + if (state->current_format.media_subtype == t->media_subtype.raw) { spa_pod_builder_add(&b, - PROP(&f[1], this->type.format_video.format, SPA_POD_TYPE_ID, - state->current_format.info.raw.format), - PROP(&f[1], this->type.format_video.size, -SPA_POD_TYPE_RECTANGLE, - &state->current_format.info.raw.size), - PROP(&f[1], this->type.format_video.framerate, -SPA_POD_TYPE_FRACTION, - &state->current_format.info.raw.framerate), 0); - } else if (state->current_format.media_subtype == this->type.media_subtype_video.mjpg || - state->current_format.media_subtype == this->type.media_subtype_video.jpeg) { + ":", t->format_video.format, "I", state->current_format.info.raw.format, + ":", t->format_video.size, "R", &state->current_format.info.raw.size, + ":", t->format_video.framerate, "F", &state->current_format.info.raw.framerate, 0); + } else if (state->current_format.media_subtype == t->media_subtype_video.mjpg || + state->current_format.media_subtype == t->media_subtype_video.jpeg) { spa_pod_builder_add(&b, - PROP(&f[1], this->type.format_video.size, -SPA_POD_TYPE_RECTANGLE, - &state->current_format.info.mjpg.size), - PROP(&f[1], this->type.format_video.framerate, -SPA_POD_TYPE_FRACTION, - &state->current_format.info.mjpg.framerate), 0); - } else if (state->current_format.media_subtype == this->type.media_subtype_video.h264) { + ":", t->format_video.size, "R", &state->current_format.info.mjpg.size, + ":", t->format_video.framerate, "F", &state->current_format.info.mjpg.framerate, 0); + } else if (state->current_format.media_subtype == t->media_subtype_video.h264) { spa_pod_builder_add(&b, - PROP(&f[1], this->type.format_video.size, -SPA_POD_TYPE_RECTANGLE, - &state->current_format.info.h264.size), - PROP(&f[1], this->type.format_video.framerate, -SPA_POD_TYPE_FRACTION, - &state->current_format.info.h264.framerate), 0); + ":", t->format_video.size, "R", &state->current_format.info.h264.size, + ":", t->format_video.framerate, "F", &state->current_format.info.h264.framerate, 0); } else return SPA_RESULT_NO_FORMAT; spa_pod_builder_pop(&b, &f[0]); - *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); return SPA_RESULT_OK; @@ -618,12 +599,13 @@ static int impl_node_port_enum_params(struct spa_node *node, struct impl *this; struct port *state; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -633,30 +615,23 @@ static int impl_node_port_enum_params(struct spa_node *node, switch (index) { case 0: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_buffers.Buffers, - PROP(&f[1], this->type.param_alloc_buffers.size, SPA_POD_TYPE_INT, - state->fmt.fmt.pix.sizeimage), - PROP(&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, - state->fmt.fmt.pix.bytesperline), - PROP_U_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - MAX_BUFFERS, 2, MAX_BUFFERS), - PROP(&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, 16)); + *param = spa_pod_builder_param(&b, t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "i", state->fmt.fmt.pix.sizeimage, + ":", t->param_alloc_buffers.stride, "i", state->fmt.fmt.pix.bytesperline, + ":", t->param_alloc_buffers.buffers, "iru", MAX_BUFFERS, + 2, 2, MAX_BUFFERS, + ":", t->param_alloc_buffers.align, "i", 16); break; case 1: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_meta_enable.MetaEnable, - PROP(&f[1], this->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - this->type.meta.Header), - PROP(&f[1], this->type.param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); + *param = spa_pod_builder_param(&b, t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); break; default: return SPA_RESULT_NOT_IMPLEMENTED; } - - *param = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); - return SPA_RESULT_OK; } diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c index b50f06c88..ab380ab44 100644 --- a/spa/plugins/v4l2/v4l2-utils.c +++ b/spa/plugins/v4l2/v4l2-utils.c @@ -680,12 +680,11 @@ spa_v4l2_enum_format(struct impl *this, if (media_subtype == this->type.media_subtype.raw) { spa_pod_builder_add(&b, - PROP(&f[1], this->type.format_video.format, SPA_POD_TYPE_ID, - video_format), 0); + ":", this->type.format_video.format, "I", video_format, 0); } spa_pod_builder_add(&b, - PROP(&f[1], this->type.format_video.size, SPA_POD_TYPE_RECTANGLE, - state->frmsize.discrete.width, state->frmsize.discrete.height), 0); + ":", this->type.format_video.size, "R", &SPA_RECTANGLE(state->frmsize.discrete.width, + state->frmsize.discrete.height), 0); spa_pod_builder_push_prop(&b, &f[1], this->type.format_video.framerate, SPA_POD_PROP_RANGE_NONE | SPA_POD_PROP_FLAG_UNSET); diff --git a/spa/plugins/videotestsrc/videotestsrc.c b/spa/plugins/videotestsrc/videotestsrc.c index 1cf311862..23000db9e 100644 --- a/spa/plugins/videotestsrc/videotestsrc.c +++ b/spa/plugins/videotestsrc/videotestsrc.c @@ -153,40 +153,25 @@ static void reset_props(struct impl *this, struct props *props) props->pattern = this->type.DEFAULT_PATTERN; } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) -#define PROP_U_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) - static int impl_node_get_props(struct spa_node *node, struct spa_props **props) { struct impl *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer)); - spa_pod_builder_props(&b, &f[0], this->type.props, - PROP(&f[1], this->type.prop_live, SPA_POD_TYPE_BOOL, - this->props.live), - PROP_EN(&f[1], this->type.prop_pattern, SPA_POD_TYPE_ID, 3, - this->props.pattern, - this->type.pattern_smpte_snow, - this->type.pattern_snow)); - - *props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + *props = spa_pod_builder_props(&b, + t->props, + ":", t->prop_live, "b", this->props.live, + ":", t->prop_pattern, "Ie", this->props.pattern, + 2, t->pattern_smpte_snow, + t->pattern_snow); return SPA_RESULT_OK; } @@ -194,18 +179,20 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props) static int impl_node_set_props(struct spa_node *node, const struct spa_props *props) { struct impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; if (props == NULL) { reset_props(this, &this->props); } else { - spa_props_query(props, - this->type.prop_live, SPA_POD_TYPE_BOOL, &this->props.live, - this->type.prop_pattern, SPA_POD_TYPE_ID, &this->props.pattern, - 0); + spa_props_parse(props, + ":", t->prop_live, "?b", &this->props.live, + ":", t->prop_pattern, "?I", &this->props.pattern, + NULL); } if (this->props.live) @@ -433,13 +420,14 @@ impl_node_port_enum_formats(struct spa_node *node, struct spa_format *fmt; uint8_t buffer[256]; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; uint32_t count, match; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -450,26 +438,22 @@ impl_node_port_enum_formats(struct spa_node *node, switch (count++) { case 0: - spa_pod_builder_format(&b, &f[0], this->type.format, - this->type.media_type.video, - this->type.media_subtype.raw, - PROP_U_EN(&f[1], this->type.format_video.format, SPA_POD_TYPE_ID, 3, - this->type.video_format.RGB, - this->type.video_format.RGB, - this->type.video_format.UYVY), - PROP_U_MM(&f[1], this->type.format_video.size, SPA_POD_TYPE_RECTANGLE, - 320, 240, - 1, 1, - INT32_MAX, INT32_MAX), - PROP_U_MM(&f[1], this->type.format_video.framerate, SPA_POD_TYPE_FRACTION, - 25, 1, - 0, 1, - INT32_MAX, 1)); + fmt = spa_pod_builder_format(&b, + t->format, + t->media_type.video, t->media_subtype.raw, + ":", t->format_video.format, "Ieu", t->video_format.RGB, + 2, t->video_format.RGB, + t->video_format.UYVY, + ":", t->format_video.size, "Rru", &SPA_RECTANGLE(320, 240), + 2, &SPA_RECTANGLE(1, 1), + &SPA_RECTANGLE(INT32_MAX, INT32_MAX), + ":", t->format_video.framerate, "Fru", &SPA_FRACTION(25,1), + 2, &SPA_FRACTION(0, 1), + &SPA_FRACTION(INT32_MAX, 1)); break; default: return SPA_RESULT_ENUM_END; } - fmt = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer)); @@ -520,7 +504,7 @@ impl_node_port_set_format(struct spa_node *node, info.media_subtype != this->type.media_subtype.raw) return SPA_RESULT_INVALID_MEDIA_TYPE; - if (!spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video)) + if (spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video) < 0) return SPA_RESULT_INVALID_MEDIA_TYPE; if (info.info.raw.format == this->type.video_format.RGB) @@ -550,12 +534,13 @@ impl_node_port_get_format(struct spa_node *node, { struct impl *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -563,17 +548,12 @@ impl_node_port_get_format(struct spa_node *node, return SPA_RESULT_NO_FORMAT; spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer)); - spa_pod_builder_format(&b, &f[0], this->type.format, - this->type.media_type.video, - this->type.media_subtype.raw, - PROP(&f[1], this->type.format_video.format, SPA_POD_TYPE_ID, - this->current_format.info.raw.format), - PROP(&f[1], this->type.format_video.size, -SPA_POD_TYPE_RECTANGLE, - &this->current_format.info.raw.size), - PROP(&f[1], this->type.format_video.framerate, -SPA_POD_TYPE_FRACTION, - &this->current_format.info.raw.framerate)); - - *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = spa_pod_builder_format(&b, + t->format, + t->media_type.video, t->media_subtype.raw, + ":", t->format_video.format, "I", this->current_format.info.raw.format, + ":", t->format_video.size, "R", &this->current_format.info.raw.size, + ":", t->format_video.framerate, "F", &this->current_format.info.raw.framerate); return SPA_RESULT_OK; } @@ -607,12 +587,13 @@ impl_node_port_enum_params(struct spa_node *node, { struct impl *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -622,31 +603,26 @@ impl_node_port_enum_params(struct spa_node *node, case 0: { struct spa_video_info_raw *raw_info = &this->current_format.info.raw; - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_buffers.Buffers, - PROP(&f[1], this->type.param_alloc_buffers.size, SPA_POD_TYPE_INT, - this->stride * raw_info->size.height), - PROP(&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, - this->stride), - PROP_U_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 2, 1, 32), - PROP(&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, - 16)); + *param = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "i", this->stride * raw_info->size.height, + ":", t->param_alloc_buffers.stride, "i", this->stride, + ":", t->param_alloc_buffers.buffers, "ir", 2, + 2, 1, 32, + ":", t->param_alloc_buffers.align, "i", 16); break; } case 1: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_meta_enable.MetaEnable, - PROP(&f[1], this->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - this->type.meta.Header), - PROP(&f[1], this->type.param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); + *param = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); break; default: return SPA_RESULT_NOT_IMPLEMENTED; } - *param = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); - return SPA_RESULT_OK; } diff --git a/spa/plugins/volume/volume.c b/spa/plugins/volume/volume.c index c4a9116ba..efab73538 100644 --- a/spa/plugins/volume/volume.c +++ b/spa/plugins/volume/volume.c @@ -135,38 +135,23 @@ static void reset_props(struct props *props) props->mute = DEFAULT_MUTE; } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_U_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) - - static int impl_node_get_props(struct spa_node *node, struct spa_props **props) { struct impl *this; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer)); - spa_pod_builder_props(&b, &f[0], this->type.props, - PROP_MM(&f[1], this->type.prop_volume, SPA_POD_TYPE_DOUBLE, - this->props.volume, - 0.0, 10.0), - PROP(&f[1], this->type.prop_mute, SPA_POD_TYPE_BOOL, - this->props.mute)); - - *props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + *props = spa_pod_builder_props(&b, + t->props, + ":", t->prop_volume, "dr", this->props.volume, 2, 0.0, 10.0, + ":", t->prop_mute, "b", this->props.mute); return SPA_RESULT_OK; } @@ -174,17 +159,19 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props) static int impl_node_set_props(struct spa_node *node, const struct spa_props *props) { struct impl *this; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; if (props == NULL) { reset_props(&this->props); } else { - spa_props_query(props, - this->type.prop_volume, SPA_POD_TYPE_DOUBLE, &this->props.volume, - this->type.prop_mute, SPA_POD_TYPE_BOOL, &this->props.mute, 0); + spa_props_parse(props, + ":", t->prop_volume, "?d", &this->props.volume, + ":", t->prop_mute, "?b", &this->props.mute, NULL); } return SPA_RESULT_OK; } @@ -288,13 +275,14 @@ impl_node_port_enum_formats(struct spa_node *node, struct spa_format *fmt; uint8_t buffer[1024]; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; uint32_t count, match; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -305,25 +293,19 @@ impl_node_port_enum_formats(struct spa_node *node, switch (count++) { case 0: - spa_pod_builder_format(&b, &f[0], this->type.format, - this->type.media_type.audio, - this->type.media_subtype.raw, - PROP_U_EN(&f[1], this->type.format_audio.format, SPA_POD_TYPE_ID, 3, - this->type.audio_format.S16, - this->type.audio_format.S16, - this->type.audio_format.S32), - PROP_U_MM(&f[1], this->type.format_audio.rate, SPA_POD_TYPE_INT, - 44100, - 1, INT32_MAX), - PROP_U_MM(&f[1], this->type.format_audio.channels, SPA_POD_TYPE_INT, - 2, - 1, INT32_MAX)); - + fmt = spa_pod_builder_format(&b, + t->format, + t->media_type.audio, t->media_subtype.raw, + ":", t->format_audio.format, "Ieu", t->audio_format.S16, + 2, t->audio_format.S16, + t->audio_format.S32, + ":", t->format_audio.rate, "iru", 44100, 2, 1, INT32_MAX, + ":", t->format_audio.channels,"iru", 2, 2, 1, INT32_MAX); break; default: return SPA_RESULT_ENUM_END; } - fmt = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer)); if ((res = spa_format_filter(fmt, filter, &b)) != SPA_RESULT_OK || match++ != index) @@ -375,7 +357,7 @@ impl_node_port_set_format(struct spa_node *node, info.media_subtype != this->type.media_subtype.raw) return SPA_RESULT_INVALID_MEDIA_TYPE; - if (!spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio)) + if (spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio) < 0) return SPA_RESULT_INVALID_MEDIA_TYPE; this->bpf = 2 * info.info.raw.channels; @@ -395,12 +377,13 @@ impl_node_port_get_format(struct spa_node *node, struct impl *this; struct port *port; struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame f[2]; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -411,16 +394,12 @@ impl_node_port_get_format(struct spa_node *node, return SPA_RESULT_NO_FORMAT; spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer)); - spa_pod_builder_format(&b, &f[0], this->type.format, - this->type.media_type.audio, - this->type.media_subtype.raw, - PROP(&f[1], this->type.format_audio.format, SPA_POD_TYPE_ID, - this->current_format.info.raw.format), - PROP(&f[1], this->type.format_audio.rate, SPA_POD_TYPE_INT, - this->current_format.info.raw.rate), - PROP(&f[1], this->type.format_audio.channels, SPA_POD_TYPE_INT, - this->current_format.info.raw.channels)); - *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = spa_pod_builder_format(&b, + t->format, + t->media_type.audio, t->media_subtype.raw, + ":", t->format_audio.format, "I", this->current_format.info.raw.format, + ":", t->format_audio.rate, "i", this->current_format.info.raw.rate, + ":", t->format_audio.channels, "i", this->current_format.info.raw.channels); return SPA_RESULT_OK; } @@ -456,14 +435,15 @@ impl_node_port_enum_params(struct spa_node *node, struct spa_param **param) { struct spa_pod_builder b = { NULL }; - struct spa_pod_frame f[2]; struct impl *this; struct port *port; + struct type *t; spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS); spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS); this = SPA_CONTAINER_OF(node, struct impl, node); + t = &this->type; spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT); @@ -474,31 +454,28 @@ impl_node_port_enum_params(struct spa_node *node, switch (index) { case 0: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_buffers.Buffers, - PROP_U_MM(&f[1], this->type.param_alloc_buffers.size, SPA_POD_TYPE_INT, - 1024 * this->bpf, - 16 * this->bpf, - INT32_MAX / this->bpf), - PROP (&f[1], this->type.param_alloc_buffers.stride, SPA_POD_TYPE_INT, 0), - PROP_U_MM(&f[1], this->type.param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 2, 1, MAX_BUFFERS), - PROP (&f[1], this->type.param_alloc_buffers.align, SPA_POD_TYPE_INT, 16)); + *param = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf, + 2, 16 * this->bpf, + INT32_MAX / this->bpf, + ":", t->param_alloc_buffers.stride, "i", 0, + ":", t->param_alloc_buffers.buffers, "iru", 2, + 2, 1, MAX_BUFFERS, + ":", t->param_alloc_buffers.align, "i", 16); break; case 1: - spa_pod_builder_object(&b, &f[0], 0, this->type.param_alloc_meta_enable.MetaEnable, - PROP(&f[1], this->type.param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - this->type.meta.Header), - PROP(&f[1], this->type.param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); + *param = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); break; default: return SPA_RESULT_NOT_IMPLEMENTED; } - *param = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); - return SPA_RESULT_OK; } diff --git a/spa/tests/meson.build b/spa/tests/meson.build index 8f9574265..05eb54c52 100644 --- a/spa/tests/meson.build +++ b/spa/tests/meson.build @@ -1,26 +1,32 @@ executable('test-mixer', 'test-mixer.c', include_directories : [spa_inc ], dependencies : [dl_lib, pthread_lib], + link_with : spalib, install : false) executable('test-ringbuffer', 'test-ringbuffer.c', include_directories : [spa_inc, spa_libinc ], dependencies : [dl_lib, pthread_lib], + link_with : spalib, install : false) executable('test-graph', 'test-graph.c', include_directories : [spa_inc ], dependencies : [dl_lib, pthread_lib], + link_with : spalib, install : false) executable('test-graph2', 'test-graph2.c', include_directories : [spa_inc ], dependencies : [dl_lib, pthread_lib], + link_with : spalib, install : false) executable('test-perf', 'test-perf.c', include_directories : [spa_inc, spa_libinc ], dependencies : [dl_lib, pthread_lib], + link_with : spalib, install : false) executable('stress-ringbuffer', 'stress-ringbuffer.c', include_directories : [spa_inc, spa_libinc ], dependencies : [dl_lib, pthread_lib], + link_with : spalib, install : false) if sdl_dep.found() executable('test-v4l2', 'test-v4l2.c', @@ -44,3 +50,13 @@ executable('test-props3', 'test-props3.c', dependencies : [], link_with : spalib, install : false) +#executable('test-props4', 'test-props4.c', +# include_directories : [spa_inc, spa_libinc ], +# dependencies : [], +# link_with : spalib, +# install : false) +executable('test-props5', 'test-props5.c', + include_directories : [spa_inc, spa_libinc ], + dependencies : [], + link_with : spalib, + install : false) diff --git a/spa/tests/test-graph.c b/spa/tests/test-graph.c index 30d6af5c6..2ac0886c3 100644 --- a/spa/tests/test-graph.c +++ b/spa/tests/test-graph.c @@ -38,6 +38,8 @@ #include #include +#include + static SPA_TYPE_MAP_IMPL(default_map, 4096); static SPA_LOG_IMPL(default_log); @@ -281,7 +283,6 @@ static int make_nodes(struct data *data, const char *device) int res; struct spa_props *props; struct spa_pod_builder b = { 0 }; - struct spa_pod_frame f[2]; uint8_t buffer[128]; if ((res = make_node(data, &data->sink, @@ -292,12 +293,12 @@ static int make_nodes(struct data *data, const char *device) spa_node_set_callbacks(data->sink, &sink_callbacks, data); spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_props(&b, &f[0], data->type.props, - SPA_POD_PROP(&f[1], data->type.props_device, 0, SPA_POD_TYPE_STRING, 1, - device ? device : "hw:0"), - SPA_POD_PROP(&f[1], data->type.props_min_latency, 0, SPA_POD_TYPE_INT, 1, - MIN_LATENCY)); - props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + props = spa_pod_builder_props(&b, + data->type.props, + ":", data->type.props_device, "s", device ? device : "hw:0", + ":", data->type.props_min_latency, "i", MIN_LATENCY); + + spa_debug_pod(&props->object.pod); if ((res = spa_node_set_props(data->sink, props)) < 0) printf("got set_props error %d\n", res); @@ -316,14 +317,11 @@ static int make_nodes(struct data *data, const char *device) } spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_props(&b, &f[0], data->type.props, - SPA_POD_PROP(&f[1], data->type.props_freq, 0, SPA_POD_TYPE_DOUBLE, 1, - 600.0), - SPA_POD_PROP(&f[1], data->type.props_volume, 0, SPA_POD_TYPE_DOUBLE, 1, - 0.5), - SPA_POD_PROP(&f[1], data->type.props_live, 0, SPA_POD_TYPE_BOOL, 1, - false)); - props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + props = spa_pod_builder_props(&b, + data->type.props, + ":", data->type.props_freq, "d", 600.0, + ":", data->type.props_volume, "d", 0.5, + ":", data->type.props_live, "b", false); if ((res = spa_node_set_props(data->source, props)) < 0) printf("got set_props error %d\n", res); @@ -370,22 +368,16 @@ static int negotiate_formats(struct data *data) struct spa_format *format, *filter; uint32_t state = 0; struct spa_pod_builder b = { 0 }; - struct spa_pod_frame f[2]; uint8_t buffer[256]; spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_format(&b, &f[0], data->type.format, - data->type.media_type.audio, - data->type.media_subtype.raw, - SPA_POD_PROP(&f[1], data->type.format_audio.format, 0, SPA_POD_TYPE_ID, 1, - data->type.audio_format.S16), - SPA_POD_PROP(&f[1], data->type.format_audio.layout, 0, SPA_POD_TYPE_INT, 1, - SPA_AUDIO_LAYOUT_INTERLEAVED), - SPA_POD_PROP(&f[1], data->type.format_audio.rate, 0, SPA_POD_TYPE_INT, 1, - 44100), - SPA_POD_PROP(&f[1], data->type.format_audio.channels, 0, SPA_POD_TYPE_INT, 1, - 2)); - filter = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + filter = spa_pod_builder_format(&b, + data->type.format, + data->type.media_type.audio, data->type.media_subtype.raw, + ":", data->type.format_audio.format, "I", data->type.audio_format.S16, + ":", data->type.format_audio.layout, "i", SPA_AUDIO_LAYOUT_INTERLEAVED, + ":", data->type.format_audio.rate, "i", 44100, + ":", data->type.format_audio.channels, "i", 2); if ((res = spa_node_port_enum_formats(data->sink, SPA_DIRECTION_INPUT, 0, &format, filter, @@ -527,7 +519,6 @@ int main(int argc, char *argv[]) int res; const char *str; - spa_graph_init(&data.graph); spa_graph_data_init(&data.graph_data, &data.graph); spa_graph_set_callbacks(&data.graph, &spa_graph_impl_default, &data.graph_data); @@ -540,6 +531,8 @@ int main(int argc, char *argv[]) data.data_loop.remove_source = do_remove_source; data.data_loop.invoke = do_invoke; + spa_debug_set_type_map(data.map); + if ((str = getenv("SPA_DEBUG"))) data.log->level = atoi(str); diff --git a/spa/tests/test-mixer.c b/spa/tests/test-mixer.c index e86a6e089..388f4d3a2 100644 --- a/spa/tests/test-mixer.c +++ b/spa/tests/test-mixer.c @@ -325,7 +325,6 @@ static int make_nodes(struct data *data, const char *device) int res; struct spa_props *props; struct spa_pod_builder b = { 0 }; - struct spa_pod_frame f[2]; uint8_t buffer[128]; if ((res = make_node(data, &data->sink, @@ -336,12 +335,10 @@ static int make_nodes(struct data *data, const char *device) spa_node_set_callbacks(data->sink, &sink_callbacks, data); spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_props(&b, &f[0], data->type.props, - SPA_POD_PROP(&f[1], data->type.props_device, 0, SPA_POD_TYPE_STRING, 1, - device ? device : "hw:0"), - SPA_POD_PROP(&f[1], data->type.props_min_latency, 0, SPA_POD_TYPE_INT, 1, - MIN_LATENCY)); - props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + props = spa_pod_builder_props(&b, + data->type.props, + ":", data->type.props_device, "s", device ? device : "hw:0", + ":", data->type.props_min_latency, "i", MIN_LATENCY); if ((res = spa_node_set_props(data->sink, props)) < 0) printf("got set_props error %d\n", res); @@ -361,14 +358,11 @@ static int make_nodes(struct data *data, const char *device) } spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_props(&b, &f[0], data->type.props, - SPA_POD_PROP(&f[1], data->type.props_freq, 0, SPA_POD_TYPE_DOUBLE, 1, - 600.0), - SPA_POD_PROP(&f[1], data->type.props_volume, 0, SPA_POD_TYPE_DOUBLE, 1, - 0.5), - SPA_POD_PROP(&f[1], data->type.props_live, 0, SPA_POD_TYPE_BOOL, 1, - false)); - props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + props = spa_pod_builder_props(&b, + data->type.props, + ":", data->type.props_freq, "d", 600.0, + ":", data->type.props_volume, "d", 0.5, + ":", data->type.props_live, "b", false); if ((res = spa_node_set_props(data->source1, props)) < 0) printf("got set_props error %d\n", res); @@ -381,14 +375,11 @@ static int make_nodes(struct data *data, const char *device) } spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_props(&b, &f[0], data->type.props, - SPA_POD_PROP(&f[1], data->type.props_freq, 0, SPA_POD_TYPE_DOUBLE, 1, - 440.0), - SPA_POD_PROP(&f[1], data->type.props_volume, 0, SPA_POD_TYPE_DOUBLE, 1, - 0.5), - SPA_POD_PROP(&f[1], data->type.props_live, 0, SPA_POD_TYPE_BOOL, 1, - false)); - props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + props = spa_pod_builder_props(&b, + data->type.props, + ":", data->type.props_freq, "d", 440.0, + ":", data->type.props_volume, "d", 0.5, + ":", data->type.props_live, "b", false); if ((res = spa_node_set_props(data->source2, props)) < 0) printf("got set_props error %d\n", res); @@ -459,22 +450,16 @@ static int negotiate_formats(struct data *data) struct spa_format *format, *filter; uint32_t state = 0; struct spa_pod_builder b = { 0 }; - struct spa_pod_frame f[2]; uint8_t buffer[256]; spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_format(&b, &f[0], data->type.format, - data->type.media_type.audio, - data->type.media_subtype.raw, - SPA_POD_PROP(&f[1], data->type.format_audio.format, 0, SPA_POD_TYPE_ID, 1, - data->type.audio_format.S16), - SPA_POD_PROP(&f[1], data->type.format_audio.layout, 0, SPA_POD_TYPE_INT, 1, - SPA_AUDIO_LAYOUT_INTERLEAVED), - SPA_POD_PROP(&f[1], data->type.format_audio.rate, 0, SPA_POD_TYPE_INT, 1, - 44100), - SPA_POD_PROP(&f[1], data->type.format_audio.channels, 0, SPA_POD_TYPE_INT, 1, - 2)); - filter = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + filter = spa_pod_builder_format(&b, + data->type.format, + data->type.media_type.audio, data->type.media_subtype.raw, + ":", data->type.format_audio.format, "I", data->type.audio_format.S16, + ":", data->type.format_audio.layout, "i", SPA_AUDIO_LAYOUT_INTERLEAVED, + ":", data->type.format_audio.rate, "i", 44100, + ":", data->type.format_audio.channels, "i", 2); if ((res = spa_node_port_enum_formats(data->sink, SPA_DIRECTION_INPUT, 0, &format, filter, diff --git a/spa/tests/test-perf.c b/spa/tests/test-perf.c index 228479e87..f6504307d 100644 --- a/spa/tests/test-perf.c +++ b/spa/tests/test-perf.c @@ -387,13 +387,12 @@ static int negotiate_formats(struct data *data) int res; struct spa_format *format; struct spa_pod_builder b = { 0 }; - struct spa_pod_frame f[2]; uint8_t buffer[256]; spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_format(&b, &f[0], data->type.format, - data->type.media_type.binary, data->type.media_subtype.raw, 0); - format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + format = spa_pod_builder_format(&b, + data->type.format, + data->type.media_type.binary, data->type.media_subtype.raw); if ((res = spa_node_port_set_format(data->sink, SPA_DIRECTION_INPUT, 0, 0, format)) < 0) return res; diff --git a/spa/tests/test-props.c b/spa/tests/test-props.c index f45a1cbfd..0f9e2d513 100644 --- a/spa/tests/test-props.c +++ b/spa/tests/test-props.c @@ -230,8 +230,8 @@ static void do_static_struct(struct spa_type_map *map) sizeof(struct spa_rectangle), SPA_POD_TYPE_RECTANGLE), { - { 320, 243}, - { 1, 1}, { INT32_MAX, INT32_MAX} + SPA_RECTANGLE(320,243), + SPA_RECTANGLE(1,1), SPA_RECTANGLE(INT32_MAX, INT32_MAX) }, SPA_POD_PROP_INIT(sizeof(test_format.props.framerate_vals) + sizeof(struct spa_pod_prop_body), @@ -239,8 +239,8 @@ static void do_static_struct(struct spa_type_map *map) SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET, sizeof(struct spa_fraction), SPA_POD_TYPE_FRACTION), { - { 25, 1}, - { 0, 1}, { INT32_MAX, 1} + SPA_FRACTION(25,1), + SPA_FRACTION(0,1), SPA_FRACTION(INT32_MAX,1) } } }; @@ -249,24 +249,23 @@ static void do_static_struct(struct spa_type_map *map) spa_debug_format(&test_format.fmt); { - uint32_t format = 0, match; - struct spa_fraction frac = { 0, 0 }; + uint32_t format = -1; + int res; + struct spa_fraction frac = { -1, -1 }; - match = spa_pod_contents_query(&test_format.fmt.pod, sizeof(struct spa_format), - type.format_video.format, SPA_POD_TYPE_ID, &format, - type.format_video.framerate, SPA_POD_TYPE_FRACTION, - &frac, 0); + res = spa_format_parse(&test_format.fmt, + ":",type.format_video.format, "I", &format, + ":",type.format_video.framerate, "F", &frac, NULL); - printf("%d %d %d %d\n", match, format, frac.num, frac.denom); + printf("%d format %d num %d denom %d\n", res, format, frac.num, frac.denom); spa_format_fixate(&test_format.fmt); - match = spa_pod_contents_query(&test_format.fmt.pod, sizeof(struct spa_format), - type.format_video.format, SPA_POD_TYPE_ID, &format, - type.format_video.framerate, SPA_POD_TYPE_FRACTION, - &frac, 0); + res = spa_format_parse(&test_format.fmt, + ":",type.format_video.format, "I", &format, + ":",type.format_video.framerate, "F", &frac, NULL); - printf("%d %d %d %d\n", match, format, frac.num, frac.denom); + printf("%d format %d num %d denom %d\n", res, format, frac.num, frac.denom); } } @@ -274,7 +273,7 @@ static void do_static_struct(struct spa_type_map *map) int main(int argc, char *argv[]) { struct spa_pod_builder b = { NULL, }; - struct spa_pod_frame frame[4]; + struct spa_pod_frame f[2]; uint8_t buffer[1024]; struct spa_format *fmt; struct spa_type_map *map = &default_map.map; @@ -284,105 +283,82 @@ int main(int argc, char *argv[]) spa_pod_builder_init(&b, buffer, sizeof(buffer)); - fmt = SPA_MEMBER(buffer, spa_pod_builder_push_format(&b, &frame[0], type.format, + fmt = SPA_MEMBER(buffer, spa_pod_builder_push_format(&b, &f[0], type.format, type.media_type.video, type.media_subtype.raw), struct spa_format); - spa_pod_builder_push_prop(&b, &frame[1], type.format_video.format, + spa_pod_builder_push_prop(&b, &f[1], type.format_video.format, SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET); spa_pod_builder_id(&b, type.video_format.I420); spa_pod_builder_id(&b, type.video_format.I420); spa_pod_builder_id(&b, type.video_format.YUY2); - spa_pod_builder_pop(&b, &frame[1]); + spa_pod_builder_pop(&b, &f[1]); struct spa_rectangle size_min_max[] = { {1, 1}, {INT32_MAX, INT32_MAX} }; - spa_pod_builder_push_prop(&b, &frame[1], + spa_pod_builder_push_prop(&b, &f[1], type.format_video.size, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET); spa_pod_builder_rectangle(&b, 320, 240); spa_pod_builder_raw(&b, size_min_max, sizeof(size_min_max)); - spa_pod_builder_pop(&b, &frame[1]); + spa_pod_builder_pop(&b, &f[1]); struct spa_fraction rate_min_max[] = { {0, 1}, {INT32_MAX, 1} }; - spa_pod_builder_push_prop(&b, &frame[1], + spa_pod_builder_push_prop(&b, &f[1], type.format_video.framerate, SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET); spa_pod_builder_fraction(&b, 25, 1); spa_pod_builder_raw(&b, rate_min_max, sizeof(rate_min_max)); - spa_pod_builder_pop(&b, &frame[1]); + spa_pod_builder_pop(&b, &f[1]); - spa_pod_builder_pop(&b, &frame[0]); + spa_pod_builder_pop(&b, &f[0]); spa_debug_pod(&fmt->pod); spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_format(&b, &frame[0], type.format, - type.media_type.video, - type.media_subtype.raw, - SPA_POD_TYPE_PROP, &frame[1], - type.format_video.format, - SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_ENUM, - SPA_POD_TYPE_ID, 3, - type.video_format.I420, - type.video_format.I420, - type.video_format.YUY2, - -SPA_POD_TYPE_PROP, &frame[1], - SPA_POD_TYPE_PROP, &frame[1], - type.format_video.size, - SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_RECTANGLE, 3, - 320, 241, - 1, 1, - INT32_MAX, INT32_MAX, - -SPA_POD_TYPE_PROP, &frame[1], - SPA_POD_TYPE_PROP, &frame[1], - type.format_video.framerate, - SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_FRACTION, 3, - 25, 1, - 0, 1, - INT32_MAX, 1, - -SPA_POD_TYPE_PROP, &frame[1]); + fmt = spa_pod_builder_format(&b, + type.format, + type.media_type.video, type.media_subtype.raw, + ":", type.format_video.format, "Ieu", type.video_format.I420, + 2, type.video_format.I420, + type.video_format.YUY2, + ":", type.format_video.size, "Rru", &SPA_RECTANGLE(320,241), + 2, &SPA_RECTANGLE(1,1), + &SPA_RECTANGLE(INT32_MAX,INT32_MAX), + ":", type.format_video.framerate, "Fru", &SPA_FRACTION(25,1), + 2, &SPA_FRACTION(0,1), + &SPA_FRACTION(INT32_MAX,1)); - fmt = SPA_MEMBER(buffer, frame[0].ref, struct spa_format); spa_debug_pod(&fmt->pod); spa_debug_format(fmt); spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_add(&b, - SPA_POD_TYPE_OBJECT, &frame[0], 0, type.format, - SPA_POD_TYPE_ID, type.media_type.video, - SPA_POD_TYPE_ID, type.media_subtype.raw, - SPA_POD_TYPE_PROP, &frame[1], - type.format_video.format, - SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_ENUM, - SPA_POD_TYPE_ID, 3, - type.video_format.I420, - type.video_format.I420, - type.video_format.YUY2, - -SPA_POD_TYPE_PROP, &frame[1], - SPA_POD_TYPE_PROP, &frame[1], - type.format_video.size, - SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_RECTANGLE, 3, - 320, 242, - 1, 1, - INT32_MAX, INT32_MAX, - -SPA_POD_TYPE_PROP, &frame[1], - SPA_POD_TYPE_PROP, &frame[1], - type.format_video.framerate, - SPA_POD_PROP_FLAG_UNSET | SPA_POD_PROP_RANGE_MIN_MAX, - SPA_POD_TYPE_FRACTION, 3, - 25, 1, - 0, 1, - INT32_MAX, 1, - -SPA_POD_TYPE_PROP, &frame[1], - -SPA_POD_TYPE_OBJECT, &frame[0], - 0); + /* + * ( "Format", + * ("video", "raw" ), + * { + * "format": ( "seu", "I420", ( "I420","YUY2" ) ), + * "size": ( "Rru", (320, 242), ( (1,1), (MAX, MAX)) ), + * "framerate": ( "Fru", (25, 1), ( (0,1), (MAX, 1)) ) + * } + * ) + */ + fmt = spa_pod_builder_add(&b, + "<", 0, type.format, + "I", type.media_type.video, + "I", type.media_subtype.raw, + ":", type.format_video.format, "Ieu", type.video_format.I420, + 2, type.video_format.I420, + type.video_format.YUY2, + ":", type.format_video.size, "Rru", &SPA_RECTANGLE(320,242), + 2, &SPA_RECTANGLE(1,1), + &SPA_RECTANGLE(INT32_MAX,INT32_MAX), + ":", type.format_video.framerate, "Fru", &SPA_FRACTION(25,1), + 2, &SPA_FRACTION(0,1), + &SPA_FRACTION(INT32_MAX,1), + ">", NULL); - fmt = SPA_MEMBER(buffer, frame[0].ref, struct spa_format); spa_debug_pod(&fmt->pod); spa_debug_format(fmt); diff --git a/spa/tests/test-props2.c b/spa/tests/test-props2.c index d21ed6653..b2408e8b9 100644 --- a/spa/tests/test-props2.c +++ b/spa/tests/test-props2.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) struct spa_pod_frame frame[4]; uint8_t buffer[1024]; struct spa_pod *obj; - struct spa_pod_iter i; + struct spa_pod_parser prs; struct spa_type_map *map = &default_map.map; spa_debug_set_type_map(map); @@ -105,14 +105,17 @@ int main(int argc, char *argv[]) struct spa_rectangle vr; struct spa_fraction vfr; struct spa_pod_array *va; - spa_pod_iter_pod(&i, obj); - spa_pod_iter_get(&i, SPA_POD_TYPE_INT, &vi, - SPA_POD_TYPE_LONG, &vl, - SPA_POD_TYPE_FLOAT, &vf, - SPA_POD_TYPE_DOUBLE, &vd, - SPA_POD_TYPE_STRING, &vs, - SPA_POD_TYPE_RECTANGLE, &vr, - SPA_POD_TYPE_FRACTION, &vfr, SPA_POD_TYPE_ARRAY, &va, 0); + spa_pod_parser_pod(&prs, obj); + spa_pod_parser_get(&prs, + "[" + "i", &vi, + "l", &vl, + "f", &vf, + "d", &vd, + "s", &vs, + "R", &vr, + "F", &vfr, + "P", &va, 0); printf("%u %lu %f %g %s %ux%u %u/%u\n", vi, vl, vf, vd, vs, vr.width, vr.height, vfr.num, vfr.denom); diff --git a/spa/tests/test-props3.c b/spa/tests/test-props3.c index 4e2e06be5..da28fde13 100644 --- a/spa/tests/test-props3.c +++ b/spa/tests/test-props3.c @@ -22,558 +22,10 @@ #include #include #include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#if 0 -/* -* JSON based format description - - [ , - [ , ], - { - : , - ... - } - ] - - = [ , , [ ,... ]] - | - - - = "123.." - - 1: s = string : "value" - i = int : - l = long : - f = float : - d = double : - b = bool : true | false - R = rectangle : [ , ] - F = fraction : [ , ] - - 2: - = default (only default value present) - e = enum : [ , ... ] - f = flags : [ ] - r = min/max : [ , ] - s = min/max/step : [ , , ] - - 3: u = unset : value is unset, choose from options or default - o = optional : value does not need to be set - r = readonly : value is read only - d = deprecated : value is deprecated - -[ "Format", - [ "video", "raw"], - { - "format" : [ "se", "I420", [ "I420", "YUY2" ] ], - "size" : [ "Rru", [320, 240], [[ 640, 480], [1024,786]]], - "framerate" : [ "Fsu", [25, 1], [[ 0, 1], [65536,1]]]" - } -] - -[ "Format", - [ "audio", "raw"], - { - "format" : [ "se", "S16LE", [ "F32LE", "S16LE" ] ], - "rate" : [ "iru", 44100, [8000, 96000]], - "channels" : [ "iru", 1, [1, 4096]]" - "interleaved" : [ "beo", true ]" - } -] -*/ -#endif - #include -#define STRUCT 0 -#define BARE 1 -#define STRING 2 -#define UTF8 3 -#define ESC 4 - -struct spa_json_iter { - const char *start; - const char *cur; - const char *end; - int state; - int depth; -}; - -struct spa_json_chunk { - const char *value; - int len; -}; - -static inline int -spa_json_chunk_extract(struct spa_json_chunk *chunk, const char *template, ...); - -enum spa_json_type { - SPA_JSON_TYPE_ANY = '-', - SPA_JSON_TYPE_CHUNK = 'c', - SPA_JSON_TYPE_INT = 'i', - SPA_JSON_TYPE_LONG = 'l', - SPA_JSON_TYPE_FLOAT = 'f', - SPA_JSON_TYPE_DOUBLE = 'd', - SPA_JSON_TYPE_STRING = 's', - SPA_JSON_TYPE_BOOL = 'b', - SPA_JSON_TYPE_RECTANGLE = 'R', - SPA_JSON_TYPE_FRACTION = 'F', - SPA_JSON_TYPE_OBJECT = 'o', - SPA_JSON_TYPE_ARRAY = 'a' -}; - -static inline bool spa_json_chunk_is_type(struct spa_json_chunk *chunk, - enum spa_json_type type) -{ - switch (type) { - case SPA_JSON_TYPE_ANY: - case SPA_JSON_TYPE_CHUNK: - return true; - case SPA_JSON_TYPE_INT: - case SPA_JSON_TYPE_LONG: - case SPA_JSON_TYPE_FLOAT: - case SPA_JSON_TYPE_DOUBLE: - return (chunk->value[0] >= '0' && chunk->value[0] <= '9') || - chunk->value[0] == '-' ; - case SPA_JSON_TYPE_STRING: - return chunk->value[0] == '\"'; - case SPA_JSON_TYPE_BOOL: - return chunk->value[0] == 't' || chunk->value[0] == 'f'; - case SPA_JSON_TYPE_RECTANGLE: - case SPA_JSON_TYPE_FRACTION: - case SPA_JSON_TYPE_ARRAY: - return chunk->value[0] == '['; - case SPA_JSON_TYPE_OBJECT: - return chunk->value[0] == '{'; - } - return false; -} - -static inline int spa_json_chunk_to_int(struct spa_json_chunk *chunk) { - return atoi(chunk->value); -} -static inline int64_t spa_json_chunk_to_long(struct spa_json_chunk *chunk) { - return atol(chunk->value); -} -static inline int64_t spa_json_chunk_to_float(struct spa_json_chunk *chunk) { - return strtof(chunk->value, NULL); -} -static inline int64_t spa_json_chunk_to_double(struct spa_json_chunk *chunk) { - return strtod(chunk->value, NULL); -} -static inline bool spa_json_chunk_to_bool(struct spa_json_chunk *chunk) { - return chunk->value[0] == 't'; -} -static inline int spa_json_chunk_to_rectangle(struct spa_json_chunk *chunk, - struct spa_rectangle *rect) { - return spa_json_chunk_extract(chunk, "[ #pi, #pi ]", &rect->width, &rect->height); -} -static inline int spa_json_chunk_to_fraction(struct spa_json_chunk *chunk, - struct spa_fraction *frac) { - return spa_json_chunk_extract(chunk, "[ #pi, #pi ]", &frac->num, &frac->denom); -} - -static inline void -spa_json_iter_init (struct spa_json_iter *iter, const char *data, size_t size) -{ - iter->start = iter->cur = data; - iter->end = size == -1 ? NULL : data + size; - iter->state = STRUCT; - iter->depth = 0; -} - -static inline bool -spa_json_iter_chunk(struct spa_json_iter *iter, struct spa_json_chunk *chunk) -{ - if (!spa_json_chunk_is_type(chunk, SPA_JSON_TYPE_OBJECT) && - !spa_json_chunk_is_type(chunk, SPA_JSON_TYPE_ARRAY)) - return false; - - spa_json_iter_init (iter, chunk->value, -1); - iter->cur++; - return true; -} - -static inline int -spa_json_iter_next_chunk(struct spa_json_iter *iter, struct spa_json_chunk *chunk) -{ - int utf8_remain = 0; - - for (;iter->end == NULL || iter->cur < iter->end; iter->cur++) { - unsigned char cur = (unsigned char) *iter->cur; -again: - switch (iter->state) { - case STRUCT: - switch (cur) { - case '\t': case ' ': case '\r': case '\n': case ':': case ',': - continue; - case '"': - chunk->value = iter->cur; - iter->state = STRING; - continue; - case '[': case '{': - chunk->value = iter->cur; - if (++iter->depth > 1) - continue; - iter->cur++; - return chunk->len = 1; - case '}': case ']': - if (iter->depth == 0) - return 0; - --iter->depth; - continue; - case '-': case 'a' ... 'z': case 'A' ... 'Z': case '0' ... '9': case '#': - chunk->value = iter->cur; - iter->state = BARE; - continue; - case '\0': - return 0; - } - return -1; - case BARE: - switch (cur) { - case '\t': case ' ': case '\r': case '\n': case ':': case ',': - case ']': case '}': - iter->state = STRUCT; - if (iter->depth > 0) - goto again; - return chunk->len = iter->cur - chunk->value; - default: - if (cur >= 32 && cur <= 126) - continue; - } - return -1; - case STRING: - switch (cur) { - case '\\': - iter->state = ESC; - continue; - case '"': - iter->state = STRUCT; - if (iter->depth > 0) - continue; - iter->cur++; - return chunk->len = iter->cur - chunk->value; - case 240 ... 247: - utf8_remain++; - case 224 ... 239: - utf8_remain++; - case 192 ... 223: - utf8_remain++; - iter->state = UTF8; - continue; - default: - if (cur >= 32 && cur <= 126) - continue; - } - return -1; - case UTF8: - switch (cur) { - case 128 ... 191: - if (--utf8_remain == 0) - iter->state = STRING; - continue; - } - return -1; - case ESC: - switch (cur) { - case '"': case '\\': case '/': case 'b': case 'f': case 'n': case 'r': - case 't': case 'u': - iter->state = STRING; - continue; - } - return -1; - } - } - return iter->depth == 0 ? 0 : -1; -} - -static inline void -spa_json_chunk_print(struct spa_json_chunk *chunk, int prefix) -{ - struct spa_json_iter iter; - if (spa_json_iter_chunk(&iter, chunk)) { - struct spa_json_chunk chunk2 = { NULL, }; - - printf ("%-*s%c\n", prefix, "", chunk->value[0]); - while (spa_json_iter_next_chunk(&iter, &chunk2) > 0) - spa_json_chunk_print(&chunk2, prefix + 2); - printf ("%-*s%c\n", prefix, "", iter.cur[0]); - } else { - printf ("%-*s%.*s\n", prefix, "", chunk->len, chunk->value); - } -} - - -static inline int spa_json_iter_find_key(struct spa_json_iter *iter, const char *key) -{ - struct spa_json_chunk ch = { NULL, }; - int res; - - iter->cur = iter->start + 1; - iter->depth = 0; - iter->state = STRUCT; - - while (true) { - /* read key */ - if ((res = spa_json_iter_next_chunk(iter, &ch)) <= 0) - return res; - - if (spa_json_chunk_is_type(&ch, SPA_JSON_TYPE_STRING) && - strncmp(key, ch.value, ch.len) == 0) - return 1; - } - return 0; -} - -enum spa_json_prop_range { - SPA_JSON_PROP_RANGE_NONE = '-', - SPA_JSON_PROP_RANGE_MIN_MAX = 'r', - SPA_JSON_PROP_RANGE_STEP = 's', - SPA_JSON_PROP_RANGE_ENUM = 'e', - SPA_JSON_PROP_RANGE_FLAGS = 'f' -}; - -enum spa_json_prop_flags { - SPA_JSON_PROP_FLAG_UNSET = (1 << 0), - SPA_JSON_PROP_FLAG_OPTIONAL = (1 << 1), - SPA_JSON_PROP_FLAG_READONLY = (1 << 2), - SPA_JSON_PROP_FLAG_DEPRECATED = (1 << 3), -}; - -struct spa_json_prop { - enum spa_json_type type; - enum spa_json_prop_range range; - enum spa_json_prop_flags flags; - struct spa_json_chunk value; - struct spa_json_chunk alternatives; -}; - -static inline int -spa_json_chunk_parse_prop(struct spa_json_chunk *chunk, char type, - struct spa_json_prop *prop) -{ - if (spa_json_chunk_is_type(chunk, SPA_JSON_TYPE_ARRAY)) { - struct spa_json_chunk flags; - int res; - char ch; - - /* [, , [,...]] */ - if ((res = spa_json_chunk_extract(chunk, - "[ #&cs, #&c-, #&ca ]", - &flags, &prop->value, &prop->alternatives)) < 3) { - printf("can't parse prop chunk %d\n", res); - return -1; - } - - /* skip \" */ - flags.value++; - prop->type = *flags.value++; - if (type != SPA_JSON_TYPE_ANY && type != SPA_JSON_TYPE_CHUNK && prop->type != type) { - printf("prop chunk of wrong type %d %d\n", prop->type, type); - return -1; - } - prop->range = *flags.value++; - /* flags */ - prop->flags = 0; - while ((ch = *flags.value++) != '\"') { - switch (ch) { - case 'u': - prop->flags |= SPA_JSON_PROP_FLAG_UNSET; - break; - case 'o': - prop->flags |= SPA_JSON_PROP_FLAG_OPTIONAL; - break; - case 'r': - prop->flags |= SPA_JSON_PROP_FLAG_READONLY; - break; - case 'd': - prop->flags |= SPA_JSON_PROP_FLAG_DEPRECATED; - break; - } - } - } - else { - /* */ - prop->type = type; - prop->range = SPA_JSON_PROP_RANGE_NONE; - prop->flags = 0; - prop->value = *chunk; - prop->alternatives = *chunk; - } - return 0; -} - -/** - * #[*] - * - * * = skip assignment - * is: - * & -> pointer to type - * p -> property, fixed value store in pointer to type - * P -> property, stored in pointer to struct spa_json_prop - * - * - * - -> any - * c -> store as chunk if of type - * s -> string - * i -> int - * l -> long - * f -> float - * d -> double - * b -> bool - * R -> rectangle - * F -> fraction - * a -> array - * o -> object - */ -static inline int -spa_json_chunk_extract(struct spa_json_chunk *chunk, - const char *template, ...) -{ - struct spa_json_iter templ[16], it[16]; - struct spa_json_chunk tch = { NULL, }, ch = { NULL, }; - struct spa_json_prop prop; - const char *match; - int collected = 0, res, level = 0; - va_list args; - bool store; - - va_start(args, template); - - spa_json_iter_init(&it[0], chunk->value, chunk->len); - spa_json_iter_init (&templ[0], template, -1); - - while (true) { - res = spa_json_iter_next_chunk(&templ[level], &tch); - if (res == 0) { - if (--level == 0) - break; - continue; - } else if (res < 0) { - return res; - } - - switch (tch.value[0]) { - case '[': case '{': - if (spa_json_iter_next_chunk(&it[level], &ch) <= 0 || - ch.value[0] != tch.value[0]) - return -1; - if (++level == 16) - return -2; - spa_json_iter_chunk(&it[level], &ch); - spa_json_iter_chunk(&templ[level], &tch); - break; - case '"': - case '-': case '0' ... '9': - case 't': case 'f': - case 'n': - if (templ[level].start[0] == '{') { - if (spa_json_iter_find_key(&it[level], tch.value) <= 0) - continue; - } else if (spa_json_iter_next_chunk(&it[level], &ch) <= 0 || - ch.len != tch.len || - strncmp(ch.value, tch.value, ch.len) != 0) - return -1; - break; - case '#': - match = tch.value + 1; - if (spa_json_iter_next_chunk(&it[level], &ch) <= 0) - return -1; - - store = (match[0] != '*'); - if (!store) - match++; - - switch (match[0]) { - case 'p': - case 'P': - if (spa_json_chunk_parse_prop(&ch, match[1], &prop) < 0) - goto skip; - - if (match[0] == 'P') { - if (store) - *va_arg(args, struct spa_json_prop *) = prop; - collected++; - break; - } - else { - if (prop.flags & SPA_JSON_PROP_FLAG_UNSET) - goto skip; - - ch = prop.value; - } - /* fallthrough */ - case '&': - if (!spa_json_chunk_is_type(&ch, match[1] == SPA_JSON_TYPE_CHUNK ? - match[2] : match[1])) { -skip: - if (store) - va_arg(args, void *); - break; - } - if (!store) - break; - - collected++; - - switch (match[1]) { - case SPA_JSON_TYPE_CHUNK: - *va_arg(args, struct spa_json_chunk *) = ch; - break; - case SPA_JSON_TYPE_INT: - *va_arg(args, int *) = spa_json_chunk_to_int(&ch); - break; - case SPA_JSON_TYPE_LONG: - *va_arg(args, int64_t *) = spa_json_chunk_to_long(&ch); - break; - case SPA_JSON_TYPE_FLOAT: - *va_arg(args, float *) = spa_json_chunk_to_float(&ch); - break; - case SPA_JSON_TYPE_DOUBLE: - *va_arg(args, double *) = spa_json_chunk_to_double(&ch); - break; - case SPA_JSON_TYPE_BOOL: - *va_arg(args, bool *) = spa_json_chunk_to_bool(&ch); - break; - case SPA_JSON_TYPE_RECTANGLE: - spa_json_chunk_to_rectangle(&ch, - va_arg(args, struct spa_rectangle *)); - break; - case SPA_JSON_TYPE_FRACTION: - spa_json_chunk_to_fraction(&ch, - va_arg(args, struct spa_fraction *)); - break; - default: - printf("ignoring invalid #p type %c\n", match[1]); - va_arg(args, void *); - collected--; - continue; - } - break; - default: - printf("ignoring unknown match type %c\n", *match); - break; - } - break; - default: - printf("invalid char %c\n", tch.value[0]); - return -2; - } - } - va_end(args); - - return collected; -} +#include +#include static int spa_json_iter_array(struct spa_json_iter *iter, @@ -749,7 +201,7 @@ static int test_extract3(const char *fmt) struct spa_json_chunk chunk; struct spa_json_chunk media_type; struct spa_json_chunk media_subtype; - struct spa_json_chunk format; + struct spa_json_chunk format = { "*unset*", 7 }; int rate = -1, res; struct spa_json_prop channels; @@ -781,6 +233,35 @@ static int test_extract3(const char *fmt) return 0; } +static int test_builder() +{ + struct spa_json_builder builder = { NULL, 0, }; + int res; + +again: + res = spa_json_builder_printf(&builder, + "[ \"Format\", " + " [ \"audio\", \"raw\"], " + " { " + " \"format\": [ \"seu\", \"S16LE\", [ \"F32LE\", \"S16LE\" ]], " + " \"rate\": %d, " + " \"channels\": %d " + " }" + "]", 48000, 2); + if (res < 0) { + printf("needed %d bytes\n", builder.offset); + builder.data = alloca(builder.offset); + builder.size = builder.offset; + builder.offset = 0; + goto again; + } + printf("have %zd bytes\n", strlen(builder.data)); + + test_extract3(builder.data); + + return 0; +} + int main(int argc, char *argv[]) { struct spa_json_iter iter; @@ -816,5 +297,7 @@ int main(int argc, char *argv[]) " }" "]"); + test_builder(); + return 0; } diff --git a/spa/tests/test-props4.c b/spa/tests/test-props4.c new file mode 100644 index 000000000..a3ef1d1b8 --- /dev/null +++ b/spa/tests/test-props4.c @@ -0,0 +1,861 @@ +/* Spa + * Copyright (C) 2017 Wim Taymans + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#if 0 +/* + ( "Format", + ( "video", "raw" ), + { + "format": ( "seu", "I420", ( "I420", "YUY2" ) ), + "size": ( "Rru", R(320, 242), ( R(1,1), R(MAX, MAX)) ), + "framerate": ( "Fru", F(25, 1), ( F(0,1), F(MAX, 1)) ) + } + ) + + ( struct + { object + [ array + + 1: s = string : "value" + i = int : + l = long : + f = float : + d = double : + b = bool : true | false + R = rectangle : [ , ] + F = fraction : [ , ] + + 2: - = default (only default value present) + e = enum : [ , ... ] + f = flags : [ ] + m = min/max : [ , ] + s = min/max/step : [ , , ] + + 3: u = unset : value is unset, choose from options or default + o = optional : value does not need to be set + r = readonly : value is read only + d = deprecated : value is deprecated +*/ +#endif + +#define SPA_POD_MAX_LEVEL 16 + +struct spa_pod_maker { + struct spa_pod_builder b; + struct spa_pod_frame frame[SPA_POD_MAX_LEVEL]; + int depth; +}; + +static inline void spa_pod_maker_init(struct spa_pod_maker *maker, + char *data, int size) +{ + spa_pod_builder_init(&maker->b, data, size); + maker->depth = 0; +} + +static const struct { + char *pat; + int len; + int64_t val; +} spa_constants[] = { + { "#I_MAX#", strlen("#I_MAX#"), INT32_MAX }, + { "#I_MIN#", strlen("#I_MIN#"), INT32_MIN }, + { "#L_MAX#", strlen("#L_MAX#"), INT64_MAX }, + { "#L_MIN#", strlen("#L_MIN#"), INT64_MIN } +}; + +static inline int64_t spa_parse_int(const char *str, char **endptr) +{ + int i; + + if (*str != '#') + return strtoll(str, endptr, 10); + + for (i = 0; i < SPA_N_ELEMENTS(spa_constants); i++) { + if (strncmp(str, spa_constants[i].pat, spa_constants[i].len) == 0) { + *endptr = (char *) (str + spa_constants[i].len); + return spa_constants[i].val; + } + } + return 0; +} + +static inline int spa_parse_string(const char *str, char **endptr) +{ + int len; + for (*endptr = (char *)str+1; **endptr != '\"' && **endptr != '\0'; (*endptr)++); + len = (*endptr)++ - (str + 1); + return len; +} + +static inline void * +spa_pod_maker_build(struct spa_pod_maker *maker, + const char *format, ...) +{ + va_list args; + const char *start, *strval; + int64_t intval; + double doubleval; + char last; + struct spa_rectangle *rectval; + struct spa_fraction *fracval; + int len; + + va_start(args, format); + while (*format != '\0') { + switch (*format) { + case '[': + spa_pod_builder_push_struct(&maker->b, &maker->frame[maker->depth++]); + break; + case '(': + spa_pod_builder_push_array(&maker->b, &maker->frame[maker->depth++]); + break; + case '{': + spa_pod_builder_push_map(&maker->b, &maker->frame[maker->depth++]); + break; + case ']': case '}': case ')': + spa_pod_builder_pop(&maker->b, &maker->frame[--maker->depth]); + break; + case '\"': + start = format + 1; + if ((len = spa_parse_string(format, (char **) &format)) < 0) + return NULL; + format += strspn(format, " \t\r\n"); + if (*format == ':') + spa_pod_builder_key_len(&maker->b, start, len); + else + spa_pod_builder_string_len(&maker->b, start, len); + continue; + case '@': + case '%': + last = *format; + format++; + switch (*format) { + case 's': + strval = va_arg(args, char *); + spa_pod_builder_string_len(&maker->b, strval, strlen(strval)); + break; + case 'i': + spa_pod_builder_int(&maker->b, va_arg(args, int)); + break; + case 'I': + spa_pod_builder_id(&maker->b, va_arg(args, int)); + break; + case 'l': + spa_pod_builder_long(&maker->b, va_arg(args, int64_t)); + break; + case 'f': + spa_pod_builder_float(&maker->b, va_arg(args, double)); + break; + case 'd': + spa_pod_builder_double(&maker->b, va_arg(args, double)); + break; + case 'b': + spa_pod_builder_bool(&maker->b, va_arg(args, int)); + break; + case 'z': + { + void *ptr = va_arg(args, void *); + int len = va_arg(args, int); + spa_pod_builder_bytes(&maker->b, ptr, len); + break; + } + case 'p': + spa_pod_builder_pointer(&maker->b, 0, va_arg(args, void *)); + break; + case 'h': + spa_pod_builder_fd(&maker->b, va_arg(args, int)); + break; + case 'a': + { + int child_size = va_arg(args, int); + int child_type = va_arg(args, int); + int n_elems = va_arg(args, int); + void *elems = va_arg(args, void *); + spa_pod_builder_array(&maker->b, child_size, child_type, n_elems, elems); + break; + } + case 'P': + spa_pod_builder_primitive(&maker->b, va_arg(args, struct spa_pod *)); + break; + case 'R': + rectval = va_arg(args, struct spa_rectangle *); + spa_pod_builder_rectangle(&maker->b, rectval->width, rectval->height); + break; + case 'F': + fracval = va_arg(args, struct spa_fraction *); + spa_pod_builder_fraction(&maker->b, fracval->num, fracval->denom); + break; + } + if (last == '@') { + format = va_arg(args, const char *); + continue; + } + break; + case '0' ... '9': case '-': case '+': case '#': + start = format; + intval = spa_parse_int(start, (char **) &format); + if (*format == '.') { + doubleval = strtod(start, (char **) &format); + if (*format == 'f') + spa_pod_builder_float(&maker->b, doubleval); + else + spa_pod_builder_double(&maker->b, doubleval); + continue; + } + switch (*format) { + case 'x': + spa_pod_builder_rectangle(&maker->b, intval, + spa_parse_int(format+1, (char **) &format)); + break; + case '/': + spa_pod_builder_fraction(&maker->b, intval, + spa_parse_int(format+1, (char **) &format)); + break; + case 'l': + spa_pod_builder_long(&maker->b, intval); + format++; + break; + default: + spa_pod_builder_int(&maker->b, intval); + break; + } + continue; + } + format++; + } + va_end(args); + + return SPA_POD_BUILDER_DEREF(&maker->b, maker->frame[maker->depth].ref, void); +} + +static inline int spa_pod_id_to_type(char id) +{ + switch (id) { + case 'n': + return SPA_POD_TYPE_NONE; + case 'b': + return SPA_POD_TYPE_BOOL; + case 'I': + return SPA_POD_TYPE_ID; + case 'i': + return SPA_POD_TYPE_INT; + case 'l': + return SPA_POD_TYPE_LONG; + case 'f': + return SPA_POD_TYPE_FLOAT; + case 'd': + return SPA_POD_TYPE_DOUBLE; + case 's': + return SPA_POD_TYPE_STRING; + case 'k': + return SPA_POD_TYPE_KEY; + case 'z': + return SPA_POD_TYPE_BYTES; + case 'R': + return SPA_POD_TYPE_RECTANGLE; + case 'F': + return SPA_POD_TYPE_FRACTION; + case 'B': + return SPA_POD_TYPE_BITMASK; + case 'A': + return SPA_POD_TYPE_ARRAY; + case 'S': + return SPA_POD_TYPE_STRUCT; + case 'O': + return SPA_POD_TYPE_OBJECT; + case 'M': + return SPA_POD_TYPE_MAP; + case 'p': + return SPA_POD_TYPE_POINTER; + case 'h': + return SPA_POD_TYPE_FD; + case 'V': case 'v': + return SPA_POD_TYPE_PROP; + case 'P': + return SPA_POD_TYPE_POD; + default: + return SPA_POD_TYPE_INVALID; + } +} + +enum spa_pod_prop_range { + SPA_POD_PROP2_RANGE_NONE = '-', + SPA_POD_PROP2_RANGE_MIN_MAX = 'r', + SPA_POD_PROP2_RANGE_STEP = 's', + SPA_POD_PROP2_RANGE_ENUM = 'e', + SPA_POD_PROP2_RANGE_FLAGS = 'f' +}; + +enum spa_pod_prop_flags { + SPA_POD_PROP2_FLAG_UNSET = (1 << 0), + SPA_POD_PROP2_FLAG_OPTIONAL = (1 << 1), + SPA_POD_PROP2_FLAG_READONLY = (1 << 2), + SPA_POD_PROP2_FLAG_DEPRECATED = (1 << 3), +}; + +struct spa_pod_prop2 { + enum spa_pod_type type; + enum spa_pod_prop_range range; + enum spa_pod_prop_flags flags; + struct spa_pod *value; + struct spa_pod *alternatives; +}; + +static inline int spa_pod_match(struct spa_pod *pod, const char *templ, ...); + + +static inline int +spa_pod_parse_prop(struct spa_pod *pod, enum spa_pod_type type, struct spa_pod_prop2 *prop) +{ + int res; + + if (SPA_POD_TYPE(pod) == SPA_POD_TYPE_STRUCT) { + const char *flags; + char ch; + + if ((res = spa_pod_match(pod, + "[ %s, %P, %P ]", + &flags, + &prop->value, + &prop->alternatives)) < 0) { + printf("can't parse prop chunk %d\n", res); + return res; + } + prop->type = spa_pod_id_to_type(*flags++); + if (type != SPA_POD_TYPE_POD && type != SPA_POD_TYPE(prop->value)) { + printf("prop chunk of wrong type %d != %d\n", SPA_POD_TYPE(prop->value), type); + return -1; + } + prop->range = *flags++; + /* flags */ + prop->flags = 0; + while ((ch = *flags++) != '\0') { + switch (ch) { + case 'u': + prop->flags |= SPA_POD_PROP2_FLAG_UNSET; + break; + case 'o': + prop->flags |= SPA_POD_PROP2_FLAG_OPTIONAL; + break; + case 'r': + prop->flags |= SPA_POD_PROP2_FLAG_READONLY; + break; + case 'd': + prop->flags |= SPA_POD_PROP2_FLAG_DEPRECATED; + break; + } + } + } + else { + /* a single value */ + if (type != SPA_POD_TYPE_POD && type != SPA_POD_TYPE(pod)) { + printf("prop chunk of wrong type %d != %d\n", SPA_POD_TYPE(prop->value), type); + return -1; + } + prop->type = SPA_POD_TYPE(pod); + prop->range = SPA_POD_PROP2_RANGE_NONE; + prop->flags = 0; + prop->value = pod; + prop->alternatives = pod; + } + return 0; +} + +static inline int +spa_pod_match(struct spa_pod *pod, + const char *templ, ...) +{ + struct spa_pod_iter it[SPA_POD_MAX_LEVEL]; + int depth = 0, collected = 0; + va_list args; + const char *start; + int64_t intval, int2val; + double doubleval; + char last; + struct spa_rectangle *rectval; + struct spa_fraction *fracval; + int type, len; + struct spa_pod *current = pod; + struct spa_pod_prop2 prop; + bool store, maybe; + + va_start(args, templ); + while (*templ != '\0') { + switch (*templ) { + case '[': + depth++; + if (current == NULL || + !spa_pod_iter_struct(&it[depth], current, SPA_POD_SIZE(current))) + goto done; + break; + case '(': + break; + case '{': + depth++; + if (current == NULL || + !spa_pod_iter_map(&it[depth], current, SPA_POD_SIZE(current))) + goto done; + break; + case ']': case '}': case ')': + if (depth == 0) + return -1; + if (--depth == 0) + goto done; + break; + case '\"': + start = templ + 1; + if ((len = spa_parse_string(templ, (char **) &templ)) < 0) + return -1; + templ += strspn(templ, " \t\r\n"); + if (*templ == ':') { + if (SPA_POD_TYPE(it[depth].data) != SPA_POD_TYPE_MAP) + return -1; + it[depth].offset = sizeof(struct spa_pod_map); + /* move to key */ + while (spa_pod_iter_has_next(&it[depth])) { + current = spa_pod_iter_next(&it[depth]); + if (SPA_POD_TYPE(current) == SPA_POD_TYPE_KEY && + strncmp(SPA_POD_CONTENTS_CONST(struct spa_pod_key, current), + start, len) == 0) + break; + current = NULL; + } + } + else { + if (current == NULL || SPA_POD_TYPE(current) != SPA_POD_TYPE_STRING || + strncmp(SPA_POD_CONTENTS_CONST(struct spa_pod_string, current), + start, len) != 0) + goto done; + } + break; + case '@': + case '%': + last = *templ; + if (*++templ == '\0') + return -1; + + store = *templ != '*'; + if (!store) + if (*++templ == '\0') + return -1; + + maybe = *templ == '?'; + if (maybe) + if (*++templ == '\0') + return -1; + + if (*templ == 'V' || *templ == 'v') { + char t = *templ; + templ++; + type = spa_pod_id_to_type(*templ); + + if (current == NULL) + goto no_current; + + if (spa_pod_parse_prop(current, type, &prop) < 0) + return -1; + + if (t == 'v') { + if (prop.flags & SPA_POD_PROP2_FLAG_UNSET) { + if (store) + va_arg(args, void *); + goto skip; + } + else + current = prop.value; + } + else { + collected++; + *va_arg(args, struct spa_pod_prop2 *) = prop; + goto skip; + } + } + + no_current: + type = spa_pod_id_to_type(*templ); + if (current == NULL || (type != SPA_POD_TYPE_POD && type != SPA_POD_TYPE(current))) { + if (!maybe) + return -1; + if (store) + va_arg(args, void *); + goto skip; + } + if (!store) + goto skip; + + collected++; + + switch (*templ) { + case 'n': case 'A': case 'S': case 'O': case 'M': case 'P': + *va_arg(args, struct spa_pod **) = current; + break; + case 'b': + case 'i': + case 'I': + *va_arg(args, int32_t *) = SPA_POD_VALUE(struct spa_pod_int, current); + break; + case 'l': + *va_arg(args, int64_t *) = SPA_POD_VALUE(struct spa_pod_long, current); + break; + case 'f': + *va_arg(args, float *) = SPA_POD_VALUE(struct spa_pod_float, current); + break; + case 'd': + *va_arg(args, double *) = SPA_POD_VALUE(struct spa_pod_double, current); + break; + case 's': + case 'k': + *va_arg(args, char **) = SPA_POD_CONTENTS(struct spa_pod_string, current); + break; + case 'z': + *va_arg(args, void **) = SPA_POD_CONTENTS(struct spa_pod_bytes, current); + *va_arg(args, uint32_t *) = SPA_POD_BODY_SIZE(current); + break; + case 'R': + *va_arg(args, struct spa_rectangle *) = + SPA_POD_VALUE(struct spa_pod_rectangle, current); + break; + case 'F': + *va_arg(args, struct spa_fraction *) = + SPA_POD_VALUE(struct spa_pod_fraction, current); + break; + case 'p': + { + struct spa_pod_pointer_body *b = SPA_POD_BODY(current); + *va_arg(args, void **) = b->value; + break; + } + case 'h': + *va_arg(args, int *) = SPA_POD_VALUE(struct spa_pod_fd, current); + break; + default: + va_arg(args, void *); + break; + } + + skip: + if (last == '@') { + templ = va_arg(args, void *); + goto next; + } + break; + case '0' ... '9': case '-': case '+': case '#': + start = templ; + intval = spa_parse_int(start, (char **) &templ); + if (*templ == '.') { + doubleval = strtod(start, (char **) &templ); + if (*templ == 'f') { + if (current == NULL || + SPA_POD_TYPE(current) != SPA_POD_TYPE_FLOAT || + doubleval != SPA_POD_VALUE(struct spa_pod_float, current)) + goto done; + break; + } + else if (current == NULL || + SPA_POD_TYPE(current) != SPA_POD_TYPE_DOUBLE || + doubleval != SPA_POD_VALUE(struct spa_pod_double, current)) + goto done; + goto next; + } + switch (*templ) { + case 'x': + if (current == NULL || + SPA_POD_TYPE(current) != SPA_POD_TYPE_RECTANGLE) + goto done; + + rectval = &SPA_POD_VALUE(struct spa_pod_rectangle, current); + int2val = spa_parse_int(templ+1, (char **) &templ); + if (rectval->width != intval || rectval->height != int2val) + goto done; + goto next; + case '/': + if (current == NULL || + SPA_POD_TYPE(current) != SPA_POD_TYPE_FRACTION) + goto done; + + fracval = &SPA_POD_VALUE(struct spa_pod_fraction, current); + int2val = spa_parse_int(templ+1, (char **) &templ); + if (fracval->num != intval || fracval->denom != int2val) + goto done; + goto next; + case 'l': + if (current == NULL || + SPA_POD_TYPE(current) != SPA_POD_TYPE_LONG || + SPA_POD_VALUE(struct spa_pod_long, current) != intval) + goto done; + break; + default: + if (current == NULL || + SPA_POD_TYPE(current) != SPA_POD_TYPE_INT || + SPA_POD_VALUE(struct spa_pod_int, current) != intval) + goto done; + break; + } + break; + case ' ': case '\n': case '\t': case '\r': case ',': + templ++; + continue; + } + templ++; + + next: + if (spa_pod_iter_has_next(&it[depth])) + current = spa_pod_iter_next(&it[depth]); + else + current = NULL; + } + va_end(args); + + done: + return collected; +} + +static int test_match(const char *fmt) +{ + const char *media_type, *media_subtype, *format; + int rate = -1, res; + struct spa_pod_prop2 channels; + struct spa_pod *pod; + struct spa_pod_maker m = { 0, }; + char buffer[4096]; + + spa_pod_maker_init(&m, buffer, sizeof(buffer)); + pod = spa_pod_maker_build(&m, fmt); + spa_debug_pod(pod); + + res = spa_pod_match(pod, + "[ \"Format\", " + " [ @s",&media_type," @s",&media_subtype," ], " + " { " + " \"rate\": @vi", &rate, + " \"format\": @vs", &format, + " \"channels\": @VP", &channels, + " \"foo\": @?VP", &channels, + " } " + "]"); + + printf("collected %d\n", res); + printf("media type %s\n", media_type); + printf("media subtype %s\n", media_subtype); + printf("media rate %d\n", rate); + printf("media format %s\n", format); + printf("media channels: %d %c %04x\n",channels.type, channels.range, channels.flags); + spa_debug_pod(channels.value); + spa_debug_pod(channels.alternatives); + return 0; +} + +int main(int argc, char *argv[]) +{ + struct spa_pod_maker m = { 0, }; + char buffer[4096]; + struct spa_pod *fmt; + + spa_pod_maker_init(&m, buffer, sizeof(buffer)); + fmt = spa_pod_maker_build(&m, + "[ \"Format\", " + " [\"video\", \"raw\" ], " + " { " + " \"format\": [ \"eu\", \"I420\", [ \"I420\",\"YUY2\" ] ], " + " \"size\": [ \"ru\", 320x242, [ 1x1, #I_MAX#x#I_MAX# ] ], " + " \"framerate\": [ \"ru\", 25/1, [ 0/1, #I_MAX#/1 ] ] " + " } " + "] "); + spa_debug_pod(fmt); + + spa_pod_maker_init(&m, buffer, sizeof(buffer)); + fmt = spa_pod_maker_build(&m, + "[ \"Format\", " + " [\"video\", %s ], " + " { " + " \"format\": [ \"eu\", \"I420\", [ %s, \"YUY2\" ] ], " + " \"size\": [ \"ru\", 320x242, [ %R, #I_MAX#x#I_MAX# ] ], " + " \"framerate\": [ \"ru\", %F, [ 0/1, #I_MAX#/1 ] ] " + " } " + "] ", + "raw", + "I420", + &(struct spa_rectangle){ 1, 1 }, + &(struct spa_fraction){ 25, 1 } + ); + spa_debug_pod(fmt); + + { + const char *format = "S16"; + int rate = 44100, channels = 2; + + spa_pod_maker_init(&m, buffer, sizeof(buffer)); + fmt = spa_pod_maker_build(&m, + "[ \"Format\", " + " [\"audio\", \"raw\" ], " + " { " + " \"format\": [@s", format, "] " + " \"rate\": [@i", rate, "] " + " \"channels\": [@i", channels, "] " + " \"rect\": [@R", &SPA_RECTANGLE(32, 22), "] " + " } " + "] "); + spa_debug_pod(fmt); + } + + { + const char *format = "S16"; + int rate = 44100, channels = 2; + struct spa_rectangle rects[3] = { { 1, 1 }, { 2, 2}, {3, 3}}; + struct spa_pod_int pod = SPA_POD_INT_INIT(12); + uint8_t bytes[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; + + spa_pod_maker_init(&m, buffer, sizeof(buffer)); + spa_pod_maker_build(&m, + "[ \"Format\", " + " [\"audio\", \"raw\" ], "); + fmt = spa_pod_maker_build(&m, + " { " + " \"format\": [ %s ] " + " \"rate\": [ %i, ( 44100, 48000, 96000 ) ]" + " \"foo\": %i, ( 1.1, 2.2, 3.2 )" + " \"baz\": ( 1.1f, 2.2f, 3.2f )" + " \"bar\": ( 1x1, 2x2, 3x2 )" + " \"faz\": ( 1/1, 2/2, 3/2 )" + " \"wha\": %a, " + " \"fuz\": %P, " +// " \"fur\": ( (1, 2), (7, 8), (7, 5) ) " +// " \"fur\": ( [1, 2], [7, 8], [7, 5] ) " + " \"buz\": %z, " + " \"boo\": %p, " + " \"foz\": %h, " + " } " + "] ", format, rate, channels, + sizeof(struct spa_rectangle), SPA_POD_TYPE_RECTANGLE, 3, rects, + &pod, + bytes, sizeof(bytes), + fmt, + STDOUT_FILENO); + spa_debug_pod(fmt); + } + + spa_pod_maker_init(&m, buffer, sizeof(buffer)); + fmt = spa_pod_maker_build(&m, + "[ \"Format\", " + " [\"video\", %s ], " + " { " + " \"format\": [ \"eu\", \"I420\", [ %s, \"YUY2\" ] ], " + " \"size\": [ \"ru\", 320x242, [ %R, #I_MAX#x#I_MAX# ] ], " + " \"framerate\": [ \"ru\", %F, [ 0/1, #I_MAX#/1 ] ] " + " } " + "] ", + "raw", + "I420", + &(struct spa_rectangle){ 1, 1 }, + &(struct spa_fraction){ 25, 1 } + ); + spa_debug_pod(fmt); + + { + const char *subtype = NULL, *format = NULL; + struct spa_pod *pod = NULL; + struct spa_rectangle rect = { 0, 0 }; + struct spa_fraction frac = { 0, 0 }; + int res; + + res = spa_pod_match(fmt, + "[ \"Format\", " + " [\"video\", %s ], " + " { " + " \"format\": [ %*s, %*s, [ %s, %*s ] ], " + " \"size\": [ \"ru\", 320x242, [ %R, %P ] ], " + " \"framerate\": [ %*P, %F, %*S ] " + " } " + "] ", + &subtype, + &format, + &rect, + &pod, + &frac); + + printf("collected %d\n", res); + printf("media type %s\n", subtype); + printf("media format %s\n", format); + printf("media size %dx%d\n", rect.width, rect.height); + printf("media size pod\n"); + spa_debug_pod(pod); + printf("media framerate %d/%d\n", frac.num, frac.denom); + + res = spa_pod_match(fmt, + "[ \"Format\", " + " [\"video\", @s", &subtype, " ], " + " { " + " \"format\": [ %*s, %*s, [ @s", &format, ", %*s ] ], " + " \"size\": [ \"ru\", 320x242, [ @R",&rect,", @P",&pod," ] ], " + " \"framerate\": [ %*P, @F",&frac,", %*S ] " + " } " + "] "); + + printf("collected %d\n", res); + printf("media type %s\n", subtype); + printf("media format %s\n", format); + printf("media size %dx%d\n", rect.width, rect.height); + printf("media size pod\n"); + spa_debug_pod(pod); + printf("media framerate %d/%d\n", frac.num, frac.denom); + + res = spa_pod_match(fmt, + "[ \"Format\", " + " [\"video\", @s", &subtype, " ], " + " { " + " \"format\": [ %*s, %*s, [ @s", &format, ", %*s ] ], " + " \"size\": [ \"ru\", 320x242, [ @R",&rect,", @P",&pod," ] ], " + " \"framerate\": [ %*P, @F",&frac,", %*S ] " + " } " + "] "); + + } + + test_match("[ \"Format\", " + " [\"audio\", \"raw\" ], " + " { " + " \"format\": [ \"se\", \"S16\", [ \"S16\", \"F32\" ] ], " + " \"rate\": [ \"iru\", 44100, [ 1, 192000 ] ], " + " \"channels\": [ \"ir\", 2, [ 1, #I_MAX# ]] " + " } " + "] "); + + test_match( + "[ \"Format\", " + " [ \"audio\", \"raw\"], " + " { " + " \"format\": \"S16LE\", " + " \"rate\": 44100, " + " \"channels\": 2 " + " }" + "]"); + + return 0; +} diff --git a/spa/tests/test-props5.c b/spa/tests/test-props5.c new file mode 100644 index 000000000..ad9080ecb --- /dev/null +++ b/spa/tests/test-props5.c @@ -0,0 +1,92 @@ +/* Spa + * Copyright (C) 2017 Wim Taymans + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + char buffer[4096]; + struct spa_pod_builder b = { 0, }; + struct spa_pod_parser prs; + struct spa_pod *fmt, *pod = NULL, *pod2 = NULL; + uint32_t format = 1, video = 2, raw = 3; + uint32_t size = 4, framerate = 5, I420 = 6, YUY2 = 7; + uint32_t media_type = -1, media_subtype = -1; + uint32_t fmt_value = -1; + int res; + + spa_pod_builder_init(&b, buffer, sizeof(buffer)); + fmt = spa_pod_builder_add(&b, + "<",0,format, + " [ i", video, "i",raw,"]" + " :", format, "ieu", I420, + 2, I420, YUY2, + " :", size, "Rru", &SPA_RECTANGLE(320,240), + 2, &SPA_RECTANGLE(1,1), + &SPA_RECTANGLE(INT32_MAX, INT32_MAX), + " :", framerate, "Fru", &SPA_FRACTION(25,1), + 2, &SPA_FRACTION(0,1), + &SPA_FRACTION(INT32_MAX, 1), + ">", NULL); + spa_debug_pod(fmt); + + spa_pod_parser_pod(&prs, fmt); + res = spa_pod_parser_get(&prs, + "<" + " [ i",&media_type,"*i"/*,&media_subtype,*/" ]" + " :", framerate, "V", &pod, + " :", 10, "?V", &pod2, + " :", format, "?i", &fmt_value, + ">", NULL); + + printf("res :%d\n", res); + printf("media-type:%d media-subtype:%d\n", media_type, media_subtype); + printf("framerate:\n"); + if (pod) + spa_debug_pod(pod); + printf("format: %d\n", fmt_value); + + spa_pod_builder_init(&b, buffer, sizeof(buffer)); + pod = spa_pod_builder_add(&b, + "<",0,format, + " P", NULL, + " [ i", 44, "i",45,"]" + ">", NULL); + spa_debug_pod(pod); + + spa_pod_parser_pod(&prs, pod); + res = spa_pod_parser_get(&prs, + "<" + " ?[ i",&media_type,"i",&media_subtype," ]" + " [ i", &video, "i",&raw,"]" + ">", NULL); + printf("res :%d\n", res); + printf("video:%d raw:%d\n", video, raw); + + return 0; +} diff --git a/spa/tests/test-ringbuffer.c b/spa/tests/test-ringbuffer.c index 4eb027f68..897b4afa2 100644 --- a/spa/tests/test-ringbuffer.c +++ b/spa/tests/test-ringbuffer.c @@ -277,7 +277,6 @@ static int make_nodes(struct data *data, const char *device) int res; struct spa_props *props; struct spa_pod_builder b = { 0 }; - struct spa_pod_frame f[2]; uint8_t buffer[128]; if ((res = make_node(data, &data->sink, @@ -288,12 +287,10 @@ static int make_nodes(struct data *data, const char *device) spa_node_set_callbacks(data->sink, &sink_callbacks, data); spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_props(&b, &f[0], data->type.props, - SPA_POD_PROP(&f[1], data->type.props_device, 0, SPA_POD_TYPE_STRING, 1, - device ? device : "hw:0"), - SPA_POD_PROP(&f[1], data->type.props_min_latency, 0, SPA_POD_TYPE_INT, 1, - 64)); - props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + props = spa_pod_builder_props(&b, + data->type.props, + ":", data->type.props_device, "s", device ? device : "hw:0", + ":", data->type.props_min_latency, "i", 64); if ((res = spa_node_set_props(data->sink, props)) < 0) printf("got set_props error %d\n", res); @@ -306,10 +303,9 @@ static int make_nodes(struct data *data, const char *device) } spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_props(&b, &f[0], data->type.props, - SPA_POD_PROP(&f[1], data->type.props_live, 0, SPA_POD_TYPE_BOOL, 1, - false)); - props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + props = spa_pod_builder_props(&b, + data->type.props, + ":", data->type.props_live, "b", false); if ((res = spa_node_set_props(data->source, props)) < 0) printf("got set_props error %d\n", res); @@ -322,22 +318,16 @@ static int negotiate_formats(struct data *data) struct spa_format *format, *filter; uint32_t state = 0; struct spa_pod_builder b = { 0 }; - struct spa_pod_frame f[2]; uint8_t buffer[256]; spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_format(&b, &f[0], data->type.format, - data->type.media_type.audio, - data->type.media_subtype.raw, - SPA_POD_PROP(&f[1], data->type.format_audio.format, 0, SPA_POD_TYPE_ID, 1, - data->type.audio_format.S16), - SPA_POD_PROP(&f[1], data->type.format_audio.layout, 0, SPA_POD_TYPE_INT, 1, - SPA_AUDIO_LAYOUT_INTERLEAVED), - SPA_POD_PROP(&f[1], data->type.format_audio.rate, 0, SPA_POD_TYPE_INT, 1, - 44100), - SPA_POD_PROP(&f[1], data->type.format_audio.channels, 0, SPA_POD_TYPE_INT, 1, - 2)); - filter = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + filter = spa_pod_builder_format(&b, + data->type.format, + data->type.media_type.audio, data->type.media_subtype.raw, + ":", data->type.format_audio.format, "I", data->type.audio_format.S16, + ":", data->type.format_audio.layout, "i", SPA_AUDIO_LAYOUT_INTERLEAVED, + ":", data->type.format_audio.rate, "i", 44100, + ":", data->type.format_audio.channels, "i", 2); if ((res = spa_node_port_enum_formats(data->sink, SPA_DIRECTION_INPUT, 0, &format, filter, diff --git a/spa/tests/test-v4l2.c b/spa/tests/test-v4l2.c index 9f76ea280..e7264ae76 100644 --- a/spa/tests/test-v4l2.c +++ b/spa/tests/test-v4l2.c @@ -299,7 +299,6 @@ static int make_nodes(struct data *data, const char *device) int res; struct spa_props *props; struct spa_pod_builder b = { 0 }; - struct spa_pod_frame f[2]; uint8_t buffer[256]; if ((res = @@ -312,10 +311,9 @@ static int make_nodes(struct data *data, const char *device) spa_node_set_callbacks(data->source, &source_callbacks, data); spa_pod_builder_init(&b, buffer, sizeof(buffer)); - spa_pod_builder_props(&b, &f[0], data->type.props, - SPA_POD_PROP(&f[1], data->type.props_device, 0, SPA_POD_TYPE_STRING, 1, - device ? device : "/dev/video0")); - props = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_props); + props = spa_pod_builder_props(&b, + data->type.props, + ":", data->type.props_device, "s", device ? device : "/dev/video0"); if ((res = spa_node_set_props(data->source, props)) < 0) printf("got set_props error %d\n", res); @@ -389,7 +387,6 @@ static int negotiate_formats(struct data *data) int res; const struct spa_port_info *info; struct spa_format *format; - struct spa_pod_frame f[2]; uint8_t buffer[256]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); @@ -407,17 +404,12 @@ static int negotiate_formats(struct data *data) return res; #else - spa_pod_builder_format(&b, &f[0], data->type.format, - data->type.media_type.video, data->type.media_subtype.raw, - SPA_POD_PROP(&f[1], data->type.format_video.format, 0, - SPA_POD_TYPE_ID, 1, - data->type.video_format.YUY2), - SPA_POD_PROP(&f[1], data->type.format_video.size, 0, - SPA_POD_TYPE_RECTANGLE, 1, - 320, 240), - SPA_POD_PROP(&f[1], data->type.format_video.framerate, 0, - SPA_POD_TYPE_FRACTION, 1, 25, 1)); - format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + format = spa_pod_builder_format(&b, + data->type.format, + data->type.media_type.video, data->type.media_subtype.raw, + ":", data->type.format_video.format, "I", data->type.video_format.YUY2, + ":", data->type.format_video.size, "R", &SPA_RECTANGLE(320, 240), + ":", data->type.format_video.framerate, "F", &SPA_FRACTION(25,1)); #endif if ((res = spa_node_port_set_format(data->source, SPA_DIRECTION_OUTPUT, 0, 0, format)) < 0) diff --git a/src/examples/export-sink.c b/src/examples/export-sink.c index 473f495ce..33ad66fd3 100644 --- a/src/examples/export-sink.c +++ b/src/examples/export-sink.c @@ -177,12 +177,6 @@ static Uint32 id_to_sdl_format(struct data *data, uint32_t id) return SDL_PIXELFORMAT_UNKNOWN; } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) - static int impl_send_command(struct spa_node *node, const struct spa_command *command) { return SPA_RESULT_OK; @@ -233,7 +227,6 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire uint32_t index) { struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node); - const struct spa_format *formats[1]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer)); struct spa_pod_frame f[2]; SDL_RendererInfo info; @@ -268,19 +261,18 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire } spa_pod_builder_pop(&b, &f[1]); spa_pod_builder_add(&b, - PROP_U_MM(&f[1], d->type.format_video.size, SPA_POD_TYPE_RECTANGLE, - WIDTH, HEIGHT, - 1, 1, info.max_texture_width, info.max_texture_height), - PROP_U_MM(&f[1], d->type.format_video.framerate, SPA_POD_TYPE_FRACTION, - 25, 1, - 0, 1, 30, 1), - 0); + ":", d->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT), + 2, &SPA_RECTANGLE(1,1), + &SPA_RECTANGLE(info.max_texture_width, + info.max_texture_height), + ":", d->type.format_video.framerate, "Fru", &SPA_FRACTION(25,1), + 2, &SPA_FRACTION(0,1), + &SPA_FRACTION(30,1), + NULL); spa_pod_builder_pop(&b, &f[0]); - formats[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); - spa_debug_format(formats[0]); - - *format = (struct spa_format *)formats[0]; + spa_debug_format(*format); return SPA_RESULT_OK; } @@ -291,7 +283,6 @@ static int impl_port_set_format(struct spa_node *node, enum spa_direction direct struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node); struct pw_type *t = d->t; struct spa_pod_builder b = { NULL }; - struct spa_pod_frame f[2]; Uint32 sdl_format; void *dest; @@ -315,24 +306,18 @@ static int impl_port_set_format(struct spa_node *node, enum spa_direction direct SDL_UnlockTexture(d->texture); spa_pod_builder_init(&b, d->params_buffer, sizeof(d->params_buffer)); - spa_pod_builder_object(&b, &f[0], 0, t->param_alloc_buffers.Buffers, - PROP(&f[1], t->param_alloc_buffers.size, SPA_POD_TYPE_INT, - d->stride * d->format.size.height), - PROP(&f[1], t->param_alloc_buffers.stride, SPA_POD_TYPE_INT, - d->stride), - PROP_U_MM(&f[1], t->param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 32, - 2, 32), - PROP(&f[1], t->param_alloc_buffers.align, SPA_POD_TYPE_INT, - 16)); - d->params[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); + d->params[0] = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "i", d->stride * d->format.size.height, + ":", t->param_alloc_buffers.stride, "i", d->stride, + ":", t->param_alloc_buffers.buffers, "iru", 32, + 2, 2, 32, + ":", t->param_alloc_buffers.align, "i", 16); - spa_pod_builder_object(&b, &f[0], 0, t->param_alloc_meta_enable.MetaEnable, - PROP(&f[1], t->param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - t->meta.Header), - PROP(&f[1], t->param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); - d->params[1] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); + d->params[1] = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); return SPA_RESULT_OK; } @@ -342,18 +327,13 @@ static int impl_port_get_format(struct spa_node *node, enum spa_direction direct { struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node); struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer)); - struct spa_pod_frame f[2]; - spa_pod_builder_push_format(&b, &f[0], d->type.format, - d->type.media_type.video, - d->type.media_subtype.raw); - spa_pod_builder_add(&b, - PROP(&f[1], d->type.format_video.format, SPA_POD_TYPE_ID, d->format.format), - PROP(&f[1], d->type.format_video.size, SPA_POD_TYPE_RECTANGLE, &d->format.size), - PROP(&f[1], d->type.format_video.framerate, SPA_POD_TYPE_FRACTION, &d->format.framerate), - 0); - spa_pod_builder_pop(&b, &f[0]); - *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = spa_pod_builder_format(&b, d->type.format, + d->type.media_type.video, + d->type.media_subtype.raw, + ":", d->type.format_video.format, "I", d->format.format, + ":", d->type.format_video.size, "R", &d->format.size, + ":", d->type.format_video.framerate, "F", &d->format.framerate); return SPA_RESULT_OK; } diff --git a/src/examples/export-source.c b/src/examples/export-source.c index a984e3156..3840c55e9 100644 --- a/src/examples/export-source.c +++ b/src/examples/export-source.c @@ -98,12 +98,6 @@ struct data { double accumulator; }; -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) - static int impl_send_command(struct spa_node *node, const struct spa_command *command) { return SPA_RESULT_OK; @@ -155,21 +149,15 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire { struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node); struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer)); - struct spa_pod_frame f[2]; if (index != 0) return SPA_RESULT_ENUM_END; - spa_pod_builder_push_format(&b, &f[0], d->type.format, - d->type.media_type.audio, - d->type.media_subtype.raw); - spa_pod_builder_add(&b, - PROP(&f[1], d->type.format_audio.format, SPA_POD_TYPE_ID, d->type.audio_format.S16), - PROP(&f[1], d->type.format_audio.channels, SPA_POD_TYPE_INT, 2), - PROP(&f[1], d->type.format_audio.rate, SPA_POD_TYPE_INT, 44100), - 0); - spa_pod_builder_pop(&b, &f[0]); - *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = spa_pod_builder_format(&b, d->type.format, + d->type.media_type.audio, d->type.media_subtype.raw, + ":", d->type.format_audio.format, "I", d->type.audio_format.S16, + ":", d->type.format_audio.channels, "i", 2, + ":", d->type.format_audio.rate, "i", 44100); spa_debug_format(*format); @@ -182,31 +170,32 @@ static int impl_port_set_format(struct spa_node *node, enum spa_direction direct struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node); struct pw_type *t = d->t; struct spa_pod_builder b = { NULL }; - struct spa_pod_frame f[2]; if (format == NULL) return SPA_RESULT_OK; spa_debug_format(format); - spa_format_audio_raw_parse(format, &d->format, &d->type.format_audio); + if (spa_format_audio_raw_parse(format, &d->format, &d->type.format_audio) < 0) + return SPA_RESULT_INVALID_MEDIA_TYPE; if (d->format.format != d->type.audio_format.S16) return SPA_RESULT_ERROR; spa_pod_builder_init(&b, d->params_buffer, sizeof(d->params_buffer)); - spa_pod_builder_object(&b, &f[0], 0, t->param_alloc_buffers.Buffers, - PROP_U_MM(&f[1], t->param_alloc_buffers.size, SPA_POD_TYPE_INT, 1024, 32, 4096), - PROP (&f[1], t->param_alloc_buffers.stride, SPA_POD_TYPE_INT, 0), - PROP_U_MM(&f[1], t->param_alloc_buffers.buffers, SPA_POD_TYPE_INT, 2, 2, 32), - PROP (&f[1], t->param_alloc_buffers.align, SPA_POD_TYPE_INT, 16)); - d->params[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); + d->params[0] = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "iru", 1024, + 2, 32, 4096, + ":", t->param_alloc_buffers.stride, "i", 0, + ":", t->param_alloc_buffers.buffers, "iru", 2, + 2, 2, 32, + ":", t->param_alloc_buffers.align, "i", 16); - spa_pod_builder_object(&b, &f[0], 0, t->param_alloc_meta_enable.MetaEnable, - PROP(&f[1], t->param_alloc_meta_enable.type, SPA_POD_TYPE_ID, t->meta.Header), - PROP(&f[1], t->param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); - d->params[1] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); + d->params[1] = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); return SPA_RESULT_OK; } @@ -216,18 +205,12 @@ static int impl_port_get_format(struct spa_node *node, enum spa_direction direct { struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node); struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer)); - struct spa_pod_frame f[2]; - spa_pod_builder_push_format(&b, &f[0], d->type.format, - d->type.media_type.audio, - d->type.media_subtype.raw); - spa_pod_builder_add(&b, - PROP(&f[1], d->type.format_audio.format, SPA_POD_TYPE_ID, d->format.format), - PROP(&f[1], d->type.format_audio.channels, SPA_POD_TYPE_INT, d->format.channels), - PROP(&f[1], d->type.format_audio.rate, SPA_POD_TYPE_INT, d->format.rate), - 0); - spa_pod_builder_pop(&b, &f[0]); - *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = spa_pod_builder_format(&b, d->type.format, + d->type.media_type.audio, d->type.media_subtype.raw, + ":", d->type.format_audio.format, "I", d->format.format, + ":", d->type.format_audio.channels, "i", d->format.channels, + ":", d->type.format_audio.rate, "i", d->format.rate); return SPA_RESULT_OK; } diff --git a/src/examples/local-v4l2.c b/src/examples/local-v4l2.c index 73d4387ff..d1f1a6092 100644 --- a/src/examples/local-v4l2.c +++ b/src/examples/local-v4l2.c @@ -177,12 +177,6 @@ static Uint32 id_to_sdl_format(struct data *data, uint32_t id) return SDL_PIXELFORMAT_UNKNOWN; } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) - static int impl_send_command(struct spa_node *node, const struct spa_command *command) { return SPA_RESULT_OK; @@ -233,7 +227,6 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire uint32_t index) { struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node); - const struct spa_format *formats[1]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer)); struct spa_pod_frame f[2]; SDL_RendererInfo info; @@ -267,20 +260,20 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire spa_pod_builder_id(&b, id); } spa_pod_builder_pop(&b, &f[1]); + spa_pod_builder_add(&b, - PROP_U_MM(&f[1], d->type.format_video.size, SPA_POD_TYPE_RECTANGLE, - WIDTH, HEIGHT, - 1, 1, info.max_texture_width, info.max_texture_height), - PROP_U_MM(&f[1], d->type.format_video.framerate, SPA_POD_TYPE_FRACTION, - 25, 1, - 0, 1, 30, 1), - 0); + ":", d->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT), + 2, &SPA_RECTANGLE(1,1), + &SPA_RECTANGLE(info.max_texture_width, + info.max_texture_height), + ":", d->type.format_video.framerate, "Fru", &SPA_FRACTION(25,1), + 2, &SPA_FRACTION(0,1), + &SPA_FRACTION(30,1), + NULL); spa_pod_builder_pop(&b, &f[0]); - formats[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); - spa_debug_format(formats[0]); - - *format = (struct spa_format *)formats[0]; + spa_debug_format(*format); return SPA_RESULT_OK; } @@ -291,7 +284,6 @@ static int impl_port_set_format(struct spa_node *node, enum spa_direction direct struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node); struct pw_type *t = d->t; struct spa_pod_builder b = { NULL }; - struct spa_pod_frame f[2]; Uint32 sdl_format; void *dest; @@ -316,24 +308,18 @@ static int impl_port_set_format(struct spa_node *node, enum spa_direction direct SDL_UnlockTexture(d->texture); spa_pod_builder_init(&b, d->params_buffer, sizeof(d->params_buffer)); - spa_pod_builder_object(&b, &f[0], 0, t->param_alloc_buffers.Buffers, - PROP(&f[1], t->param_alloc_buffers.size, SPA_POD_TYPE_INT, - d->stride * d->format.size.height), - PROP(&f[1], t->param_alloc_buffers.stride, SPA_POD_TYPE_INT, - d->stride), - PROP_U_MM(&f[1], t->param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 32, - 2, 32), - PROP(&f[1], t->param_alloc_buffers.align, SPA_POD_TYPE_INT, - 16)); - d->params[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); + d->params[0] = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "i", d->stride * d->format.size.height, + ":", t->param_alloc_buffers.stride, "i", d->stride, + ":", t->param_alloc_buffers.buffers, "iru", 2, + 2, 1, 32, + ":", t->param_alloc_buffers.align, "i", 16); - spa_pod_builder_object(&b, &f[0], 0, t->param_alloc_meta_enable.MetaEnable, - PROP(&f[1], t->param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - t->meta.Header), - PROP(&f[1], t->param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); - d->params[1] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); + d->params[1] = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); return SPA_RESULT_OK; } diff --git a/src/examples/video-play.c b/src/examples/video-play.c index 0b88adcb5..fccbe9d81 100644 --- a/src/examples/video-play.c +++ b/src/examples/video-play.c @@ -223,12 +223,6 @@ static Uint32 id_to_sdl_format(struct data *data, uint32_t id) return SDL_PIXELFORMAT_UNKNOWN; } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) - static void on_stream_format_changed(void *_data, struct spa_format *format) { @@ -236,7 +230,6 @@ on_stream_format_changed(void *_data, struct spa_format *format) struct pw_stream *stream = data->stream; struct pw_type *t = data->t; struct spa_pod_builder b = { NULL }; - struct spa_pod_frame f[2]; struct spa_param *params[2]; Uint32 sdl_format; void *d; @@ -265,24 +258,18 @@ on_stream_format_changed(void *_data, struct spa_format *format) SDL_UnlockTexture(data->texture); spa_pod_builder_init(&b, data->params_buffer, sizeof(data->params_buffer)); - spa_pod_builder_object(&b, &f[0], 0, t->param_alloc_buffers.Buffers, - PROP(&f[1], t->param_alloc_buffers.size, SPA_POD_TYPE_INT, - data->stride * data->format.size.height), - PROP(&f[1], t->param_alloc_buffers.stride, SPA_POD_TYPE_INT, - data->stride), - PROP_U_MM(&f[1], t->param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 32, - 2, 32), - PROP(&f[1], t->param_alloc_buffers.align, SPA_POD_TYPE_INT, - 16)); - params[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); + params[0] = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "i", data->stride * data->format.size.height, + ":", t->param_alloc_buffers.stride, "i", data->stride, + ":", t->param_alloc_buffers.buffers, "iru", 32, + 2, 2, 32, + ":", t->param_alloc_buffers.align, "i", 16); - spa_pod_builder_object(&b, &f[0], 0, t->param_alloc_meta_enable.MetaEnable, - PROP(&f[1], t->param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - t->meta.Header), - PROP(&f[1], t->param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); - params[1] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); + params[1] = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); pw_stream_finish_format(stream, SPA_RESULT_OK, params, 2); } @@ -344,13 +331,14 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo } spa_pod_builder_pop(&b, &f[1]); spa_pod_builder_add(&b, - PROP_U_MM(&f[1], data->type.format_video.size, SPA_POD_TYPE_RECTANGLE, - WIDTH, HEIGHT, - 1, 1, info.max_texture_width, info.max_texture_height), - PROP_U_MM(&f[1], data->type.format_video.framerate, SPA_POD_TYPE_FRACTION, - 25, 1, - 0, 1, 30, 1), - 0); + ":", data->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT), + 2, &SPA_RECTANGLE(1,1), + &SPA_RECTANGLE(info.max_texture_width, + info.max_texture_height), + ":", data->type.format_video.framerate, "Fru", &SPA_FRACTION(25,1), + 2, &SPA_RECTANGLE(0,1), + &SPA_RECTANGLE(30,1), + NULL); spa_pod_builder_pop(&b, &f[0]); formats[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); diff --git a/src/examples/video-src.c b/src/examples/video-src.c index 9d5bb6580..4e2b8a940 100644 --- a/src/examples/video-src.c +++ b/src/examples/video-src.c @@ -165,12 +165,6 @@ static void on_stream_state_changed(void *_data, enum pw_stream_state old, enum } } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) - static void on_stream_format_changed(void *_data, struct spa_format *format) { @@ -178,7 +172,6 @@ on_stream_format_changed(void *_data, struct spa_format *format) struct pw_stream *stream = data->stream; struct pw_type *t = data->t; struct spa_pod_builder b = { NULL }; - struct spa_pod_frame f[2]; struct spa_param *params[2]; if (format == NULL) { @@ -190,24 +183,18 @@ on_stream_format_changed(void *_data, struct spa_format *format) data->stride = SPA_ROUND_UP_N(data->format.size.width * BPP, 4); spa_pod_builder_init(&b, data->params_buffer, sizeof(data->params_buffer)); - spa_pod_builder_object(&b, &f[0], 0, t->param_alloc_buffers.Buffers, - PROP(&f[1], t->param_alloc_buffers.size, SPA_POD_TYPE_INT, - data->stride * data->format.size.height), - PROP(&f[1], t->param_alloc_buffers.stride, SPA_POD_TYPE_INT, - data->stride), - PROP_U_MM(&f[1], t->param_alloc_buffers.buffers, SPA_POD_TYPE_INT, - 32, - 2, 32), - PROP(&f[1], t->param_alloc_buffers.align, SPA_POD_TYPE_INT, - 16)); - params[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); + params[0] = spa_pod_builder_param(&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "i", data->stride * data->format.size.height, + ":", t->param_alloc_buffers.stride, "i", data->stride, + ":", t->param_alloc_buffers.buffers, "iru", 2, + 2, 1, 32, + ":", t->param_alloc_buffers.align, "i", 16); - spa_pod_builder_object(&b, &f[0], 0, t->param_alloc_meta_enable.MetaEnable, - PROP(&f[1], t->param_alloc_meta_enable.type, SPA_POD_TYPE_ID, - t->meta.Header), - PROP(&f[1], t->param_alloc_meta_enable.size, SPA_POD_TYPE_INT, - sizeof(struct spa_meta_header))); - params[1] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_param); + params[1] = spa_pod_builder_param(&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header)); pw_stream_finish_format(stream, SPA_RESULT_OK, params, 2); } @@ -234,24 +221,19 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo const struct spa_format *formats[1]; uint8_t buffer[1024]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); - struct spa_pod_frame f[2]; printf("remote state: \"%s\"\n", pw_remote_state_as_string(state)); data->stream = pw_stream_new(remote, "video-src", NULL); - spa_pod_builder_format(&b, &f[0], data->type.format, - data->type.media_type.video, - data->type.media_subtype.raw, - PROP(&f[1], data->type.format_video.format, SPA_POD_TYPE_ID, - data->type.video_format.RGB), - PROP_U_MM(&f[1], data->type.format_video.size, SPA_POD_TYPE_RECTANGLE, - 320, 240, - 1, 1, 4096, 4096), - PROP(&f[1], data->type.format_video.framerate, SPA_POD_TYPE_FRACTION, - 25, 1)); - formats[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); + formats[0] = spa_pod_builder_format(&b, data->type.format, + data->type.media_type.video, data->type.media_subtype.raw, + ":", data->type.format_video.format, "I", data->type.video_format.RGB, + ":", data->type.format_video.size, "Rru", &SPA_RECTANGLE(320, 240), + 2, &SPA_RECTANGLE(1, 1), + &SPA_RECTANGLE(4096, 4096), + ":", data->type.format_video.framerate, "F", &SPA_FRACTION(25, 1)); pw_stream_add_listener(data->stream, &data->stream_listener, diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index c3e214ecc..340e6d270 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -217,21 +217,8 @@ gst_pipewire_sink_class_init (GstPipeWireSinkClass * klass) process_mem_data_quark = g_quark_from_static_string ("GstPipeWireSinkProcessMemQuark"); } +#define SPA_PROP_RANGE(min,max) 2,min,max -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_R(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_READONLY,type,1,__VA_ARGS__) -#define PROP_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) -#define PROP_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) -#define PROP_U_EN(f,key,type,n,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_ENUM,type,n,__VA_ARGS__) static void pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink) { @@ -244,43 +231,44 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink) struct spa_param *port_params[3]; struct spa_pod_builder b = { NULL }; uint8_t buffer[1024]; - struct spa_pod_frame f[2]; + struct spa_pod_frame f[1]; config = gst_buffer_pool_get_config (GST_BUFFER_POOL (pool)); gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, &max_buffers); spa_pod_builder_init (&b, buffer, sizeof (buffer)); - spa_pod_builder_push_object (&b, &f[0], 0, t->param_alloc_buffers.Buffers); + spa_pod_builder_push_param (&b, &f[0], t->param_alloc_buffers.Buffers); if (size == 0) spa_pod_builder_add (&b, - PROP_U_MM (&f[1], t->param_alloc_buffers.size, SPA_POD_TYPE_INT, 0, 0, INT32_MAX), 0); + ":", t->param_alloc_buffers.size, "iru", 0, SPA_PROP_RANGE(0, INT32_MAX), NULL); else spa_pod_builder_add (&b, - PROP_MM (&f[1], t->param_alloc_buffers.size, SPA_POD_TYPE_INT, size, size, INT32_MAX), 0); + ":", t->param_alloc_buffers.size, "ir", size, SPA_PROP_RANGE(size, INT32_MAX), NULL); spa_pod_builder_add (&b, - PROP_MM (&f[1], t->param_alloc_buffers.stride, SPA_POD_TYPE_INT, 0, 0, INT32_MAX), - PROP_U_MM (&f[1], t->param_alloc_buffers.buffers, SPA_POD_TYPE_INT, min_buffers, min_buffers, max_buffers ? max_buffers : INT32_MAX), - PROP (&f[1], t->param_alloc_buffers.align, SPA_POD_TYPE_INT, 16), - 0); + ":", t->param_alloc_buffers.stride, "ir", 0, SPA_PROP_RANGE(0, INT32_MAX), + ":", t->param_alloc_buffers.buffers, "iru", min_buffers, + SPA_PROP_RANGE(min_buffers, + max_buffers ? max_buffers : INT32_MAX), + ":", t->param_alloc_buffers.align, "i", 16, + NULL); spa_pod_builder_pop (&b, &f[0]); port_params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, struct spa_param); - spa_pod_builder_object (&b, &f[0], 0, t->param_alloc_meta_enable.MetaEnable, - PROP (&f[1], t->param_alloc_meta_enable.type, SPA_POD_TYPE_ID, t->meta.Header), - PROP (&f[1], t->param_alloc_meta_enable.size, SPA_POD_TYPE_INT, sizeof (struct spa_meta_header))); - port_params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, struct spa_param); + port_params[1] = spa_pod_builder_param (&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof (struct spa_meta_header)); - spa_pod_builder_object (&b, &f[0], 0, t->param_alloc_meta_enable.MetaEnable, - PROP (&f[1], t->param_alloc_meta_enable.type, SPA_POD_TYPE_ID, t->meta.Ringbuffer), - PROP (&f[1], t->param_alloc_meta_enable.size, SPA_POD_TYPE_INT, sizeof (struct spa_meta_ringbuffer)), - PROP (&f[1], t->param_alloc_meta_enable.ringbufferSize, SPA_POD_TYPE_INT, - size * SPA_MAX (4, - SPA_MAX (min_buffers, max_buffers))), - PROP (&f[1], t->param_alloc_meta_enable.ringbufferStride, SPA_POD_TYPE_INT, 0), - PROP (&f[1], t->param_alloc_meta_enable.ringbufferBlocks, SPA_POD_TYPE_INT, 1), - PROP (&f[1], t->param_alloc_meta_enable.ringbufferAlign, SPA_POD_TYPE_INT, 16)); - port_params[2] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, struct spa_param); + port_params[2] = spa_pod_builder_param (&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer, + ":", t->param_alloc_meta_enable.size, "i", sizeof (struct spa_meta_ringbuffer), + ":", t->param_alloc_meta_enable.ringbufferSize, "i", size * SPA_MAX (4, + SPA_MAX (min_buffers, max_buffers)), + ":", t->param_alloc_meta_enable.ringbufferStride, "i", 0, + ":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1, + ":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16); pw_thread_loop_lock (sink->main_loop); pw_stream_finish_format (sink->stream, SPA_RESULT_OK, port_params, 2); diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index 9c883f6ce..762594b25 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -726,11 +726,7 @@ connect_error: } } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) -#define PROP_U_MM(f,key,type,...) \ - SPA_POD_PROP (f,key,SPA_POD_PROP_FLAG_UNSET | \ - SPA_POD_PROP_RANGE_MIN_MAX,type,3,__VA_ARGS__) +#define SPA_PROP_RANGE(min,max) 2,min,max static void on_format_changed (void *data, @@ -757,20 +753,19 @@ on_format_changed (void *data, struct spa_param *params[2]; struct spa_pod_builder b = { NULL }; uint8_t buffer[512]; - struct spa_pod_frame f[2]; spa_pod_builder_init (&b, buffer, sizeof (buffer)); - spa_pod_builder_object (&b, &f[0], 0, t->param_alloc_buffers.Buffers, - PROP_U_MM (&f[1], t->param_alloc_buffers.size, SPA_POD_TYPE_INT, 0, 0, INT32_MAX), - PROP_U_MM (&f[1], t->param_alloc_buffers.stride, SPA_POD_TYPE_INT, 0, 0, INT32_MAX), - PROP_U_MM (&f[1], t->param_alloc_buffers.buffers, SPA_POD_TYPE_INT, 16, 0, INT32_MAX), - PROP (&f[1], t->param_alloc_buffers.align, SPA_POD_TYPE_INT, 16)); - params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, struct spa_param); + params[0] = spa_pod_builder_param (&b, + t->param_alloc_buffers.Buffers, + ":", t->param_alloc_buffers.size, "ir", 0, SPA_PROP_RANGE(0, INT32_MAX), + ":", t->param_alloc_buffers.stride, "ir", 0, SPA_PROP_RANGE(0, INT32_MAX), + ":", t->param_alloc_buffers.buffers, "ir", 16, SPA_PROP_RANGE(1, INT32_MAX), + ":", t->param_alloc_buffers.align, "i", 16); - spa_pod_builder_object (&b, &f[0], 0, t->param_alloc_meta_enable.MetaEnable, - PROP (&f[1], t->param_alloc_meta_enable.type, SPA_POD_TYPE_ID, t->meta.Header), - PROP (&f[1], t->param_alloc_meta_enable.size, SPA_POD_TYPE_INT, sizeof (struct spa_meta_header))); - params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, struct spa_param); + params[1] = spa_pod_builder_param (&b, + t->param_alloc_meta_enable.MetaEnable, + ":", t->param_alloc_meta_enable.type, "I", t->meta.Header, + ":", t->param_alloc_meta_enable.size, "i", sizeof (struct spa_meta_header)); GST_DEBUG_OBJECT (pwsrc, "doing finish format"); pw_stream_finish_format (pwsrc->stream, SPA_RESULT_OK, params, 2); diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index f8fe40867..db2d151c6 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -19,7 +19,7 @@ #include -#include "spa/pod-iter.h" +#include "spa/pod-parser.h" #include "pipewire/pipewire.h" #include "pipewire/interfaces.h" @@ -36,13 +36,12 @@ client_node_marshal_done(void *object, int seq, int res) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_DONE); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, seq, - SPA_POD_TYPE_INT, res); + spa_pod_builder_struct(b, + "i", seq, + "i", res); pw_protocol_native_end_proxy(proxy, b); } @@ -56,14 +55,14 @@ client_node_marshal_update(void *object, { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_UPDATE); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, change_mask, - SPA_POD_TYPE_INT, max_input_ports, - SPA_POD_TYPE_INT, max_output_ports, SPA_POD_TYPE_POD, props); + spa_pod_builder_struct(b, + "i", change_mask, + "i", max_input_ports, + "i", max_output_ports, + "P", props); pw_protocol_native_end_proxy(proxy, b); } @@ -81,36 +80,35 @@ client_node_marshal_port_update(void *object, { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f[2]; int i; b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE); spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f[0], - SPA_POD_TYPE_INT, direction, - SPA_POD_TYPE_INT, port_id, - SPA_POD_TYPE_INT, change_mask, SPA_POD_TYPE_INT, n_possible_formats, 0); + "[", + "i", direction, + "i", port_id, + "i", change_mask, + "i", n_possible_formats, NULL); for (i = 0; i < n_possible_formats; i++) - spa_pod_builder_add(b, SPA_POD_TYPE_POD, possible_formats[i], 0); + spa_pod_builder_add(b, "P", possible_formats[i], NULL); - spa_pod_builder_add(b, SPA_POD_TYPE_POD, format, SPA_POD_TYPE_INT, n_params, 0); + spa_pod_builder_add(b, + "P", format, + "i", n_params, NULL); - for (i = 0; i < n_params; i++) { - const struct spa_param *p = params[i]; - spa_pod_builder_add(b, SPA_POD_TYPE_POD, p, 0); - } + for (i = 0; i < n_params; i++) + spa_pod_builder_add(b, "P", params[i], NULL); if (info) { - spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f[1], - SPA_POD_TYPE_INT, info->flags, SPA_POD_TYPE_INT, info->rate, 0); - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f[1], 0); + spa_pod_builder_struct(b, + "i", info->flags, + "i", info->rate); } else { - spa_pod_builder_add(b, SPA_POD_TYPE_POD, NULL, 0); + spa_pod_builder_add(b, "P", NULL, NULL); } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f[0], 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_proxy(proxy, b); } @@ -119,11 +117,10 @@ static void client_node_marshal_event_method(void *object, struct spa_event *eve { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_EVENT); - spa_pod_builder_struct(b, &f, SPA_POD_TYPE_POD, event); + spa_pod_builder_struct(b, "P", event); pw_protocol_native_end_proxy(proxy, b); } @@ -132,11 +129,10 @@ static void client_node_marshal_destroy(void *object) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_DESTROY); - spa_pod_builder_struct(b, &f, 0); + spa_pod_builder_struct(b); pw_protocol_native_end_proxy(proxy, b); } @@ -144,14 +140,15 @@ static void client_node_marshal_destroy(void *object) static bool client_node_demarshal_set_props(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t seq; const struct spa_props *props = NULL; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &seq, - -SPA_POD_TYPE_OBJECT, &props, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &seq, + "O", &props, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_props, seq, props); @@ -161,11 +158,11 @@ static bool client_node_demarshal_set_props(void *object, void *data, size_t siz static bool client_node_demarshal_event_event(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; const struct spa_event *event; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, SPA_POD_TYPE_OBJECT, &event, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, "[ O", &event, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_client_node_proxy_events, event, event); @@ -175,13 +172,15 @@ static bool client_node_demarshal_event_event(void *object, void *data, size_t s static bool client_node_demarshal_add_port(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; int32_t seq, direction, port_id; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &seq, - SPA_POD_TYPE_INT, &direction, SPA_POD_TYPE_INT, &port_id, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &seq, + "i", &direction, + "i", &port_id, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_client_node_proxy_events, add_port, seq, direction, port_id); @@ -191,13 +190,15 @@ static bool client_node_demarshal_add_port(void *object, void *data, size_t size static bool client_node_demarshal_remove_port(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; int32_t seq, direction, port_id; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &seq, - SPA_POD_TYPE_INT, &direction, SPA_POD_TYPE_INT, &port_id, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &seq, + "i", &direction, + "i", &port_id, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_client_node_proxy_events, remove_port, seq, direction, port_id); @@ -207,17 +208,18 @@ static bool client_node_demarshal_remove_port(void *object, void *data, size_t s static bool client_node_demarshal_set_format(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t seq, direction, port_id, flags; const struct spa_format *format = NULL; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &seq, - SPA_POD_TYPE_INT, &direction, - SPA_POD_TYPE_INT, &port_id, - SPA_POD_TYPE_INT, &flags, - -SPA_POD_TYPE_OBJECT, &format, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &seq, + "i", &direction, + "i", &port_id, + "i", &flags, + "O", &format, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_format, seq, direction, port_id, @@ -228,16 +230,17 @@ static bool client_node_demarshal_set_format(void *object, void *data, size_t si static bool client_node_demarshal_set_param(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t seq, direction, port_id; const struct spa_param *param = NULL; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &seq, - SPA_POD_TYPE_INT, &direction, - SPA_POD_TYPE_INT, &port_id, - -SPA_POD_TYPE_OBJECT, ¶m, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &seq, + "i", &direction, + "i", &port_id, + "O", ¶m, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_param, seq, direction, port_id, param); @@ -247,19 +250,21 @@ static bool client_node_demarshal_set_param(void *object, void *data, size_t siz static bool client_node_demarshal_add_mem(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t direction, port_id, mem_id, type, memfd_idx, flags, offset, sz; int memfd; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &direction, - SPA_POD_TYPE_INT, &port_id, - SPA_POD_TYPE_INT, &mem_id, - SPA_POD_TYPE_ID, &type, - SPA_POD_TYPE_INT, &memfd_idx, - SPA_POD_TYPE_INT, &flags, - SPA_POD_TYPE_INT, &offset, SPA_POD_TYPE_INT, &sz, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &direction, + "i", &port_id, + "i", &mem_id, + "I", &type, + "i", &memfd_idx, + "i", &flags, + "i", &offset, + "i", &sz, NULL) < 0) return false; memfd = pw_protocol_native_get_proxy_fd(proxy, memfd_idx); @@ -275,52 +280,54 @@ static bool client_node_demarshal_add_mem(void *object, void *data, size_t size) static bool client_node_demarshal_use_buffers(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t seq, direction, port_id, n_buffers, data_id; struct pw_client_node_buffer *buffers; int i, j; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &seq, - SPA_POD_TYPE_INT, &direction, - SPA_POD_TYPE_INT, &port_id, SPA_POD_TYPE_INT, &n_buffers, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &seq, + "i", &direction, + "i", &port_id, + "i", &n_buffers, NULL) < 0) return false; buffers = alloca(sizeof(struct pw_client_node_buffer) * n_buffers); for (i = 0; i < n_buffers; i++) { struct spa_buffer *buf = buffers[i].buffer = alloca(sizeof(struct spa_buffer)); - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &buffers[i].mem_id, - SPA_POD_TYPE_INT, &buffers[i].offset, - SPA_POD_TYPE_INT, &buffers[i].size, - SPA_POD_TYPE_INT, &buf->id, - SPA_POD_TYPE_INT, &buf->n_metas, 0)) + if (spa_pod_parser_get(&prs, + "i", &buffers[i].mem_id, + "i", &buffers[i].offset, + "i", &buffers[i].size, + "i", &buf->id, + "i", &buf->n_metas, NULL) < 0) return false; buf->metas = alloca(sizeof(struct spa_meta) * buf->n_metas); for (j = 0; j < buf->n_metas; j++) { struct spa_meta *m = &buf->metas[j]; - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_ID, &m->type, - SPA_POD_TYPE_INT, &m->size, 0)) + if (spa_pod_parser_get(&prs, + "I", &m->type, + "i", &m->size, NULL) < 0) return false; } - if (!spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &buf->n_datas, 0)) + if (spa_pod_parser_get(&prs, "i", &buf->n_datas, NULL) < 0) return false; buf->datas = alloca(sizeof(struct spa_data) * buf->n_datas); for (j = 0; j < buf->n_datas; j++) { struct spa_data *d = &buf->datas[j]; - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_ID, &d->type, - SPA_POD_TYPE_INT, &data_id, - SPA_POD_TYPE_INT, &d->flags, - SPA_POD_TYPE_INT, &d->mapoffset, - SPA_POD_TYPE_INT, &d->maxsize, 0)) + if (spa_pod_parser_get(&prs, + "I", &d->type, + "i", &data_id, + "i", &d->flags, + "i", &d->mapoffset, + "i", &d->maxsize, NULL) < 0) return false; d->data = SPA_UINT32_TO_PTR(data_id); @@ -336,12 +343,15 @@ static bool client_node_demarshal_use_buffers(void *object, void *data, size_t s static bool client_node_demarshal_node_command(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; const struct spa_command *command; uint32_t seq; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &seq, SPA_POD_TYPE_OBJECT, &command, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &seq, + "O", &command, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_client_node_proxy_events, node_command, seq, command); @@ -351,15 +361,16 @@ static bool client_node_demarshal_node_command(void *object, void *data, size_t static bool client_node_demarshal_port_command(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; const struct spa_command *command; uint32_t direction, port_id; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &direction, - SPA_POD_TYPE_INT, &port_id, - SPA_POD_TYPE_OBJECT, &command, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &direction, + "i", &port_id, + "O", &command, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_command, direction, @@ -371,20 +382,21 @@ static bool client_node_demarshal_port_command(void *object, void *data, size_t static bool client_node_demarshal_transport(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t node_id, ridx, widx, memfd_idx; int readfd, writefd; struct pw_client_node_transport_info info; struct pw_client_node_transport *transport; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &node_id, - SPA_POD_TYPE_INT, &ridx, - SPA_POD_TYPE_INT, &widx, - SPA_POD_TYPE_INT, &memfd_idx, - SPA_POD_TYPE_INT, &info.offset, - SPA_POD_TYPE_INT, &info.size, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &node_id, + "i", &ridx, + "i", &widx, + "i", &memfd_idx, + "i", &info.offset, + "i", &info.size, NULL) < 0) return false; readfd = pw_protocol_native_get_proxy_fd(proxy, ridx); @@ -406,13 +418,12 @@ client_node_marshal_set_props(void *object, uint32_t seq, const struct spa_props { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PROPS); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, seq, - SPA_POD_TYPE_POD, props); + spa_pod_builder_struct(b, + "i", seq, + "P", props); pw_protocol_native_end_resource(resource, b); } @@ -421,11 +432,10 @@ static void client_node_marshal_event_event(void *object, const struct spa_event { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_EVENT); - spa_pod_builder_struct(b, &f, SPA_POD_TYPE_POD, event); + spa_pod_builder_struct(b, "P", event); pw_protocol_native_end_resource(resource, b); } @@ -436,13 +446,13 @@ client_node_marshal_add_port(void *object, { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, seq, - SPA_POD_TYPE_INT, direction, SPA_POD_TYPE_INT, port_id); + spa_pod_builder_struct(b, + "i", seq, + "i", direction, + "i", port_id); pw_protocol_native_end_resource(resource, b); } @@ -453,13 +463,13 @@ client_node_marshal_remove_port(void *object, { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, seq, - SPA_POD_TYPE_INT, direction, SPA_POD_TYPE_INT, port_id); + spa_pod_builder_struct(b, + "i", seq, + "i", direction, + "i", port_id); pw_protocol_native_end_resource(resource, b); } @@ -474,16 +484,15 @@ client_node_marshal_set_format(void *object, { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_FORMAT); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, seq, - SPA_POD_TYPE_INT, direction, - SPA_POD_TYPE_INT, port_id, - SPA_POD_TYPE_INT, flags, - SPA_POD_TYPE_POD, format); + spa_pod_builder_struct(b, + "i", seq, + "i", direction, + "i", port_id, + "i", flags, + "P", format); pw_protocol_native_end_resource(resource, b); } @@ -497,15 +506,14 @@ client_node_marshal_set_param(void *object, { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, seq, - SPA_POD_TYPE_INT, direction, - SPA_POD_TYPE_INT, port_id, - SPA_POD_TYPE_POD, param); + spa_pod_builder_struct(b, + "i", seq, + "i", direction, + "i", port_id, + "P", param); pw_protocol_native_end_resource(resource, b); } @@ -520,18 +528,18 @@ client_node_marshal_add_mem(void *object, { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, direction, - SPA_POD_TYPE_INT, port_id, - SPA_POD_TYPE_INT, mem_id, - SPA_POD_TYPE_ID, type, - SPA_POD_TYPE_INT, pw_protocol_native_add_resource_fd(resource, memfd), - SPA_POD_TYPE_INT, flags, - SPA_POD_TYPE_INT, offset, SPA_POD_TYPE_INT, size); + spa_pod_builder_struct(b, + "i", direction, + "i", port_id, + "i", mem_id, + "I", type, + "i", pw_protocol_native_add_resource_fd(resource, memfd), + "i", flags, + "i", offset, + "i", size); pw_protocol_native_end_resource(resource, b); } @@ -545,43 +553,45 @@ client_node_marshal_use_buffers(void *object, { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i, j; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_USE_BUFFERS); spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, seq, - SPA_POD_TYPE_INT, direction, - SPA_POD_TYPE_INT, port_id, SPA_POD_TYPE_INT, n_buffers, 0); + "[", + "i", seq, + "i", direction, + "i", port_id, + "i", n_buffers, NULL); for (i = 0; i < n_buffers; i++) { struct spa_buffer *buf = buffers[i].buffer; spa_pod_builder_add(b, - SPA_POD_TYPE_INT, buffers[i].mem_id, - SPA_POD_TYPE_INT, buffers[i].offset, - SPA_POD_TYPE_INT, buffers[i].size, - SPA_POD_TYPE_INT, buf->id, SPA_POD_TYPE_INT, buf->n_metas, 0); + "i", buffers[i].mem_id, + "i", buffers[i].offset, + "i", buffers[i].size, + "i", buf->id, + "i", buf->n_metas, NULL); for (j = 0; j < buf->n_metas; j++) { struct spa_meta *m = &buf->metas[j]; spa_pod_builder_add(b, - SPA_POD_TYPE_ID, m->type, SPA_POD_TYPE_INT, m->size, 0); + "I", m->type, + "i", m->size, NULL); } - spa_pod_builder_add(b, SPA_POD_TYPE_INT, buf->n_datas, 0); + spa_pod_builder_add(b, "i", buf->n_datas, NULL); for (j = 0; j < buf->n_datas; j++) { struct spa_data *d = &buf->datas[j]; spa_pod_builder_add(b, - SPA_POD_TYPE_ID, d->type, - SPA_POD_TYPE_INT, SPA_PTR_TO_UINT32(d->data), - SPA_POD_TYPE_INT, d->flags, - SPA_POD_TYPE_INT, d->mapoffset, - SPA_POD_TYPE_INT, d->maxsize, 0); + "I", d->type, + "i", SPA_PTR_TO_UINT32(d->data), + "i", d->flags, + "i", d->mapoffset, + "i", d->maxsize, NULL); } } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_resource(resource, b); } @@ -591,11 +601,10 @@ client_node_marshal_node_command(void *object, uint32_t seq, const struct spa_co { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_NODE_COMMAND); - spa_pod_builder_struct(b, &f, SPA_POD_TYPE_INT, seq, SPA_POD_TYPE_POD, command); + spa_pod_builder_struct(b, "i", seq, "P", command); pw_protocol_native_end_resource(resource, b); } @@ -608,14 +617,13 @@ client_node_marshal_port_command(void *object, { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_COMMAND); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, direction, - SPA_POD_TYPE_INT, port_id, - SPA_POD_TYPE_POD, command); + spa_pod_builder_struct(b, + "i", direction, + "i", port_id, + "P", command); pw_protocol_native_end_resource(resource, b); } @@ -625,20 +633,19 @@ static void client_node_marshal_transport(void *object, uint32_t node_id, int re { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; struct pw_client_node_transport_info info; pw_client_node_transport_get_info(transport, &info); b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, node_id, - SPA_POD_TYPE_INT, pw_protocol_native_add_resource_fd(resource, readfd), - SPA_POD_TYPE_INT, pw_protocol_native_add_resource_fd(resource, writefd), - SPA_POD_TYPE_INT, pw_protocol_native_add_resource_fd(resource, info.memfd), - SPA_POD_TYPE_INT, info.offset, - SPA_POD_TYPE_INT, info.size); + spa_pod_builder_struct(b, + "i", node_id, + "i", pw_protocol_native_add_resource_fd(resource, readfd), + "i", pw_protocol_native_add_resource_fd(resource, writefd), + "i", pw_protocol_native_add_resource_fd(resource, info.memfd), + "i", info.offset, + "i", info.size); pw_protocol_native_end_resource(resource, b); } @@ -647,13 +654,14 @@ static void client_node_marshal_transport(void *object, uint32_t node_id, int re static bool client_node_demarshal_done(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t seq, res; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &seq, - SPA_POD_TYPE_INT, &res, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &seq, + "i", &res, NULL) < 0) return false; pw_resource_do(resource, struct pw_client_node_proxy_methods, done, seq, res); @@ -663,15 +671,17 @@ static bool client_node_demarshal_done(void *object, void *data, size_t size) static bool client_node_demarshal_update(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t change_mask, max_input_ports, max_output_ports; const struct spa_props *props; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &change_mask, - SPA_POD_TYPE_INT, &max_input_ports, - SPA_POD_TYPE_INT, &max_output_ports, -SPA_POD_TYPE_OBJECT, &props, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &change_mask, + "i", &max_input_ports, + "i", &max_output_ports, + "O", &props, NULL) < 0) return false; pw_resource_do(resource, struct pw_client_node_proxy_methods, update, change_mask, @@ -684,45 +694,47 @@ static bool client_node_demarshal_update(void *object, void *data, size_t size) static bool client_node_demarshal_port_update(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t i, direction, port_id, change_mask, n_possible_formats, n_params; const struct spa_param **params = NULL; const struct spa_format **possible_formats = NULL, *format = NULL; struct spa_port_info info, *infop = NULL; struct spa_pod *ipod; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &direction, - SPA_POD_TYPE_INT, &port_id, - SPA_POD_TYPE_INT, &change_mask, - SPA_POD_TYPE_INT, &n_possible_formats, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &direction, + "i", &port_id, + "i", &change_mask, + "i", &n_possible_formats, NULL) < 0) return false; possible_formats = alloca(n_possible_formats * sizeof(struct spa_format *)); for (i = 0; i < n_possible_formats; i++) - if (!spa_pod_iter_get(&it, SPA_POD_TYPE_OBJECT, &possible_formats[i], 0)) + if (spa_pod_parser_get(&prs, "O", &possible_formats[i], NULL) < 0) return false; - if (!spa_pod_iter_get(&it, -SPA_POD_TYPE_OBJECT, &format, SPA_POD_TYPE_INT, &n_params, 0)) + if (spa_pod_parser_get(&prs, "O", &format, "i", &n_params, NULL) < 0) return false; params = alloca(n_params * sizeof(struct spa_param *)); for (i = 0; i < n_params; i++) - if (!spa_pod_iter_get(&it, SPA_POD_TYPE_OBJECT, ¶ms[i], 0)) + if (spa_pod_parser_get(&prs, "O", ¶ms[i], NULL) < 0) return false; - if (!spa_pod_iter_get(&it, -SPA_POD_TYPE_STRUCT, &ipod, 0)) + if (spa_pod_parser_get(&prs, "T", &ipod, NULL) < 0) return false; if (ipod) { - struct spa_pod_iter it2; + struct spa_pod_parser p2; infop = &info; - if (!spa_pod_iter_pod(&it2, ipod) || - !spa_pod_iter_get(&it2, - SPA_POD_TYPE_INT, &info.flags, - SPA_POD_TYPE_INT, &info.rate, 0)) + spa_pod_parser_pod(&p2, ipod); + if (spa_pod_parser_get(&p2, + "[" + "i", &info.flags, + "i", &info.rate, NULL) < 0) return false; } @@ -740,11 +752,13 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s static bool client_node_demarshal_event_method(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; struct spa_event *event; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, SPA_POD_TYPE_OBJECT, &event, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "O", &event, NULL) < 0) return false; pw_resource_do(resource, struct pw_client_node_proxy_methods, event, event); @@ -754,9 +768,10 @@ static bool client_node_demarshal_event_method(void *object, void *data, size_t static bool client_node_demarshal_destroy(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; - if (!spa_pod_iter_struct(&it, data, size)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, "[", NULL) < 0) return false; pw_resource_do(resource, struct pw_client_node_proxy_methods, destroy); diff --git a/src/modules/module-jack/jack-node.c b/src/modules/module-jack/jack-node.c index 7852c0186..eb45e6558 100644 --- a/src/modules/module-jack/jack-node.c +++ b/src/modules/module-jack/jack-node.c @@ -368,9 +368,6 @@ static int port_set_io(struct spa_node *node, enum spa_direction direction, uint return SPA_RESULT_OK; } -#define PROP(f,key,type,...) \ - SPA_POD_PROP (f,key,0,type,1,__VA_ARGS__) - static int port_enum_formats(struct spa_node *node, enum spa_direction direction, uint32_t port_id, struct spa_format **format, const struct spa_format *filter, @@ -383,8 +380,6 @@ static int port_enum_formats(struct spa_node *node, enum spa_direction direction struct spa_format *fmt; uint8_t buffer[4096]; int res; - - struct spa_pod_frame f[2]; struct jack_engine_control *ctrl = pd->node->node.server->engine_control; if (index > 0) @@ -394,27 +389,29 @@ static int port_enum_formats(struct spa_node *node, enum spa_direction direction if (pd->port.jack_port) { if (pd->port.jack_port->type_id == 0) { - spa_pod_builder_format(&b, &f[0], t->format, + fmt = spa_pod_builder_format(&b, + t->format, t->media_type.audio, t->media_subtype.raw, - PROP(&f[1], t->format_audio.format, SPA_POD_TYPE_ID, t->audio_format.F32), - PROP(&f[1], t->format_audio.rate, SPA_POD_TYPE_INT, ctrl->sample_rate), - PROP(&f[1], t->format_audio.channels, SPA_POD_TYPE_INT, 1)); + ":", t->format_audio.format, "I", t->audio_format.F32, + ":", t->format_audio.rate, "i", ctrl->sample_rate, + ":", t->format_audio.channels, "i", 1); } else if (pd->port.jack_port->type_id == 1) { - spa_pod_builder_format(&b, &f[0], t->format, + fmt = spa_pod_builder_format(&b, + t->format, t->media_type.audio, t->media_subtype_audio.midi); } else return SPA_RESULT_ENUM_END; } else { - spa_pod_builder_format(&b, &f[0], t->format, + fmt = spa_pod_builder_format(&b, + t->format, t->media_type.audio, t->media_subtype.raw, - PROP(&f[1], t->format_audio.format, SPA_POD_TYPE_ID, t->audio_format.S16), - PROP(&f[1], t->format_audio.rate, SPA_POD_TYPE_INT, ctrl->sample_rate), - PROP(&f[1], t->format_audio.channels, SPA_POD_TYPE_INT, 2)); + ":", t->format_audio.format, "I", t->audio_format.S16, + ":", t->format_audio.rate, "i", ctrl->sample_rate, + ":", t->format_audio.channels, "i", 2); } - fmt = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format); spa_pod_builder_init(&b, pd->buffer, sizeof(pd->buffer)); if ((res = spa_format_filter(fmt, filter, &b)) < 0) diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index 9fcb77f4c..46c13b71c 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -20,7 +20,7 @@ #include #include -#include "spa/pod-iter.h" +#include "spa/pod-parser.h" #include "pipewire/pipewire.h" #include "pipewire/protocol.h" @@ -34,21 +34,20 @@ static void core_marshal_client_update(void *object, const struct spa_dict *prop { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; int i, n_items; b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_CLIENT_UPDATE); n_items = props ? props->n_items : 0; - spa_pod_builder_add(b, SPA_POD_TYPE_STRUCT, &f, SPA_POD_TYPE_INT, n_items, 0); + spa_pod_builder_add(b, "[ i", n_items, NULL); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, - SPA_POD_TYPE_STRING, props->items[i].key, - SPA_POD_TYPE_STRING, props->items[i].value, 0); + "s", props->items[i].key, + "s", props->items[i].value, NULL); } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_proxy(proxy, b); } @@ -57,11 +56,10 @@ static void core_marshal_sync(void *object, uint32_t seq) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_SYNC); - spa_pod_builder_struct(b, &f, SPA_POD_TYPE_INT, seq); + spa_pod_builder_struct(b, "i", seq); pw_protocol_native_end_proxy(proxy, b); } @@ -70,13 +68,12 @@ static void core_marshal_get_registry(void *object, uint32_t version, uint32_t n { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_GET_REGISTRY); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, version, - SPA_POD_TYPE_INT, new_id); + spa_pod_builder_struct(b, + "i", version, + "i", new_id); pw_protocol_native_end_proxy(proxy, b); } @@ -89,7 +86,6 @@ core_marshal_create_object(void *object, { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i, n_items; b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_CREATE_OBJECT); @@ -97,20 +93,20 @@ core_marshal_create_object(void *object, n_items = props ? props->n_items : 0; spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_STRING, factory_name, - SPA_POD_TYPE_ID, type, - SPA_POD_TYPE_INT, version, - SPA_POD_TYPE_INT, n_items, 0); + "[" + "s", factory_name, + "I", type, + "i", version, + "i", n_items, NULL); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, - SPA_POD_TYPE_STRING, props->items[i].key, - SPA_POD_TYPE_STRING, props->items[i].value, 0); + "s", props->items[i].key, + "s", props->items[i].value, NULL); } spa_pod_builder_add(b, - SPA_POD_TYPE_INT, new_id, - -SPA_POD_TYPE_STRUCT, &f, 0); + "i", new_id, + "]", NULL); pw_protocol_native_end_proxy(proxy, b); } @@ -127,7 +123,6 @@ core_marshal_create_link(void *object, { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i, n_items; b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_CREATE_LINK); @@ -135,22 +130,22 @@ core_marshal_create_link(void *object, n_items = props ? props->n_items : 0; spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, output_node_id, - SPA_POD_TYPE_INT, output_port_id, - SPA_POD_TYPE_INT, input_node_id, - SPA_POD_TYPE_INT, input_port_id, - SPA_POD_TYPE_POD, filter, - SPA_POD_TYPE_INT, n_items, 0); + "[" + "i", output_node_id, + "i", output_port_id, + "i", input_node_id, + "i", input_port_id, + "P", filter, + "i", n_items, NULL); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, - SPA_POD_TYPE_STRING, props->items[i].key, - SPA_POD_TYPE_STRING, props->items[i].value, 0); + "s", props->items[i].key, + "s", props->items[i].value, NULL); } spa_pod_builder_add(b, - SPA_POD_TYPE_INT, new_id, - -SPA_POD_TYPE_STRUCT, &f, 0); + "i", new_id, + "]", NULL); pw_protocol_native_end_proxy(proxy, b); } @@ -160,19 +155,19 @@ core_marshal_update_types_client(void *object, uint32_t first_id, uint32_t n_typ { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i; b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_UPDATE_TYPES); spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, first_id, SPA_POD_TYPE_INT, n_types, 0); + "[" + " i", first_id, + " i", n_types, NULL); for (i = 0; i < n_types; i++) { - spa_pod_builder_add(b, SPA_POD_TYPE_STRING, types[i], 0); + spa_pod_builder_add(b, "s", types[i], NULL); } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_proxy(proxy, b); } @@ -182,26 +177,29 @@ static bool core_demarshal_info(void *object, void *data, size_t size) struct pw_proxy *proxy = object; struct spa_dict props; struct pw_core_info info; - struct spa_pod_iter it; + struct spa_pod_parser prs; int i; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, - SPA_POD_TYPE_LONG, &info.change_mask, - SPA_POD_TYPE_STRING, &info.user_name, - SPA_POD_TYPE_STRING, &info.host_name, - SPA_POD_TYPE_STRING, &info.version, - SPA_POD_TYPE_STRING, &info.name, - SPA_POD_TYPE_INT, &info.cookie, SPA_POD_TYPE_INT, &props.n_items, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &info.id, + "l", &info.change_mask, + "s", &info.user_name, + "s", &info.host_name, + "s", &info.version, + "s", &info.name, + "i", &info.cookie, + "i", &props.n_items, NULL) < 0) return false; info.props = &props; props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_STRING, &props.items[i].key, - SPA_POD_TYPE_STRING, &props.items[i].value, 0)) + if (spa_pod_parser_get(&prs, + "s", &props.items[i].key, + "s", &props.items[i].value, + NULL) < 0) return false; } pw_proxy_notify(proxy, struct pw_core_proxy_events, info, &info); @@ -211,11 +209,11 @@ static bool core_demarshal_info(void *object, void *data, size_t size) static bool core_demarshal_done(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t seq; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &seq, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, "[ i", &seq, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_core_proxy_events, done, seq); @@ -225,14 +223,15 @@ static bool core_demarshal_done(void *object, void *data, size_t size) static bool core_demarshal_error(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t id, res; const char *error; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &id, - SPA_POD_TYPE_INT, &res, SPA_POD_TYPE_STRING, &error, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[ i", &id, + "i", &res, + "s", &error, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_core_proxy_events, error, id, res, error); @@ -242,11 +241,11 @@ static bool core_demarshal_error(void *object, void *data, size_t size) static bool core_demarshal_remove_id(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t id; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &id, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, "[ i", &id, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_core_proxy_events, remove_id, id); @@ -256,18 +255,21 @@ static bool core_demarshal_remove_id(void *object, void *data, size_t size) static bool core_demarshal_update_types_client(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t first_id, n_types; const char **types; int i; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &first_id, SPA_POD_TYPE_INT, &n_types, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + " i", &first_id, + " i", &n_types, NULL) < 0) return false; types = alloca(n_types * sizeof(char *)); for (i = 0; i < n_types; i++) { - if (!spa_pod_iter_get(&it, SPA_POD_TYPE_STRING, &types[i], 0)) + if (spa_pod_parser_get(&prs, "s", &types[i], NULL) < 0) return false; } pw_proxy_notify(proxy, struct pw_core_proxy_events, update_types, first_id, n_types, types); @@ -278,7 +280,6 @@ static void core_marshal_info(void *object, struct pw_core_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i, n_items; b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_INFO); @@ -286,22 +287,22 @@ static void core_marshal_info(void *object, struct pw_core_info *info) n_items = info->props ? info->props->n_items : 0; spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, info->id, - SPA_POD_TYPE_LONG, info->change_mask, - SPA_POD_TYPE_STRING, info->user_name, - SPA_POD_TYPE_STRING, info->host_name, - SPA_POD_TYPE_STRING, info->version, - SPA_POD_TYPE_STRING, info->name, - SPA_POD_TYPE_INT, info->cookie, - SPA_POD_TYPE_INT, n_items, 0); + "[", + "i", info->id, + "l", info->change_mask, + "s", info->user_name, + "s", info->host_name, + "s", info->version, + "s", info->name, + "i", info->cookie, + "i", n_items, NULL); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, - SPA_POD_TYPE_STRING, info->props->items[i].key, - SPA_POD_TYPE_STRING, info->props->items[i].value, 0); + "s", info->props->items[i].key, + "s", info->props->items[i].value, NULL); } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_resource(resource, b); } @@ -310,11 +311,10 @@ static void core_marshal_done(void *object, uint32_t seq) { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_DONE); - spa_pod_builder_struct(b, &f, SPA_POD_TYPE_INT, seq); + spa_pod_builder_struct(b, "i", seq); pw_protocol_native_end_resource(resource, b); } @@ -324,7 +324,6 @@ static void core_marshal_error(void *object, uint32_t id, int res, const char *e struct pw_resource *resource = object; char buffer[128]; struct spa_pod_builder *b; - struct spa_pod_frame f; va_list ap; b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_ERROR); @@ -333,10 +332,10 @@ static void core_marshal_error(void *object, uint32_t id, int res, const char *e vsnprintf(buffer, sizeof(buffer), error, ap); va_end(ap); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, id, - SPA_POD_TYPE_INT, res, - SPA_POD_TYPE_STRING, buffer); + spa_pod_builder_struct(b, + "i", id, + "i", res, + "s", buffer); pw_protocol_native_end_resource(resource, b); } @@ -345,11 +344,10 @@ static void core_marshal_remove_id(void *object, uint32_t id) { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_REMOVE_ID); - spa_pod_builder_struct(b, &f, SPA_POD_TYPE_INT, id); + spa_pod_builder_struct(b, "i", id); pw_protocol_native_end_resource(resource, b); } @@ -359,19 +357,19 @@ core_marshal_update_types_server(void *object, uint32_t first_id, uint32_t n_typ { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i; b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_UPDATE_TYPES); spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, first_id, SPA_POD_TYPE_INT, n_types, 0); + "[", + "i", first_id, + "i", n_types, NULL); for (i = 0; i < n_types; i++) { - spa_pod_builder_add(b, SPA_POD_TYPE_STRING, types[i], 0); + spa_pod_builder_add(b, "s", types[i], NULL); } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_resource(resource, b); } @@ -380,18 +378,19 @@ static bool core_demarshal_client_update(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_dict props; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t i; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &props.n_items, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, "[ i", &props.n_items, NULL) < 0) return false; props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_STRING, &props.items[i].key, - SPA_POD_TYPE_STRING, &props.items[i].value, 0)) + if (spa_pod_parser_get(&prs, + "s", &props.items[i].key, + "s", &props.items[i].value, + NULL) < 0) return false; } pw_resource_do(resource, struct pw_core_proxy_methods, client_update, &props); @@ -401,11 +400,11 @@ static bool core_demarshal_client_update(void *object, void *data, size_t size) static bool core_demarshal_sync(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t seq; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &seq, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, "[i]", &seq, NULL) < 0) return false; pw_resource_do(resource, struct pw_core_proxy_methods, sync, seq); @@ -415,14 +414,11 @@ static bool core_demarshal_sync(void *object, void *data, size_t size) static bool core_demarshal_get_registry(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; int32_t version, new_id; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &version, - SPA_POD_TYPE_INT, &new_id, 0)) - + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, "[ii]", &version, &new_id, NULL) < 0) return false; pw_resource_do(resource, struct pw_core_proxy_methods, get_registry, version, new_id); @@ -432,28 +428,27 @@ static bool core_demarshal_get_registry(void *object, void *data, size_t size) static bool core_demarshal_create_object(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t version, type, new_id, i; const char *factory_name; struct spa_dict props; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_STRING, &factory_name, - SPA_POD_TYPE_ID, &type, - SPA_POD_TYPE_INT, &version, - SPA_POD_TYPE_INT, &props.n_items, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "s", &factory_name, + "I", &type, + "i", &version, + "i", &props.n_items, NULL) < 0) return false; props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_STRING, &props.items[i].key, - SPA_POD_TYPE_STRING, &props.items[i].value, 0)) + if (spa_pod_parser_get(&prs, "ss", + &props.items[i].key, &props.items[i].value, NULL) < 0) return false; } - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &new_id, 0)) + if (spa_pod_parser_get(&prs, "i", &new_id, NULL) < 0) return false; pw_resource_do(resource, struct pw_core_proxy_methods, create_object, factory_name, @@ -465,30 +460,30 @@ static bool core_demarshal_create_object(void *object, void *data, size_t size) static bool core_demarshal_create_link(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t new_id, i; uint32_t output_node_id, output_port_id, input_node_id, input_port_id; struct spa_format *filter = NULL; struct spa_dict props; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &output_node_id, - SPA_POD_TYPE_INT, &output_port_id, - SPA_POD_TYPE_INT, &input_node_id, - SPA_POD_TYPE_INT, &input_port_id, - -SPA_POD_TYPE_OBJECT, &filter, - SPA_POD_TYPE_INT, &props.n_items, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &output_node_id, + "i", &output_port_id, + "i", &input_node_id, + "i", &input_port_id, + "P", &filter, + "i", &props.n_items, NULL) < 0) return false; props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_STRING, &props.items[i].key, - SPA_POD_TYPE_STRING, &props.items[i].value, 0)) + if (spa_pod_parser_get(&prs, "ss", + &props.items[i].key, &props.items[i].value, NULL) < 0) return false; } - if (!spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &new_id, 0)) + if (spa_pod_parser_get(&prs, "i", &new_id, NULL) < 0) return false; pw_resource_do(resource, struct pw_core_proxy_methods, create_link, output_node_id, @@ -504,18 +499,21 @@ static bool core_demarshal_create_link(void *object, void *data, size_t size) static bool core_demarshal_update_types_server(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t first_id, n_types; const char **types; int i; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &first_id, SPA_POD_TYPE_INT, &n_types, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &first_id, + "i", &n_types, NULL) < 0) return false; types = alloca(n_types * sizeof(char *)); for (i = 0; i < n_types; i++) { - if (!spa_pod_iter_get(&it, SPA_POD_TYPE_STRING, &types[i], 0)) + if (spa_pod_parser_get(&prs, "s", &types[i], NULL) < 0) return false; } pw_resource_do(resource, struct pw_core_proxy_methods, update_types, first_id, n_types, types); @@ -527,16 +525,15 @@ static void registry_marshal_global(void *object, uint32_t id, uint32_t parent_i { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, id, - SPA_POD_TYPE_INT, parent_id, - SPA_POD_TYPE_INT, permissions, - SPA_POD_TYPE_ID, type, - SPA_POD_TYPE_INT, version); + spa_pod_builder_struct(b, + "i", id, + "i", parent_id, + "i", permissions, + "I", type, + "i", version); pw_protocol_native_end_resource(resource, b); } @@ -545,11 +542,10 @@ static void registry_marshal_global_remove(void *object, uint32_t id) { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL_REMOVE); - spa_pod_builder_struct(b, &f, SPA_POD_TYPE_INT, id); + spa_pod_builder_struct(b, "i", id); pw_protocol_native_end_resource(resource, b); } @@ -557,15 +553,16 @@ static void registry_marshal_global_remove(void *object, uint32_t id) static bool registry_demarshal_bind(void *object, void *data, size_t size) { struct pw_resource *resource = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t id, version, type, new_id; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &id, - SPA_POD_TYPE_ID, &type, - SPA_POD_TYPE_INT, &version, - SPA_POD_TYPE_INT, &new_id, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &id, + "I", &type, + "i", &version, + "i", &new_id, NULL) < 0) return false; pw_resource_do(resource, struct pw_registry_proxy_methods, bind, id, type, version, new_id); @@ -576,7 +573,6 @@ static void module_marshal_info(void *object, struct pw_module_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i, n_items; b = pw_protocol_native_begin_resource(resource, PW_MODULE_PROXY_EVENT_INFO); @@ -584,19 +580,20 @@ static void module_marshal_info(void *object, struct pw_module_info *info) n_items = info->props ? info->props->n_items : 0; spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, info->id, - SPA_POD_TYPE_LONG, info->change_mask, - SPA_POD_TYPE_STRING, info->name, - SPA_POD_TYPE_STRING, info->filename, - SPA_POD_TYPE_STRING, info->args, SPA_POD_TYPE_INT, n_items, 0); + "[", + "i", info->id, + "l", info->change_mask, + "s", info->name, + "s", info->filename, + "s", info->args, + "i", n_items, NULL); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, - SPA_POD_TYPE_STRING, info->props->items[i].key, - SPA_POD_TYPE_STRING, info->props->items[i].value, 0); + "s", info->props->items[i].key, + "s", info->props->items[i].value, NULL); } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_resource(resource, b); } @@ -604,26 +601,27 @@ static void module_marshal_info(void *object, struct pw_module_info *info) static bool module_demarshal_info(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; struct spa_dict props; struct pw_module_info info; int i; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, - SPA_POD_TYPE_LONG, &info.change_mask, - SPA_POD_TYPE_STRING, &info.name, - SPA_POD_TYPE_STRING, &info.filename, - SPA_POD_TYPE_STRING, &info.args, SPA_POD_TYPE_INT, &props.n_items, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &info.id, + "l", &info.change_mask, + "s", &info.name, + "s", &info.filename, + "s", &info.args, + "i", &props.n_items, NULL) < 0) return false; info.props = &props; props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_STRING, &props.items[i].key, - SPA_POD_TYPE_STRING, &props.items[i].value, 0)) + if (spa_pod_parser_get(&prs, "ss", + &props.items[i].key, &props.items[i].value, NULL) < 0) return false; } pw_proxy_notify(proxy, struct pw_module_proxy_events, info, &info); @@ -634,7 +632,6 @@ static void factory_marshal_info(void *object, struct pw_factory_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i, n_items; b = pw_protocol_native_begin_resource(resource, PW_FACTORY_PROXY_EVENT_INFO); @@ -642,20 +639,20 @@ static void factory_marshal_info(void *object, struct pw_factory_info *info) n_items = info->props ? info->props->n_items : 0; spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, info->id, - SPA_POD_TYPE_LONG, info->change_mask, - SPA_POD_TYPE_STRING, info->name, - SPA_POD_TYPE_ID, info->type, - SPA_POD_TYPE_INT, info->version, - SPA_POD_TYPE_INT, n_items, 0); + "[", + "i", info->id, + "l", info->change_mask, + "s", info->name, + "I", info->type, + "i", info->version, + "i", n_items, NULL); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, - SPA_POD_TYPE_STRING, info->props->items[i].key, - SPA_POD_TYPE_STRING, info->props->items[i].value, 0); + "s", info->props->items[i].key, + "s", info->props->items[i].value, NULL); } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_resource(resource, b); } @@ -663,27 +660,28 @@ static void factory_marshal_info(void *object, struct pw_factory_info *info) static bool factory_demarshal_info(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; struct spa_dict props; struct pw_factory_info info; int i; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, - SPA_POD_TYPE_LONG, &info.change_mask, - SPA_POD_TYPE_STRING, &info.name, - SPA_POD_TYPE_ID, &info.type, - SPA_POD_TYPE_INT, &info.version, - SPA_POD_TYPE_INT, &props.n_items, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &info.id, + "l", &info.change_mask, + "s", &info.name, + "I", &info.type, + "i", &info.version, + "i", &props.n_items, NULL) < 0) return false; info.props = &props; props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_STRING, &props.items[i].key, - SPA_POD_TYPE_STRING, &props.items[i].value, 0)) + if (spa_pod_parser_get(&prs, + "s", &props.items[i].key, + "s", &props.items[i].value, NULL) < 0) return false; } pw_proxy_notify(proxy, struct pw_factory_proxy_events, info, &info); @@ -694,43 +692,42 @@ static void node_marshal_info(void *object, struct pw_node_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i, n_items; b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_INFO); spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, info->id, - SPA_POD_TYPE_LONG, info->change_mask, - SPA_POD_TYPE_STRING, info->name, - SPA_POD_TYPE_INT, info->max_input_ports, - SPA_POD_TYPE_INT, info->n_input_ports, - SPA_POD_TYPE_INT, info->n_input_formats, 0); + "[", + "i", info->id, + "l", info->change_mask, + "s", info->name, + "i", info->max_input_ports, + "i", info->n_input_ports, + "i", info->n_input_formats, NULL); for (i = 0; i < info->n_input_formats; i++) - spa_pod_builder_add(b, SPA_POD_TYPE_POD, info->input_formats[i], 0); + spa_pod_builder_add(b, "P", info->input_formats[i], NULL); spa_pod_builder_add(b, - SPA_POD_TYPE_INT, info->max_output_ports, - SPA_POD_TYPE_INT, info->n_output_ports, - SPA_POD_TYPE_INT, info->n_output_formats, 0); + "i", info->max_output_ports, + "i", info->n_output_ports, + "i", info->n_output_formats, 0); for (i = 0; i < info->n_output_formats; i++) - spa_pod_builder_add(b, SPA_POD_TYPE_POD, info->output_formats[i], 0); + spa_pod_builder_add(b, "P", info->output_formats[i], NULL); n_items = info->props ? info->props->n_items : 0; spa_pod_builder_add(b, - SPA_POD_TYPE_INT, info->state, - SPA_POD_TYPE_STRING, info->error, SPA_POD_TYPE_INT, n_items, 0); + "i", info->state, + "s", info->error, "i", n_items, NULL); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, - SPA_POD_TYPE_STRING, info->props->items[i].key, - SPA_POD_TYPE_STRING, info->props->items[i].value, 0); + "s", info->props->items[i].key, + "s", info->props->items[i].value, NULL); } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_resource(resource, b); } @@ -738,49 +735,50 @@ static void node_marshal_info(void *object, struct pw_node_info *info) static bool node_demarshal_info(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; struct spa_dict props; struct pw_node_info info; int i; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, - SPA_POD_TYPE_LONG, &info.change_mask, - SPA_POD_TYPE_STRING, &info.name, - SPA_POD_TYPE_INT, &info.max_input_ports, - SPA_POD_TYPE_INT, &info.n_input_ports, - SPA_POD_TYPE_INT, &info.n_input_formats, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &info.id, + "l", &info.change_mask, + "s", &info.name, + "i", &info.max_input_ports, + "i", &info.n_input_ports, + "i", &info.n_input_formats, NULL) < 0) return false; info.input_formats = alloca(info.n_input_formats * sizeof(struct spa_format *)); for (i = 0; i < info.n_input_formats; i++) - if (!spa_pod_iter_get(&it, SPA_POD_TYPE_OBJECT, &info.input_formats[i], 0)) + if (spa_pod_parser_get(&prs, "P", &info.input_formats[i], NULL) < 0) return false; - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.max_output_ports, - SPA_POD_TYPE_INT, &info.n_output_ports, - SPA_POD_TYPE_INT, &info.n_output_formats, 0)) + if (spa_pod_parser_get(&prs, + "i", &info.max_output_ports, + "i", &info.n_output_ports, + "i", &info.n_output_formats, NULL) < 0) return false; info.output_formats = alloca(info.n_output_formats * sizeof(struct spa_format *)); for (i = 0; i < info.n_output_formats; i++) - if (!spa_pod_iter_get(&it, SPA_POD_TYPE_OBJECT, &info.output_formats[i], 0)) + if (spa_pod_parser_get(&prs, "P", &info.output_formats[i], NULL) < 0) return false; - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.state, - SPA_POD_TYPE_STRING, &info.error, - SPA_POD_TYPE_INT, &props.n_items, 0)) + if (spa_pod_parser_get(&prs, + "i", &info.state, + "s", &info.error, + "i", &props.n_items, NULL) < 0) return false; info.props = &props; props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_STRING, &props.items[i].key, - SPA_POD_TYPE_STRING, &props.items[i].value, 0)) + if (spa_pod_parser_get(&prs, + "s", &props.items[i].key, + "s", &props.items[i].value, NULL) < 0) return false; } pw_proxy_notify(proxy, struct pw_node_proxy_events, info, &info); @@ -791,7 +789,6 @@ static void client_marshal_info(void *object, struct pw_client_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i, n_items; b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_INFO); @@ -799,17 +796,17 @@ static void client_marshal_info(void *object, struct pw_client_info *info) n_items = info->props ? info->props->n_items : 0; spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, info->id, - SPA_POD_TYPE_LONG, info->change_mask, - SPA_POD_TYPE_INT, n_items, 0); + "[", + "i", info->id, + "l", info->change_mask, + "i", n_items, NULL); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, - SPA_POD_TYPE_STRING, info->props->items[i].key, - SPA_POD_TYPE_STRING, info->props->items[i].value, 0); + "s", info->props->items[i].key, + "s", info->props->items[i].value, NULL); } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_resource(resource, b); } @@ -817,24 +814,25 @@ static void client_marshal_info(void *object, struct pw_client_info *info) static bool client_demarshal_info(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; struct spa_dict props; struct pw_client_info info; uint32_t i; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, - SPA_POD_TYPE_LONG, &info.change_mask, - SPA_POD_TYPE_INT, &props.n_items, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &info.id, + "l", &info.change_mask, + "i", &props.n_items, NULL) < 0) return false; info.props = &props; props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_STRING, &props.items[i].key, - SPA_POD_TYPE_STRING, &props.items[i].value, 0)) + if (spa_pod_parser_get(&prs, + "s", &props.items[i].key, + "s", &props.items[i].value, NULL) < 0) return false; } pw_proxy_notify(proxy, struct pw_client_proxy_events, info, &info); @@ -845,7 +843,6 @@ static void link_marshal_info(void *object, struct pw_link_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; - struct spa_pod_frame f; uint32_t i, n_items; b = pw_protocol_native_begin_resource(resource, PW_LINK_PROXY_EVENT_INFO); @@ -853,22 +850,22 @@ static void link_marshal_info(void *object, struct pw_link_info *info) n_items = info->props ? info->props->n_items : 0; spa_pod_builder_add(b, - SPA_POD_TYPE_STRUCT, &f, - SPA_POD_TYPE_INT, info->id, - SPA_POD_TYPE_LONG, info->change_mask, - SPA_POD_TYPE_INT, info->output_node_id, - SPA_POD_TYPE_INT, info->output_port_id, - SPA_POD_TYPE_INT, info->input_node_id, - SPA_POD_TYPE_INT, info->input_port_id, - SPA_POD_TYPE_POD, info->format, - SPA_POD_TYPE_INT, n_items, 0); + "[", + "i", info->id, + "l", info->change_mask, + "i", info->output_node_id, + "i", info->output_port_id, + "i", info->input_node_id, + "i", info->input_port_id, + "P", info->format, + "i", n_items, NULL); for (i = 0; i < n_items; i++) { spa_pod_builder_add(b, - SPA_POD_TYPE_STRING, info->props->items[i].key, - SPA_POD_TYPE_STRING, info->props->items[i].value, 0); + "s", info->props->items[i].key, + "s", info->props->items[i].value, NULL); } - spa_pod_builder_add(b, -SPA_POD_TYPE_STRUCT, &f, 0); + spa_pod_builder_add(b, "]", NULL); pw_protocol_native_end_resource(resource, b); } @@ -876,29 +873,30 @@ static void link_marshal_info(void *object, struct pw_link_info *info) static bool link_demarshal_info(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; struct spa_dict props; struct pw_link_info info = { 0, }; int i; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &info.id, - SPA_POD_TYPE_LONG, &info.change_mask, - SPA_POD_TYPE_INT, &info.output_node_id, - SPA_POD_TYPE_INT, &info.output_port_id, - SPA_POD_TYPE_INT, &info.input_node_id, - SPA_POD_TYPE_INT, &info.input_port_id, - -SPA_POD_TYPE_OBJECT, &info.format, - SPA_POD_TYPE_INT, &props.n_items, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &info.id, + "l", &info.change_mask, + "i", &info.output_node_id, + "i", &info.output_port_id, + "i", &info.input_node_id, + "i", &info.input_port_id, + "P", &info.format, + "i", &props.n_items, NULL) < 0) return false; info.props = &props; props.items = alloca(props.n_items * sizeof(struct spa_dict_item)); for (i = 0; i < props.n_items; i++) { - if (!spa_pod_iter_get(&it, - SPA_POD_TYPE_STRING, &props.items[i].key, - SPA_POD_TYPE_STRING, &props.items[i].value, 0)) + if (spa_pod_parser_get(&prs, + "s", &props.items[i].key, + "s", &props.items[i].value, NULL) < 0) return false; } pw_proxy_notify(proxy, struct pw_link_proxy_events, info, &info); @@ -908,16 +906,17 @@ static bool link_demarshal_info(void *object, void *data, size_t size) static bool registry_demarshal_global(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t id, parent_id, permissions, type, version; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, - SPA_POD_TYPE_INT, &id, - SPA_POD_TYPE_INT, &parent_id, - SPA_POD_TYPE_INT, &permissions, - SPA_POD_TYPE_ID, &type, - SPA_POD_TYPE_INT, &version, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[" + "i", &id, + "i", &parent_id, + "i", &permissions, + "I", &type, + "i", &version, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_registry_proxy_events, global, id, parent_id, permissions, type, version); @@ -927,11 +926,11 @@ static bool registry_demarshal_global(void *object, void *data, size_t size) static bool registry_demarshal_global_remove(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; - struct spa_pod_iter it; + struct spa_pod_parser prs; uint32_t id; - if (!spa_pod_iter_struct(&it, data, size) || - !spa_pod_iter_get(&it, SPA_POD_TYPE_INT, &id, 0)) + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, "[ i", &id, NULL) < 0) return false; pw_proxy_notify(proxy, struct pw_registry_proxy_events, global_remove, id); @@ -943,15 +942,14 @@ static void registry_marshal_bind(void *object, uint32_t id, { struct pw_proxy *proxy = object; struct spa_pod_builder *b; - struct spa_pod_frame f; b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_BIND); - spa_pod_builder_struct(b, &f, - SPA_POD_TYPE_INT, id, - SPA_POD_TYPE_ID, type, - SPA_POD_TYPE_INT, version, - SPA_POD_TYPE_INT, new_id); + spa_pod_builder_struct(b, + "i", id, + "I", type, + "i", version, + "i", new_id); pw_protocol_native_end_proxy(proxy, b); } diff --git a/src/modules/spa/spa-monitor.c b/src/modules/spa/spa-monitor.c index 84e38e977..408fe3713 100644 --- a/src/modules/spa/spa-monitor.c +++ b/src/modules/spa/spa-monitor.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include @@ -73,27 +73,29 @@ static void add_item(struct pw_spa_monitor *this, struct spa_monitor_item *item) const struct spa_support *support; uint32_t n_support; - spa_pod_object_query(&item->object, - t->monitor.name, SPA_POD_TYPE_STRING, &name, - t->monitor.id, SPA_POD_TYPE_STRING, &id, - t->monitor.klass, SPA_POD_TYPE_STRING, &klass, - t->monitor.factory, SPA_POD_TYPE_POINTER, &factory, - t->monitor.info, SPA_POD_TYPE_STRUCT, &info, 0); + if (spa_pod_object_parse(&item->object, + ":",t->monitor.name, "s", &name, + ":",t->monitor.id, "s", &id, + ":",t->monitor.klass, "s", &klass, + ":",t->monitor.factory, "p", &factory, + ":",t->monitor.info, "T", &info, NULL) < 0) + return; pw_log_debug("monitor %p: add: \"%s\" (%s)", this, name, id); props = pw_properties_new(NULL, NULL); if (info) { - struct spa_pod_iter it; + struct spa_pod_parser prs; - spa_pod_iter_pod(&it, info); - while (true) { - const char *key, *val; - if (!spa_pod_iter_get - (&it, SPA_POD_TYPE_STRING, &key, SPA_POD_TYPE_STRING, &val, 0)) - break; - pw_properties_set(props, key, val); + spa_pod_parser_pod(&prs, info); + if (spa_pod_parser_get(&prs, "[", NULL) == 0) { + while (true) { + const char *key, *val; + if (spa_pod_parser_get(&prs, "ss", &key, &val, NULL) < 0) + break; + pw_properties_set(props, key, val); + } } } @@ -157,9 +159,10 @@ static void remove_item(struct pw_spa_monitor *this, struct spa_monitor_item *it const char *name, *id; struct pw_type *t = pw_core_get_type(impl->core); - spa_pod_object_query(&item->object, - t->monitor.name, SPA_POD_TYPE_STRING, &name, - t->monitor.id, SPA_POD_TYPE_STRING, &id, 0); + if (spa_pod_object_parse(&item->object, + ":",t->monitor.name, "s", &name, + ":",t->monitor.id, "s", &id, NULL) < 0) + return; pw_log_debug("monitor %p: remove: \"%s\" (%s)", this, name, id); mitem = find_item(this, id); @@ -183,8 +186,9 @@ static void on_monitor_event(void *data, struct spa_event *event) struct spa_monitor_item *item = SPA_POD_CONTENTS(struct spa_event, event); const char *name; - spa_pod_object_query(&item->object, - t->monitor.name, SPA_POD_TYPE_STRING, &name, 0); + if (spa_pod_object_parse(&item->object, + ":",t->monitor.name, "s", &name, NULL) < 0) + return; pw_log_debug("monitor %p: changed: \"%s\"", this, name); } diff --git a/src/pipewire/link.c b/src/pipewire/link.c index 57357e306..677f73df0 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -236,9 +236,8 @@ static struct spa_param *find_meta_enable(struct pw_core *core, struct spa_param (¶ms[i]->object.pod, core->type.param_alloc_meta_enable.MetaEnable)) { uint32_t qtype; - if (spa_param_query(params[i], - core->type.param_alloc_meta_enable.type, - SPA_POD_TYPE_ID, &qtype, 0) != 1) + if (spa_param_parse(params[i], + ":", core->type.param_alloc_meta_enable.type, "I", &qtype, NULL) < 0) continue; if (qtype == type) @@ -285,11 +284,9 @@ static struct spa_buffer **alloc_buffers(struct pw_link *this, (¶ms[i]->object.pod, this->core->type.param_alloc_meta_enable.MetaEnable)) { uint32_t type, size; - if (spa_param_query(params[i], - this->core->type.param_alloc_meta_enable.type, - SPA_POD_TYPE_ID, &type, - this->core->type.param_alloc_meta_enable.size, - SPA_POD_TYPE_INT, &size, 0) != 2) + if (spa_param_parse(params[i], + ":", this->core->type.param_alloc_meta_enable.type, "I", &type, + ":", this->core->type.param_alloc_meta_enable.size, "i", &size, NULL) < 0) continue; pw_log_debug("link %p: enable meta %d %d", this, type, size); @@ -534,11 +531,9 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s uint32_t ms, s; max_buffers = 1; - if (spa_param_query(param, - this->core->type.param_alloc_meta_enable.ringbufferSize, - SPA_POD_TYPE_INT, &ms, - this->core->type.param_alloc_meta_enable. - ringbufferStride, SPA_POD_TYPE_INT, &s, 0) == 2) { + if (spa_param_parse(param, + ":", this->core->type.param_alloc_meta_enable.ringbufferSize, "i", &ms, + ":", this->core->type.param_alloc_meta_enable.ringbufferStride, "i", &s, NULL) >= 0) { minsize = ms; stride = s; } @@ -551,13 +546,10 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s uint32_t qmax_buffers = max_buffers, qminsize = minsize, qstride = stride; - spa_param_query(param, - this->core->type.param_alloc_buffers.size, - SPA_POD_TYPE_INT, &qminsize, - this->core->type.param_alloc_buffers.stride, - SPA_POD_TYPE_INT, &qstride, - this->core->type.param_alloc_buffers.buffers, - SPA_POD_TYPE_INT, &qmax_buffers, 0); + spa_param_parse(param, + ":", this->core->type.param_alloc_buffers.size, "i", &qminsize, + ":", this->core->type.param_alloc_buffers.stride, "i", &qstride, + ":", this->core->type.param_alloc_buffers.buffers, "i", &qmax_buffers, NULL); max_buffers = qmax_buffers == 0 ? max_buffers : SPA_MIN(qmax_buffers,