summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2017-11-09 17:07:04 +0100
committerWim Taymans <wtaymans@redhat.com>2017-11-09 17:16:54 +0100
commit58451d626ca9824c753009b77c61a31c37c97aea (patch)
treedcd09bb49d22aae20490ff10ea65829456854769
parentcc47fb7e3addeef7c0bc9dee5ed8a37c5dc0d1b0 (diff)
Implement param filtering
Make a new pod filter function and use it in the plugins to filter in enum_params. Small tweaks to the pod_builder
-rw-r--r--spa/include/spa/pod-builder.h27
-rw-r--r--spa/include/spa/pod-utils.h16
-rw-r--r--spa/lib/debug.c44
-rw-r--r--spa/lib/format.c64
-rw-r--r--spa/lib/meson.build6
-rw-r--r--spa/lib/pod.c507
-rw-r--r--spa/lib/pod.h (renamed from spa/lib/format.h)19
-rw-r--r--spa/lib/props.c364
-rw-r--r--spa/lib/props.h44
-rw-r--r--spa/plugins/alsa/alsa-sink.c86
-rw-r--r--spa/plugins/alsa/alsa-source.c39
-rw-r--r--spa/plugins/alsa/alsa-utils.c4
-rw-r--r--spa/plugins/audiomixer/audiomixer.c49
-rw-r--r--spa/plugins/audiotestsrc/audiotestsrc.c61
-rw-r--r--spa/plugins/ffmpeg/ffmpeg-dec.c162
-rw-r--r--spa/plugins/ffmpeg/ffmpeg-enc.c30
-rw-r--r--spa/plugins/support/logger.c2
-rw-r--r--spa/plugins/support/mapper.c1
-rw-r--r--spa/plugins/test/fakesink.c45
-rw-r--r--spa/plugins/test/fakesrc.c48
-rw-r--r--spa/plugins/v4l2/v4l2-source.c46
-rw-r--r--spa/plugins/videotestsrc/videotestsrc.c64
-rw-r--r--spa/plugins/volume/volume.c61
-rw-r--r--spa/tests/test-ringbuffer.c1
-rw-r--r--spa/tests/test-v4l2.c2
-rw-r--r--src/examples/video-play.c5
-rw-r--r--src/examples/video-src.c5
-rw-r--r--src/gst/gstpipewireformat.c5
-rw-r--r--src/modules/module-client-node/client-node.c59
-rw-r--r--src/modules/module-jack/jack-node.c74
-rw-r--r--src/modules/module-protocol-native/connection.c6
-rw-r--r--src/modules/spa/module-monitor.c2
-rw-r--r--src/modules/spa/module-node.c2
-rw-r--r--src/pipewire/core.c2
-rw-r--r--src/pipewire/link.c43
35 files changed, 1114 insertions, 881 deletions
diff --git a/spa/include/spa/pod-builder.h b/spa/include/spa/pod-builder.h
index 320c7ce8..feb2ed2f 100644
--- a/spa/include/spa/pod-builder.h
+++ b/spa/include/spa/pod-builder.h
@@ -36,9 +36,10 @@ struct spa_pod_builder {
void *data;
uint32_t size;
uint32_t offset;
- uint32_t (*write) (struct spa_pod_builder *builder, uint32_t ref, const void *data,
- uint32_t size);
+
+ uint32_t (*write) (struct spa_pod_builder *builder, const void *data, uint32_t size);
void * (*deref) (struct spa_pod_builder *builder, uint32_t ref);
+ void (*reset) (struct spa_pod_builder *builder, uint32_t offset);
bool in_array;
bool first;
int depth;
@@ -47,15 +48,21 @@ struct spa_pod_builder {
#define SPA_POD_BUILDER_INIT(buffer,size) { buffer, size, }
-static inline void spa_pod_builder_init(struct spa_pod_builder *builder, void *data, uint32_t size)
+static inline void
+spa_pod_builder_reset(struct spa_pod_builder *builder, uint32_t offset)
{
- builder->data = data;
- builder->size = size;
- builder->offset = 0;
+ if (builder->reset)
+ builder->reset(builder, offset);
+ builder->offset = offset;
builder->depth = 0;
builder->in_array = builder->first = false;
}
+static inline void spa_pod_builder_init(struct spa_pod_builder *builder, void *data, uint32_t size)
+{
+ *builder = (struct spa_pod_builder) SPA_POD_BUILDER_INIT(data, size);
+}
+
static inline void *
spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t ref)
{
@@ -85,7 +92,7 @@ spa_pod_builder_raw(struct spa_pod_builder *builder, const void *data, uint32_t
int i;
if (builder->write) {
- ref = builder->write(builder, -1, data, size);
+ ref = builder->write(builder, data, size);
} else {
ref = builder->offset;
if (ref + size > builder->size)
@@ -123,10 +130,8 @@ static inline uint32_t spa_pod_builder_pop(struct spa_pod_builder *builder)
struct spa_pod_frame *frame = &builder->frame[--builder->depth], *top;
if (frame->ref != -1) {
- if (builder->write)
- builder->write(builder, frame->ref, &frame->pod, sizeof(struct spa_pod));
- else
- memcpy(builder->data + frame->ref, &frame->pod, sizeof(struct spa_pod));
+ struct spa_pod *pod = spa_pod_builder_deref(builder, frame->ref);
+ *pod = frame->pod;
}
top = builder->depth > 0 ? &builder->frame[builder->depth-1] : NULL;
builder->in_array = (top && (top->pod.type == SPA_POD_TYPE_ARRAY ||
diff --git a/spa/include/spa/pod-utils.h b/spa/include/spa/pod-utils.h
index 091337da..86a36567 100644
--- a/spa/include/spa/pod-utils.h
+++ b/spa/include/spa/pod-utils.h
@@ -46,7 +46,8 @@ static inline bool spa_pod_is_object_type(struct spa_pod *pod, uint32_t type)
return (pod->type == SPA_POD_TYPE_OBJECT
&& ((struct spa_pod_object *) pod)->body.type == type);
}
-static inline bool spa_pod_has_next(const void *pod, uint32_t size, const struct spa_pod *iter)
+
+static inline bool spa_pod_is_iter(const void *pod, uint32_t size, const struct spa_pod *iter)
{
return iter < SPA_MEMBER(pod, size, struct spa_pod);
}
@@ -63,18 +64,25 @@ static inline struct spa_pod *spa_pod_next(const struct spa_pod *iter)
#define SPA_POD_FOREACH(pod, size, iter) \
for ((iter) = (pod); \
- spa_pod_has_next(pod, size, iter); \
+ spa_pod_is_iter(pod, size, iter); \
(iter) = spa_pod_next(iter))
+#define SPA_POD_FOREACH_SAFE(pod, size, iter, tmp) \
+ for ((iter) = (pod), (tmp) = spa_pod_next(iter); \
+ spa_pod_is_iter(pod, size, iter); \
+ (iter) = (tmp), \
+ (tmp) = spa_pod_next(iter))
+
+
#define SPA_POD_CONTENTS_FOREACH(pod, offset, iter) \
SPA_POD_FOREACH(SPA_MEMBER((pod), (offset), struct spa_pod),SPA_POD_SIZE (pod)-(offset),iter)
#define SPA_POD_OBJECT_BODY_FOREACH(body, size, iter) \
for ((iter) = SPA_MEMBER((body), sizeof(struct spa_pod_object_body), struct spa_pod); \
- spa_pod_has_next(body, size, iter); \
+ spa_pod_is_iter(body, size, iter); \
(iter) = spa_pod_next(iter))
-#define SPA_POD_OBJECT_FOREACH(obj, iter) \
+#define SPA_POD_OBJECT_FOREACH(obj, iter) \
SPA_POD_OBJECT_BODY_FOREACH(&obj->body, SPA_POD_BODY_SIZE(obj), iter)
#define SPA_POD_PROP_ALTERNATIVE_FOREACH(body, _size, iter) \
diff --git a/spa/lib/debug.c b/spa/lib/debug.c
index 1d18032f..627b6320 100644
--- a/spa/lib/debug.c
+++ b/spa/lib/debug.c
@@ -259,11 +259,45 @@ print_pod_value(uint32_t size, uint32_t type, void *body, int prefix)
prefix + 4);
i = 0;
- SPA_POD_PROP_ALTERNATIVE_FOREACH(b, size, alt) {
- if (i == 0)
- printf("%-*sAlternatives:\n", prefix + 2, "");
- print_pod_value(b->value.size, b->value.type, alt, prefix + 4);
- i++;
+ switch (b->flags & SPA_POD_PROP_RANGE_MASK) {
+ case SPA_POD_PROP_RANGE_NONE:
+ break;
+ case SPA_POD_PROP_RANGE_MIN_MAX:
+ SPA_POD_PROP_ALTERNATIVE_FOREACH(b, size, alt) {
+ if (i == 0)
+ printf("%-*sMin: ", prefix + 2, "");
+ else if (i == 1)
+ printf("%-*sMax: ", prefix + 2, "");
+ else
+ break;
+ print_pod_value(b->value.size, b->value.type, alt, 0);
+ i++;
+ }
+ break;
+ case SPA_POD_PROP_RANGE_STEP:
+ SPA_POD_PROP_ALTERNATIVE_FOREACH(b, size, alt) {
+ if (i == 0)
+ printf("%-*sMin: ", prefix + 2, "");
+ else if (i == 1)
+ printf("%-*sMax: ", prefix + 2, "");
+ else if (i == 2)
+ printf("%-*sStep: ", prefix + 2, "");
+ else
+ break;
+ print_pod_value(b->value.size, b->value.type, alt, 0);
+ i++;
+ }
+ break;
+ case SPA_POD_PROP_RANGE_ENUM:
+ SPA_POD_PROP_ALTERNATIVE_FOREACH(b, size, alt) {
+ if (i == 0)
+ printf("%-*sEnum:\n", prefix + 2, "");
+ print_pod_value(b->value.size, b->value.type, alt, prefix + 4);
+ i++;
+ }
+ break;
+ case SPA_POD_PROP_RANGE_FLAGS:
+ break;
}
break;
}
diff --git a/spa/lib/format.c b/spa/lib/format.c
deleted file mode 100644
index cf5ffe59..00000000
--- a/spa/lib/format.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Simple Plugin API
- * Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
- *
- * 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 <stdint.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <lib/props.h>
-
-int
-spa_pod_object_filter(const struct spa_pod_object *obj,
- struct spa_pod_object *filter,
- struct spa_pod_builder *result)
-{
- int res;
-
- if (obj == NULL || result == NULL)
- return SPA_RESULT_INVALID_ARGUMENTS;
-
- if (filter == NULL) {
- spa_pod_builder_raw_padded(result, obj, SPA_POD_SIZE(obj));
- return SPA_RESULT_OK;
- }
-
- spa_pod_builder_push_object(result, obj->body.id, obj->body.type);
- res = spa_props_filter(result,
- SPA_POD_CONTENTS(struct spa_pod_object, obj),
- SPA_POD_CONTENTS_SIZE(struct spa_pod_object, obj),
- SPA_POD_CONTENTS(struct spa_pod_object, filter),
- SPA_POD_CONTENTS_SIZE(struct spa_pod_object, filter));
- spa_pod_builder_pop(result);
-
- return res;
-}
-
-int
-spa_pod_object_compare(const struct spa_pod_object *obj1,
- const struct spa_pod_object *obj2)
-{
- if (obj1 == NULL || obj2 == NULL)
- return SPA_RESULT_INVALID_ARGUMENTS;
-
- return spa_props_compare(SPA_POD_CONTENTS(struct spa_pod_object, obj1),
- SPA_POD_CONTENTS_SIZE(struct spa_pod_object, obj1),
- SPA_POD_CONTENTS(struct spa_pod_object, obj2),
- SPA_POD_CONTENTS_SIZE(struct spa_pod_object, obj2));
-}
diff --git a/spa/lib/meson.build b/spa/lib/meson.build
index 9acd00f0..8f85ae48 100644
--- a/spa/lib/meson.build
+++ b/spa/lib/meson.build
@@ -1,14 +1,12 @@
spalib_headers = [
'debug.h',
- 'format.h',
- 'props.h',
+ 'pod.h',
]
install_headers(spalib_headers, subdir : 'spa/lib')
spalib_sources = ['debug.c',
- 'props.c',
- 'format.c']
+ 'pod.c' ]
spalib = shared_library('spa-lib',
spalib_sources,
diff --git a/spa/lib/pod.c b/spa/lib/pod.c
new file mode 100644
index 00000000..671e83fc
--- /dev/null
+++ b/spa/lib/pod.c
@@ -0,0 +1,507 @@
+/* Simple Plugin API
+ * Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
+ *
+ * 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 <stdint.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <spa/props.h>
+#include <spa/pod-builder.h>
+
+static int compare_value(enum spa_pod_type type, const void *r1, const void *r2)
+{
+ switch (type) {
+ case SPA_POD_TYPE_INVALID:
+ return 0;
+ case SPA_POD_TYPE_BOOL:
+ case SPA_POD_TYPE_ID:
+ return *(int32_t *) r1 == *(uint32_t *) r2 ? 0 : 1;
+ case SPA_POD_TYPE_INT:
+ return *(int32_t *) r1 - *(int32_t *) r2;
+ case SPA_POD_TYPE_LONG:
+ return *(int64_t *) r1 - *(int64_t *) r2;
+ case SPA_POD_TYPE_FLOAT:
+ return *(float *) r1 - *(float *) r2;
+ case SPA_POD_TYPE_DOUBLE:
+ return *(double *) r1 - *(double *) r2;
+ case SPA_POD_TYPE_STRING:
+ return strcmp(r1, r2);
+ case SPA_POD_TYPE_RECTANGLE:
+ {
+ const struct spa_rectangle *rec1 = (struct spa_rectangle *) r1,
+ *rec2 = (struct spa_rectangle *) r2;
+ if (rec1->width == rec2->width && rec1->height == rec2->height)
+ return 0;
+ else if (rec1->width < rec2->width || rec1->height < rec2->height)
+ return -1;
+ else
+ return 1;
+ }
+ case SPA_POD_TYPE_FRACTION:
+ {
+ const struct spa_fraction *f1 = (struct spa_fraction *) r1,
+ *f2 = (struct spa_fraction *) r2;
+ int64_t n1, n2;
+ n1 = ((int64_t) f1->num) * f2->denom;
+ n2 = ((int64_t) f2->num) * f1->denom;
+ if (n1 < n2)
+ return -1;
+ else if (n1 > n2)
+ return 1;
+ else
+ return 0;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+static void fix_default(struct spa_pod_prop *prop)
+{
+ void *val = SPA_MEMBER(prop, sizeof(struct spa_pod_prop), void),
+ *alt = SPA_MEMBER(val, prop->body.value.size, void);
+ int i, nalt = SPA_POD_PROP_N_VALUES(prop) - 1;
+
+ switch (prop->body.flags & SPA_POD_PROP_RANGE_MASK) {
+ case SPA_POD_PROP_RANGE_NONE:
+ break;
+ case SPA_POD_PROP_RANGE_MIN_MAX:
+ case SPA_POD_PROP_RANGE_STEP:
+ if (compare_value(prop->body.value.type, val, alt) < 0)
+ memcpy(val, alt, prop->body.value.size);
+ alt = SPA_MEMBER(alt, prop->body.value.size, void);
+ if (compare_value(prop->body.value.type, val, alt) > 0)
+ memcpy(val, alt, prop->body.value.size);
+ break;
+ case SPA_POD_PROP_RANGE_ENUM:
+ {
+ void *best = NULL;
+
+ for (i = 0; i < nalt; i++) {
+ if (compare_value(prop->body.value.type, val, alt) == 0) {
+ best = alt;
+ break;
+ }
+ if (best == NULL)
+ best = alt;
+ alt = SPA_MEMBER(alt, prop->body.value.size, void);
+ }
+ if (best)
+ memcpy(val, best, prop->body.value.size);
+
+ if (nalt <= 1) {
+ prop->body.flags &= ~SPA_POD_PROP_FLAG_UNSET;
+ prop->body.flags &= ~SPA_POD_PROP_RANGE_MASK;
+ prop->body.flags |= SPA_POD_PROP_RANGE_NONE;
+ }
+ break;
+ }
+ case SPA_POD_PROP_RANGE_FLAGS:
+ break;
+ }
+}
+
+static inline struct spa_pod_prop *find_prop(const struct spa_pod *pod, uint32_t size, uint32_t key)
+{
+ const struct spa_pod *res;
+ SPA_POD_FOREACH(pod, size, res) {
+ if (res->type == SPA_POD_TYPE_PROP
+ && ((struct spa_pod_prop *) res)->body.key == key)
+ return (struct spa_pod_prop *) res;
+ }
+ return NULL;
+}
+
+static int
+filter_prop(struct spa_pod_builder *b,
+ const struct spa_pod_prop *p1,
+ const struct spa_pod_prop *p2)
+{
+ struct spa_pod_prop *np;
+ int nalt1, nalt2;
+ void *alt1, *alt2, *a1, *a2;
+ uint32_t rt1, rt2;
+ int j, k;
+
+ /* incompatible property types */
+ if (p1->body.value.type != p2->body.value.type)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ rt1 = p1->body.flags & SPA_POD_PROP_RANGE_MASK;
+ rt2 = p2->body.flags & SPA_POD_PROP_RANGE_MASK;
+
+ alt1 = SPA_MEMBER(p1, sizeof(struct spa_pod_prop), void);
+ nalt1 = SPA_POD_PROP_N_VALUES(p1);
+ alt2 = SPA_MEMBER(p2, sizeof(struct spa_pod_prop), void);
+ nalt2 = SPA_POD_PROP_N_VALUES(p2);
+
+ if (p1->body.flags & SPA_POD_PROP_FLAG_UNSET) {
+ alt1 = SPA_MEMBER(alt1, p1->body.value.size, void);
+ nalt1--;
+ } else {
+ nalt1 = 1;
+ rt1 = SPA_POD_PROP_RANGE_NONE;
+ }
+
+ if (p2->body.flags & SPA_POD_PROP_FLAG_UNSET) {
+ alt2 = SPA_MEMBER(alt2, p2->body.value.size, void);
+ nalt2--;
+ } else {
+ nalt2 = 1;
+ rt2 = SPA_POD_PROP_RANGE_NONE;
+ }
+
+ /* start with copying the property */
+ np = spa_pod_builder_deref(b, spa_pod_builder_push_prop(b, p1->body.key, 0));
+
+ /* default value */
+ spa_pod_builder_raw(b, &p1->body.value, sizeof(p1->body.value) + p1->body.value.size);
+
+ if ((rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_NONE) ||
+ (rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_ENUM) ||
+ (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_NONE) ||
+ (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_ENUM)) {
+ int n_copied = 0;
+ /* copy all equal values but don't copy the default value again */
+ for (j = 0, a1 = alt1; j < nalt1; j++, a1 += p1->body.value.size) {
+ for (k = 0, a2 = alt2; k < nalt2; k++, a2 += p2->body.value.size) {
+ if (compare_value(p1->body.value.type, a1, a2) == 0) {
+ if (rt1 == SPA_POD_PROP_RANGE_ENUM || j > 0)
+ spa_pod_builder_raw(b, a1, p1->body.value.size);
+ n_copied++;
+ }
+ }
+ }
+ if (n_copied == 0)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+ np->body.flags |= SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET;
+ }
+
+ if ((rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_MIN_MAX) ||
+ (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_MIN_MAX)) {
+ int n_copied = 0;
+ /* copy all values inside the range */
+ for (j = 0, a1 = alt1, a2 = alt2; j < nalt1; j++, a1 += p1->body.value.size) {
+ if (compare_value(p1->body.value.type, a1, a2) < 0)
+ continue;
+ if (compare_value(p1->body.value.type, a1, a2 + p2->body.value.size) > 0)
+ continue;
+ spa_pod_builder_raw(b, a1, p1->body.value.size);
+ n_copied++;
+ }
+ if (n_copied == 0)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+ np->body.flags |= SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET;
+ }
+
+ if ((rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_STEP) ||
+ (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_STEP)) {
+ return SPA_RESULT_NOT_IMPLEMENTED;
+ }
+
+ if ((rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_NONE) ||
+ (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_ENUM)) {
+ int n_copied = 0;
+ /* copy all values inside the range */
+ for (k = 0, a1 = alt1, a2 = alt2; k < nalt2; k++, a2 += p2->body.value.size) {
+ if (compare_value(p1->body.value.type, a2, a1) < 0)
+ continue;
+ if (compare_value(p1->body.value.type, a2, a1 + p1->body.value.size) > 0)
+ continue;
+ spa_pod_builder_raw(b, a2, p2->body.value.size);
+ n_copied++;
+ }
+ if (n_copied == 0)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+ np->body.flags |= SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET;
+ }
+
+ if (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_MIN_MAX) {
+ if (compare_value(p1->body.value.type, alt1, alt2) < 0)
+ spa_pod_builder_raw(b, alt2, p2->body.value.size);
+ else
+ spa_pod_builder_raw(b, alt1, p1->body.value.size);
+
+ alt1 += p1->body.value.size;
+ alt2 += p2->body.value.size;
+
+ if (compare_value(p1->body.value.type, alt1, alt2) < 0)
+ spa_pod_builder_raw(b, alt1, p1->body.value.size);
+ else
+ spa_pod_builder_raw(b, alt2, p2->body.value.size);
+
+ np->body.flags |= SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET;
+ }
+
+ if (rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_FLAGS)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+
+ if (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_STEP)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+
+ if (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_FLAGS)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+
+ if (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_FLAGS)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+
+ if (rt1 == SPA_POD_PROP_RANGE_STEP && rt2 == SPA_POD_PROP_RANGE_NONE)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+ if (rt1 == SPA_POD_PROP_RANGE_STEP && rt2 == SPA_POD_PROP_RANGE_MIN_MAX)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+
+ if (rt1 == SPA_POD_PROP_RANGE_STEP && rt2 == SPA_POD_PROP_RANGE_STEP)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+ if (rt1 == SPA_POD_PROP_RANGE_STEP && rt2 == SPA_POD_PROP_RANGE_ENUM)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+ if (rt1 == SPA_POD_PROP_RANGE_STEP && rt2 == SPA_POD_PROP_RANGE_FLAGS)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+
+ if (rt1 == SPA_POD_PROP_RANGE_FLAGS && rt2 == SPA_POD_PROP_RANGE_NONE)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+ if (rt1 == SPA_POD_PROP_RANGE_FLAGS && rt2 == SPA_POD_PROP_RANGE_MIN_MAX)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+ if (rt1 == SPA_POD_PROP_RANGE_FLAGS && rt2 == SPA_POD_PROP_RANGE_STEP)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+ if (rt1 == SPA_POD_PROP_RANGE_FLAGS && rt2 == SPA_POD_PROP_RANGE_ENUM)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+ if (rt1 == SPA_POD_PROP_RANGE_FLAGS && rt2 == SPA_POD_PROP_RANGE_FLAGS)
+ return SPA_RESULT_NOT_IMPLEMENTED;
+
+ spa_pod_builder_pop(b);
+ fix_default(np);
+
+ return SPA_RESULT_OK;
+}
+
+int pod_filter(struct spa_pod_builder *b,
+ const struct spa_pod *pod,
+ uint32_t pod_size,
+ const struct spa_pod *filter,
+ uint32_t filter_size)
+{
+ const struct spa_pod *pp, *pf, *tmp;
+ int res = SPA_RESULT_OK;
+
+ pf = filter;
+
+ SPA_POD_FOREACH_SAFE(pod, pod_size, pp, tmp) {
+ bool do_copy = false, do_filter = false, do_advance = false;
+ void *pc, *fc;
+ uint32_t pcs, fcs;
+
+ switch (SPA_POD_TYPE(pp)) {
+ case SPA_POD_TYPE_STRUCT:
+ if (pf != NULL) {
+ if (SPA_POD_TYPE(pf) != SPA_POD_TYPE_STRUCT)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ pc = SPA_POD_CONTENTS(struct spa_pod_struct, pp);
+ pcs = SPA_POD_CONTENTS_SIZE(struct spa_pod_struct, pp);
+ fc = SPA_POD_CONTENTS(struct spa_pod_struct, pf);
+ fcs = SPA_POD_CONTENTS_SIZE(struct spa_pod_struct, pf);
+
+ spa_pod_builder_push_struct(b);
+ do_filter = true;
+ do_advance = true;
+ }
+ else
+ do_copy = true;
+ break;
+ case SPA_POD_TYPE_OBJECT:
+ if (pf != NULL) {
+ struct spa_pod_object *p1;
+
+ p1 = (struct spa_pod_object *) pp;
+
+ if (SPA_POD_TYPE(pf) != SPA_POD_TYPE_OBJECT)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ pc = SPA_POD_CONTENTS(struct spa_pod_object, pp);
+ pcs = SPA_POD_CONTENTS_SIZE(struct spa_pod_object, pp);
+ fc = SPA_POD_CONTENTS(struct spa_pod_object, pf);
+ fcs = SPA_POD_CONTENTS_SIZE(struct spa_pod_object, pf);
+
+ spa_pod_builder_push_object(b, p1->body.id, p1->body.type);
+ do_filter = true;
+ do_advance = true;
+ }
+ else
+ do_copy = true;
+ break;
+
+ case SPA_POD_TYPE_PROP:
+ {
+ struct spa_pod_prop *p1, *p2;
+
+ p1 = (struct spa_pod_prop *) pp;
+ p2 = find_prop(filter, filter_size, p1->body.key);
+
+ if (p2 != NULL)
+ res = filter_prop(b, p1, p2);
+ else
+ do_copy = true;
+ break;
+ }
+ default:
+ if (pf != NULL) {
+ if (SPA_POD_SIZE(pp) != SPA_POD_SIZE(pf))
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+ if (memcmp(pp, pf, SPA_POD_SIZE(pp)) != 0)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+ do_advance = true;
+ }
+ do_copy = true;
+ break;
+ }
+ if (do_copy)
+ spa_pod_builder_raw_padded(b, pp, SPA_POD_SIZE(pp));
+ else if (do_filter) {
+ res = pod_filter(b, pc, pcs, fc, fcs);
+ spa_pod_builder_pop(b);
+ }
+ if (do_advance) {
+ pf = spa_pod_next(pf);
+ if (!spa_pod_is_iter(filter, filter_size, pf))
+ pf = NULL;
+ }
+
+ if (res < 0)
+ break;
+ }
+ return res;
+}
+
+int
+spa_pod_filter(struct spa_pod_builder *b,
+ const struct spa_pod *pod,
+ const struct spa_pod *filter)
+{
+ spa_return_val_if_fail(pod != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(b != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+
+ if (filter == NULL) {
+ spa_pod_builder_raw_padded(b, pod, SPA_POD_SIZE(pod));
+ return SPA_RESULT_OK;
+ }
+ return pod_filter(b, pod, SPA_POD_SIZE(pod), filter, SPA_POD_SIZE(filter));
+
+}
+
+int pod_compare(const struct spa_pod *pod1,
+ uint32_t pod1_size,
+ const struct spa_pod *pod2,
+ uint32_t pod2_size)
+{
+ const struct spa_pod *p1, *p2;
+ int res;
+
+ p2 = pod2;
+
+ SPA_POD_FOREACH(pod1, pod1_size, p1) {
+ bool do_recurse = false, do_advance = true;
+ void *a1, *a2;
+ void *p1c, *p2c;
+ uint32_t p1cs, p2cs;
+
+ if (p2 == NULL)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ switch (SPA_POD_TYPE(p1)) {
+ case SPA_POD_TYPE_STRUCT:
+ if (SPA_POD_TYPE(p2) != SPA_POD_TYPE_STRUCT)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ p1c = SPA_POD_CONTENTS(struct spa_pod_struct, p1);
+ p1cs = SPA_POD_CONTENTS_SIZE(struct spa_pod_struct, p1);
+ p2c = SPA_POD_CONTENTS(struct spa_pod_struct, p2);
+ p2cs = SPA_POD_CONTENTS_SIZE(struct spa_pod_struct, p2);
+ do_recurse = true;
+ do_advance = true;
+ break;
+ case SPA_POD_TYPE_OBJECT:
+ if (SPA_POD_TYPE(p2) != SPA_POD_TYPE_OBJECT)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ p1c = SPA_POD_CONTENTS(struct spa_pod_object, p1);
+ p1cs = SPA_POD_CONTENTS_SIZE(struct spa_pod_object, p1);
+ p2c = SPA_POD_CONTENTS(struct spa_pod_object, p2);
+ p2cs = SPA_POD_CONTENTS_SIZE(struct spa_pod_object, p2);
+ do_recurse = true;
+ do_advance = true;
+ break;
+ case SPA_POD_TYPE_PROP:
+ {
+ struct spa_pod_prop *pr1, *pr2;
+
+ pr1 = (struct spa_pod_prop *) p1;
+ pr2 = find_prop(pod2, pod2_size, pr1->body.key);
+
+ if (pr2 == NULL)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ /* incompatible property types */
+ if (pr1->body.value.type != pr2->body.value.type)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ if (pr1->body.flags & SPA_POD_PROP_FLAG_UNSET ||
+ pr2->body.flags & SPA_POD_PROP_FLAG_UNSET)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ a1 = SPA_MEMBER(pr1, sizeof(struct spa_pod_prop), void);
+ a2 = SPA_MEMBER(pr2, sizeof(struct spa_pod_prop), void);
+
+ res = compare_value(pr1->body.value.type, a1, a2);
+ break;
+ }
+ default:
+ if (SPA_POD_TYPE(p1) != SPA_POD_TYPE(p2))
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ res = compare_value(SPA_POD_TYPE(p1), SPA_POD_BODY(p1), SPA_POD_BODY(p2));
+ do_advance = true;
+ break;
+ }
+ if (do_advance) {
+ p2 = spa_pod_next(p2);
+ if (!spa_pod_is_iter(pod2, pod2_size, p2))
+ p2 = NULL;
+ }
+ if (do_recurse) {
+ res = pod_compare(p1c, p1cs, p2c, p2cs);
+ }
+ if (res != 0)
+ return res;
+ }
+ if (p2 != NULL)
+ return SPA_RESULT_INCOMPATIBLE_PROPS;
+
+ return SPA_RESULT_OK;
+}
+
+int spa_pod_compare(const struct spa_pod *pod1,
+ const struct spa_pod *pod2)
+{
+ spa_return_val_if_fail(pod1 != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(pod2 != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+
+ return pod_compare(pod1, SPA_POD_SIZE(pod1), pod2, SPA_POD_SIZE(pod2));
+}
diff --git a/spa/lib/format.h b/spa/lib/pod.h
index 35a08f62..aa6f6d10 100644
--- a/spa/lib/format.h
+++ b/spa/lib/pod.h
@@ -1,5 +1,5 @@
/* Simple Plugin API
- * Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
+ * Copyright (C) 2017 Wim Taymans <wim.taymans@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -17,24 +17,25 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef __SPA_LIBFORMAT_H__
-#define __SPA_LIBFORMAT_H__
+#ifndef __SPA_LIBPOD_H__
+#define __SPA_LIBPOD_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/props.h>
+#include <spa/pod-builder.h>
-int spa_pod_object_filter(const struct spa_pod_object *obj,
- const struct spa_pod_object *filter,
- struct spa_pod_builder *result);
+int spa_pod_filter(struct spa_pod_builder *b,
+ const struct spa_pod *pod,
+ const struct spa_pod *filter);
-int spa_pod_object_compare(const struct spa_pod_object *obj1,
- const struct spa_pod_object *obj2);
+int spa_pod_compare(const struct spa_pod *pod1,
+ const struct spa_pod *pod2);
#ifdef __cplusplus
} /* extern "C" */
#endif
-#endif /* __SPA_LIBFORMAT_H__ */
+#endif /* __SPA_LIBPOD_H__ */
diff --git a/spa/lib/props.c b/spa/lib/props.c
deleted file mode 100644
index 40494edf..00000000
--- a/spa/lib/props.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/* Simple Plugin API
- * Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
- *
- * 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 <stdint.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <spa/props.h>
-#include <spa/pod-builder.h>
-
-static int compare_value(enum spa_pod_type type, const void *r1, const void *r2)
-{
- switch (type) {
- case SPA_POD_TYPE_INVALID:
- return 0;
- case SPA_POD_TYPE_BOOL:
- case SPA_POD_TYPE_ID:
- return *(int32_t *) r1 == *(uint32_t *) r2 ? 0 : 1;
- case SPA_POD_TYPE_INT:
- return *(int32_t *) r1 - *(int32_t *) r2;
- case SPA_POD_TYPE_LONG:
- return *(int64_t *) r1 - *(int64_t *) r2;
- case SPA_POD_TYPE_FLOAT:
- return *(float *) r1 - *(float *) r2;
- case SPA_POD_TYPE_DOUBLE:
- return *(double *) r1 - *(double *) r2;
- case SPA_POD_TYPE_STRING:
- return strcmp(r1, r2);
- case SPA_POD_TYPE_RECTANGLE:
- {
- const struct spa_rectangle *rec1 = (struct spa_rectangle *) r1,
- *rec2 = (struct spa_rectangle *) r2;
- if (rec1->width == rec2->width && rec1->height == rec2->height)
- return 0;
- else if (rec1->width < rec2->width || rec1->height < rec2->height)
- return -1;
- else
- return 1;
- }
- case SPA_POD_TYPE_FRACTION:
- {
- const struct spa_fraction *f1 = (struct spa_fraction *) r1,
- *f2 = (struct spa_fraction *) r2;
- int64_t n1, n2;
- n1 = ((int64_t) f1->num) * f2->denom;
- n2 = ((int64_t) f2->num) * f1->denom;
- if (n1 < n2)
- return -1;
- else if (n1 > n2)
- return 1;
- else
- return 0;
- }
- default:
- break;
- }
- return 0;
-}
-
-static void fix_default(struct spa_pod_prop *prop)
-{
- void *val = SPA_MEMBER(prop, sizeof(struct spa_pod_prop), void),
- *alt = SPA_MEMBER(val, prop->body.value.size, void);
- int i, nalt = SPA_POD_PROP_N_VALUES(prop) - 1;
-
- switch (prop->body.flags & SPA_POD_PROP_RANGE_MASK) {
- case SPA_POD_PROP_RANGE_NONE:
- break;
- case SPA_POD_PROP_RANGE_MIN_MAX:
- case SPA_POD_PROP_RANGE_STEP:
- if (compare_value(prop->body.value.type, val, alt) < 0)
- memcpy(val, alt, prop->body.value.size);
- alt = SPA_MEMBER(alt, prop->body.value.size, void);
- if (compare_value(prop->body.value.type, val, alt) > 0)
- memcpy(val, alt, prop->body.value.size);
- break;
- case SPA_POD_PROP_RANGE_ENUM:
- {
- void *best = NULL;
-
- for (i = 0; i < nalt; i++) {
- if (compare_value(prop->body.value.type, val, alt) == 0) {
- best = alt;
- break;
- }
- if (best == NULL)
- best = alt;
- alt = SPA_MEMBER(alt, prop->body.value.size, void);
- }
- if (best)
- memcpy(val, best, prop->body.value.size);
-
- if (nalt == 1) {
- prop->body.flags &= ~SPA_POD_PROP_FLAG_UNSET;
- prop->body.flags &= ~SPA_POD_PROP_RANGE_MASK;
- prop->body.flags |= SPA_POD_PROP_RANGE_NONE;
- }
- break;
- }
- case SPA_POD_PROP_RANGE_FLAGS:
- break;
- }
-}
-
-static inline struct spa_pod_prop *find_prop(const struct spa_pod *pod, uint32_t size, uint32_t key)
-{
- const struct spa_pod *res;
- SPA_POD_FOREACH(pod, size, res) {
- if (res->type == SPA_POD_TYPE_PROP
- && ((struct spa_pod_prop *) res)->body.key == key)
- return (struct spa_pod_prop *) res;
- }
- return NULL;
-}
-
-int
-spa_props_filter(struct spa_pod_builder *b,
- const struct spa_pod *props,
- uint32_t props_size,
- const struct spa_pod *filter,
- uint32_t filter_size)
-{
- int j, k;
- const struct spa_pod *pp, *pf;
-
- pf = filter;
-
- SPA_POD_FOREACH(props, props_size, pp) {
- struct spa_pod_prop *p1, *p2, *np;
- int nalt1, nalt2;
- void *alt1, *alt2, *a1, *a2;
- uint32_t rt1, rt2;
-
- if (pp->type != SPA_POD_TYPE_PROP) {
- if (pf != NULL) {
- if (SPA_POD_SIZE(pp) != SPA_POD_SIZE(pf))
- return SPA_RESULT_INCOMPATIBLE_PROPS;
-
- if (memcmp(pf, pp, SPA_POD_SIZE(pp)) != 0)
- return SPA_RESULT_INCOMPATIBLE_PROPS;
-
- if (spa_pod_has_next(filter, filter_size, pf))
- pf = spa_pod_next(pf);
- else
- pf = NULL;
- }
- spa_pod_builder_raw_padded(b, pp, SPA_POD_SIZE(pp));
- continue;
- }
-
- p1 = (struct spa_pod_prop *) pp;
-
- if (filter == NULL || (p2 = find_prop(filter, filter_size, p1->body.key)) == NULL) {
- /* no filter, copy the complete property */
- spa_pod_builder_raw_padded(b, p1, SPA_POD_SIZE(p1));
- continue;
- }
-
- /* incompatible property types */
- if (p1->body.value.type != p2->body.value.type)
- return SPA_RESULT_INCOMPATIBLE_PROPS;
-
- rt1 = p1->body.flags & SPA_POD_PROP_RANGE_MASK;
- rt2 = p2->body.flags & SPA_POD_PROP_RANGE_MASK;
-
- /* else we filter. start with copying the property */
- np = spa_pod_builder_deref(b,
- spa_pod_builder_push_prop(b, p1->body.key, 0));
-
- /* default value */
- spa_pod_builder_raw(b, &p1->body.value,
- sizeof(p1->body.value) + p1->body.value.size);
-
- alt1 = SPA_MEMBER(p1, sizeof(struct spa_pod_prop), void);
- nalt1 = SPA_POD_PROP_N_VALUES(p1);
- alt2 = SPA_MEMBER(p2, sizeof(struct spa_pod_prop), void);
- nalt2 = SPA_POD_PROP_N_VALUES(p2);
-
- if (p1->body.flags & SPA_POD_PROP_FLAG_UNSET) {
- alt1 = SPA_MEMBER(alt1, p1->body.value.size, void);
- nalt1--;
- } else {
- nalt1 = 1;
- rt1 = SPA_POD_PROP_RANGE_NONE;
- }
-
- if (p2->body.flags & SPA_POD_PROP_FLAG_UNSET) {
- alt2 = SPA_MEMBER(alt2, p2->body.value.size, void);
- nalt2--;
- } else {
- nalt2 = 1;
- rt2 = SPA_POD_PROP_RANGE_NONE;
- }
-
- if ((rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_NONE) ||
- (rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_ENUM) ||
- (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_NONE) ||
- (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_ENUM)) {
- int n_copied = 0;
- /* copy all equal values */
- for (j = 0, a1 = alt1; j < nalt1; j++, a1 += p1->body.value.size) {
- for (k = 0, a2 = alt2; k < nalt2; k++, a2 += p2->body.value.size) {
- if (compare_value(p1->body.value.type, a1, a2) == 0) {
- spa_pod_builder_raw(b, a1, p1->body.value.size);
- n_copied++;
- }
- }
- }
- if (n_copied == 0)
- return SPA_RESULT_INCOMPATIBLE_PROPS;
- np->body.flags |= SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET;
- }
-
- if ((rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_MIN_MAX) ||
- (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_MIN_MAX)) {
- int n_copied = 0;
- /* copy all values inside the range */
- for (j = 0, a1 = alt1, a2 = alt2; j < nalt1; j++, a1 += p1->body.value.size) {
- if (compare_value(p1->body.value.type, a1, a2) < 0)
- continue;
- if (compare_value(p1->body.value.type, a1, a2 + p2->body.value.size)
- > 0)
- continue;
- spa_pod_builder_raw(b, a1, p1->body.value.size);
- n_copied++;
- }
- if (n_copied == 0)
- return SPA_RESULT_INCOMPATIBLE_PROPS;
- np->body.flags |= SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET;
- }
-
- if ((rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_STEP) ||
- (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_STEP)) {
- return SPA_RESULT_NOT_IMPLEMENTED;
- }
-
- if ((rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_NONE) ||
- (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_ENUM)) {
- int n_copied = 0;
- /* copy all values inside the range */
- for (k = 0, a1 = alt1, a2 = alt2; k < nalt2; k++, a2 += p2->body.value.size) {
- if (compare_value(p1->body.value.type, a2, a1) < 0)
- continue;
- if (compare_value(p1->body.value.type, a2, a1 + p1->body.value.size)
- > 0)
- continue;
- spa_pod_builder_raw(b, a2, p2->body.value.size);
- n_copied++;
- }
- if (n_copied == 0)
- return SPA_RESULT_INCOMPATIBLE_PROPS;
- np->body.flags |= SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET;
- }
-
- if (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_MIN_MAX) {
- if (compare_value(p1->body.value.type, alt1, alt2) < 0)
- spa_pod_builder_raw(b, alt2, p2->body.value.size);
- else
- spa_pod_builder_raw(b, alt1, p1->body.value.size);
-
- alt1 += p1->body.value.size;
- alt2 += p2->body.value.size;
-
- if (compare_value(p1->body.value.type, alt1, alt2) < 0)
- spa_pod_builder_raw(b, alt1, p1->body.value.size);
- else
- spa_pod_builder_raw(b, alt2, p2->body.value.size);
-
- np->body.flags |= SPA_POD_PROP_RANGE_MIN_MAX | SPA_POD_PROP_FLAG_UNSET;
- }
-
- if (rt1 == SPA_POD_PROP_RANGE_NONE && rt2 == SPA_POD_PROP_RANGE_FLAGS)
- return SPA_RESULT_NOT_IMPLEMENTED;
-
- if (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_STEP)
- return SPA_RESULT_NOT_IMPLEMENTED;
-
- if (rt1 == SPA_POD_PROP_RANGE_MIN_MAX && rt2 == SPA_POD_PROP_RANGE_FLAGS)
- return SPA_RESULT_NOT_IMPLEMENTED;
-
- if (rt1 == SPA_POD_PROP_RANGE_ENUM && rt2 == SPA_POD_PROP_RANGE_FLAGS)
- return SPA_RESULT_NOT_IMPLEMENTED;
-
- if (rt1 == SPA_POD_PROP_RANGE_STEP && rt2 == SPA_POD_PROP_RANGE_NONE)
- return SPA_RESULT_NOT_IMPLEMENTED;
- if (rt1 == SPA_POD_PROP_RANGE_STEP && rt2 == SPA_POD_PROP_RANGE_MIN_MAX)
- return SPA_RESULT_NOT_IMPLEMENTED;
-
- if (rt1 == SPA_POD_PROP_RANGE_STEP && rt2 == SPA_POD_PROP_RANGE_STEP)
- return SPA_RESULT_NOT_IMPLEMENTED;
- if (rt1 == SPA_POD_PROP_RANGE_STEP && rt2 == SPA_POD_PROP_RANGE_ENUM)
- return SPA_RESULT_NOT_IMPLEMENTED;
- if (rt1 == SPA_POD_PROP_RANGE_STEP && rt2 == SPA_POD_PROP_RANGE_FLAGS)
- return SPA_RESULT_NOT_IMPLEMENTED;
-
- if (rt1 == SPA_POD_PROP_RANGE_FLAGS && rt2 == SPA_POD_PROP_RANGE_NONE)
- return SPA_RESULT_NOT_IMPLEMENTED;
- if (rt1 == SPA_POD_PROP_RANGE_FLAGS && rt2 == SPA_POD_PROP_RANGE_MIN_MAX)
- return SPA_RESULT_NOT_IMPLEMENTED;
- if (rt1 == SPA_POD_PROP_RANGE_FLAGS && rt2 == SPA_POD_PROP_RANGE_STEP)
- return SPA_RESULT_NOT_IMPLEMENTED;
- if (rt1 == SPA_POD_PROP_RANGE_FLAGS && rt2 == SPA_POD_PROP_RANGE_ENUM)
- return SPA_RESULT_NOT_IMPLEMENTED;
- if (rt1 == SPA_POD_PROP_RANGE_FLAGS && rt2 == SPA_POD_PROP_RANGE_FLAGS)
- return SPA_RESULT_NOT_IMPLEMENTED;
-
- spa_pod_builder_pop(b);
- fix_default(np);
- }
- return SPA_RESULT_OK;
-}
-
-int spa_props_compare(const struct spa_pod *props1,
- uint32_t props1_size,
- const struct spa_pod *props2,
- uint32_t props2_size)
-{
- const struct spa_pod *pr;
-
- SPA_POD_FOREACH(props1, props1_size, pr) {
- struct spa_pod_prop *p1, *p2;
- void *a1, *a2;
-
- if (pr->type != SPA_POD_TYPE_PROP)
- continue;
-
- p1 = (struct spa_pod_prop *) pr;
-
- if ((p2 = find_prop(props2, props2_size, p1->body.key)) == NULL)
- return SPA_RESULT_INCOMPATIBLE_PROPS;
-
- /* incompatible property types */
- if (p1->body.value.type != p2->body.value.type)
- return SPA_RESULT_INCOMPATIBLE_PROPS;
-
- if (p1->body.flags & SPA_POD_PROP_FLAG_UNSET ||
- p2->body.flags & SPA_POD_PROP_FLAG_UNSET)
- return SPA_RESULT_INCOMPATIBLE_PROPS;
-
- a1 = SPA_MEMBER(p1, sizeof(struct spa_pod_prop), void);
- a2 = SPA_MEMBER(p2, sizeof(struct spa_pod_prop), void);
-
- if (compare_value(p1->body.value.type, a1, a2) != 0)
- return SPA_RESULT_INCOMPATIBLE_PROPS;
- }
- return SPA_RESULT_OK;
-}
diff --git a/spa/lib/props.h b/spa/lib/props.h
deleted file mode 100644
index ec31b7ca..00000000
--- a/spa/lib/props.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Simple Plugin API
- * Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
- *
- * 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_LIBPROPS_H__
-#define __SPA_LIBPROPS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <spa/props.h>
-#include <spa/pod-builder.h>
-
-int spa_props_filter(struct spa_pod_builder *b,
- const struct spa_pod *props,
- uint32_t props_size,
- const struct spa_pod *filter,
- uint32_t filter_size);
-
-int spa_props_compare(const struct spa_pod *props1,
- uint32_t props1_size,
- const struct spa_pod *props2,
- uint32_t props2_size);
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* __SPA_LIBPROPS_H__ */
diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c
index 5c1430ba..5e319c06 100644
--- a/spa/plugins/alsa/alsa-sink.c
+++ b/spa/plugins/alsa/alsa-sink.c
@@ -23,7 +23,7 @@
#include <spa/node.h>
#include <spa/audio/format.h>
-#include <lib/props.h>
+#include <lib/pod.h>
#define NAME "alsa-sink"
@@ -49,6 +49,8 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct state *this;
struct type *t;
+ struct spa_pod *param;
+ uint32_t offset;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -57,11 +59,14 @@ static int impl_node_enum_params(struct spa_node *node,
this = SPA_CONTAINER_OF(node, struct state, node);
t = &this->type;
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param.List,
":", t->param.listId, "I", t->param.idProps);
}
@@ -71,21 +76,25 @@ static int impl_node_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
- id, t->props,
- ":", t->prop_device, "S", p->device, sizeof(p->device),
- ":", t->prop_device_name, "S-r", p->device_name, sizeof(p->device_name),
- ":", t->prop_card_name, "S-r", p->card_name, sizeof(p->card_name),
- ":", t->prop_min_latency, "ir", p->min_latency,
- 2, 1, INT32_MAX,
- ":", t->prop_max_latency, "ir", p->max_latency,
- 2, 1, INT32_MAX);
+ param = spa_pod_builder_object(builder,
+ id, t->props,
+ ":", t->prop_device, "S", p->device, sizeof(p->device),
+ ":", t->prop_device_name, "S-r", p->device_name, sizeof(p->device_name),
+ ":", t->prop_card_name, "S-r", p->card_name, sizeof(p->card_name),
+ ":", t->prop_min_latency, "ir", p->min_latency,
+ 2, 1, INT32_MAX,
+ ":", t->prop_max_latency, "ir", p->max_latency,
+ 2, 1, INT32_MAX);
}
else
return SPA_RESULT_UNKNOWN_PARAM;
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
@@ -261,31 +270,6 @@ impl_node_port_get_info(struct spa_node *node,
return SPA_RESULT_OK;
}
-static int port_get_format(struct spa_node *node,
- enum spa_direction direction, uint32_t port_id,
- uint32_t *index,
- const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
-{
- struct state *this = SPA_CONTAINER_OF(node, struct state, node);
- struct type *t = &this->type;
-
- if (!this->have_format)
- return SPA_RESULT_NO_FORMAT;
- if (*index > 0)
- return SPA_RESULT_ENUM_END;
-
- spa_pod_builder_object(builder,
- t->param.idFormat, t->format,
- "I", t->media_type.audio,
- "I", 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;
-}
-
static int
impl_node_port_enum_params(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
@@ -296,6 +280,8 @@ impl_node_port_enum_params(struct spa_node *node,
struct state *this;
struct type *t;
+ struct spa_pod *param;
+ uint32_t offset;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -306,6 +292,9 @@ impl_node_port_enum_params(struct spa_node *node,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat,
@@ -313,7 +302,7 @@ impl_node_port_enum_params(struct spa_node *node,
t->param.idMeta };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
@@ -322,7 +311,18 @@ impl_node_port_enum_params(struct spa_node *node,
return spa_alsa_enum_format(this, index, filter, builder);
}
else if (id == t->param.idFormat) {
- return port_get_format(node, direction, port_id, index, filter, builder);
+ if (!this->have_format)
+ return SPA_RESULT_NO_FORMAT;
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ param = spa_pod_builder_object(builder,
+ t->param.idFormat, t->format,
+ "I", t->media_type.audio,
+ "I", 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);
}
else if (id == t->param.idBuffers) {
if (!this->have_format)
@@ -330,7 +330,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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,
@@ -346,13 +346,13 @@ impl_node_port_enum_params(struct spa_node *node,
switch (*index) {
case 0:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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 1:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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),
@@ -373,6 +373,10 @@ impl_node_port_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
diff --git a/spa/plugins/alsa/alsa-source.c b/spa/plugins/alsa/alsa-source.c
index 8ff5c59c..a1bcb228 100644
--- a/spa/plugins/alsa/alsa-source.c
+++ b/spa/plugins/alsa/alsa-source.c
@@ -24,7 +24,8 @@
#include <spa/node.h>
#include <spa/list.h>
#include <spa/audio/format.h>
-#include <lib/props.h>
+
+#include <lib/pod.h>
#define NAME "alsa-source"
@@ -48,6 +49,8 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct state *this;
struct type *t;
+ struct spa_pod *param;
+ uint32_t offset;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -56,11 +59,14 @@ static int impl_node_enum_params(struct spa_node *node,
this = SPA_CONTAINER_OF(node, struct state, node);
t = &this->type;
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param.List,
":", t->param.listId, "I", t->param.idProps);
}
@@ -70,7 +76,7 @@ static int impl_node_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->props,
":", t->prop_device, "S", p->device, sizeof(p->device),
":", t->prop_device_name, "S-r", p->device_name, sizeof(p->device_name),
@@ -83,6 +89,10 @@ static int impl_node_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
@@ -290,7 +300,7 @@ static void recycle_buffer(struct state *this, uint32_t buffer_id)
static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
- const struct spa_pod_object *filter,
+ struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct state *this = SPA_CONTAINER_OF(node, struct state, node);
@@ -301,7 +311,7 @@ static int port_get_format(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ *param = spa_pod_builder_object(builder,
t->param.idFormat, t->format,
"I", t->media_type.audio,
"I", t->media_subtype.raw,
@@ -321,6 +331,9 @@ impl_node_port_enum_params(struct spa_node *node,
{
struct state *this;
struct type *t;
+ struct spa_pod *param;
+ uint32_t offset;
+ int res;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -331,6 +344,9 @@ impl_node_port_enum_params(struct spa_node *node,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat,
@@ -338,7 +354,7 @@ impl_node_port_enum_params(struct spa_node *node,
t->param.idMeta };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
@@ -347,7 +363,8 @@ impl_node_port_enum_params(struct spa_node *node,
return spa_alsa_enum_format(this, index, filter, builder);
}
else if (id == t->param.idFormat) {
- return port_get_format(node, direction, port_id, index, filter, builder);
+ if ((res = port_get_format(node, direction, port_id, index, &param, builder)) < 0)
+ return res;
}
else if (id == t->param.idBuffers) {
if (!this->have_format)
@@ -355,7 +372,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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,
@@ -369,7 +386,7 @@ impl_node_port_enum_params(struct spa_node *node,
switch (*index) {
case 0:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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));
@@ -383,6 +400,10 @@ impl_node_port_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
diff --git a/spa/plugins/alsa/alsa-utils.c b/spa/plugins/alsa/alsa-utils.c
index 191ced23..c78f1917 100644
--- a/spa/plugins/alsa/alsa-utils.c
+++ b/spa/plugins/alsa/alsa-utils.c
@@ -10,7 +10,7 @@
#include <sys/timerfd.h>
#include <lib/debug.h>
-#include <lib/format.h>
+#include <lib/pod.h>
#include "alsa-utils.h"
@@ -202,7 +202,7 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
(*index)++;
- if ((res = spa_pod_object_filter(fmt, filter, builder)) < 0)
+ if ((res = spa_pod_filter(builder, (struct spa_pod*)fmt, (struct spa_pod*)filter)) < 0)
goto next;
if (!opened)
diff --git a/spa/plugins/audiomixer/audiomixer.c b/spa/plugins/audiomixer/audiomixer.c
index 01e99900..c51d12c6 100644
--- a/spa/plugins/audiomixer/audiomixer.c
+++ b/spa/plugins/audiomixer/audiomixer.c
@@ -25,10 +25,10 @@
#include <spa/type-map.h>
#include <spa/node.h>
#include <spa/audio/format-utils.h>
-#include <lib/format.h>
-#include <lib/props.h>
#include <spa/param-alloc.h>
+#include <lib/pod.h>
+
#include "conv.h"
#define NAME "audiomixer"
@@ -323,22 +323,15 @@ impl_node_port_get_info(struct spa_node *node,
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
- const struct spa_pod_object *filter,
+ struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
- struct spa_pod_object *fmt;
- uint8_t buffer[256];
- struct spa_pod_builder b = { NULL, };
struct type *t = &this->type;
- int res;
-
- next:
- spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (*index) {
case 0:
- fmt = spa_pod_builder_object(&b,
+ *param = spa_pod_builder_object(builder,
t->param.idEnumFormat, t->format,
"I", t->media_type.audio,
"I", t->media_subtype.raw,
@@ -353,19 +346,13 @@ static int port_enum_formats(struct spa_node *node,
default:
return SPA_RESULT_ENUM_END;
}
-
- (*index)++;
-
- if ((res = spa_pod_object_filter(fmt, filter, builder)) != SPA_RESULT_OK)
- goto next;
-
return SPA_RESULT_OK;
}
static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
- const struct spa_pod_object *filter,
+ struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
@@ -377,7 +364,7 @@ static int port_get_format(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ *param = spa_pod_builder_object(builder,
t->param.idFormat, t->format,
"I", t->media_type.audio,
"I", t->media_subtype.raw,
@@ -398,6 +385,9 @@ impl_node_port_enum_params(struct spa_node *node,
struct impl *this;
struct type *t;
struct port *port;
+ struct spa_pod *param;
+ uint32_t offset;
+ int res;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -410,6 +400,9 @@ impl_node_port_enum_params(struct spa_node *node,
port = GET_PORT(this, direction, port_id);
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat,
@@ -417,16 +410,18 @@ impl_node_port_enum_params(struct spa_node *node,
t->param.idMeta };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
}
else if (id == t->param.idEnumFormat) {
- return port_enum_formats(node, direction, port_id, index, filter, builder);
+ if ((res = port_enum_formats(node, direction, port_id, index, &param, builder)) < 0)
+ return res;
}
else if (id == t->param.idFormat) {
- return port_get_format(node, direction, port_id, index, filter, builder);
+ if ((res = port_get_format(node, direction, port_id, index, &param, builder)) < 0)
+ return res;
}
else if (id == t->param.idBuffers) {
if (!port->have_format)
@@ -434,7 +429,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param_alloc_buffers.Buffers,
":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
2, 16 * this->bpf,
@@ -450,13 +445,13 @@ impl_node_port_enum_params(struct spa_node *node,
switch (*index) {
case 0:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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 1:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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),
@@ -475,6 +470,10 @@ impl_node_port_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c
index 1ca581f4..e2a58561 100644
--- a/spa/plugins/audiotestsrc/audiotestsrc.c
+++ b/spa/plugins/audiotestsrc/audiotestsrc.c
@@ -32,8 +32,7 @@
#include <spa/list.h>
#include <spa/audio/format-utils.h>
-#include <lib/format.h>
-#include <lib/props.h>
+#include <lib/pod.h>
#define NAME "audiotestsrc"
@@ -173,6 +172,8 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct impl *this;
struct type *t;
+ uint32_t offset;
+ struct spa_pod *param;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -181,11 +182,14 @@ static int impl_node_enum_params(struct spa_node *node,
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param.List,
":", t->param.listId, "I", t->param.idProps);
}
@@ -195,7 +199,7 @@ static int impl_node_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->props,
":", t->prop_live, "b", p->live,
":", t->prop_wave, "Ie", p->wave,
@@ -211,6 +215,10 @@ static int impl_node_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
@@ -507,21 +515,14 @@ static int
port_enum_formats(struct impl *this,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
- const struct spa_pod_object *filter,
+ struct spa_pod **param,
struct spa_pod_builder *builder)
{
- struct spa_pod_object *fmt;
struct type *t = &this->type;
- uint8_t buffer[1024];
- struct spa_pod_builder b = { 0 };
- int res;
-
- next:
- spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (*index) {
case 0:
- fmt = spa_pod_builder_object(&b,
+ *param = spa_pod_builder_object(builder,
t->param.idEnumFormat, t->format,
"I", t->media_type.audio,
"I", t->media_subtype.raw,
@@ -538,12 +539,6 @@ port_enum_formats(struct impl *this,
default:
return SPA_RESULT_ENUM_END;
}
-
- (*index)++;
-
- if ((res = spa_pod_object_filter(fmt, filter, builder)) != SPA_RESULT_OK)
- goto next;
-
return SPA_RESULT_OK;
}
@@ -552,7 +547,7 @@ port_get_format(struct impl *this,
enum spa_direction direction,
uint32_t port_id,
uint32_t *index,
- const struct spa_pod_object *filter,
+ struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct type *t = &this->type;
@@ -563,7 +558,7 @@ port_get_format(struct impl *this,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ *param = spa_pod_builder_object(builder,
t->param.idFormat, t->format,
"I", t->media_type.audio,
"I", t->media_subtype.raw,
@@ -583,6 +578,9 @@ impl_node_port_enum_params(struct spa_node *node,
{
struct impl *this;
struct type *t;
+ uint32_t offset;
+ struct spa_pod *param;
+ int res;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -593,6 +591,9 @@ impl_node_port_enum_params(struct spa_node *node,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat,
@@ -600,16 +601,18 @@ impl_node_port_enum_params(struct spa_node *node,
t->param.idMeta };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
}
else if (id == t->param.idEnumFormat) {
- return port_enum_formats(this, direction, port_id, index, filter, builder);
+ if ((res = port_enum_formats(this, direction, port_id, index, &param, builder)) < 0)
+ return res;
}
else if (id == t->param.idFormat) {
- return port_get_format(this, direction, port_id, index, filter, builder);
+ if ((res = port_get_format(this, direction, port_id, index, &param, builder)) < 0)
+ return res;
}
else if (id == t->param.idBuffers) {
if (!this->have_format)
@@ -617,7 +620,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param_alloc_buffers.Buffers,
":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
2, 16 * this->bpf,
@@ -633,13 +636,13 @@ impl_node_port_enum_params(struct spa_node *node,
switch (*index) {
case 0:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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 1:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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),
@@ -658,6 +661,10 @@ impl_node_port_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
diff --git a/spa/plugins/ffmpeg/ffmpeg-dec.c b/spa/plugins/ffmpeg/ffmpeg-dec.c
index 46891d7c..642dfd83 100644
--- a/spa/plugins/ffmpeg/ffmpeg-dec.c
+++ b/spa/plugins/ffmpeg/ffmpeg-dec.c
@@ -26,7 +26,7 @@
#include <spa/log.h>
#include <spa/node.h>
#include <spa/video/format-utils.h>
-#include <lib/props.h>
+#include <lib/pod.h>
#define IS_VALID_PORT(this,d,id) ((id) == 0)
#define MAX_BUFFERS 32
@@ -189,11 +189,36 @@ spa_ffmpeg_dec_node_remove_port(struct spa_node *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
+static int
+spa_ffmpeg_dec_node_port_get_info(struct spa_node *node,
+ enum spa_direction direction,
+ uint32_t port_id,
+ const struct spa_port_info **info)
+{
+ struct impl *this;
+ struct port *port;
+
+ if (node == NULL || info == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = SPA_CONTAINER_OF(node, struct impl, node);
+
+ if (!IS_VALID_PORT(this, direction, port_id))
+ return SPA_RESULT_INVALID_PORT;
+
+ port =
+ direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
+ *info = &port->info;
+
+ return SPA_RESULT_OK;
+}
+
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
//struct impl *this;
@@ -207,55 +232,13 @@ static int port_enum_formats(struct spa_node *node,
switch (*index) {
case 0:
+ *param = NULL;
break;
default:
return SPA_RESULT_ENUM_END;
}
- return SPA_RESULT_OK;
-}
-
-static int port_set_format(struct spa_node *node,
- enum spa_direction direction, uint32_t port_id,
- uint32_t flags,
- const struct spa_pod_object *format)
-{
- struct impl *this;
- struct port *port;
-
- if (node == NULL || format == NULL)
- return SPA_RESULT_INVALID_ARGUMENTS;
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
-
- if (!IS_VALID_PORT(this, direction, port_id))
- return SPA_RESULT_INVALID_PORT;
-
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
-
- if (format == NULL) {
- port->have_format = false;
- return SPA_RESULT_OK;
- } else {
- struct spa_video_info info = { 0 };
-
- spa_pod_object_parse(format,
- "I", &info.media_type,
- "I", &info.media_subtype);
- if (info.media_type != this->type.media_type.video &&
- 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) < 0)
- return SPA_RESULT_INVALID_MEDIA_TYPE;
-
- if (!(flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)) {
- port->current_format = info;
- port->have_format = true;
- }
- }
return SPA_RESULT_OK;
}
@@ -263,7 +246,8 @@ static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct port *port;
@@ -277,29 +261,7 @@ static int port_get_format(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- return SPA_RESULT_OK;
-}
-
-static int
-spa_ffmpeg_dec_node_port_get_info(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_port_info **info)
-{
- struct impl *this;
- struct port *port;
-
- if (node == NULL || info == NULL)
- return SPA_RESULT_INVALID_ARGUMENTS;
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
-
- if (!IS_VALID_PORT(this, direction, port_id))
- return SPA_RESULT_INVALID_PORT;
-
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
- *info = &port->info;
+ *param = NULL;
return SPA_RESULT_OK;
}
@@ -313,28 +275,84 @@ spa_ffmpeg_dec_node_port_enum_params(struct spa_node *node,
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct type *t = &this->type;
+ uint32_t offset;
+ struct spa_pod *param;
+ int res;
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
}
else if (id == t->param.idEnumFormat) {
- return port_enum_formats(node, direction, port_id, index, filter, builder);
+ if ((res = port_enum_formats(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idFormat) {
- return port_get_format(node, direction, port_id, index, filter, builder);
+ if ((res = port_get_format(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else
return SPA_RESULT_UNKNOWN_PARAM;
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
+ return SPA_RESULT_OK;
+}
+
+static int port_set_format(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t flags,
+ const struct spa_pod_object *format)
+{
+ struct impl *this;
+ struct port *port;
+
+ if (node == NULL || format == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = SPA_CONTAINER_OF(node, struct impl, node);
+
+ if (!IS_VALID_PORT(this, direction, port_id))
+ return SPA_RESULT_INVALID_PORT;
+
+ port =
+ direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
+
+ if (format == NULL) {
+ port->have_format = false;
+ return SPA_RESULT_OK;
+ } else {
+ struct spa_video_info info = { 0 };
+
+ spa_pod_object_parse(format,
+ "I", &info.media_type,
+ "I", &info.media_subtype);
+
+ if (info.media_type != this->type.media_type.video &&
+ 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) < 0)
+ return SPA_RESULT_INVALID_MEDIA_TYPE;
+
+ if (!(flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)) {
+ port->current_format = info;
+ port->have_format = true;
+ }
+ }
return SPA_RESULT_OK;
}
diff --git a/spa/plugins/ffmpeg/ffmpeg-enc.c b/spa/plugins/ffmpeg/ffmpeg-enc.c
index 829cec02..7fb7aed9 100644
--- a/spa/plugins/ffmpeg/ffmpeg-enc.c
+++ b/spa/plugins/ffmpeg/ffmpeg-enc.c
@@ -26,7 +26,8 @@
#include <spa/type-map.h>
#include <spa/node.h>
#include <spa/video/format-utils.h>
-#include <lib/props.h>
+
+#include <lib/pod.h>
#define IS_VALID_PORT(this,d,id) ((id) == 0)
#define MAX_BUFFERS 32
@@ -218,7 +219,8 @@ static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
//struct impl *this = SPA_CONTAINER_OF (node, struct impl, node);
//struct port *port;
@@ -227,6 +229,7 @@ static int port_enum_formats(struct spa_node *node,
switch (*index) {
case 0:
+ *param = NULL;
break;
default:
return SPA_RESULT_ENUM_END;
@@ -238,7 +241,8 @@ static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct port *port;
@@ -252,6 +256,8 @@ static int port_get_format(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
+ *param = NULL;
+
return SPA_RESULT_OK;
}
@@ -264,28 +270,40 @@ spa_ffmpeg_enc_node_port_enum_params(struct spa_node *node,
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct type *t = &this->type;
+ uint32_t offset;
+ struct spa_pod *param;
+ int res;
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
}
else if (id == t->param.idEnumFormat) {
- return port_enum_formats(node, direction, port_id, index, filter, builder);
+ if ((res = port_enum_formats(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idFormat) {
- return port_get_format(node, direction, port_id, index, filter, builder);
+ if ((res = port_get_format(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else
return SPA_RESULT_UNKNOWN_PARAM;
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
diff --git a/spa/plugins/support/logger.c b/spa/plugins/support/logger.c
index f181f9a5..bc7bd6a9 100644
--- a/spa/plugins/support/logger.c
+++ b/spa/plugins/support/logger.c
@@ -31,7 +31,7 @@
#include <spa/node.h>
#include <spa/param-alloc.h>
#include <spa/list.h>
-#include <lib/props.h>
+#include <lib/pod.h>
#define NAME "logger"
diff --git a/spa/plugins/support/mapper.c b/spa/plugins/support/mapper.c
index 9c4ff2a0..2b1807c1 100644
--- a/spa/plugins/support/mapper.c
+++ b/spa/plugins/support/mapper.c
@@ -31,7 +31,6 @@
#include <spa/node.h>
#include <spa/param-alloc.h>
#include <spa/list.h>
-#include <lib/props.h>
#define NAME "mapper"
diff --git a/spa/plugins/test/fakesink.c b/spa/plugins/test/fakesink.c
index e4ce4ba9..2556f389 100644
--- a/spa/plugins/test/fakesink.c
+++ b/spa/plugins/test/fakesink.c
@@ -30,7 +30,7 @@
#include <spa/node.h>
#include <spa/param-alloc.h>
#include <spa/list.h>
-#include <lib/props.h>
+#include <lib/pod.h>
#define NAME "fakesink"
@@ -130,6 +130,8 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct impl *this;
struct type *t;
+ uint32_t offset;
+ struct spa_pod *param;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -137,11 +139,14 @@ static int impl_node_enum_params(struct spa_node *node,
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param.List,
":", t->param.listId, "I", t->param.idProps);
}
@@ -149,7 +154,7 @@ static int impl_node_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->props,
":", t->prop_live, "b", this->props.live);
}
@@ -158,6 +163,10 @@ static int impl_node_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
@@ -421,7 +430,8 @@ static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
return SPA_RESULT_ENUM_END;
}
@@ -430,7 +440,8 @@ static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
@@ -440,7 +451,7 @@ static int port_get_format(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_primitive(builder, SPA_MEMBER(this->format_buffer, 0, struct spa_pod));
+ *param = SPA_MEMBER(this->format_buffer, 0, struct spa_pod);
return SPA_RESULT_OK;
}
@@ -454,6 +465,9 @@ impl_node_port_enum_params(struct spa_node *node,
{
struct impl *this;
struct type *t;
+ uint32_t offset;
+ struct spa_pod *param;
+ int res;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -464,6 +478,9 @@ impl_node_port_enum_params(struct spa_node *node,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat,
@@ -471,22 +488,24 @@ impl_node_port_enum_params(struct spa_node *node,
t->param.idMeta };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
}
else if (id == t->param.idEnumFormat) {
- return port_enum_formats(node, direction, port_id, index, filter, builder);
+ if ((res = port_enum_formats(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idFormat) {
- return port_get_format(node, direction, port_id, index, filter, builder);
+ if ((res = port_get_format(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idBuffers) {
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param_alloc_buffers.Buffers,
":", t->param_alloc_buffers.size, "i", 128,
":", t->param_alloc_buffers.stride, "i", 1,
@@ -497,7 +516,7 @@ impl_node_port_enum_params(struct spa_node *node,
else if (id == t->param.idMeta) {
switch (*index) {
case 0:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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));
@@ -511,6 +530,10 @@ impl_node_port_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
diff --git a/spa/plugins/test/fakesrc.c b/spa/plugins/test/fakesrc.c
index 8fa752f5..47a03fe0 100644
--- a/spa/plugins/test/fakesrc.c
+++ b/spa/plugins/test/fakesrc.c
@@ -30,7 +30,8 @@
#include <spa/node.h>
#include <spa/param-alloc.h>
#include <spa/list.h>
-#include <lib/props.h>
+
+#include <lib/pod.h>
#define NAME "fakesrc"
@@ -136,6 +137,8 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct impl *this;
struct type *t;
+ uint32_t offset;
+ struct spa_pod *param;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -144,21 +147,24 @@ static int impl_node_enum_params(struct spa_node *node,
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param.List,
":", t->param.listId, "I", t->param.idProps);
}
- if (id == t->param.idProps) {
+ else if (id == t->param.idProps) {
struct props *p = &this->props;
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->props,
":", t->prop_live, "b", p->live,
":", t->prop_pattern, "Ie", p->pattern,
@@ -169,6 +175,10 @@ static int impl_node_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
@@ -436,7 +446,8 @@ static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
return SPA_RESULT_ENUM_END;
}
@@ -445,7 +456,8 @@ static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
@@ -454,7 +466,7 @@ static int port_get_format(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_primitive(builder, SPA_MEMBER(this->format_buffer, 0, struct spa_pod));
+ *param = SPA_MEMBER(this->format_buffer, 0, struct spa_pod);
return SPA_RESULT_OK;
}
@@ -468,6 +480,9 @@ impl_node_port_enum_params(struct spa_node *node,
{
struct impl *this;
struct type *t;
+ uint32_t offset;
+ struct spa_pod *param;
+ int res;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -478,6 +493,9 @@ impl_node_port_enum_params(struct spa_node *node,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat,
@@ -485,22 +503,24 @@ impl_node_port_enum_params(struct spa_node *node,
t->param.idMeta };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
}
else if (id == t->param.idEnumFormat) {
- return port_enum_formats(node, direction, port_id, index, filter, builder);
+ if ((res = port_enum_formats(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idFormat) {
- return port_get_format(node, direction, port_id, index, filter, builder);
+ if ((res = port_get_format(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idBuffers) {
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param_alloc_buffers.Buffers,
":", t->param_alloc_buffers.size, "i", 128,
":", t->param_alloc_buffers.stride, "i", 1,
@@ -511,7 +531,7 @@ impl_node_port_enum_params(struct spa_node *node,
else if (id == t->param.idMeta) {
switch (*index) {
case 0:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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));
@@ -525,6 +545,10 @@ impl_node_port_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c
index 5a76fb60..3a331ed3 100644
--- a/spa/plugins/v4l2/v4l2-source.c
+++ b/spa/plugins/v4l2/v4l2-source.c
@@ -32,8 +32,9 @@
#include <spa/loop.h>
#include <spa/param-alloc.h>
#include <spa/type-map.h>
+
#include <lib/debug.h>
-#include <lib/props.h>
+#include <lib/pod.h>
#define NAME "v4l2-source"
@@ -173,6 +174,8 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct impl *this;
struct type *t;
+ struct spa_pod *param;
+ uint32_t offset;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -181,11 +184,14 @@ static int impl_node_enum_params(struct spa_node *node,
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param.List,
":", t->param.listId, "I", t->param.idProps);
}
@@ -195,16 +201,20 @@ static int impl_node_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder, t->param.idProps, t->props,
- ":", t->prop_device, "S", p->device, sizeof(p->device),
- ":", t->prop_device_name, "S-r", p->device_name, sizeof(p->device_name),
- ":", t->prop_device_fd, "i-r", p->device_fd);
+ param = spa_pod_builder_object(builder, t->param.idProps, t->props,
+ ":", t->prop_device, "S", p->device, sizeof(p->device),
+ ":", t->prop_device_name, "S-r", p->device_name, sizeof(p->device_name),
+ ":", t->prop_device_fd, "i-r", p->device_fd);
}
else
return SPA_RESULT_UNKNOWN_PARAM;
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
@@ -459,7 +469,8 @@ static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct type *t = &this->type;
@@ -493,7 +504,7 @@ static int port_get_format(struct spa_node *node,
} else
return SPA_RESULT_NO_FORMAT;
- spa_pod_builder_pop(builder);
+ *param = spa_pod_builder_pop_deref(builder);
return SPA_RESULT_OK;
}
@@ -509,6 +520,9 @@ static int impl_node_port_enum_params(struct spa_node *node,
struct impl *this;
struct port *port;
struct type *t;
+ struct spa_pod *param;
+ uint32_t offset;
+ int res;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -521,6 +535,9 @@ static int impl_node_port_enum_params(struct spa_node *node,
port = &this->out_ports[port_id];
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat,
@@ -528,7 +545,7 @@ static int impl_node_port_enum_params(struct spa_node *node,
t->param.idMeta };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
@@ -537,7 +554,8 @@ static int impl_node_port_enum_params(struct spa_node *node,
return spa_v4l2_enum_format(this, index, filter, builder);
}
else if (id == t->param.idFormat) {
- return port_get_format(node, direction, port_id, index, filter, builder);
+ if((res = port_get_format(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idBuffers) {
if (!port->have_format)
@@ -545,7 +563,7 @@ static int impl_node_port_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param_alloc_buffers.Buffers,
":", t->param_alloc_buffers.size, "i", port->fmt.fmt.pix.sizeimage,
":", t->param_alloc_buffers.stride, "i", port->fmt.fmt.pix.bytesperline,
@@ -556,7 +574,7 @@ static int impl_node_port_enum_params(struct spa_node *node,
else if (id == t->param.idMeta) {
switch (*index) {
case 0:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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));
@@ -570,6 +588,10 @@ static int impl_node_port_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
diff --git a/spa/plugins/videotestsrc/videotestsrc.c b/spa/plugins/videotestsrc/videotestsrc.c
index c8d88952..9089a4e5 100644
--- a/spa/plugins/videotestsrc/videotestsrc.c
+++ b/spa/plugins/videotestsrc/videotestsrc.c
@@ -33,8 +33,7 @@
#include <spa/list.h>
#include <spa/video/format-utils.h>
-#include <lib/format.h>
-#include <lib/props.h>
+#include <lib/pod.h>
#define NAME "videotestsrc"
@@ -157,6 +156,8 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct impl *this;
struct type *t;
+ uint32_t offset;
+ struct spa_pod *param;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -164,11 +165,14 @@ static int impl_node_enum_params(struct spa_node *node,
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param.List,
":", t->param.listId, "I", t->param.idProps);
}
@@ -178,7 +182,7 @@ static int impl_node_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->props,
":", t->prop_live, "b", p->live,
":", t->prop_pattern, "Ie", p->pattern,
@@ -190,6 +194,10 @@ static int impl_node_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
@@ -451,21 +459,15 @@ static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
- struct spa_pod_object *fmt;
- uint8_t buffer[256];
- struct spa_pod_builder b = { NULL, };
struct type *t = &this->type;
- int res;
-
- next:
- spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (*index) {
case 0:
- fmt = spa_pod_builder_object(&b,
+ *param = spa_pod_builder_object(builder,
t->param.idEnumFormat, t->format,
"I", t->media_type.video,
"I", t->media_subtype.raw,
@@ -482,11 +484,6 @@ static int port_enum_formats(struct spa_node *node,
default:
return SPA_RESULT_ENUM_END;
}
- (*index)++;
-
- if ((res = spa_pod_object_filter(fmt, filter, builder)) != SPA_RESULT_OK)
- goto next;
-
return SPA_RESULT_OK;
}
@@ -494,18 +491,18 @@ static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct type *t = &this->type;
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
-
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ *param = spa_pod_builder_object(builder,
t->param.idFormat, t->format,
"I", t->media_type.video,
"I", t->media_subtype.raw,
@@ -525,6 +522,9 @@ impl_node_port_enum_params(struct spa_node *node,
{
struct impl *this;
struct type *t;
+ uint32_t offset;
+ struct spa_pod *param;
+ int res;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -535,6 +535,9 @@ impl_node_port_enum_params(struct spa_node *node,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat,
@@ -542,16 +545,18 @@ impl_node_port_enum_params(struct spa_node *node,
t->param.idMeta };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
}
else if (id == t->param.idEnumFormat) {
- return port_enum_formats(node, direction, port_id, index, filter, builder);
+ if ((res = port_enum_formats(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idFormat) {
- return port_get_format(node, direction, port_id, index, filter, builder);
+ if ((res = port_get_format(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idBuffers) {
struct spa_video_info_raw *raw_info = &this->current_format.info.raw;
@@ -561,7 +566,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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,
@@ -575,7 +580,7 @@ impl_node_port_enum_params(struct spa_node *node,
switch (*index) {
case 0:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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));
@@ -585,8 +590,15 @@ impl_node_port_enum_params(struct spa_node *node,
return SPA_RESULT_ENUM_END;
}
}
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
diff --git a/spa/plugins/volume/volume.c b/spa/plugins/volume/volume.c
index 17d8aafc..0eae0b30 100644
--- a/spa/plugins/volume/volume.c
+++ b/spa/plugins/volume/volume.c
@@ -26,8 +26,8 @@
#include <spa/list.h>
#include <spa/audio/format-utils.h>
#include <spa/param-alloc.h>
-#include <lib/props.h>
-#include <lib/format.h>
+
+#include <lib/pod.h>
#define NAME "volume"
@@ -143,6 +143,8 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct impl *this;
struct type *t;
+ uint32_t offset;
+ struct spa_pod *param;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -151,11 +153,14 @@ static int impl_node_enum_params(struct spa_node *node,
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param.List,
":", t->param.listId, "I", t->param.idProps);
}
@@ -165,7 +170,7 @@ static int impl_node_enum_params(struct spa_node *node,
if(*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->props,
":", t->prop_volume, "dr", p->volume, 2, 0.0, 10.0,
":", t->prop_mute, "b", p->mute);
@@ -175,6 +180,10 @@ static int impl_node_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
@@ -318,21 +327,15 @@ static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
- int res;
- struct spa_pod_object *fmt;
- uint8_t buffer[1024];
- struct spa_pod_builder b = { NULL, };
struct type *t = &this->type;
- next:
- spa_pod_builder_init(&b, buffer, sizeof(buffer));
-
switch (*index) {
case 0:
- fmt = spa_pod_builder_object(&b,
+ *param = spa_pod_builder_object(builder,
t->param.idEnumFormat, t->format,
"I", t->media_type.audio,
"I", t->media_subtype.raw,
@@ -345,11 +348,6 @@ static int port_enum_formats(struct spa_node *node,
default:
return SPA_RESULT_ENUM_END;
}
- (*index)++;
-
- if ((res = spa_pod_object_filter(fmt, filter, builder)) != SPA_RESULT_OK)
- goto next;
-
return SPA_RESULT_OK;
}
@@ -357,7 +355,8 @@ static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct port *port;
@@ -370,7 +369,7 @@ static int port_get_format(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ *param = spa_pod_builder_object(builder,
t->param.idFormat, t->format,
"I", t->media_type.audio,
"I", t->media_subtype.raw,
@@ -391,6 +390,9 @@ impl_node_port_enum_params(struct spa_node *node,
struct impl *this;
struct type *t;
struct port *port;
+ uint32_t offset;
+ struct spa_pod *param;
+ int res;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -403,6 +405,9 @@ impl_node_port_enum_params(struct spa_node *node,
port = GET_PORT(this, direction, port_id);
+ offset = builder->offset;
+
+ next:
if (id == t->param.idList) {
uint32_t list[] = { t->param.idEnumFormat,
t->param.idFormat,
@@ -410,16 +415,18 @@ impl_node_port_enum_params(struct spa_node *node,
t->param.idMeta };
if (*index < SPA_N_ELEMENTS(list))
- spa_pod_builder_object(builder, id, t->param.List,
+ param = spa_pod_builder_object(builder, id, t->param.List,
":", t->param.listId, "I", list[*index]);
else
return SPA_RESULT_ENUM_END;
}
else if (id == t->param.idEnumFormat) {
- return port_enum_formats(node, direction, port_id, index, filter, builder);
+ if ((res = port_enum_formats(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idFormat) {
- return port_get_format(node, direction, port_id, index, filter, builder);
+ if ((res = port_get_format(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idBuffers) {
if (!port->have_format)
@@ -427,7 +434,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (*index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, t->param_alloc_buffers.Buffers,
":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
2, 16 * this->bpf,
@@ -440,7 +447,7 @@ impl_node_port_enum_params(struct spa_node *node,
else if (id == t->param.idMeta) {
switch (*index) {
case 0:
- spa_pod_builder_object(builder,
+ param = spa_pod_builder_object(builder,
id, 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));
@@ -454,6 +461,10 @@ impl_node_port_enum_params(struct spa_node *node,
(*index)++;
+ spa_pod_builder_reset(builder, offset);
+ if (spa_pod_filter(builder, param, (struct spa_pod*)filter) < 0)
+ goto next;
+
return SPA_RESULT_OK;
}
diff --git a/spa/tests/test-ringbuffer.c b/spa/tests/test-ringbuffer.c
index 38b9e00b..f3322c69 100644
--- a/spa/tests/test-ringbuffer.c
+++ b/spa/tests/test-ringbuffer.c
@@ -34,7 +34,6 @@
#include <spa/format-utils.h>
#include <lib/debug.h>
-#include <lib/props.h>
static SPA_TYPE_MAP_IMPL(default_map, 4096);
static SPA_LOG_IMPL(default_log);
diff --git a/spa/tests/test-v4l2.c b/spa/tests/test-v4l2.c
index 032b1fc7..5e495269 100644
--- a/spa/tests/test-v4l2.c
+++ b/spa/tests/test-v4l2.c
@@ -33,8 +33,8 @@
#include <spa/node.h>
#include <spa/loop.h>
#include <spa/video/format-utils.h>
+
#include <lib/debug.h>
-#include <lib/props.h>
static SPA_TYPE_MAP_IMPL(default_map, 4096);
static SPA_LOG_IMPL(default_log);
diff --git a/src/examples/video-play.c b/src/examples/video-play.c
index 478e2382..e8f2c89b 100644
--- a/src/examples/video-play.c
+++ b/src/examples/video-play.c
@@ -82,7 +82,6 @@ struct data {
struct spa_video_info_raw format;
int32_t stride;
- uint8_t params_buffer[1024];
int counter;
};
@@ -240,7 +239,8 @@ on_stream_format_changed(void *_data, struct spa_pod_object *format)
struct data *data = _data;
struct pw_stream *stream = data->stream;
struct pw_type *t = data->t;
- struct spa_pod_builder b = { NULL };
+ uint8_t params_buffer[1024];
+ struct spa_pod_builder b = SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer));
struct spa_pod_object *params[2];
Uint32 sdl_format;
void *d;
@@ -266,7 +266,6 @@ on_stream_format_changed(void *_data, struct spa_pod_object *format)
SDL_LockTexture(data->texture, NULL, &d, &data->stride);
SDL_UnlockTexture(data->texture);
- spa_pod_builder_init(&b, data->params_buffer, sizeof(data->params_buffer));
params[0] = spa_pod_builder_object(&b,
t->param.idBuffers, t->param_alloc_buffers.Buffers,
":", t->param_alloc_buffers.size, "i", data->stride * data->format.size.height,
diff --git a/src/examples/video-src.c b/src/examples/video-src.c
index 7d13e861..101f814c 100644
--- a/src/examples/video-src.c
+++ b/src/examples/video-src.c
@@ -75,7 +75,6 @@ struct data {
struct spa_video_info_raw format;
int32_t stride;
- uint8_t params_buffer[1024];
int counter;
uint32_t seq;
};
@@ -172,7 +171,8 @@ on_stream_format_changed(void *_data, struct spa_pod_object *format)
struct data *data = _data;
struct pw_stream *stream = data->stream;
struct pw_type *t = data->t;
- struct spa_pod_builder b = { NULL };
+ uint8_t params_buffer[1024];
+ struct spa_pod_builder b = SPA_POD_BUILDER_INIT(params_buffer, sizeof(params_buffer));
struct spa_pod_object *params[2];
if (format == NULL) {
@@ -183,7 +183,6 @@ on_stream_format_changed(void *_data, struct spa_pod_object *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));
params[0] = spa_pod_builder_object(&b,
t->param.idBuffers, t->param_alloc_buffers.Buffers,
":", t->param_alloc_buffers.size, "i", data->stride * data->format.size.height,
diff --git a/src/gst/gstpipewireformat.c b/src/gst/gstpipewireformat.c
index 54a8329a..65192e56 100644
--- a/src/gst/gstpipewireformat.c
+++ b/src/gst/gstpipewireformat.c
@@ -529,10 +529,9 @@ handle_audio_fields (ConvertData *d)
}
static uint32_t
-write_pod (struct spa_pod_builder *b, uint32_t ref, const void *data, uint32_t size)
+write_pod (struct spa_pod_builder *b, const void *data, uint32_t size)
{
- if (ref == -1)
- ref = b->offset;
+ uint32_t ref = b->offset;
if (b->size <= b->offset) {
b->size = SPA_ROUND_UP_N (b->offset + size, 512);
diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c
index 0f0f82c6..3f1d8099 100644
--- a/src/modules/module-client-node/client-node.c
+++ b/src/modules/module-client-node/client-node.c
@@ -29,7 +29,7 @@
#include <sys/eventfd.h>
#include "spa/node.h"
-#include "spa/lib/format.h"
+#include "spa/lib/pod.h"
#include "pipewire/pipewire.h"
#include "pipewire/interfaces.h"
@@ -57,6 +57,10 @@
#define CHECK_OUT_PORT(this,d,p) (CHECK_OUT_PORT_ID(this,d,p) && (this)->out_ports[p].valid)
#define CHECK_PORT(this,d,p) (CHECK_IN_PORT (this,d,p) || CHECK_OUT_PORT (this,d,p))
+#define GET_IN_PORT(this,p) (&this->in_ports[p])
+#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 CHECK_PORT_BUFFER(this,b,p) (b < p->n_buffers)
struct proxy_buffer {
@@ -152,6 +156,7 @@ static int spa_proxy_node_enum_params(struct spa_node *node,
struct spa_pod_builder *builder)
{
struct proxy *this;
+ uint32_t offset;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -159,6 +164,8 @@ static int spa_proxy_node_enum_params(struct spa_node *node,
this = SPA_CONTAINER_OF(node, struct proxy, node);
+ offset = builder->offset;
+
while (true) {
struct spa_pod_object *param;
@@ -167,10 +174,13 @@ static int spa_proxy_node_enum_params(struct spa_node *node,
param = this->params[(*index)++];
- if (param->body.id == id) {
- spa_pod_builder_primitive(builder, &param->pod);
+ if (param->body.id != id)
+ continue;
+
+ if (spa_pod_filter(builder, &param->pod, &filter->pod) == SPA_RESULT_OK)
break;
- }
+
+ spa_pod_builder_reset(builder, offset);
}
return SPA_RESULT_OK;
}
@@ -312,11 +322,7 @@ do_update_port(struct proxy *this,
struct proxy_port *port;
struct pw_type *t = this->impl->t;
- if (direction == SPA_DIRECTION_INPUT) {
- port = &this->in_ports[port_id];
- } else {
- port = &this->out_ports[port_id];
- }
+ port = GET_PORT(this, direction, port_id);
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_PARAMS) {
int i;
@@ -369,11 +375,12 @@ static void do_uninit_port(struct proxy *this, enum spa_direction direction, uin
struct proxy_port *port;
spa_log_info(this->log, "proxy %p: removing port %d", this, port_id);
+
if (direction == SPA_DIRECTION_INPUT) {
- port = &this->in_ports[port_id];
+ port = GET_IN_PORT(this, port_id);
this->n_inputs--;
} else {
- port = &this->out_ports[port_id];
+ port = GET_OUT_PORT(this, port_id);
this->n_outputs--;
}
clear_port(this, port, direction, port_id);
@@ -394,8 +401,7 @@ spa_proxy_node_add_port(struct spa_node *node, enum spa_direction direction, uin
if (!CHECK_FREE_PORT(this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
+ port = GET_PORT(this, direction, port_id);
clear_port(this, port, direction, port_id);
return SPA_RESULT_OK;
@@ -435,9 +441,7 @@ spa_proxy_node_port_get_info(struct spa_node *node,
if (!CHECK_PORT(this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
-
+ port = GET_PORT(this, direction, port_id);
*info = &port->info;
return SPA_RESULT_OK;
@@ -452,6 +456,7 @@ spa_proxy_node_port_enum_params(struct spa_node *node,
{
struct proxy *this;
struct proxy_port *port;
+ uint32_t offset;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
@@ -461,9 +466,9 @@ spa_proxy_node_port_enum_params(struct spa_node *node,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
+ port = GET_PORT(this, direction, port_id);
+ offset = builder->offset;
while (true) {
struct spa_pod_object *param;
@@ -472,10 +477,13 @@ spa_proxy_node_port_enum_params(struct spa_node *node,
param = port->params[(*index)++];
- if (param->body.id == id) {
- spa_pod_builder_primitive(builder, &param->pod);
+ if (param->body.id != id)
+ continue;
+
+ if (spa_pod_filter(builder, &param->pod, &filter->pod) == SPA_RESULT_OK)
break;
- }
+
+ spa_pod_builder_reset(builder, offset);
}
return SPA_RESULT_OK;
}
@@ -523,8 +531,7 @@ spa_proxy_node_port_set_io(struct spa_node *node,
if (!CHECK_PORT(this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
+ port = GET_PORT(this, direction, port_id);
port->io = io;
return SPA_RESULT_OK;
@@ -555,8 +562,7 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
if (!CHECK_PORT(this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
+ port = GET_PORT(this, direction, port_id);
if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
@@ -661,8 +667,7 @@ spa_proxy_node_port_alloc_buffers(struct spa_node *node,
if (!CHECK_PORT(this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
+ port = GET_PORT(this, direction, port_id);
if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
diff --git a/src/modules/module-jack/jack-node.c b/src/modules/module-jack/jack-node.c
index 24c50e81..0bd9e46b 100644
--- a/src/modules/module-jack/jack-node.c
+++ b/src/modules/module-jack/jack-node.c
@@ -30,9 +30,10 @@
#include <spa/node.h>
#include <spa/hook.h>
-#include <spa/lib/format.h>
#include <spa/audio/format-utils.h>
+#include <spa/lib/pod.h>
+
#include "pipewire/pipewire.h"
#include "pipewire/core.h"
#include "pipewire/private.h"
@@ -374,29 +375,41 @@ static int port_set_io(struct spa_node *node, enum spa_direction direction, uint
return SPA_RESULT_OK;
}
+static int port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
+ const struct spa_port_info **info)
+{
+ struct node_data *nd = SPA_CONTAINER_OF(node, struct node_data, node_impl);
+ struct port_data *pd = nd->port_data[direction][port_id];
+ struct pw_jack_port *port = &pd->port;
+
+ pd->info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | SPA_PORT_INFO_FLAG_LIVE;
+ if (port->direction == PW_DIRECTION_OUTPUT && port->jack_port != NULL)
+ pd->info.flags |= SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS;
+
+ pd->info.rate = pd->node->node.server->engine_control->sample_rate;
+ *info = &pd->info;
+
+ return SPA_RESULT_OK;
+}
+
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod_object *filter,
- struct spa_pod_builder *builder)
+ struct spa_pod_builder *builder,
+ struct spa_pod **param)
{
struct node_data *nd = SPA_CONTAINER_OF(node, struct node_data, node_impl);
struct port_data *pd = nd->port_data[direction][port_id];
struct type *t = &pd->node->type;
- struct spa_pod_builder b = { NULL, };
- struct spa_pod_object *fmt;
- uint8_t buffer[4096];
- int res;
struct jack_engine_control *ctrl = pd->node->node.server->engine_control;
if (index > 0)
return SPA_RESULT_ENUM_END;
- spa_pod_builder_init(&b, buffer, sizeof(buffer));
-
if (pd->port.jack_port) {
if (pd->port.jack_port->type_id == 0) {
- fmt = spa_pod_builder_object(&b,
+ *param = spa_pod_builder_object(builder,
t->param.idEnumFormat, t->format,
"I", t->media_type.audio,
"I", t->media_subtype.raw,
@@ -405,7 +418,7 @@ static int port_enum_formats(struct spa_node *node,
":", t->format_audio.channels, "i", 1);
}
else if (pd->port.jack_port->type_id == 1) {
- fmt = spa_pod_builder_object(&b,
+ *param = spa_pod_builder_object(builder,
t->param.idEnumFormat, t->format,
"I", t->media_type.audio,
"I", t->media_subtype_audio.midi);
@@ -414,7 +427,7 @@ static int port_enum_formats(struct spa_node *node,
return SPA_RESULT_ENUM_END;
}
else {
- fmt = spa_pod_builder_object(&b,
+ *param = spa_pod_builder_object(builder,
t->param.idEnumFormat, t->format,
"I", t->media_type.audio,
"I", t->media_subtype.raw,
@@ -422,27 +435,6 @@ static int port_enum_formats(struct spa_node *node,
":", t->format_audio.rate, "i", ctrl->sample_rate,
":", t->format_audio.channels, "i", 2);
}
-
- if ((res = spa_pod_object_filter(fmt, filter, builder)) < 0)
- return res;
-
- return SPA_RESULT_OK;
-}
-
-static int port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- const struct spa_port_info **info)
-{
- struct node_data *nd = SPA_CONTAINER_OF(node, struct node_data, node_impl);
- struct port_data *pd = nd->port_data[direction][port_id];
- struct pw_jack_port *port = &pd->port;
-
- pd->info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | SPA_PORT_INFO_FLAG_LIVE;
- if (port->direction == PW_DIRECTION_OUTPUT && port->jack_port != NULL)
- pd->info.flags |= SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS;
-
- pd->info.rate = pd->node->node.server->engine_control->sample_rate;
- *info = &pd->info;
-
return SPA_RESULT_OK;
}
@@ -454,16 +446,30 @@ static int port_enum_params(struct spa_node *node,
{
struct node_data *nd = SPA_CONTAINER_OF(node, struct node_data, node_impl);
struct type *t = &nd->type;
+ struct spa_pod *param;
+ uint32_t offset;
+ int res;
+
+ offset = builder->offset;
+ next:
if (id == t->param.idEnumFormat) {
- return port_enum_formats(node, direction, port_id, index, filter, builder);
+ if ((res = port_enum_formats(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else if (id == t->param.idFormat) {
- return port_enum_formats(node, direction, port_id, index, filter, builder);
+ if ((res = port_enum_formats(node, direction, port_id, index, filter, builder, &param)) < 0)
+ return res;
}
else
return SPA_RESULT_UNKNOWN_PARAM;
+ (*index)++;
+
+ spa_pod_builder_reset(builder, offset);
+ if ((res = spa_pod_filter(builder, param, (struct spa_pod*)filter)) < 0)
+ goto next;
+
return SPA_RESULT_ENUM_END;
}
diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c
index 73b8b4bd..93dc3977 100644
--- a/src/modules/module-protocol-native/connection.c
+++ b/src/modules/module-protocol-native/connection.c
@@ -338,12 +338,12 @@ static inline void *begin_write(struct pw_protocol_native_connection *conn, uint
return p + 2;
}
-static uint32_t write_pod(struct spa_pod_builder *b, uint32_t ref, const void *data, uint32_t size)
+static uint32_t write_pod(struct spa_pod_builder *b, const void *data, uint32_t size)
{
struct impl *impl = SPA_CONTAINER_OF(b, struct impl, builder);
+ uint32_t ref = b->offset;
- if (ref == -1)
- ref = b->offset;
+ ref = b->offset;
if (b->size <= b->offset) {
b->size = SPA_ROUND_UP_N(b->offset + size, 4096);
diff --git a/src/modules/spa/module-monitor.c b/src/modules/spa/module-monitor.c
index 720fd2dd..58573947 100644
--- a/src/modules/spa/module-monitor.c
+++ b/src/modules/spa/module-monitor.c
@@ -25,8 +25,6 @@
#include <getopt.h>
#include <limits.h>
-#include <spa/lib/props.h>
-
#include <pipewire/utils.h>
#include <pipewire/log.h>
#include <pipewire/core.h>
diff --git a/src/modules/spa/module-node.c b/src/modules/spa/module-node.c
index 8583134c..2d9bd931 100644
--- a/src/modules/spa/module-node.c
+++ b/src/modules/spa/module-node.c
@@ -25,8 +25,6 @@
#include <getopt.h>
#include <limits.h>
-#include <spa/lib/props.h>
-
#include <pipewire/core.h>
#include <pipewire/log.h>
#include <pipewire/module.h>
diff --git a/src/pipewire/core.c b/src/pipewire/core.c
index b0efd931..6f534890 100644
--- a/src/pipewire/core.c
+++ b/src/pipewire/core.c
@@ -787,7 +787,7 @@ int pw_core_find_format(struct pw_core *core,
asprintf(error, "error output enum formats: %d", res);
goto error;
}
- format = spa_pod_builder_deref(&fb, 0);
+ format = spa_pod_builder_deref(builder, 0);
pw_log_debug("Got filtered:");
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
diff --git a/src/pipewire/link.c b/src/pipewire/link.c
index e7bc3a80..b754b2db 100644
--- a/src/pipewire/link.c
+++ b/src/pipewire/link.c
@@ -24,8 +24,7 @@
#include <spa/video/format.h>
#include <spa/pod-utils.h>
-#include <spa/lib/format.h>
-#include <spa/lib/props.h>
+#include <spa/lib/pod.h>
#include "pipewire.h"
#include "private.h"
@@ -148,7 +147,7 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
goto error;
}
current = spa_pod_builder_deref(&b, 0);
- if (spa_pod_object_compare(current, format) < 0) {
+ if (spa_pod_compare((struct spa_pod*)current, (struct spa_pod*)format) != 0) {
pw_log_debug("link %p: output format change, renegotiate", this);
pw_node_set_state(output->node, PW_NODE_STATE_SUSPENDED);
out_state = PW_PORT_STATE_CONFIGURE;
@@ -167,7 +166,7 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
goto error;
}
current = spa_pod_builder_deref(&b, 0);
- if (spa_pod_object_compare(current, format) < 0) {
+ if (spa_pod_compare((struct spa_pod*)current, (struct spa_pod*)format) != 0) {
pw_log_debug("link %p: input format change, renegotiate", this);
pw_node_set_state(input->node, PW_NODE_STATE_SUSPENDED);
in_state = PW_PORT_STATE_CONFIGURE;
@@ -399,7 +398,6 @@ param_filter(struct pw_link *this,
uint32_t id,
struct spa_pod_builder *result)
{
- int res;
uint8_t ibuf[2048], obuf[2048];
struct spa_pod_builder ib = { 0 }, ob = { 0 };
struct spa_pod_object *oparam, *iparam;
@@ -407,44 +405,37 @@ param_filter(struct pw_link *this,
for (iidx = 0;;) {
spa_pod_builder_init(&ib, ibuf, sizeof(ibuf));
+ pw_log_debug("iparam %d", iidx);
if (spa_node_port_enum_params(in_port->node->node, in_port->direction, in_port->port_id,
id, &iidx, NULL, &ib) < 0)
break;
iparam = spa_pod_builder_deref(&ib, 0);
+ pw_log_debug("iparam %d", iidx);
+ if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
+ spa_debug_pod(&iparam->pod, 0);
+
for (oidx = 0;;) {
uint32_t offset;
spa_pod_builder_init(&ob, obuf, sizeof(obuf));
+
+ offset = result->offset;
+
+ pw_log_debug("oparam %d %d", oidx, offset);
if (spa_node_port_enum_params(out_port->node->node, out_port->direction,
out_port->port_id, id, &oidx,
- NULL, &ob) < 0)
+ iparam, result) < 0) {
break;
- oparam = spa_pod_builder_deref(&ob, 0);
+ }
+ oparam = spa_pod_builder_deref(result, offset);
- if (iidx == 1 && pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
+ pw_log_debug("oparam %d", oidx);
+ if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
spa_debug_pod(&oparam->pod, 0);
- if (iparam->body.type != oparam->body.type)
- continue;
-
- offset = result->offset;
- spa_pod_builder_push_object(result, id, iparam->body.type);
- if ((res = spa_props_filter(result,
- SPA_POD_CONTENTS(struct spa_pod_object, iparam),
- SPA_POD_CONTENTS_SIZE(struct spa_pod_object, iparam),
- SPA_POD_CONTENTS(struct spa_pod_object, oparam),
- SPA_POD_CONTENTS_SIZE(struct spa_pod_object, oparam))) < 0) {
- result->offset = offset;
- result->depth = 0;
- continue;
- }
- spa_pod_builder_pop(result);
num++;
}
- if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
- spa_debug_pod(&iparam->pod, 0);
-
}
return num;
}