summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2017-11-07 17:39:31 +0100
committerWim Taymans <wtaymans@redhat.com>2017-11-07 17:48:40 +0100
commitf3bca483980639c73e3e21acf90f35160c95e53e (patch)
tree11c4069727ce300865d660aeb8064ebcb2a2718c
parentb6ee67905db2124a1105da7da6969200aa305957 (diff)
Unify props, params and formats
Make enum_params and set_param to configure properties, format and other parameters. This allows us to remove some duplicate code and make the properties and parameters much more extensible. Use the object id to mark the id of the parameter. Remove the spa_format and spa_props. We can now make the client-node easier by merging the various format methods into the params. Make the stream API more powerful now that we can pass params around.
-rw-r--r--spa/include/spa/audio/format-utils.h2
-rw-r--r--spa/include/spa/clock.h19
-rw-r--r--spa/include/spa/defs.h2
-rw-r--r--spa/include/spa/format-builder.h61
-rw-r--r--spa/include/spa/format-utils.h34
-rw-r--r--spa/include/spa/format.h19
-rw-r--r--spa/include/spa/meson.build1
-rw-r--r--spa/include/spa/node.h227
-rw-r--r--spa/include/spa/param-alloc.h24
-rw-r--r--spa/include/spa/param.h82
-rw-r--r--spa/include/spa/pod-utils.h12
-rw-r--r--spa/include/spa/props.h31
-rw-r--r--spa/include/spa/video/format-utils.h6
-rw-r--r--spa/lib/debug.c51
-rw-r--r--spa/lib/debug.h6
-rw-r--r--spa/lib/format.c47
-rw-r--r--spa/lib/format.h10
-rw-r--r--spa/lib/props.c1
-rw-r--r--spa/lib/props.h1
-rw-r--r--spa/plugins/alsa/alsa-sink.c303
-rw-r--r--spa/plugins/alsa/alsa-source.c264
-rw-r--r--spa/plugins/alsa/alsa-utils.c27
-rw-r--r--spa/plugins/alsa/alsa-utils.h8
-rw-r--r--spa/plugins/audiomixer/audiomixer.c315
-rw-r--r--spa/plugins/audiotestsrc/audiotestsrc.c367
-rw-r--r--spa/plugins/ffmpeg/ffmpeg-dec.c115
-rw-r--r--spa/plugins/ffmpeg/ffmpeg-enc.c190
-rw-r--r--spa/plugins/support/logger.c1
-rw-r--r--spa/plugins/support/mapper.c1
-rw-r--r--spa/plugins/test/fakesink.c269
-rw-r--r--spa/plugins/test/fakesrc.c274
-rw-r--r--spa/plugins/v4l2/v4l2-source.c362
-rw-r--r--spa/plugins/v4l2/v4l2-utils.c86
-rw-r--r--spa/plugins/videotestsrc/videotestsrc.c332
-rw-r--r--spa/plugins/volume/volume.c324
-rw-r--r--spa/tests/test-graph.c59
-rw-r--r--spa/tests/test-graph2.c1
-rw-r--r--spa/tests/test-mixer.c78
-rw-r--r--spa/tests/test-perf.c24
-rw-r--r--spa/tests/test-props.c52
-rw-r--r--spa/tests/test-props2.c4
-rw-r--r--spa/tests/test-props5.c6
-rw-r--r--spa/tests/test-ringbuffer.c51
-rw-r--r--spa/tests/test-v4l2.c25
-rw-r--r--spa/tools/spa-inspect.c74
-rw-r--r--spa/tools/spa-monitor.c2
-rw-r--r--src/daemon/pipewire.conf.in2
-rw-r--r--src/examples/export-sink.c206
-rw-r--r--src/examples/export-source.c204
-rw-r--r--src/examples/export-spa.c1
-rw-r--r--src/examples/local-v4l2.c154
-rw-r--r--src/examples/video-play.c41
-rw-r--r--src/examples/video-src.c31
-rw-r--r--src/extensions/client-node.h175
-rw-r--r--src/gst/gstpipewiredeviceprovider.c12
-rw-r--r--src/gst/gstpipewireformat.c38
-rw-r--r--src/gst/gstpipewireformat.h6
-rw-r--r--src/gst/gstpipewiresink.c21
-rw-r--r--src/gst/gstpipewiresrc.c23
-rw-r--r--src/modules/module-autolink.c1
-rw-r--r--src/modules/module-client-node/client-node.c314
-rw-r--r--src/modules/module-client-node/protocol-native.c356
-rw-r--r--src/modules/module-flatpak.c2
-rw-r--r--src/modules/module-jack.c9
-rw-r--r--src/modules/module-jack/jack-node.c106
-rw-r--r--src/modules/module-protocol-native.c8
-rw-r--r--src/modules/module-protocol-native/connection.c4
-rw-r--r--src/modules/module-protocol-native/protocol-native.c32
-rw-r--r--src/modules/spa/spa-node.c12
-rw-r--r--src/pipewire/core.c82
-rw-r--r--src/pipewire/core.h20
-rw-r--r--src/pipewire/interfaces.h4
-rw-r--r--src/pipewire/introspect.c66
-rw-r--r--src/pipewire/introspect.h14
-rw-r--r--src/pipewire/link.c130
-rw-r--r--src/pipewire/link.h2
-rw-r--r--src/pipewire/node.c69
-rw-r--r--src/pipewire/port.c13
-rw-r--r--src/pipewire/private.h27
-rw-r--r--src/pipewire/remote.c292
-rw-r--r--src/pipewire/stream.c206
-rw-r--r--src/pipewire/stream.h25
-rw-r--r--src/pipewire/type.c1
-rw-r--r--src/pipewire/type.h1
-rw-r--r--src/pipewire/utils.h4
-rw-r--r--src/tools/pipewire-cli.c24
-rw-r--r--src/tools/pipewire-monitor.c23
87 files changed, 3602 insertions, 3409 deletions
diff --git a/spa/include/spa/audio/format-utils.h b/spa/include/spa/audio/format-utils.h
index 015611e5..de5998fb 100644
--- a/spa/include/spa/audio/format-utils.h
+++ b/spa/include/spa/audio/format-utils.h
@@ -51,7 +51,7 @@ spa_type_format_audio_map(struct spa_type_map *map, struct spa_type_format_audio
}
static inline int
-spa_format_audio_raw_parse(const struct spa_format *format,
+spa_format_audio_raw_parse(const struct spa_pod_object *format,
struct spa_audio_info_raw *info, struct spa_type_format_audio *type)
{
struct spa_pod_parser prs;
diff --git a/spa/include/spa/clock.h b/spa/include/spa/clock.h
index d0f3fb84..9145d1c1 100644
--- a/spa/include/spa/clock.h
+++ b/spa/include/spa/clock.h
@@ -41,7 +41,7 @@ enum spa_clock_state {
#include <spa/defs.h>
#include <spa/plugin.h>
-#include <spa/props.h>
+#include <spa/pod-builder.h>
/**
* spa_clock:
@@ -64,9 +64,8 @@ struct spa_clock {
/**
* spa_clock::get_props:
* @clock: a #spa_clock
- * @props: a location for a #struct spa_props pointer
*
- * Get the configurable properties of @clock.
+ * Get the parameters of @clock.
*
* The returned @props is a snapshot of the current configuration and
* can be modified. The modifications will take effect after a call
@@ -77,8 +76,9 @@ struct spa_clock {
* #SPA_RESULT_NOT_IMPLEMENTED when there are no properties
* implemented on @clock
*/
- int (*get_props) (struct spa_clock *clock,
- struct spa_props **props);
+ int (*enum_params) (struct spa_clock *clock,
+ uint32_t id, uint32_t *index,
+ struct spa_pod_builder *builder);
/**
* spa_clock::set_props:
* @clock: a #spa_clock
@@ -101,8 +101,9 @@ struct spa_clock {
* #SPA_RESULT_WRONG_PROPERTY_TYPE when a property has the wrong
* type.
*/
- int (*set_props) (struct spa_clock *clock,
- const struct spa_props *props);
+ int (*set_param) (struct spa_clock *clock,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param);
int (*get_time) (struct spa_clock *clock,
int32_t *rate,
@@ -110,8 +111,8 @@ struct spa_clock {
int64_t *monotonic_time);
};
-#define spa_clock_get_props(n,...) (n)->get_props((n),__VA_ARGS__)
-#define spa_clock_set_props(n,...) (n)->set_props((n),__VA_ARGS__)
+#define spa_clock_enum_params(n,...) (n)->enum_params((n),__VA_ARGS__)
+#define spa_clock_set_param(n,...) (n)->set_param((n),__VA_ARGS__)
#define spa_clock_get_time(n,...) (n)->get_time((n),__VA_ARGS__)
#ifdef __cplusplus
diff --git a/spa/include/spa/defs.h b/spa/include/spa/defs.h
index 62ccfe8f..15fba949 100644
--- a/spa/include/spa/defs.h
+++ b/spa/include/spa/defs.h
@@ -73,6 +73,8 @@ enum spa_result {
SPA_RESULT_INCOMPATIBLE_VERSION = -37,
SPA_RESULT_NOT_FOUND = -38,
SPA_RESULT_BUSY = -39,
+ SPA_RESULT_UNKNOWN_PARAM = -40,
+ SPA_RESULT_PARAM_INCOMPLETE = -41,
};
#define SPA_ASYNC_BIT (1 << 30)
diff --git a/spa/include/spa/format-builder.h b/spa/include/spa/format-builder.h
deleted file mode 100644
index 3a92a004..00000000
--- a/spa/include/spa/format-builder.h
+++ /dev/null
@@ -1,61 +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_FORMAT_BUILDER_H__
-#define __SPA_FORMAT_BUILDER_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdarg.h>
-
-#include <spa/format.h>
-#include <spa/pod-builder.h>
-
-#define SPA_FORMAT_INIT(size,type,media_type,media_subtype) \
- { { size, SPA_POD_TYPE_OBJECT }, \
- { { 0, type }, \
- SPA_POD_ID_INIT(media_type), \
- SPA_POD_ID_INIT(media_subtype) } }
-
-static inline uint32_t
-spa_pod_builder_push_format(struct spa_pod_builder *builder,
- struct spa_pod_frame *frame,
- uint32_t format_type,
- uint32_t media_type,
- uint32_t media_subtype)
-{
- const struct spa_format p = SPA_FORMAT_INIT(sizeof(struct spa_format_body),
- format_type, media_type, media_subtype);
- return spa_pod_builder_push(builder, frame, &p.pod,
- spa_pod_builder_raw(builder, &p, sizeof(p)));
-}
-
-#define spa_pod_builder_format(b,format_type,media_type,media_subtype,...) \
- spa_pod_builder_object(b, 0, format_type, \
- "I",media_type, \
- "I",media_subtype, \
- ##__VA_ARGS__)
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* __SPA_FORMAT_BUILDER_H__ */
diff --git a/spa/include/spa/format-utils.h b/spa/include/spa/format-utils.h
index 12f1c24f..a2e09bd5 100644
--- a/spa/include/spa/format-utils.h
+++ b/spa/include/spa/format-utils.h
@@ -138,40 +138,6 @@ spa_type_media_subtype_audio_map(struct spa_type_map *map,
}
}
-#define SPA_FORMAT_BODY_FOREACH(body, size, iter) \
- for ((iter) = SPA_MEMBER((body), sizeof(struct spa_format_body), struct spa_pod_prop); \
- (iter) < SPA_MEMBER((body), (size), struct spa_pod_prop); \
- (iter) = SPA_MEMBER((iter), SPA_ROUND_UP_N(SPA_POD_SIZE(iter), 8), struct spa_pod_prop))
-
-#define SPA_FORMAT_FOREACH(format, iter) \
- SPA_FORMAT_BODY_FOREACH(&format->body, SPA_POD_BODY_SIZE(format), iter)
-
-#define SPA_FORMAT_MEDIA_TYPE(f) SPA_POD_VALUE(struct spa_pod_id, &f->body.media_type)
-#define SPA_FORMAT_MEDIA_SUBTYPE(f) SPA_POD_VALUE(struct spa_pod_id, &f->body.media_subtype)
-
-#define spa_format_parse(format,...) \
-({ \
- struct spa_pod_parser __p; \
- const struct spa_format *__format = format; \
- spa_pod_parser_pod(&__p, &__format->pod); \
- spa_pod_parser_get(&__p, "<", ##__VA_ARGS__, NULL); \
-})
-
-static inline struct spa_pod_prop *spa_format_find_prop(const struct spa_format *format, uint32_t key)
-{
- return spa_pod_contents_find_prop(&format->pod, sizeof(struct spa_format), key);
-}
-
-static inline int spa_format_fixate(struct spa_format *format)
-{
- struct spa_pod_prop *prop;
-
- SPA_FORMAT_FOREACH(format, prop)
- prop->body.flags &= ~SPA_POD_PROP_FLAG_UNSET;
-
- return SPA_RESULT_OK;
-}
-
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/spa/include/spa/format.h b/spa/include/spa/format.h
index 4f4d72c1..a9c05b33 100644
--- a/spa/include/spa/format.h
+++ b/spa/include/spa/format.h
@@ -24,7 +24,6 @@
extern "C" {
#endif
-struct spa_format;
#define SPA_TYPE__Format SPA_TYPE_POD_OBJECT_BASE "Format"
#define SPA_TYPE_FORMAT_BASE SPA_TYPE__Format ":"
@@ -77,24 +76,6 @@ struct spa_format;
#define SPA_TYPE_MEDIA_SUBTYPE__gsm SPA_TYPE_MEDIA_SUBTYPE_BASE "gsm"
#define SPA_TYPE_MEDIA_SUBTYPE__midi SPA_TYPE_MEDIA_SUBTYPE_BASE "midi"
-struct spa_format_body {
- struct spa_pod_object_body obj_body;
- struct spa_pod_id media_type SPA_ALIGNED(8);
- struct spa_pod_id media_subtype SPA_ALIGNED(8);
- /* contents follow, series of spa_pod_prop */
-};
-
-/**
- * spa_format:
- * @media_type: media type
- * @media_subtype: subtype
- * @pod: POD object with properties
- */
-struct spa_format {
- struct spa_pod pod;
- struct spa_format_body body;
-};
-
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/spa/include/spa/meson.build b/spa/include/spa/meson.build
index 18e0bbce..dbe9cd4f 100644
--- a/spa/include/spa/meson.build
+++ b/spa/include/spa/meson.build
@@ -8,7 +8,6 @@ spa_headers = [
'event.h',
'event-node.h',
'format.h',
- 'format-builder.h',
'format-utils.h',
'hook.h',
'list.h',
diff --git a/spa/include/spa/node.h b/spa/include/spa/node.h
index 126ea174..c16d6e98 100644
--- a/spa/include/spa/node.h
+++ b/spa/include/spa/node.h
@@ -32,6 +32,7 @@ struct spa_node;
#include <spa/defs.h>
#include <spa/plugin.h>
#include <spa/props.h>
+#include <spa/pod-builder.h>
#include <spa/param.h>
#include <spa/event-node.h>
#include <spa/command-node.h>
@@ -134,6 +135,10 @@ struct spa_node_callbacks {
};
+#define SPA_NODE_PARAM_FLAG_TEST_ONLY (1 << 0) /* just check if the param is accepted */
+#define SPA_NODE_PARAM_FLAG_FIXATE (1 << 1) /* fixate the non-optional unset fields */
+#define SPA_NODE_PARAM_FLAG_NEAREST (1 << 2) /* allow set fields to be rounded to the
+ * nearest allowed field value. */
/**
* struct spa_node:
*
@@ -154,49 +159,61 @@ struct spa_node {
*/
const struct spa_dict *info;
/**
- * spa_node::get_props:
- * @node: a #spa_node
- * @props: a location for a #struct spa_props pointer
+ * Enumerate the parameters of a node.
*
- * Get the configurable properties of @node.
+ * Parameters are identified with an \a id. Some parameters can have
+ * multiple values, see the documentation of the parameter id.
*
- * The returned @props is a snapshot of the current configuration and
- * can be modified. The modifications will take effect after a call
- * to spa_node::set_props.
+ * Parameters can be filtered by passing a non-NULL \a filter.
*
* This function must be called from the main thread.
*
- * Returns: #SPA_RESULT_OK on success
- * #SPA_RESULT_INVALID_ARGUMENTS when node or props are %NULL
- * #SPA_RESULT_NOT_IMPLEMENTED when there are no properties
- * implemented on @node
+ * \param node a \ref spa_node
+ * \param id the param id to enumerate
+ * \param index the index of enumeration, pass 0 for the first item and the
+ * index is updated to retrieve the next item.
+ * \param filter and optional filter to use
+ * \param param builder for the result object.
+ *
+ * \return #SPA_RESULT_OK on success
+ * #SPA_RESULT_INVALID_ARGUMENTS when node or builder are %NULL
+ * #SPA_RESULT_UNKNOWN_PARAM the parameter \a id is unknown
+ * #SPA_RESULT_ENUM_END when there are no more parameters to enumerate
+ * #SPA_RESULT_NOT_IMPLEMENTED when there are no parameters
+ * implemented on \a node
*/
- int (*get_props) (struct spa_node *node, struct spa_props **props);
+ int (*enum_params) (struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder);
/**
- * struct spa_node::set_props:
- * @node: a #struct spa_node
- * @props: a #struct spa_props
- *
- * Set the configurable properties in @node.
+ * Set the configurable parameter in \a node.
*
- * Usually, @props will be obtained from struct spa_node::get_props and then
- * modified but it is also possible to set another #struct spa_props object
- * as long as its keys and types match those of struct spa_props::get_props.
+ * Usually, \a param will be obtained from enum_params and then
+ * modified but it is also possible to set another spa_pod_object
+ * as long as its keys and types match a supported object.
*
- * Properties with keys that are not known are ignored.
- *
- * If @props is NULL, all the properties are reset to their defaults.
+ * Objects with property keys that are not known are ignored.
*
* This function must be called from the main thread.
*
- * Returns: #SPA_RESULT_OK on success
- * #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
- * #SPA_RESULT_NOT_IMPLEMENTED when no properties can be
- * modified on @node.
- * #SPA_RESULT_WRONG_PROPERTY_TYPE when a property has the wrong
+ * \param node a \ref spa_node
+ * \param id the parameter id to configure
+ * \param flags additional flags
+ * \param param the parameter to configure
+ *
+ * \return #SPA_RESULT_OK on success
+ * #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
+ * #SPA_RESULT_NOT_IMPLEMENTED when there are no parameters
+ * implemented on \a node
+ * #SPA_RESULT_WRONG_PROPERTY_TYPE when a property has the wrong
* type.
+ * #SPA_RESULT_UNKNOWN_PARAM the parameter is unknown
*/
- int (*set_props) (struct spa_node *node, const struct spa_props *props);
+ int (*set_param) (struct spa_node *node,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param);
+
/**
* struct spa_node::send_command:
* @node: a #struct spa_node
@@ -292,117 +309,72 @@ struct spa_node {
int (*add_port) (struct spa_node *node, enum spa_direction direction, uint32_t port_id);
int (*remove_port) (struct spa_node *node, enum spa_direction direction, uint32_t port_id);
+ int (*port_get_info) (struct spa_node *node,
+ enum spa_direction direction,
+ uint32_t port_id,
+ const struct spa_port_info **info);
+
/**
- * struct spa_node::port_enum_formats:
- * @node: a #struct spa_node
- * @direction: a #enum spa_direction
- * @port_id: the port to query
- * @format: pointer to a format
- * @filter: a format filter
- * @index: an index variable, 0 to get the first item
+ * Enumerate all possible parameters of \a id on \a port_id of \a node
+ * that are compatible with \a filter.
*
- * Enumerate all possible formats on @port_id of @node that are compatible
- * with @filter. When @port_id is #SPA_ID_INVALID, the enumeration will
- * list all the formats possible on a port that would be added with
- * add_port().
- *
- * Use @index to retrieve the formats one by one until the function
+ * Use \a index to retrieve the parameters one by one until the function
* returns #SPA_RESULT_ENUM_END.
*
- * The result format can be queried and modified and ultimately be used
- * to call struct spa_node::port_set_format.
+ * The result parameters can be queried and modified and ultimately be used
+ * to call struct spa_node::port_set_param.
*
* This function must be called from the main thread.
*
- * Returns: #SPA_RESULT_OK on success
- * #SPA_RESULT_INVALID_ARGUMENTS when node or format is %NULL
- * #SPA_RESULT_INVALID_PORT when port_id is not valid
- * #SPA_RESULT_ENUM_END when no format exists
+ * \param node a #struct spa_node
+ * \param direction a #enum spa_direction
+ * \param port_id the port to query
+ * \param id the parameter id to query
+ * \param index an index state variable, 0 to get the first item
+ * \param filter a parameter filter or NULL for no filter
+ * \param builder a builder for the result parameter object
+ * \return #SPA_RESULT_OK on success
+ * #SPA_RESULT_INVALID_ARGUMENTS when node or index or builder is %NULL
+ * #SPA_RESULT_INVALID_PORT when port_id is not valid
+ * #SPA_RESULT_ENUM_END when no more parameters exists
+ * #SPA_RESULT_UNKNOWN_PARAM when \a id is unknown
*/
- int (*port_enum_formats) (struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index);
- /**
- * struct spa_node::port_set_format:
- * @node: a #struct spa_node
- * @direction: a #enum spa_direction
- * @port_id: the port to configure
- * @flags: flags
- * @format: a #struct spa_format with the format
- *
- * Set a format on @port_id of @node.
- *
- * When @format is %NULL, the current format will be removed.
- *
- * This function takes a copy of the format.
- *
- * Upon completion, this function might change the state of a node to
- * the READY state or to CONFIGURE when @format is NULL.
- *
- * This function must be called from the main thread.
- *
- * Returns: #SPA_RESULT_OK on success
- * #SPA_RESULT_OK_RECHECK on success, the value of @format might have been
- * changed depending on @flags and the final value can be found by
- * doing struct spa_node::get_format.
- * #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
- * #SPA_RESULT_INVALID_PORT when port_id is not valid
- * #SPA_RESULT_INVALID_MEDIA_TYPE when the media type is not valid
- * #SPA_RESULT_INVALID_FORMAT_PROPERTIES when one of the mandatory format
- * properties is not specified and #SPA_PORT_FORMAT_FLAG_FIXATE was
- * not set in @flags.
- * #SPA_RESULT_WRONG_PROPERTY_TYPE when the type or size of a property
- * is not correct.
- * #SPA_RESULT_ASYNC the function is executed asynchronously
- */
-#define SPA_PORT_FORMAT_FLAG_TEST_ONLY (1 << 0) /* just check if the format is accepted */
-#define SPA_PORT_FORMAT_FLAG_FIXATE (1 << 1) /* fixate the non-optional unset fields */
-#define SPA_PORT_FORMAT_FLAG_NEAREST (1 << 2) /* allow set fields to be rounded to the
- * nearest allowed field value. */
- int (*port_set_format) (struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format);
+ int (*port_enum_params) (struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder);
+
/**
- * struct spa_node::port_get_format:
- * @node: a #struct spa_node
- * @direction: a #enum spa_direction
- * @port_id: the port to query
- * @format: a pointer to a location to hold the #struct spa_format
+ * Set a parameter on \a port_id of \a node.
*
- * Get the format on @port_id of @node. The result #struct spa_format can
- * not be modified.
+ * When \a param is %NULL, the parameter will be unset.
*
* This function must be called from the main thread.
*
- * Returns: #SPA_RESULT_OK on success
- * #SPA_RESULT_INVALID_ARGUMENTS when @node or @format is %NULL
- * #SPA_RESULT_INVALID_PORT when @port_id is not valid
- * #SPA_RESULT_INVALID_NO_FORMAT when no format was set
+ * \param node a #struct spa_node
+ * \param direction a #enum spa_direction
+ * \param port_id the port to configure
+ * \param flags optional flags
+ * \param param a #struct spa_pod_object with the parameter to set
+ * \return #SPA_RESULT_OK on success
+ * #SPA_RESULT_OK_RECHECK on success, the value of \a param might have been
+ * changed depending on \a flags and the final value can be found by
+ * doing struct spa_node::enum_params.
+ * #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
+ * #SPA_RESULT_INVALID_PORT when port_id is not valid
+ * #SPA_RESULT_INVALID_PARAM_INCOMPLETE when one of the mandatory param
+ * properties is not specified and #SPA_NODE_PARAM_FLAG_FIXATE was
+ * not set in \a flags.
+ * #SPA_RESULT_WRONG_PROPERTY_TYPE when the type or size of a property
+ * is not correct.
+ * #SPA_RESULT_ASYNC the function is executed asynchronously
*/
- int (*port_get_format) (struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_format **format);
-
- int (*port_get_info) (struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_port_info **info);
-
- int (*port_enum_params) (struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t index,
- struct spa_param **param);
int (*port_set_param) (struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- const struct spa_param *param);
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param);
/**
* struct spa_node::port_use_buffers:
@@ -477,7 +449,7 @@ struct spa_node {
int (*port_alloc_buffers) (struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers);
@@ -595,17 +567,14 @@ struct spa_node {
int (*process_output) (struct spa_node *node);
};
-#define spa_node_get_props(n,...) (n)->get_props((n),__VA_ARGS__)
-#define spa_node_set_props(n,...) (n)->set_props((n),__VA_ARGS__)
+#define spa_node_enum_params(n,...) (n)->enum_params((n),__VA_ARGS__)
+#define spa_node_set_param(n,...) (n)->set_param((n),__VA_ARGS__)
#define spa_node_send_command(n,...) (n)->send_command((n),__VA_ARGS__)
#define spa_node_set_callbacks(n,...) (n)->set_callbacks((n),__VA_ARGS__)
#define spa_node_get_n_ports(n,...) (n)->get_n_ports((n),__VA_ARGS__)
#define spa_node_get_port_ids(n,...) (n)->get_port_ids((n),__VA_ARGS__)
#define spa_node_add_port(n,...) (n)->add_port((n),__VA_ARGS__)
#define spa_node_remove_port(n,...) (n)->remove_port((n),__VA_ARGS__)
-#define spa_node_port_enum_formats(n,...) (n)->port_enum_formats((n),__VA_ARGS__)
-#define spa_node_port_set_format(n,...) (n)->port_set_format((n),__VA_ARGS__)
-#define spa_node_port_get_format(n,...) (n)->port_get_format((n),__VA_ARGS__)
#define spa_node_port_get_info(n,...) (n)->port_get_info((n),__VA_ARGS__)
#define spa_node_port_enum_params(n,...) (n)->port_enum_params((n),__VA_ARGS__)
#define spa_node_port_set_param(n,...) (n)->port_set_param((n),__VA_ARGS__)
diff --git a/spa/include/spa/param-alloc.h b/spa/include/spa/param-alloc.h
index 9b4252d1..b0035b87 100644
--- a/spa/include/spa/param-alloc.h
+++ b/spa/include/spa/param-alloc.h
@@ -66,6 +66,7 @@ spa_type_param_alloc_buffers_map(struct spa_type_map *map,
#define SPA_TYPE_PARAM_ALLOC_META_ENABLE__size SPA_TYPE_PARAM_ALLOC_META_ENABLE_BASE "size"
#define SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferSize SPA_TYPE_PARAM_ALLOC_META_ENABLE_BASE "ringbufferSize"
+#define SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferMinAvail SPA_TYPE_PARAM_ALLOC_META_ENABLE_BASE "ringbufferMinAvail"
#define SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferStride SPA_TYPE_PARAM_ALLOC_META_ENABLE_BASE "ringbufferStride"
#define SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferBlocks SPA_TYPE_PARAM_ALLOC_META_ENABLE_BASE "ringbufferBlocks"
#define SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferAlign SPA_TYPE_PARAM_ALLOC_META_ENABLE_BASE "ringbufferAlign"
@@ -75,6 +76,7 @@ struct spa_type_param_alloc_meta_enable {
uint32_t type;
uint32_t size;
uint32_t ringbufferSize;
+ uint32_t ringbufferMinAvail;
uint32_t ringbufferStride;
uint32_t ringbufferBlocks;
uint32_t ringbufferAlign;
@@ -85,13 +87,21 @@ spa_type_param_alloc_meta_enable_map(struct spa_type_map *map,
struct spa_type_param_alloc_meta_enable *type)
{
if (type->MetaEnable == 0) {
- type->MetaEnable = spa_type_map_get_id(map, SPA_TYPE_PARAM_ALLOC__MetaEnable);
- type->type = spa_type_map_get_id(map, SPA_TYPE_PARAM_ALLOC_META_ENABLE__type);
- type->size = spa_type_map_get_id(map, SPA_TYPE_PARAM_ALLOC_META_ENABLE__size);
- type->ringbufferSize = spa_type_map_get_id(map, SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferSize);
- type->ringbufferStride = spa_type_map_get_id(map, SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferStride);
- type->ringbufferBlocks = spa_type_map_get_id(map, SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferBlocks);
- type->ringbufferAlign = spa_type_map_get_id(map, SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferAlign);
+ int i;
+#define OFF(n) offsetof(struct spa_type_param_alloc_meta_enable, n)
+ static struct { off_t offset; const char *type; } tab[] = {
+ { OFF(MetaEnable), SPA_TYPE_PARAM_ALLOC__MetaEnable },
+ { OFF(type), SPA_TYPE_PARAM_ALLOC_META_ENABLE__type },
+ { OFF(size), SPA_TYPE_PARAM_ALLOC_META_ENABLE__size },
+ { OFF(ringbufferSize), SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferSize },
+ { OFF(ringbufferMinAvail), SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferMinAvail },
+ { OFF(ringbufferStride), SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferStride },
+ { OFF(ringbufferBlocks), SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferBlocks },
+ { OFF(ringbufferAlign), SPA_TYPE_PARAM_ALLOC_META_ENABLE__ringbufferAlign },
+ };
+#undef OFF
+ for (i = 0; i < SPA_N_ELEMENTS(tab); i++)
+ *SPA_MEMBER(type, tab[i].offset, uint32_t) = spa_type_map_get_id(map, tab[i].type);
}
}
diff --git a/spa/include/spa/param.h b/spa/include/spa/param.h
index 91d86e28..f6f5d593 100644
--- a/spa/include/spa/param.h
+++ b/spa/include/spa/param.h
@@ -26,52 +26,64 @@ extern "C" {
#include <spa/defs.h>
#include <spa/pod-utils.h>
+#include <spa/type-map.h>
-struct spa_param;
-#define SPA_TYPE__Param SPA_TYPE_POD_OBJECT_BASE "Param"
-#define SPA_TYPE_PARAM_BASE SPA_TYPE__Param ":"
+/* base for parameter objects */
+#define SPA_TYPE__Param SPA_TYPE_POD_OBJECT_BASE "Param"
+#define SPA_TYPE_PARAM_BASE SPA_TYPE__Param ":"
-struct spa_param {
- struct spa_pod_object object;
-};
+/* base for parameter object enumerations */
+#define SPA_TYPE__ParamId SPA_TYPE_ENUM_BASE "ParamId"
+#define SPA_TYPE_PARAM_ID_BASE SPA_TYPE__ParamId ":"
-static inline uint32_t
-spa_pod_builder_push_param(struct spa_pod_builder *builder,
- struct spa_pod_frame *frame,
- uint32_t param_type)
-{
- return spa_pod_builder_push_object(builder, frame, 0, param_type);
-}
+/** List of supported parameters */
+#define SPA_TYPE_PARAM_ID__List SPA_TYPE_PARAM_ID_BASE "List"
-#define spa_pod_builder_param(b,param_type,...) \
- spa_pod_builder_object(b, 0, param_type, \
- ##__VA_ARGS__)
+/* object with supported parameter id */
+#define SPA_TYPE_PARAM__List SPA_TYPE_PARAM_BASE "List"
+#define SPA_TYPE_PARAM_LIST_BASE SPA_TYPE_PARAM__List ":"
+#define SPA_TYPE_PARAM_LIST__id SPA_TYPE_PARAM_LIST_BASE "id"
+/** Property parameter id, deals with SPA_TYPE__Props */
+#define SPA_TYPE_PARAM_ID__Props SPA_TYPE_PARAM_ID_BASE "Props"
-#define spa_param_parse(param,...) \
-({ \
- struct spa_pod_parser __p; \
- const struct spa_param *__param = param; \
- spa_pod_parser_pod(&__p, &__param->object.pod); \
- spa_pod_parser_get(&__p, "<", ##__VA_ARGS__, NULL); \
-})
+/** The available formats */
+#define SPA_TYPE_PARAM_ID__EnumFormat SPA_TYPE_PARAM_ID_BASE "EnumFormat"
-#define SPA_PARAM_BODY_FOREACH(body, size, iter) \
- for ((iter) = SPA_MEMBER((body), sizeof(struct spa_pod_object_body), struct spa_pod_prop); \
- (iter) < SPA_MEMBER((body), (size), struct spa_pod_prop); \
- (iter) = SPA_MEMBER((iter), SPA_ROUND_UP_N(SPA_POD_SIZE(iter), 8), struct spa_pod_prop))
+/** The current format */
+#define SPA_TYPE_PARAM_ID__Format SPA_TYPE_PARAM_ID_BASE "Format"
-#define SPA_PARAM_FOREACH(param, iter) \
- SPA_PARAM_BODY_FOREACH(&param->object.body, SPA_POD_BODY_SIZE(param), iter)
+/** The supported buffer sizes */
+#define SPA_TYPE_PARAM_ID__Buffers SPA_TYPE_PARAM_ID_BASE "Buffers"
-static inline int spa_param_fixate(struct spa_param *param)
-{
- struct spa_pod_prop *prop;
+/** The supported metadata */
+#define SPA_TYPE_PARAM_ID__Meta SPA_TYPE_PARAM_ID_BASE "Meta"
- SPA_PARAM_FOREACH(param, prop)
- prop->body.flags &= ~SPA_POD_PROP_FLAG_UNSET;
+struct spa_type_param {
+ uint32_t idList; /**< id of the list param */
+ uint32_t List; /**< list object type */
+ uint32_t listId; /**< id in the list object */
+ uint32_t idProps; /**< id to enumerate properties */
+ uint32_t idEnumFormat; /**< id to enumerate formats */
+ uint32_t idFormat; /**< id to get/set format parameter */
+ uint32_t idBuffers; /**< id to enumerate buffer requirements */
+ uint32_t idMeta; /**< id to enumerate supported metadata */
+};
- return SPA_RESULT_OK;
+static inline void
+spa_type_param_map(struct spa_type_map *map,
+ struct spa_type_param *type)
+{
+ if (type->idList == 0) {
+ type->idList = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID__List);
+ type->List = spa_type_map_get_id(map, SPA_TYPE_PARAM__List);
+ type->listId = spa_type_map_get_id(map, SPA_TYPE_PARAM_LIST__id);
+ type->idProps = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID__Props);
+ type->idEnumFormat = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID__EnumFormat);
+ type->idFormat = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID__Format);
+ type->idBuffers = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID__Buffers);
+ type->idMeta = spa_type_map_get_id(map, SPA_TYPE_PARAM_ID__Meta);
+ }
}
#ifdef __cplusplus
diff --git a/spa/include/spa/pod-utils.h b/spa/include/spa/pod-utils.h
index 56442c42..bad8dc73 100644
--- a/spa/include/spa/pod-utils.h
+++ b/spa/include/spa/pod-utils.h
@@ -98,6 +98,8 @@ static inline struct spa_pod_prop *spa_pod_struct_find_prop(const struct spa_pod
return spa_pod_contents_find_prop(&obj->pod, sizeof(struct spa_pod_struct), key);
}
+#include <spa/pod-parser.h>
+
#define spa_pod_object_parse(object,...) \
({ \
struct spa_pod_parser __p; \
@@ -106,6 +108,16 @@ static inline struct spa_pod_prop *spa_pod_struct_find_prop(const struct spa_pod
spa_pod_parser_get(&__p, "<", ##__VA_ARGS__, NULL); \
})
+static inline int spa_pod_object_fixate(struct spa_pod_object *obj)
+{
+ struct spa_pod *res;
+ SPA_POD_OBJECT_FOREACH(obj, res) {
+ if (res->type == SPA_POD_TYPE_PROP)
+ ((struct spa_pod_prop *) res)->body.flags &= ~SPA_POD_PROP_FLAG_UNSET;
+ }
+ return SPA_RESULT_OK;
+}
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/spa/include/spa/props.h b/spa/include/spa/props.h
index 4566aca8..64e973bb 100644
--- a/spa/include/spa/props.h
+++ b/spa/include/spa/props.h
@@ -25,16 +25,12 @@ extern "C" {
#endif
#include <spa/pod.h>
-#include <spa/pod-builder.h>
-#include <spa/pod-parser.h>
+#include <spa/param.h>
-struct spa_props {
- struct spa_pod_object object;
-};
-
-#define SPA_TYPE__Props SPA_TYPE_POD_OBJECT_BASE "Props"
-#define SPA_TYPE_PROPS_BASE SPA_TYPE__Props ":"
+#define SPA_TYPE__Props SPA_TYPE_POD_OBJECT_BASE "Props"
+#define SPA_TYPE_PROPS_BASE SPA_TYPE__Props ":"
+/** Common property ids */
#define SPA_TYPE_PROPS__device SPA_TYPE_PROPS_BASE "device"
#define SPA_TYPE_PROPS__deviceName SPA_TYPE_PROPS_BASE "deviceName"
#define SPA_TYPE_PROPS__deviceFd SPA_TYPE_PROPS_BASE "deviceFd"
@@ -52,25 +48,6 @@ struct spa_props {
#define SPA_TYPE_PROPS__mute SPA_TYPE_PROPS_BASE "mute"
#define SPA_TYPE_PROPS__patternType SPA_TYPE_PROPS_BASE "patternType"
-static inline uint32_t
-spa_pod_builder_push_props(struct spa_pod_builder *builder,
- struct spa_pod_frame *frame,
- uint32_t props_type)
-{
- return spa_pod_builder_push_object(builder, frame, 0, props_type);
-}
-
-#define spa_pod_builder_props(b,props_type,...) \
- spa_pod_builder_object(b, 0, props_type,##__VA_ARGS__)
-
-#define spa_props_parse(props,...) \
-({ \
- struct spa_pod_parser __p; \
- const struct spa_props *__props = props; \
- spa_pod_parser_pod(&__p, &__props->object.pod); \
- spa_pod_parser_get(&__p, "<", ##__VA_ARGS__, NULL); \
-})
-
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/spa/include/spa/video/format-utils.h b/spa/include/spa/video/format-utils.h
index e0f51f59..8a8a8486 100644
--- a/spa/include/spa/video/format-utils.h
+++ b/spa/include/spa/video/format-utils.h
@@ -75,7 +75,7 @@ spa_type_format_video_map(struct spa_type_map *map, struct spa_type_format_video
}
static inline int
-spa_format_video_raw_parse(const struct spa_format *format,
+spa_format_video_raw_parse(const struct spa_pod_object *format,
struct spa_video_info_raw *info, struct spa_type_format_video *type)
{
struct spa_pod_parser prs;
@@ -98,7 +98,7 @@ spa_format_video_raw_parse(const struct spa_format *format,
}
static inline int
-spa_format_video_h264_parse(const struct spa_format *format,
+spa_format_video_h264_parse(const struct spa_pod_object *format,
struct spa_video_info_h264 *info, struct spa_type_format_video *type)
{
struct spa_pod_parser prs;
@@ -112,7 +112,7 @@ spa_format_video_h264_parse(const struct spa_format *format,
}
static inline int
-spa_format_video_mjpg_parse(const struct spa_format *format,
+spa_format_video_mjpg_parse(const struct spa_pod_object *format,
struct spa_video_info_mjpg *info, struct spa_type_format_video *type)
{
struct spa_pod_parser prs;
diff --git a/spa/lib/debug.c b/spa/lib/debug.c
index cc137c36..1d18032f 100644
--- a/spa/lib/debug.c
+++ b/spa/lib/debug.c
@@ -138,18 +138,6 @@ int spa_debug_dump_mem(const void *mem, size_t size)
return SPA_RESULT_OK;
}
-int spa_debug_props(const struct spa_props *props)
-{
- spa_debug_pod(&props->object.pod);
- return SPA_RESULT_OK;
-}
-
-int spa_debug_param(const struct spa_param *param)
-{
- spa_debug_pod(&param->object.pod);
- return SPA_RESULT_OK;
-}
-
static const char *pod_type_names[] = {
[SPA_POD_TYPE_INVALID] = "invalid",
[SPA_POD_TYPE_NONE] = "none",
@@ -248,7 +236,8 @@ print_pod_value(uint32_t size, uint32_t type, void *body, int prefix)
struct spa_pod_object_body *b = body;
struct spa_pod *p;
- printf("%-*sObject: size %d, id %d, type %s\n", prefix, "", size, b->id,
+ printf("%-*sObject: size %d, id %s, type %s\n", prefix, "", size,
+ map ? spa_type_map_get_type(map, b->id) : "*no map*",
map ? spa_type_map_get_type(map, b->type) : "*no map*");
SPA_POD_OBJECT_BODY_FOREACH(b, size, p)
print_pod_value(p->size, p->type, SPA_POD_BODY(p), prefix + 2);
@@ -292,12 +281,6 @@ print_pod_value(uint32_t size, uint32_t type, void *body, int prefix)
}
}
-int spa_debug_pod(const struct spa_pod *pod)
-{
- print_pod_value(pod->size, pod->type, SPA_POD_BODY(pod), 0);
- return SPA_RESULT_OK;
-}
-
static void
print_format_value(uint32_t size, uint32_t type, void *body)
{
@@ -356,19 +339,20 @@ print_format_value(uint32_t size, uint32_t type, void *body)
}
}
-int spa_debug_format(const struct spa_format *format)
+static int spa_debug_format(const struct spa_pod_object *format)
{
int i;
const char *media_type;
const char *media_subtype;
- struct spa_pod_prop *prop;
+ struct spa_pod *pod;
uint32_t mtype, mstype;
if (format == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
- mtype = format->body.media_type.value;
- mstype = format->body.media_subtype.value;
+ if (spa_pod_object_parse(format, "I", &mtype,
+ "I", &mstype) < 0)
+ return SPA_RESULT_INVALID_ARGUMENTS;
media_type = spa_type_map_get_type(map, mtype);
media_subtype = spa_type_map_get_type(map, mstype);
@@ -376,9 +360,15 @@ int spa_debug_format(const struct spa_format *format)
fprintf(stderr, "%-6s %s/%s\n", "", rindex(media_type, ':') + 1,
rindex(media_subtype, ':') + 1);
- SPA_FORMAT_FOREACH(format, prop) {
+ SPA_POD_OBJECT_FOREACH(format, pod) {
+ struct spa_pod_prop *prop;
const char *key;
+ if (pod->type != SPA_POD_TYPE_PROP)
+ continue;
+
+ prop = (struct spa_pod_prop *)pod;
+
if ((prop->body.flags & SPA_POD_PROP_FLAG_UNSET) &&
(prop->body.flags & SPA_POD_PROP_FLAG_OPTIONAL))
continue;
@@ -428,6 +418,19 @@ int spa_debug_format(const struct spa_format *format)
return SPA_RESULT_OK;
}
+int spa_debug_pod(const struct spa_pod *pod, uint32_t flags)
+{
+ int res = SPA_RESULT_OK;
+
+ if (flags & SPA_DEBUG_FLAG_FORMAT)
+ res = spa_debug_format((struct spa_pod_object*)pod);
+ else
+ print_pod_value(pod->size, pod->type, SPA_POD_BODY(pod), 0);
+
+ return res;
+}
+
+
int spa_debug_dict(const struct spa_dict *dict)
{
unsigned int i;
diff --git a/spa/lib/debug.h b/spa/lib/debug.h
index e63213b2..91c82fd0 100644
--- a/spa/lib/debug.h
+++ b/spa/lib/debug.h
@@ -37,10 +37,8 @@ void spa_debug_set_type_map(const struct spa_type_map *map);
int spa_debug_port_info(const struct spa_port_info *info);
int spa_debug_buffer(const struct spa_buffer *buffer);
-int spa_debug_props(const struct spa_props *props);
-int spa_debug_param(const struct spa_param *param);
-int spa_debug_pod(const struct spa_pod *pod);
-int spa_debug_format(const struct spa_format *format);
+#define SPA_DEBUG_FLAG_FORMAT (1 << 0)
+int spa_debug_pod(const struct spa_pod *pod, uint32_t flags);
int spa_debug_dump_mem(const void *data, size_t size);
int spa_debug_dict(const struct spa_dict *dict);
diff --git a/spa/lib/format.c b/spa/lib/format.c
index 6577065c..0230fc15 100644
--- a/spa/lib/format.c
+++ b/spa/lib/format.c
@@ -22,57 +22,44 @@
#include <stdio.h>
#include <string.h>
-#include <spa/format-builder.h>
-#include <spa/video/format-utils.h>
-
#include <lib/props.h>
int
-spa_format_filter(const struct spa_format *format,
- const struct spa_format *filter,
- struct spa_pod_builder *result)
+spa_pod_object_filter(const struct spa_pod_object *obj,
+ struct spa_pod_object *filter,
+ struct spa_pod_builder *result)
{
struct spa_pod_frame f;
int res;
- if (format == NULL || result == NULL)
+ if (obj == NULL || result == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (filter == NULL) {
- spa_pod_builder_raw_padded(result, format, SPA_POD_SIZE(format));
+ spa_pod_builder_raw_padded(result, obj, SPA_POD_SIZE(obj));
return SPA_RESULT_OK;
}
- if (SPA_FORMAT_MEDIA_TYPE(filter) != SPA_FORMAT_MEDIA_TYPE(format) ||
- SPA_FORMAT_MEDIA_SUBTYPE(filter) != SPA_FORMAT_MEDIA_SUBTYPE(format))
- return SPA_RESULT_INVALID_MEDIA_TYPE;
-
- spa_pod_builder_push_format(result, &f, filter->body.obj_body.type,
- SPA_FORMAT_MEDIA_TYPE(filter),
- SPA_FORMAT_MEDIA_SUBTYPE(filter));
+ spa_pod_builder_push_object(result, &f, obj->body.id, obj->body.type);
res = spa_props_filter(result,
- SPA_POD_CONTENTS(struct spa_format, format),
- SPA_POD_CONTENTS_SIZE(struct spa_format, format),
- SPA_POD_CONTENTS(struct spa_format, filter),
- SPA_POD_CONTENTS_SIZE(struct spa_format, filter));
+ 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, &f);
return res;
}
int
-spa_format_compare(const struct spa_format *format1,
- const struct spa_format *format2)
+spa_pod_object_compare(const struct spa_pod_object *obj1,
+ const struct spa_pod_object *obj2)
{
- if (format1 == NULL || format2 == NULL)
+ if (obj1 == NULL || obj2 == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
- if (SPA_FORMAT_MEDIA_TYPE(format1) != SPA_FORMAT_MEDIA_TYPE(format2) ||
- SPA_FORMAT_MEDIA_SUBTYPE(format1) != SPA_FORMAT_MEDIA_SUBTYPE(format2))
- return SPA_RESULT_INVALID_MEDIA_TYPE;
-
- return spa_props_compare(SPA_POD_CONTENTS(struct spa_format, format1),
- SPA_POD_CONTENTS_SIZE(struct spa_format, format1),
- SPA_POD_CONTENTS(struct spa_format, format2),
- SPA_POD_CONTENTS_SIZE(struct spa_format, format2));
+ 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/format.h b/spa/lib/format.h
index 0b6ddc42..35a08f62 100644
--- a/spa/lib/format.h
+++ b/spa/lib/format.h
@@ -26,12 +26,12 @@ extern "C" {
#include <spa/props.h>
-int spa_format_filter(const struct spa_format *format,
- const struct spa_format *filter,
- struct spa_pod_builder *result);
+int spa_pod_object_filter(const struct spa_pod_object *obj,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *result);
-int spa_format_compare(const struct spa_format *format1,
- const struct spa_format *format2);
+int spa_pod_object_compare(const struct spa_pod_object *obj1,
+ const struct spa_pod_object *obj2);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/spa/lib/props.c b/spa/lib/props.c
index 9f7cf86a..513d1d21 100644
--- a/spa/lib/props.c
+++ b/spa/lib/props.c
@@ -23,6 +23,7 @@
#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)
{
diff --git a/spa/lib/props.h b/spa/lib/props.h
index f4351221..ec31b7ca 100644
--- a/spa/lib/props.h
+++ b/spa/lib/props.h
@@ -25,6 +25,7 @@ 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,
diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c
index b65fe423..5471a8d0 100644
--- a/spa/plugins/alsa/alsa-sink.c
+++ b/spa/plugins/alsa/alsa-sink.c
@@ -42,20 +42,22 @@ static void reset_props(struct props *props)
props->max_latency = default_max_latency;
}
-static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
+static int impl_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct state *this;
- struct spa_pod_builder b = { NULL, };
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct state, node);
- spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer));
-
- *props = spa_pod_builder_props(&b,
- this->type.props,
+ if (id == this->type.param.idProps) {
+ spa_pod_builder_object(builder,
+ id, this->type.props,
":", this->type.prop_device, "S", this->props.device, sizeof(this->props.device),
":", this->type.prop_device_name, "S", this->props.device_name, sizeof(this->props.device_name),
":", this->type.prop_card_name, "S", this->props.card_name, sizeof(this->props.card_name),
@@ -63,11 +65,15 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
2, 1, INT32_MAX,
":", this->type.prop_max_latency, "ir", this->props.max_latency,
2, 1, INT32_MAX);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
-static int impl_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct state *this;
@@ -75,14 +81,18 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr
this = SPA_CONTAINER_OF(node, struct state, node);
- if (props == NULL) {
- reset_props(&this->props);
- return SPA_RESULT_OK;
- } else {
- spa_props_parse(props,
+ if (id == this->type.param.idProps) {
+ if (param == NULL) {
+ reset_props(&this->props);
+ return SPA_RESULT_OK;
+ }
+ spa_pod_object_parse(param,
":", this->type.prop_device, "?S", this->props.device, sizeof(this->props.device),
":", this->type.prop_min_latency, "?i", &this->props.min_latency, NULL);
}
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
return SPA_RESULT_OK;
}
@@ -213,50 +223,149 @@ static int impl_node_remove_port(struct spa_node *node, enum spa_direction direc
}
static int
-impl_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+impl_node_port_get_info(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id, const struct spa_port_info **info)
{
struct state *this;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct state, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- return spa_alsa_enum_format(this, format, filter, index);
+ *info = &this->info;
+
+ return SPA_RESULT_OK;
}
-static int clear_buffers(struct state *this)
+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)
{
- if (this->n_buffers > 0) {
- spa_list_init(&this->ready);
- this->n_buffers = 0;
- }
+ struct state *this = SPA_CONTAINER_OF(node, struct state, node);
+ return spa_alsa_enum_format(this, index, filter, builder);
+}
+
+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_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format)
+impl_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
+
struct state *this;
- int err;
+ struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct state, node);
+ t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ 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,
+ INT32_MAX,
+ ":", t->param_alloc_buffers.stride, "i", 0,
+ ":", t->param_alloc_buffers.buffers, "ir", 2,
+ 2, 2, MAX_BUFFERS,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ switch (*index) {
+ case 0:
+ 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,
+ 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),
+ ":", t->param_alloc_meta_enable.ringbufferSize, "iru",
+ this->props.max_latency * this->frame_size,
+ 2, this->props.min_latency * this->frame_size,
+ this->period_frames * this->frame_size,
+ ":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
+ ":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
+ ":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
+ break;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
+ (*index)++;
+
+ return SPA_RESULT_OK;
+}
+
+static int clear_buffers(struct state *this)
+{
+ if (this->n_buffers > 0) {
+ spa_list_init(&this->ready);
+ this->n_buffers = 0;
+ }
+ 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 state *this = SPA_CONTAINER_OF(node, struct state, node);
+ int err;
+
if (format == NULL) {
spa_log_info(this->log, "clear format");
spa_alsa_pause(this, false);
@@ -264,9 +373,11 @@ impl_node_port_set_format(struct spa_node *node,
spa_alsa_close(this);
this->have_format = false;
} else {
- struct spa_audio_info info = { SPA_FORMAT_MEDIA_TYPE(format),
- SPA_FORMAT_MEDIA_SUBTYPE(format),
- };
+ struct spa_audio_info info = { 0 };
+
+ spa_pod_object_parse(format,
+ "I", &info.media_type,
+ "I", &info.media_subtype);
if (info.media_type != this->type.media_type.audio ||
info.media_subtype != this->type.media_subtype.raw)
@@ -291,123 +402,26 @@ impl_node_port_set_format(struct spa_node *node,
}
static int
-impl_node_port_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_format **format)
-{
- struct state *this;
- struct spa_pod_builder b = { NULL, };
- struct type *t;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct state, node);
- t = &this->type;
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- if (!this->have_format)
- return SPA_RESULT_NO_FORMAT;
-
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
- *format = spa_pod_builder_format(&b,
- t->format,
- t->media_type.audio, t->media_subtype.raw,
- ":", t->format_audio.format, "I", this->current_format.info.raw.format,
- ":", t->format_audio.rate, "i", this->current_format.info.raw.rate,
- ":", t->format_audio.channels, "i", this->current_format.info.raw.channels);
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_get_info(struct spa_node *node,
- enum spa_direction direction, uint32_t port_id, const struct spa_port_info **info)
-{
- struct state *this;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct state, node);
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- *info = &this->info;
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t index,
- struct spa_param **param)
+impl_node_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
-
struct state *this;
- struct spa_pod_builder b = { NULL };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct state, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- spa_pod_builder_init(&b, this->params_buffer, sizeof(this->params_buffer));
-
- switch (index) {
- case 0:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "iru", this->props.min_latency * this->frame_size,
- 2, this->props.min_latency * this->frame_size,
- INT32_MAX,
- ":", t->param_alloc_buffers.stride, "i", 0,
- ":", t->param_alloc_buffers.buffers, "ir", 2,
- 2, 2, MAX_BUFFERS,
- ":", t->param_alloc_buffers.align, "i", 16);
- break;
-
- case 1:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- break;
-
- case 2:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_ringbuffer),
- ":", t->param_alloc_meta_enable.ringbufferSize, "iru",
- this->props.max_latency * this->frame_size,
- 2, this->props.min_latency * this->frame_size,
- this->period_frames * this->frame_size,
- ":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
- ":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
- ":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
- break;
-
- default:
- return SPA_RESULT_ENUM_END;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
}
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_set_param(struct spa_node *node,
- enum spa_direction direction, uint32_t port_id, const struct spa_param *param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
@@ -462,7 +476,7 @@ static int
impl_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -573,17 +587,14 @@ static const struct spa_dict node_info = {
static const struct spa_node impl_node = {
SPA_VERSION_NODE,
&node_info,
- impl_node_get_props,
- impl_node_set_props,
+ impl_node_enum_params,
+ impl_node_set_param,
impl_node_send_command,
impl_node_set_callbacks,
impl_node_get_n_ports,
impl_node_get_port_ids,
impl_node_add_port,
impl_node_remove_port,
- impl_node_port_enum_formats,
- impl_node_port_set_format,
- impl_node_port_get_format,
impl_node_port_get_info,
impl_node_port_enum_params,
impl_node_port_set_param,
diff --git a/spa/plugins/alsa/alsa-source.c b/spa/plugins/alsa/alsa-source.c
index 8f86e440..9c5ce098 100644
--- a/spa/plugins/alsa/alsa-source.c
+++ b/spa/plugins/alsa/alsa-source.c
@@ -41,20 +41,21 @@ static void reset_props(struct props *props)
props->min_latency = default_min_latency;
}
-static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
+static int impl_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct state *this;
- struct spa_pod_builder b = { NULL, };
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct state, node);
- spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer));
-
- *props = spa_pod_builder_props(&b,
- this->type.props,
+ spa_pod_builder_object(builder,
+ id, this->type.props,
":", this->type.prop_device, "S", this->props.device, sizeof(this->props.device),
":", this->type.prop_device_name, "S", this->props.device_name, sizeof(this->props.device_name),
":", this->type.prop_card_name, "S", this->props.card_name, sizeof(this->props.card_name),
@@ -64,7 +65,8 @@ static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
return SPA_RESULT_OK;
}
-static int impl_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct state *this;
@@ -72,14 +74,9 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr
this = SPA_CONTAINER_OF(node, struct state, node);
- if (props == NULL) {
- reset_props(&this->props);
- return SPA_RESULT_OK;
- } else {
- spa_props_parse(props,
- ":", this->type.prop_device, "?S", this->props.device, sizeof(this->props.device),
- ":", this->type.prop_min_latency, "?i", &this->props.min_latency, NULL);
- }
+ spa_pod_object_parse(param,
+ ":", this->type.prop_device, "?S", this->props.device, sizeof(this->props.device),
+ ":", this->type.prop_min_latency, "?i", &this->props.min_latency, NULL);
return SPA_RESULT_OK;
}
@@ -227,21 +224,21 @@ static int impl_node_remove_port(struct spa_node *node, enum spa_direction direc
}
static int
-impl_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format, const struct spa_format *filter, uint32_t index)
+impl_node_port_get_info(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id, const struct spa_port_info **info)
{
struct state *this;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct state, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- return spa_alsa_enum_format(this, format, filter, index);
+ *info = &this->info;
+
+ return SPA_RESULT_OK;
}
static void recycle_buffer(struct state *this, uint32_t buffer_id)
@@ -257,39 +254,125 @@ static void recycle_buffer(struct state *this, uint32_t buffer_id)
spa_list_append(&this->free, &b->link);
}
-static int clear_buffers(struct state *this)
+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)
{
- if (this->n_buffers > 0) {
- spa_list_init(&this->free);
- spa_list_init(&this->ready);
- this->n_buffers = 0;
- }
+ struct state *this = SPA_CONTAINER_OF(node, struct state, node);
+ return spa_alsa_enum_format(this, index, filter, builder);
+}
+
+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_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id, uint32_t flags, const struct spa_format *format)
+impl_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct state *this;
- int err;
+ struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct state, node);
+ t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ 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,
+ ":", t->param_alloc_buffers.buffers, "ir", 2,
+ 2, 1, 32,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ switch (*index) {
+ case 0:
+ 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;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
+ (*index)++;
+
+ return SPA_RESULT_OK;
+}
+
+static int clear_buffers(struct state *this)
+{
+ if (this->n_buffers > 0) {
+ spa_list_init(&this->free);
+ spa_list_init(&this->ready);
+ this->n_buffers = 0;
+ }
+ 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 state *this = SPA_CONTAINER_OF(node, struct state, node);
+ int err;
+
if (format == NULL) {
spa_alsa_pause(this, false);
clear_buffers(this);
spa_alsa_close(this);
this->have_format = false;
} else {
- struct spa_audio_info info = { SPA_FORMAT_MEDIA_TYPE(format),
- SPA_FORMAT_MEDIA_SUBTYPE(format),
- };
+ struct spa_audio_info info = { 0 };
+
+ spa_pod_object_parse(format,
+ "I", &info.media_type,
+ "I", &info.media_subtype);
if (info.media_type != this->type.media_type.audio ||
info.media_subtype != this->type.media_subtype.raw)
@@ -314,101 +397,26 @@ impl_node_port_set_format(struct spa_node *node,
}
static int
-impl_node_port_get_format(struct spa_node *node,
- enum spa_direction direction, uint32_t port_id, const struct spa_format **format)
-{
- struct state *this;
- struct spa_pod_builder b = { NULL, };
- struct type *t;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct state, node);
- t = &this->type;
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- if (!this->have_format)
- return SPA_RESULT_NO_FORMAT;
-
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
- *format = spa_pod_builder_format(&b,
- t->format,
- t->media_type.audio, t->media_subtype.raw,
- ":", t->format_audio.format, "I", this->current_format.info.raw.format,
- ":", t->format_audio.rate, "i", this->current_format.info.raw.rate,
- ":", t->format_audio.channels, "i", this->current_format.info.raw.channels);
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_get_info(struct spa_node *node,
- enum spa_direction direction, uint32_t port_id, const struct spa_port_info **info)
-{
- struct state *this;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct state, node);
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- *info = &this->info;
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction, uint32_t port_id, uint32_t index, struct spa_param **param)
+impl_node_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct state *this;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct state, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- spa_pod_builder_init(&b, this->params_buffer, sizeof(this->params_buffer));
-
- switch (index) {
- case 0:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "i", this->props.min_latency * this->frame_size,
- ":", t->param_alloc_buffers.stride, "i", 0,
- ":", t->param_alloc_buffers.buffers, "ir", 2,
- 2, 1, 32,
- ":", t->param_alloc_buffers.align, "i", 16);
- break;
-
- case 1:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- break;
-
- default:
- return SPA_RESULT_NOT_IMPLEMENTED;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
}
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_set_param(struct spa_node *node,
- enum spa_direction direction, uint32_t port_id, const struct spa_param *param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
@@ -461,7 +469,7 @@ static int
impl_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -579,17 +587,14 @@ static const struct spa_dict node_info = {
static const struct spa_node impl_node = {
SPA_VERSION_NODE,
&node_info,
- impl_node_get_props,
- impl_node_set_props,
+ impl_node_enum_params,
+ impl_node_set_param,
impl_node_send_command,
impl_node_set_callbacks,
impl_node_get_n_ports,
impl_node_get_port_ids,
impl_node_add_port,
impl_node_remove_port,
- impl_node_port_enum_formats,
- impl_node_port_set_format,
- impl_node_port_get_format,
impl_node_port_get_info,
impl_node_port_enum_params,
impl_node_port_set_param,
@@ -602,12 +607,15 @@ static const struct spa_node impl_node = {
impl_node_process_output,
};
-static int impl_clock_get_props(struct spa_clock *clock, struct spa_props **props)
+static int impl_clock_enum_params(struct spa_clock *clock, uint32_t id, uint32_t *index,
+ struct spa_pod_builder *builder)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int impl_clock_set_props(struct spa_clock *clock, const struct spa_props *props)
+static int impl_clock_set_param(struct spa_clock *clock,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@@ -637,8 +645,8 @@ static const struct spa_clock impl_clock = {
SPA_VERSION_CLOCK,
NULL,
SPA_CLOCK_STATE_STOPPED,
- impl_clock_get_props,
- impl_clock_set_props,
+ impl_clock_enum_params,
+ impl_clock_set_param,
impl_clock_get_time,
};
diff --git a/spa/plugins/alsa/alsa-utils.c b/spa/plugins/alsa/alsa-utils.c
index e7cc2b26..58e82794 100644
--- a/spa/plugins/alsa/alsa-utils.c
+++ b/spa/plugins/alsa/alsa-utils.c
@@ -117,7 +117,9 @@ static snd_pcm_format_t spa_alsa_format_to_alsa(struct type *map, uint32_t forma
}
int
-spa_alsa_enum_format(struct state *state, struct spa_format **format, const struct spa_format *filter, uint32_t index)
+spa_alsa_enum_format(struct state *state, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
snd_pcm_t *hndl;
snd_pcm_hw_params_t *params;
@@ -128,11 +130,11 @@ spa_alsa_enum_format(struct state *state, struct spa_format **format, const stru
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
struct spa_pod_frame f[2];
struct spa_pod_prop *prop;
- struct spa_format *fmt;
+ struct spa_pod_object *fmt;
int res;
bool opened;
- if (index == 1)
+ if (*index > 0)
return SPA_RESULT_ENUM_END;
opened = state->opened;
@@ -143,8 +145,11 @@ spa_alsa_enum_format(struct state *state, struct spa_format **format, const stru
snd_pcm_hw_params_alloca(&params);
CHECK(snd_pcm_hw_params_any(hndl, params), "Broken configuration: no configurations available");
- spa_pod_builder_push_format(&b, &f[0], state->type.format,
- state->type.media_type.audio, state->type.media_subtype.raw);
+ spa_pod_builder_push_object(&b, &f[0],
+ state->type.param.idEnumFormat, state->type.format);
+ spa_pod_builder_add(&b,
+ "I", state->type.media_type.audio,
+ "I", state->type.media_subtype.raw, 0);
snd_pcm_format_mask_alloca(&fmask);
snd_pcm_hw_params_get_format_mask(params, fmask);
@@ -195,13 +200,13 @@ spa_alsa_enum_format(struct state *state, struct spa_format **format, const stru
spa_pod_builder_pop(&b, &f[1]);
spa_pod_builder_pop(&b, &f[0]);
- fmt = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format);
+ fmt = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_pod_object);
- spa_pod_builder_init(&b, state->format_buffer, sizeof(state->format_buffer));
- if ((res = spa_format_filter(fmt, filter, &b)) < 0)
+ (*index)++;
+
+ if ((res = spa_pod_object_filter(fmt, filter, builder)) < 0)
return res;
- *format = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_format);
if (!opened)
spa_alsa_close(state);
@@ -251,7 +256,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
CHECK(snd_pcm_hw_params_set_channels_near(hndl, params, &rchannels), "set_channels");
if (rchannels != info->channels) {
spa_log_info(state->log, "Channels doesn't match (requested %u, get %u", info->channels, rchannels);
- if (flags & SPA_PORT_FORMAT_FLAG_NEAREST)
+ if (flags & SPA_NODE_PARAM_FLAG_NEAREST)
info->channels = rchannels;
else
return -EINVAL;
@@ -262,7 +267,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
CHECK(snd_pcm_hw_params_set_rate_near(hndl, params, &rrate, 0), "set_rate_near");
if (rrate != info->rate) {
spa_log_info(state->log, "Rate doesn't match (requested %iHz, get %iHz)", info->rate, rrate);
- if (flags & SPA_PORT_FORMAT_FLAG_NEAREST)
+ if (flags & SPA_NODE_PARAM_FLAG_NEAREST)
info->rate = rrate;
else
return -EINVAL;
diff --git a/spa/plugins/alsa/alsa-utils.h b/spa/plugins/alsa/alsa-utils.h
index b1270951..6d39e664 100644
--- a/spa/plugins/alsa/alsa-utils.h
+++ b/spa/plugins/alsa/alsa-utils.h
@@ -37,7 +37,6 @@ extern "C" {
#include <spa/loop.h>
#include <spa/ringbuffer.h>
#include <spa/audio/format-utils.h>
-#include <spa/format-builder.h>
struct props {
char device[64];
@@ -67,6 +66,7 @@ struct type {
uint32_t prop_card_name;
uint32_t prop_min_latency;
uint32_t prop_max_latency;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -92,6 +92,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->prop_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency);
type->prop_max_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__maxLatency);
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -124,7 +125,6 @@ struct state {
const struct spa_node_callbacks *callbacks;
void *callbacks_data;
- uint8_t props_buffer[1024];
struct props props;
bool opened;
@@ -169,7 +169,9 @@ struct state {
int
spa_alsa_enum_format(struct state *state,
- struct spa_format **format, const struct spa_format *filter, uint32_t index);
+ uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder);
int spa_alsa_set_format(struct state *state, struct spa_audio_info *info, uint32_t flags);
diff --git a/spa/plugins/audiomixer/audiomixer.c b/spa/plugins/audiomixer/audiomixer.c
index 79ba5b40..50dc76ed 100644
--- a/spa/plugins/audiomixer/audiomixer.c
+++ b/spa/plugins/audiomixer/audiomixer.c
@@ -25,7 +25,6 @@
#include <spa/type-map.h>
#include <spa/node.h>
#include <spa/audio/format-utils.h>
-#include <spa/format-builder.h>
#include <lib/format.h>
#include <lib/props.h>
#include <spa/param-alloc.h>
@@ -69,6 +68,7 @@ struct port {
struct type {
uint32_t node;
uint32_t format;
+ struct spa_type_param param;
struct spa_type_media_type media_type;
struct spa_type_media_subtype media_subtype;
struct spa_type_format_audio format_audio;
@@ -84,6 +84,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
{
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
+ spa_type_param_map(map, &type->param);
spa_type_media_type_map(map, &type->media_type);
spa_type_media_subtype_map(map, &type->media_subtype);
spa_type_format_audio_map(map, &type->format_audio);
@@ -133,12 +134,16 @@ struct impl {
#define GET_OUT_PORT(this,p) (&this->out_ports[p])
#define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
-static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
+static int impl_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int impl_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@@ -294,41 +299,50 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
return SPA_RESULT_OK;
}
-
static int
-impl_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+impl_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;
- int res;
- struct spa_format *fmt;
- uint8_t buffer[256];
- struct spa_pod_builder b = { NULL, };
- uint32_t count, match;
- struct type *t;
+ struct port *port;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
- t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- count = match = filter ? 0 : index;
+ port = GET_PORT(this, direction, 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 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 (count++) {
+ switch (*index) {
case 0:
- fmt = spa_pod_builder_format(&b,
- t->format,
- t->media_type.audio, t->media_subtype.raw,
+ fmt = spa_pod_builder_object(&b,
+ t->param.idEnumFormat, t->format,
+ "I", t->media_type.audio,
+ "I", t->media_subtype.raw,
":", t->format_audio.format, "Ieu", t->audio_format.S16,
2, t->audio_format.S16,
t->audio_format.F32,
@@ -341,44 +355,133 @@ impl_node_port_enum_formats(struct spa_node *node,
return SPA_RESULT_ENUM_END;
}
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
+ (*index)++;
- if ((res = spa_format_filter(fmt, filter, &b)) != SPA_RESULT_OK || match++ != index)
+ if ((res = spa_pod_object_filter(fmt, filter, builder)) != SPA_RESULT_OK)
goto next;
- *format = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_format);
-
return SPA_RESULT_OK;
}
-static int clear_buffers(struct impl *this, struct port *port)
+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)
{
- if (port->n_buffers > 0) {
- spa_log_info(this->log, NAME " %p: clear buffers %p", this, port);
- port->n_buffers = 0;
- spa_list_init(&port->queue);
- }
+ struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
+ struct port *port;
+ struct type *t = &this->type;
+
+ port = GET_PORT(this, direction, port_id);
+
+ if (!port->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->format.info.raw.format,
+ ":", t->format_audio.rate, "i", this->format.info.raw.rate,
+ ":", t->format_audio.channels, "i", this->format.info.raw.channels);
+
return SPA_RESULT_OK;
}
static int
-impl_node_port_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format)
+impl_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
- struct port *port;
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ spa_pod_builder_object(builder,
+ id, t->param_alloc_buffers.Buffers,
+ ":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
+ 2, 16 * this->bpf,
+ INT32_MAX / this->bpf,
+ ":", t->param_alloc_buffers.stride, "i", 0,
+ ":", t->param_alloc_buffers.buffers, "iru", 2,
+ 2, 2, MAX_BUFFERS,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ switch (*index) {
+ case 0:
+ 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,
+ 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),
+ ":", t->param_alloc_meta_enable.ringbufferSize, "iru", 1024 * this->bpf,
+ 2, 16 * this->bpf, INT32_MAX / this->bpf,
+ ":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
+ ":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
+ ":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
+ break;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
+ (*index)++;
+
+ return SPA_RESULT_OK;
+}
+
+static int clear_buffers(struct impl *this, struct port *port)
+{
+ if (port->n_buffers > 0) {
+ spa_log_info(this->log, NAME " %p: clear buffers %p", this, port);
+ port->n_buffers = 0;
+ spa_list_init(&port->queue);
+ }
+ 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 = SPA_CONTAINER_OF(node, struct impl, node);
+ struct port *port;
+ struct type *t = &this->type;
+
port = GET_PORT(this, direction, port_id);
if (format == NULL) {
@@ -389,9 +492,11 @@ impl_node_port_set_format(struct spa_node *node,
clear_buffers(this, port);
}
} else {
- struct spa_audio_info info = { SPA_FORMAT_MEDIA_TYPE(format),
- SPA_FORMAT_MEDIA_SUBTYPE(format),
- };
+ struct spa_audio_info info = { 0 };
+
+ spa_pod_object_parse(format,
+ "I", &info.media_type,
+ "I", &info.media_subtype);
if (info.media_type != t->media_type.audio ||
info.media_subtype != t->media_subtype.raw)
@@ -430,129 +535,28 @@ impl_node_port_set_format(struct spa_node *node,
return SPA_RESULT_OK;
}
-static int
-impl_node_port_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_format **format)
-{
- struct impl *this;
- struct port *port;
- struct spa_pod_builder b = { NULL, };
- struct type *t;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
- t = &this->type;
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- port = GET_PORT(this, direction, port_id);
-
- if (!port->have_format)
- return SPA_RESULT_NO_FORMAT;
-
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
- *format = spa_pod_builder_format(&b,
- t->format,
- t->media_type.audio, t->media_subtype.raw,
- ":", t->format_audio.format, "I", this->format.info.raw.format,
- ":", t->format_audio.rate, "i", this->format.info.raw.rate,
- ":", t->format_audio.channels, "i", this->format.info.raw.channels);
-
- return SPA_RESULT_OK;
-}
static int
-impl_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;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- port = GET_PORT(this, direction, port_id);
- *info = &port->info;
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t index,
- struct spa_param **param)
+impl_node_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
-
- switch (index) {
- case 0:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
- 2, 16 * this->bpf,
- INT32_MAX / this->bpf,
- ":", t->param_alloc_buffers.stride, "i", 0,
- ":", t->param_alloc_buffers.buffers, "iru", 2,
- 2, 2, MAX_BUFFERS,
- ":", t->param_alloc_buffers.align, "i", 16);
- break;
-
- case 1:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- break;
-
- case 2:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_ringbuffer),
- ":", t->param_alloc_meta_enable.ringbufferSize, "iru", 1024 * this->bpf,
- 2, 16 * this->bpf, INT32_MAX / this->bpf,
- ":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
- ":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
- ":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
- break;
-
- default:
- return SPA_RESULT_ENUM_END;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
}
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_set_param(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
@@ -620,7 +624,7 @@ static int
impl_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -933,17 +937,14 @@ static int impl_node_process_output(struct spa_node *node)
static const struct spa_node impl_node = {
SPA_VERSION_NODE,
NULL,
- impl_node_get_props,
- impl_node_set_props,
+ impl_node_enum_params,
+ impl_node_set_param,
impl_node_send_command,
impl_node_set_callbacks,
impl_node_get_n_ports,
impl_node_get_port_ids,
impl_node_add_port,
impl_node_remove_port,
- impl_node_port_enum_formats,
- impl_node_port_set_format,
- impl_node_port_get_format,
impl_node_port_get_info,
impl_node_port_enum_params,
impl_node_port_set_param,
diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c
index d0102e05..7bf61cf4 100644
--- a/spa/plugins/audiotestsrc/audiotestsrc.c
+++ b/spa/plugins/audiotestsrc/audiotestsrc.c
@@ -31,7 +31,6 @@
#include <spa/param-alloc.h>
#include <spa/list.h>
#include <spa/audio/format-utils.h>
-#include <spa/format-builder.h>
#include <lib/format.h>
#include <lib/props.h>
@@ -53,6 +52,7 @@ struct type {
uint32_t prop_volume;
uint32_t wave_sine;
uint32_t wave_square;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -77,6 +77,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
type->wave_sine = spa_type_map_get_id(map, SPA_TYPE_PROPS__waveType ":sine");
type->wave_square = spa_type_map_get_id(map, SPA_TYPE_PROPS__waveType ":square");
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -132,7 +133,6 @@ struct impl {
struct itimerspec timerspec;
struct spa_port_info info;
- uint8_t params_buffer[1024];
struct spa_port_io *io;
bool have_format;
@@ -169,33 +169,41 @@ static void reset_props(struct impl *this, struct props *props)
props->volume = DEFAULT_VOLUME;
}
-static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
+static int impl_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
- spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer));
- *props = spa_pod_builder_props(&b, t->props,
- ":", t->prop_live, "b", this->props.live,
- ":", t->prop_wave, "Ie", this->props.wave,
- 2, t->wave_sine,
- t->wave_square,
- ":", t->prop_freq, "dr", this->props.freq,
- 2, 0.0, 50000000.0,
- ":", t->prop_volume, "dr", this->props.volume,
- 2, 0.0, 10.0);
+ if (id == t->param.idProps) {
+ spa_pod_builder_object(builder,
+ id, t->props,
+ ":", t->prop_live, "b", this->props.live,
+ ":", t->prop_wave, "Ie", this->props.wave,
+ 2, t->wave_sine,
+ t->wave_square,
+ ":", t->prop_freq, "dr", this->props.freq,
+ 2, 0.0, 50000000.0,
+ ":", t->prop_volume, "dr", this->props.volume,
+ 2, 0.0, 10.0);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
-static int impl_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
struct type *t;
@@ -205,21 +213,25 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
- if (props == NULL) {
- reset_props(this, &this->props);
- } else {
- spa_props_parse(props,
+ if (id == t->param.idProps) {
+ if (param == NULL) {
+ reset_props(this, &this->props);
+ return SPA_RESULT_OK;
+ }
+ spa_pod_object_parse(param,
":",t->prop_live, "?b", &this->props.live,
":",t->prop_wave, "?I", &this->props.wave,
":",t->prop_freq, "?d", &this->props.freq,
":",t->prop_volume, "?d", &this->props.volume,
NULL);
- }
- if (this->props.live)
- this->info.flags |= SPA_PORT_INFO_FLAG_LIVE;
+ if (this->props.live)
+ this->info.flags |= SPA_PORT_INFO_FLAG_LIVE;
+ else
+ this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
+ }
else
- this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
@@ -458,39 +470,47 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
}
static int
-impl_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+impl_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;
- int res;
- struct spa_format *fmt;
- uint8_t buffer[256];
- struct spa_pod_builder b = { NULL, };
- uint32_t count, match;
- struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
- t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- count = match = filter ? 0 : index;
+ *info = &this->info;
+
+ return SPA_RESULT_OK;
+}
+
+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_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 (count++) {
+ switch (*index) {
case 0:
- fmt = spa_pod_builder_format(&b, t->format,
- t->media_type.audio,
- t->media_subtype.raw,
+ fmt = spa_pod_builder_object(&b,
+ t->param.idEnumFormat, t->format,
+ "I", t->media_type.audio,
+ "I", t->media_subtype.raw,
":", t->format_audio.format, "Ieu", t->audio_format.S16,
4, t->audio_format.S16,
t->audio_format.S32,
@@ -505,55 +525,144 @@ impl_node_port_enum_formats(struct spa_node *node,
return SPA_RESULT_ENUM_END;
}
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
+ (*index)++;
- if ((res = spa_format_filter(fmt, filter, &b)) != SPA_RESULT_OK || match++ != index)
+ if ((res = spa_pod_object_filter(fmt, filter, builder)) != SPA_RESULT_OK)
goto next;
- *format = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_format);
-
return SPA_RESULT_OK;
}
-static int clear_buffers(struct impl *this)
+static int
+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_builder *builder)
{
- if (this->n_buffers > 0) {
- spa_log_info(this->log, NAME " %p: clear buffers", this);
- this->n_buffers = 0;
- spa_list_init(&this->empty);
- this->started = false;
- set_timer(this, false);
- }
+ 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_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format)
+impl_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(this, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(this, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ spa_pod_builder_object(builder,
+ id, t->param_alloc_buffers.Buffers,
+ ":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
+ 2, 16 * this->bpf,
+ INT32_MAX / this->bpf,
+ ":", t->param_alloc_buffers.stride, "i", 0,
+ ":", t->param_alloc_buffers.buffers, "iru", 2,
+ 2, 1, 32,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ switch (*index) {
+ case 0:
+ 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,
+ 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),
+ ":", t->param_alloc_meta_enable.ringbufferSize, "ir", 5512 * this->bpf,
+ 2, 16 * this->bpf, INT32_MAX / this->bpf,
+ ":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
+ ":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
+ ":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
+ break;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
+ (*index)++;
+
+ return SPA_RESULT_OK;
+}
+
+static int clear_buffers(struct impl *this)
+{
+ if (this->n_buffers > 0) {
+ spa_log_info(this->log, NAME " %p: clear buffers", this);
+ this->n_buffers = 0;
+ spa_list_init(&this->empty);
+ this->started = false;
+ set_timer(this, false);
+ }
+ return SPA_RESULT_OK;
+}
+
+static int
+port_set_format(struct impl *this,
+ enum spa_direction direction,
+ uint32_t port_id,
+ uint32_t flags,
+ const struct spa_pod_object *format)
+{
+ struct type *t = &this->type;
+
if (format == NULL) {
this->have_format = false;
clear_buffers(this);
} else {
- struct spa_audio_info info = { SPA_FORMAT_MEDIA_TYPE(format),
- SPA_FORMAT_MEDIA_SUBTYPE(format),
- };
+ struct spa_audio_info info = { 0 };
int idx;
int sizes[4] = { 2, 4, 4, 8 };
+ spa_pod_object_parse(format,
+ "I", &info.media_type,
+ "I", &info.media_subtype);
+
if (info.media_type != t->media_type.audio ||
info.media_subtype != t->media_subtype.raw)
return SPA_RESULT_INVALID_MEDIA_TYPE;
@@ -581,128 +690,29 @@ impl_node_port_set_format(struct spa_node *node,
if (this->have_format) {
this->info.rate = this->current_format.info.raw.rate;
}
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_format **format)
-{
- struct impl *this;
- struct spa_pod_builder b = { NULL, };
- struct type *t;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
- t = &this->type;
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- if (!this->have_format)
- return SPA_RESULT_NO_FORMAT;
-
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
- *format = spa_pod_builder_format(&b, t->format,
- t->media_type.audio, t->media_subtype.raw,
- ":", t->format_audio.format, "I", this->current_format.info.raw.format,
- ":", t->format_audio.rate, "i", this->current_format.info.raw.rate,
- ":", t->format_audio.channels, "i", this->current_format.info.raw.channels);
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_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;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- *info = &this->info;
-
return SPA_RESULT_OK;
}
static int
-impl_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t index,
- struct spa_param **param)
+impl_node_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- spa_pod_builder_init(&b, this->params_buffer, sizeof(this->params_buffer));
-
- switch (index) {
- case 0:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
- 2, 16 * this->bpf,
- INT32_MAX / this->bpf,
- ":", t->param_alloc_buffers.stride, "i", 0,
- ":", t->param_alloc_buffers.buffers, "iru", 2,
- 2, 1, 32,
- ":", t->param_alloc_buffers.align, "i", 16);
- break;
-
- case 1:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- break;
-
- case 2:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_ringbuffer),
- ":", t->param_alloc_meta_enable.ringbufferSize, "ir", 5512 * this->bpf,
- 2, 16 * this->bpf, INT32_MAX / this->bpf,
- ":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
- ":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
- ":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
- break;
-
- default:
- return SPA_RESULT_ENUM_END;
- }
-
- return SPA_RESULT_OK;
-}
+ if (id == t->param.idFormat)
+ return port_set_format(this, direction, port_id, flags, param);
-static int
-impl_node_port_set_param(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
@@ -754,7 +764,7 @@ static int
impl_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -874,17 +884,14 @@ static const struct spa_dict node_info = {
static const struct spa_node impl_node = {
SPA_VERSION_NODE,
&node_info,
- impl_node_get_props,
- impl_node_set_props,
+ impl_node_enum_params,
+ impl_node_set_param,
impl_node_send_command,
impl_node_set_callbacks,
impl_node_get_n_ports,
impl_node_get_port_ids,
impl_node_add_port,
impl_node_remove_port,
- impl_node_port_enum_formats,
- impl_node_port_set_format,
- impl_node_port_get_format,
impl_node_port_get_info,
impl_node_port_enum_params,
impl_node_port_set_param,
@@ -897,12 +904,14 @@ static const struct spa_node impl_node = {
impl_node_process_output,
};
-static int impl_clock_get_props(struct spa_clock *clock, struct spa_props **props)
+static int impl_clock_enum_params(struct spa_clock *clock, uint32_t id, uint32_t *index,
+ struct spa_pod_builder *builder)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int impl_clock_set_props(struct spa_clock *clock, const struct spa_props *props)
+static int impl_clock_set_param(struct spa_clock *clock, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@@ -936,8 +945,8 @@ static const struct spa_clock impl_clock = {
SPA_VERSION_CLOCK,
NULL,
SPA_CLOCK_STATE_STOPPED,
- impl_clock_get_props,
- impl_clock_set_props,
+ impl_clock_enum_params,
+ impl_clock_set_param,
impl_clock_get_time,
};
diff --git a/spa/plugins/ffmpeg/ffmpeg-dec.c b/spa/plugins/ffmpeg/ffmpeg-dec.c
index 8376f992..e214a2e5 100644
--- a/spa/plugins/ffmpeg/ffmpeg-dec.c
+++ b/spa/plugins/ffmpeg/ffmpeg-dec.c
@@ -48,6 +48,7 @@ struct port {
struct type {
uint32_t node;
+ struct spa_type_param param;
struct spa_type_media_type media_type;
struct spa_type_media_subtype media_subtype;
struct spa_type_format_video format_video;
@@ -57,6 +58,7 @@ struct type {
static inline void init_type(struct type *type, struct spa_type_map *map)
{
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
+ spa_type_param_map(map, &type->param);
spa_type_media_type_map(map, &type->media_type);
spa_type_media_subtype_map(map, &type->media_subtype);
spa_type_format_video_map(map, &type->format_video);
@@ -80,12 +82,17 @@ struct impl {
bool started;
};
-static int spa_ffmpeg_dec_node_get_props(struct spa_node *node, struct spa_props **props)
+static int spa_ffmpeg_dec_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int spa_ffmpeg_dec_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int spa_ffmpeg_dec_node_set_param(struct spa_node *node,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@@ -182,17 +189,15 @@ spa_ffmpeg_dec_node_remove_port(struct spa_node *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int
-spa_ffmpeg_dec_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+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 impl *this;
- if (node == NULL || format == NULL)
+ if (node == NULL || index == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
//this = SPA_CONTAINER_OF (node, struct impl, node);
@@ -200,23 +205,20 @@ spa_ffmpeg_dec_node_port_enum_formats(struct spa_node *node,
if (!IS_VALID_PORT(this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
- switch (index) {
+ switch (*index) {
case 0:
break;
default:
return SPA_RESULT_ENUM_END;
}
- *format = NULL;
return SPA_RESULT_OK;
}
-static int
-spa_ffmpeg_dec_node_port_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format)
+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;
@@ -236,9 +238,11 @@ spa_ffmpeg_dec_node_port_set_format(struct spa_node *node,
port->have_format = false;
return SPA_RESULT_OK;
} else {
- struct spa_video_info info = { SPA_FORMAT_MEDIA_TYPE(format),
- SPA_FORMAT_MEDIA_SUBTYPE(format),
- };
+ 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)
@@ -247,7 +251,7 @@ spa_ffmpeg_dec_node_port_set_format(struct spa_node *node,
if (spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video) < 0)
return SPA_RESULT_INVALID_MEDIA_TYPE;
- if (!(flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY)) {
+ if (!(flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)) {
port->current_format = info;
port->have_format = true;
}
@@ -255,30 +259,23 @@ spa_ffmpeg_dec_node_port_set_format(struct spa_node *node,
return SPA_RESULT_OK;
}
-static int
-spa_ffmpeg_dec_node_port_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_format **format)
+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 impl *this;
+ struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
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 (!port->have_format)
return SPA_RESULT_NO_FORMAT;
- *format = NULL;
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
return SPA_RESULT_OK;
}
@@ -309,21 +306,38 @@ spa_ffmpeg_dec_node_port_get_info(struct spa_node *node,
static int
spa_ffmpeg_dec_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t index,
- struct spa_param **param)
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
+ struct type *t = &this->type;
+
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
spa_ffmpeg_dec_node_port_set_param(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
+ struct type *t = &this->type;
+
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
@@ -346,7 +360,7 @@ static int
spa_ffmpeg_dec_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -433,17 +447,14 @@ spa_ffmpeg_dec_node_port_send_command(struct spa_node *node,
static const struct spa_node ffmpeg_dec_node = {
SPA_VERSION_NODE,
NULL,
- spa_ffmpeg_dec_node_get_props,
- spa_ffmpeg_dec_node_set_props,
+ spa_ffmpeg_dec_node_enum_params,
+ spa_ffmpeg_dec_node_set_param,
spa_ffmpeg_dec_node_send_command,
spa_ffmpeg_dec_node_set_callbacks,
spa_ffmpeg_dec_node_get_n_ports,
spa_ffmpeg_dec_node_get_port_ids,
spa_ffmpeg_dec_node_add_port,
spa_ffmpeg_dec_node_remove_port,
- spa_ffmpeg_dec_node_port_enum_formats,
- spa_ffmpeg_dec_node_port_set_format,
- spa_ffmpeg_dec_node_port_get_format,
spa_ffmpeg_dec_node_port_get_info,
spa_ffmpeg_dec_node_port_enum_params,
spa_ffmpeg_dec_node_port_set_param,
diff --git a/spa/plugins/ffmpeg/ffmpeg-enc.c b/spa/plugins/ffmpeg/ffmpeg-enc.c
index 4e173563..dbc9d2de 100644
--- a/spa/plugins/ffmpeg/ffmpeg-enc.c
+++ b/spa/plugins/ffmpeg/ffmpeg-enc.c
@@ -52,6 +52,7 @@ struct port {
struct type {
uint32_t node;
+ struct spa_type_param param;
struct spa_type_media_type media_type;
struct spa_type_media_subtype media_subtype;
struct spa_type_format_video format_video;
@@ -61,6 +62,7 @@ struct type {
static inline void init_type(struct type *type, struct spa_type_map *map)
{
type->node = spa_type_map_get_id(map, SPA_TYPE__Node);
+ spa_type_param_map(map, &type->param);
spa_type_media_type_map(map, &type->media_type);
spa_type_media_subtype_map(map, &type->media_subtype);
spa_type_format_video_map(map, &type->format_video);
@@ -84,12 +86,16 @@ struct impl {
bool started;
};
-static int spa_ffmpeg_enc_node_get_props(struct spa_node *node, struct spa_props **props)
+static int spa_ffmpeg_enc_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int spa_ffmpeg_enc_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int spa_ffmpeg_enc_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@@ -186,52 +192,95 @@ spa_ffmpeg_enc_node_remove_port(struct spa_node *node,
}
static int
-spa_ffmpeg_enc_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter, uint32_t index)
+spa_ffmpeg_enc_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;
+ struct impl *this;
+ struct port *port;
- if (node == NULL || format == NULL)
+ if (node == NULL || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
- //this = SPA_CONTAINER_OF (node, struct impl, node);
+ 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 impl *this = SPA_CONTAINER_OF (node, struct impl, node);
+ //struct port *port;
+
//port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
- switch (index) {
+ switch (*index) {
case 0:
break;
default:
return SPA_RESULT_ENUM_END;
}
- *format = NULL;
-
return SPA_RESULT_OK;
}
-static int
-spa_ffmpeg_enc_node_port_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags, const struct spa_format *format)
+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 impl *this;
+ struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct port *port;
- if (node == NULL || format == NULL)
- return SPA_RESULT_INVALID_ARGUMENTS;
+ port =
+ direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
- this = SPA_CONTAINER_OF(node, struct impl, node);
+ if (!port->have_format)
+ return SPA_RESULT_NO_FORMAT;
- if (!IS_VALID_PORT(this, direction, port_id))
- return SPA_RESULT_INVALID_PORT;
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ return SPA_RESULT_OK;
+}
+
+static int
+spa_ffmpeg_enc_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
+{
+ struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
+ struct type *t = &this->type;
+
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+}
+
+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 = SPA_CONTAINER_OF(node, struct impl, node);
+ struct port *port;
port =
direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
@@ -240,9 +289,11 @@ spa_ffmpeg_enc_node_port_set_format(struct spa_node *node,
port->have_format = false;
return SPA_RESULT_OK;
} else {
- struct spa_video_info info = { SPA_FORMAT_MEDIA_TYPE(format),
- SPA_FORMAT_MEDIA_SUBTYPE(format),
- };
+ 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)
@@ -251,7 +302,7 @@ spa_ffmpeg_enc_node_port_set_format(struct spa_node *node,
if (spa_format_video_raw_parse(format, &info.info.raw, &this->type.format_video) < 0)
return SPA_RESULT_INVALID_MEDIA_TYPE;
- if (!(flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY)) {
+ if (!(flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)) {
port->current_format = info;
port->have_format = true;
}
@@ -260,69 +311,19 @@ spa_ffmpeg_enc_node_port_set_format(struct spa_node *node,
}
static int
-spa_ffmpeg_enc_node_port_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id, const struct spa_format **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 (!port->have_format)
- return SPA_RESULT_NO_FORMAT;
-
- *format = NULL;
-
- return SPA_RESULT_OK;
-}
-
-static int
-spa_ffmpeg_enc_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
-spa_ffmpeg_enc_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id, uint32_t index, struct spa_param **param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
-}
-
-static int
spa_ffmpeg_enc_node_port_set_param(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id, const struct spa_param *param)
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
+ struct type *t = &this->type;
+
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
@@ -344,7 +345,7 @@ static int
spa_ffmpeg_enc_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -428,17 +429,14 @@ static int spa_ffmpeg_enc_node_process_output(struct spa_node *node)
static const struct spa_node ffmpeg_enc_node = {
SPA_VERSION_NODE,
NULL,
- spa_ffmpeg_enc_node_get_props,
- spa_ffmpeg_enc_node_set_props,
+ spa_ffmpeg_enc_node_enum_params,
+ spa_ffmpeg_enc_node_set_param,
spa_ffmpeg_enc_node_send_command,
spa_ffmpeg_enc_node_set_callbacks,
spa_ffmpeg_enc_node_get_n_ports,
spa_ffmpeg_enc_node_get_port_ids,
spa_ffmpeg_enc_node_add_port,
spa_ffmpeg_enc_node_remove_port,
- spa_ffmpeg_enc_node_port_enum_formats,
- spa_ffmpeg_enc_node_port_set_format,
- spa_ffmpeg_enc_node_port_get_format,
spa_ffmpeg_enc_node_port_get_info,
spa_ffmpeg_enc_node_port_enum_params,
spa_ffmpeg_enc_node_port_set_param,
diff --git a/spa/plugins/support/logger.c b/spa/plugins/support/logger.c
index 50e8d9c6..f181f9a5 100644
--- a/spa/plugins/support/logger.c
+++ b/spa/plugins/support/logger.c
@@ -31,7 +31,6 @@
#include <spa/node.h>
#include <spa/param-alloc.h>
#include <spa/list.h>
-#include <spa/format-builder.h>
#include <lib/props.h>
#define NAME "logger"
diff --git a/spa/plugins/support/mapper.c b/spa/plugins/support/mapper.c
index af7952ee..9c4ff2a0 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 <spa/format-builder.h>
#include <lib/props.h>
#define NAME "mapper"
diff --git a/spa/plugins/test/fakesink.c b/spa/plugins/test/fakesink.c
index e8641e23..8ac36845 100644
--- a/spa/plugins/test/fakesink.c
+++ b/spa/plugins/test/fakesink.c
@@ -30,7 +30,6 @@
#include <spa/node.h>
#include <spa/param-alloc.h>
#include <spa/list.h>
-#include <spa/format-builder.h>
#include <lib/props.h>
#define NAME "fakesink"
@@ -41,6 +40,7 @@ struct type {
uint32_t format;
uint32_t props;
uint32_t prop_live;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_event_node event_node;
@@ -56,6 +56,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
type->prop_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_event_node_map(map, &type->event_node);
@@ -88,7 +89,6 @@ struct impl {
struct spa_log *log;
struct spa_loop *data_loop;
- uint8_t props_buffer[512];
struct props props;
const struct spa_node_callbacks *callbacks;
@@ -98,7 +98,6 @@ struct impl {
struct itimerspec timerspec;
struct spa_port_info info;
- uint8_t params_buffer[1024];
struct spa_port_io *io;
bool have_format;
@@ -125,43 +124,57 @@ static void reset_props(struct impl *this, struct props *props)
props->live = DEFAULT_LIVE;
}
-static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
+static int impl_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
- struct spa_pod_builder b = { NULL, };
+ struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
+ t = &this->type;
- spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer));
- *props = spa_pod_builder_props(&b,
- this->type.props,
- ":", this->type.prop_live, "b", this->props.live);
+ if (id == t->param.idProps) {
+ spa_pod_builder_object(builder,
+ id, t->props,
+ ":", t->prop_live, "b", this->props.live);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
-static int impl_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
+ struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
+ t = &this->type;
- if (props == NULL) {
- reset_props(this, &this->props);
- } else {
- spa_props_parse(props,
- ":", this->type.prop_live, "?b", &this->props.live, NULL);
- }
+ if (id == t->param.idProps) {
+ if (param == NULL) {
+ reset_props(this, &this->props);
+ return SPA_RESULT_OK;
+ }
+ spa_pod_object_parse(param,
+ ":", t->prop_live, "?b", &this->props.live, NULL);
- if (this->props.live)
- this->info.flags |= SPA_PORT_INFO_FLAG_LIVE;
+ if (this->props.live)
+ this->info.flags |= SPA_PORT_INFO_FLAG_LIVE;
+ else
+ this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
+ }
else
- this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
@@ -373,159 +386,162 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
}
static int
-impl_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter, uint32_t index)
+impl_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;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- return SPA_RESULT_ENUM_END;
+ *info = &this->info;
+
+ return SPA_RESULT_OK;
}
-static int clear_buffers(struct impl *this)
+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)
{
- if (this->n_buffers > 0) {
- spa_log_info(this->log, NAME " %p: clear buffers", this);
- this->n_buffers = 0;
- spa_list_init(&this->ready);
- this->started = false;
- set_timer(this, false);
- }
- return SPA_RESULT_OK;
+ return SPA_RESULT_ENUM_END;
}
-static int
-impl_node_port_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format)
+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 impl *this;
+ struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ if (!this->have_format)
+ return SPA_RESULT_NO_FORMAT;
- this = SPA_CONTAINER_OF(node, struct impl, node);
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ spa_pod_builder_primitive(builder, SPA_MEMBER(this->format_buffer, 0, struct spa_pod));
- if (format == NULL) {
- this->have_format = false;
- clear_buffers(this);
- } else {
- if (SPA_POD_SIZE(format) > sizeof(this->format_buffer))
- return SPA_RESULT_ERROR;
- memcpy(this->format_buffer, format, SPA_POD_SIZE(format));
- this->have_format = true;
- }
return SPA_RESULT_OK;
}
static int
-impl_node_port_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_format **format)
+impl_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
+ struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
+ t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- if (!this->have_format)
- return SPA_RESULT_NO_FORMAT;
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
- *format = (const struct spa_format *) this->format_buffer;
+ 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,
+ ":", t->param_alloc_buffers.buffers, "ir", 2,
+ 2, 1, 32,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ switch (*index) {
+ case 0:
+ 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;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
+ (*index)++;
return SPA_RESULT_OK;
}
-static int
-impl_node_port_get_info(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_port_info **info)
+static int clear_buffers(struct impl *this)
{
- struct impl *this;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ if (this->n_buffers > 0) {
+ spa_log_info(this->log, NAME " %p: clear buffers", this);
+ this->n_buffers = 0;
+ spa_list_init(&this->ready);
+ this->started = false;
+ set_timer(this, false);
+ }
+ return SPA_RESULT_OK;
+}
- *info = &this->info;
+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 = SPA_CONTAINER_OF(node, struct impl, node);
+ if (format == NULL) {
+ this->have_format = false;
+ clear_buffers(this);
+ } else {
+ if (SPA_POD_SIZE(format) > sizeof(this->format_buffer))
+ return SPA_RESULT_ERROR;
+ memcpy(this->format_buffer, format, SPA_POD_SIZE(format));
+ this->have_format = true;
+ }
return SPA_RESULT_OK;
}
static int
-impl_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t index,
- struct spa_param **param)
+impl_node_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
- struct spa_pod_builder b = { NULL };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- spa_pod_builder_init(&b, this->params_buffer, sizeof(this->params_buffer));
-
- switch (index) {
- case 0:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "i", 128,
- ":", t->param_alloc_buffers.stride, "i", 1,
- ":", t->param_alloc_buffers.buffers, "ir", 2,
- 2, 1, 32,
- ":", t->param_alloc_buffers.align, "i", 16);
- break;
-
- case 1:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- break;
-
- default:
- return SPA_RESULT_NOT_IMPLEMENTED;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
}
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_set_param(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
@@ -574,7 +590,7 @@ static int
impl_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -669,17 +685,14 @@ static int impl_node_process_output(struct spa_node *node)
static const struct spa_node impl_node = {
SPA_VERSION_NODE,
NULL,
- impl_node_get_props,
- impl_node_set_props,
+ impl_node_enum_params,
+ impl_node_set_param,
impl_node_send_command,
impl_node_set_callbacks,
impl_node_get_n_ports,
impl_node_get_port_ids,
impl_node_add_port,
impl_node_remove_port,
- impl_node_port_enum_formats,
- impl_node_port_set_format,
- impl_node_port_get_format,
impl_node_port_get_info,
impl_node_port_enum_params,
impl_node_port_set_param,
@@ -692,12 +705,14 @@ static const struct spa_node impl_node = {
impl_node_process_output,
};
-static int impl_clock_get_props(struct spa_clock *clock, struct spa_props **props)
+static int impl_clock_enum_params(struct spa_clock *clock, uint32_t id, uint32_t *index,
+ struct spa_pod_builder *builder)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int impl_clock_set_props(struct spa_clock *clock, const struct spa_props *props)
+static int impl_clock_set_param(struct spa_clock *clock, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@@ -731,8 +746,8 @@ static const struct spa_clock impl_clock = {
SPA_VERSION_CLOCK,
NULL,
SPA_CLOCK_STATE_STOPPED,
- impl_clock_get_props,
- impl_clock_set_props,
+ impl_clock_enum_params,
+ impl_clock_set_param,
impl_clock_get_time,
};
diff --git a/spa/plugins/test/fakesrc.c b/spa/plugins/test/fakesrc.c
index ab0d5bd7..48303902 100644
--- a/spa/plugins/test/fakesrc.c
+++ b/spa/plugins/test/fakesrc.c
@@ -30,7 +30,6 @@
#include <spa/node.h>
#include <spa/param-alloc.h>
#include <spa/list.h>
-#include <spa/format-builder.h>
#include <lib/props.h>
#define NAME "fakesrc"
@@ -42,6 +41,7 @@ struct type {
uint32_t props;
uint32_t prop_live;
uint32_t prop_pattern;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_event_node event_node;
@@ -58,6 +58,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
type->prop_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
type->prop_pattern = spa_type_map_get_id(map, SPA_TYPE_PROPS__patternType);
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_event_node_map(map, &type->event_node);
@@ -91,7 +92,6 @@ struct impl {
struct spa_log *log;
struct spa_loop *data_loop;
- uint8_t props_buffer[512];
struct props props;
const struct spa_node_callbacks *callbacks;
@@ -101,7 +101,6 @@ struct impl {
struct itimerspec timerspec;
struct spa_port_info info;
- uint8_t params_buffer[1024];
struct spa_port_io *io;
bool have_format;
@@ -131,29 +130,36 @@ static void reset_props(struct impl *this, struct props *props)
props->pattern = DEFAULT_PATTERN;
}
-static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
+static int impl_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
- spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer));
- *props = spa_pod_builder_props(&b,
- t->props,
- ":", t->prop_live, "b", this->props.live,
- ":", t->prop_pattern, "Ie", this->props.pattern,
- 1, this->props.pattern);
+ if (id == t->param.idProps) {
+ spa_pod_builder_object(builder,
+ id, t->props,
+ ":", t->prop_live, "b", this->props.live,
+ ":", t->prop_pattern, "Ie", this->props.pattern,
+ 1, this->props.pattern);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
-static int impl_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
struct type *t;
@@ -163,18 +169,22 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
- if (props == NULL) {
- reset_props(this, &this->props);
- } else {
- spa_props_parse(props,
- ":", t->prop_live, "?b", &this->props.live,
- ":", t->prop_pattern, "?I", &this->props.pattern, NULL);
- }
+ if (id == t->param.idProps) {
+ if (param == NULL) {
+ reset_props(this, &this->props);
+ return SPA_RESULT_OK;
+ }
+ spa_pod_object_parse(param,
+ ":", t->prop_live, "?b", &this->props.live,
+ ":", t->prop_pattern, "?I", &this->props.pattern, NULL);
- if (this->props.live)
- this->info.flags |= SPA_PORT_INFO_FLAG_LIVE;
+ if (this->props.live)
+ this->info.flags |= SPA_PORT_INFO_FLAG_LIVE;
+ else
+ this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
+ }
else
- this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
@@ -387,164 +397,159 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
}
static int
-impl_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+impl_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;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- return SPA_RESULT_ENUM_END;
-}
+ *info = &this->info;
-static int clear_buffers(struct impl *this)
-{
- if (this->n_buffers > 0) {
- spa_log_info(this->log, NAME " %p: clear buffers", this);
- this->n_buffers = 0;
- spa_list_init(&this->empty);
- this->started = false;
- set_timer(this, false);
- }
return SPA_RESULT_OK;
}
-static int
-impl_node_port_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format)
+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 impl *this;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ return SPA_RESULT_ENUM_END;
+}
- this = SPA_CONTAINER_OF(node, struct impl, node);
+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 impl *this = SPA_CONTAINER_OF(node, struct impl, node);
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ if (!this->have_format)
+ return SPA_RESULT_NO_FORMAT;
- if (format == NULL) {
- this->have_format = false;
- clear_buffers(this);
- } else {
- if (SPA_POD_SIZE(format) > sizeof(this->format_buffer))
- return SPA_RESULT_ERROR;
- memcpy(this->format_buffer, format, SPA_POD_SIZE(format));
- this->have_format = true;
- }
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
- if (this->have_format) {
- }
+ spa_pod_builder_primitive(builder, SPA_MEMBER(this->format_buffer, 0, struct spa_pod));
return SPA_RESULT_OK;
}
static int
-impl_node_port_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_format **format)
+impl_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
+ struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
+ t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- if (!this->have_format)
- return SPA_RESULT_NO_FORMAT;
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ 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,
+ ":", t->param_alloc_buffers.buffers, "ir", 32,
+ 2, 2, 32,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ switch (*index) {
+ case 0:
+ 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;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
- *format = (const struct spa_format *) this->format_buffer;
+ (*index)++;
return SPA_RESULT_OK;
}
-static int
-impl_node_port_get_info(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_port_info **info)
+static int clear_buffers(struct impl *this)
{
- struct impl *this;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ if (this->n_buffers > 0) {
+ spa_log_info(this->log, NAME " %p: clear buffers", this);
+ this->n_buffers = 0;
+ spa_list_init(&this->empty);
+ this->started = false;
+ set_timer(this, false);
+ }
+ return SPA_RESULT_OK;
+}
- *info = &this->info;
+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 = SPA_CONTAINER_OF(node, struct impl, node);
+ if (format == NULL) {
+ this->have_format = false;
+ clear_buffers(this);
+ } else {
+ if (SPA_POD_SIZE(format) > sizeof(this->format_buffer))
+ return SPA_RESULT_ERROR;
+ memcpy(this->format_buffer, format, SPA_POD_SIZE(format));
+ this->have_format = true;
+ }
return SPA_RESULT_OK;
}
static int
-impl_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t index,
- struct spa_param **param)
+impl_node_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
- struct spa_pod_builder b = { NULL };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- spa_pod_builder_init(&b, this->params_buffer, sizeof(this->params_buffer));
-
- switch (index) {
- case 0:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "i", 128,
- ":", t->param_alloc_buffers.stride, "i", 1,
- ":", t->param_alloc_buffers.buffers, "ir", 32,
- 2, 2, 32,
- ":", t->param_alloc_buffers.align, "i", 16);
- break;
-
- case 1:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- break;
-
- default:
- return SPA_RESULT_NOT_IMPLEMENTED;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
}
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_set_param(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
@@ -595,7 +600,7 @@ static int
impl_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -709,17 +714,14 @@ static int impl_node_process_output(struct spa_node *node)
static const struct spa_node impl_node = {
SPA_VERSION_NODE,
NULL,
- impl_node_get_props,
- impl_node_set_props,
+ impl_node_enum_params,
+ impl_node_set_param,
impl_node_send_command,
impl_node_set_callbacks,
impl_node_get_n_ports,
impl_node_get_port_ids,
impl_node_add_port,
impl_node_remove_port,
- impl_node_port_enum_formats,
- impl_node_port_set_format,
- impl_node_port_get_format,
impl_node_port_get_info,
impl_node_port_enum_params,
impl_node_port_set_param,
@@ -732,12 +734,14 @@ static const struct spa_node impl_node = {
impl_node_process_output,
};
-static int impl_clock_get_props(struct spa_clock *clock, struct spa_props **props)
+static int impl_clock_enum_params(struct spa_clock *clock, uint32_t id, uint32_t *index,
+ struct spa_pod_builder *builder)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int impl_clock_set_props(struct spa_clock *clock, const struct spa_props *props)
+static int impl_clock_set_param(struct spa_clock *clock, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@@ -771,8 +775,8 @@ static const struct spa_clock impl_clock = {
SPA_VERSION_CLOCK,
NULL,
SPA_CLOCK_STATE_STOPPED,
- impl_clock_get_props,
- impl_clock_set_props,
+ impl_clock_enum_params,
+ impl_clock_set_param,
impl_clock_get_time,
};
diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c
index 422a445e..97ad9d1e 100644
--- a/spa/plugins/v4l2/v4l2-source.c
+++ b/spa/plugins/v4l2/v4l2-source.c
@@ -32,7 +32,6 @@
#include <spa/loop.h>
#include <spa/param-alloc.h>
#include <spa/type-map.h>
-#include <spa/format-builder.h>
#include <lib/debug.h>
#include <lib/props.h>
@@ -69,6 +68,7 @@ struct type {
uint32_t prop_device;
uint32_t prop_device_name;
uint32_t prop_device_fd;
+ struct spa_type_param param;
struct spa_type_media_type media_type;
struct spa_type_media_subtype media_subtype;
struct spa_type_media_subtype_video media_subtype_video;
@@ -91,6 +91,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->prop_device = spa_type_map_get_id(map, SPA_TYPE_PROPS__device);
type->prop_device_name = spa_type_map_get_id(map, SPA_TYPE_PROPS__deviceName);
type->prop_device_fd = spa_type_map_get_id(map, SPA_TYPE_PROPS__deviceFd);
+ spa_type_param_map(map, &type->param);
spa_type_media_type_map(map, &type->media_type);
spa_type_media_subtype_map(map, &type->media_subtype);
spa_type_media_subtype_video_map(map, &type->media_subtype_video);
@@ -136,7 +137,6 @@ struct port {
struct spa_source source;
struct spa_port_info info;
- uint8_t params_buffer[1024];
struct spa_port_io *io;
int64_t last_ticks;
@@ -168,28 +168,51 @@ struct impl {
#include "v4l2-utils.c"
-static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
+static int get_props(struct impl *this, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
+{
+ struct type *t = &this->type;
+
+ switch (*index) {
+ case 0:
+ spa_pod_builder_object(builder, t->param.idProps, t->props,
+ ":", t->prop_device, "S", this->props.device, sizeof(this->props.device),
+ ":", t->prop_device_name, "S-r", this->props.device_name, sizeof(this->props.device_name),
+ ":", t->prop_device_fd, "i-r", this->props.device_fd);
+ break;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ (*index)++;
+
+ return SPA_RESULT_OK;
+}
+
+static int impl_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
- spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer));
- *props = spa_pod_builder_props(&b, t->props,
- ":", t->prop_device, "S", this->props.device, sizeof(this->props.device),
- ":", t->prop_device_name, "S-r", this->props.device_name, sizeof(this->props.device_name),
- ":", t->prop_device_fd, "i-r", this->props.device_fd);
+ if (id == t->param.idProps)
+ return get_props(this, index, filter, builder);
- return SPA_RESULT_OK;
+ return SPA_RESULT_UNKNOWN_PARAM;
}
-static int impl_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int impl_node_set_param(struct spa_node *node,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
struct type *t;
@@ -199,12 +222,16 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
- if (props == NULL) {
- reset_props(&this->props);
- return SPA_RESULT_OK;
+ if (id == t->param.idProps) {
+ if (param == NULL) {
+ reset_props(&this->props);
+ return SPA_RESULT_OK;
+ }
+ spa_pod_object_parse(param,
+ ":", t->prop_device, "?S", this->props.device, sizeof(this->props.device), NULL);
}
- spa_props_parse(props,
- ":", t->prop_device, "?S", this->props.device, sizeof(this->props.device), NULL);
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
@@ -409,41 +436,96 @@ static int impl_node_remove_port(struct spa_node *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int
-impl_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+static int impl_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;
- int res;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- res = spa_v4l2_enum_format(this, format, filter, index);
+ *info = &this->out_ports[port_id].info;
- return res;
+ 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 impl *this = SPA_CONTAINER_OF(node, struct impl, node);
+ return spa_v4l2_enum_format(this, index, filter, builder);
}
-static int impl_node_port_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format)
+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 impl *this = SPA_CONTAINER_OF(node, struct impl, node);
+ struct spa_pod_frame f[1];
+ struct type *t = &this->type;
+ struct port *port = &this->out_ports[port_id];
+
+ if (!port->have_format)
+ return SPA_RESULT_NO_FORMAT;
+
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ spa_pod_builder_push_object(builder, &f[0],
+ t->param.idFormat, t->format);
+
+ spa_pod_builder_add(builder,
+ "I", port->current_format.media_type,
+ "I", port->current_format.media_subtype, 0);
+
+ if (port->current_format.media_subtype == t->media_subtype.raw) {
+ spa_pod_builder_add(builder,
+ ":", t->format_video.format, "I", port->current_format.info.raw.format,
+ ":", t->format_video.size, "R", &port->current_format.info.raw.size,
+ ":", t->format_video.framerate, "F", &port->current_format.info.raw.framerate, 0);
+ } else if (port->current_format.media_subtype == t->media_subtype_video.mjpg ||
+ port->current_format.media_subtype == t->media_subtype_video.jpeg) {
+ spa_pod_builder_add(builder,
+ ":", t->format_video.size, "R", &port->current_format.info.mjpg.size,
+ ":", t->format_video.framerate, "F", &port->current_format.info.mjpg.framerate, 0);
+ } else if (port->current_format.media_subtype == t->media_subtype_video.h264) {
+ spa_pod_builder_add(builder,
+ ":", t->format_video.size, "R", &port->current_format.info.h264.size,
+ ":", t->format_video.framerate, "F", &port->current_format.info.h264.framerate, 0);
+ } else
+ return SPA_RESULT_NO_FORMAT;
+
+ spa_pod_builder_pop(builder, &f[0]);
+
+ return SPA_RESULT_OK;
+}
+
+static int impl_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction,
+ uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
+{
+
struct impl *this;
struct port *port;
- struct spa_video_info info;
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
@@ -452,6 +534,66 @@ static int impl_node_port_set_format(struct spa_node *node,
port = &this->out_ports[port_id];
+ if (id == t->param.idList) {
+ uint32_t list[] = { t->param.idEnumFormat,
+ t->param.idFormat,
+ t->param.idBuffers,
+ t->param.idMeta };
+
+ if (*index < SPA_N_ELEMENTS(list))
+ 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);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ 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,
+ ":", t->param_alloc_buffers.buffers, "iru", MAX_BUFFERS,
+ 2, 2, MAX_BUFFERS,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ switch (*index) {
+ case 0:
+ 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;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
+ (*index)++;
+
+ 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 = SPA_CONTAINER_OF(node, struct impl, node);
+ struct spa_video_info info;
+ struct type *t = &this->type;
+ struct port *port = &this->out_ports[port_id];
+
if (format == NULL) {
spa_v4l2_stream_off(this);
spa_v4l2_clear_buffers(this);
@@ -459,8 +601,9 @@ static int impl_node_port_set_format(struct spa_node *node,
port->have_format = false;
return SPA_RESULT_OK;
} else {
- info.media_type = SPA_FORMAT_MEDIA_TYPE(format);
- info.media_subtype = SPA_FORMAT_MEDIA_SUBTYPE(format);
+ spa_pod_object_parse(format,
+ "I", &info.media_type,
+ "I", &info.media_subtype);
if (info.media_type != t->media_type.video) {
spa_log_error(this->log, "media type must be video");
@@ -500,15 +643,15 @@ static int impl_node_port_set_format(struct spa_node *node,
}
}
- if (port->have_format && !(flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY)) {
+ if (port->have_format && !(flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)) {
spa_v4l2_use_buffers(this, NULL, 0);
port->have_format = false;
}
- if (spa_v4l2_set_format(this, &info, flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY) < 0)
+ if (spa_v4l2_set_format(this, &info, flags & SPA_NODE_PARAM_FLAG_TEST_ONLY) < 0)
return SPA_RESULT_INVALID_MEDIA_TYPE;
- if (!(flags & SPA_PORT_FORMAT_FLAG_TEST_ONLY)) {
+ if (!(flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)) {
port->current_format = info;
port->have_format = true;
}
@@ -516,131 +659,26 @@ static int impl_node_port_set_format(struct spa_node *node,
return SPA_RESULT_OK;
}
-static int impl_node_port_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_format **format)
-{
- struct impl *this;
- struct port *port;
- struct spa_pod_builder b = { NULL, };
- struct spa_pod_frame f[1];
- struct type *t;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
- t = &this->type;
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- port = &this->out_ports[port_id];
-
- if (!port->have_format)
- return SPA_RESULT_NO_FORMAT;
-
- b.data = port->format_buffer;
- b.size = sizeof(port->format_buffer);
-
- spa_pod_builder_push_format(&b, &f[0], t->format,
- port->current_format.media_type,
- port->current_format.media_subtype);
-
- if (port->current_format.media_subtype == t->media_subtype.raw) {
- spa_pod_builder_add(&b,
- ":", t->format_video.format, "I", port->current_format.info.raw.format,
- ":", t->format_video.size, "R", &port->current_format.info.raw.size,
- ":", t->format_video.framerate, "F", &port->current_format.info.raw.framerate, 0);
- } else if (port->current_format.media_subtype == t->media_subtype_video.mjpg ||
- port->current_format.media_subtype == t->media_subtype_video.jpeg) {
- spa_pod_builder_add(&b,
- ":", t->format_video.size, "R", &port->current_format.info.mjpg.size,
- ":", t->format_video.framerate, "F", &port->current_format.info.mjpg.framerate, 0);
- } else if (port->current_format.media_subtype == t->media_subtype_video.h264) {
- spa_pod_builder_add(&b,
- ":", t->format_video.size, "R", &port->current_format.info.h264.size,
- ":", t->format_video.framerate, "F", &port->current_format.info.h264.framerate, 0);
- } else
- return SPA_RESULT_NO_FORMAT;
-
- spa_pod_builder_pop(&b, &f[0]);
- *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format);
-
- return SPA_RESULT_OK;
-}
-
-static int impl_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;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- *info = &this->out_ports[port_id].info;
-
- return SPA_RESULT_OK;
-}
-
-static int impl_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t index,
- struct spa_param **param)
+static int impl_node_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
-
struct impl *this;
- struct port *port;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- port = &this->out_ports[port_id];
-
- spa_pod_builder_init(&b, port->params_buffer, sizeof(port->params_buffer));
-
- switch (index) {
- case 0:
- *param = spa_pod_builder_param(&b, 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,
- ":", t->param_alloc_buffers.buffers, "iru", MAX_BUFFERS,
- 2, 2, MAX_BUFFERS,
- ":", t->param_alloc_buffers.align, "i", 16);
- break;
-
- case 1:
- *param = spa_pod_builder_param(&b, t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- break;
-
- default:
- return SPA_RESULT_NOT_IMPLEMENTED;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
}
- return SPA_RESULT_OK;
-}
-
-static int impl_node_port_set_param(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int impl_node_port_use_buffers(struct spa_node *node,
@@ -680,7 +718,7 @@ static int
impl_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -812,17 +850,14 @@ static const struct spa_dict info = {
static const struct spa_node impl_node = {
SPA_VERSION_NODE,
&info,
- impl_node_get_props,
- impl_node_set_props,
+ impl_node_enum_params,
+ impl_node_set_param,
impl_node_send_command,
impl_node_set_callbacks,
impl_node_get_n_ports,
impl_node_get_port_ids,
impl_node_add_port,
impl_node_remove_port,
- impl_node_port_enum_formats,
- impl_node_port_set_format,
- impl_node_port_get_format,
impl_node_port_get_info,
impl_node_port_enum_params,
impl_node_port_set_param,
@@ -835,12 +870,15 @@ static const struct spa_node impl_node = {
impl_node_process_output,
};
-static int impl_clock_get_props(struct spa_clock *clock, struct spa_props **props)
+static int impl_clock_enum_params(struct spa_clock *clock, uint32_t id, uint32_t *index,
+ struct spa_pod_builder *builder)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int impl_clock_set_props(struct spa_clock *clock, const struct spa_props *props)
+static int impl_clock_set_param(struct spa_clock *clock,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@@ -872,8 +910,8 @@ static const struct spa_clock impl_clock = {
SPA_VERSION_CLOCK,
NULL,
SPA_CLOCK_STATE_STOPPED,
- impl_clock_get_props,
- impl_clock_set_props,
+ impl_clock_enum_params,
+ impl_clock_set_param,
impl_clock_get_time,
};
diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c
index 9de541e1..71564ca7 100644
--- a/spa/plugins/v4l2/v4l2-utils.c
+++ b/spa/plugins/v4l2/v4l2-utils.c
@@ -398,18 +398,19 @@ static const struct format_info *find_format_info_by_media_type(struct type *typ
}
static uint32_t
-enum_filter_format(struct type *type, const struct spa_format *filter, uint32_t index)
+enum_filter_format(struct type *type, uint32_t media_type, int32_t media_subtype,
+ const struct spa_pod_object *filter, uint32_t index)
{
uint32_t video_format = 0;
- if ((filter->body.media_type.value == type->media_type.video ||
- filter->body.media_type.value == type->media_type.image)) {
- if (filter->body.media_subtype.value == type->media_subtype.raw) {
+ if ((media_type == type->media_type.video ||
+ media_type == type->media_type.image)) {
+ if (media_subtype == type->media_subtype.raw) {
struct spa_pod_prop *p;
uint32_t n_values;
const uint32_t *values;
- if (!(p = spa_format_find_prop(filter, type->format_video.format)))
+ if (!(p = spa_pod_object_find_prop(filter, type->format_video.format)))
return type->video_format.UNKNOWN;
if (p->body.value.type != SPA_POD_TYPE_ID)
@@ -522,24 +523,22 @@ filter_framerate(struct v4l2_frmivalenum *frmival,
static int
spa_v4l2_enum_format(struct impl *this,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+ uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct port *port = &this->out_ports[0];
int res, n_fractions;
const struct format_info *info;
struct spa_pod_frame f[2];
struct spa_pod_prop *prop;
- struct spa_pod_builder b = { NULL, };
uint32_t media_type, media_subtype, video_format;
+ uint32_t filter_media_type, filter_media_subtype;
if (spa_v4l2_open(this) < 0)
return SPA_RESULT_ERROR;
- *format = NULL;
-
- if (index == 0) {
+ if (*index == 0) {
spa_zero(port->fmtdesc);
port->fmtdesc.index = 0;
port->fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -549,6 +548,12 @@ spa_v4l2_enum_format(struct impl *this,
spa_zero(port->frmival);
}
+ if (filter) {
+ spa_pod_object_parse(filter,
+ "I", &filter_media_type,
+ "I", &filter_media_subtype);
+ }
+
if (false) {
next_fmtdesc:
port->fmtdesc.index++;
@@ -557,14 +562,17 @@ spa_v4l2_enum_format(struct impl *this,
while (port->next_fmtdesc) {
if (filter) {
- video_format =
- enum_filter_format(&this->type, filter, port->fmtdesc.index);
+ video_format = enum_filter_format(&this->type,
+ filter_media_type,
+ filter_media_subtype,
+ filter, port->fmtdesc.index);
+
if (video_format == this->type.video_format.UNKNOWN)
return SPA_RESULT_ENUM_END;
info = find_format_info_by_media_type(&this->type,
- filter->body.media_type.value,
- filter->body.media_subtype.value,
+ filter_media_type,
+ filter_media_subtype,
video_format, 0);
if (info == NULL)
goto next_fmtdesc;
@@ -591,7 +599,7 @@ spa_v4l2_enum_format(struct impl *this,
struct spa_pod_prop *p;
/* check if we have a fixed frame size */
- if (!(p = spa_format_find_prop(filter, this->type.format_video.size)))
+ if (!(p = spa_pod_object_find_prop(filter, this->type.format_video.size)))
goto do_frmsize;
if (p->body.value.type != SPA_POD_TYPE_RECTANGLE)
@@ -625,7 +633,7 @@ spa_v4l2_enum_format(struct impl *this,
uint32_t i, n_values;
/* check if we have a fixed frame size */
- if (!(p = spa_format_find_prop(filter, this->type.format_video.size)))
+ if (!(p = spa_pod_object_find_prop(filter, this->type.format_video.size)))
goto have_size;
range = p->body.flags & SPA_POD_PROP_RANGE_MASK;
@@ -675,21 +683,25 @@ spa_v4l2_enum_format(struct impl *this,
media_subtype = *SPA_MEMBER(&this->type, info->media_subtype_offset, uint32_t);
video_format = *SPA_MEMBER(&this->type, info->format_offset, uint32_t);
- spa_pod_builder_init(&b, port->format_buffer, sizeof(port->format_buffer));
- spa_pod_builder_push_format(&b, &f[0], this->type.format, media_type, media_subtype);
+ spa_pod_builder_init(builder, port->format_buffer, sizeof(port->format_buffer));
+ spa_pod_builder_push_object(builder, &f[0],
+ this->type.param.idEnumFormat, this->type.format);
+ spa_pod_builder_add(builder,
+ "I", media_type,
+ "I", media_subtype, 0);
if (media_subtype == this->type.media_subtype.raw) {
- spa_pod_builder_add(&b,
- ":", this->type.format_video.format, "I", video_format, 0);
+ spa_pod_builder_add(builder,
+ ":", this->type.format_video.format, "I", video_format, 0);
}
- spa_pod_builder_add(&b,
+ spa_pod_builder_add(builder,
":", this->type.format_video.size, "R", &SPA_RECTANGLE(port->frmsize.discrete.width,
port->frmsize.discrete.height), 0);
- spa_pod_builder_push_prop(&b, &f[1], this->type.format_video.framerate,
+ spa_pod_builder_push_prop(builder, &f[1], this->type.format_video.framerate,
SPA_POD_PROP_RANGE_NONE | SPA_POD_PROP_FLAG_UNSET);
- prop = SPA_POD_BUILDER_DEREF(&b, f[1].ref, struct spa_pod_prop);
+ prop = SPA_POD_BUILDER_DEREF(builder, f[1].ref, struct spa_pod_prop);
n_fractions = 0;
port->frmival.index = 0;
@@ -712,7 +724,7 @@ spa_v4l2_enum_format(struct impl *this,
uint32_t i, n_values;
const struct spa_fraction step = { 1, 1 }, *values;
- if (!(p = spa_format_find_prop(filter, this->type.format_video.framerate)))
+ if (!(p = spa_pod_object_find_prop(filter, this->type.format_video.framerate)))
goto have_framerate;
if (p->body.value.type != SPA_POD_TYPE_FRACTION)
@@ -746,21 +758,21 @@ spa_v4l2_enum_format(struct impl *this,
if (port->frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
prop->body.flags |= SPA_POD_PROP_RANGE_ENUM;
if (n_fractions == 0)
- spa_pod_builder_fraction(&b,
+ spa_pod_builder_fraction(builder,
port->frmival.discrete.denominator,
port->frmival.discrete.numerator);
- spa_pod_builder_fraction(&b,
+ spa_pod_builder_fraction(builder,
port->frmival.discrete.denominator,
port->frmival.discrete.numerator);
port->frmival.index++;
} else if (port->frmival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS ||
port->frmival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
if (n_fractions == 0)
- spa_pod_builder_fraction(&b, 25, 1);
- spa_pod_builder_fraction(&b,
+ spa_pod_builder_fraction(builder, 25, 1);
+ spa_pod_builder_fraction(builder,
port->frmival.stepwise.min.denominator,
port->frmival.stepwise.min.numerator);
- spa_pod_builder_fraction(&b,
+ spa_pod_builder_fraction(builder,
port->frmival.stepwise.max.denominator,
port->frmival.stepwise.max.numerator);
@@ -768,7 +780,7 @@ spa_v4l2_enum_format(struct impl *this,
prop->body.flags |= SPA_POD_PROP_RANGE_MIN_MAX;
} else {
prop->body.flags |= SPA_POD_PROP_RANGE_STEP;
- spa_pod_builder_fraction(&b,
+ spa_pod_builder_fraction(builder,
port->frmival.stepwise.step.denominator,
port->frmival.stepwise.step.numerator);
}
@@ -779,10 +791,10 @@ spa_v4l2_enum_format(struct impl *this,
if (n_fractions <= 1) {
prop->body.flags &= ~(SPA_POD_PROP_RANGE_MASK | SPA_POD_PROP_FLAG_UNSET);
}
- spa_pod_builder_pop(&b, &f[1]);
- spa_pod_builder_pop(&b, &f[0]);
+ spa_pod_builder_pop(builder, &f[1]);
+ spa_pod_builder_pop(builder, &f[0]);
- *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format);
+ (*index)++;
return SPA_RESULT_OK;
}
@@ -1028,7 +1040,7 @@ static int spa_v4l2_use_buffers(struct impl *this, struct spa_buffer **buffers,
static int
mmap_init(struct impl *this,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -1137,7 +1149,7 @@ static int read_init(struct impl *this)
static int
spa_v4l2_alloc_buffers(struct impl *this,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
diff --git a/spa/plugins/videotestsrc/videotestsrc.c b/spa/plugins/videotestsrc/videotestsrc.c
index 51668fe2..5f2a3f17 100644
--- a/spa/plugins/videotestsrc/videotestsrc.c
+++ b/spa/plugins/videotestsrc/videotestsrc.c
@@ -32,7 +32,6 @@
#include <spa/param-alloc.h>
#include <spa/list.h>
#include <spa/video/format-utils.h>
-#include <spa/format-builder.h>
#include <lib/format.h>
#include <lib/props.h>
@@ -51,6 +50,7 @@ struct type {
uint32_t prop_pattern;
uint32_t pattern_smpte_snow;
uint32_t pattern_snow;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -73,6 +73,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->prop_pattern = spa_type_map_get_id(map, SPA_TYPE_PROPS__patternType);
type->pattern_smpte_snow = spa_type_map_get_id(map, SPA_TYPE_PROPS__patternType ":smpte-snow");
type->pattern_snow = spa_type_map_get_id(map, SPA_TYPE_PROPS__patternType ":snow");
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -121,7 +122,6 @@ struct impl {
struct itimerspec timerspec;
struct spa_port_info info;
- uint8_t params_buffer[1024];
struct spa_port_io *io;
bool have_format;
@@ -153,30 +153,39 @@ static void reset_props(struct impl *this, struct props *props)
props->pattern = this->type.DEFAULT_PATTERN;
}
-static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
+static int impl_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
- spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer));
- *props = spa_pod_builder_props(&b,
- t->props,
- ":", t->prop_live, "b", this->props.live,
- ":", t->prop_pattern, "Ie", this->props.pattern,
- 2, t->pattern_smpte_snow,
- t->pattern_snow);
+ if (id == t->param.idProps) {
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ spa_pod_builder_object(builder,
+ id, t->props,
+ ":", t->prop_live, "b", this->props.live,
+ ":", t->prop_pattern, "Ie", this->props.pattern,
+ 2, t->pattern_smpte_snow,
+ t->pattern_snow);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
-static int impl_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
struct type *t;
@@ -186,19 +195,19 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
- if (props == NULL) {
- reset_props(this, &this->props);
- } else {
- spa_props_parse(props,
+ if (id == t->param.idProps) {
+ spa_pod_object_parse(param,
":", t->prop_live, "?b", &this->props.live,
":", t->prop_pattern, "?I", &this->props.pattern,
NULL);
- }
- if (this->props.live)
- this->info.flags |= SPA_PORT_INFO_FLAG_LIVE;
+ if (this->props.live)
+ this->info.flags |= SPA_PORT_INFO_FLAG_LIVE;
+ else
+ this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
+ }
else
- this->info.flags &= ~SPA_PORT_INFO_FLAG_LIVE;
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
@@ -408,39 +417,47 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
}
static int
-impl_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+impl_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;
- int res;
- struct spa_format *fmt;
- uint8_t buffer[256];
- struct spa_pod_builder b = { NULL, };
- uint32_t count, match;
- struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
- t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- count = match = filter ? 0 : index;
+ *info = &this->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 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 (count++) {
+ switch (*index) {
case 0:
- fmt = spa_pod_builder_format(&b,
- t->format,
- t->media_type.video, t->media_subtype.raw,
+ fmt = spa_pod_builder_object(&b,
+ t->param.idEnumFormat, t->format,
+ "I", t->media_type.video,
+ "I", t->media_subtype.raw,
":", t->format_video.format, "Ieu", t->video_format.RGB,
2, t->video_format.RGB,
t->video_format.UYVY,
@@ -454,13 +471,93 @@ impl_node_port_enum_formats(struct spa_node *node,
default:
return SPA_RESULT_ENUM_END;
}
+ (*index)++;
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
-
- if ((res = spa_format_filter(fmt, filter, &b)) != SPA_RESULT_OK || match++ != index)
+ if ((res = spa_pod_object_filter(fmt, filter, builder)) != SPA_RESULT_OK)
goto next;
- *format = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_format);
+ 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 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,
+ t->param.idFormat, t->format,
+ "I", t->media_type.video,
+ "I", t->media_subtype.raw,
+ ":", t->format_video.format, "I", this->current_format.info.raw.format,
+ ":", t->format_video.size, "R", &this->current_format.info.raw.size,
+ ":", t->format_video.framerate, "F", &this->current_format.info.raw.framerate);
+
+ return SPA_RESULT_OK;
+}
+
+static int
+impl_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
+{
+ struct impl *this;
+ struct type *t;
+
+ spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+
+ this = SPA_CONTAINER_OF(node, struct impl, node);
+ t = &this->type;
+
+ spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ struct spa_video_info_raw *raw_info = &this->current_format.info.raw;
+
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ 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,
+ ":", t->param_alloc_buffers.buffers, "ir", 2,
+ 2, 1, 32,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ switch (*index) {
+ case 0:
+ 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;
+
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ }
+ (*index)++;
return SPA_RESULT_OK;
}
@@ -477,28 +574,22 @@ static int clear_buffers(struct impl *this)
return SPA_RESULT_OK;
}
-static int
-impl_node_port_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format)
+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;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
if (format == NULL) {
this->have_format = false;
clear_buffers(this);
} else {
- struct spa_video_info info = { SPA_FORMAT_MEDIA_TYPE(format),
- SPA_FORMAT_MEDIA_SUBTYPE(format),
- };
+ 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)
@@ -527,112 +618,26 @@ impl_node_port_set_format(struct spa_node *node,
}
static int
-impl_node_port_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_format **format)
-{
- struct impl *this;
- struct spa_pod_builder b = { NULL, };
- struct type *t;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
- t = &this->type;
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- if (!this->have_format)
- return SPA_RESULT_NO_FORMAT;
-
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
- *format = spa_pod_builder_format(&b,
- t->format,
- t->media_type.video, t->media_subtype.raw,
- ":", t->format_video.format, "I", this->current_format.info.raw.format,
- ":", t->format_video.size, "R", &this->current_format.info.raw.size,
- ":", t->format_video.framerate, "F", &this->current_format.info.raw.framerate);
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_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;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
-
- *info = &this->info;
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t index,
- struct spa_param **param)
+impl_node_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- spa_pod_builder_init(&b, this->params_buffer, sizeof(this->params_buffer));
-
- switch (index) {
- case 0: {
- struct spa_video_info_raw *raw_info = &this->current_format.info.raw;
-
- *param = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "i", this->stride * raw_info->size.height,
- ":", t->param_alloc_buffers.stride, "i", this->stride,
- ":", t->param_alloc_buffers.buffers, "ir", 2,
- 2, 1, 32,
- ":", t->param_alloc_buffers.align, "i", 16);
- break;
- }
- case 1:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- break;
-
- default:
- return SPA_RESULT_NOT_IMPLEMENTED;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
}
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_set_param(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
@@ -683,7 +688,7 @@ static int
impl_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -803,17 +808,14 @@ static const struct spa_dict node_info = {
static const struct spa_node impl_node = {
SPA_VERSION_NODE,
&node_info,
- impl_node_get_props,
- impl_node_set_props,
+ impl_node_enum_params,
+ impl_node_set_param,
impl_node_send_command,
impl_node_set_callbacks,
impl_node_get_n_ports,
impl_node_get_port_ids,
impl_node_add_port,
impl_node_remove_port,
- impl_node_port_enum_formats,
- impl_node_port_set_format,
- impl_node_port_get_format,
impl_node_port_get_info,
impl_node_port_enum_params,
impl_node_port_set_param,
@@ -826,12 +828,14 @@ static const struct spa_node impl_node = {
impl_node_process_output,
};
-static int impl_clock_get_props(struct spa_clock *clock, struct spa_props **props)
+static int impl_clock_enum_params(struct spa_clock *clock, uint32_t id, uint32_t *index,
+ struct spa_pod_builder *builder)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int impl_clock_set_props(struct spa_clock *clock, const struct spa_props *props)
+static int impl_clock_set_param(struct spa_clock *clock, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@@ -865,8 +869,8 @@ static const struct spa_clock impl_clock = {
SPA_VERSION_CLOCK,
NULL,
SPA_CLOCK_STATE_STOPPED,
- impl_clock_get_props,
- impl_clock_set_props,
+ impl_clock_enum_params,
+ impl_clock_set_param,
impl_clock_get_time,
};
diff --git a/spa/plugins/volume/volume.c b/spa/plugins/volume/volume.c
index c68b8d59..f618b737 100644
--- a/spa/plugins/volume/volume.c
+++ b/spa/plugins/volume/volume.c
@@ -25,7 +25,6 @@
#include <spa/node.h>
#include <spa/list.h>
#include <spa/audio/format-utils.h>
-#include <spa/format-builder.h>
#include <spa/param-alloc.h>
#include <lib/props.h>
#include <lib/format.h>
@@ -67,6 +66,7 @@ struct type {
uint32_t props;
uint32_t prop_volume;
uint32_t prop_mute;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -86,6 +86,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
type->prop_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
type->prop_mute = spa_type_map_get_id(map, SPA_TYPE_PROPS__mute);
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -106,7 +107,6 @@ struct impl {
struct spa_type_map *map;
struct spa_log *log;
- uint8_t props_buffer[512];
struct props props;
const struct spa_node_callbacks *callbacks;
@@ -135,28 +135,35 @@ static void reset_props(struct props *props)
props->mute = DEFAULT_MUTE;
}
-static int impl_node_get_props(struct spa_node *node, struct spa_props **props)
+static int impl_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(props != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
- spa_pod_builder_init(&b, this->props_buffer, sizeof(this->props_buffer));
- *props = spa_pod_builder_props(&b,
- t->props,
- ":", t->prop_volume, "dr", this->props.volume, 2, 0.0, 10.0,
- ":", t->prop_mute, "b", this->props.mute);
+ if (id == t->param.idProps) {
+ spa_pod_builder_object(builder,
+ id, t->props,
+ ":", t->prop_volume, "dr", this->props.volume, 2, 0.0, 10.0,
+ ":", t->prop_mute, "b", this->props.mute);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
return SPA_RESULT_OK;
}
-static int impl_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct impl *this;
struct type *t;
@@ -166,13 +173,18 @@ static int impl_node_set_props(struct spa_node *node, const struct spa_props *pr
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
- if (props == NULL) {
- reset_props(&this->props);
- } else {
- spa_props_parse(props,
+ if (id == t->param.idProps) {
+ if (param == NULL) {
+ reset_props(&this->props);
+ return SPA_RESULT_OK;
+ }
+ spa_pod_object_parse(param,
":", t->prop_volume, "?d", &this->props.volume,
":", t->prop_mute, "?b", &this->props.mute, NULL);
}
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
return SPA_RESULT_OK;
}
@@ -263,39 +275,50 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
}
static int
-impl_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+impl_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;
- int res;
- struct spa_format *fmt;
- uint8_t buffer[1024];
- struct spa_pod_builder b = { NULL, };
- uint32_t count, match;
- struct type *t;
+ struct port *port;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
- t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- count = match = filter ? 0 : index;
+ 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 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 (count++) {
+ switch (*index) {
case 0:
- fmt = spa_pod_builder_format(&b,
- t->format,
- t->media_type.audio, t->media_subtype.raw,
+ fmt = spa_pod_builder_object(&b,
+ t->param.idEnumFormat, t->format,
+ "I", t->media_type.audio,
+ "I", t->media_subtype.raw,
":", t->format_audio.format, "Ieu", t->audio_format.S16,
2, t->audio_format.S16,
t->audio_format.S32,
@@ -305,187 +328,167 @@ impl_node_port_enum_formats(struct spa_node *node,
default:
return SPA_RESULT_ENUM_END;
}
+ (*index)++;
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
-
- if ((res = spa_format_filter(fmt, filter, &b)) != SPA_RESULT_OK || match++ != index)
+ if ((res = spa_pod_object_filter(fmt, filter, builder)) != SPA_RESULT_OK)
goto next;
- *format = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_format);
-
- return SPA_RESULT_OK;
-}
-
-static int clear_buffers(struct impl *this, struct port *port)
-{
- if (port->n_buffers > 0) {
- spa_log_info(this->log, NAME " %p: clear buffers", this);
- port->n_buffers = 0;
- spa_list_init(&port->empty);
- }
return SPA_RESULT_OK;
}
-static int
-impl_node_port_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format)
+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 impl *this;
+ struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct port *port;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct impl, node);
-
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ struct type *t = &this->type;
port =
direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
- if (format == NULL) {
- port->have_format = false;
- clear_buffers(this, port);
- } else {
- struct spa_audio_info info = { SPA_FORMAT_MEDIA_TYPE(format),
- SPA_FORMAT_MEDIA_SUBTYPE(format),
- };
-
- if (info.media_type != this->type.media_type.audio ||
- info.media_subtype != this->type.media_subtype.raw)
- return SPA_RESULT_INVALID_MEDIA_TYPE;
+ if (!port->have_format)
+ return SPA_RESULT_NO_FORMAT;
- if (spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio) < 0)
- return SPA_RESULT_INVALID_MEDIA_TYPE;
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
- this->bpf = 2 * info.info.raw.channels;
- this->current_format = info;
- port->have_format = true;
- }
+ 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_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_format **format)
+impl_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct impl *this;
- struct port *port;
- struct spa_pod_builder b = { NULL, };
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(format != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ spa_pod_builder_object(builder,
+ id, t->param_alloc_buffers.Buffers,
+ ":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
+ 2, 16 * this->bpf,
+ INT32_MAX / this->bpf,
+ ":", t->param_alloc_buffers.stride, "i", 0,
+ ":", t->param_alloc_buffers.buffers, "iru", 2,
+ 2, 1, MAX_BUFFERS,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ switch (*index) {
+ case 0:
+ 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;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
- if (!port->have_format)
- return SPA_RESULT_NO_FORMAT;
+ (*index)++;
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
- *format = spa_pod_builder_format(&b,
- t->format,
- t->media_type.audio, t->media_subtype.raw,
- ":", t->format_audio.format, "I", this->current_format.info.raw.format,
- ":", t->format_audio.rate, "i", this->current_format.info.raw.rate,
- ":", t->format_audio.channels, "i", this->current_format.info.raw.channels);
+ return SPA_RESULT_OK;
+}
+static int clear_buffers(struct impl *this, struct port *port)
+{
+ if (port->n_buffers > 0) {
+ spa_log_info(this->log, NAME " %p: clear buffers", this);
+ port->n_buffers = 0;
+ spa_list_init(&port->empty);
+ }
return SPA_RESULT_OK;
}
-static int
-impl_node_port_get_info(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_port_info **info)
+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 impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct port *port;
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(info != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ port =
+ direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
- this = SPA_CONTAINER_OF(node, struct impl, node);
+ if (format == NULL) {
+ port->have_format = false;
+ clear_buffers(this, port);
+ } else {
+ struct spa_audio_info info = { 0 };
- spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
+ spa_pod_object_parse(format,
+ "I", &info.media_type,
+ "I", &info.media_subtype);
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
- *info = &port->info;
+ if (info.media_type != this->type.media_type.audio ||
+ info.media_subtype != this->type.media_subtype.raw)
+ return SPA_RESULT_INVALID_MEDIA_TYPE;
+
+ if (spa_format_audio_raw_parse(format, &info.info.raw, &this->type.format_audio) < 0)
+ return SPA_RESULT_INVALID_MEDIA_TYPE;
+
+ this->bpf = 2 * info.info.raw.channels;
+ this->current_format = info;
+ port->have_format = true;
+ }
return SPA_RESULT_OK;
}
static int
-impl_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t index,
- struct spa_param **param)
+impl_node_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
- struct spa_pod_builder b = { NULL };
struct impl *this;
- struct port *port;
struct type *t;
spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct impl, node);
t = &this->type;
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), SPA_RESULT_INVALID_PORT);
- port =
- direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
-
- spa_pod_builder_init(&b, port->params_buffer, sizeof(port->params_buffer));
-
- switch (index) {
- case 0:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "iru", 1024 * this->bpf,
- 2, 16 * this->bpf,
- INT32_MAX / this->bpf,
- ":", t->param_alloc_buffers.stride, "i", 0,
- ":", t->param_alloc_buffers.buffers, "iru", 2,
- 2, 1, MAX_BUFFERS,
- ":", t->param_alloc_buffers.align, "i", 16);
- break;
-
- case 1:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- break;
-
- default:
- return SPA_RESULT_NOT_IMPLEMENTED;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
}
-
- return SPA_RESULT_OK;
-}
-
-static int
-impl_node_port_set_param(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int
@@ -544,7 +547,7 @@ static int
impl_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -762,17 +765,14 @@ static int impl_node_process_output(struct spa_node *node)
static const struct spa_node impl_node = {
SPA_VERSION_NODE,
NULL,
- impl_node_get_props,
- impl_node_set_props,
+ impl_node_enum_params,
+ impl_node_set_param,
impl_node_send_command,
impl_node_set_callbacks,
impl_node_get_n_ports,
impl_node_get_port_ids,
impl_node_add_port,
impl_node_remove_port,
- impl_node_port_enum_formats,
- impl_node_port_set_format,
- impl_node_port_get_format,
impl_node_port_get_info,
impl_node_port_enum_params,
impl_node_port_set_param,
diff --git a/spa/tests/test-graph.c b/spa/tests/test-graph.c
index d164cb47..bdea80aa 100644
--- a/spa/tests/test-graph.c
+++ b/spa/tests/test-graph.c
@@ -34,7 +34,6 @@
#include <spa/type-map-impl.h>
#include <spa/audio/format-utils.h>
#include <spa/format-utils.h>
-#include <spa/format-builder.h>
static SPA_TYPE_MAP_IMPL(default_map, 4096);
static SPA_LOG_IMPL(default_log);
@@ -55,6 +54,7 @@ struct type {
uint32_t props_volume;
uint32_t props_min_latency;
uint32_t props_live;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -75,6 +75,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->props_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
type->props_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency);
type->props_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -284,7 +285,7 @@ do_invoke(struct spa_loop *loop,
static int make_nodes(struct data *data, const char *device)
{
int res;
- struct spa_props *props;
+ struct spa_pod_object *props;
struct spa_pod_builder b = { 0 };
uint8_t buffer[128];
@@ -296,14 +297,14 @@ static int make_nodes(struct data *data, const char *device)
spa_node_set_callbacks(data->sink, &sink_callbacks, data);
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- props = spa_pod_builder_props(&b,
- data->type.props,
+ props = spa_pod_builder_object(&b,
+ 0, data->type.props,
":", data->type.props_device, "s", device ? device : "hw:0",
":", data->type.props_min_latency, "i", MIN_LATENCY);
- spa_debug_pod(&props->object.pod);
+ spa_debug_pod(&props->pod, 0);
- if ((res = spa_node_set_props(data->sink, props)) < 0)
+ if ((res = spa_node_set_param(data->sink, data->type.param.idProps, 0, props)) < 0)
printf("got set_props error %d\n", res);
if ((res = make_node(data, &data->volume,
@@ -320,13 +321,13 @@ static int make_nodes(struct data *data, const char *device)
}
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- props = spa_pod_builder_props(&b,
- data->type.props,
+ props = spa_pod_builder_object(&b,
+ 0, data->type.props,
":", data->type.props_freq, "d", 600.0,
":", data->type.props_volume, "d", 0.5,
":", data->type.props_live, "b", false);
- if ((res = spa_node_set_props(data->source, props)) < 0)
+ if ((res = spa_node_set_param(data->source, data->type.param.idProps, 0, props)) < 0)
printf("got set_props error %d\n", res);
data->source_volume_io[0] = SPA_PORT_IO_INIT;
@@ -367,31 +368,41 @@ static int make_nodes(struct data *data, const char *device)
static int negotiate_formats(struct data *data)
{
- int res;
- struct spa_format *format, *filter;
+ int res, ref;
+ struct spa_pod_object *format, *filter;
uint32_t state = 0;
struct spa_pod_builder b = { 0 };
- uint8_t buffer[256];
+ uint8_t buffer[4096];
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- filter = spa_pod_builder_format(&b,
- data->type.format,
- data->type.media_type.audio, data->type.media_subtype.raw,
+ filter = spa_pod_builder_object(&b,
+ 0, data->type.format,
+ "I", data->type.media_type.audio,
+ "I", data->type.media_subtype.raw,
":", data->type.format_audio.format, "I", data->type.audio_format.S16,
":", data->type.format_audio.layout, "i", SPA_AUDIO_LAYOUT_INTERLEAVED,
":", data->type.format_audio.rate, "i", 44100,
":", data->type.format_audio.channels, "i", 2);
- if ((res =
- spa_node_port_enum_formats(data->sink, SPA_DIRECTION_INPUT, 0, &format, filter,
- state)) < 0)
+ ref = b.offset;
+
+ if ((res = spa_node_port_enum_params(data->sink,
+ SPA_DIRECTION_INPUT, 0,
+ data->type.param.idEnumFormat, &state,
+ filter, &b)) < 0)
return res;
+ format = SPA_POD_BUILDER_DEREF(&b, ref, struct spa_pod_object);
+
- if ((res = spa_node_port_set_format(data->sink, SPA_DIRECTION_INPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->sink,
+ SPA_DIRECTION_INPUT, 0,
+ data->type.param.idFormat, 0, format)) < 0)
return res;
- if ((res = spa_node_port_set_format(data->volume, SPA_DIRECTION_OUTPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->volume,
+ SPA_DIRECTION_OUTPUT, 0,
+ data->type.param.idFormat, 0, format)) < 0)
return res;
init_buffer(data, data->volume_buffers, data->volume_buffer, 1, BUFFER_SIZE);
@@ -404,9 +415,13 @@ static int negotiate_formats(struct data *data)
1)) < 0)
return res;
- if ((res = spa_node_port_set_format(data->volume, SPA_DIRECTION_INPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->volume,
+ SPA_DIRECTION_INPUT, 0,
+ data->type.param.idFormat, 0, format)) < 0)
return res;
- if ((res = spa_node_port_set_format(data->source, SPA_DIRECTION_OUTPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->source,
+ SPA_DIRECTION_OUTPUT, 0,
+ data->type.param.idFormat, 0, format)) < 0)
return res;
init_buffer(data, data->source_buffers, data->source_buffer, 1, BUFFER_SIZE);
diff --git a/spa/tests/test-graph2.c b/spa/tests/test-graph2.c
index 503fbc72..ebe0f0c5 100644
--- a/spa/tests/test-graph2.c
+++ b/spa/tests/test-graph2.c
@@ -34,7 +34,6 @@
#include <spa/type-map-impl.h>
#include <spa/audio/format-utils.h>
#include <spa/format-utils.h>
-#include <spa/format-builder.h>
#include <spa/graph.h>
#include <spa/graph-scheduler1.h>
diff --git a/spa/tests/test-mixer.c b/spa/tests/test-mixer.c
index 67e2f071..2838e452 100644
--- a/spa/tests/test-mixer.c
+++ b/spa/tests/test-mixer.c
@@ -34,7 +34,6 @@
#include <spa/type-map-impl.h>
#include <spa/audio/format-utils.h>
#include <spa/format-utils.h>
-#include <spa/format-builder.h>
#define USE_GRAPH
@@ -55,6 +54,7 @@ struct type {
uint32_t props_volume;
uint32_t props_min_latency;
uint32_t props_live;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -75,6 +75,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->props_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
type->props_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency);
type->props_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -326,7 +327,7 @@ do_invoke(struct spa_loop *loop,
static int make_nodes(struct data *data, const char *device)
{
int res;
- struct spa_props *props;
+ struct spa_pod_object *props;
struct spa_pod_builder b = { 0 };
uint8_t buffer[128];
@@ -338,12 +339,12 @@ static int make_nodes(struct data *data, const char *device)
spa_node_set_callbacks(data->sink, &sink_callbacks, data);
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- props = spa_pod_builder_props(&b,
- data->type.props,
+ props = spa_pod_builder_object(&b,
+ 0, data->type.props,
":", data->type.props_device, "s", device ? device : "hw:0",
":", data->type.props_min_latency, "i", MIN_LATENCY);
- if ((res = spa_node_set_props(data->sink, props)) < 0)
+ if ((res = spa_node_set_param(data->sink, data->type.param.idProps, 0, props)) < 0)
printf("got set_props error %d\n", res);
if ((res = make_node(data, &data->mix,
@@ -361,13 +362,13 @@ static int make_nodes(struct data *data, const char *device)
}
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- props = spa_pod_builder_props(&b,
- data->type.props,
+ props = spa_pod_builder_object(&b,
+ 0, data->type.props,
":", data->type.props_freq, "d", 600.0,
":", data->type.props_volume, "d", 0.5,
":", data->type.props_live, "b", false);
- if ((res = spa_node_set_props(data->source1, props)) < 0)
+ if ((res = spa_node_set_param(data->source1, data->type.param.idProps, 0, props)) < 0)
printf("got set_props error %d\n", res);
if ((res = make_node(data, &data->source2,
@@ -378,13 +379,13 @@ static int make_nodes(struct data *data, const char *device)
}
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- props = spa_pod_builder_props(&b,
- data->type.props,
+ props = spa_pod_builder_object(&b,
+ 0, data->type.props,
":", data->type.props_freq, "d", 440.0,
":", data->type.props_volume, "d", 0.5,
":", data->type.props_live, "b", false);
- if ((res = spa_node_set_props(data->source2, props)) < 0)
+ if ((res = spa_node_set_param(data->source2, data->type.param.idProps, 0, props)) < 0)
printf("got set_props error %d\n", res);
data->mix_ports[0] = 0;
@@ -450,29 +451,42 @@ static int make_nodes(struct data *data, const char *device)
static int negotiate_formats(struct data *data)
{
int res;
- struct spa_format *format, *filter;
- uint32_t state = 0;
+ struct spa_pod_object *format, *filter;
+ uint32_t state = 0, ref;
struct spa_pod_builder b = { 0 };
- uint8_t buffer[256];
+ uint8_t buffer[2048];
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- filter = spa_pod_builder_format(&b,
- data->type.format,
- data->type.media_type.audio, data->type.media_subtype.raw,
+ filter = spa_pod_builder_object(&b,
+ 0, data->type.format,
+ "I", data->type.media_type.audio,
+ "I", data->type.media_subtype.raw,
":", data->type.format_audio.format, "I", data->type.audio_format.S16,
":", data->type.format_audio.layout, "i", SPA_AUDIO_LAYOUT_INTERLEAVED,
":", data->type.format_audio.rate, "i", 44100,
":", data->type.format_audio.channels, "i", 2);
+ ref = b.offset;
+
if ((res =
- spa_node_port_enum_formats(data->sink, SPA_DIRECTION_INPUT, 0, &format, filter,
- state)) < 0)
+ spa_node_port_enum_params(data->sink,
+ SPA_DIRECTION_INPUT, 0,
+ data->type.param.idEnumFormat, &state,
+ filter, &b)) < 0)
return res;
- if ((res = spa_node_port_set_format(data->sink, SPA_DIRECTION_INPUT, 0, 0, format)) < 0)
+ format = SPA_POD_BUILDER_DEREF(&b, ref, struct spa_pod_object);
+
+ if ((res = spa_node_port_set_param(data->sink,
+ SPA_DIRECTION_INPUT, 0,
+ data->type.param.idFormat, 0,
+ format)) < 0)
return res;
- if ((res = spa_node_port_set_format(data->mix, SPA_DIRECTION_OUTPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->mix,
+ SPA_DIRECTION_OUTPUT, 0,
+ data->type.param.idFormat, 0,
+ format)) < 0)
return res;
init_buffer(data, data->mix_buffers, data->mix_buffer, 1, BUFFER_SIZE2);
@@ -486,11 +500,16 @@ static int negotiate_formats(struct data *data)
return res;
if ((res =
- spa_node_port_set_format(data->mix, SPA_DIRECTION_INPUT, data->mix_ports[0], 0,
- format)) < 0)
+ spa_node_port_set_param(data->mix,
+ SPA_DIRECTION_INPUT, data->mix_ports[0],
+ data->type.param.idFormat, 0,
+ format)) < 0)
return res;
- if ((res = spa_node_port_set_format(data->source1, SPA_DIRECTION_OUTPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->source1,
+ SPA_DIRECTION_OUTPUT, 0,
+ data->type.param.idFormat, 0,
+ format)) < 0)
return res;
init_buffer(data, data->source1_buffers, data->source1_buffer, 2, BUFFER_SIZE1);
@@ -504,11 +523,16 @@ static int negotiate_formats(struct data *data)
return res;
if ((res =
- spa_node_port_set_format(data->mix, SPA_DIRECTION_INPUT, data->mix_ports[1], 0,
- format)) < 0)
+ spa_node_port_set_param(data->mix,
+ SPA_DIRECTION_INPUT, data->mix_ports[1],
+ data->type.param.idFormat, 0,
+ format)) < 0)
return res;
- if ((res = spa_node_port_set_format(data->source2, SPA_DIRECTION_OUTPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->source2,
+ SPA_DIRECTION_OUTPUT, 0,
+ data->type.param.idFormat, 0,
+ format)) < 0)
return res;
init_buffer(data, data->source2_buffers, data->source2_buffer, 2, BUFFER_SIZE2);
diff --git a/spa/tests/test-perf.c b/spa/tests/test-perf.c
index f6504307..c26f4775 100644
--- a/spa/tests/test-perf.c
+++ b/spa/tests/test-perf.c
@@ -32,7 +32,6 @@
#include <spa/type-map-impl.h>
#include <spa/audio/format-utils.h>
#include <spa/format-utils.h>
-#include <spa/format-builder.h>
#include <spa/graph.h>
#include <spa/graph-scheduler1.h>
@@ -55,6 +54,7 @@ struct type {
uint32_t props_volume;
uint32_t props_min_latency;
uint32_t props_live;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -73,6 +73,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->props_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
type->props_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency);
type->props_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -385,19 +386,26 @@ static int make_nodes(struct data *data)
static int negotiate_formats(struct data *data)
{
int res;
- struct spa_format *format;
+ struct spa_pod_object *format;
struct spa_pod_builder b = { 0 };
uint8_t buffer[256];
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- format = spa_pod_builder_format(&b,
- data->type.format,
- data->type.media_type.binary, data->type.media_subtype.raw);
-
- if ((res = spa_node_port_set_format(data->sink, SPA_DIRECTION_INPUT, 0, 0, format)) < 0)
+ format = spa_pod_builder_object(&b,
+ 0, data->type.format,
+ "I", data->type.media_type.binary,
+ "I", data->type.media_subtype.raw);
+
+ if ((res = spa_node_port_set_param(data->sink,
+ SPA_DIRECTION_INPUT, 0,
+ data->type.param.idFormat, 0,
+ format)) < 0)
return res;
- if ((res = spa_node_port_set_format(data->source, SPA_DIRECTION_OUTPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->source,
+ SPA_DIRECTION_OUTPUT, 0,
+ data->type.param.idFormat, 0,
+ format)) < 0)
return res;
init_buffer(data, data->source_buffers, data->source_buffer, 1, BUFFER_SIZE);
diff --git a/spa/tests/test-props.c b/spa/tests/test-props.c
index 0f9e2d51..81f63c33 100644
--- a/spa/tests/test-props.c
+++ b/spa/tests/test-props.c
@@ -29,7 +29,6 @@
#include <spa/node.h>
#include <spa/loop.h>
#include <spa/video/format-utils.h>
-#include <spa/format-builder.h>
#include <lib/debug.h>
@@ -187,9 +186,12 @@ static inline void type_init(struct spa_type_map *map)
static void do_static_struct(struct spa_type_map *map)
{
struct _test_format {
- struct spa_format fmt;
+ struct spa_pod_object fmt;
struct {
+ struct spa_pod_id media_type SPA_ALIGNED(8);
+ struct spa_pod_id media_subtype SPA_ALIGNED(8);
+
struct spa_pod_prop prop_format SPA_ALIGNED(8);
struct {
uint32_t def_format;
@@ -211,9 +213,12 @@ static void do_static_struct(struct spa_type_map *map)
} framerate_vals;
} props;
} test_format = {
- SPA_FORMAT_INIT(sizeof(test_format.props) + sizeof(struct spa_format_body),
- type.format, type.media_type.video, type.media_subtype.raw),
+ SPA_POD_OBJECT_INIT(sizeof(test_format.props) + sizeof(struct spa_pod_object_body),
+ 0, type.format),
{
+ SPA_POD_ID_INIT(type.media_type.video),
+ SPA_POD_ID_INIT(type.media_subtype.raw),
+
SPA_POD_PROP_INIT(sizeof(test_format.props.format_vals) +
sizeof(struct spa_pod_prop_body),
type.format_video.format,
@@ -245,23 +250,23 @@ static void do_static_struct(struct spa_type_map *map)
}
};
- spa_debug_pod(&test_format.fmt.pod);
- spa_debug_format(&test_format.fmt);
+ spa_debug_pod(&test_format.fmt.pod, 0);
+ spa_debug_pod(&test_format.fmt.pod, SPA_DEBUG_FLAG_FORMAT);
{
uint32_t format = -1;
int res;
struct spa_fraction frac = { -1, -1 };
- res = spa_format_parse(&test_format.fmt,
+ res = spa_pod_object_parse(&test_format.fmt,
":",type.format_video.format, "I", &format,
":",type.format_video.framerate, "F", &frac, NULL);
printf("%d format %d num %d denom %d\n", res, format, frac.num, frac.denom);
- spa_format_fixate(&test_format.fmt);
+ spa_pod_object_fixate(&test_format.fmt);
- res = spa_format_parse(&test_format.fmt,
+ res = spa_pod_object_parse(&test_format.fmt,
":",type.format_video.format, "I", &format,
":",type.format_video.framerate, "F", &frac, NULL);
@@ -275,7 +280,7 @@ int main(int argc, char *argv[])
struct spa_pod_builder b = { NULL, };
struct spa_pod_frame f[2];
uint8_t buffer[1024];
- struct spa_format *fmt;
+ struct spa_pod_object *fmt;
struct spa_type_map *map = &default_map.map;
type_init(map);
@@ -283,10 +288,12 @@ int main(int argc, char *argv[])
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- fmt = SPA_MEMBER(buffer, spa_pod_builder_push_format(&b, &f[0], type.format,
- type.media_type.video,
- type.media_subtype.raw),
- struct spa_format);
+ fmt = SPA_MEMBER(buffer, spa_pod_builder_push_object(&b, &f[0], 0, type.format),
+ struct spa_pod_object);
+
+ spa_pod_builder_id(&b, type.media_type.video);
+ spa_pod_builder_id(&b, type.media_subtype.raw);
+
spa_pod_builder_push_prop(&b, &f[1], type.format_video.format,
SPA_POD_PROP_RANGE_ENUM | SPA_POD_PROP_FLAG_UNSET);
spa_pod_builder_id(&b, type.video_format.I420);
@@ -312,13 +319,14 @@ int main(int argc, char *argv[])
spa_pod_builder_pop(&b, &f[0]);
- spa_debug_pod(&fmt->pod);
+ spa_debug_pod(&fmt->pod, 0);
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- fmt = spa_pod_builder_format(&b,
- type.format,
- type.media_type.video, type.media_subtype.raw,
+ fmt = spa_pod_builder_object(&b,
+ 0, type.format,
+ "I", type.media_type.video,
+ "I", type.media_subtype.raw,
":", type.format_video.format, "Ieu", type.video_format.I420,
2, type.video_format.I420,
type.video_format.YUY2,
@@ -329,8 +337,8 @@ int main(int argc, char *argv[])
2, &SPA_FRACTION(0,1),
&SPA_FRACTION(INT32_MAX,1));
- spa_debug_pod(&fmt->pod);
- spa_debug_format(fmt);
+ spa_debug_pod(&fmt->pod, 0);
+ spa_debug_pod(&fmt->pod, SPA_DEBUG_FLAG_FORMAT);
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@@ -359,8 +367,8 @@ int main(int argc, char *argv[])
&SPA_FRACTION(INT32_MAX,1),
">", NULL);
- spa_debug_pod(&fmt->pod);
- spa_debug_format(fmt);
+ spa_debug_pod(&fmt->pod, 0);
+ spa_debug_pod(&fmt->pod, SPA_DEBUG_FLAG_FORMAT);
do_static_struct(map);
diff --git a/spa/tests/test-props2.c b/spa/tests/test-props2.c
index b2408e8b..691a7f9c 100644
--- a/spa/tests/test-props2.c
+++ b/spa/tests/test-props2.c
@@ -89,11 +89,11 @@ int main(int argc, char *argv[])
spa_pod_builder_pop(&b, &frame[0]);
obj = SPA_POD_BUILDER_DEREF(&b, frame[0].ref, struct spa_pod);
- spa_debug_pod(obj);
+ spa_debug_pod(obj, 0);
struct spa_pod_prop *p = spa_pod_object_find_prop((struct spa_pod_object *) obj, 4);
printf("%d %d\n", p->body.key, p->body.flags);
- spa_debug_pod(&p->body.value);
+ spa_debug_pod(&p->body.value, 0);
obj = SPA_POD_BUILDER_DEREF(&b, frame[2].ref, struct spa_pod);
diff --git a/spa/tests/test-props5.c b/spa/tests/test-props5.c
index ad9080ec..e62e17a9 100644
--- a/spa/tests/test-props5.c
+++ b/spa/tests/test-props5.c
@@ -53,7 +53,7 @@ int main(int argc, char *argv[])
2, &SPA_FRACTION(0,1),
&SPA_FRACTION(INT32_MAX, 1),
">", NULL);
- spa_debug_pod(fmt);
+ spa_debug_pod(fmt, 0);
spa_pod_parser_pod(&prs, fmt);
res = spa_pod_parser_get(&prs,
@@ -68,7 +68,7 @@ int main(int argc, char *argv[])
printf("media-type:%d media-subtype:%d\n", media_type, media_subtype);
printf("framerate:\n");
if (pod)
- spa_debug_pod(pod);
+ spa_debug_pod(pod, 0);
printf("format: %d\n", fmt_value);
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
" P", NULL,
" [ i", 44, "i",45,"]"
">", NULL);
- spa_debug_pod(pod);
+ spa_debug_pod(pod, 0);
spa_pod_parser_pod(&prs, pod);
res = spa_pod_parser_get(&prs,
diff --git a/spa/tests/test-ringbuffer.c b/spa/tests/test-ringbuffer.c
index 897b4afa..bc75197d 100644
--- a/spa/tests/test-ringbuffer.c
+++ b/spa/tests/test-ringbuffer.c
@@ -32,7 +32,6 @@
#include <spa/type-map-impl.h>
#include <spa/audio/format-utils.h>
#include <spa/format-utils.h>
-#include <spa/format-builder.h>
#include <lib/debug.h>
#include <lib/props.h>
@@ -49,6 +48,7 @@ struct type {
uint32_t props_volume;
uint32_t props_min_latency;
uint32_t props_live;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -69,6 +69,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->props_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
type->props_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency);
type->props_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -275,7 +276,7 @@ do_invoke(struct spa_loop *loop,
static int make_nodes(struct data *data, const char *device)
{
int res;
- struct spa_props *props;
+ struct spa_pod_object *props;
struct spa_pod_builder b = { 0 };
uint8_t buffer[128];
@@ -287,12 +288,12 @@ static int make_nodes(struct data *data, const char *device)
spa_node_set_callbacks(data->sink, &sink_callbacks, data);
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- props = spa_pod_builder_props(&b,
- data->type.props,
+ props = spa_pod_builder_object(&b,
+ 0, data->type.props,
":", data->type.props_device, "s", device ? device : "hw:0",
":", data->type.props_min_latency, "i", 64);
- if ((res = spa_node_set_props(data->sink, props)) < 0)
+ if ((res = spa_node_set_param(data->sink, data->type.param.idProps, 0, props)) < 0)
printf("got set_props error %d\n", res);
if ((res = make_node(data, &data->source,
@@ -303,11 +304,11 @@ static int make_nodes(struct data *data, const char *device)
}
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- props = spa_pod_builder_props(&b,
- data->type.props,
+ props = spa_pod_builder_object(&b,
+ 0, data->type.props,
":", data->type.props_live, "b", false);
- if ((res = spa_node_set_props(data->source, props)) < 0)
+ if ((res = spa_node_set_param(data->source, data->type.param.idProps, 0, props)) < 0)
printf("got set_props error %d\n", res);
return res;
}
@@ -315,27 +316,36 @@ static int make_nodes(struct data *data, const char *device)
static int negotiate_formats(struct data *data)
{
int res;
- struct spa_format *format, *filter;
- uint32_t state = 0;
+ struct spa_pod_object *format, *filter;
+ uint32_t state = 0, ref;
struct spa_pod_builder b = { 0 };
- uint8_t buffer[256];
+ uint8_t buffer[4096];
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- filter = spa_pod_builder_format(&b,
- data->type.format,
- data->type.media_type.audio, data->type.media_subtype.raw,
+
+ filter = spa_pod_builder_object(&b,
+ 0, data->type.format,
+ "I", data->type.media_type.audio,
+ "I", data->type.media_subtype.raw,
":", data->type.format_audio.format, "I", data->type.audio_format.S16,
":", data->type.format_audio.layout, "i", SPA_AUDIO_LAYOUT_INTERLEAVED,
":", data->type.format_audio.rate, "i", 44100,
":", data->type.format_audio.channels, "i", 2);
- if ((res =
- spa_node_port_enum_formats(data->sink, SPA_DIRECTION_INPUT, 0, &format, filter,
- state)) < 0)
+ ref = b.offset;
+
+ if ((res = spa_node_port_enum_params(data->sink,
+ SPA_DIRECTION_INPUT, 0,
+ data->type.param.idEnumFormat, &state,
+ filter, &b)) < 0)
return res;
+ format = SPA_POD_BUILDER_DEREF(&b, ref, struct spa_pod_object);
- if ((res = spa_node_port_set_format(data->sink, SPA_DIRECTION_INPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->sink,
+ SPA_DIRECTION_INPUT, 0,
+ data->type.param.idFormat, 0,
+ format)) < 0)
return res;
data->source_sink_io[0] = SPA_PORT_IO_INIT;
@@ -343,7 +353,10 @@ static int negotiate_formats(struct data *data)
spa_node_port_set_io(data->source, SPA_DIRECTION_OUTPUT, 0, &data->source_sink_io[0]);
spa_node_port_set_io(data->sink, SPA_DIRECTION_INPUT, 0, &data->source_sink_io[0]);
- if ((res = spa_node_port_set_format(data->source, SPA_DIRECTION_OUTPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->source,
+ SPA_DIRECTION_OUTPUT, 0,
+ data->type.param.idFormat, 0,
+ format)) < 0)
return res;
init_buffer(data, data->source_buffers, data->source_buffer, 1, BUFFER_SIZE);
diff --git a/spa/tests/test-v4l2.c b/spa/tests/test-v4l2.c
index e7264ae7..9a41e116 100644
--- a/spa/tests/test-v4l2.c
+++ b/spa/tests/test-v4l2.c
@@ -33,7 +33,6 @@
#include <spa/node.h>
#include <spa/loop.h>
#include <spa/video/format-utils.h>
-#include <spa/format-builder.h>
#include <lib/debug.h>
#include <lib/props.h>
@@ -46,6 +45,7 @@ struct type {
uint32_t format;
uint32_t props_device;
uint32_t SDL_Texture;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -63,6 +63,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
type->props_device = spa_type_map_get_id(map, SPA_TYPE_PROPS__device);
type->SDL_Texture = spa_type_map_get_id(map, SPA_TYPE_POINTER_BASE "SDL_Texture");
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -297,7 +298,7 @@ do_invoke(struct spa_loop *loop,
static int make_nodes(struct data *data, const char *device)
{
int res;
- struct spa_props *props;
+ struct spa_pod_object *props;
struct spa_pod_builder b = { 0 };
uint8_t buffer[256];
@@ -311,11 +312,11 @@ static int make_nodes(struct data *data, const char *device)
spa_node_set_callbacks(data->source, &source_callbacks, data);
spa_pod_builder_init(&b, buffer, sizeof(buffer));
- props = spa_pod_builder_props(&b,
- data->type.props,
+ props = spa_pod_builder_object(&b,
+ 0, data->type.props,
":", data->type.props_device, "s", device ? device : "/dev/video0");
- if ((res = spa_node_set_props(data->source, props)) < 0)
+ if ((res = spa_node_set_param(data->source, data->type.param.idProps, 0, props)) < 0)
printf("got set_props error %d\n", res);
return res;
@@ -386,7 +387,7 @@ static int negotiate_formats(struct data *data)
{
int res;
const struct spa_port_info *info;
- struct spa_format *format;
+ struct spa_pod_object *format;
uint8_t buffer[256];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
@@ -404,15 +405,19 @@ static int negotiate_formats(struct data *data)
return res;
#else
- format = spa_pod_builder_format(&b,
- data->type.format,
- data->type.media_type.video, data->type.media_subtype.raw,
+ format = spa_pod_builder_object(&b,
+ 0, data->type.format,
+ "I", data->type.media_type.video,
+ "I", data->type.media_subtype.raw,
":", data->type.format_video.format, "I", data->type.video_format.YUY2,
":", data->type.format_video.size, "R", &SPA_RECTANGLE(320, 240),
":", data->type.format_video.framerate, "F", &SPA_FRACTION(25,1));
#endif
- if ((res = spa_node_port_set_format(data->source, SPA_DIRECTION_OUTPUT, 0, 0, format)) < 0)
+ if ((res = spa_node_port_set_param(data->source,
+ SPA_DIRECTION_OUTPUT, 0,
+ data->type.param.idFormat, 0,
+ (struct spa_pod_object*)format)) < 0)
return res;
if ((res = spa_node_port_get_info(data->source, SPA_DIRECTION_OUTPUT, 0, &info)) < 0)
diff --git a/spa/tools/spa-inspect.c b/spa/tools/spa-inspect.c
index 7a355c08..c3ad604f 100644
--- a/spa/tools/spa-inspect.c
+++ b/spa/tools/spa-inspect.c
@@ -37,6 +37,7 @@ static SPA_LOG_IMPL(default_log);
struct type {
uint32_t node;
uint32_t clock;
+ struct spa_type_param param;
};
struct data {
@@ -54,40 +55,51 @@ inspect_port(struct data *data, struct spa_node *node, enum spa_direction direct
uint32_t port_id)
{
int res;
- struct spa_format *format;
- uint32_t index;
-
- for (index = 0;; index++) {
- if ((res =
- spa_node_port_enum_formats(node, direction, port_id, &format, NULL,
- index)) < 0) {
+ uint32_t idx1, idx2;
+ uint32_t buffer[4096];
+ struct spa_pod_builder b = { 0 };
+
+ for (idx1 = 0;;) {
+ struct spa_pod_object *param;
+ uint32_t id;
+
+ spa_pod_builder_init(&b, buffer, sizeof(buffer));
+ if ((res = spa_node_port_enum_params(node,
+ direction, port_id,
+ data->type.param.idList, &idx1,
+ NULL, &b)) < 0) {
if (res != SPA_RESULT_ENUM_END)
printf("got error %d\n", res);
break;
}
- if (format)
- spa_debug_format(format);
- }
-
-
- for (index = 0;; index++) {
- struct spa_param *param;
-
- if ((res = spa_node_port_enum_params(node, direction, port_id, index, &param)) < 0) {
- if (res != SPA_RESULT_ENUM_END)
- printf("port_enum_params error: %d\n", res);
- break;
+ param = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
+ spa_debug_pod(&param->pod, 0);
+
+ spa_pod_object_parse(param,
+ ":", data->type.param.listId, "I", &id,
+ NULL);
+
+ for (idx2 = 0;;) {
+ spa_pod_builder_init(&b, buffer, sizeof(buffer));
+ if ((res = spa_node_port_enum_params(node,
+ direction, port_id,
+ id, &idx2,
+ NULL, &b)) < 0) {
+ if (res != SPA_RESULT_ENUM_END)
+ printf("got error %d\n", res);
+ break;
+ }
+ param = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
+ spa_debug_pod(&param->pod, 0);
}
- spa_debug_param(param);
}
}
static void inspect_node(struct data *data, struct spa_node *node)
{
int res;
- uint32_t i, n_input, max_input, n_output, max_output;
+ uint32_t i, n_input, max_input, n_output, max_output, index = 0;
uint32_t *in_ports, *out_ports;
- struct spa_props *props;
printf("node info:\n");
if (node->info)
@@ -95,10 +107,19 @@ static void inspect_node(struct data *data, struct spa_node *node)
else
printf(" none\n");
- if ((res = spa_node_get_props(node, &props)) < 0)
- printf("can't get properties: %d\n", res);
- else
- spa_debug_props(props);
+ for (index = 0;;) {
+ uint8_t buf[2048];
+ struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
+ struct spa_pod_object *param;
+
+ if ((res = spa_node_enum_params(node, SPA_ID_INVALID, &index, NULL, &b)) < 0) {
+ if (res != SPA_RESULT_ENUM_END)
+ printf("enum_params error: %d\n", res);
+ break;
+ }
+ param = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
+ spa_debug_pod(&param->pod, 0);
+ }
if ((res = spa_node_get_n_ports(node, &n_input, &max_input, &n_output, &max_output)) < 0) {
printf("can't get n_ports: %d\n", res);
@@ -224,6 +245,7 @@ int main(int argc, char *argv[])
data.type.node = spa_type_map_get_id(data.map, SPA_TYPE__Node);
data.type.clock = spa_type_map_get_id(data.map, SPA_TYPE__Clock);
+ spa_type_param_map(data.map, &data.type.param);
if ((handle = dlopen(argv[1], RTLD_NOW)) == NULL) {
printf("can't load %s\n", argv[1]);
diff --git a/spa/tools/spa-monitor.c b/spa/tools/spa-monitor.c
index 2e31b69b..b20a2a17 100644
--- a/spa/tools/spa-monitor.c
+++ b/spa/tools/spa-monitor.c
@@ -60,7 +60,7 @@ struct data {
static void inspect_item(struct data *data, struct spa_monitor_item *item)
{
- spa_debug_pod(&item->object.pod);
+ spa_debug_pod(&item->object.pod, 0);
}
static void on_monitor_event(void *_data, struct spa_event *event)
diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in
index 19f47ccc..9fda6a0d 100644
--- a/src/daemon/pipewire.conf.in
+++ b/src/daemon/pipewire.conf.in
@@ -1,7 +1,7 @@
#load-module libpipewire-module-protocol-dbus
load-module libpipewire-module-protocol-native
load-module libpipewire-module-suspend-on-idle
-#load-module libpipewire-module-spa-monitor alsa/libspa-alsa alsa-monitor alsa
+load-module libpipewire-module-spa-monitor alsa/libspa-alsa alsa-monitor alsa
load-module libpipewire-module-spa-monitor v4l2/libspa-v4l2 v4l2-monitor v4l2
#load-module libpipewire-module-spa-node videotestsrc/libspa-videotestsrc videotestsrc videotestsrc Spa:POD:Object:Props:patternType=Spa:POD:Object:Props:patternType:snow
load-module libpipewire-module-autolink
diff --git a/src/examples/export-sink.c b/src/examples/export-sink.c
index c826937e..47500bc3 100644
--- a/src/examples/export-sink.c
+++ b/src/examples/export-sink.c
@@ -25,7 +25,6 @@
#include <spa/type-map.h>
#include <spa/format-utils.h>
#include <spa/video/format-utils.h>
-#include <spa/format-builder.h>
#include <spa/props.h>
#include <spa/lib/debug.h>
@@ -90,7 +89,6 @@ struct data {
struct spa_video_info_raw format;
int32_t stride;
- uint8_t params_buffer[1024];
struct spa_param *params[2];
struct spa_buffer *buffers[32];
@@ -223,27 +221,42 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction,
return SPA_RESULT_OK;
}
-static int impl_port_enum_formats(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
+ const struct spa_port_info **info)
+{
+ struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
+
+ d->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
+ d->port_info.rate = 0;
+ d->port_info.props = NULL;
+
+ *info = &d->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 data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
- struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer));
struct spa_pod_frame f[2];
SDL_RendererInfo info;
int i, c;
- if (index != 0)
+ if (*index != 0)
return SPA_RESULT_ENUM_END;
SDL_GetRendererInfo(d->renderer, &info);
- spa_pod_builder_push_format(&b, &f[0], d->type.format,
- d->type.media_type.video,
- d->type.media_subtype.raw);
+ spa_pod_builder_push_object(builder, &f[0],
+ d->t->param.idEnumFormat, d->type.format);
+ spa_pod_builder_id(builder, d->type.media_type.video);
+ spa_pod_builder_id(builder, d->type.media_subtype.raw);
- spa_pod_builder_push_prop(&b, &f[1], d->type.format_video.format,
+ spa_pod_builder_push_prop(builder, &f[1], d->type.format_video.format,
SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_ENUM);
for (i = 0, c = 0; i < info.num_texture_formats; i++) {
@@ -251,18 +264,18 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire
if (id == 0)
continue;
if (c++ == 0)
- spa_pod_builder_id(&b, id);
- spa_pod_builder_id(&b, id);
+ spa_pod_builder_id(builder, id);
+ spa_pod_builder_id(builder, id);
}
for (i = 0; i < SPA_N_ELEMENTS(video_formats); i++) {
uint32_t id =
*SPA_MEMBER(&d->type.video_format, video_formats[i].id,
uint32_t);
if (id != d->type.video_format.UNKNOWN)
- spa_pod_builder_id(&b, id);
+ spa_pod_builder_id(builder, id);
}
- spa_pod_builder_pop(&b, &f[1]);
- spa_pod_builder_add(&b,
+ spa_pod_builder_pop(builder, &f[1]);
+ spa_pod_builder_add(builder,
":", d->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT),
2, &SPA_RECTANGLE(1,1),
&SPA_RECTANGLE(info.max_texture_width,
@@ -271,27 +284,106 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire
2, &SPA_FRACTION(0,1),
&SPA_FRACTION(30,1),
NULL);
- spa_pod_builder_pop(&b, &f[0]);
- *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format);
+ spa_pod_builder_pop(builder, &f[0]);
+
+ (*index)++;
+
+ return SPA_RESULT_OK;
+}
- spa_debug_format(*format);
+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 data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
+
+ if (*index != 0 || d->format.format == 0)
+ return SPA_RESULT_ENUM_END;
+
+ spa_pod_builder_object(builder,
+ d->t->param.idFormat, d->type.format,
+ "I", d->type.media_type.video,
+ "I", d->type.media_subtype.raw,
+ ":", d->type.format_video.format, "I", d->format.format,
+ ":", d->type.format_video.size, "R", &d->format.size,
+ ":", d->type.format_video.framerate, "F", &d->format.framerate);
+
+ (*index)++;
return SPA_RESULT_OK;
}
-static int impl_port_set_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- uint32_t flags, const struct spa_format *format)
+static int impl_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
struct pw_type *t = d->t;
- struct spa_pod_builder b = { NULL };
+
+ if (id == t->param.idList) {
+ uint32_t list[] = { t->param.idEnumFormat,
+ t->param.idFormat,
+ t->param.idBuffers,
+ t->param.idMeta };
+
+ if (*index < SPA_N_ELEMENTS(list))
+ 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);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ if (*index != 0)
+ return SPA_RESULT_ENUM_END;
+
+ spa_pod_builder_object(builder,
+ id, t->param_alloc_buffers.Buffers,
+ ":", t->param_alloc_buffers.size, "i", d->stride * d->format.size.height,
+ ":", t->param_alloc_buffers.stride, "i", d->stride,
+ ":", t->param_alloc_buffers.buffers, "iru", 32,
+ 2, 2, 32,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ if (*index != 0)
+ return SPA_RESULT_ENUM_END;
+
+ 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));
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
+ (*index)++;
+
+ 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 data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
Uint32 sdl_format;
void *dest;
if (format == NULL)
return SPA_RESULT_OK;
- spa_debug_format(format);
+ spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
spa_format_video_raw_parse(format, &d->format, &d->type.format_video);
@@ -307,64 +399,22 @@ static int impl_port_set_format(struct spa_node *node, enum spa_direction direct
SDL_LockTexture(d->texture, NULL, &dest, &d->stride);
SDL_UnlockTexture(d->texture);
- spa_pod_builder_init(&b, d->params_buffer, sizeof(d->params_buffer));
- d->params[0] = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "i", d->stride * d->format.size.height,
- ":", t->param_alloc_buffers.stride, "i", d->stride,
- ":", t->param_alloc_buffers.buffers, "iru", 32,
- 2, 2, 32,
- ":", t->param_alloc_buffers.align, "i", 16);
-
- d->params[1] = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
-
- return SPA_RESULT_OK;
-}
-
-static int impl_port_get_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- const struct spa_format **format)
-{
- struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
- struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer));
-
- *format = spa_pod_builder_format(&b, d->type.format,
- d->type.media_type.video,
- d->type.media_subtype.raw,
- ":", d->type.format_video.format, "I", d->format.format,
- ":", d->type.format_video.size, "R", &d->format.size,
- ":", d->type.format_video.framerate, "F", &d->format.framerate);
-
- return SPA_RESULT_OK;
-}
-
-static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- const struct spa_port_info **info)
-{
- struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
-
- d->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
- d->port_info.rate = 0;
- d->port_info.props = NULL;
-
- *info = &d->port_info;
-
return SPA_RESULT_OK;
}
-static int impl_port_enum_params(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- uint32_t index, struct spa_param **param)
+static int impl_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
+ struct pw_type *t = d->t;
- if (index >= 2)
- return SPA_RESULT_ENUM_END;
-
- *param = d->params[index];
-
- return SPA_RESULT_OK;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int impl_port_use_buffers(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
@@ -443,11 +493,9 @@ static const struct spa_node impl_node = {
.get_n_ports = impl_get_n_ports,
.get_port_ids = impl_get_port_ids,
.port_set_io = impl_port_set_io,
- .port_enum_formats = impl_port_enum_formats,
- .port_set_format = impl_port_set_format,
- .port_get_format = impl_port_get_format,
.port_get_info = impl_port_get_info,
.port_enum_params = impl_port_enum_params,
+ .port_set_param = impl_port_set_param,
.port_use_buffers = impl_port_use_buffers,
.process_input = impl_node_process_input,
};
diff --git a/src/examples/export-source.c b/src/examples/export-source.c
index 075a9022..43980bc8 100644
--- a/src/examples/export-source.c
+++ b/src/examples/export-source.c
@@ -24,7 +24,6 @@
#include <spa/type-map.h>
#include <spa/format-utils.h>
#include <spa/audio/format-utils.h>
-#include <spa/format-builder.h>
#include <spa/props.h>
#include <spa/lib/debug.h>
@@ -88,8 +87,6 @@ struct data {
struct spa_audio_info_raw format;
- uint8_t params_buffer[1024];
-
struct buffer buffers[32];
int n_buffers;
struct spa_list empty;
@@ -141,117 +138,178 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction,
return SPA_RESULT_OK;
}
-static int impl_port_enum_formats(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
+ const struct spa_port_info **info)
+{
+ struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
+
+ d->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
+ d->port_info.rate = 0;
+ d->port_info.props = NULL;
+
+ *info = &d->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 data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
- struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer));
- if (index != 0)
+ if (*index != 0)
return SPA_RESULT_ENUM_END;
- *format = spa_pod_builder_format(&b, d->type.format,
- d->type.media_type.audio, d->type.media_subtype.raw,
+ spa_pod_builder_object(builder,
+ d->t->param.idEnumFormat, d->type.format,
+ "I", d->type.media_type.audio,
+ "I", d->type.media_subtype.raw,
":", d->type.format_audio.format, "I", d->type.audio_format.S16,
":", d->type.format_audio.channels, "i", 2,
":", d->type.format_audio.rate, "i", 44100);
- spa_debug_format(*format);
+ (*index)++;
return SPA_RESULT_OK;
}
-static int impl_port_set_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- uint32_t flags, const struct spa_format *format)
+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 data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
- if (format == NULL)
- return SPA_RESULT_OK;
+ if (*index != 0)
+ return SPA_RESULT_ENUM_END;
- spa_debug_format(format);
+ if (d->format.format == 0)
+ return SPA_RESULT_ENUM_END;
- if (spa_format_audio_raw_parse(format, &d->format, &d->type.format_audio) < 0)
- return SPA_RESULT_INVALID_MEDIA_TYPE;
+ spa_pod_builder_object(builder,
+ d->t->param.idFormat, d->type.format,
+ "I", d->type.media_type.audio,
+ "I", d->type.media_subtype.raw,
+ ":", d->type.format_audio.format, "I", d->format.format,
+ ":", d->type.format_audio.channels, "i", d->format.channels,
+ ":", d->type.format_audio.rate, "i", d->format.rate);
- if (d->format.format != d->type.audio_format.S16)
- return SPA_RESULT_ERROR;
+ (*index)++;
return SPA_RESULT_OK;
}
-static int impl_port_get_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- const struct spa_format **format)
+static int impl_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
- struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer));
+ struct pw_type *t = d->t;
- *format = spa_pod_builder_format(&b, d->type.format,
- d->type.media_type.audio, d->type.media_subtype.raw,
- ":", d->type.format_audio.format, "I", d->format.format,
- ":", d->type.format_audio.channels, "i", d->format.channels,
- ":", d->type.format_audio.rate, "i", d->format.rate);
+ if (id == t->param.idList) {
+ uint32_t list[] = { t->param.idEnumFormat,
+ t->param.idFormat,
+ t->param.idBuffers,
+ t->param.idMeta };
+
+ if (*index < SPA_N_ELEMENTS(list))
+ 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);
+ }
+ else if (id == t->param.idFormat) {
+ return port_get_format(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ spa_pod_builder_object(builder,
+ id, t->param_alloc_buffers.Buffers,
+ ":", t->param_alloc_buffers.size, "iru", 1024,
+ 2, 32, 4096,
+ ":", t->param_alloc_buffers.stride, "i", 0,
+ ":", t->param_alloc_buffers.buffers, "iru", 2,
+ 2, 2, 32,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ switch (*index) {
+ case 0:
+ 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,
+ 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),
+ ":", t->param_alloc_meta_enable.ringbufferSize, "ir", 1024 * 4,
+ 2, 16 * 4, INT32_MAX / 4,
+ ":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
+ ":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
+ ":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
+ break;
+ default:
+ return SPA_RESULT_ENUM_END;
+ }
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
+ (*index)++;
return SPA_RESULT_OK;
}
-static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- const struct spa_port_info **info)
+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 data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
- d->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
- d->port_info.rate = 0;
- d->port_info.props = NULL;
+ if (format == NULL) {
+ d->format.format = 0;
+ return SPA_RESULT_OK;
+ }
- *info = &d->port_info;
+ spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
+
+ if (spa_format_audio_raw_parse(format, &d->format, &d->type.format_audio) < 0)
+ return SPA_RESULT_INVALID_MEDIA_TYPE;
+
+ if (d->format.format != d->type.audio_format.S16)
+ return SPA_RESULT_ERROR;
return SPA_RESULT_OK;
}
-static int impl_port_enum_params(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- uint32_t index, struct spa_param **param)
+static int impl_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
struct pw_type *t = d->t;
- struct spa_pod_builder b = { NULL };
-
- spa_pod_builder_init(&b, d->params_buffer, sizeof(d->params_buffer));
- switch (index) {
- case 0:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "iru", 1024,
- 2, 32, 4096,
- ":", t->param_alloc_buffers.stride, "i", 0,
- ":", t->param_alloc_buffers.buffers, "iru", 2,
- 2, 2, 32,
- ":", t->param_alloc_buffers.align, "i", 16);
- break;
- case 1:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- break;
- case 2:
- *param = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_ringbuffer),
- ":", t->param_alloc_meta_enable.ringbufferSize, "ir", 1024 * 4,
- 2, 16 * 4, INT32_MAX / 4,
- ":", t->param_alloc_meta_enable.ringbufferStride, "i", 0,
- ":", t->param_alloc_meta_enable.ringbufferBlocks, "i", 1,
- ":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
- break;
- default:
- return SPA_RESULT_ENUM_END;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
}
- return SPA_RESULT_OK;
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int impl_port_use_buffers(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
@@ -378,11 +436,9 @@ static const struct spa_node impl_node = {
.get_n_ports = impl_get_n_ports,
.get_port_ids = impl_get_port_ids,
.port_set_io = impl_port_set_io,
- .port_enum_formats = impl_port_enum_formats,
- .port_set_format = impl_port_set_format,
- .port_get_format = impl_port_get_format,
.port_get_info = impl_port_get_info,
.port_enum_params = impl_port_enum_params,
+ .port_set_param = impl_port_set_param,
.port_use_buffers = impl_port_use_buffers,
.port_reuse_buffer = impl_port_reuse_buffer,
.process_output = impl_node_process_output,
diff --git a/src/examples/export-spa.c b/src/examples/export-spa.c
index 9ae770b7..7611b8a2 100644
--- a/src/examples/export-spa.c
+++ b/src/examples/export-spa.c
@@ -24,7 +24,6 @@
#include <spa/type-map.h>
#include <spa/format-utils.h>
#include <spa/video/format-utils.h>
-#include <spa/format-builder.h>
#include <spa/props.h>
#include <spa/lib/debug.h>
diff --git a/src/examples/local-v4l2.c b/src/examples/local-v4l2.c
index 7880bab8..b5a99123 100644
--- a/src/examples/local-v4l2.c
+++ b/src/examples/local-v4l2.c
@@ -25,7 +25,6 @@
#include <spa/type-map.h>
#include <spa/format-utils.h>
#include <spa/video/format-utils.h>
-#include <spa/format-builder.h>
#include <spa/props.h>
#include <spa/lib/debug.h>
@@ -85,14 +84,9 @@ struct data {
const struct spa_node_callbacks *callbacks;
void *callbacks_data;
- uint8_t buffer[1024];
-
struct spa_video_info_raw format;
int32_t stride;
- uint8_t params_buffer[1024];
- struct spa_param *params[2];
-
struct spa_buffer *buffers[32];
int n_buffers;
};
@@ -223,27 +217,42 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction,
return SPA_RESULT_OK;
}
-static int impl_port_enum_formats(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
+ const struct spa_port_info **info)
+{
+ struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
+
+ d->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
+ d->port_info.rate = 0;
+ d->port_info.props = NULL;
+
+ *info = &d->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 data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
- struct spa_pod_builder b = SPA_POD_BUILDER_INIT(d->buffer, sizeof(d->buffer));
struct spa_pod_frame f[2];
SDL_RendererInfo info;
int i, c;
- if (index != 0)
+ if (*index != 0)
return SPA_RESULT_ENUM_END;
SDL_GetRendererInfo(d->renderer, &info);
- spa_pod_builder_push_format(&b, &f[0], d->type.format,
- d->type.media_type.video,
- d->type.media_subtype.raw);
+ spa_pod_builder_push_object(builder, &f[0],
+ d->t->param.idEnumFormat, d->type.format);
+ spa_pod_builder_id(builder, d->type.media_type.video);
+ spa_pod_builder_id(builder, d->type.media_subtype.raw);
- spa_pod_builder_push_prop(&b, &f[1], d->type.format_video.format,
+ spa_pod_builder_push_prop(builder, &f[1], d->type.format_video.format,
SPA_POD_PROP_FLAG_UNSET |
SPA_POD_PROP_RANGE_ENUM);
for (i = 0, c = 0; i < info.num_texture_formats; i++) {
@@ -251,19 +260,19 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire
if (id == 0)
continue;
if (c++ == 0)
- spa_pod_builder_id(&b, id);
- spa_pod_builder_id(&b, id);
+ spa_pod_builder_id(builder, id);
+ spa_pod_builder_id(builder, id);
}
for (i = 0; i < SPA_N_ELEMENTS(video_formats); i++) {
uint32_t id =
*SPA_MEMBER(&d->type.video_format, video_formats[i].id,
uint32_t);
if (id != d->type.video_format.UNKNOWN)
- spa_pod_builder_id(&b, id);
+ spa_pod_builder_id(builder, id);
}
- spa_pod_builder_pop(&b, &f[1]);
+ spa_pod_builder_pop(builder, &f[1]);
- spa_pod_builder_add(&b,
+ spa_pod_builder_add(builder,
":", d->type.format_video.size, "Rru", &SPA_RECTANGLE(WIDTH, HEIGHT),
2, &SPA_RECTANGLE(1,1),
&SPA_RECTANGLE(info.max_texture_width,
@@ -272,28 +281,64 @@ static int impl_port_enum_formats(struct spa_node *node, enum spa_direction dire
2, &SPA_FRACTION(0,1),
&SPA_FRACTION(30,1),
NULL);
- spa_pod_builder_pop(&b, &f[0]);
- *format = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format);
+ spa_pod_builder_pop(builder, &f[0]);
- spa_debug_format(*format);
+ (*index)++;
return SPA_RESULT_OK;
}
-static int impl_port_set_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- uint32_t flags, const struct spa_format *format)
+static int impl_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
struct pw_type *t = d->t;
- struct spa_pod_builder b = { NULL };
+
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idBuffers) {
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ spa_pod_builder_object(builder,
+ id, t->param_alloc_buffers.Buffers,
+ ":", t->param_alloc_buffers.size, "i", d->stride * d->format.size.height,
+ ":", t->param_alloc_buffers.stride, "i", d->stride,
+ ":", t->param_alloc_buffers.buffers, "iru", 2,
+ 2, 1, 32,
+ ":", t->param_alloc_buffers.align, "i", 16);
+ }
+ else if (id == t->param.idMeta) {
+ if (*index > 0)
+ return SPA_RESULT_ENUM_END;
+
+ 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));
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
+ (*index)++;
+ 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 data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
Uint32 sdl_format;
void *dest;
- if (format == NULL) {
+ if (format == NULL)
return SPA_RESULT_OK;
- }
- spa_debug_format(format);
+ spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
spa_format_video_raw_parse(format, &d->format, &d->type.format_video);
@@ -309,48 +354,22 @@ static int impl_port_set_format(struct spa_node *node, enum spa_direction direct
SDL_LockTexture(d->texture, NULL, &dest, &d->stride);
SDL_UnlockTexture(d->texture);
- spa_pod_builder_init(&b, d->params_buffer, sizeof(d->params_buffer));
- d->params[0] = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
- ":", t->param_alloc_buffers.size, "i", d->stride * d->format.size.height,
- ":", t->param_alloc_buffers.stride, "i", d->stride,
- ":", t->param_alloc_buffers.buffers, "iru", 2,
- 2, 1, 32,
- ":", t->param_alloc_buffers.align, "i", 16);
-
- d->params[1] = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
- ":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
- ":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
-
- return SPA_RESULT_OK;
-}
-
-static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- const struct spa_port_info **info)
-{
- struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
-
- d->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
- d->port_info.rate = 0;
- d->port_info.props = NULL;
-
- *info = &d->port_info;
-
return SPA_RESULT_OK;
}
-static int impl_port_enum_params(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- uint32_t index, struct spa_param **param)
+static int impl_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
+ struct pw_type *t = d->t;
- if (index >= 2)
- return SPA_RESULT_ENUM_END;
-
- *param = d->params[index];
-
- return SPA_RESULT_OK;
+ if (id == t->param.idFormat) {
+ return port_set_format(node, direction, port_id, flags, param);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
}
static int impl_port_use_buffers(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
@@ -425,10 +444,9 @@ static const struct spa_node impl_node = {
.get_n_ports = impl_get_n_ports,
.get_port_ids = impl_get_port_ids,
.port_set_io = impl_port_set_io,
- .port_enum_formats = impl_port_enum_formats,
- .port_set_format = impl_port_set_format,
.port_get_info = impl_port_get_info,
.port_enum_params = impl_port_enum_params,
+ .port_set_param = impl_port_set_param,
.port_use_buffers = impl_port_use_buffers,
.process_input = impl_node_process_input,
};
diff --git a/src/examples/video-play.c b/src/examples/video-play.c
index 2dafc3e8..733c0c86 100644
--- a/src/examples/video-play.c
+++ b/src/examples/video-play.c
@@ -25,7 +25,6 @@
#include <spa/type-map.h>
#include <spa/format-utils.h>
#include <spa/video/format-utils.h>
-#include <spa/format-builder.h>
#include <spa/props.h>
#include <spa/lib/debug.h>
@@ -34,6 +33,7 @@
struct type {
uint32_t format;
uint32_t props;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -46,6 +46,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
{
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -234,28 +235,26 @@ static Uint32 id_to_sdl_format(struct data *data, uint32_t id)
}
static void
-on_stream_format_changed(void *_data, struct spa_format *format)
+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 };
- struct spa_param *params[2];
+ struct spa_pod_object *params[2];
Uint32 sdl_format;
void *d;
if (format == NULL) {
- pw_stream_finish_format(stream, SPA_RESULT_OK, NULL, 0);
+ pw_stream_finish_format(stream, SPA_RESULT_OK, 0, NULL);
return;
}
- spa_debug_format(format);
-
spa_format_video_raw_parse(format, &data->format, &data->type.format_video);
sdl_format = id_to_sdl_format(data, data->format.format);
if (sdl_format == SDL_PIXELFORMAT_UNKNOWN) {
- pw_stream_finish_format(stream, SPA_RESULT_ERROR, NULL, 0);
+ pw_stream_finish_format(stream, SPA_RESULT_ERROR, 0, NULL);
return;
}
@@ -268,20 +267,20 @@ on_stream_format_changed(void *_data, struct spa_format *format)
SDL_UnlockTexture(data->texture);
spa_pod_builder_init(&b, data->params_buffer, sizeof(data->params_buffer));
- params[0] = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
+ 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,
":", t->param_alloc_buffers.stride, "i", data->stride,
":", t->param_alloc_buffers.buffers, "iru", 32,
2, 2, 32,
":", t->param_alloc_buffers.align, "i", 16);
- params[1] = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
+ params[1] = spa_pod_builder_object(&b,
+ t->param.idMeta, t->param_alloc_meta_enable.MetaEnable,
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- pw_stream_finish_format(stream, SPA_RESULT_OK, params, 2);
+ pw_stream_finish_format(stream, SPA_RESULT_OK, 2, params);
}
static const struct pw_stream_events stream_events = {
@@ -304,7 +303,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
case PW_REMOTE_STATE_CONNECTED:
{
- const struct spa_format *formats[1];
+ const struct spa_pod_object *params[1];
uint8_t buffer[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
struct spa_pod_frame f[2];
@@ -318,9 +317,10 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
SDL_GetRendererInfo(data->renderer, &info);
- spa_pod_builder_push_format(&b, &f[0], data->type.format,
- data->type.media_type.video,
- data->type.media_subtype.raw);
+ spa_pod_builder_push_object(&b, &f[0],
+ data->type.param.idEnumFormat, data->type.format);
+ spa_pod_builder_id(&b, data->type.media_type.video);
+ spa_pod_builder_id(&b, data->type.media_subtype.raw);
spa_pod_builder_push_prop(&b, &f[1], data->type.format_video.format,
SPA_POD_PROP_FLAG_UNSET |
@@ -351,10 +351,10 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
&SPA_RECTANGLE(30,1),
NULL);
spa_pod_builder_pop(&b, &f[0]);
- formats[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_format);
+ params[0] = SPA_POD_BUILDER_DEREF(&b, f[0].ref, struct spa_pod_object);
printf("supported formats:\n");
- spa_debug_format(formats[0]);
+ spa_debug_pod(&params[0]->pod, SPA_DEBUG_FLAG_FORMAT);
pw_stream_add_listener(data->stream,
&data->stream_listener,
@@ -363,8 +363,9 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
pw_stream_connect(data->stream,
PW_DIRECTION_INPUT,
- PW_STREAM_MODE_BUFFER,
- data->path, PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE, 1, formats);
+ data->path,
+ PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE,
+ 1, params);
break;
}
default:
diff --git a/src/examples/video-src.c b/src/examples/video-src.c
index 4e2b8a94..7d13e861 100644
--- a/src/examples/video-src.c
+++ b/src/examples/video-src.c
@@ -25,7 +25,6 @@
#include <spa/type-map.h>
#include <spa/format-utils.h>
#include <spa/video/format-utils.h>
-#include <spa/format-builder.h>
#include <spa/props.h>
#include <spa/lib/debug.h>
@@ -34,6 +33,7 @@
struct type {
uint32_t format;
uint32_t props;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_media_type media_type;
@@ -46,6 +46,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
{
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
type->props = spa_type_map_get_id(map, SPA_TYPE__Props);
+ spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
@@ -166,16 +167,16 @@ static void on_stream_state_changed(void *_data, enum pw_stream_state old, enum
}
static void
-on_stream_format_changed(void *_data, struct spa_format *format)
+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 };
- struct spa_param *params[2];
+ struct spa_pod_object *params[2];
if (format == NULL) {
- pw_stream_finish_format(stream, SPA_RESULT_OK, NULL, 0);
+ pw_stream_finish_format(stream, SPA_RESULT_OK, 0, NULL);
return;
}
spa_format_video_raw_parse(format, &data->format, &data->type.format_video);
@@ -183,20 +184,20 @@ on_stream_format_changed(void *_data, struct spa_format *format)
data->stride = SPA_ROUND_UP_N(data->format.size.width * BPP, 4);
spa_pod_builder_init(&b, data->params_buffer, sizeof(data->params_buffer));
- params[0] = spa_pod_builder_param(&b,
- t->param_alloc_buffers.Buffers,
+ 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,
":", t->param_alloc_buffers.stride, "i", data->stride,
":", t->param_alloc_buffers.buffers, "iru", 2,
2, 1, 32,
":", t->param_alloc_buffers.align, "i", 16);
- params[1] = spa_pod_builder_param(&b,
- t->param_alloc_meta_enable.MetaEnable,
+ params[1] = spa_pod_builder_object(&b,
+ t->param.idMeta, t->param_alloc_meta_enable.MetaEnable,
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
":", t->param_alloc_meta_enable.size, "i", sizeof(struct spa_meta_header));
- pw_stream_finish_format(stream, SPA_RESULT_OK, params, 2);
+ pw_stream_finish_format(stream, SPA_RESULT_OK, 2, params);
}
static const struct pw_stream_events stream_events = {
@@ -218,7 +219,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
case PW_REMOTE_STATE_CONNECTED:
{
- const struct spa_format *formats[1];
+ const struct spa_pod_object *params[1];
uint8_t buffer[1024];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
@@ -227,8 +228,10 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
data->stream = pw_stream_new(remote, "video-src", NULL);
- formats[0] = spa_pod_builder_format(&b, data->type.format,
- data->type.media_type.video, data->type.media_subtype.raw,
+ params[0] = spa_pod_builder_object(&b,
+ data->type.param.idEnumFormat, data->type.format,
+ "I", data->type.media_type.video,
+ "I", data->type.media_subtype.raw,
":", data->type.format_video.format, "I", data->type.video_format.RGB,
":", data->type.format_video.size, "Rru", &SPA_RECTANGLE(320, 240),
2, &SPA_RECTANGLE(1, 1),
@@ -242,8 +245,8 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
pw_stream_connect(data->stream,
PW_DIRECTION_OUTPUT,
- PW_STREAM_MODE_BUFFER,
- NULL, PW_STREAM_FLAG_NONE, 1, formats);
+ NULL, PW_STREAM_FLAG_NONE,
+ 1, params);
break;
}
default:
diff --git a/src/extensions/client-node.h b/src/extensions/client-node.h
index 6c3a90af..61936672 100644
--- a/src/extensions/client-node.h
+++ b/src/extensions/client-node.h
@@ -182,21 +182,22 @@ struct pw_client_node_proxy_methods {
/**
* Update the node ports and properties
*
- * Update the maximum number of ports and the properties of the
+ * Update the maximum number of ports and the params of the
* client node.
* \param change_mask bitfield with changed parameters
* \param max_input_ports new max input ports
* \param max_output_ports new max output ports
- * \param props new properties
+ * \param params new params
*/
void (*update) (void *object,
#define PW_CLIENT_NODE_UPDATE_MAX_INPUTS (1 << 0)
#define PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS (1 << 1)
-#define PW_CLIENT_NODE_UPDATE_PROPS (1 << 2)
+#define PW_CLIENT_NODE_UPDATE_PARAMS (1 << 2)
uint32_t change_mask,
uint32_t max_input_ports,
uint32_t max_output_ports,
- const struct spa_props *props);
+ uint32_t n_params,
+ const struct spa_pod_object **params);
/**
* Update a node port
@@ -205,9 +206,6 @@ struct pw_client_node_proxy_methods {
* \param direction the direction of the port
* \param port_id the port id to update
* \param change_mask a bitfield of changed items
- * \param n_possible_formats number of possible formats
- * \param possible_formats array of possible formats on the port
- * \param format the current format on the port
* \param n_params number of port parameters
* \param params array of port parameters
* \param info port information
@@ -215,19 +213,14 @@ struct pw_client_node_proxy_methods {
void (*port_update) (void *object,
enum spa_direction direction,
uint32_t port_id,
-#define PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS (1 << 0)
-#define PW_CLIENT_NODE_PORT_UPDATE_FORMAT (1 << 1)
-#define PW_CLIENT_NODE_PORT_UPDATE_PARAMS (1 << 2)
-#define PW_CLIENT_NODE_PORT_UPDATE_INFO (1 << 3)
+#define PW_CLIENT_NODE_PORT_UPDATE_PARAMS (1 << 0)
+#define PW_CLIENT_NODE_PORT_UPDATE_INFO (1 << 1)
uint32_t change_mask,
- uint32_t n_possible_formats,
- const struct spa_format **possible_formats,
- const struct spa_format *format,
uint32_t n_params,
- const struct spa_param **params,
+ const struct spa_pod_object **params,
const struct spa_port_info *info);
/**
- * Activate of deactivate the node
+ * Activate or deactivate the node
*/
void (*set_active) (void *object, bool active);
/**
@@ -252,12 +245,14 @@ pw_client_node_proxy_update(struct pw_client_node_proxy *p,
uint32_t change_mask,
uint32_t max_input_ports,
uint32_t max_output_ports,
- const struct spa_props *props)
+ uint32_t n_params,
+ const struct spa_pod_object **params)
{
pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, update, change_mask,
max_input_ports,
max_output_ports,
- props);
+ n_params,
+ params);
}
static inline void
@@ -265,19 +260,13 @@ pw_client_node_proxy_port_update(struct pw_client_node_proxy *p,
enum spa_direction direction,
uint32_t port_id,
uint32_t change_mask,
- uint32_t n_possible_formats,
- const struct spa_format **possible_formats,
- const struct spa_format *format,
uint32_t n_params,
- const struct spa_param **params,
+ const struct spa_pod_object **params,
const struct spa_port_info *info)
{
pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, port_update, direction,
port_id,
change_mask,
- n_possible_formats,
- possible_formats,
- format,
n_params,
params,
info);
@@ -302,18 +291,17 @@ pw_client_node_proxy_destroy(struct pw_client_node_proxy *p)
}
-#define PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT 0
-#define PW_CLIENT_NODE_PROXY_EVENT_SET_PROPS 1
-#define PW_CLIENT_NODE_PROXY_EVENT_EVENT 2
-#define PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT 3
-#define PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT 4
-#define PW_CLIENT_NODE_PROXY_EVENT_SET_FORMAT 5
-#define PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM 6
-#define PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM 7
-#define PW_CLIENT_NODE_PROXY_EVENT_USE_BUFFERS 8
-#define PW_CLIENT_NODE_PROXY_EVENT_NODE_COMMAND 9
-#define PW_CLIENT_NODE_PROXY_EVENT_PORT_COMMAND 10
-#define PW_CLIENT_NODE_PROXY_EVENT_NUM 11
+#define PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT 0
+#define PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM 1
+#define PW_CLIENT_NODE_PROXY_EVENT_EVENT 2
+#define PW_CLIENT_NODE_PROXY_EVENT_COMMAND 3
+#define PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT 4
+#define PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT 5
+#define PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM 6
+#define PW_CLIENT_NODE_PROXY_EVENT_PORT_ADD_MEM 7
+#define PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS 8
+#define PW_CLIENT_NODE_PROXY_EVENT_PORT_COMMAND 9
+#define PW_CLIENT_NODE_PROXY_EVENT_NUM 10
/** \ref pw_client_node events */
struct pw_client_node_proxy_events {
@@ -342,16 +330,25 @@ struct pw_client_node_proxy_events {
* this event is sent
*
* \param seq a sequence number
- * \param props the props to set
+ * \param id the id of the parameter
+ * \param flags parameter flags
+ * \param param the param to set
*/
- void (*set_props) (void *object,
- uint32_t seq,
- const struct spa_props *props);
+ void (*set_param) (void *object, uint32_t seq,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param);
/**
* Receive an event from the client node
* \param event the received event */
void (*event) (void *object, const struct spa_event *event);
/**
+ * Notify of a new node command
+ *
+ * \param seq a sequence number
+ * \param command the command
+ */
+ void (*command) (void *object, uint32_t seq, const struct spa_command *command);
+ /**
* A new port was added to the node
*
* The server can at any time add a port to the node when there
@@ -377,33 +374,21 @@ struct pw_client_node_proxy_events {
enum spa_direction direction,
uint32_t port_id);
/**
- * A format was configured on the port
- *
- * \param seq a sequence number
- * \param direction a port direction
- * \param port_id the port id
- * \param flags flags used when setting the format
- * \param format the new format
- */
- void (*set_format) (void *object,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format);
- /**
* A parameter was configured on the port
*
* \param seq a sequence number
* \param direction a port direction
* \param port_id the port id
+ * \param id the id of the parameter
+ * \param flags flags used when setting the param
* \param param the new param
*/
- void (*set_param) (void *object,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param);
+ void (*port_set_param) (void *object,
+ uint32_t seq,
+ enum spa_direction direction,
+ uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param);
/**
* Memory was added for a port
*
@@ -416,15 +401,15 @@ struct pw_client_node_proxy_events {
* \param offset valid offset of mapped memory from \a memfd
* \param size valid size of mapped memory from \a memfd
*/
- void (*add_mem) (void *object,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t mem_id,
- uint32_t type,
- int memfd,
- uint32_t flags,
- uint32_t offset,
- uint32_t size);
+ void (*port_add_mem) (void *object,
+ enum spa_direction direction,
+ uint32_t port_id,
+ uint32_t mem_id,
+ uint32_t type,
+ int memfd,
+ uint32_t flags,
+ uint32_t offset,
+ uint32_t size);
/**
* Notify the port of buffers
*
@@ -434,19 +419,12 @@ struct pw_client_node_proxy_events {
* \param n_buffer the number of buffers
* \param buffers and array of buffer descriptions
*/
- void (*use_buffers) (void *object,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t n_buffers,
- struct pw_client_node_buffer *buffers);
- /**
- * Notify of a new node command
- *
- * \param seq a sequence number
- * \param command the command
- */
- void (*node_command) (void *object, uint32_t seq, const struct spa_command *command);
+ void (*port_use_buffers) (void *object,
+ uint32_t seq,
+ enum spa_direction direction,
+ uint32_t port_id,
+ uint32_t n_buffers,
+ struct pw_client_node_buffer *buffers);
/**
* Notify of a new port command
*
@@ -470,17 +448,26 @@ pw_client_node_proxy_add_listener(struct pw_client_node_proxy *p,
pw_proxy_add_proxy_listener((struct pw_proxy*)p, listener, events, data);
}
-#define pw_client_node_resource_transport(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,transport,__VA_ARGS__)
-#define pw_client_node_resource_set_props(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,props,__VA_ARGS__)
-#define pw_client_node_resource_event(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,event,__VA_ARGS__)
-#define pw_client_node_resource_add_port(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,add_port,__VA_ARGS__)
-#define pw_client_node_resource_remove_port(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,remove_port,__VA_ARGS__)
-#define pw_client_node_resource_set_format(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,set_format,__VA_ARGS__)
-#define pw_client_node_resource_set_param(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,set_param,__VA_ARGS__)
-#define pw_client_node_resource_add_mem(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,add_mem,__VA_ARGS__)
-#define pw_client_node_resource_use_buffers(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,use_buffers,__VA_ARGS__)
-#define pw_client_node_resource_node_command(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,node_command,__VA_ARGS__)
-#define pw_client_node_resource_port_command(r,...) pw_resource_notify(r,struct pw_client_node_proxy_events,port_command,__VA_ARGS__)
+#define pw_client_node_resource_transport(r,...) \
+ pw_resource_notify(r,struct pw_client_node_proxy_events,transport,__VA_ARGS__)
+#define pw_client_node_resource_set_param(r,...) \
+ pw_resource_notify(r,struct pw_client_node_proxy_events,set_param,__VA_ARGS__)
+#define pw_client_node_resource_event(r,...) \
+ pw_resource_notify(r,struct pw_client_node_proxy_events,event,__VA_ARGS__)
+#define pw_client_node_resource_command(r,...) \
+ pw_resource_notify(r,struct pw_client_node_proxy_events,command,__VA_ARGS__)
+#define pw_client_node_resource_add_port(r,...) \
+ pw_resource_notify(r,struct pw_client_node_proxy_events,add_port,__VA_ARGS__)
+#define pw_client_node_resource_remove_port(r,...) \
+ pw_resource_notify(r,struct pw_client_node_proxy_events,remove_port,__VA_ARGS__)
+#define pw_client_node_resource_port_set_param(r,...) \
+ pw_resource_notify(r,struct pw_client_node_proxy_events,port_set_param,__VA_ARGS__)
+#define pw_client_node_resource_port_add_mem(r,...) \
+ pw_resource_notify(r,struct pw_client_node_proxy_events,port_add_mem,__VA_ARGS__)
+#define pw_client_node_resource_port_use_buffers(r,...) \
+ pw_resource_notify(r,struct pw_client_node_proxy_events,port_use_buffers,__VA_ARGS__)
+#define pw_client_node_resource_port_command(r,...) \
+ pw_resource_notify(r,struct pw_client_node_proxy_events,port_command,__VA_ARGS__)
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c
index eb70afe1..336dcc09 100644
--- a/src/gst/gstpipewiredeviceprovider.c
+++ b/src/gst/gstpipewiredeviceprovider.c
@@ -207,16 +207,20 @@ new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info, uint
if (info->max_input_ports > 0 && info->max_output_ports == 0) {
type = GST_PIPEWIRE_DEVICE_TYPE_SINK;
- for (i = 0; i < info->n_input_formats; i++) {
- GstCaps *c1 = gst_caps_from_format (info->input_formats[i], t->map);
+ for (i = 0; i < info->n_input_params; i++) {
+ if (info->input_params[i]->body.id != t->param.idEnumFormat)
+ continue;
+ GstCaps *c1 = gst_caps_from_format (info->input_params[i], t->map);
if (c1)
gst_caps_append (caps, c1);
}
}
else if (info->max_output_ports > 0 && info->max_input_ports == 0) {
type = GST_PIPEWIRE_DEVICE_TYPE_SOURCE;
- for (i = 0; i < info->n_output_formats; i++) {
- GstCaps *c1 = gst_caps_from_format (info->output_formats[i], t->map);
+ for (i = 0; i < info->n_output_params; i++) {
+ if (info->output_params[i]->body.id != t->param.idEnumFormat)
+ continue;
+ GstCaps *c1 = gst_caps_from_format (info->output_params[i], t->map);
if (c1)
gst_caps_append (caps, c1);
}
diff --git a/src/gst/gstpipewireformat.c b/src/gst/gstpipewireformat.c
index 346d35cb..01c835fb 100644
--- a/src/gst/gstpipewireformat.c
+++ b/src/gst/gstpipewireformat.c
@@ -24,7 +24,7 @@
#include <gst/video/video.h>
#include <gst/audio/audio.h>
-#include <spa/format-builder.h>
+#include <spa/pod-builder.h>
#include <spa/video/format-utils.h>
#include <spa/audio/format-utils.h>
@@ -542,7 +542,7 @@ write_pod (struct spa_pod_builder *b, uint32_t ref, const void *data, uint32_t s
return ref;
}
-static struct spa_format *
+static struct spa_pod_object *
convert_1 (GstCapsFeatures *cf, GstStructure *cs)
{
ConvertData d;
@@ -557,9 +557,9 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
d.b.write = write_pod;
- spa_pod_builder_push_format (&d.b, &f, type.format,
- *d.type->media_type,
- *d.type->media_subtype);
+ spa_pod_builder_push_object (&d.b, &f, 0, type.format);
+ spa_pod_builder_id(&d.b, *d.type->media_type);
+ spa_pod_builder_id(&d.b, *d.type->media_subtype);
if (*d.type->media_type == type.media_type.video)
handle_video_fields (&d);
@@ -568,15 +568,15 @@ convert_1 (GstCapsFeatures *cf, GstStructure *cs)
spa_pod_builder_pop (&d.b, &f);
- return SPA_MEMBER (d.b.data, 0, struct spa_format);
+ return SPA_MEMBER (d.b.data, 0, struct spa_pod_object);
}
-struct spa_format *
+struct spa_pod_object *
gst_caps_to_format (GstCaps *caps, guint index, struct spa_type_map *map)
{
GstCapsFeatures *f;
GstStructure *s;
- struct spa_format *res;
+ struct spa_pod_object *res;
g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
@@ -596,7 +596,7 @@ foreach_func (GstCapsFeatures *features,
GstStructure *structure,
GPtrArray *array)
{
- struct spa_format *fmt;
+ struct spa_pod_object *fmt;
if ((fmt = convert_1 (features, structure)))
g_ptr_array_insert (array, -1, fmt);
@@ -794,7 +794,7 @@ handle_fraction_prop (struct spa_pod_prop *prop, const char *key, GstCaps *res)
}
}
GstCaps *
-gst_caps_from_format (const struct spa_format *format, struct spa_type_map *map)
+gst_caps_from_format (const struct spa_pod_object *format, struct spa_type_map *map)
{
GstCaps *res = NULL;
uint32_t media_type, media_subtype;
@@ -802,13 +802,13 @@ gst_caps_from_format (const struct spa_format *format, struct spa_type_map *map)
ensure_types(map);
- media_type = SPA_FORMAT_MEDIA_TYPE (format);
- media_subtype = SPA_FORMAT_MEDIA_SUBTYPE (format);
+ spa_pod_object_parse(format, "I", &media_type,
+ "I", &media_subtype);
if (media_type == type.media_type.video) {
if (media_subtype == type.media_subtype.raw) {
res = gst_caps_new_empty_simple ("video/x-raw");
- if ((prop = spa_format_find_prop (format, type.format_video.format))) {
+ if ((prop = spa_pod_object_find_prop (format, type.format_video.format))) {
handle_id_prop (prop, "format", res);
}
}
@@ -821,13 +821,13 @@ gst_caps_from_format (const struct spa_format *format, struct spa_type_map *map)
"alignment", G_TYPE_STRING, "au",
NULL);
}
- if ((prop = spa_format_find_prop (format, type.format_video.size))) {
+ if ((prop = spa_pod_object_find_prop (format, type.format_video.size))) {
handle_rect_prop (prop, "width", "height", res);
}
- if ((prop = spa_format_find_prop (format, type.format_video.framerate))) {
+ if ((prop = spa_pod_object_find_prop (format, type.format_video.framerate))) {
handle_fraction_prop (prop, "framerate", res);
}
- if ((prop = spa_format_find_prop (format, type.format_video.max_framerate))) {
+ if ((prop = spa_pod_object_find_prop (format, type.format_video.max_framerate))) {
handle_fraction_prop (prop, "max-framerate", res);
}
} else if (media_type == type.media_type.audio) {
@@ -835,13 +835,13 @@ gst_caps_from_format (const struct spa_format *format, struct spa_type_map *map)
res = gst_caps_new_simple ("audio/x-raw",
"layout", G_TYPE_STRING, "interleaved",
NULL);
- if ((prop = spa_format_find_prop (format, type.format_audio.format))) {
+ if ((prop = spa_pod_object_find_prop (format, type.format_audio.format))) {
handle_id_prop (prop, "format", res);
}
- if ((prop = spa_format_find_prop (format, type.format_audio.rate))) {
+ if ((prop = spa_pod_object_find_prop (format, type.format_audio.rate))) {
handle_int_prop (prop, "rate", res);
}
- if ((prop = spa_format_find_prop (format, type.format_audio.channels))) {
+ if ((prop = spa_pod_object_find_prop (format, type.format_audio.channels))) {
handle_int_prop (prop, "channels", res);
}
}
diff --git a/src/gst/gstpipewireformat.h b/src/gst/gstpipewireformat.h
index e5cc0776..c01c38c6 100644
--- a/src/gst/gstpipewireformat.h
+++ b/src/gst/gstpipewireformat.h
@@ -27,10 +27,10 @@
G_BEGIN_DECLS
-struct spa_format * gst_caps_to_format (GstCaps *caps, guint index, struct spa_type_map *map);
-GPtrArray * gst_caps_to_format_all (GstCaps *caps, struct spa_type_map *map);
+struct spa_pod_object * gst_caps_to_format (GstCaps *caps, guint index, struct spa_type_map *map);
+GPtrArray * gst_caps_to_format_all (GstCaps *caps, struct spa_type_map *map);
-GstCaps * gst_caps_from_format (const struct spa_format *format, struct spa_type_map *map);
+GstCaps * gst_caps_from_format (const struct spa_pod_object *format, struct spa_type_map *map);
G_END_DECLS
diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c
index 340e6d27..ed08c055 100644
--- a/src/gst/gstpipewiresink.c
+++ b/src/gst/gstpipewiresink.c
@@ -228,7 +228,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
guint size;
guint min_buffers;
guint max_buffers;
- struct spa_param *port_params[3];
+ struct spa_pod_object *port_params[3];
struct spa_pod_builder b = { NULL };
uint8_t buffer[1024];
struct spa_pod_frame f[1];
@@ -237,7 +237,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
gst_buffer_pool_config_get_params (config, &caps, &size, &min_buffers, &max_buffers);
spa_pod_builder_init (&b, buffer, sizeof (buffer));
- spa_pod_builder_push_param (&b, &f[0], t->param_alloc_buffers.Buffers);
+ spa_pod_builder_push_object (&b, &f[0], t->param.idBuffers, t->param_alloc_buffers.Buffers);
if (size == 0)
spa_pod_builder_add (&b,
":", t->param_alloc_buffers.size, "iru", 0, SPA_PROP_RANGE(0, INT32_MAX), NULL);
@@ -253,15 +253,15 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
":", t->param_alloc_buffers.align, "i", 16,
NULL);
spa_pod_builder_pop (&b, &f[0]);
- port_params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, struct spa_param);
+ port_params[0] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, struct spa_pod_object);
- port_params[1] = spa_pod_builder_param (&b,
- t->param_alloc_meta_enable.MetaEnable,
+ port_params[1] = spa_pod_builder_object (&b,
+ t->param.idMeta, 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));
- port_params[2] = spa_pod_builder_param (&b,
- t->param_alloc_meta_enable.MetaEnable,
+ port_params[2] = spa_pod_builder_object (&b,
+ t->param.idMeta, t->param_alloc_meta_enable.MetaEnable,
":", t->param_alloc_meta_enable.type, "I", t->meta.Ringbuffer,
":", t->param_alloc_meta_enable.size, "i", sizeof (struct spa_meta_ringbuffer),
":", t->param_alloc_meta_enable.ringbufferSize, "i", size * SPA_MAX (4,
@@ -271,7 +271,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
":", t->param_alloc_meta_enable.ringbufferAlign, "i", 16);
pw_thread_loop_lock (sink->main_loop);
- pw_stream_finish_format (sink->stream, SPA_RESULT_OK, port_params, 2);
+ pw_stream_finish_format (sink->stream, SPA_RESULT_OK, 2, port_params);
pw_thread_loop_unlock (sink->main_loop);
}
@@ -586,7 +586,7 @@ on_state_changed (void *data, enum pw_stream_state old, enum pw_stream_state sta
}
static void
-on_format_changed (void *data, struct spa_format *format)
+on_format_changed (void *data, struct spa_pod_object *format)
{
GstPipeWireSink *pwsink = data;
@@ -621,11 +621,10 @@ gst_pipewire_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
pw_stream_connect (pwsink->stream,
PW_DIRECTION_OUTPUT,
- PW_STREAM_MODE_BUFFER,
pwsink->path,
flags,
possible->len,
- (const struct spa_format **) possible->pdata);
+ (const struct spa_pod_object **) possible->pdata);
while (TRUE) {
state = pw_stream_get_state (pwsink->stream, &error);
diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c
index 2f8b88ea..98240e63 100644
--- a/src/gst/gstpipewiresrc.c
+++ b/src/gst/gstpipewiresrc.c
@@ -663,11 +663,10 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc)
GST_DEBUG_OBJECT (basesrc, "connect capture with path %s", pwsrc->path);
pw_stream_connect (pwsrc->stream,
PW_DIRECTION_INPUT,
- PW_STREAM_MODE_BUFFER,
pwsrc->path,
PW_STREAM_FLAG_AUTOCONNECT,
possible->len,
- (const struct spa_format **)possible->pdata);
+ (const struct spa_pod_object **)possible->pdata);
g_ptr_array_free (possible, TRUE);
while (TRUE) {
@@ -729,8 +728,8 @@ connect_error:
#define SPA_PROP_RANGE(min,max) 2,min,max
static void
-on_format_changed (void *data,
- struct spa_format *format)
+on_format_changed (void *data,
+ struct spa_pod_object *format)
{
GstPipeWireSrc *pwsrc = data;
GstCaps *caps;
@@ -740,7 +739,7 @@ on_format_changed (void *data,
if (format == NULL) {
GST_DEBUG_OBJECT (pwsrc, "clear format");
- pw_stream_finish_format (pwsrc->stream, SPA_RESULT_OK, NULL, 0);
+ pw_stream_finish_format (pwsrc->stream, SPA_RESULT_OK, 0, NULL);
return;
}
@@ -750,28 +749,28 @@ on_format_changed (void *data,
gst_caps_unref (caps);
if (res) {
- struct spa_param *params[2];
+ struct spa_pod_object *params[2];
struct spa_pod_builder b = { NULL };
uint8_t buffer[512];
spa_pod_builder_init (&b, buffer, sizeof (buffer));
- params[0] = spa_pod_builder_param (&b,
- t->param_alloc_buffers.Buffers,
+ params[0] = spa_pod_builder_object (&b,
+ 0, t->param_alloc_buffers.Buffers,
":", t->param_alloc_buffers.size, "ir", 0, SPA_PROP_RANGE(0, INT32_MAX),
":", t->param_alloc_buffers.stride, "ir", 0, SPA_PROP_RANGE(0, INT32_MAX),
":", t->param_alloc_buffers.buffers, "ir", 16, SPA_PROP_RANGE(1, INT32_MAX),
":", t->param_alloc_buffers.align, "i", 16);
- params[1] = spa_pod_builder_param (&b,
- t->param_alloc_meta_enable.MetaEnable,
+ params[1] = spa_pod_builder_object (&b,
+ 0, t->param_alloc_meta_enable.MetaEnable,
":", t->param_alloc_meta_enable.type, "I", t->meta.Header,
":", t->param_alloc_meta_enable.size, "i", sizeof (struct spa_meta_header));
GST_DEBUG_OBJECT (pwsrc, "doing finish format");
- pw_stream_finish_format (pwsrc->stream, SPA_RESULT_OK, params, 2);
+ pw_stream_finish_format (pwsrc->stream, SPA_RESULT_OK, 2, params);
} else {
GST_WARNING_OBJECT (pwsrc, "finish format with error");
- pw_stream_finish_format (pwsrc->stream, SPA_RESULT_INVALID_MEDIA_TYPE, NULL, 0);
+ pw_stream_finish_format (pwsrc->stream, SPA_RESULT_INVALID_MEDIA_TYPE, 0, NULL);
}
}
diff --git a/src/modules/module-autolink.c b/src/modules/module-autolink.c
index 658a0ea0..820f5841 100644
--- a/src/modules/module-autolink.c
+++ b/src/modules/module-autolink.c
@@ -28,6 +28,7 @@
#include "pipewire/link.h"
#include "pipewire/log.h"
#include "pipewire/module.h"
+#include "pipewire/private.h"
struct impl {
struct pw_core *core;
diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c
index e21296d6..0f0f82c6 100644
--- a/src/modules/module-client-node/client-node.c
+++ b/src/modules/module-client-node/client-node.c
@@ -29,7 +29,6 @@
#include <sys/eventfd.h>
#include "spa/node.h"
-#include "spa/format-builder.h"
#include "spa/lib/format.h"
#include "pipewire/pipewire.h"
@@ -73,11 +72,10 @@ struct proxy_buffer {
struct proxy_port {
bool valid;
struct spa_port_info info;
- struct spa_format *format;
- uint32_t n_formats;
- struct spa_format **formats;
+
+ bool have_format;
uint32_t n_params;
- struct spa_param **params;
+ struct spa_pod_object **params;
struct spa_port_io *io;
uint32_t n_buffers;
@@ -108,6 +106,9 @@ struct proxy {
struct proxy_port in_ports[MAX_INPUTS];
struct proxy_port out_ports[MAX_OUTPUTS];
+ uint32_t n_params;
+ struct spa_pod_object **params;
+
uint8_t format_buffer[1024];
uint32_t seq;
};
@@ -145,14 +146,51 @@ static int clear_buffers(struct proxy *this, struct proxy_port *port)
return SPA_RESULT_OK;
}
-static int spa_proxy_node_get_props(struct spa_node *node, struct spa_props **props)
+static int spa_proxy_node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ struct proxy *this;
+
+ spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+
+ this = SPA_CONTAINER_OF(node, struct proxy, node);
+
+ while (true) {
+ struct spa_pod_object *param;
+
+ if (*index >= this->n_params)
+ return SPA_RESULT_ENUM_END;
+
+ param = this->params[(*index)++];
+
+ if (param->body.id == id) {
+ spa_pod_builder_primitive(builder, &param->pod);
+ break;
+ }
+ }
+ return SPA_RESULT_OK;
}
-static int spa_proxy_node_set_props(struct spa_node *node, const struct spa_props *props)
+static int spa_proxy_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ struct proxy *this;
+
+ if (node == NULL)
+ return SPA_RESULT_INVALID_ARGUMENTS;
+
+ this = SPA_CONTAINER_OF(node, struct proxy, node);
+
+ if (this->resource == NULL)
+ return SPA_RESULT_OK;
+
+ pw_client_node_resource_set_param(this->resource, this->seq, id, flags, param);
+
+ return SPA_RESULT_RETURN_ASYNC(this->seq++);
}
static inline void do_flush(struct proxy *this)
@@ -180,10 +218,10 @@ static int spa_proxy_node_send_command(struct spa_node *node, const struct spa_c
t = this->impl->t;
if (SPA_COMMAND_TYPE(command) == t->command_node.ClockUpdate) {
- pw_client_node_resource_node_command(this->resource, this->seq++, command);
+ pw_client_node_resource_command(this->resource, this->seq++, command);
} else {
/* send start */
- pw_client_node_resource_node_command(this->resource, this->seq, command);
+ pw_client_node_resource_command(this->resource, this->seq, command);
res = SPA_RESULT_RETURN_ASYNC(this->seq++);
}
return res;
@@ -267,15 +305,12 @@ do_update_port(struct proxy *this,
enum spa_direction direction,
uint32_t port_id,
uint32_t change_mask,
- uint32_t n_possible_formats,
- const struct spa_format **possible_formats,
- const struct spa_format *format,
uint32_t n_params,
- const struct spa_param **params,
+ const struct spa_pod_object **params,
const struct spa_port_info *info)
{
struct proxy_port *port;
- uint32_t i;
+ struct pw_type *t = this->impl->t;
if (direction == SPA_DIRECTION_INPUT) {
port = &this->in_ports[port_id];
@@ -283,31 +318,23 @@ do_update_port(struct proxy *this,
port = &this->out_ports[port_id];
}
- if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS) {
- spa_log_info(this->log, "proxy %p: %d formats", this, n_possible_formats);
- for (i = 0; i < port->n_formats; i++)
- free(port->formats[i]);
- port->n_formats = n_possible_formats;
- port->formats =
- realloc(port->formats, port->n_formats * sizeof(struct spa_format *));
- for (i = 0; i < port->n_formats; i++)
- port->formats[i] = spa_format_copy(possible_formats[i]);
- }
- if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_FORMAT) {
- spa_log_info(this->log, "proxy %p: update format %p", this, format);
- if (port->format)
- free(port->format);
- port->format = spa_format_copy(format);
- }
-
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_PARAMS) {
+ int i;
+
+ port->have_format = false;
+
spa_log_info(this->log, "proxy %p: update %d params", this, n_params);
for (i = 0; i < port->n_params; i++)
free(port->params[i]);
port->n_params = n_params;
- port->params = realloc(port->params, port->n_params * sizeof(struct spa_param *));
- for (i = 0; i < port->n_params; i++)
- port->params[i] = spa_param_copy(params[i]);
+ port->params = realloc(port->params, port->n_params * sizeof(struct spa_pod_object *));
+
+ for (i = 0; i < port->n_params; i++) {
+ port->params[i] = spa_pod_object_copy(params[i]);
+ if (port->params[i]->body.id == t->param.idFormat)
+ port->have_format = true;
+ }
+
}
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_INFO && info)
@@ -315,7 +342,7 @@ do_update_port(struct proxy *this,
if (!port->valid) {
spa_log_info(this->log, "proxy %p: adding port %d", this, port_id);
- port->format = NULL;
+ port->have_format = false;
port->valid = true;
if (direction == SPA_DIRECTION_INPUT)
@@ -332,10 +359,8 @@ clear_port(struct proxy *this,
do_update_port(this,
direction,
port_id,
- PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS |
- PW_CLIENT_NODE_PORT_UPDATE_FORMAT |
PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
- PW_CLIENT_NODE_PORT_UPDATE_INFO, 0, NULL, NULL, 0, NULL, NULL);
+ PW_CLIENT_NODE_PORT_UPDATE_INFO, 0, NULL, NULL);
clear_buffers(this, port);
}
@@ -395,21 +420,14 @@ spa_proxy_node_remove_port(struct spa_node *node, enum spa_direction direction,
}
static int
-spa_proxy_node_port_enum_formats(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+spa_proxy_node_port_get_info(struct spa_node *node,
+ enum spa_direction direction,
+ uint32_t port_id, const struct spa_port_info **info)
{
struct proxy *this;
struct proxy_port *port;
- struct spa_format *fmt;
- struct spa_pod_builder b = { NULL, };
- int res;
- uint32_t count, match = 0;
- if (node == NULL || format == NULL)
+ if (node == NULL || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = SPA_CONTAINER_OF(node, struct proxy, node);
@@ -420,84 +438,57 @@ spa_proxy_node_port_enum_formats(struct spa_node *node,
port =
direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
- count = match = filter ? 0 : index;
-
- next:
- if (count >= port->n_formats)
- return SPA_RESULT_ENUM_END;
-
- fmt = port->formats[count++];
-
- spa_pod_builder_init(&b, this->format_buffer, sizeof(this->format_buffer));
-
- if ((res = spa_format_filter(fmt, filter, &b)) != SPA_RESULT_OK || match++ != index)
- goto next;
-
- *format = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_format);
+ *info = &port->info;
return SPA_RESULT_OK;
}
static int
-spa_proxy_node_port_set_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id, uint32_t flags, const struct spa_format *format)
-{
- struct proxy *this;
-
- if (node == NULL)
- return SPA_RESULT_INVALID_ARGUMENTS;
-
- this = SPA_CONTAINER_OF(node, struct proxy, node);
-
- if (!CHECK_PORT(this, direction, port_id))
- return SPA_RESULT_INVALID_PORT;
-
- if (this->resource == NULL)
- return SPA_RESULT_OK;
-
- pw_client_node_resource_set_format(this->resource,
- this->seq, direction, port_id, flags, format);
-
- return SPA_RESULT_RETURN_ASYNC(this->seq++);
-}
-
-static int
-spa_proxy_node_port_get_format(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id, const struct spa_format **format)
+spa_proxy_node_port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
struct proxy *this;
struct proxy_port *port;
- if (node == NULL || format == NULL)
- return SPA_RESULT_INVALID_ARGUMENTS;
+ spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(index != NULL, SPA_RESULT_INVALID_ARGUMENTS);
+ spa_return_val_if_fail(builder != NULL, SPA_RESULT_INVALID_ARGUMENTS);
this = SPA_CONTAINER_OF(node, struct proxy, node);
- if (!CHECK_PORT(this, direction, port_id))
- return SPA_RESULT_INVALID_PORT;
+ 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];
- if (!port->format)
- return SPA_RESULT_NO_FORMAT;
+ while (true) {
+ struct spa_pod_object *param;
+
+ if (*index >= port->n_params)
+ return SPA_RESULT_ENUM_END;
- *format = port->format;
+ param = port->params[(*index)++];
+ if (param->body.id == id) {
+ spa_pod_builder_primitive(builder, &param->pod);
+ break;
+ }
+ }
return SPA_RESULT_OK;
}
static int
-spa_proxy_node_port_get_info(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id, const struct spa_port_info **info)
+spa_proxy_node_port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct proxy *this;
- struct proxy_port *port;
- if (node == NULL || info == NULL)
+ if (node == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = SPA_CONTAINER_OF(node, struct proxy, node);
@@ -505,46 +496,16 @@ 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];
-
- *info = &port->info;
-
- return SPA_RESULT_OK;
-}
-
-static int
-spa_proxy_node_port_enum_params(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id, uint32_t index, struct spa_param **param)
-{
- struct proxy *this;
- struct proxy_port *port;
-
- spa_return_val_if_fail(node != NULL, SPA_RESULT_INVALID_ARGUMENTS);
- spa_return_val_if_fail(param != NULL, SPA_RESULT_INVALID_ARGUMENTS);
-
- this = SPA_CONTAINER_OF(node, struct proxy, 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];
-
- if (index >= port->n_params)
- return SPA_RESULT_ENUM_END;
-
- *param = port->params[index];
+ if (this->resource == NULL)
+ return SPA_RESULT_OK;
- return SPA_RESULT_OK;
-}
+ pw_client_node_resource_port_set_param(this->resource,
+ this->seq,
+ direction, port_id,
+ id, flags,
+ param);
-static int
-spa_proxy_node_port_set_param(struct spa_node *node,
- enum spa_direction direction,
- uint32_t port_id, const struct spa_param *param)
-{
- return SPA_RESULT_NOT_IMPLEMENTED;
+ return SPA_RESULT_RETURN_ASYNC(this->seq++);
}
static int
@@ -597,7 +558,7 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
port =
direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
- if (!port->format)
+ if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
clear_buffers(this, port);
@@ -633,12 +594,12 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
mb[i].offset = 0;
mb[i].size = msh->size;
- pw_client_node_resource_add_mem(this->resource,
- direction,
- port_id,
- mb[i].mem_id,
- t->data.MemFd,
- msh->fd, msh->flags, msh->offset, msh->size);
+ pw_client_node_resource_port_add_mem(this->resource,
+ direction,
+ port_id,
+ mb[i].mem_id,
+ t->data.MemFd,
+ msh->fd, msh->flags, msh->offset, msh->size);
for (j = 0; j < buffers[i]->n_metas; j++) {
memcpy(&b->buffer.metas[j], &buffers[i]->metas[j], sizeof(struct spa_meta));
@@ -651,13 +612,13 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
if (d->type == t->data.DmaBuf ||
d->type == t->data.MemFd) {
- pw_client_node_resource_add_mem(this->resource,
- direction,
- port_id,
- n_mem,
- d->type,
- d->fd,
- d->flags, d->mapoffset, d->maxsize);
+ pw_client_node_resource_port_add_mem(this->resource,
+ direction,
+ port_id,
+ n_mem,
+ d->type,
+ d->fd,
+ d->flags, d->mapoffset, d->maxsize);
b->buffer.datas[j].type = t->data.Id;
b->buffer.datas[j].data = SPA_UINT32_TO_PTR(n_mem);
n_mem++;
@@ -672,8 +633,10 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
}
}
- pw_client_node_resource_use_buffers(this->resource,
- this->seq, direction, port_id, n_buffers, mb);
+ pw_client_node_resource_port_use_buffers(this->resource,
+ this->seq,
+ direction, port_id,
+ n_buffers, mb);
return SPA_RESULT_RETURN_ASYNC(this->seq++);
}
@@ -682,7 +645,7 @@ static int
spa_proxy_node_port_alloc_buffers(struct spa_node *node,
enum spa_direction direction,
uint32_t port_id,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_params,
struct spa_buffer **buffers,
uint32_t *n_buffers)
@@ -701,7 +664,7 @@ spa_proxy_node_port_alloc_buffers(struct spa_node *node,
port =
direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
- if (!port->format)
+ if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
return SPA_RESULT_NOT_IMPLEMENTED;
@@ -874,7 +837,9 @@ static void
client_node_update(void *data,
uint32_t change_mask,
uint32_t max_input_ports,
- uint32_t max_output_ports, const struct spa_props *props)
+ uint32_t max_output_ports,
+ uint32_t n_params,
+ const struct spa_pod_object **params)
{
struct impl *impl = data;
struct proxy *this = &impl->proxy;
@@ -883,7 +848,18 @@ client_node_update(void *data,
this->max_inputs = max_input_ports;
if (change_mask & PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS)
this->max_outputs = max_output_ports;
+ if (change_mask & PW_CLIENT_NODE_UPDATE_PARAMS) {
+ int i;
+ spa_log_info(this->log, "proxy %p: update %d params", this, n_params);
+
+ for (i = 0; i < this->n_params; i++)
+ free(this->params[i]);
+ this->n_params = n_params;
+ this->params = realloc(this->params, this->n_params * sizeof(struct spa_pod_object *));
+ for (i = 0; i < this->n_params; i++)
+ this->params[i] = spa_pod_object_copy(params[i]);
+ }
spa_log_info(this->log, "proxy %p: got node update max_in %u, max_out %u", this,
this->max_inputs, this->max_outputs);
}
@@ -893,11 +869,9 @@ client_node_port_update(void *data,
enum spa_direction direction,
uint32_t port_id,
uint32_t change_mask,
- uint32_t n_possible_formats,
- const struct spa_format **possible_formats,
- const struct spa_format *format,
uint32_t n_params,
- const struct spa_param **params, const struct spa_port_info *info)
+ const struct spa_pod_object **params,
+ const struct spa_port_info *info)
{
struct impl *impl = data;
struct proxy *this = &impl->proxy;
@@ -916,8 +890,7 @@ client_node_port_update(void *data,
direction,
port_id,
change_mask,
- n_possible_formats,
- possible_formats, format, n_params, params, info);
+ n_params, params, info);
}
}
@@ -979,17 +952,14 @@ static void proxy_on_data_fd_events(struct spa_source *source)
static const struct spa_node proxy_node = {
SPA_VERSION_NODE,
NULL,
- spa_proxy_node_get_props,
- spa_proxy_node_set_props,
+ spa_proxy_node_enum_params,
+ spa_proxy_node_set_param,
spa_proxy_node_send_command,
spa_proxy_node_set_callbacks,
spa_proxy_node_get_n_ports,
spa_proxy_node_get_port_ids,
spa_proxy_node_add_port,
spa_proxy_node_remove_port,
- spa_proxy_node_port_enum_formats,
- spa_proxy_node_port_set_format,
- spa_proxy_node_port_get_format,
spa_proxy_node_port_get_info,
spa_proxy_node_port_enum_params,
spa_proxy_node_port_set_param,
diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c
index f8c90a45..2d84c57a 100644
--- a/src/modules/module-client-node/protocol-native.c
+++ b/src/modules/module-client-node/protocol-native.c
@@ -51,18 +51,27 @@ static void
client_node_marshal_update(void *object,
uint32_t change_mask,
uint32_t max_input_ports,
- uint32_t max_output_ports, const struct spa_props *props)
+ uint32_t max_output_ports,
+ uint32_t n_params,
+ const struct spa_pod_object **params)
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
+ int i;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_UPDATE);
- spa_pod_builder_struct(b,
- "i", change_mask,
- "i", max_input_ports,
- "i", max_output_ports,
- "P", props);
+ spa_pod_builder_add(b,
+ "[",
+ "i", change_mask,
+ "i", max_input_ports,
+ "i", max_output_ports,
+ "i", n_params, NULL);
+
+ for (i = 0; i < n_params; i++)
+ spa_pod_builder_add(b, "P", params[i], NULL);
+
+ spa_pod_builder_add(b, "]", NULL);
pw_protocol_native_end_proxy(proxy, b);
}
@@ -72,11 +81,9 @@ client_node_marshal_port_update(void *object,
enum spa_direction direction,
uint32_t port_id,
uint32_t change_mask,
- uint32_t n_possible_formats,
- const struct spa_format **possible_formats,
- const struct spa_format *format,
uint32_t n_params,
- const struct spa_param **params, const struct spa_port_info *info)
+ const struct spa_pod_object **params,
+ const struct spa_port_info *info)
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
@@ -89,13 +96,6 @@ client_node_marshal_port_update(void *object,
"i", direction,
"i", port_id,
"i", change_mask,
- "i", n_possible_formats, NULL);
-
- for (i = 0; i < n_possible_formats; i++)
- spa_pod_builder_add(b, "P", possible_formats[i], NULL);
-
- spa_pod_builder_add(b,
- "P", format,
"i", n_params, NULL);
for (i = 0; i < n_params; i++)
@@ -149,21 +149,57 @@ static void client_node_marshal_destroy(void *object)
pw_protocol_native_end_proxy(proxy, b);
}
-static bool client_node_demarshal_set_props(void *object, void *data, size_t size)
+static bool client_node_demarshal_transport(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
- uint32_t seq;
- const struct spa_props *props = NULL;
+ uint32_t node_id, ridx, widx, memfd_idx;
+ int readfd, writefd;
+ struct pw_client_node_transport_info info;
+ struct pw_client_node_transport *transport;
+
+ spa_pod_parser_init(&prs, data, size, 0);
+ if (spa_pod_parser_get(&prs,
+ "["
+ "i", &node_id,
+ "i", &ridx,
+ "i", &widx,
+ "i", &memfd_idx,
+ "i", &info.offset,
+ "i", &info.size, NULL) < 0)
+ return false;
+
+ readfd = pw_protocol_native_get_proxy_fd(proxy, ridx);
+ writefd = pw_protocol_native_get_proxy_fd(proxy, widx);
+ info.memfd = pw_protocol_native_get_proxy_fd(proxy, memfd_idx);
+
+ if (readfd == -1 || writefd == -1 || info.memfd == -1)
+ return false;
+
+ transport = pw_client_node_transport_new_from_info(&info);
+
+ pw_proxy_notify(proxy, struct pw_client_node_proxy_events, transport, node_id,
+ readfd, writefd, transport);
+ return true;
+}
+
+static bool client_node_demarshal_set_param(void *object, void *data, size_t size)
+{
+ struct pw_proxy *proxy = object;
+ struct spa_pod_parser prs;
+ uint32_t seq, id, flags;
+ const struct spa_pod_object *param = NULL;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
"i", &seq,
- "O", &props, NULL) < 0)
+ "I", &id,
+ "i", &flags,
+ "O", &param, NULL) < 0)
return false;
- pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_props, seq, props);
+ pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_param, seq, id, flags, param);
return true;
}
@@ -181,25 +217,25 @@ static bool client_node_demarshal_event_event(void *object, void *data, size_t s
return true;
}
-static bool client_node_demarshal_add_port(void *object, void *data, size_t size)
+static bool client_node_demarshal_command(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
- int32_t seq, direction, port_id;
+ const struct spa_command *command;
+ uint32_t seq;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
"i", &seq,
- "i", &direction,
- "i", &port_id, NULL) < 0)
+ "O", &command, NULL) < 0)
return false;
- pw_proxy_notify(proxy, struct pw_client_node_proxy_events, add_port, seq, direction, port_id);
+ pw_proxy_notify(proxy, struct pw_client_node_proxy_events, command, seq, command);
return true;
}
-static bool client_node_demarshal_remove_port(void *object, void *data, size_t size)
+static bool client_node_demarshal_add_port(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
@@ -213,38 +249,34 @@ static bool client_node_demarshal_remove_port(void *object, void *data, size_t s
"i", &port_id, NULL) < 0)
return false;
- pw_proxy_notify(proxy, struct pw_client_node_proxy_events, remove_port, seq, direction, port_id);
+ pw_proxy_notify(proxy, struct pw_client_node_proxy_events, add_port, seq, direction, port_id);
return true;
}
-static bool client_node_demarshal_set_format(void *object, void *data, size_t size)
+static bool client_node_demarshal_remove_port(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
- uint32_t seq, direction, port_id, flags;
- const struct spa_format *format = NULL;
+ int32_t seq, direction, port_id;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
"["
"i", &seq,
"i", &direction,
- "i", &port_id,
- "i", &flags,
- "O", &format, NULL) < 0)
+ "i", &port_id, NULL) < 0)
return false;
- pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_format, seq, direction, port_id,
- flags, format);
+ pw_proxy_notify(proxy, struct pw_client_node_proxy_events, remove_port, seq, direction, port_id);
return true;
}
-static bool client_node_demarshal_set_param(void *object, void *data, size_t size)
+static bool client_node_demarshal_port_set_param(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
- uint32_t seq, direction, port_id;
- const struct spa_param *param = NULL;
+ uint32_t seq, direction, port_id, id, flags;
+ const struct spa_pod_object *param = NULL;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
@@ -252,14 +284,17 @@ static bool client_node_demarshal_set_param(void *object, void *data, size_t siz
"i", &seq,
"i", &direction,
"i", &port_id,
+ "I", &id,
+ "i", &flags,
"O", &param, NULL) < 0)
return false;
- pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_param, seq, direction, port_id, param);
+ pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_set_param,
+ seq, direction, port_id, id, flags, param);
return true;
}
-static bool client_node_demarshal_add_mem(void *object, void *data, size_t size)
+static bool client_node_demarshal_port_add_mem(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
@@ -281,7 +316,7 @@ static bool client_node_demarshal_add_mem(void *object, void *data, size_t size)
memfd = pw_protocol_native_get_proxy_fd(proxy, memfd_idx);
- pw_proxy_notify(proxy, struct pw_client_node_proxy_events, add_mem, direction,
+ pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_add_mem, direction,
port_id,
mem_id,
type,
@@ -289,7 +324,7 @@ static bool client_node_demarshal_add_mem(void *object, void *data, size_t size)
return true;
}
-static bool client_node_demarshal_use_buffers(void *object, void *data, size_t size)
+static bool client_node_demarshal_port_use_buffers(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
struct spa_pod_parser prs;
@@ -345,31 +380,13 @@ static bool client_node_demarshal_use_buffers(void *object, void *data, size_t s
d->data = SPA_UINT32_TO_PTR(data_id);
}
}
- pw_proxy_notify(proxy, struct pw_client_node_proxy_events, use_buffers, seq,
+ pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_use_buffers, seq,
direction,
port_id,
n_buffers, buffers);
return true;
}
-static bool client_node_demarshal_node_command(void *object, void *data, size_t size)
-{
- struct pw_proxy *proxy = object;
- struct spa_pod_parser prs;
- const struct spa_command *command;
- uint32_t seq;
-
- spa_pod_parser_init(&prs, data, size, 0);
- if (spa_pod_parser_get(&prs,
- "["
- "i", &seq,
- "O", &command, NULL) < 0)
- return false;
-
- pw_proxy_notify(proxy, struct pw_client_node_proxy_events, node_command, seq, command);
- return true;
-}
-
static bool client_node_demarshal_port_command(void *object, void *data, size_t size)
{
struct pw_proxy *proxy = object;
@@ -391,51 +408,42 @@ static bool client_node_demarshal_port_command(void *object, void *data, size_t
return true;
}
-static bool client_node_demarshal_transport(void *object, void *data, size_t size)
+static void client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd,
+ struct pw_client_node_transport *transport)
{
- struct pw_proxy *proxy = object;
- struct spa_pod_parser prs;
- uint32_t node_id, ridx, widx, memfd_idx;
- int readfd, writefd;
+ struct pw_resource *resource = object;
+ struct spa_pod_builder *b;
struct pw_client_node_transport_info info;
- struct pw_client_node_transport *transport;
-
- spa_pod_parser_init(&prs, data, size, 0);
- if (spa_pod_parser_get(&prs,
- "["
- "i", &node_id,
- "i", &ridx,
- "i", &widx,
- "i", &memfd_idx,
- "i", &info.offset,
- "i", &info.size, NULL) < 0)
- return false;
- readfd = pw_protocol_native_get_proxy_fd(proxy, ridx);
- writefd = pw_protocol_native_get_proxy_fd(proxy, widx);
- info.memfd = pw_protocol_native_get_proxy_fd(proxy, memfd_idx);
+ pw_client_node_transport_get_info(transport, &info);
- if (readfd == -1 || writefd == -1 || info.memfd == -1)
- return false;
+ b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT);
- transport = pw_client_node_transport_new_from_info(&info);
+ spa_pod_builder_struct(b,
+ "i", node_id,
+ "i", pw_protocol_native_add_resource_fd(resource, readfd),
+ "i", pw_protocol_native_add_resource_fd(resource, writefd),
+ "i", pw_protocol_native_add_resource_fd(resource, info.memfd),
+ "i", info.offset,
+ "i", info.size);
- pw_proxy_notify(proxy, struct pw_client_node_proxy_events, transport, node_id,
- readfd, writefd, transport);
- return true;
+ pw_protocol_native_end_resource(resource, b);
}
static void
-client_node_marshal_set_props(void *object, uint32_t seq, const struct spa_props *props)
+client_node_marshal_set_param(void *object, uint32_t seq, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
- b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PROPS);
+ b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM);
spa_pod_builder_struct(b,
"i", seq,
- "P", props);
+ "I", id,
+ "i", flags,
+ "P", param);
pw_protocol_native_end_resource(resource, b);
}
@@ -453,30 +461,26 @@ static void client_node_marshal_event_event(void *object, const struct spa_event
}
static void
-client_node_marshal_add_port(void *object,
- uint32_t seq, enum spa_direction direction, uint32_t port_id)
+client_node_marshal_command(void *object, uint32_t seq, const struct spa_command *command)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
- b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT);
+ b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_COMMAND);
- spa_pod_builder_struct(b,
- "i", seq,
- "i", direction,
- "i", port_id);
+ spa_pod_builder_struct(b, "i", seq, "P", command);
pw_protocol_native_end_resource(resource, b);
}
static void
-client_node_marshal_remove_port(void *object,
- uint32_t seq, enum spa_direction direction, uint32_t port_id)
+client_node_marshal_add_port(void *object,
+ uint32_t seq, enum spa_direction direction, uint32_t port_id)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
- b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT);
+ b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT);
spa_pod_builder_struct(b,
"i", seq,
@@ -487,61 +491,59 @@ client_node_marshal_remove_port(void *object,
}
static void
-client_node_marshal_set_format(void *object,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t flags,
- const struct spa_format *format)
+client_node_marshal_remove_port(void *object,
+ uint32_t seq, enum spa_direction direction, uint32_t port_id)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
- b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_FORMAT);
+ b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT);
spa_pod_builder_struct(b,
"i", seq,
"i", direction,
- "i", port_id,
- "i", flags,
- "P", format);
+ "i", port_id);
pw_protocol_native_end_resource(resource, b);
}
static void
-client_node_marshal_set_param(void *object,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
+client_node_marshal_port_set_param(void *object,
+ uint32_t seq,
+ enum spa_direction direction,
+ uint32_t port_id,
+ uint32_t id,
+ uint32_t flags,
+ const struct spa_pod_object *param)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
- b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM);
+ b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM);
spa_pod_builder_struct(b,
"i", seq,
"i", direction,
"i", port_id,
+ "I", id,
+ "i", flags,
"P", param);
pw_protocol_native_end_resource(resource, b);
}
static void
-client_node_marshal_add_mem(void *object,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t mem_id,
- uint32_t type,
- int memfd, uint32_t flags, uint32_t offset, uint32_t size)
+client_node_marshal_port_add_mem(void *object,
+ enum spa_direction direction,
+ uint32_t port_id,
+ uint32_t mem_id,
+ uint32_t type,
+ int memfd, uint32_t flags, uint32_t offset, uint32_t size)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
- b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM);
+ b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_ADD_MEM);
spa_pod_builder_struct(b,
"i", direction,
@@ -557,17 +559,17 @@ client_node_marshal_add_mem(void *object,
}
static void
-client_node_marshal_use_buffers(void *object,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t n_buffers, struct pw_client_node_buffer *buffers)
+client_node_marshal_port_use_buffers(void *object,
+ uint32_t seq,
+ enum spa_direction direction,
+ uint32_t port_id,
+ uint32_t n_buffers, struct pw_client_node_buffer *buffers)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
uint32_t i, j;
- b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_USE_BUFFERS);
+ b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS);
spa_pod_builder_add(b,
"[",
@@ -609,19 +611,6 @@ client_node_marshal_use_buffers(void *object,
}
static void
-client_node_marshal_node_command(void *object, uint32_t seq, const struct spa_command *command)
-{
- struct pw_resource *resource = object;
- struct spa_pod_builder *b;
-
- b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_NODE_COMMAND);
-
- spa_pod_builder_struct(b, "i", seq, "P", command);
-
- pw_protocol_native_end_resource(resource, b);
-}
-
-static void
client_node_marshal_port_command(void *object,
uint32_t direction,
uint32_t port_id,
@@ -640,28 +629,6 @@ client_node_marshal_port_command(void *object,
pw_protocol_native_end_resource(resource, b);
}
-static void client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd,
- struct pw_client_node_transport *transport)
-{
- struct pw_resource *resource = object;
- struct spa_pod_builder *b;
- struct pw_client_node_transport_info info;
-
- pw_client_node_transport_get_info(transport, &info);
-
- b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT);
-
- spa_pod_builder_struct(b,
- "i", node_id,
- "i", pw_protocol_native_add_resource_fd(resource, readfd),
- "i", pw_protocol_native_add_resource_fd(resource, writefd),
- "i", pw_protocol_native_add_resource_fd(resource, info.memfd),
- "i", info.offset,
- "i", info.size);
-
- pw_protocol_native_end_resource(resource, b);
-}
-
static bool client_node_demarshal_done(void *object, void *data, size_t size)
{
@@ -684,8 +651,9 @@ static bool client_node_demarshal_update(void *object, void *data, size_t size)
{
struct pw_resource *resource = object;
struct spa_pod_parser prs;
- uint32_t change_mask, max_input_ports, max_output_ports;
- const struct spa_props *props;
+ uint32_t change_mask, max_input_ports, max_output_ports, n_params;
+ const struct spa_pod_object **params;
+ int i;
spa_pod_parser_init(&prs, data, size, 0);
if (spa_pod_parser_get(&prs,
@@ -693,13 +661,19 @@ static bool client_node_demarshal_update(void *object, void *data, size_t size)
"i", &change_mask,
"i", &max_input_ports,
"i", &max_output_ports,
- "O", &props, NULL) < 0)
+ "i", &n_params, NULL) < 0)
return false;
+ params = alloca(n_params * sizeof(struct spa_pod_object *));
+ for (i = 0; i < n_params; i++)
+ if (spa_pod_parser_get(&prs, "O", &params[i], NULL) < 0)
+ return false;
+
pw_resource_do(resource, struct pw_client_node_proxy_methods, update, change_mask,
max_input_ports,
max_output_ports,
- props);
+ n_params,
+ params);
return true;
}
@@ -707,9 +681,8 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s
{
struct pw_resource *resource = object;
struct spa_pod_parser prs;
- uint32_t i, direction, port_id, change_mask, n_possible_formats, n_params;
- const struct spa_param **params = NULL;
- const struct spa_format **possible_formats = NULL, *format = NULL;
+ uint32_t i, direction, port_id, change_mask, n_params;
+ const struct spa_pod_object **params = NULL;
struct spa_port_info info, *infop = NULL;
struct spa_pod *ipod;
@@ -719,18 +692,10 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s
"i", &direction,
"i", &port_id,
"i", &change_mask,
- "i", &n_possible_formats, NULL) < 0)
- return false;
-
- possible_formats = alloca(n_possible_formats * sizeof(struct spa_format *));
- for (i = 0; i < n_possible_formats; i++)
- if (spa_pod_parser_get(&prs, "O", &possible_formats[i], NULL) < 0)
- return false;
-
- if (spa_pod_parser_get(&prs, "O", &format, "i", &n_params, NULL) < 0)
+ "i", &n_params, NULL) < 0)
return false;
- params = alloca(n_params * sizeof(struct spa_param *));
+ params = alloca(n_params * sizeof(struct spa_pod_object *));
for (i = 0; i < n_params; i++)
if (spa_pod_parser_get(&prs, "O", &params[i], NULL) < 0)
return false;
@@ -753,9 +718,6 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s
pw_resource_do(resource, struct pw_client_node_proxy_methods, port_update, direction,
port_id,
change_mask,
- n_possible_formats,
- possible_formats,
- format,
n_params,
params, infop);
return true;
@@ -828,29 +790,27 @@ static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_
static const struct pw_client_node_proxy_events pw_protocol_native_client_node_event_marshal = {
PW_VERSION_CLIENT_NODE_PROXY_EVENTS,
&client_node_marshal_transport,
- &client_node_marshal_set_props,
+ &client_node_marshal_set_param,
&client_node_marshal_event_event,
+ &client_node_marshal_command,
&client_node_marshal_add_port,
&client_node_marshal_remove_port,
- &client_node_marshal_set_format,
- &client_node_marshal_set_param,
- &client_node_marshal_add_mem,
- &client_node_marshal_use_buffers,
- &client_node_marshal_node_command,
+ &client_node_marshal_port_set_param,
+ &client_node_marshal_port_add_mem,
+ &client_node_marshal_port_use_buffers,
&client_node_marshal_port_command,
};
static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_event_demarshal[] = {
{ &client_node_demarshal_transport, 0 },
- { &client_node_demarshal_set_props, PW_PROTOCOL_NATIVE_REMAP },
+ { &client_node_demarshal_set_param, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_event_event, PW_PROTOCOL_NATIVE_REMAP },
+ { &client_node_demarshal_command, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_add_port, 0 },
{ &client_node_demarshal_remove_port, 0 },
- { &client_node_demarshal_set_format, PW_PROTOCOL_NATIVE_REMAP },
- { &client_node_demarshal_set_param, PW_PROTOCOL_NATIVE_REMAP },
- { &client_node_demarshal_add_mem, PW_PROTOCOL_NATIVE_REMAP },
- { &client_node_demarshal_use_buffers, PW_PROTOCOL_NATIVE_REMAP },
- { &client_node_demarshal_node_command, PW_PROTOCOL_NATIVE_REMAP },
+ { &client_node_demarshal_port_set_param, PW_PROTOCOL_NATIVE_REMAP },
+ { &client_node_demarshal_port_add_mem, PW_PROTOCOL_NATIVE_REMAP },
+ { &client_node_demarshal_port_use_buffers, PW_PROTOCOL_NATIVE_REMAP },
{ &client_node_demarshal_port_command, PW_PROTOCOL_NATIVE_REMAP },
};
diff --git a/src/modules/module-flatpak.c b/src/modules/module-flatpak.c
index 92238d10..58a2e45d 100644
--- a/src/modules/module-flatpak.c
+++ b/src/modules/module-flatpak.c
@@ -434,7 +434,7 @@ do_create_link(void *data,
uint32_t output_port_id,
uint32_t input_node_id,
uint32_t input_port_id,
- const struct spa_format *filter,
+ const struct spa_pod_object *filter,
const struct spa_dict *props,
uint32_t new_id)
{
diff --git a/src/modules/module-jack.c b/src/modules/module-jack.c
index 9eb663c5..55ee0201 100644
--- a/src/modules/module-jack.c
+++ b/src/modules/module-jack.c
@@ -1291,7 +1291,9 @@ static bool on_global(void *data, struct pw_global *global)
const char *str;
char *error;
struct pw_port *in_port, *out_port;
- struct spa_props *props;
+ uint32_t index = 0;
+ uint8_t buf[2048];
+ struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
if (pw_global_get_type(global) != impl->t->node)
return true;
@@ -1323,10 +1325,11 @@ static bool on_global(void *data, struct pw_global *global)
return true;
}
- if (spa_node_get_props(node->node, &props) == SPA_RESULT_OK) {
+ if (spa_node_enum_params(node->node, SPA_ID_INVALID, &index, NULL, &b) == SPA_RESULT_OK) {
int min_latency = -1;
+ struct spa_pod_object *props = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
- spa_props_parse(props,
+ spa_pod_object_parse(props,
":", impl->prop_min_latency, "?i", &min_latency, NULL);
if (min_latency != -1)
diff --git a/src/modules/module-jack/jack-node.c b/src/modules/module-jack/jack-node.c
index 2f425474..24c50e81 100644
--- a/src/modules/module-jack/jack-node.c
+++ b/src/modules/module-jack/jack-node.c
@@ -30,7 +30,6 @@
#include <spa/node.h>
#include <spa/hook.h>
-#include <spa/format-builder.h>
#include <spa/lib/format.h>
#include <spa/audio/format-utils.h>
@@ -47,6 +46,7 @@
struct type {
uint32_t format;
+ struct spa_type_param param;
struct spa_type_data data;
struct spa_type_media_type media_type;
struct spa_type_media_subtype media_subtype;
@@ -58,6 +58,7 @@ struct type {
static inline void init_type(struct type *type, struct spa_type_map *map)
{
type->format = spa_type_map_get_id(map, SPA_TYPE__Format);
+ spa_type_param_map(map, &type->param);
spa_type_data_map(map, &type->data);
spa_type_media_type_map(map, &type->media_type);
spa_type_media_subtype_map(map, &type->media_subtype);
@@ -121,12 +122,17 @@ struct port_data {
/** \endcond */
-static int node_get_props(struct spa_node *node, struct spa_props **props)
+static int node_enum_params(struct spa_node *node,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
-static int node_set_props(struct spa_node *node, const struct spa_props *props)
+static int node_set_param(struct spa_node *node,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
@@ -368,16 +374,17 @@ static int port_set_io(struct spa_node *node, enum spa_direction direction, uint
return SPA_RESULT_OK;
}
-static int port_enum_formats(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- struct spa_format **format,
- const struct spa_format *filter,
- uint32_t index)
+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 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_format *fmt;
+ struct spa_pod_object *fmt;
uint8_t buffer[4096];
int res;
struct jack_engine_control *ctrl = pd->node->node.server->engine_control;
@@ -389,55 +396,39 @@ static int port_enum_formats(struct spa_node *node, enum spa_direction direction
if (pd->port.jack_port) {
if (pd->port.jack_port->type_id == 0) {
- fmt = spa_pod_builder_format(&b,
- t->format,
- t->media_type.audio, t->media_subtype.raw,
+ fmt = spa_pod_builder_object(&b,
+ t->param.idEnumFormat, t->format,
+ "I", t->media_type.audio,
+ "I", t->media_subtype.raw,
":", t->format_audio.format, "I", t->audio_format.F32,
":", t->format_audio.rate, "i", ctrl->sample_rate,
":", t->format_audio.channels, "i", 1);
}
else if (pd->port.jack_port->type_id == 1) {
- fmt = spa_pod_builder_format(&b,
- t->format,
- t->media_type.audio, t->media_subtype_audio.midi);
+ fmt = spa_pod_builder_object(&b,
+ t->param.idEnumFormat, t->format,
+ "I", t->media_type.audio,
+ "I", t->media_subtype_audio.midi);
}
else
return SPA_RESULT_ENUM_END;
}
else {
- fmt = spa_pod_builder_format(&b,
- t->format,
- t->media_type.audio, t->media_subtype.raw,
+ fmt = spa_pod_builder_object(&b,
+ t->param.idEnumFormat, t->format,
+ "I", t->media_type.audio,
+ "I", t->media_subtype.raw,
":", t->format_audio.format, "I", t->audio_format.S16,
":", t->format_audio.rate, "i", ctrl->sample_rate,
":", t->format_audio.channels, "i", 2);
}
- spa_pod_builder_init(&b, pd->buffer, sizeof(pd->buffer));
- if ((res = spa_format_filter(fmt, filter, &b)) < 0)
+ if ((res = spa_pod_object_filter(fmt, filter, builder)) < 0)
return res;
- *format = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_format);
-
- 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_format *format)
-{
return SPA_RESULT_OK;
}
-static int port_get_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- const struct spa_format **format)
-{
- int res;
- struct spa_format *fmt;
- res = port_enum_formats(node, direction, port_id, &fmt, NULL, 0);
- *format = fmt;
- return res;
-}
-
static int port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
const struct spa_port_info **info)
{
@@ -455,14 +446,31 @@ static int port_get_info(struct spa_node *node, enum spa_direction direction, ui
return SPA_RESULT_OK;
}
-static int port_enum_params(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- uint32_t index, struct spa_param **param)
+static int port_enum_params(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t *index,
+ const struct spa_pod_object *filter,
+ struct spa_pod_builder *builder)
{
+ struct node_data *nd = SPA_CONTAINER_OF(node, struct node_data, node_impl);
+ struct type *t = &nd->type;
+
+ if (id == t->param.idEnumFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else if (id == t->param.idFormat) {
+ return port_enum_formats(node, direction, port_id, index, filter, builder);
+ }
+ else
+ return SPA_RESULT_UNKNOWN_PARAM;
+
return SPA_RESULT_ENUM_END;
}
-static int port_set_param(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- const struct spa_param *param)
+static int port_set_param(struct spa_node *node,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
return SPA_RESULT_OK;
}
@@ -501,7 +509,7 @@ static int port_use_buffers(struct spa_node *node, enum spa_direction direction,
}
static int port_alloc_buffers(struct spa_node *node, enum spa_direction direction, uint32_t port_id,
- struct spa_param **params, uint32_t n_params,
+ struct spa_pod_object **params, uint32_t n_params,
struct spa_buffer **buffers, uint32_t *n_buffers)
{
struct node_data *nd = SPA_CONTAINER_OF(node, struct node_data, node_impl);
@@ -551,17 +559,14 @@ static int port_send_command(struct spa_node *node, enum spa_direction direction
static const struct spa_node driver_impl = {
SPA_VERSION_NODE,
NULL,
- .get_props = node_get_props,
- .set_props = node_set_props,
+ .enum_params = node_enum_params,
+ .set_param = node_set_param,
.send_command = node_send_command,
.set_callbacks = node_set_callbacks,
.get_n_ports = node_get_n_ports,
.get_port_ids = node_get_port_ids,
.add_port = node_add_port,
.remove_port = node_remove_port,
- .port_enum_formats = port_enum_formats,
- .port_set_format = port_set_format,
- .port_get_format = port_get_format,
.port_get_info = port_get_info,
.port_enum_params = port_enum_params,
.port_set_param = port_set_param,
@@ -577,17 +582,14 @@ static const struct spa_node driver_impl = {
static const struct spa_node node_impl = {
SPA_VERSION_NODE,
NULL,
- .get_props = node_get_props,
- .set_props = node_set_props,
+ .enum_params = node_enum_params,
+ .set_param = node_set_param,
.send_command = node_send_command,
.set_callbacks = node_set_callbacks,
.get_n_ports = node_get_n_ports,
.get_port_ids = node_get_port_ids,
.add_port = node_add_port,
.remove_port = node_remove_port,
- .port_enum_formats = port_enum_formats,
- .port_set_format = port_set_format,
- .port_get_format = port_get_format,
.port_get_info = port_get_info,
.port_enum_params = port_enum_params,
.port_set_param = port_set_param,
diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c
index 35790a2f..72da904e 100644
--- a/src/modules/module-protocol-native.c
+++ b/src/modules/module-protocol-native.c
@@ -99,6 +99,7 @@ struct client_data {
static bool pod_remap_data(uint32_t type, void *body, uint32_t size, struct pw_map *types)
{
void *t;
+
switch (type) {
case SPA_POD_TYPE_ID:
if ((t = pw_map_lookup(types, *(int32_t *) body)) == NULL)
@@ -131,6 +132,11 @@ static bool pod_remap_data(uint32_t type, void *body, uint32_t size, struct pw_m
struct spa_pod_object_body *b = body;
struct spa_pod *p;
+ if ((t = pw_map_lookup(types, b->id)) != NULL)
+ b->id = PW_MAP_PTR_TO_ID(t);
+ else
+ b->id = SPA_ID_INVALID;
+
if ((t = pw_map_lookup(types, b->type)) == NULL)
return false;
b->type = PW_MAP_PTR_TO_ID(t);
@@ -211,7 +217,7 @@ process_messages(struct client_data *data)
if (!pod_remap_data(SPA_POD_TYPE_STRUCT, message, size, &client->types))
goto invalid_message;
- if (!demarshal[opcode].func (resource, message, size))
+ if (!demarshal[opcode].func(resource, message, size))
goto invalid_message;
}
return;
diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c
index 1f28b4a0..3ab70807 100644
--- a/src/modules/module-protocol-native/connection.c
+++ b/src/modules/module-protocol-native/connection.c
@@ -322,7 +322,7 @@ pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *con
if (debug_messages) {
printf("<<<<<<<<< in: %d %d %zd\n", *dest_id, *opcode, len);
- spa_debug_pod((struct spa_pod *)data);
+ spa_debug_pod((struct spa_pod *)data, 0);
}
return true;
@@ -428,7 +428,7 @@ pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn,
if (debug_messages) {
printf(">>>>>>>>> out: %d %d %d\n", impl->dest_id, impl->opcode, size);
- spa_debug_pod((struct spa_pod *)p);
+ spa_debug_pod((struct spa_pod *)p, 0);
}
spa_hook_list_call(&conn->listener_list, struct pw_protocol_native_connection_events, need_flush);
}
diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c
index 46c13b71..d696e4b2 100644
--- a/src/modules/module-protocol-native/protocol-native.c
+++ b/src/modules/module-protocol-native/protocol-native.c
@@ -117,7 +117,7 @@ core_marshal_create_link(void *object,
uint32_t output_port_id,
uint32_t input_node_id,
uint32_t input_port_id,
- const struct spa_format *filter,
+ const struct spa_pod_object *filter,
const struct spa_dict *props,
uint32_t new_id)
{
@@ -463,7 +463,7 @@ static bool core_demarshal_create_link(void *object, void *data, size_t size)
struct spa_pod_parser prs;
uint32_t new_id, i;
uint32_t output_node_id, output_port_id, input_node_id, input_port_id;
- struct spa_format *filter = NULL;
+ struct spa_pod_object *filter = NULL;
struct spa_dict props;
spa_pod_parser_init(&prs, data, size, 0);
@@ -703,18 +703,18 @@ static void node_marshal_info(void *object, struct pw_node_info *info)
"s", info->name,
"i", info->max_input_ports,
"i", info->n_input_ports,
- "i", info->n_input_formats, NULL);
+ "i", info->n_input_params, NULL);
- for (i = 0; i < info->n_input_formats; i++)
- spa_pod_builder_add(b, "P", info->input_formats[i], NULL);
+ for (i = 0; i < info->n_input_params; i++)
+ spa_pod_builder_add(b, "P", info->input_params[i], NULL);
spa_pod_builder_add(b,
"i", info->max_output_ports,
"i", info->n_output_ports,
- "i", info->n_output_formats, 0);
+ "i", info->n_output_params, 0);
- for (i = 0; i < info->n_output_formats; i++)
- spa_pod_builder_add(b, "P", info->output_formats[i], NULL);
+ for (i = 0; i < info->n_output_params; i++)
+ spa_pod_builder_add(b, "P", info->output_params[i], NULL);
n_items = info->props ? info->props->n_items : 0;
@@ -748,23 +748,23 @@ static bool node_demarshal_info(void *object, void *data, size_t size)
"s", &info.name,
"i", &info.max_input_ports,
"i", &info.n_input_ports,
- "i", &info.n_input_formats, NULL) < 0)
+ "i", &info.n_input_params, NULL) < 0)
return false;
- info.input_formats = alloca(info.n_input_formats * sizeof(struct spa_format *));
- for (i = 0; i < info.n_input_formats; i++)
- if (spa_pod_parser_get(&prs, "P", &info.input_formats[i], NULL) < 0)
+ info.input_params = alloca(info.n_input_params * sizeof(struct spa_pod_object *));
+ for (i = 0; i < info.n_input_params; i++)
+ if (spa_pod_parser_get(&prs, "P", &info.input_params[i], NULL) < 0)
return false;
if (spa_pod_parser_get(&prs,
"i", &info.max_output_ports,
"i", &info.n_output_ports,
- "i", &info.n_output_formats, NULL) < 0)
+ "i", &info.n_output_params, NULL) < 0)
return false;
- info.output_formats = alloca(info.n_output_formats * sizeof(struct spa_format *));
- for (i = 0; i < info.n_output_formats; i++)
- if (spa_pod_parser_get(&prs, "P", &info.output_formats[i], NULL) < 0)
+ info.output_params = alloca(info.n_output_params * sizeof(struct spa_pod_object *));
+ for (i = 0; i < info.n_output_params; i++)
+ if (spa_pod_parser_get(&prs, "P", &info.output_params[i], NULL) < 0)
return false;
if (spa_pod_parser_get(&prs,
diff --git a/src/modules/spa/spa-node.c b/src/modules/spa/spa-node.c
index 70857dde..083a11dd 100644
--- a/src/modules/spa/spa-node.c
+++ b/src/modules/spa/spa-node.c
@@ -154,15 +154,19 @@ static int
setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_properties *pw_props)
{
int res;
- struct spa_props *props;
+ struct spa_pod_object *props;
void *state = NULL;
const char *key;
struct pw_type *t = pw_core_get_type(core);
+ uint32_t index = 0;
+ uint8_t buf[2048];
+ struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
- if ((res = spa_node_get_props(spa_node, &props)) != SPA_RESULT_OK) {
+ if ((res = spa_node_enum_params(spa_node, t->param.idProps, &index, NULL, &b)) != SPA_RESULT_OK) {
pw_log_debug("spa_node_get_props failed: %d", res);
return SPA_RESULT_ERROR;
}
+ props = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
while ((key = pw_properties_iterate(pw_props, &state))) {
struct spa_pod_prop *prop;
@@ -175,7 +179,7 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie
if (id == SPA_ID_INVALID)
continue;
- if ((prop = spa_pod_object_find_prop(&props->object, id))) {
+ if ((prop = spa_pod_object_find_prop(props, id))) {
const char *value = pw_properties_get(pw_props, key);
pw_log_info("configure prop %s", key);
@@ -213,7 +217,7 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie
}
}
- if ((res = spa_node_set_props(spa_node, props)) != SPA_RESULT_OK) {
+ if ((res = spa_node_set_param(spa_node, t->param.idProps, 0, props)) != SPA_RESULT_OK) {
pw_log_debug("spa_node_set_props failed: %d", res);
return SPA_RESULT_ERROR;
}
diff --git a/src/pipewire/core.c b/src/pipewire/core.c
index d2b7adad..bac98c01 100644
--- a/src/pipewire/core.c
+++ b/src/pipewire/core.c
@@ -229,7 +229,7 @@ core_create_link(void *object,
uint32_t output_port_id,
uint32_t input_node_id,
uint32_t input_port_id,
- const struct spa_format *filter,
+ const struct spa_pod_object *filter,
const struct spa_dict *props,
uint32_t new_id)
{
@@ -625,7 +625,7 @@ struct pw_port *pw_core_find_port(struct pw_core *core,
uint32_t id,
struct pw_properties *props,
uint32_t n_format_filters,
- struct spa_format **format_filters,
+ struct spa_pod_object **format_filters,
char **error)
{
struct pw_port *best = NULL;
@@ -658,6 +658,8 @@ struct pw_port *pw_core_find_port(struct pw_core *core,
}
} else {
struct pw_port *p, *pin, *pout;
+ uint8_t buf[4096];
+ struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
p = pw_node_get_free_port(n, pw_direction_reverse(other_port->direction));
if (p == NULL)
@@ -675,11 +677,13 @@ struct pw_port *pw_core_find_port(struct pw_core *core,
pout,
pin,
props,
- n_format_filters, format_filters, error) == NULL) {
+ n_format_filters,
+ format_filters,
+ &b,
+ error) < 0) {
free(*error);
continue;
}
-
best = p;
}
}
@@ -705,18 +709,19 @@ struct pw_port *pw_core_find_port(struct pw_core *core,
*
* \memberof pw_core
*/
-struct spa_format *pw_core_find_format(struct pw_core *core,
- struct pw_port *output,
- struct pw_port *input,
- struct pw_properties *props,
- uint32_t n_format_filters,
- struct spa_format **format_filters,
- char **error)
+int pw_core_find_format(struct pw_core *core,
+ struct pw_port *output,
+ struct pw_port *input,
+ struct pw_properties *props,
+ uint32_t n_format_filters,
+ struct spa_pod_object **format_filters,
+ struct spa_pod_builder *builder,
+ char **error)
{
uint32_t out_state, in_state;
int res;
- struct spa_format *filter = NULL, *format;
uint32_t iidx = 0, oidx = 0;
+ struct pw_type *t = &core->type;
out_state = output->state;
in_state = input->state;
@@ -731,60 +736,71 @@ struct spa_format *pw_core_find_format(struct pw_core *core,
if (in_state == PW_PORT_STATE_CONFIGURE && out_state > PW_PORT_STATE_CONFIGURE) {
/* only input needs format */
- if ((res = spa_node_port_get_format(output->node->node, output->direction, output->port_id,
- (const struct spa_format **) &format)) < 0) {
+ if ((res = spa_node_port_enum_params(output->node->node,
+ output->direction, output->port_id,
+ t->param.idFormat, &oidx,
+ NULL, builder)) < 0) {
asprintf(error, "error get output format: %d", res);
goto error;
}
} else if (out_state == PW_PORT_STATE_CONFIGURE && in_state > PW_PORT_STATE_CONFIGURE) {
/* only output needs format */
- if ((res = spa_node_port_get_format(input->node->node, input->direction, input->port_id,
- (const struct spa_format **) &format)) < 0) {
+ if ((res = spa_node_port_enum_params(input->node->node,
+ input->direction, input->port_id,
+ t->param.idFormat, &iidx,
+ NULL, builder)) < 0) {
asprintf(error, "error get input format: %d", res);
goto error;
}
} else if (in_state == PW_PORT_STATE_CONFIGURE && out_state == PW_PORT_STATE_CONFIGURE) {
+ struct spa_pod_builder fb = { 0 };
+ uint8_t fbuf[4096];
+ struct spa_pod_object *format;
again:
/* both ports need a format */
pw_log_debug("core %p: do enum input %d", core, iidx);
- if ((res = spa_node_port_enum_formats(input->node->node, input->direction, input->port_id,
- &filter, NULL, iidx)) < 0) {
- if (res == SPA_RESULT_ENUM_END && iidx != 0) {
+ spa_pod_builder_init(&fb, fbuf, sizeof(fbuf));
+ if ((res = spa_node_port_enum_params(input->node->node,
+ input->direction, input->port_id,
+ t->param.idEnumFormat, &iidx,
+ NULL, &fb)) < 0) {
+ if (res == SPA_RESULT_ENUM_END && iidx == 0) {
asprintf(error, "error input enum formats: %d", res);
goto error;
}
+ asprintf(error, "no more input formats");
+ goto error;
}
- pw_log_debug("enum output %d with filter: %p", oidx, filter);
+ format = SPA_POD_BUILDER_DEREF(&fb, 0, struct spa_pod_object);
+ pw_log_debug("enum output %d with filter: %p", oidx, format);
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
- spa_debug_format(filter);
+ spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
- if ((res = spa_node_port_enum_formats(output->node->node, output->direction, output->port_id,
- &format, filter, oidx)) < 0) {
+ if ((res = spa_node_port_enum_params(output->node->node,
+ output->direction, output->port_id,
+ t->param.idEnumFormat, &oidx,
+ format, builder)) < 0) {
if (res == SPA_RESULT_ENUM_END) {
oidx = 0;
- iidx++;
goto again;
}
asprintf(error, "error output enum formats: %d", res);
goto error;
}
+ format = SPA_POD_BUILDER_DEREF(&fb, 0, struct spa_pod_object);
+
pw_log_debug("Got filtered:");
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
- spa_debug_format(format);
-
- spa_format_fixate(format);
+ spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
} else {
+ res = SPA_RESULT_ERROR;
asprintf(error, "error node state");
goto error;
}
- if (format == NULL) {
- asprintf(error, "error get format");
- goto error;
- }
- return format;
+ return res;
error:
- return NULL;
+ return res;
}
/** Find a factory by name
diff --git a/src/pipewire/core.h b/src/pipewire/core.h
index d14923c0..20a69e1c 100644
--- a/src/pipewire/core.h
+++ b/src/pipewire/core.h
@@ -159,26 +159,6 @@ bool pw_core_for_each_global(struct pw_core *core,
/** Find a core global by id */
struct pw_global *pw_core_find_global(struct pw_core *core, uint32_t id);
-/** Find a good format between 2 ports */
-struct spa_format *
-pw_core_find_format(struct pw_core *core,
- struct pw_port *output,
- struct pw_port *input,
- struct pw_properties *props,
- uint32_t n_format_filters,
- struct spa_format **format_filters,
- char **error);
-
-/** Find a ports compatible with \a other_port and the format filters */
-struct pw_port *
-pw_core_find_port(struct pw_core *core,
- struct pw_port *other_port,
- uint32_t id,
- struct pw_properties *props,
- uint32_t n_format_filters,
- struct spa_format **format_filters,
- char **error);
-
/** Find a factory by name */
struct pw_factory *
pw_core_find_factory(struct pw_core *core, const char *name);
diff --git a/src/pipewire/interfaces.h b/src/pipewire/interfaces.h
index b20319bc..f761de55 100644
--- a/src/pipewire/interfaces.h
+++ b/src/pipewire/interfaces.h
@@ -157,7 +157,7 @@ struct pw_core_proxy_methods {
uint32_t output_port_id,
uint32_t input_node_id,
uint32_t input_port_id,
- const struct spa_format *filter,
+ const struct spa_pod_object *filter,
const struct spa_dict *props,
uint32_t new_id);
};
@@ -209,7 +209,7 @@ pw_core_proxy_create_link(struct pw_core_proxy *core,
uint32_t output_port_id,
uint32_t input_node_id,
uint32_t input_port_id,
- const struct spa_format *filter,
+ const struct spa_pod_object *filter,
const struct spa_dict *prop,
size_t user_data_size)
{
diff --git a/src/pipewire/introspect.c b/src/pipewire/introspect.c
index d69d2961..77cc3cd0 100644
--- a/src/pipewire/introspect.c
+++ b/src/pipewire/introspect.c
@@ -199,40 +199,40 @@ struct pw_node_info *pw_node_info_update(struct pw_node_info *info,
info->max_input_ports = update->max_input_ports;
info->n_input_ports = update->n_input_ports;
}
- if (update->change_mask & PW_NODE_CHANGE_MASK_INPUT_FORMATS) {
- for (i = 0; i < info->n_input_formats; i++)
- free(info->input_formats[i]);
- info->n_input_formats = update->n_input_formats;
- if (info->n_input_formats)
- info->input_formats =
- realloc(info->input_formats,
- info->n_input_formats * sizeof(struct spa_format *));
+ if (update->change_mask & PW_NODE_CHANGE_MASK_INPUT_PARAMS) {
+ for (i = 0; i < info->n_input_params; i++)
+ free(info->input_params[i]);
+ info->n_input_params = update->n_input_params;
+ if (info->n_input_params)
+ info->input_params =
+ realloc(info->input_params,
+ info->n_input_params * sizeof(struct spa_pod_object *));
else {
- free(info->input_formats);
- info->input_formats = NULL;
+ free(info->input_params);
+ info->input_params = NULL;
}
- for (i = 0; i < info->n_input_formats; i++) {
- info->input_formats[i] = spa_format_copy(update->input_formats[i]);
+ for (i = 0; i < info->n_input_params; i++) {
+ info->input_params[i] = spa_pod_object_copy(update->input_params[i]);
}
}
if (update->change_mask & PW_NODE_CHANGE_MASK_OUTPUT_PORTS) {
info->max_output_ports = update->max_output_ports;
info->n_output_ports = update->n_output_ports;
}
- if (update->change_mask & PW_NODE_CHANGE_MASK_OUTPUT_FORMATS) {
- for (i = 0; i < info->n_output_formats; i++)
- free(info->output_formats[i]);
- info->n_output_formats = update->n_output_formats;
- if (info->n_output_formats)
- info->output_formats =
- realloc(info->output_formats,
- info->n_output_formats * sizeof(struct spa_format *));
+ if (update->change_mask & PW_NODE_CHANGE_MASK_OUTPUT_PARAMS) {
+ for (i = 0; i < info->n_output_params; i++)
+ free(info->output_params[i]);
+ info->n_output_params = update->n_output_params;
+ if (info->n_output_params)
+ info->output_params =
+ realloc(info->output_params,
+ info->n_output_params * sizeof(struct spa_pod_object *));
else {
- free(info->output_formats);
- info->output_formats = NULL;
+ free(info->output_params);
+ info->output_params = NULL;
}
- for (i = 0; i < info->n_output_formats; i++) {
- info->output_formats[i] = spa_format_copy(update->output_formats[i]);
+ for (i = 0; i < info->n_output_params; i++) {
+ info->output_params[i] = spa_pod_object_copy(update->output_params[i]);
}
}
@@ -256,15 +256,15 @@ void pw_node_info_free(struct pw_node_info *info)
if (info->name)
free((void *) info->name);
- if (info->input_formats) {
- for (i = 0; i < info->n_input_formats; i++)
- free(info->input_formats[i]);
- free(info->input_formats);
+ if (info->input_params) {
+ for (i = 0; i < info->n_input_params; i++)
+ free(info->input_params[i]);
+ free(info->input_params);
}
- if (info->output_formats) {
- for (i = 0; i < info->n_output_formats; i++)
- free(info->output_formats[i]);
- free(info->output_formats);
+ if (info->output_params) {
+ for (i = 0; i < info->n_output_params; i++)
+ free(info->output_params[i]);
+ free(info->output_params);
}
if (info->error)
free((void *) info->error);
@@ -414,7 +414,7 @@ struct pw_link_info *pw_link_info_update(struct pw_link_info *info,
if (update->change_mask & PW_LINK_CHANGE_MASK_FORMAT) {
if (info->format)
free(info->format);
- info->format = spa_format_copy(update->format);
+ info->format = spa_pod_object_copy(update->format);
}
return info;
}
diff --git a/src/pipewire/introspect.h b/src/pipewire/introspect.h
index f71dcdd9..c5441558 100644
--- a/src/pipewire/introspect.h
+++ b/src/pipewire/introspect.h
@@ -143,21 +143,21 @@ struct pw_node_info {
uint32_t id; /**< id of the global */
#define PW_NODE_CHANGE_MASK_NAME (1 << 0)
#define PW_NODE_CHANGE_MASK_INPUT_PORTS (1 << 1)
-#define PW_NODE_CHANGE_MASK_INPUT_FORMATS (1 << 2)
+#define PW_NODE_CHANGE_MASK_INPUT_PARAMS (1 << 2)
#define PW_NODE_CHANGE_MASK_OUTPUT_PORTS (1 << 3)
-#define PW_NODE_CHANGE_MASK_OUTPUT_FORMATS (1 << 4)
+#define PW_NODE_CHANGE_MASK_OUTPUT_PARAMS (1 << 4)
#define PW_NODE_CHANGE_MASK_STATE (1 << 5)
#define PW_NODE_CHANGE_MASK_PROPS (1 << 6)
uint64_t change_mask; /**< bitfield of changed fields since last call */
const char *name; /**< name the node, suitable for display */
uint32_t max_input_ports; /**< maximum number of inputs */
uint32_t n_input_ports; /**< number of inputs */
- uint32_t n_input_formats; /**< number of input formats */
- struct spa_format **input_formats; /**< array of input formats */
+ uint32_t n_input_params; /**< number of input params */
+ struct spa_pod_object **input_params; /**< array of input params */
uint32_t max_output_ports; /**< maximum number of outputs */
uint32_t n_output_ports; /**< number of outputs */
- uint32_t n_output_formats; /**< number of output formats */
- struct spa_format **output_formats; /**< array of output formats */
+ uint32_t n_output_params; /**< number of output params */
+ struct spa_pod_object **output_params; /**< array of output params */
enum pw_node_state state; /**< the current state of the node */
const char *error; /**< an error reason if \a state is error */
struct spa_dict *props; /**< the properties of the node */
@@ -200,7 +200,7 @@ struct pw_link_info {
uint32_t output_port_id; /**< output port id */
uint32_t input_node_id; /**< server side input node id */
uint32_t input_port_id; /**< input port id */
- struct spa_format *format; /**< format over link */
+ struct spa_pod_object *format; /**< format over link */
struct spa_dict *props; /**< the properties of the link */
};
diff --git a/src/pipewire/link.c b/src/pipewire/link.c
index 6edc8eb2..cb32f96e 100644
--- a/src/pipewire/link.c
+++ b/src/pipewire/link.c
@@ -43,7 +43,7 @@ struct impl {
struct pw_work_queue *work;
- struct spa_format *format_filter;
+ struct spa_pod_object *format_filter;
struct pw_properties *properties;
struct spa_hook input_port_listener;
@@ -115,11 +115,15 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
{
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
int res = SPA_RESULT_ERROR, res2;
- struct spa_format *format, *current;
+ struct spa_pod_object *format = NULL, *current;
char *error = NULL;
struct pw_resource *resource;
bool changed = true;
struct pw_port *input, *output;
+ uint8_t buffer[4096];
+ struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
+ struct pw_type *t = &this->core->type;
+ uint32_t index = 0;
if (in_state != PW_PORT_STATE_CONFIGURE && out_state != PW_PORT_STATE_CONFIGURE)
return SPA_RESULT_OK;
@@ -129,19 +133,22 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
input = this->input;
output = this->output;
- format = pw_core_find_format(this->core, output, input, NULL, 0, NULL, &error);
- if (format == NULL)
+ if ((res = pw_core_find_format(this->core, output, input, NULL, 0, NULL, &b, &error)) < 0)
goto error;
- format = spa_format_copy(format);
+ format = spa_pod_object_copy(SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object));
+ spa_pod_object_fixate(format);
if (out_state > PW_PORT_STATE_CONFIGURE && output->node->info.state == PW_NODE_STATE_IDLE) {
- if ((res = spa_node_port_get_format(output->node->node, output->direction, output->port_id,
- (const struct spa_format **) &current)) < 0) {
+ if ((res = spa_node_port_enum_params(output->node->node,
+ output->direction, output->port_id,
+ t->param.idFormat, &index,
+ NULL, &b)) < 0) {
asprintf(&error, "error get output format: %d", res);
goto error;
}
- if (spa_format_compare(current, format) < 0) {
+ current = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
+ if (spa_pod_object_compare(current, 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;
@@ -152,12 +159,15 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
}
}
if (in_state > PW_PORT_STATE_CONFIGURE && input->node->info.state == PW_NODE_STATE_IDLE) {
- if ((res = spa_node_port_get_format(input->node->node, input->direction, input->port_id,
- (const struct spa_format **) &current)) < 0) {
+ if ((res = spa_node_port_enum_params(input->node->node,
+ input->direction, input->port_id,
+ t->param.idFormat, &index,
+ NULL, &b)) < 0) {
asprintf(&error, "error get input format: %d", res);
goto error;
}
- if (spa_format_compare(current, format) < 0) {
+ current = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
+ if (spa_pod_object_compare(current, 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;
@@ -170,11 +180,13 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
pw_log_debug("link %p: doing set format %p", this, format);
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
- spa_debug_format(format);
+ spa_debug_pod(&format->pod, SPA_DEBUG_FLAG_FORMAT);
if (out_state == PW_PORT_STATE_CONFIGURE) {
pw_log_debug("link %p: doing set format on output", this);
- if ((res = pw_port_set_format(output, SPA_PORT_FORMAT_FLAG_NEAREST, format)) < 0) {
+ if ((res = pw_port_set_param(output,
+ t->param.idFormat, SPA_NODE_PARAM_FLAG_NEAREST,
+ format)) < 0) {
asprintf(&error, "error set output format: %d", res);
goto error;
}
@@ -184,7 +196,9 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
}
if (in_state == PW_PORT_STATE_CONFIGURE) {
pw_log_debug("link %p: doing set format on input", this);
- if ((res2 = pw_port_set_format(input, SPA_PORT_FORMAT_FLAG_NEAREST, format)) < 0) {
+ if ((res2 = pw_port_set_param(input,
+ t->param.idFormat, SPA_NODE_PARAM_FLAG_NEAREST,
+ format)) < 0) {
asprintf(&error, "error set input format: %d", res2);
goto error;
}
@@ -215,28 +229,28 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
return res;
}
-static struct spa_param *find_param(struct spa_param **params, int n_params, uint32_t type)
+static struct spa_pod_object *find_param(struct spa_pod_object **params, int n_params, uint32_t type)
{
uint32_t i;
for (i = 0; i < n_params; i++) {
- if (spa_pod_is_object_type(&params[i]->object.pod, type))
+ if (spa_pod_is_object_type(&params[i]->pod, type))
return params[i];
}
return NULL;
}
-static struct spa_param *find_meta_enable(struct pw_core *core, struct spa_param **params,
+static struct spa_pod_object *find_meta_enable(struct pw_core *core, struct spa_pod_object **params,
int n_params, uint32_t type)
{
uint32_t i;
for (i = 0; i < n_params; i++) {
if (spa_pod_is_object_type
- (&params[i]->object.pod, core->type.param_alloc_meta_enable.MetaEnable)) {
+ (&params[i]->pod, core->type.param_alloc_meta_enable.MetaEnable)) {
uint32_t qtype;
- if (spa_param_parse(params[i],
+ if (spa_pod_object_parse(params[i],
":", core->type.param_alloc_meta_enable.type, "I", &qtype, NULL) < 0)
continue;
@@ -250,7 +264,7 @@ static struct spa_param *find_meta_enable(struct pw_core *core, struct spa_param
static struct spa_buffer **alloc_buffers(struct pw_link *this,
uint32_t n_buffers,
uint32_t n_params,
- struct spa_param **params,
+ struct spa_pod_object **params,
uint32_t n_datas,
size_t *data_sizes,
ssize_t *data_strides,
@@ -281,10 +295,10 @@ static struct spa_buffer **alloc_buffers(struct pw_link *this,
/* collect metadata */
for (i = 0; i < n_params; i++) {
if (spa_pod_is_object_type
- (&params[i]->object.pod, this->core->type.param_alloc_meta_enable.MetaEnable)) {
+ (&params[i]->pod, this->core->type.param_alloc_meta_enable.MetaEnable)) {
uint32_t type, size;
- if (spa_param_parse(params[i],
+ if (spa_pod_object_parse(params[i],
":", this->core->type.param_alloc_meta_enable.type, "I", &type,
":", this->core->type.param_alloc_meta_enable.size, "i", &size, NULL) < 0)
continue;
@@ -382,38 +396,46 @@ static int
param_filter(struct pw_link *this,
struct pw_port *in_port,
struct pw_port *out_port,
+ uint32_t id,
struct spa_pod_builder *result)
{
int res;
- struct spa_param *oparam, *iparam;
- int iidx, oidx, num = 0;
+ uint8_t ibuf[2048], obuf[2048];
+ struct spa_pod_builder ib = { 0 }, ob = { 0 };
+ struct spa_pod_object *oparam, *iparam;
+ uint32_t iidx, oidx, num = 0;
- for (iidx = 0;; iidx++) {
+ for (iidx = 0;;) {
+ spa_pod_builder_init(&ib, ibuf, sizeof(ibuf));
if (spa_node_port_enum_params(in_port->node->node, in_port->direction, in_port->port_id,
- iidx, &iparam) < 0)
+ id, &iidx, NULL, &ib) < 0)
break;
+ iparam = SPA_POD_BUILDER_DEREF(&ib, 0, struct spa_pod_object);
- for (oidx = 0;; oidx++) {
+ for (oidx = 0;;) {
struct spa_pod_frame f;
uint32_t offset;
+ spa_pod_builder_init(&ob, obuf, sizeof(obuf));
if (spa_node_port_enum_params(out_port->node->node, out_port->direction,
- out_port->port_id, oidx, &oparam) < 0)
+ out_port->port_id, id, &oidx,
+ NULL, &ob) < 0)
break;
+ oparam = SPA_POD_BUILDER_DEREF(&ob, 0, struct spa_pod_object);
- if (iidx == 0 && pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
- spa_debug_param(oparam);
+ if (iidx == 1 && pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
+ spa_debug_pod(&oparam->pod, 0);
- if (iparam->object.body.type != oparam->object.body.type)
+ if (iparam->body.type != oparam->body.type)
continue;
offset = result->offset;
- spa_pod_builder_push_object(result, &f, 0, iparam->object.body.type);
+ spa_pod_builder_push_object(result, &f, id, iparam->body.type);
if ((res = spa_props_filter(result,
- SPA_POD_CONTENTS(struct spa_param, iparam),
- SPA_POD_CONTENTS_SIZE(struct spa_param, iparam),
- SPA_POD_CONTENTS(struct spa_param, oparam),
- SPA_POD_CONTENTS_SIZE(struct spa_param, oparam))) < 0) {
+ 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->stack = NULL;
continue;
@@ -422,7 +444,7 @@ param_filter(struct pw_link *this,
num++;
}
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
- spa_debug_param(iparam);
+ spa_debug_pod(&iparam->pod, 0);
}
return num;
@@ -436,6 +458,7 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
uint32_t in_flags, out_flags;
char *error = NULL;
struct pw_port *input, *output;
+ struct pw_type *t = &this->core->type;
if (in_state != PW_PORT_STATE_READY && out_state != PW_PORT_STATE_READY)
return SPA_RESULT_OK;
@@ -506,34 +529,35 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
}
if (this->buffers == NULL) {
- struct spa_param **params, *param;
+ struct spa_pod_object **params, *param;
uint8_t buffer[4096];
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
int i, offset, n_params;
uint32_t max_buffers;
size_t minsize = 1024, stride = 0;
- n_params = param_filter(this, input, output, &b);
+ n_params = param_filter(this, input, output, t->param.idBuffers, &b);
+ n_params += param_filter(this, input, output, t->param.idMeta, &b);
- params = alloca(n_params * sizeof(struct spa_param *));
+ params = alloca(n_params * sizeof(struct spa_pod_object *));
for (i = 0, offset = 0; i < n_params; i++) {
- params[i] = SPA_MEMBER(buffer, offset, struct spa_param);
- spa_param_fixate(params[i]);
+ params[i] = SPA_MEMBER(buffer, offset, struct spa_pod_object);
+ spa_pod_object_fixate(params[i]);
pw_log_debug("fixated param %d:", i);
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
- spa_debug_param(params[i]);
+ spa_debug_pod(&params[i]->pod, 0);
offset += SPA_ROUND_UP_N(SPA_POD_SIZE(params[i]), 8);
}
param = find_meta_enable(this->core, params, n_params,
- this->core->type.meta.Ringbuffer);
+ t->meta.Ringbuffer);
if (param) {
uint32_t ms, s;
max_buffers = 1;
- if (spa_param_parse(param,
- ":", this->core->type.param_alloc_meta_enable.ringbufferSize, "i", &ms,
- ":", this->core->type.param_alloc_meta_enable.ringbufferStride, "i", &s, NULL) >= 0) {
+ if (spa_pod_object_parse(param,
+ ":", t->param_alloc_meta_enable.ringbufferSize, "i", &ms,
+ ":", t->param_alloc_meta_enable.ringbufferStride, "i", &s, NULL) >= 0) {
minsize = ms;
stride = s;
}
@@ -541,15 +565,15 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
max_buffers = MAX_BUFFERS;
minsize = stride = 0;
param = find_param(params, n_params,
- this->core->type.param_alloc_buffers.Buffers);
+ t->param_alloc_buffers.Buffers);
if (param) {
uint32_t qmax_buffers = max_buffers,
qminsize = minsize, qstride = stride;
- spa_param_parse(param,
- ":", this->core->type.param_alloc_buffers.size, "i", &qminsize,
- ":", this->core->type.param_alloc_buffers.stride, "i", &qstride,
- ":", this->core->type.param_alloc_buffers.buffers, "i", &qmax_buffers, NULL);
+ spa_pod_object_parse(param,
+ ":", t->param_alloc_buffers.size, "i", &qminsize,
+ ":", t->param_alloc_buffers.stride, "i", &qstride,
+ ":", t->param_alloc_buffers.buffers, "i", &qmax_buffers, NULL);
max_buffers =
qmax_buffers == 0 ? max_buffers : SPA_MIN(qmax_buffers,
@@ -1050,7 +1074,7 @@ static const struct pw_node_events output_node_events = {
struct pw_link *pw_link_new(struct pw_core *core,
struct pw_port *output,
struct pw_port *input,
- struct spa_format *format_filter,
+ struct spa_pod_object *format_filter,
struct pw_properties *properties,
char **error,
size_t user_data_size)
diff --git a/src/pipewire/link.h b/src/pipewire/link.h
index 800d5581..7c7353f9 100644
--- a/src/pipewire/link.h
+++ b/src/pipewire/link.h
@@ -81,7 +81,7 @@ struct pw_link *
pw_link_new(struct pw_core *core, /**< the core object */
struct pw_port *output, /**< an output port */
struct pw_port *input, /**< an input port */
- struct spa_format *format_filter, /**< an optional format filter */
+ struct spa_pod_object *format_filter, /**< an optional format filter */
struct pw_properties *properties /**< extra properties */,
char **error, /**< error string when result is NULL */
size_t user_data_size /**< extra user data size */);
diff --git a/src/pipewire/node.c b/src/pipewire/node.c
index d07663bd..3a58c6b0 100644
--- a/src/pipewire/node.c
+++ b/src/pipewire/node.c
@@ -83,14 +83,14 @@ static int suspend_node(struct pw_node *this)
pw_log_debug("node %p: suspend node", this);
spa_list_for_each(p, &this->input_ports, link) {
- if ((res = pw_port_set_format(p, 0, NULL)) < 0)
+ if ((res = pw_port_set_param(p, this->core->type.param.idFormat, 0, NULL)) < 0)
pw_log_warn("error unset format input: %d", res);
/* force CONFIGURE in case of async */
p->state = PW_PORT_STATE_CONFIGURE;
}
spa_list_for_each(p, &this->output_ports, link) {
- if ((res = pw_port_set_format(p, 0, NULL)) < 0)
+ if ((res = pw_port_set_param(p, this->core->type.param.idFormat, 0, NULL)) < 0)
pw_log_warn("error unset format output: %d", res);
/* force CONFIGURE in case of async */
p->state = PW_PORT_STATE_CONFIGURE;
@@ -222,39 +222,52 @@ static int update_port_ids(struct pw_node *node)
static void
update_info(struct pw_node *this)
{
- this->info.input_formats = NULL;
+ uint8_t buffer[4096];
+ struct spa_pod_builder b = { 0 };
+
+ this->info.input_params = NULL;
if (!spa_list_is_empty(&this->input_ports)) {
struct pw_port *port = spa_list_first(&this->input_ports, struct pw_port, link);
+ uint32_t state = 0;
- for (this->info.n_input_formats = 0;; this->info.n_input_formats++) {
- struct spa_format *fmt;
+ for (this->info.n_input_params = 0;; this->info.n_input_params++) {
+ struct spa_pod_object *fmt;
- if (spa_node_port_enum_formats(port->node->node, port->direction, port->port_id,
- &fmt, NULL, this->info.n_input_formats) < 0)
+ spa_pod_builder_init(&b, buffer, sizeof(buffer));
+ if (spa_node_port_enum_params(port->node->node,
+ port->direction, port->port_id,
+ this->core->type.param.idEnumFormat, &state,
+ NULL, &b) < 0)
break;
+ fmt = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
- this->info.input_formats =
- realloc(this->info.input_formats,
- sizeof(struct spa_format *) * (this->info.n_input_formats + 1));
- this->info.input_formats[this->info.n_input_formats] = spa_format_copy(fmt);
+ this->info.input_params =
+ realloc(this->info.input_params,
+ sizeof(struct spa_pod_object *) * (this->info.n_input_params + 1));
+ this->info.input_params[this->info.n_input_params] = spa_pod_object_copy(fmt);
}
}
- this->info.output_formats = NULL;
+ this->info.output_params = NULL;
if (!spa_list_is_empty(&this->output_ports)) {
struct pw_port *port = spa_list_first(&this->output_ports, struct pw_port, link);
+ uint32_t state = 0;
- for (this->info.n_output_formats = 0;; this->info.n_output_formats++) {
- struct spa_format *fmt;
+ for (this->info.n_output_params = 0;; this->info.n_output_params++) {
+ struct spa_pod_object *fmt;
- if (spa_node_port_enum_formats(port->node->node, port->direction, port->port_id,
- &fmt, NULL, this->info.n_output_formats) < 0)
+ spa_pod_builder_init(&b, buffer, sizeof(buffer));
+ if (spa_node_port_enum_params(port->node->node,
+ port->direction, port->port_id,
+ this->core->type.param.idEnumFormat, &state,
+ NULL, &b) < 0)
break;
+ fmt = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
- this->info.output_formats =
- realloc(this->info.output_formats,
- sizeof(struct spa_format *) * (this->info.n_output_formats + 1));
- this->info.output_formats[this->info.n_output_formats] = spa_format_copy(fmt);
+ this->info.output_params =
+ realloc(this->info.output_params,
+ sizeof(struct spa_pod_object *) * (this->info.n_output_params + 1));
+ this->info.output_params[this->info.n_output_params] = spa_pod_object_copy(fmt);
}
}
}
@@ -265,16 +278,16 @@ clear_info(struct pw_node *this)
int i;
free((char*)this->info.name);
- if (this->info.input_formats) {
- for (i = 0; i < this->info.n_input_formats; i++)
- free(this->info.input_formats[i]);
- free(this->info.input_formats);
+ if (this->info.input_params) {
+ for (i = 0; i < this->info.n_input_params; i++)
+ free(this->info.input_params[i]);
+ free(this->info.input_params);
}
- if (this->info.output_formats) {
- for (i = 0; i < this->info.n_output_formats; i++)
- free(this->info.output_formats[i]);
- free(this->info.output_formats);
+ if (this->info.output_params) {
+ for (i = 0; i < this->info.n_output_params; i++)
+ free(this->info.output_params[i]);
+ free(this->info.output_params);
}
free((char*)this->info.error);
diff --git a/src/pipewire/port.c b/src/pipewire/port.c
index c3bf2731..e3fc2eab 100644
--- a/src/pipewire/port.c
+++ b/src/pipewire/port.c
@@ -364,15 +364,16 @@ do_port_pause(struct spa_loop *loop,
&SPA_COMMAND_INIT(node->core->type.command_node.Pause));
}
-int pw_port_set_format(struct pw_port *port, uint32_t flags, const struct spa_format *format)
+int pw_port_set_param(struct pw_port *port, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
int res;
- res = spa_node_port_set_format(port->node->node, port->direction, port->port_id, flags, format);
- pw_log_debug("port %p: set format %d", port, res);
+ res = spa_node_port_set_param(port->node->node, port->direction, port->port_id, id, flags, param);
+ pw_log_debug("port %p: set param %d %d", port, id, res);
- if (!SPA_RESULT_IS_ASYNC(res)) {
- if (format == NULL || res < 0) {
+ if (!SPA_RESULT_IS_ASYNC(res) && id == port->node->core->type.param.idFormat) {
+ if (param == NULL || res < 0) {
if (port->allocated) {
free(port->buffers);
pw_memblock_free(&port->buffer_mem);
@@ -425,7 +426,7 @@ int pw_port_use_buffers(struct pw_port *port, struct spa_buffer **buffers, uint3
}
int pw_port_alloc_buffers(struct pw_port *port,
- struct spa_param **params, uint32_t n_params,
+ struct spa_pod_object **params, uint32_t n_params,
struct spa_buffer **buffers, uint32_t *n_buffers)
{
int res;
diff --git a/src/pipewire/private.h b/src/pipewire/private.h
index 13a2fbc5..50dea0bd 100644
--- a/src/pipewire/private.h
+++ b/src/pipewire/private.h
@@ -389,6 +389,26 @@ struct pw_factory {
void *user_data;
};
+/** Find a good format between 2 ports */
+int pw_core_find_format(struct pw_core *core,
+ struct pw_port *output,
+ struct pw_port *input,
+ struct pw_properties *props,
+ uint32_t n_format_filters,
+ struct spa_pod_object **format_filters,
+ struct spa_pod_builder *builder,
+ char **error);
+
+/** Find a ports compatible with \a other_port and the format filters */
+struct pw_port *
+pw_core_find_port(struct pw_core *core,
+ struct pw_port *other_port,
+ uint32_t id,
+ struct pw_properties *props,
+ uint32_t n_format_filters,
+ struct spa_pod_object **format_filters,
+ char **error);
+
/** Create a new port \memberof pw_port
* \return a newly allocated port */
struct pw_port *
@@ -406,15 +426,16 @@ bool pw_port_add(struct pw_port *port, struct pw_node *node);
/** Destroy a port \memberof pw_port */
void pw_port_destroy(struct pw_port *port);
-/** Set a format on a port \memberof pw_port */
-int pw_port_set_format(struct pw_port *port, uint32_t flags, const struct spa_format *format);
+/** Set a param on a port \memberof pw_port */
+int pw_port_set_param(struct pw_port *port, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param);
/** Use buffers on a port \memberof pw_port */
int pw_port_use_buffers(struct pw_port *port, struct spa_buffer **buffers, uint32_t n_buffers);
/** Allocate memory for buffers on a port \memberof pw_port */
int pw_port_alloc_buffers(struct pw_port *port,
- struct spa_param **params, uint32_t n_params,
+ struct spa_pod_object **params, uint32_t n_params,
struct spa_buffer **buffers, uint32_t *n_buffers);
/** Change the state of the node */
diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c
index 20b60e29..a8c483e0 100644
--- a/src/pipewire/remote.c
+++ b/src/pipewire/remote.c
@@ -639,36 +639,42 @@ static void client_node_transport(void *object, uint32_t node_id,
static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_t change_mask)
{
struct node_data *data = proxy->user_data;
- const struct spa_format *format = NULL;
const struct spa_port_info *port_info = NULL;
struct spa_port_info pi;
- uint32_t n_possible_formats = 0, n_params = 0;
- struct spa_param **params = NULL;
- struct spa_format **possible_formats = NULL;
-
- if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS) {
- if (port->direction == PW_DIRECTION_INPUT) {
- n_possible_formats = data->node->info.n_input_formats;
- possible_formats = data->node->info.input_formats;
- }
- else if (port->direction == PW_DIRECTION_OUTPUT) {
- n_possible_formats = data->node->info.n_output_formats;
- possible_formats = data->node->info.output_formats;
- }
- }
- if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_FORMAT) {
- spa_node_port_get_format(port->node->node, port->direction, port->port_id, &format);
- }
- if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_PARAMS) {
- for (;; n_params++) {
- struct spa_param *param;
+ uint32_t n_params = 0;
+ struct spa_pod_object **params = NULL;
- if (spa_node_port_enum_params(port->node->node, port->direction, port->port_id,
- n_params, &param) < 0)
+ if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_PARAMS) {
+ uint32_t idx1, idx2, id;
+ uint8_t buf[2048];
+ struct spa_pod_builder b = { 0 };
+
+ for (idx1 = 0;;) {
+ struct spa_pod_object *param;
+
+ spa_pod_builder_init(&b, buf, sizeof(buf));
+ if (spa_node_port_enum_params(port->node->node,
+ port->direction, port->port_id,
+ data->t->param.idList, &idx1,
+ NULL, &b) < 0)
break;
-
- params = realloc(params, sizeof(struct spa_param *) * (n_params + 1));
- params[n_params] = spa_param_copy(param);
+ param = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
+
+ spa_pod_object_parse(param,
+ ":", data->t->param.listId, "I", &id, NULL);
+
+ for (idx2 = 0;; n_params++) {
+ spa_pod_builder_init(&b, buf, sizeof(buf));
+ if (spa_node_port_enum_params(port->node->node,
+ port->direction, port->port_id,
+ id, &idx2,
+ NULL, &b) < 0)
+ break;
+ param = SPA_POD_BUILDER_DEREF(&b, 0, struct spa_pod_object);
+
+ params = realloc(params, sizeof(struct spa_pod_object *) * (n_params + 1));
+ params[n_params] = spa_pod_object_copy(param);
+ }
}
}
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_INFO) {
@@ -681,11 +687,8 @@ static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32
port->direction,
port->port_id,
change_mask,
- n_possible_formats,
- (const struct spa_format **) possible_formats,
- format,
n_params,
- (const struct spa_param **) params,
+ (const struct spa_pod_object **)params,
&pi);
if (params) {
while (n_params > 0)
@@ -695,9 +698,10 @@ static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32
}
static void
-client_node_set_props(void *object, uint32_t seq, const struct spa_props *props)
+client_node_set_param(void *object, uint32_t seq, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
- pw_log_warn("set property not implemented");
+ pw_log_warn("set param not implemented");
}
static void client_node_event(void *object, const struct spa_event *event)
@@ -705,6 +709,85 @@ static void client_node_event(void *object, const struct spa_event *event)
pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event));
}
+
+static void node_need_input(void *data)
+{
+ struct node_data *d = data;
+ uint64_t cmd = 1;
+ pw_client_node_transport_add_message(d->trans,
+ &PW_CLIENT_NODE_MESSAGE_INIT(PW_CLIENT_NODE_MESSAGE_NEED_INPUT));
+ write(d->rtwritefd, &cmd, 8);
+}
+
+static void node_have_output(void *data)
+{
+ struct node_data *d = data;
+ uint64_t cmd = 1;
+ pw_client_node_transport_add_message(d->trans,
+ &PW_CLIENT_NODE_MESSAGE_INIT(PW_CLIENT_NODE_MESSAGE_HAVE_OUTPUT));
+ write(d->rtwritefd, &cmd, 8);
+}
+
+static void client_node_command(void *object, uint32_t seq, const struct spa_command *command)
+{
+ struct pw_proxy *proxy = object;
+ struct node_data *data = proxy->user_data;
+ struct pw_remote *remote = proxy->remote;
+ int res;
+
+ if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.Pause) {
+ pw_log_debug("node %p: pause %d", proxy, seq);
+
+ pw_loop_update_io(remote->core->data_loop,
+ data->rtsocket_source,
+ SPA_IO_ERR | SPA_IO_HUP);
+
+ if ((res = spa_node_send_command(data->node->node, command)) < 0)
+ pw_log_warn("node %p: pause failed", proxy);
+
+ pw_client_node_proxy_done(data->node_proxy, seq, res);
+ }
+ else if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.Start) {
+ int i;
+
+ pw_log_debug("node %p: start %d", proxy, seq);
+
+ pw_loop_update_io(remote->core->data_loop,
+ data->rtsocket_source,
+ SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP);
+
+ if ((res = spa_node_send_command(data->node->node, command)) < 0)
+ pw_log_warn("node %p: start failed", proxy);
+
+ /* FIXME we should call process_output on the node and see what its
+ * status is */
+ for (i = 0; i < data->trans->area->max_input_ports; i++)
+ data->trans->inputs[i].status = SPA_RESULT_NEED_BUFFER;
+ node_need_input(data);
+
+ pw_client_node_proxy_done(data->node_proxy, seq, res);
+ }
+ else if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.ClockUpdate) {
+ struct spa_command_node_clock_update *cu = (__typeof__(cu)) command;
+
+#if 0
+ if (cu->body.flags.value & SPA_COMMAND_NODE_CLOCK_UPDATE_FLAG_LIVE) {
+ pw_properties_set(stream->properties, PW_STREAM_PROP_IS_LIVE, "1");
+ pw_properties_setf(stream->properties,
+ PW_STREAM_PROP_LATENCY_MIN, "%" PRId64,
+ cu->body.latency.value);
+ }
+ impl->last_ticks = cu->body.ticks.value;
+ impl->last_rate = cu->body.rate.value;
+ impl->last_monotonic = cu->body.monotonic_time.value;
+#endif
+ }
+ else {
+ pw_log_warn("unhandled node command %d", SPA_COMMAND_TYPE(command));
+ pw_client_node_proxy_done(data->node_proxy, seq, SPA_RESULT_NOT_IMPLEMENTED);
+ }
+}
+
static void
client_node_add_port(void *object, uint32_t seq, enum spa_direction direction, uint32_t port_id)
{
@@ -718,10 +801,11 @@ client_node_remove_port(void *object, uint32_t seq, enum spa_direction direction
}
static void
-client_node_set_format(void *object,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id, uint32_t flags, const struct spa_format *format)
+client_node_port_set_param(void *object,
+ uint32_t seq,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct pw_proxy *proxy = object;
struct node_data *data = proxy->user_data;
@@ -734,12 +818,11 @@ client_node_set_format(void *object,
goto done;
}
- res = pw_port_set_format(port->port, flags, format);
+ res = pw_port_set_param(port->port, id, flags, param);
if (res != SPA_RESULT_OK)
goto done;
add_port_update(proxy, port->port,
- PW_CLIENT_NODE_PORT_UPDATE_FORMAT |
PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
PW_CLIENT_NODE_PORT_UPDATE_INFO);
@@ -747,16 +830,6 @@ client_node_set_format(void *object,
pw_client_node_proxy_done(data->node_proxy, seq, res);
}
-static void
-client_node_set_param(void *object,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
-{
- pw_log_warn("set param not implemented");
-}
-
static struct mem_id *find_mem(struct port *port, uint32_t id)
{
struct mem_id *mid;
@@ -807,11 +880,10 @@ static void clear_port(struct port *port)
}
static void
-client_node_add_mem(void *object,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t mem_id,
- uint32_t type, int memfd, uint32_t flags, uint32_t offset, uint32_t size)
+client_node_port_add_mem(void *object,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t mem_id,
+ uint32_t type, int memfd, uint32_t flags, uint32_t offset, uint32_t size)
{
struct pw_proxy *proxy = object;
struct node_data *data = proxy->user_data;
@@ -837,10 +909,10 @@ client_node_add_mem(void *object,
}
static void
-client_node_use_buffers(void *object,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id, uint32_t n_buffers, struct pw_client_node_buffer *buffers)
+client_node_port_use_buffers(void *object,
+ uint32_t seq,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t n_buffers, struct pw_client_node_buffer *buffers)
{
struct pw_proxy *proxy = object;
struct node_data *data = proxy->user_data;
@@ -964,93 +1036,6 @@ client_node_use_buffers(void *object,
}
-static void node_need_input(void *data)
-{
- struct node_data *d = data;
- uint64_t cmd = 1;
- pw_client_node_transport_add_message(d->trans,
- &PW_CLIENT_NODE_MESSAGE_INIT(PW_CLIENT_NODE_MESSAGE_NEED_INPUT));
- write(d->rtwritefd, &cmd, 8);
-}
-
-static void node_have_output(void *data)
-{
- struct node_data *d = data;
- uint64_t cmd = 1;
- pw_client_node_transport_add_message(d->trans,
- &PW_CLIENT_NODE_MESSAGE_INIT(PW_CLIENT_NODE_MESSAGE_HAVE_OUTPUT));
- write(d->rtwritefd, &cmd, 8);
-}
-
-static bool
-handle_node_command(struct pw_proxy *proxy, uint32_t seq, const struct spa_command *command)
-{
- struct node_data *data = proxy->user_data;
- struct pw_remote *remote = proxy->remote;
- int res;
-
- if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.Pause) {
- pw_log_debug("node %p: pause %d", proxy, seq);
-
- pw_loop_update_io(remote->core->data_loop,
- data->rtsocket_source,
- SPA_IO_ERR | SPA_IO_HUP);
-
- if ((res = spa_node_send_command(data->node->node, command)) < 0)
- pw_log_warn("node %p: pause failed", proxy);
-
- pw_client_node_proxy_done(data->node_proxy, seq, res);
- }
- else if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.Start) {
- int i;
-
- pw_log_debug("node %p: start %d", proxy, seq);
-
- pw_loop_update_io(remote->core->data_loop,
- data->rtsocket_source,
- SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP);
-
- if ((res = spa_node_send_command(data->node->node, command)) < 0)
- pw_log_warn("node %p: start failed", proxy);
-
- /* FIXME we should call process_output on the node and see what its
- * status is */
- for (i = 0; i < data->trans->area->max_input_ports; i++)
- data->trans->inputs[i].status = SPA_RESULT_NEED_BUFFER;
- node_need_input(data);
-
- pw_client_node_proxy_done(data->node_proxy, seq, res);
- }
- else if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.ClockUpdate) {
- struct spa_command_node_clock_update *cu = (__typeof__(cu)) command;
-
-#if 0
- if (cu->body.flags.value & SPA_COMMAND_NODE_CLOCK_UPDATE_FLAG_LIVE) {
- pw_properties_set(stream->properties, PW_STREAM_PROP_IS_LIVE, "1");
- pw_properties_setf(stream->properties,
- PW_STREAM_PROP_LATENCY_MIN, "%" PRId64,
- cu->body.latency.value);
- }
- impl->last_ticks = cu->body.ticks.value;
- impl->last_rate = cu->body.rate.value;
- impl->last_monotonic = cu->body.monotonic_time.value;
-#endif
- }
- else {
- pw_log_warn("unhandled node command %d", SPA_COMMAND_TYPE(command));
- pw_client_node_proxy_done(data->node_proxy, seq, SPA_RESULT_NOT_IMPLEMENTED);
- }
- return true;
-}
-
-
-
-static void client_node_node_command(void *object, uint32_t seq, const struct spa_command *command)
-{
- struct pw_proxy *proxy = object;
- handle_node_command(proxy, seq, command);
-}
-
static void
client_node_port_command(void *object,
uint32_t direction,
@@ -1063,15 +1048,14 @@ client_node_port_command(void *object,
static const struct pw_client_node_proxy_events client_node_events = {
PW_VERSION_CLIENT_NODE_PROXY_EVENTS,
.transport = client_node_transport,
- .set_props = client_node_set_props,
+ .set_param = client_node_set_param,
.event = client_node_event,
+ .command = client_node_command,
.add_port = client_node_add_port,
.remove_port = client_node_remove_port,
- .set_format = client_node_set_format,
- .set_param = client_node_set_param,
- .add_mem = client_node_add_mem,
- .use_buffers = client_node_use_buffers,
- .node_command = client_node_node_command,
+ .port_set_param = client_node_port_set_param,
+ .port_add_mem = client_node_port_add_mem,
+ .port_use_buffers = client_node_port_use_buffers,
.port_command = client_node_port_command,
};
@@ -1083,19 +1067,19 @@ static void do_node_init(struct pw_proxy *proxy)
pw_client_node_proxy_update(data->node_proxy,
PW_CLIENT_NODE_UPDATE_MAX_INPUTS |
PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS |
- PW_CLIENT_NODE_UPDATE_PROPS,
+ PW_CLIENT_NODE_UPDATE_PARAMS,
data->node->info.max_input_ports,
data->node->info.max_output_ports,
- NULL);
+ 0, NULL);
spa_list_for_each(port, &data->node->input_ports, link) {
add_port_update(proxy, port,
- PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS |
+ PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
PW_CLIENT_NODE_PORT_UPDATE_INFO);
}
spa_list_for_each(port, &data->node->output_ports, link) {
add_port_update(proxy, port,
- PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS |
+ PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
PW_CLIENT_NODE_PORT_UPDATE_INFO);
}
pw_client_node_proxy_done(data->node_proxy, 0, SPA_RESULT_OK);
diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c
index 315b4425..25ee5a0f 100644
--- a/src/pipewire/stream.c
+++ b/src/pipewire/stream.c
@@ -64,19 +64,19 @@ struct stream {
uint32_t type_client_node;
- uint32_t n_possible_formats;
- struct spa_format **possible_formats;
+ uint32_t n_init_params;
+ struct spa_pod_object **init_params;
uint32_t n_params;
- struct spa_param **params;
+ struct spa_pod_object **params;
+
+ struct spa_pod_object *format;
- struct spa_format *format;
struct spa_port_info port_info;
enum spa_direction direction;
uint32_t port_id;
uint32_t pending_seq;
- enum pw_stream_mode mode;
enum pw_stream_flags flags;
int rtwritefd;
@@ -307,27 +307,28 @@ static void unhandle_socket(struct pw_stream *stream)
}
static void
-set_possible_formats(struct pw_stream *stream,
- int n_possible_formats, const struct spa_format **possible_formats)
+set_init_params(struct pw_stream *stream,
+ int n_init_params,
+ const struct spa_pod_object **init_params)
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
int i;
- if (impl->possible_formats) {
- for (i = 0; i < impl->n_possible_formats; i++)
- free(impl->possible_formats[i]);
- free(impl->possible_formats);
- impl->possible_formats = NULL;
+ if (impl->init_params) {
+ for (i = 0; i < impl->n_init_params; i++)
+ free(impl->init_params[i]);
+ free(impl->init_params);
+ impl->init_params = NULL;
}
- impl->n_possible_formats = n_possible_formats;
- if (n_possible_formats > 0) {
- impl->possible_formats = malloc(n_possible_formats * sizeof(struct spa_format *));
- for (i = 0; i < n_possible_formats; i++)
- impl->possible_formats[i] = spa_format_copy(possible_formats[i]);
+ impl->n_init_params = n_init_params;
+ if (n_init_params > 0) {
+ impl->init_params = malloc(n_init_params * sizeof(struct spa_pod_object *));
+ for (i = 0; i < n_init_params; i++)
+ impl->init_params[i] = spa_pod_object_copy(init_params[i]);
}
}
-static void set_params(struct pw_stream *stream, int n_params, struct spa_param **params)
+static void set_params(struct pw_stream *stream, int n_params, struct spa_pod_object **params)
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
int i;
@@ -340,9 +341,9 @@ static void set_params(struct pw_stream *stream, int n_params, struct spa_param
}
impl->n_params = n_params;
if (n_params > 0) {
- impl->params = malloc(n_params * sizeof(struct spa_param *));
+ impl->params = malloc(n_params * sizeof(struct spa_pod_object *));
for (i = 0; i < n_params; i++)
- impl->params[i] = spa_param_copy(params[i]);
+ impl->params[i] = spa_pod_object_copy(params[i]);
}
}
@@ -361,7 +362,7 @@ void pw_stream_destroy(struct pw_stream *stream)
spa_list_remove(&stream->link);
- set_possible_formats(stream, 0, NULL);
+ set_init_params(stream, 0, NULL);
set_params(stream, 0, NULL);
if (impl->format)
@@ -396,23 +397,38 @@ static void add_node_update(struct pw_stream *stream, uint32_t change_mask)
max_output_ports = impl->direction == SPA_DIRECTION_OUTPUT ? 1 : 0;
pw_client_node_proxy_update(impl->node_proxy,
- change_mask, max_input_ports, max_output_ports, NULL);
+ change_mask, max_input_ports, max_output_ports,
+ 0, NULL);
}
static void add_port_update(struct pw_stream *stream, uint32_t change_mask)
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
+ uint32_t n_params;
+ struct spa_pod_object **params;
+ int i, j;
+
+ n_params = impl->n_params + impl->n_init_params;
+ if (impl->format)
+ n_params += 1;
+ params = alloca(n_params * sizeof(struct spa_pod_object *));
+
+ j = 0;
+ for (i = 0; i < impl->n_init_params; i++)
+ params[j++] = (struct spa_pod_object *)impl->init_params[i];
+ if (impl->format)
+ params[j++] = impl->format;
+ for (i = 0; i < impl->n_params; i++)
+ params[j++] = impl->params[i];
pw_client_node_proxy_port_update(impl->node_proxy,
impl->direction,
impl->port_id,
change_mask,
- impl->n_possible_formats,
- (const struct spa_format **) impl->possible_formats,
- impl->format,
- impl->n_params,
- (const struct spa_param **) impl->params, &impl->port_info);
+ n_params,
+ (const struct spa_pod_object **) params,
+ &impl->port_info);
}
static inline void send_need_input(struct pw_stream *stream)
@@ -472,8 +488,10 @@ static void do_node_init(struct pw_stream *stream)
PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS);
impl->port_info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS;
- add_port_update(stream, PW_CLIENT_NODE_PORT_UPDATE_POSSIBLE_FORMATS |
- PW_CLIENT_NODE_PORT_UPDATE_INFO);
+
+ add_port_update(stream, PW_CLIENT_NODE_PORT_UPDATE_PARAMS |
+ PW_CLIENT_NODE_PORT_UPDATE_INFO);
+
add_async_complete(stream, 0, SPA_RESULT_OK);
if (!(impl->flags & PW_STREAM_FLAG_INACTIVE))
pw_client_node_proxy_set_active(impl->node_proxy, true);
@@ -639,10 +657,22 @@ static void handle_socket(struct pw_stream *stream, int rtreadfd, int rtwritefd)
return;
}
-static bool
-handle_node_command(struct pw_stream *stream, uint32_t seq, const struct spa_command *command)
+static void
+client_node_set_param(void *data, uint32_t seq, uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
- struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
+ pw_log_warn("set param not implemented");
+}
+
+static void client_node_event(void *data, const struct spa_event *event)
+{
+ pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event));
+}
+
+static void client_node_command(void *data, uint32_t seq, const struct spa_command *command)
+{
+ struct stream *impl = data;
+ struct pw_stream *stream = &impl->this;
struct pw_remote *remote = stream->remote;
if (SPA_COMMAND_TYPE(command) == remote->core->type.command_node.Pause) {
@@ -697,18 +727,6 @@ handle_node_command(struct pw_stream *stream, uint32_t seq, const struct spa_com
pw_log_warn("unhandled node command %d", SPA_COMMAND_TYPE(command));
add_async_complete(stream, seq, SPA_RESULT_NOT_IMPLEMENTED);
}
- return true;
-}
-
-static void
-client_node_set_props(void *data, uint32_t seq, const struct spa_props *props)
-{
- pw_log_warn("set property not implemented");
-}
-
-static void client_node_event(void *data, const struct spa_event *event)
-{
- pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event));
}
static void
@@ -724,45 +742,48 @@ client_node_remove_port(void *data, uint32_t seq, enum spa_direction direction,
}
static void
-client_node_set_format(void *data,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id, uint32_t flags, const struct spa_format *format)
+client_node_port_set_param(void *data,
+ uint32_t seq,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t id, uint32_t flags,
+ const struct spa_pod_object *param)
{
struct stream *impl = data;
struct pw_stream *stream = &impl->this;
+ struct pw_type *t = &stream->remote->core->type;
- pw_log_debug("stream %p: format changed %d", stream, seq);
+ if (id == t->param.idFormat) {
+ pw_log_debug("stream %p: format changed %d", stream, seq);
- if (impl->format)
- free(impl->format);
- impl->format = format ? spa_format_copy(format) : NULL;
- impl->pending_seq = seq;
+ if (impl->format)
+ free(impl->format);
+ if (param) {
+ impl->format = spa_pod_object_copy(param);
+ impl->format->body.id = id;
+ }
+ else
+ impl->format = NULL;
- spa_hook_list_call(&stream->listener_list, struct pw_stream_events, format_changed, impl->format);
+ impl->pending_seq = seq;
- if (format)
- stream_set_state(stream, PW_STREAM_STATE_READY, NULL);
- else
- stream_set_state(stream, PW_STREAM_STATE_CONFIGURE, NULL);
-}
+ spa_hook_list_call(&stream->listener_list,
+ struct pw_stream_events,
+ format_changed, impl->format);
-static void
-client_node_set_param(void *data,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id,
- const struct spa_param *param)
-{
- pw_log_warn("set param not implemented");
+ if (impl->format)
+ stream_set_state(stream, PW_STREAM_STATE_READY, NULL);
+ else
+ stream_set_state(stream, PW_STREAM_STATE_CONFIGURE, NULL);
+ }
+ else
+ pw_log_warn("set param not implemented");
}
static void
-client_node_add_mem(void *data,
- enum spa_direction direction,
- uint32_t port_id,
- uint32_t mem_id,
- uint32_t type, int memfd, uint32_t flags, uint32_t offset, uint32_t size)
+client_node_port_add_mem(void *data,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t mem_id,
+ uint32_t type, int memfd, uint32_t flags, uint32_t offset, uint32_t size)
{
struct stream *impl = data;
struct pw_stream *stream = &impl->this;
@@ -787,10 +808,10 @@ client_node_add_mem(void *data,
}
static void
-client_node_use_buffers(void *data,
- uint32_t seq,
- enum spa_direction direction,
- uint32_t port_id, uint32_t n_buffers, struct pw_client_node_buffer *buffers)
+client_node_port_use_buffers(void *data,
+ uint32_t seq,
+ enum spa_direction direction, uint32_t port_id,
+ uint32_t n_buffers, struct pw_client_node_buffer *buffers)
{
struct stream *impl = data;
struct pw_stream *stream = &impl->this;
@@ -901,13 +922,6 @@ client_node_use_buffers(void *data,
}
}
-static void client_node_node_command(void *data, uint32_t seq, const struct spa_command *command)
-{
- struct stream *impl = data;
- struct pw_stream *this = &impl->this;
- handle_node_command(this, seq, command);
-}
-
static void
client_node_port_command(void *data,
uint32_t direction,
@@ -940,15 +954,14 @@ static void client_node_transport(void *data, uint32_t node_id,
static const struct pw_client_node_proxy_events client_node_events = {
PW_VERSION_CLIENT_NODE_PROXY_EVENTS,
.transport = client_node_transport,
- .set_props = client_node_set_props,
+ .set_param = client_node_set_param,
.event = client_node_event,
+ .command = client_node_command,
.add_port = client_node_add_port,
.remove_port = client_node_remove_port,
- .set_format = client_node_set_format,
- .set_param = client_node_set_param,
- .add_mem = client_node_add_mem,
- .use_buffers = client_node_use_buffers,
- .node_command = client_node_node_command,
+ .port_set_param = client_node_port_set_param,
+ .port_add_mem = client_node_port_add_mem,
+ .port_use_buffers = client_node_port_use_buffers,
.port_command = client_node_port_command,
};
@@ -972,21 +985,19 @@ static const struct pw_proxy_events proxy_events = {
bool
pw_stream_connect(struct pw_stream *stream,
enum pw_direction direction,
- enum pw_stream_mode mode,
const char *port_path,
enum pw_stream_flags flags,
- uint32_t n_possible_formats,
- const struct spa_format **possible_formats)
+ uint32_t n_params,
+ const struct spa_pod_object **params)
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
impl->direction =
direction == PW_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
impl->port_id = 0;
- impl->mode = mode;
impl->flags = flags;
- set_possible_formats(stream, n_possible_formats, possible_formats);
+ set_init_params(stream, n_params, params);
stream_set_state(stream, PW_STREAM_STATE_CONNECTING, NULL);
@@ -1021,7 +1032,9 @@ pw_stream_get_node_id(struct pw_stream *stream)
void
pw_stream_finish_format(struct pw_stream *stream,
- int res, struct spa_param **params, uint32_t n_params)
+ int res,
+ uint32_t n_params,
+ struct spa_pod_object **params)
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
@@ -1030,8 +1043,7 @@ pw_stream_finish_format(struct pw_stream *stream,
set_params(stream, n_params, params);
if (SPA_RESULT_IS_OK(res)) {
- add_port_update(stream, (n_params ? PW_CLIENT_NODE_PORT_UPDATE_PARAMS : 0) |
- PW_CLIENT_NODE_PORT_UPDATE_FORMAT);
+ add_port_update(stream, PW_CLIENT_NODE_PORT_UPDATE_PARAMS);
if (!impl->format) {
clear_buffers(stream);
diff --git a/src/pipewire/stream.h b/src/pipewire/stream.h
index 519824ee..7f8ef23c 100644
--- a/src/pipewire/stream.h
+++ b/src/pipewire/stream.h
@@ -189,9 +189,9 @@ struct pw_stream_events {
void (*state_changed) (void *data, enum pw_stream_state old,
enum pw_stream_state state, const char *error);
/** when the format changed. The listener should call
- * pw_stream_finish_format() from within this callbaclk or later to complete
- * the format negotiation */
- void (*format_changed) (void *data, struct spa_format *format);
+ * pw_stream_finish_format() from within this callback or later to complete
+ * the format negotiation and start the buffer negotiation. */
+ void (*format_changed) (void *data, struct spa_pod_object *format);
/** when a new buffer was created for this stream */
void (*add_buffer) (void *data, uint32_t id);
@@ -217,12 +217,6 @@ enum pw_stream_flags {
PW_STREAM_FLAG_INACTIVE = (1 << 2), /**< start the stream inactive */
};
-/** \enum pw_stream_mode The method for transfering data for a stream \memberof pw_stream */
-enum pw_stream_mode {
- PW_STREAM_MODE_BUFFER = 0, /**< data is placed in buffers */
- PW_STREAM_MODE_RINGBUFFER = 1, /**< a ringbuffer is used to exchange data */
-};
-
/** A time structure \memberof pw_stream */
struct pw_time {
int64_t now; /**< the monotonic time */
@@ -267,12 +261,13 @@ const struct pw_properties *pw_stream_get_properties(struct pw_stream *stream);
bool
pw_stream_connect(struct pw_stream *stream, /**< a \ref pw_stream */
enum pw_direction direction, /**< the stream direction */
- enum pw_stream_mode mode, /**< a \ref pw_stream_mode */
const char *port_path, /**< the port path to connect to or NULL
* to let the server choose a port */
enum pw_stream_flags flags, /**< stream flags */
- uint32_t n_possible_formats, /**< number of items in \a possible_formats */
- const struct spa_format **possible_formats /**< an array with possible accepted formats */);
+ uint32_t n_params, /**< number of items in \a params */
+ const struct spa_pod_object **params /**< an array with params. The params
+ * should ideally contain supported
+ * formats. */);
/** Get the node ID of the stream. \memberof pw_stream
* \return node ID. */
@@ -291,8 +286,10 @@ void pw_stream_disconnect(struct pw_stream *stream);
void
pw_stream_finish_format(struct pw_stream *stream, /**< a \ref pw_stream */
int res, /**< a result code */
- struct spa_param **params, /**< an array of pointers to \ref spa_param */
- uint32_t n_params /**< number of elements in \a params */);
+ uint32_t n_params, /**< number of elements in \a params */
+ struct spa_pod_object **params /**< an array of params. The params should
+ * ideally contain parameters for doing
+ * buffer allocation. */);
/** Activate or deactivate the stream \memberof pw_stream */
void pw_stream_set_active(struct pw_stream *stream, bool active);
diff --git a/src/pipewire/type.c b/src/pipewire/type.c
index 7c7ea1dc..ca89a149 100644
--- a/src/pipewire/type.c
+++ b/src/pipewire/type.c
@@ -52,6 +52,7 @@ void pw_type_init(struct pw_type *type)
type->spa_format = spa_type_map_get_id(type->map, SPA_TYPE__Format);
type->spa_props = spa_type_map_get_id(type->map, SPA_TYPE__Props);
+ spa_type_param_map(type->map, &type->param);
spa_type_meta_map(type->map, &type->meta);
spa_type_data_map(type->map, &type->data);
spa_type_event_node_map(type->map, &type->event_node);
diff --git a/src/pipewire/type.h b/src/pipewire/type.h
index 2268a7d4..14fa8218 100644
--- a/src/pipewire/type.h
+++ b/src/pipewire/type.h
@@ -63,6 +63,7 @@ struct pw_type {
uint32_t spa_format;
uint32_t spa_props;
+ struct spa_type_param param;
struct spa_type_meta meta;
struct spa_type_data data;
struct spa_type_event_node event_node;
diff --git a/src/pipewire/utils.h b/src/pipewire/utils.h
index a23b1882..7d5f0bad 100644
--- a/src/pipewire/utils.h
+++ b/src/pipewire/utils.h
@@ -54,9 +54,7 @@ pw_spa_pod_copy(const struct spa_pod *pod)
return pod ? memcpy(malloc(SPA_POD_SIZE(pod)), pod, SPA_POD_SIZE(pod)) : NULL;
}
-#define spa_format_copy(f) ((struct spa_format*)pw_spa_pod_copy(&(f)->pod))
-#define spa_props_copy(p) ((struct spa_prop*)pw_spa_pod_copy(&(p)->object.pod))
-#define spa_param_copy(p) ((struct spa_param*)pw_spa_pod_copy(&(p)->object.pod))
+#define spa_pod_object_copy(p) ((struct spa_pod_object*)pw_spa_pod_copy(&(p)->pod))
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c
index b744ed28..4fe5725e 100644
--- a/src/tools/pipewire-cli.c
+++ b/src/tools/pipewire-cli.c
@@ -524,20 +524,28 @@ static void info_module(struct proxy_data *pd)
static void info_node(struct proxy_data *pd)
{
struct pw_node_info *info = pd->info;
+ struct pw_type *t = pd->rd->data->t;
int i;
info_global(pd);
fprintf(stdout, "%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name);
fprintf(stdout, "%c\tinput ports: %u/%u\n", MARK_CHANGE(1), info->n_input_ports, info->max_input_ports);
- fprintf(stdout, "%c\tinput formats:\n", MARK_CHANGE(2));
- for (i = 0; i < info->n_input_formats; i++)
- spa_debug_format(info->input_formats[i]);
+ fprintf(stdout, "%c\tinput params:\n", MARK_CHANGE(2));
+ for (i = 0; i < info->n_input_params; i++) {
+ uint32_t flags = 0;
+ if (info->input_params[i]->body.type == t->spa_format)
+ flags |= SPA_DEBUG_FLAG_FORMAT;
+ spa_debug_pod(&info->input_params[i]->pod, flags);
+ }
fprintf(stdout, "%c\toutput ports: %u/%u\n", MARK_CHANGE(3), info->n_output_ports, info->max_output_ports);
- fprintf(stdout, "%c\toutput formats:\n", MARK_CHANGE(4));
- for (i = 0; i < info->n_output_formats; i++)
- spa_debug_format(info->output_formats[i]);
-
+ fprintf(stdout, "%c\toutput params:\n", MARK_CHANGE(4));
+ for (i = 0; i < info->n_output_params; i++) {
+ uint32_t flags = 0;
+ if (info->output_params[i]->body.type == t->spa_format)
+ flags |= SPA_DEBUG_FLAG_FORMAT;
+ spa_debug_pod(&info->output_params[i]->pod, flags);
+ }
fprintf(stdout, "%c\tstate: \"%s\"", MARK_CHANGE(5), pw_node_state_as_string(info->state));
if (info->state == PW_NODE_STATE_ERROR && info->error)
fprintf(stdout, " \"%s\"\n", info->error);
@@ -579,7 +587,7 @@ static void info_link(struct proxy_data *pd)
fprintf(stdout, "%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id);
fprintf(stdout, "%c\tformat:\n", MARK_CHANGE(2));
if (info->format)
- spa_debug_format(info->format);
+ spa_debug_pod(&info->format->pod, SPA_DEBUG_FLAG_FORMAT);
else
fprintf(stdout, "\t\tnone\n");
print_properties(info->props, MARK_CHANGE(3));
diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c
index 3f3a8828..d166187a 100644
--- a/src/tools/pipewire-monitor.c
+++ b/src/tools/pipewire-monitor.c
@@ -128,6 +128,7 @@ static void node_event_info(void *object, struct pw_node_info *info)
{
struct proxy_data *data = object;
bool print_all, print_mark;
+ struct pw_type *t = pw_core_get_type(data->data->core);
print_all = true;
if (data->info == NULL) {
@@ -152,14 +153,22 @@ static void node_event_info(void *object, struct pw_node_info *info)
printf("%c\tname: \"%s\"\n", MARK_CHANGE(0), info->name);
printf("%c\tinput ports: %u/%u\n", MARK_CHANGE(1), info->n_input_ports, info->max_input_ports);
- printf("%c\tinput formats:\n", MARK_CHANGE(2));
- for (i = 0; i < info->n_input_formats; i++)
- spa_debug_format(info->input_formats[i]);
+ printf("%c\tinput params:\n", MARK_CHANGE(2));
+ for (i = 0; i < info->n_input_params; i++) {
+ uint32_t flags = 0;
+ if (info->input_params[i]->body.type == t->spa_format)
+ flags |= SPA_DEBUG_FLAG_FORMAT;
+ spa_debug_pod(&info->input_params[i]->pod, flags);
+ }
printf("%c\toutput ports: %u/%u\n", MARK_CHANGE(3), info->n_output_ports, info->max_output_ports);
- printf("%c\toutput formats:\n", MARK_CHANGE(4));
- for (i = 0; i < info->n_output_formats; i++)
- spa_debug_format(info->output_formats[i]);
+ printf("%c\toutput params:\n", MARK_CHANGE(4));
+ for (i = 0; i < info->n_output_params; i++) {
+ uint32_t flags = 0;
+ if (info->output_params[i]->body.type == t->spa_format)
+ flags |= SPA_DEBUG_FLAG_FORMAT;
+ spa_debug_pod(&info->output_params[i]->pod, flags);
+ }
printf("%c\tstate: \"%s\"", MARK_CHANGE(5), pw_node_state_as_string(info->state));
if (info->state == PW_NODE_STATE_ERROR && info->error)
@@ -274,7 +283,7 @@ static void link_event_info(void *object, struct pw_link_info *info)
printf("%c\tinput-port-id: %u\n", MARK_CHANGE(1), info->input_port_id);
printf("%c\tformat:\n", MARK_CHANGE(2));
if (info->format)
- spa_debug_format(info->format);
+ spa_debug_pod(&info->format->pod, SPA_DEBUG_FLAG_FORMAT);
else
printf("\t\tnone\n");
print_properties(info->props, MARK_CHANGE(3));