node: improve async handling

Remove the done and error callbacks. The error callback is in an
error message. The done callback is replace with spa_pending.

Make enum_params take a callback and data for the results. This allows
us to push the results one after another to the app and avoids ownership
issues of the passed data. We can then extend this to handle the async
case by doing a _wait call with a spa_pending+callback+data that will
be called when the _enum_params returns and async result.
Add a sync method.

All methods can now return SPA_RESULT_IS_ASYNC return values and you
can use spa_node_wait() to register a callback when they complete
with optional extra parameters. This makes it easier to sync and
handle the reply.

Make helper methods to simulate the sync enum_params behaviour for
sync nodes.

Let the transport generate the sequence number for pw_resource_sync()
and pw_proxy_sync(). That way we don't need to keep track of numbers
ourselves and we can match the reply to the request easily.
This commit is contained in:
Wim Taymans 2019-02-20 17:51:05 +01:00
parent b743518f78
commit 7b12212eeb
67 changed files with 1894 additions and 1209 deletions

@ -1 +1 @@
Subproject commit af96643eaa5d3d9df727629e96a0b1f101a16664
Subproject commit 65f9c4652514675b5cc6769d17853aee9542c63f

@ -1 +1 @@
Subproject commit 61edd78bf4a3bba5edab0ba0c10a7d7f12ff3f7a
Subproject commit 71e5c131917b0cad04911f6cb868d44691dbae8d

View file

@ -37,6 +37,7 @@
#include <spa/support/loop.h>
#include <spa/node/node.h>
#include <spa/node/io.h>
#include <spa/node/utils.h>
#include <spa/param/param.h>
#include <spa/param/props.h>
#include <spa/param/audio/format-utils.h>
@ -371,10 +372,10 @@ static int negotiate_formats(struct data *data)
spa_debug_pod(0, NULL, filter);
spa_log_debug(&default_log.log, "enum_params");
if ((res = spa_node_port_enum_params(data->sink,
if ((res = spa_node_port_enum_params_sync(data->sink,
SPA_DIRECTION_INPUT, 0,
SPA_PARAM_EnumFormat, &state,
filter, &format, &b)) <= 0)
filter, &format, &b)) != 1)
return -EBADF;
spa_log_debug(&default_log.log, "sink set_param");

View file

@ -38,12 +38,15 @@
#include <spa/support/loop.h>
#include <spa/node/node.h>
#include <spa/node/io.h>
#include <spa/node/utils.h>
#include <spa/param/param.h>
#include <spa/param/props.h>
#include <spa/param/video/format-utils.h>
#include <spa/debug/pod.h>
static SPA_LOG_IMPL(default_log);
#define PATH "build/spa/plugins/"
#define MAX_BUFFERS 8
@ -58,7 +61,8 @@ struct buffer {
struct data {
struct spa_log *log;
struct spa_loop data_loop;
struct spa_loop *loop;
struct spa_loop_control *control;
struct spa_support support[4];
uint32_t n_support;
@ -87,9 +91,8 @@ struct data {
unsigned int n_buffers;
};
static int make_node(struct data *data, struct spa_node **node, const char *lib, const char *name)
static int load_handle(struct data *data, struct spa_handle **handle, const char *lib, const char *name)
{
struct spa_handle *handle;
int res;
void *hnd;
spa_handle_factory_enum_func_t enum_func;
@ -106,7 +109,6 @@ static int make_node(struct data *data, struct spa_node **node, const char *lib,
for (i = 0;;) {
const struct spa_handle_factory *factory;
void *iface;
if ((res = enum_func(&factory, &i)) <= 0) {
if (res != 0)
@ -116,23 +118,35 @@ static int make_node(struct data *data, struct spa_node **node, const char *lib,
if (strcmp(factory->name, name))
continue;
handle = calloc(1, spa_handle_factory_get_size(factory, NULL));
if ((res =
spa_handle_factory_init(factory, handle, NULL, data->support,
data->n_support)) < 0) {
*handle = calloc(1, spa_handle_factory_get_size(factory, NULL));
if ((res = spa_handle_factory_init(factory, *handle,
NULL, data->support,
data->n_support)) < 0) {
printf("can't make factory instance: %d\n", res);
return res;
}
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Node, &iface)) < 0) {
printf("can't get interface %d\n", res);
return res;
}
*node = iface;
return 0;
}
return -EBADF;
}
static int make_node(struct data *data, struct spa_node **node, const char *lib, const char *name)
{
struct spa_handle *handle = NULL;
void *iface;
int res;
if ((res = load_handle(data, &handle, lib, name)) < 0)
return res;
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Node, &iface)) < 0) {
printf("can't get interface %d\n", res);
return res;
}
*node = iface;
return 0;
}
static void handle_events(struct data *data)
{
SDL_Event event;
@ -159,10 +173,8 @@ static int on_source_ready(void *_data, int status)
handle_events(data);
if ((res = spa_node_process(data->source)) < 0)
printf("got process error %d\n", res);
if (io->buffer_id > MAX_BUFFERS)
if (io->status != SPA_STATUS_HAVE_BUFFER ||
io->buffer_id > MAX_BUFFERS)
return -EINVAL;
b = &data->buffers[io->buffer_id];
@ -221,6 +233,10 @@ static int on_source_ready(void *_data, int status)
}
io->status = SPA_STATUS_NEED_BUFFER;
if ((res = spa_node_process(data->source)) < 0)
printf("got process error %d\n", res);
return 0;
}
@ -229,49 +245,29 @@ static const struct spa_node_callbacks source_callbacks = {
.ready = on_source_ready
};
static int do_add_source(struct spa_loop *loop, struct spa_source *source)
{
struct data *data = SPA_CONTAINER_OF(loop, struct data, data_loop);
data->sources[data->n_sources] = *source;
data->n_sources++;
data->rebuild_fds = true;
return 0;
}
static int do_update_source(struct spa_source *source)
{
return 0;
}
static void do_remove_source(struct spa_source *source)
{
}
static int
do_invoke(struct spa_loop *loop,
spa_invoke_func_t func, uint32_t seq, const void *data, size_t size, bool block, void *user_data)
{
return func(loop, false, seq, data, size, user_data);
}
static int make_nodes(struct data *data, const char *device)
{
int res;
struct spa_pod *props;
struct spa_pod_builder b = { 0 };
uint8_t buffer[256];
uint32_t index;
if ((res =
make_node(data, &data->source, "build/spa/plugins/v4l2/libspa-v4l2.so",
"v4l2-source")) < 0) {
make_node(data, &data->source, PATH "v4l2/libspa-v4l2.so", "v4l2-source")) < 0) {
printf("can't create v4l2-source: %d\n", res);
return res;
}
spa_node_set_callbacks(data->source, &source_callbacks, data);
index = 0;
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if ((res = spa_node_enum_params_sync(data->source, SPA_PARAM_Props,
&index, NULL, &props, &b)) == 1) {
spa_debug_pod(0, NULL, props);
}
spa_pod_builder_init(&b, buffer, sizeof(buffer));
props = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, 0,
@ -422,52 +418,14 @@ static void *loop(void *user_data)
struct data *data = user_data;
printf("enter thread\n");
spa_loop_control_enter(data->control);
while (data->running) {
int r;
unsigned int i;
/* rebuild */
if (data->rebuild_fds) {
for (i = 0; i < data->n_sources; i++) {
struct spa_source *p = &data->sources[i];
data->fds[i].fd = p->fd;
data->fds[i].events = p->mask;
}
data->n_fds = data->n_sources;
data->rebuild_fds = false;
}
r = poll((struct pollfd *) data->fds, data->n_fds, -1);
if (r < 0) {
if (errno == EINTR)
continue;
break;
}
if (r == 0) {
fprintf(stderr, "select timeout");
break;
}
/* after */
for (i = 0; i < data->n_sources; i++) {
struct spa_source *p = &data->sources[i];
p->rmask = 0;
if (data->fds[i].revents & POLLIN)
p->rmask |= SPA_IO_IN;
if (data->fds[i].revents & POLLOUT)
p->rmask |= SPA_IO_OUT;
if (data->fds[i].revents & POLLHUP)
p->rmask |= SPA_IO_HUP;
if (data->fds[i].revents & POLLERR)
p->rmask |= SPA_IO_ERR;
}
for (i = 0; i < data->n_sources; i++) {
struct spa_source *p = &data->sources[i];
if (p->rmask)
p->func(p);
}
spa_loop_control_iterate(data->control, -1);
}
printf("leave thread\n");
spa_loop_control_leave(data->control);
return NULL;
}
@ -507,6 +465,22 @@ int main(int argc, char *argv[])
struct data data = { 0 };
int res;
const char *str;
struct spa_handle *handle = NULL;
void *iface;
if ((res = load_handle(&data, &handle, PATH "support/libspa-support.so", "loop")) < 0)
return res;
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Loop, &iface)) < 0) {
printf("can't get interface %d\n", res);
return res;
}
data.loop = iface;
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_LoopControl, &iface)) < 0) {
printf("can't get interface %d\n", res);
return res;
}
data.control = iface;
data.use_buffer = true;
@ -515,15 +489,9 @@ int main(int argc, char *argv[])
if ((str = getenv("SPA_DEBUG")))
data.log->level = atoi(str);
data.data_loop.version = SPA_VERSION_LOOP;
data.data_loop.add_source = do_add_source;
data.data_loop.update_source = do_update_source;
data.data_loop.remove_source = do_remove_source;
data.data_loop.invoke = do_invoke;
data.support[0] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_Log, data.log);
data.support[1] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_MainLoop, &data.data_loop);
data.support[2] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DataLoop, &data.data_loop);
data.support[1] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_MainLoop, data.loop);
data.support[2] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DataLoop, data.loop);
data.n_support = 3;
if (SDL_Init(SDL_INIT_VIDEO) < 0) {

View file

@ -32,6 +32,7 @@ extern "C" {
struct spa_node;
#include <spa/utils/defs.h>
#include <spa/utils/result.h>
#include <spa/utils/type.h>
#include <spa/support/plugin.h>
@ -97,14 +98,6 @@ struct spa_node_callbacks {
#define SPA_VERSION_NODE_CALLBACKS 0
uint32_t version; /**< version of this structure */
/** Emited as a reply to a sync method with \a seq.
*
* Will be called from the main thread. */
int (*done) (void *data, uint32_t seq);
/** an asynchronous error occured */
int (*error) (void *data, int res, const char *message);
/** Emited when info changes */
int (*info) (void *data, const struct spa_node_info *info);
@ -156,6 +149,12 @@ struct spa_node_callbacks {
#define SPA_NODE_PARAM_FLAG_NEAREST (1 << 2) /* allow set fields to be rounded to the
* nearest allowed field value. */
/** the result of enum_param. */
struct spa_result_node_enum_params {
uint32_t next; /**< next index of iteration */
struct spa_pod *param; /**< the result param */
};
/**
* A spa_node is a component that can consume and produce buffers.
*/
@ -182,13 +181,46 @@ struct spa_node {
/**
* Perform a sync operation.
*
* Calling this method will emit the done event or -EIO when
* no callbacks are installed.
* This method will complete when all previous methods on the node
* are completed.
*
* Because all methods are serialized in the node, this can be used
* to wait for completion of all previous method calls.
*
* If this function returns an async result, use spa_node_wait() to
* install a hook to receive the completion notification.
*
* \return 0 on success
* -EINVAL when node is NULL
* an async result
*/
int (*sync) (struct spa_node *node, uint32_t seq);
int (*sync) (struct spa_node *node);
/**
* Wait for an async function to complete and signal the result
* callback with result parameters.
*
* When a function returns an sync result, pass the async result
* to this function to create a hook that will be called when
* the operation completes.
*
* The generic completion callback can have an optional result.
* Depending on the method, this result will be NULL or point to
* a structure with extra return values. See the documentation
* of the function to see what result structure will be passed.
*
* The hook is automatically removed after the hook is called.
*
* \param node a spa_node
* \param res an async return value to wait for
* \param pending a spa_pending structure
* \param func a result callback
* \param data data passed to \a func
* \return 0 on success
* -EINVAL when node is NULL
*/
int (*wait) (struct spa_node *node, int res, struct spa_pending *pending,
spa_result_func_t func, void *data);
/**
* Enumerate the parameters of a node.
@ -202,23 +234,26 @@ struct spa_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 start the index of enumeration, pass 0 for the first item
* \param num the number of parameters to enumerate
* \param filter and optional filter to use
* \param param result param or NULL
* \param builder builder for the param object.
* \return 1 on success and \a param contains the result
* 0 when there are no more parameters to enumerate
* \param func the callback with the result. The result will be
* of type struct spa_result_node_enum_params. The next field
* can be used to continue the enumeration.
* \param data first argument to \a func
*
* \return the return value of \a func or 0 when no more
* items can be iterated.
* -EINVAL when invalid arguments are given
* -ENOENT the parameter \a id is unknown
* -ENOTSUP when there are no parameters
* implemented on \a node
*/
int (*enum_params) (struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t max,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder);
spa_result_func_t func, void *data);
/**
* Set the configurable parameter in \a node.
*
@ -318,22 +353,25 @@ struct spa_node {
* \param direction an 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 start the first index to query, 0 to get the first item
* \param num the maximum number of params to query
* \param filter a parameter filter or NULL for no filter
* \param param result parameter
* \param builder a builder for the result parameter object
* \return 1 on success
* \param func the callback with the result. The result will be
* of type struct spa_result_node_enum_params. The next field
* can be used to continue the enumeration.
* \param data first argument to \a func
*
* \return the return value of \a func or 0 when no more
* items can be iterated.
* 0 when no more parameters exists
* -EINVAL when invalid parameters are given
* -ENOENT when \a id is unknown
*/
int (*port_enum_params) (struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder);
spa_result_func_t func, void *data);
/**
* Set a parameter on \a port_id of \a node.
*
@ -497,7 +535,8 @@ struct spa_node {
};
#define spa_node_set_callbacks(n,...) (n)->set_callbacks((n),__VA_ARGS__)
#define spa_node_sync(n,...) (n)->sync((n),__VA_ARGS__)
#define spa_node_sync(n) (n)->sync((n))
#define spa_node_wait(n,...) (n)->wait((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_set_io(n,...) (n)->set_io((n),__VA_ARGS__)

View file

@ -0,0 +1,95 @@
/* Simple Plugin API
*
* Copyright © 2019 Wim Taymans
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef SPA_NODE_UTILS_H
#define SPA_NODE_UTILS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/node/node.h>
struct spa_result_node_enum_params_data {
struct spa_pod_builder *builder;
struct spa_result_node_enum_params data;
};
static inline int spa_result_func_node_enum_params(void *data,
int seq, int res, const void *result)
{
struct spa_result_node_enum_params_data *d =
(struct spa_result_node_enum_params_data *)data;
const struct spa_result_node_enum_params *r =
(const struct spa_result_node_enum_params *)result;
if (res == 1) {
uint32_t offset = d->builder->state.offset;
spa_pod_builder_raw_padded(d->builder, r->param, SPA_POD_SIZE(r->param));
d->data.next = r->next;
d->data.param = SPA_MEMBER(d->builder->data, offset, struct spa_pod);
}
return res;
}
static inline int spa_node_enum_params_sync(struct spa_node *node,
uint32_t id, uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct spa_result_node_enum_params_data data = { builder, };
int res;
if ((res = spa_node_enum_params(node, id, *index, 1,
filter, spa_result_func_node_enum_params, &data)) != 1)
return res;
*index = data.data.next;
*param = data.data.param;
return res;
}
static inline int spa_node_port_enum_params_sync(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct spa_result_node_enum_params_data data = { builder, };
int res;
if ((res = spa_node_port_enum_params(node, direction, port_id, id, *index, 1,
filter, spa_result_func_node_enum_params, &data)) != 1)
return res;
*index = data.data.next;
*param = data.data.param;
return res;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SPA_NODE_UTILS_H */

View file

@ -629,6 +629,19 @@ static inline int spa_pod_builder_add(struct spa_pod_builder *builder, ...)
spa_pod_builder_pop(b, &f); \
})
/** Copy a pod structure */
static inline struct spa_pod *
spa_pod_copy(const struct spa_pod *pod)
{
size_t size;
struct spa_pod *c;
size = SPA_POD_SIZE(pod);
if ((c = (struct spa_pod *) malloc(size)) == NULL)
return NULL;
return (struct spa_pod *) memcpy(c, pod, size);
}
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -36,6 +36,7 @@ struct spa_source;
#include <spa/utils/defs.h>
#include <spa/utils/hook.h>
#include <spa/utils/result.h>
enum spa_io {
SPA_IO_IN = (1 << 0),

View file

@ -36,18 +36,6 @@ extern "C" {
#include <stddef.h>
#include <stdio.h>
#define SPA_ASYNC_BIT (1 << 30)
#define SPA_ASYNC_MASK (3 << 30)
#define SPA_ASYNC_SEQ_MASK (SPA_ASYNC_BIT - 1)
#define SPA_RESULT_IS_OK(res) ((res) >= 0)
#define SPA_RESULT_IS_ERROR(res) ((res) < 0)
#define SPA_RESULT_IS_ASYNC(res) (((res) & SPA_ASYNC_MASK) == SPA_ASYNC_BIT)
#define SPA_RESULT_ASYNC_SEQ(res) ((res) & SPA_ASYNC_SEQ_MASK)
#define SPA_RESULT_RETURN_ASYNC(seq) (SPA_ASYNC_BIT | ((seq) & SPA_ASYNC_SEQ_MASK))
#define SPA_FLAG_MASK(field,mask,flag) (((field) & (mask)) == (flag))
#define SPA_FLAG_CHECK(field,flag) SPA_FLAG_MASK(field,flag,flag)
#define SPA_FLAG_SET(field,flag) ((field) |= (flag))

View file

@ -0,0 +1,61 @@
/* Simple Plugin API
*
* Copyright © 2018 Wim Taymans
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef SPA_UTILS_RESULT_H
#define SPA_UTILS_RESULT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <spa/utils/defs.h>
#include <spa/utils/list.h>
#define SPA_ASYNC_BIT (1 << 30)
#define SPA_ASYNC_MASK (3 << 30)
#define SPA_ASYNC_SEQ_MASK (SPA_ASYNC_BIT - 1)
#define SPA_RESULT_IS_OK(res) ((res) >= 0)
#define SPA_RESULT_IS_ERROR(res) ((res) < 0)
#define SPA_RESULT_IS_ASYNC(res) (((res) & SPA_ASYNC_MASK) == SPA_ASYNC_BIT)
#define SPA_RESULT_ASYNC_SEQ(res) ((res) & SPA_ASYNC_SEQ_MASK)
#define SPA_RESULT_RETURN_ASYNC(seq) (SPA_ASYNC_BIT | SPA_RESULT_ASYNC_SEQ(seq))
typedef int (*spa_result_func_t) (void *data, int seq, int res, const void *result);
struct spa_pending {
struct spa_list link;
int seq;
int res;
spa_result_func_t func;
void *data;
void (*removed) (struct spa_pending *pending);
};
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* SPA_UTILS_RESULT_H */

View file

@ -49,22 +49,26 @@ static void reset_props(struct props *props)
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct state *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct state, node);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -74,10 +78,10 @@ static int impl_node_enum_params(struct spa_node *node,
uint32_t list[] = { SPA_PARAM_PropInfo,
SPA_PARAM_Props };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
@ -86,7 +90,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
@ -131,7 +135,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id,
@ -150,12 +154,18 @@ static int impl_node_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size)
@ -265,16 +275,8 @@ static void emit_port_info(struct state *this)
}
static int
impl_node_sync(struct spa_node *node, uint32_t seq)
impl_node_sync(struct spa_node *node)
{
struct state *this;
spa_return_val_if_fail(node != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct state, node);
spa_return_val_if_fail(this->callbacks && this->callbacks->done, -EIO);
this->callbacks->done(this->callbacks_data, seq);
return 0;
}
@ -312,25 +314,29 @@ static int impl_node_remove_port(struct spa_node *node, enum spa_direction direc
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct state *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct state, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -343,21 +349,21 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO, };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
return spa_alsa_enum_format(this, index, filter, result, builder);
return spa_alsa_enum_format(this, start, num, filter, func, data);
case SPA_PARAM_Format:
if (!this->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw);
@ -366,7 +372,7 @@ impl_node_port_enum_params(struct spa_node *node,
case SPA_PARAM_Buffers:
if (!this->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -385,7 +391,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!this->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -398,7 +404,7 @@ impl_node_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -426,12 +432,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct state *this)

View file

@ -49,25 +49,28 @@ static void reset_props(struct props *props)
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct state *this;
struct spa_pod *param;
uint8_t buffer[1024];
struct spa_pod_builder b = { 0 };
struct props *p;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct state, node);
p = &this->props;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -77,16 +80,16 @@ static int impl_node_enum_params(struct spa_node *node,
uint32_t list[] = { SPA_PARAM_PropInfo,
SPA_PARAM_Props, };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_PropInfo:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
@ -128,7 +131,7 @@ static int impl_node_enum_params(struct spa_node *node,
break;
case SPA_PARAM_Props:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id,
@ -147,12 +150,18 @@ static int impl_node_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size)
@ -310,24 +319,28 @@ static void recycle_buffer(struct state *this, uint32_t buffer_id)
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct state *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct state, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -339,21 +352,21 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Buffers,
SPA_PARAM_Meta };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
return spa_alsa_enum_format(this, index, filter, result, builder);
return spa_alsa_enum_format(this, start, num, filter, func, data);
case SPA_PARAM_Format:
if (!this->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw);
@ -362,7 +375,7 @@ impl_node_port_enum_params(struct spa_node *node,
case SPA_PARAM_Buffers:
if (!this->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -381,7 +394,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!this->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -394,7 +407,7 @@ impl_node_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -416,12 +429,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct state *this)

View file

@ -217,10 +217,9 @@ static void sanitize_map(snd_pcm_chmap_t* map)
}
int
spa_alsa_enum_format(struct state *state, uint32_t *index,
spa_alsa_enum_format(struct state *state, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
snd_pcm_t *hndl;
snd_pcm_hw_params_t *params;
@ -237,11 +236,15 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
int res;
bool opened;
struct spa_pod_frame f[2];
struct spa_result_node_enum_params result;
uint32_t count = 0;
opened = state->opened;
if ((err = spa_alsa_open(state)) < 0)
return err;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -313,12 +316,11 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
uint32_t channel;
snd_pcm_chmap_t* map;
if (maps[*index] == NULL) {
res = 0;
if (maps[result.next] == NULL) {
snd_pcm_free_chmaps(maps);
goto exit;
goto enum_end;
}
map = &maps[*index]->map;
map = &maps[result.next]->map;
spa_log_debug(state->log, "map %d channels", map->channels);
sanitize_map(map);
@ -336,10 +338,8 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
snd_pcm_free_chmaps(maps);
}
else {
if (*index > 0) {
res = 0;
goto exit;
}
if (result.next > 0)
goto enum_end;
spa_pod_builder_push_choice(&b, &f[1], SPA_CHOICE_None, 0);
choice = (struct spa_pod_choice*)spa_pod_builder_frame(&b, &f[1]);
@ -354,13 +354,19 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
fmt = spa_pod_builder_pop(&b, &f[0]);
(*index)++;
result.next++;
if ((res = spa_pod_filter(builder, result, fmt, filter)) < 0)
if ((res = spa_pod_filter(&b, &result.param, fmt, filter)) < 0)
goto next;
res = 1;
if ((res = func(data, count, 1, &result)) != 0)
goto exit;
if (++count != num)
goto next;
enum_end:
res = 0;
exit:
if (!opened)
spa_alsa_close(state);

View file

@ -144,10 +144,9 @@ struct state {
int
spa_alsa_enum_format(struct state *state,
uint32_t *index,
uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder);
spa_result_func_t func, void *data);
int spa_alsa_set_format(struct state *state, struct spa_audio_info *info, uint32_t flags);

View file

@ -31,6 +31,7 @@
#include <spa/node/node.h>
#include <spa/buffer/alloc.h>
#include <spa/node/io.h>
#include <spa/node/utils.h>
#include <spa/param/audio/format-utils.h>
#include <spa/param/param.h>
#include <spa/pod/filter.h>
@ -145,11 +146,11 @@ static int debug_params(struct impl *this, struct spa_node *node,
state = 0;
while (true) {
spa_pod_builder_init(&b, buffer, sizeof(buffer));
res = spa_node_port_enum_params(node,
res = spa_node_port_enum_params_sync(node,
direction, port_id,
id, &state,
NULL, &param, &b);
if (res <= 0)
if (res != 1)
break;
spa_debug_pod(2, NULL, param);
@ -177,20 +178,20 @@ static int negotiate_link_format(struct impl *this, struct link *link)
state = 0;
filter = NULL;
if ((res = spa_node_port_enum_params(link->out_node,
if ((res = spa_node_port_enum_params_sync(link->out_node,
SPA_DIRECTION_OUTPUT, link->out_port,
SPA_PARAM_EnumFormat, &state,
filter, &format, &b)) <= 0) {
filter, &format, &b)) != 1) {
debug_params(this, link->out_node, SPA_DIRECTION_OUTPUT, link->out_port,
SPA_PARAM_EnumFormat, filter);
return -ENOTSUP;
}
filter = format;
state = 0;
if ((res = spa_node_port_enum_params(link->in_node,
if ((res = spa_node_port_enum_params_sync(link->in_node,
SPA_DIRECTION_INPUT, link->in_port,
SPA_PARAM_EnumFormat, &state,
filter, &format, &b)) <= 0) {
filter, &format, &b)) != 1) {
debug_params(this, link->in_node, SPA_DIRECTION_INPUT, link->in_port,
SPA_PARAM_EnumFormat, filter);
return -ENOTSUP;
@ -263,19 +264,19 @@ static int negotiate_link_buffers(struct impl *this, struct link *link)
return 0;
state = 0;
if ((res = spa_node_port_enum_params(link->in_node,
if ((res = spa_node_port_enum_params_sync(link->in_node,
SPA_DIRECTION_INPUT, link->in_port,
SPA_PARAM_Buffers, &state,
param, &param, &b)) <= 0) {
param, &param, &b)) != 1) {
debug_params(this, link->out_node, SPA_DIRECTION_OUTPUT, link->out_port,
SPA_PARAM_Buffers, param);
return -ENOTSUP;
}
state = 0;
if ((res = spa_node_port_enum_params(link->out_node,
if ((res = spa_node_port_enum_params_sync(link->out_node,
SPA_DIRECTION_OUTPUT, link->out_port,
SPA_PARAM_Buffers, &state,
param, &param, &b)) <= 0) {
param, &param, &b)) != 1) {
debug_params(this, link->in_node, SPA_DIRECTION_INPUT, link->in_port,
SPA_PARAM_Buffers, param);
return -ENOTSUP;
@ -384,28 +385,32 @@ static int setup_buffers(struct impl *this, enum spa_direction direction)
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (id) {
case SPA_PARAM_EnumProfile:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamProfile, id,
@ -421,9 +426,10 @@ static int impl_node_enum_params(struct spa_node *node,
}
break;
case SPA_PARAM_Props:
switch (*index) {
switch (result.next) {
case 0:
return spa_node_enum_params(this->channelmix, id, index, filter, result, builder);
return spa_node_enum_params(this->channelmix,
id, start, num, filter, func, data);
default:
return 0;
}
@ -432,12 +438,18 @@ static int impl_node_enum_params(struct spa_node *node,
default:
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size)
@ -633,28 +645,34 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (id) {
case SPA_PARAM_PropInfo:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_volume),
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(1.0, 0.0, 10.0));
@ -665,21 +683,21 @@ impl_node_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Buffers),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers)));
break;
case 1:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Range),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_range)));
break;
case 2:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Control),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_sequence)));
@ -690,14 +708,20 @@ impl_node_port_enum_params(struct spa_node *node,
break;
default:
return spa_node_port_enum_params(this->fmt[direction], direction, port_id,
id, index, filter, result, builder);
id, start, num, filter, func, data);
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int

View file

@ -432,22 +432,26 @@ static int setup_convert(struct impl *this,
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -457,10 +461,10 @@ static int impl_node_enum_params(struct spa_node *node,
uint32_t list[] = { SPA_PARAM_PropInfo,
SPA_PARAM_Props };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
@ -469,7 +473,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
@ -493,7 +497,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id,
@ -509,12 +513,18 @@ static int impl_node_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int apply_props(struct impl *this, const struct spa_pod *param)
@ -625,7 +635,7 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
@ -634,7 +644,7 @@ static int port_enum_formats(struct spa_node *node,
other = GET_PORT(this, SPA_DIRECTION_REVERSE(direction), 0);
switch (*index) {
switch (index) {
case 0:
if (other->have_format) {
*param = spa_pod_builder_add_object(builder,
@ -663,21 +673,22 @@ static int port_enum_formats(struct spa_node *node,
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct port *port, *other;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
@ -686,6 +697,8 @@ impl_node_port_enum_params(struct spa_node *node,
port = GET_PORT(this, direction, port_id);
other = GET_PORT(this, SPA_DIRECTION_REVERSE(direction), port_id);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -698,23 +711,24 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &port->format.info.raw);
@ -726,7 +740,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
if (other->n_buffers > 0) {
@ -753,7 +767,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -766,7 +780,7 @@ impl_node_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -787,12 +801,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this, struct port *port)

View file

@ -188,10 +188,9 @@ static int setup_convert(struct impl *this)
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
return -ENOTSUP;
}
@ -276,7 +275,7 @@ static int int32_cmp(const void *v1, const void *v2)
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
@ -287,7 +286,7 @@ static int port_enum_formats(struct spa_node *node,
other = GET_PORT(this, SPA_DIRECTION_REVERSE(direction), 0);
spa_log_debug(this->log, NAME " %p: enum %p", this, other);
switch (*index) {
switch (index) {
case 0:
if (port->have_format) {
*param = spa_format_audio_raw_build(builder,
@ -360,22 +359,22 @@ static int port_enum_formats(struct spa_node *node,
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct port *port, *other;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
@ -384,6 +383,8 @@ impl_node_port_enum_params(struct spa_node *node,
port = GET_PORT(this, direction, port_id);
other = GET_PORT(this, SPA_DIRECTION_REVERSE(direction), port_id);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -396,23 +397,24 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &port->format.info.raw);
@ -425,7 +427,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
if (other->n_buffers > 0) {
@ -453,7 +455,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -466,7 +468,7 @@ impl_node_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -482,12 +484,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int calc_width(struct spa_audio_info *info)

View file

@ -169,17 +169,21 @@ static int init_port(struct impl *this, enum spa_direction direction, uint32_t p
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -188,10 +192,10 @@ static int impl_node_enum_params(struct spa_node *node,
{
uint32_t list[] = { SPA_PARAM_Profile };
if (*index < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(builder,
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
@ -199,12 +203,18 @@ static int impl_node_enum_params(struct spa_node *node,
default:
return 0;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size)
@ -345,14 +355,14 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct port *port = GET_PORT(this, direction, port_id);
switch (*index) {
switch (index) {
case 0:
if (PORT_IS_DSP(direction, port_id) || port->have_format) {
*param = spa_format_audio_raw_build(builder,
@ -392,27 +402,29 @@ static int port_enum_formats(struct spa_node *node,
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct port *port;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
port = GET_PORT(this, direction, port_id);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -428,22 +440,22 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO, };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id, result.next, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &port->format.info.raw);
@ -451,7 +463,7 @@ impl_node_port_enum_params(struct spa_node *node,
case SPA_PARAM_Buffers:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -469,7 +481,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -481,7 +493,7 @@ impl_node_port_enum_params(struct spa_node *node,
}
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -496,12 +508,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this, struct port *port)

View file

@ -157,10 +157,9 @@ static int setup_convert(struct impl *this,
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
return -ENOTSUP;
}
@ -274,7 +273,7 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
@ -284,7 +283,7 @@ static int port_enum_formats(struct spa_node *node,
other = GET_PORT(this, SPA_DIRECTION_REVERSE(direction), 0);
switch (*index) {
switch (index) {
case 0:
if (other->have_format) {
spa_pod_builder_push_object(builder, &f,
@ -320,21 +319,22 @@ static int port_enum_formats(struct spa_node *node,
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct port *port, *other;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
@ -343,6 +343,8 @@ impl_node_port_enum_params(struct spa_node *node,
port = GET_PORT(this, direction, port_id);
other = GET_PORT(this, SPA_DIRECTION_REVERSE(direction), port_id);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -355,22 +357,23 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &port->format.info.raw);
@ -381,7 +384,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
if (other->n_buffers > 0) {
@ -409,7 +412,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -421,7 +424,7 @@ impl_node_port_enum_params(struct spa_node *node,
}
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -442,12 +445,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this, struct port *port)

View file

@ -165,16 +165,22 @@ static int init_port(struct impl *this, enum spa_direction direction,
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -184,10 +190,10 @@ static int impl_node_enum_params(struct spa_node *node,
{
uint32_t list[] = { SPA_PARAM_Profile };
if (*index < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(builder,
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
@ -195,12 +201,18 @@ static int impl_node_enum_params(struct spa_node *node,
default:
return 0;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size)
@ -332,14 +344,14 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
struct port *port = GET_PORT(this, direction, port_id);
switch (*index) {
switch (index) {
case 0:
if (direction == SPA_DIRECTION_OUTPUT || port->have_format) {
*param = spa_format_audio_raw_build(builder,
@ -384,21 +396,22 @@ static int port_enum_formats(struct spa_node *node,
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct port *port;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
@ -406,6 +419,8 @@ impl_node_port_enum_params(struct spa_node *node,
port = GET_PORT(this, direction, port_id);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -420,22 +435,23 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &port->format.info.raw);
@ -443,7 +459,7 @@ impl_node_port_enum_params(struct spa_node *node,
case SPA_PARAM_Buffers:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -462,7 +478,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -474,7 +490,7 @@ impl_node_port_enum_params(struct spa_node *node,
}
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -489,12 +505,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this, struct port *port)

View file

@ -127,10 +127,9 @@ struct impl {
#define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
return -ENOTSUP;
}
@ -278,13 +277,13 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
switch (*index) {
switch (index) {
case 0:
if (this->have_format) {
*param = spa_pod_builder_add_object(builder,
@ -315,22 +314,23 @@ static int port_enum_formats(struct spa_node *node,
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 *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct impl *this;
struct port *port;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
@ -338,6 +338,8 @@ impl_node_port_enum_params(struct spa_node *node,
port = GET_PORT(this, direction, port_id);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -350,22 +352,23 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO, };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &this->format.info.raw);
@ -373,7 +376,7 @@ impl_node_port_enum_params(struct spa_node *node,
case SPA_PARAM_Buffers:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -391,7 +394,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -403,7 +406,7 @@ impl_node_port_enum_params(struct spa_node *node,
}
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -430,12 +433,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this, struct port *port)

View file

@ -126,22 +126,26 @@ struct impl {
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) < MAX_PORTS)
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -151,10 +155,10 @@ static int impl_node_enum_params(struct spa_node *node,
uint32_t list[] = { SPA_PARAM_PropInfo,
SPA_PARAM_Props };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
@ -164,7 +168,7 @@ static int impl_node_enum_params(struct spa_node *node,
struct props *p = &this->props;
struct spa_pod_frame f[2];
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
@ -211,7 +215,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id,
@ -229,12 +233,18 @@ static int impl_node_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
@ -505,11 +515,11 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int
port_enum_formats(struct impl *this,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
switch (*index) {
switch (index) {
case 0:
*param = spa_pod_builder_add_object(builder,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
@ -532,26 +542,29 @@ port_enum_formats(struct impl *this,
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 *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_pod *param;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -564,23 +577,24 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO, };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(this, direction, port_id, index, &param, &b)) <= 0)
if ((res = port_enum_formats(this, direction, port_id,
result.next, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!this->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw);
@ -589,7 +603,7 @@ impl_node_port_enum_params(struct spa_node *node,
case SPA_PARAM_Buffers:
if (!this->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -607,7 +621,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!this->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -619,7 +633,7 @@ impl_node_port_enum_params(struct spa_node *node,
}
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -646,12 +660,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this)

View file

@ -146,22 +146,26 @@ static void reset_props(struct props *props)
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -171,10 +175,10 @@ static int impl_node_enum_params(struct spa_node *node,
uint32_t list[] = { SPA_PARAM_PropInfo,
SPA_PARAM_Props };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
@ -183,7 +187,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
@ -207,7 +211,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id,
@ -223,12 +227,18 @@ static int impl_node_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size)
@ -901,26 +911,30 @@ static int impl_node_remove_port(struct spa_node *node, enum spa_direction direc
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 *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -932,16 +946,16 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Buffers,
SPA_PARAM_Meta };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if (*index > 0)
if (result.next > 0)
return 0;
switch (this->transport->codec) {
@ -987,7 +1001,7 @@ impl_node_port_enum_params(struct spa_node *node,
case SPA_PARAM_Format:
if (!this->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw);
@ -996,7 +1010,7 @@ impl_node_port_enum_params(struct spa_node *node,
case SPA_PARAM_Buffers:
if (!this->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -1015,7 +1029,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!this->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -1031,12 +1045,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this)

View file

@ -73,10 +73,9 @@ struct impl {
};
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
return -ENOTSUP;
}
@ -163,22 +162,19 @@ impl_node_remove_port(struct spa_node *node,
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
//struct impl *this;
if (node == NULL || index == NULL)
return -EINVAL;
//this = SPA_CONTAINER_OF (node, struct impl, node);
if (!IS_VALID_PORT(this, direction, port_id))
return -EINVAL;
switch (*index) {
switch (index) {
case 0:
*param = NULL;
break;
@ -190,7 +186,7 @@ static int port_enum_formats(struct spa_node *node,
static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
@ -203,7 +199,7 @@ static int port_get_format(struct spa_node *node,
if (!port->have_format)
return -EIO;
if (*index > 0)
if (index > 0)
return 0;
*param = NULL;
@ -213,17 +209,20 @@ static int port_get_format(struct spa_node *node,
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 *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_pod *param;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -233,21 +232,23 @@ impl_node_port_enum_params(struct spa_node *node,
uint32_t list[] = { SPA_PARAM_EnumFormat,
SPA_PARAM_Format };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, filter, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if ((res = port_get_format(node, direction, port_id, index, filter, &param, &b)) <= 0)
if ((res = port_get_format(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
@ -255,12 +256,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int port_set_format(struct spa_node *node,

View file

@ -76,10 +76,9 @@ struct impl {
};
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
return -ENOTSUP;
}
@ -164,12 +163,12 @@ impl_node_remove_port(struct spa_node *node,
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
switch (*index) {
switch (index) {
case 0:
*param = NULL;
break;
@ -181,7 +180,7 @@ static int port_enum_formats(struct spa_node *node,
static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
@ -194,7 +193,7 @@ static int port_get_format(struct spa_node *node,
if (!port->have_format)
return -EIO;
if (*index > 0)
if (index > 0)
return 0;
*param = NULL;
@ -204,17 +203,20 @@ static int port_get_format(struct spa_node *node,
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 *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_pod *param;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -224,21 +226,23 @@ impl_node_port_enum_params(struct spa_node *node,
uint32_t list[] = { SPA_PARAM_EnumFormat,
SPA_PARAM_Format };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, filter, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if ((res = port_get_format(node, direction, port_id, index, filter, &param, &b)) <= 0)
if ((res = port_get_format(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
@ -246,12 +250,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int port_set_format(struct spa_node *node,

View file

@ -38,6 +38,7 @@
#include <spa/support/log.h>
#include <spa/support/plugin.h>
#include <spa/utils/list.h>
#include <spa/utils/result.h>
#include <spa/utils/type.h>
#include <spa/utils/ringbuffer.h>

View file

@ -98,27 +98,32 @@ static void reset_props(struct impl *this, struct props *props)
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_pod *param;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (id) {
case SPA_PARAM_List:
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -126,7 +131,7 @@ static int impl_node_enum_params(struct spa_node *node,
SPA_PARAM_LIST_id, SPA_POD_Id(SPA_PARAM_Props));
break;
case SPA_PARAM_Props:
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -137,12 +142,18 @@ static int impl_node_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size)
@ -368,7 +379,7 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
@ -378,7 +389,7 @@ static int port_enum_formats(struct spa_node *node,
static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
@ -388,7 +399,7 @@ static int port_get_format(struct spa_node *node,
if (!this->have_format)
return -EIO;
if (*index > 0)
if (index > 0)
return 0;
*param = SPA_MEMBER(this->format_buffer, 0, struct spa_pod);
@ -398,23 +409,26 @@ static int port_get_format(struct spa_node *node,
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 *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_pod *param;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -426,24 +440,26 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Buffers,
SPA_PARAM_Meta };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, filter, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if ((res = port_get_format(node, direction, port_id, index, filter, &param, &b)) <= 0)
if ((res = port_get_format(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Buffers:
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -455,7 +471,7 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));
break;
case SPA_PARAM_Meta:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -470,12 +486,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this)

View file

@ -102,28 +102,32 @@ static void reset_props(struct impl *this, struct props *props)
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_pod *param;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (id) {
case SPA_PARAM_List:
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -135,7 +139,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -148,12 +152,18 @@ static int impl_node_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size)
@ -384,7 +394,7 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
@ -394,7 +404,7 @@ static int port_enum_formats(struct spa_node *node,
static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
@ -403,7 +413,7 @@ static int port_get_format(struct spa_node *node,
if (!this->have_format)
return -EIO;
if (*index > 0)
if (index > 0)
return 0;
*param = SPA_MEMBER(this->format_buffer, 0, struct spa_pod);
@ -413,23 +423,26 @@ static int port_get_format(struct spa_node *node,
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 *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_pod *param;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -441,36 +454,41 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Buffers,
SPA_PARAM_Meta };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, filter, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if ((res = port_get_format(node, direction, port_id, index, filter, &param, &b)) <= 0)
if ((res = port_get_format(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Buffers:
if (*index > 0)
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamBuffers, id,
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(32, 2, 32),
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
SPA_PARAM_BUFFERS_size, SPA_POD_Int(128),
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(1),
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));
break;
default:
return 0;
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamBuffers, id,
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(32, 2, 32),
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
SPA_PARAM_BUFFERS_size, SPA_POD_Int(128),
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(1),
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));
}
break;
case SPA_PARAM_Meta:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -485,12 +503,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this)

View file

@ -146,23 +146,33 @@ struct impl {
#include "v4l2-utils.c"
static int impl_node_wait(struct spa_node *node, int res, struct spa_pending *pending,
spa_result_func_t func, void *data)
{
return -ENOTSUP;
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -172,10 +182,10 @@ static int impl_node_enum_params(struct spa_node *node,
uint32_t list[] = { SPA_PARAM_PropInfo,
SPA_PARAM_Props };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
@ -184,7 +194,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
@ -215,7 +225,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id,
@ -232,12 +242,18 @@ static int impl_node_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_param(struct spa_node *node,
@ -387,7 +403,7 @@ static int impl_node_remove_port(struct spa_node *node,
static int port_get_format(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
@ -398,7 +414,7 @@ static int port_get_format(struct spa_node *node,
if (!port->have_format)
return -EIO;
if (*index > 0)
if (index > 0)
return 0;
spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, SPA_PARAM_Format);
@ -440,10 +456,9 @@ static int port_get_format(struct spa_node *node,
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
@ -451,11 +466,13 @@ static int impl_node_port_enum_params(struct spa_node *node,
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
@ -463,6 +480,8 @@ static int impl_node_port_enum_params(struct spa_node *node,
port = GET_PORT(this, direction, port_id);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -476,28 +495,29 @@ static int impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_PropInfo:
return spa_v4l2_enum_controls(this, index, filter, result, builder);
return spa_v4l2_enum_controls(this, start, num, filter, func, data);
case SPA_PARAM_EnumFormat:
return spa_v4l2_enum_format(this, index, filter, result, builder);
return spa_v4l2_enum_format(this, start, num, filter, func, data);
case SPA_PARAM_Format:
if((res = port_get_format(node, direction, port_id, index, filter, &param, &b)) <= 0)
if((res = port_get_format(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Buffers:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -510,7 +530,7 @@ static int impl_node_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_Meta:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -522,7 +542,7 @@ static int impl_node_port_enum_params(struct spa_node *node,
}
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -549,12 +569,18 @@ static int impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int port_set_format(struct spa_node *node,
@ -880,11 +906,12 @@ static int impl_node_process(struct spa_node *node)
static const struct spa_node impl_node = {
SPA_VERSION_NODE,
.set_callbacks = impl_node_set_callbacks,
.wait = impl_node_wait,
.enum_params = impl_node_enum_params,
.set_param = impl_node_set_param,
.set_io = impl_node_set_io,
.send_command = impl_node_send_command,
.set_callbacks = impl_node_set_callbacks,
.add_port = impl_node_add_port,
.remove_port = impl_node_remove_port,
.port_enum_params = impl_node_port_enum_params,
@ -942,7 +969,9 @@ impl_init(const struct spa_handle_factory *factory,
spa_return_val_if_fail(handle != NULL, -EINVAL);
handle->get_interface = impl_get_interface;
handle->clear = impl_clear, this = (struct impl *) handle;
handle->clear = impl_clear;
this = (struct impl *) handle;
for (i = 0; i < n_support; i++) {
if (support[i].type == SPA_TYPE_INTERFACE_Log)

View file

@ -521,10 +521,9 @@ filter_framerate(struct v4l2_frmivalenum *frmival,
static int
spa_v4l2_enum_format(struct impl *this,
uint32_t *index,
uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct port *port = &this->out_ports[0];
int res, n_fractions;
@ -532,12 +531,18 @@ spa_v4l2_enum_format(struct impl *this,
struct spa_pod_choice *choice;
uint32_t filter_media_type, filter_media_subtype, video_format;
struct spa_v4l2_device *dev = &port->dev;
uint8_t buffer[1024];
struct spa_pod_builder b = { 0 };
struct spa_pod_frame f[2];
struct spa_result_node_enum_params result;
uint32_t count = 0;
if ((res = spa_v4l2_open(dev, this->props.device)) < 0)
return res;
if (*index == 0) {
result.next = start;
if (result.next == 0) {
spa_zero(port->fmtdesc);
port->fmtdesc.index = 0;
port->fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@ -558,6 +563,7 @@ spa_v4l2_enum_format(struct impl *this,
port->next_fmtdesc = true;
}
next:
while (port->next_fmtdesc) {
if (filter) {
video_format = enum_filter_format(filter_media_type,
@ -681,25 +687,26 @@ spa_v4l2_enum_format(struct impl *this,
}
}
spa_pod_builder_push_object(builder, &f[0], SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
spa_pod_builder_add(builder,
spa_pod_builder_init(&b, buffer, sizeof(buffer));
spa_pod_builder_push_object(&b, &f[0], SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat);
spa_pod_builder_add(&b,
SPA_FORMAT_mediaType, SPA_POD_Id(info->media_type),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(info->media_subtype),
0);
if (info->media_subtype == SPA_MEDIA_SUBTYPE_raw) {
spa_pod_builder_prop(builder, SPA_FORMAT_VIDEO_format, 0);
spa_pod_builder_id(builder, info->format);
spa_pod_builder_prop(&b, SPA_FORMAT_VIDEO_format, 0);
spa_pod_builder_id(&b, info->format);
}
spa_pod_builder_prop(builder, SPA_FORMAT_VIDEO_size, 0);
spa_pod_builder_rectangle(builder, port->frmsize.discrete.width, port->frmsize.discrete.height);
spa_pod_builder_prop(&b, SPA_FORMAT_VIDEO_size, 0);
spa_pod_builder_rectangle(&b, port->frmsize.discrete.width, port->frmsize.discrete.height);
spa_pod_builder_prop(builder, SPA_FORMAT_VIDEO_framerate, 0);
spa_pod_builder_prop(&b, SPA_FORMAT_VIDEO_framerate, 0);
n_fractions = 0;
spa_pod_builder_push_choice(builder, &f[1], SPA_CHOICE_None, 0);
choice = (struct spa_pod_choice*)spa_pod_builder_frame(builder, &f[1]);
spa_pod_builder_push_choice(&b, &f[1], SPA_CHOICE_None, 0);
choice = (struct spa_pod_choice*)spa_pod_builder_frame(&b, &f[1]);
port->frmival.index = 0;
while (true) {
@ -765,21 +772,21 @@ spa_v4l2_enum_format(struct impl *this,
if (port->frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
choice->body.type = SPA_CHOICE_Enum;
if (n_fractions == 0)
spa_pod_builder_fraction(builder,
spa_pod_builder_fraction(&b,
port->frmival.discrete.denominator,
port->frmival.discrete.numerator);
spa_pod_builder_fraction(builder,
spa_pod_builder_fraction(&b,
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(builder, 25, 1);
spa_pod_builder_fraction(builder,
spa_pod_builder_fraction(&b, 25, 1);
spa_pod_builder_fraction(&b,
port->frmival.stepwise.min.denominator,
port->frmival.stepwise.min.numerator);
spa_pod_builder_fraction(builder,
spa_pod_builder_fraction(&b,
port->frmival.stepwise.max.denominator,
port->frmival.stepwise.max.numerator);
@ -787,7 +794,7 @@ spa_v4l2_enum_format(struct impl *this,
choice->body.type = SPA_CHOICE_Range;
} else {
choice->body.type = SPA_CHOICE_Step;
spa_pod_builder_fraction(builder,
spa_pod_builder_fraction(&b,
port->frmival.stepwise.step.denominator,
port->frmival.stepwise.step.numerator);
}
@ -801,21 +808,21 @@ spa_v4l2_enum_format(struct impl *this,
if (n_fractions <= 1)
choice->body.type = SPA_CHOICE_None;
spa_pod_builder_pop(builder, &f[1]);
*result = spa_pod_builder_pop(builder, &f[0]);
spa_pod_builder_pop(&b, &f[1]);
result.param = spa_pod_builder_pop(&b, &f[0]);
result.next++;
(*index)++;
if ((res = func(data, count, 1, &result)) != 0)
goto exit;
res = 1;
if (++count != num)
goto next;
enum_end:
res = 0;
exit:
spa_v4l2_close(dev);
return res;
enum_end:
res = 0;
goto exit;
}
static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format, bool try_only)
@ -999,10 +1006,9 @@ static uint32_t control_to_prop_id(struct impl *impl, uint32_t control_id)
static int
spa_v4l2_enum_controls(struct impl *this,
uint32_t *index,
uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct port *port = &this->out_ports[0];
struct spa_v4l2_device *dev = &port->dev;
@ -1014,19 +1020,23 @@ spa_v4l2_enum_controls(struct impl *this,
int res;
const unsigned next_fl = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
struct spa_pod_frame f[2];
struct spa_result_node_enum_params result;
uint32_t count = 0;
if ((res = spa_v4l2_open(dev, this->props.device)) < 0)
return res;
result.next = start;
next:
spa_zero(queryctrl);
if (*index == 0) {
*index |= next_fl;
if (result.next == 0) {
result.next |= next_fl;
port->n_controls = 0;
}
queryctrl.id = *index;
queryctrl.id = result.next;
spa_log_debug(this->log, "test control %08x", queryctrl.id);
if (query_ext_ctrl_ioctl(port, &queryctrl) != 0) {
@ -1034,12 +1044,12 @@ spa_v4l2_enum_controls(struct impl *this,
if (queryctrl.id != next_fl)
goto enum_end;
if (*index & next_fl)
*index = V4L2_CID_USER_BASE;
else if (*index >= V4L2_CID_USER_BASE && *index < V4L2_CID_LASTP1)
(*index)++;
else if (*index >= V4L2_CID_LASTP1)
*index = V4L2_CID_PRIVATE_BASE;
if (result.next & next_fl)
result.next = V4L2_CID_USER_BASE;
else if (result.next >= V4L2_CID_USER_BASE && result.next < V4L2_CID_LASTP1)
result.next++;
else if (result.next >= V4L2_CID_LASTP1)
result.next = V4L2_CID_PRIVATE_BASE;
else
goto enum_end;
goto next;
@ -1048,10 +1058,10 @@ spa_v4l2_enum_controls(struct impl *this,
spa_log_error(this->log, "VIDIOC_QUERYCTRL: %m");
return res;
}
if (*index & next_fl)
(*index) = queryctrl.id | next_fl;
if (result.next & next_fl)
result.next = queryctrl.id | next_fl;
else
(*index)++;
result.next++;
if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
goto next;
@ -1129,19 +1139,20 @@ spa_v4l2_enum_controls(struct impl *this,
goto next;
}
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
res = 1;
if ((res = func(data, count, 1, &result)) != 0)
goto exit;
if (++count != num)
goto next;
enum_end:
res = 0;
exit:
spa_v4l2_close(dev);
return res;
enum_end:
res = 0;
goto exit;
}
static int mmap_read(struct impl *this)

View file

@ -111,21 +111,26 @@ struct impl {
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) < MAX_PORTS)
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -135,10 +140,10 @@ static int impl_node_enum_params(struct spa_node *node,
uint32_t list[] = { SPA_PARAM_PropInfo,
SPA_PARAM_Props };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
@ -148,7 +153,7 @@ static int impl_node_enum_params(struct spa_node *node,
struct props *p = &this->props;
struct spa_pod_frame f[2];
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
@ -181,7 +186,7 @@ static int impl_node_enum_params(struct spa_node *node,
{
struct props *p = &this->props;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id,
@ -197,12 +202,18 @@ static int impl_node_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size)
@ -448,12 +459,12 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
switch (*index) {
switch (index) {
case 0:
*param = spa_pod_builder_add_object(builder,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
@ -480,26 +491,29 @@ static int port_enum_formats(struct spa_node *node,
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 *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_pod *param;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -511,26 +525,27 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Buffers,
SPA_PARAM_Meta };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, filter, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!this->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_video_raw_build(builder, id, &this->current_format.info.raw);
param = spa_format_video_raw_build(&b, id, &this->current_format.info.raw);
break;
case SPA_PARAM_Buffers:
@ -539,7 +554,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!this->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -555,7 +570,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!this->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -571,12 +586,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this)

View file

@ -103,24 +103,28 @@ struct impl {
#define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_pod *param;
struct props *p;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
p = &this->props;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -130,16 +134,16 @@ static int impl_node_enum_params(struct spa_node *node,
uint32_t list[] = { SPA_PARAM_PropInfo,
SPA_PARAM_Props };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_PropInfo:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
@ -159,7 +163,7 @@ static int impl_node_enum_params(struct spa_node *node,
}
break;
case SPA_PARAM_Props:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Props, id,
@ -174,12 +178,18 @@ static int impl_node_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size)
@ -283,12 +293,12 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
switch (*index) {
switch (index) {
case 0:
*param = spa_pod_builder_add_object(builder,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
@ -309,22 +319,23 @@ static int port_enum_formats(struct spa_node *node,
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 *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
spa_result_func_t func, void *data)
{
struct impl *this;
struct port *port;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_pod *param;
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
@ -344,23 +355,24 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, filter, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id,
result.next, filter, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw);
@ -369,7 +381,7 @@ impl_node_port_enum_params(struct spa_node *node,
case SPA_PARAM_Buffers:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -384,7 +396,7 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));
break;
case SPA_PARAM_Meta:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -396,7 +408,7 @@ impl_node_port_enum_params(struct spa_node *node,
}
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -417,12 +429,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this, struct port *port)

View file

@ -32,6 +32,7 @@
#include <spa/support/log-impl.h>
#include <spa/support/loop.h>
#include <spa/node/node.h>
#include <spa/node/utils.h>
#include <spa/pod/parser.h>
#include <spa/param/param.h>
#include <spa/param/format.h>
@ -63,9 +64,9 @@ inspect_node_params(struct data *data, struct spa_node *node)
uint32_t id;
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if ((res = spa_node_enum_params(node,
if ((res = spa_node_enum_params_sync(node,
SPA_PARAM_List, &idx1,
NULL, &param, &b)) <= 0) {
NULL, &param, &b)) != 1) {
if (res != 0)
error(0, -res, "enum_params");
break;
@ -78,9 +79,9 @@ inspect_node_params(struct data *data, struct spa_node *node)
printf("enumerating: %s:\n", spa_debug_type_find_name(spa_type_param, id));
for (idx2 = 0;;) {
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if ((res = spa_node_enum_params(node,
if ((res = spa_node_enum_params_sync(node,
id, &idx2,
NULL, &param, &b)) <= 0) {
NULL, &param, &b)) != 1) {
if (res != 0)
error(0, -res, "enum_params %d", id);
break;
@ -104,10 +105,10 @@ inspect_port_params(struct data *data, struct spa_node *node,
uint32_t id;
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if ((res = spa_node_port_enum_params(node,
if ((res = spa_node_port_enum_params_sync(node,
direction, port_id,
SPA_PARAM_List, &idx1,
NULL, &param, &b)) <= 0) {
NULL, &param, &b)) != 1) {
if (res != 0)
error(0, -res, "port_enum_params");
break;
@ -119,10 +120,10 @@ inspect_port_params(struct data *data, struct spa_node *node,
printf("enumerating: %s:\n", spa_debug_type_find_name(spa_type_param, id));
for (idx2 = 0;;) {
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if ((res = spa_node_port_enum_params(node,
if ((res = spa_node_port_enum_params_sync(node,
direction, port_id,
id, &idx2,
NULL, &param, &b)) <= 0) {
NULL, &param, &b)) != 1) {
if (res != 0)
error(0, -res, "port_enum_params");
break;

View file

@ -30,6 +30,7 @@
#include <spa/param/props.h>
#include <spa/node/io.h>
#include <spa/control/control.h>
#include <spa/pod/filter.h>
#include <spa/debug/format.h>
#include <spa/debug/pod.h>
@ -179,36 +180,24 @@ static int impl_port_set_io(struct spa_node *node,
return 0;
}
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
SDL_RendererInfo info;
if (*index != 0)
return 0;
SDL_GetRendererInfo(d->renderer, &info);
*result = sdl_build_formats(&info, builder);
(*index)++;
return 1;
}
static int impl_port_enum_params(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (id) {
case SPA_PARAM_List:
@ -219,28 +208,36 @@ static int impl_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO };
if (*index < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(builder,
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
return port_enum_formats(node, direction, port_id, index, filter, result, builder);
{
SDL_RendererInfo info;
case SPA_PARAM_Format:
if (*index != 0 || d->format.format == 0)
if (result.next != 0)
return 0;
param = spa_format_video_raw_build(builder, id, &d->format);
SDL_GetRendererInfo(d->renderer, &info);
param = sdl_build_formats(&info, &b);
break;
}
case SPA_PARAM_Format:
if (result.next != 0 || d->format.format == 0)
return 0;
param = spa_format_video_raw_build(&b, id, &d->format);
break;
case SPA_PARAM_Buffers:
if (*index != 0)
if (result.next != 0)
return 0;
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamBuffers, id,
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 2, MAX_BUFFERS),
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
@ -250,15 +247,15 @@ static int impl_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_Meta:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
break;
case 1:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_VideoDamage),
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_region)));
@ -269,15 +266,15 @@ static int impl_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Buffers),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers)));
break;
case 1:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Notify),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_sequence) + 1024));
@ -289,12 +286,18 @@ static int impl_port_enum_params(struct spa_node *node,
default:
return -ENOENT;
}
result.next++;
(*index)++;
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
*result = param;
if ((res = func(data, count, 1, &result)) != 0)
return res;
return 1;
if (++count != num)
goto next;
return 0;
}
static int port_set_format(struct spa_node *node,

View file

@ -30,6 +30,7 @@
#include <spa/param/audio/format-utils.h>
#include <spa/param/props.h>
#include <spa/node/io.h>
#include <spa/pod/filter.h>
#include <spa/debug/format.h>
#include <pipewire/pipewire.h>
@ -147,43 +148,24 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction,
return 0;
}
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
if (*index != 0)
return 0;
*param = spa_pod_builder_add_object(builder,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(5,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S16P,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_F32P,
SPA_AUDIO_FORMAT_F32),
SPA_FORMAT_AUDIO_channels, SPA_POD_CHOICE_RANGE_Int(2, 1, INT32_MAX),
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(44100, 1, INT32_MAX));
(*index)++;
return 1;
}
static int impl_port_enum_params(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (id) {
case SPA_PARAM_List:
@ -194,30 +176,45 @@ static int impl_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO };
if (*index < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(builder,
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
return port_enum_formats(node, direction, port_id, index, filter, result, builder);
if (result.next != 0)
return 0;
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
SPA_FORMAT_AUDIO_format, SPA_POD_CHOICE_ENUM_Id(5,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_S16P,
SPA_AUDIO_FORMAT_S16,
SPA_AUDIO_FORMAT_F32P,
SPA_AUDIO_FORMAT_F32),
SPA_FORMAT_AUDIO_channels, SPA_POD_CHOICE_RANGE_Int(2, 1, INT32_MAX),
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(44100, 1, INT32_MAX));
break;
case SPA_PARAM_Format:
if (*index != 0)
if (result.next != 0)
return 0;
if (d->format.format == 0)
return 0;
param = spa_format_audio_raw_build(builder, id, &d->format);
param = spa_format_audio_raw_build(&b, id, &d->format);
break;
case SPA_PARAM_Buffers:
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamBuffers, id,
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(1, 1, 32),
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
@ -227,9 +224,9 @@ static int impl_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_Meta:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
@ -239,15 +236,15 @@ static int impl_port_enum_params(struct spa_node *node,
}
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Buffers),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_buffers)));
break;
case 1:
param = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
SPA_PARAM_IO_id, SPA_POD_Id(SPA_IO_Notify),
SPA_PARAM_IO_size, SPA_POD_Int(sizeof(struct spa_io_sequence) + 1024));
@ -260,10 +257,18 @@ static int impl_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
*result = param;
result.next++;
return 1;
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int port_set_format(struct spa_node *node,

View file

@ -33,6 +33,7 @@
#include <spa/param/video/format-utils.h>
#include <spa/param/props.h>
#include <spa/pod/filter.h>
#include <spa/node/io.h>
#include <spa/debug/format.h>
@ -121,45 +122,42 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction,
return 0;
}
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
SDL_RendererInfo info;
if (*index != 0)
return 0;
SDL_GetRendererInfo(d->renderer, &info);
*result = sdl_build_formats(&info, builder);
(*index)++;
return 1;
}
static int impl_port_enum_params(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct data *d = SPA_CONTAINER_OF(node, struct data, impl_node);
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
switch (id) {
case SPA_PARAM_EnumFormat:
return port_enum_formats(node, direction, port_id, index, filter, result, builder);
{
SDL_RendererInfo info;
case SPA_PARAM_Buffers:
if (*index > 0)
if (result.next > 0)
return 0;
*result = spa_pod_builder_add_object(builder,
SDL_GetRendererInfo(d->renderer, &info);
param = sdl_build_formats(&info, &b);
break;
}
case SPA_PARAM_Buffers:
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamBuffers, id,
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, 32),
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
@ -169,10 +167,10 @@ static int impl_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_Meta:
if (*index > 0)
if (result.next > 0)
return 0;
*result = spa_pod_builder_add_object(builder,
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header),
SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)));
@ -182,8 +180,18 @@ static int impl_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
return 1;
result.next++;
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int port_set_format(struct spa_node *node, enum spa_direction direction, uint32_t port_id,

View file

@ -193,7 +193,7 @@ static void *find_object(struct impl *impl, uint32_t id)
static void schedule_rescan(struct impl *impl)
{
if (impl->core_proxy)
pw_core_proxy_sync(impl->core_proxy, 0, ++impl->seq);
impl->seq = pw_core_proxy_sync(impl->core_proxy, 0);
}
static void remove_idle_timeout(struct session *sess)
@ -574,7 +574,8 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id,
node->type = NODE_TYPE_DEVICE;
node->manager = sess;
pw_log_debug(NAME" %p: new session for device node %d", impl, id);
pw_log_debug(NAME" %p: new session for device node %d %d", impl, id,
need_dsp);
}
return 1;
}
@ -687,14 +688,15 @@ handle_port(struct impl *impl, uint32_t id, uint32_t parent_id, uint32_t type,
spa_list_append(&node->port_list, &port->l);
pw_log_debug(NAME" %p: new port %d for node %d type %d %08x", impl, id, parent_id,
node->type, port->flags);
if (node->type == NODE_TYPE_DEVICE) {
pw_port_proxy_enum_params((struct pw_port_proxy*)p,
SPA_PARAM_EnumFormat,
0, -1, NULL);
}
pw_log_debug(NAME" %p: new port %d for node %d type %d %08x", impl, id, parent_id,
node->type, port->flags);
return 0;
}
@ -1240,12 +1242,16 @@ static void rescan_session(struct impl *impl, struct session *sess)
struct spa_pod *param;
const char *str;
if (node->info->props == NULL)
if (node->info->props == NULL) {
pw_log_debug(NAME " %p: node %p has no properties", impl, node);
return;
}
if (node->media_type != SPA_MEDIA_TYPE_audio ||
node->media_subtype != SPA_MEDIA_SUBTYPE_raw)
node->media_subtype != SPA_MEDIA_SUBTYPE_raw) {
pw_log_debug(NAME " %p: node %p has no media type", impl, node);
return;
}
info = node->format;
@ -1290,6 +1296,7 @@ static void do_rescan(struct impl *impl)
struct node *node;
clock_gettime(CLOCK_MONOTONIC, &impl->now);
pw_log_debug("media-session %p: do rescan", impl);
spa_list_for_each(sess, &impl->session_list, l)
rescan_session(impl, sess);
@ -1300,6 +1307,7 @@ static void do_rescan(struct impl *impl)
static int core_done(void *data, uint32_t id, uint32_t seq)
{
struct impl *impl = data;
pw_log_debug("media-session %p: sync %d %u/%u", impl, id, seq, impl->seq);
if (impl->seq == seq)
do_rescan(impl);
return 0;

View file

@ -46,7 +46,7 @@ struct pw_protocol_native_ext {
uint32_t version;
struct spa_pod_builder * (*begin_proxy) (struct pw_proxy *proxy,
uint8_t opcode);
uint8_t opcode, int *res);
uint32_t (*add_proxy_fd) (struct pw_proxy *proxy, int fd);
int (*get_proxy_fd) (struct pw_proxy *proxy, uint32_t index);
@ -55,14 +55,13 @@ struct pw_protocol_native_ext {
struct spa_pod_builder *builder);
struct spa_pod_builder * (*begin_resource) (struct pw_resource *resource,
uint8_t opcode);
uint8_t opcode, int *res);
uint32_t (*add_resource_fd) (struct pw_resource *resource, int fd);
int (*get_resource_fd) (struct pw_resource *resource, uint32_t index);
int (*end_resource) (struct pw_resource *resource,
struct spa_pod_builder *builder);
};
#define pw_protocol_native_begin_proxy(p,...) pw_protocol_ext(pw_proxy_get_protocol(p),struct pw_protocol_native_ext,begin_proxy,p,__VA_ARGS__)

View file

@ -279,9 +279,8 @@ static void add_pending(GstPipeWireDeviceProvider *self, struct pending *p,
spa_list_append(&self->pending, &p->link);
p->callback = callback;
p->data = data;
p->seq = ++self->seq;
pw_log_debug("add pending %d", p->seq);
pw_core_proxy_sync(self->core_proxy, 0, p->seq);
self->seq = p->seq = pw_core_proxy_sync(self->core_proxy, 0);
}
static void remove_pending(struct pending *p)
@ -559,7 +558,6 @@ gst_pipewire_device_provider_probe (GstDeviceProvider * provider)
spa_list_init(&data->ports);
spa_list_init(&self->pending);
self->seq = 1;
pw_remote_add_listener(r, &listener, &remote_events, data);
if (pw_remote_connect (r) < 0)
@ -591,7 +589,7 @@ gst_pipewire_device_provider_probe (GstDeviceProvider * provider)
data->registry = pw_core_proxy_get_registry(self->core_proxy,
PW_TYPE_INTERFACE_Registry, PW_VERSION_REGISTRY, 0);
pw_registry_proxy_add_listener(data->registry, &data->registry_listener, &registry_events, data);
pw_core_proxy_sync(self->core_proxy, 0, ++self->seq);
self->seq = pw_core_proxy_sync(self->core_proxy, 0);
for (;;) {
if (pw_remote_get_state(r, NULL) <= 0)
@ -624,7 +622,6 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider)
self->loop = pw_loop_new (NULL);
self->list_only = FALSE;
spa_list_init(&self->pending);
self->seq = 1;
if (!(self->main_loop = pw_thread_loop_new (self->loop, "pipewire-device-monitor"))) {
GST_ERROR_OBJECT (self, "Could not create PipeWire mainloop");
@ -681,7 +678,7 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider)
data->registry = self->registry;
pw_registry_proxy_add_listener(self->registry, &data->registry_listener, &registry_events, data);
pw_core_proxy_sync(self->core_proxy, 0, ++self->seq);
self->seq = pw_core_proxy_sync(self->core_proxy, 0);
for (;;) {
if (self->end)

View file

@ -122,10 +122,9 @@ struct impl {
#define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
return -ENOTSUP;
}
@ -274,13 +273,13 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
switch (*index) {
switch (index) {
case 0:
if (this->have_format) {
*param = spa_format_audio_raw_build(builder, SPA_PARAM_EnumFormat,
@ -304,21 +303,22 @@ static int port_enum_formats(struct spa_node *node,
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct port *port;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
@ -326,6 +326,8 @@ impl_node_port_enum_params(struct spa_node *node,
port = GET_PORT(this, direction, port_id);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -338,32 +340,32 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id, result.next, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(builder, id, &this->format.info.raw);
param = spa_format_audio_raw_build(&b, id, &this->format.info.raw);
break;
case SPA_PARAM_Buffers:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -382,7 +384,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -395,7 +397,7 @@ impl_node_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -422,12 +424,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this, struct port *port)

View file

@ -146,6 +146,8 @@ struct node {
uint32_t n_params;
struct spa_pod **params;
struct spa_list pending_list;
};
struct impl {
@ -163,6 +165,7 @@ struct impl {
struct spa_hook resource_listener;
struct pw_array mems;
uint32_t init_seq;
int fds[2];
int other_fds[2];
@ -352,34 +355,47 @@ static void mix_clear(struct node *this, struct mix *mix)
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct node *this;
uint8_t buffer[1024];
struct spa_pod_builder b = { 0 };
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
result.next = start;
while (true) {
struct spa_pod *param;
if (*index >= this->n_params)
if (result.next >= this->n_params)
return 0;
param = this->params[(*index)++];
param = this->params[result.next++];
if (param == NULL || !spa_pod_is_object_id(param, id))
continue;
if (spa_pod_filter(builder, result, param, filter) == 0)
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if (spa_pod_filter(&b, &result.param, param, filter) != 0)
continue;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
break;
}
return 1;
return 0;
}
static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
@ -392,7 +408,7 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
this = SPA_CONTAINER_OF(node, struct node, node);
if (this->resource == NULL)
return 0;
return -EIO;
return pw_client_node_resource_set_param(this->resource, id, flags, param);
}
@ -410,9 +426,12 @@ static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size
this = SPA_CONTAINER_OF(node, struct node, node);
impl = this->impl;
if (this->resource == NULL)
if (impl->this.flags & 1)
return 0;
if (this->resource == NULL)
return -EIO;
if (data) {
if ((mem = pw_memblock_find(data)) == NULL)
return -EINVAL;
@ -451,7 +470,7 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
this = SPA_CONTAINER_OF(node, struct node, node);
if (this->resource == NULL)
return 0;
return -EIO;
pw_log_debug("client-node %p: send command %d", node, SPA_COMMAND_TYPE(command));
return pw_client_node_resource_command(this->resource, command);
@ -460,9 +479,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
static void emit_port_info(struct node *this, struct port *port)
{
if (this->callbacks && this->callbacks->port_info) {
this->callbacks->port_info(this->callbacks_data, port->direction, port->id, &port->info);
}
if (this->callbacks && this->callbacks->port_info)
this->callbacks->port_info(this->callbacks_data,
port->direction, port->id, &port->info);
}
static int
@ -471,6 +490,7 @@ impl_node_set_callbacks(struct spa_node *node,
void *data)
{
struct node *this;
int res = 0;
uint32_t i;
spa_return_val_if_fail(node != NULL, -EINVAL);
@ -479,6 +499,8 @@ impl_node_set_callbacks(struct spa_node *node,
this->callbacks = callbacks;
this->callbacks_data = data;
pw_log_debug("client-node %p: callbacks %p", this, callbacks);
for (i = 0; i < MAX_INPUTS; i++) {
if (this->in_ports[i])
emit_port_info(this, this->in_ports[i]);
@ -487,17 +509,50 @@ impl_node_set_callbacks(struct spa_node *node,
if (this->out_ports[i])
emit_port_info(this, this->out_ports[i]);
}
return 0;
if (callbacks && this->resource)
res = pw_resource_sync(this->resource);
return res;
}
static int
impl_node_sync(struct spa_node *node, uint32_t seq)
impl_node_sync(struct spa_node *node)
{
struct node *this;
spa_return_val_if_fail(node != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
pw_log_debug("client-node %p: sync %u", node, seq);
return pw_resource_sync(this->resource, seq);
pw_log_debug("client-node %p: sync", node);
if (this->resource == NULL)
return -EIO;
return pw_resource_sync(this->resource);
}
static int
impl_node_wait(struct spa_node *node, int res, struct spa_pending *pending,
spa_result_func_t func, void *data)
{
struct node *this;
int seq;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
spa_return_val_if_fail(pending != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
pw_log_debug("client-node %p: wait %d %d", node, res, SPA_RESULT_ASYNC_SEQ(res));
if (this->resource == NULL)
return -EIO;
seq = pw_resource_sync(this->resource);
pending->seq = seq;
pending->res = res;
pending->func = func;
pending->data = data;
spa_list_append(&this->pending_list, &pending->link);
return seq;
}
static void
@ -520,7 +575,7 @@ do_update_port(struct node *this,
port->params = realloc(port->params, port->n_params * sizeof(struct spa_pod *));
for (i = 0; i < port->n_params; i++) {
port->params[i] = params[i] ? pw_spa_pod_copy(params[i]) : NULL;
port->params[i] = params[i] ? spa_pod_copy(params[i]) : NULL;
if (port->params[i] && spa_pod_is_object_id(port->params[i], SPA_PARAM_Format))
port->have_format = true;
@ -608,17 +663,21 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct node *this;
struct port *port;
uint8_t buffer[1024];
struct spa_pod_builder b = { 0 };
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
@ -629,21 +688,30 @@ impl_node_port_enum_params(struct spa_node *node,
pw_log_debug("client-node %p: port %d.%d", this,
direction, port_id);
result.next = start;
while (true) {
struct spa_pod *param;
if (*index >= port->n_params)
if (result.next >= port->n_params)
return 0;
param = port->params[(*index)++];
param = port->params[result.next++];
if (param == NULL || !spa_pod_is_object_id(param, id))
continue;
if (spa_pod_filter(builder, result, param, filter) == 0)
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
continue;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
break;
}
return 1;
return 0;
}
static int
@ -661,7 +729,7 @@ impl_node_port_set_param(struct spa_node *node,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
if (this->resource == NULL)
return 0;
return -EIO;
pw_log_debug("node %p: port %d.%d add param %s %d", this,
direction, port_id,
@ -692,7 +760,7 @@ static int do_port_set_io(struct impl *impl,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
if (this->resource == NULL)
return 0;
return -EIO;
port = GET_PORT(this, direction, port_id);
@ -781,7 +849,7 @@ do_port_use_buffers(struct impl *impl,
mix->n_buffers = n_buffers;
if (this->resource == NULL)
return 0;
return -EIO;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &mix->buffers[i];
@ -963,7 +1031,7 @@ client_node_update(void *data,
this->params = realloc(this->params, this->n_params * sizeof(struct spa_pod *));
for (i = 0; i < this->n_params; i++)
this->params[i] = params[i] ? pw_spa_pod_copy(params[i]) : NULL;
this->params[i] = params[i] ? spa_pod_copy(params[i]) : NULL;
}
if (change_mask & PW_CLIENT_NODE_UPDATE_PROPS) {
pw_node_update_properties(impl->this.node, props);
@ -1068,6 +1136,7 @@ static const struct spa_node impl_node = {
NULL,
.set_callbacks = impl_node_set_callbacks,
.sync = impl_node_sync,
.wait = impl_node_wait,
.enum_params = impl_node_enum_params,
.set_param = impl_node_set_param,
.set_io = impl_node_set_io,
@ -1109,6 +1178,7 @@ node_init(struct node *this,
}
this->node = impl_node;
spa_list_init(&this->pending_list);
init_ios(this->ios);
@ -1174,18 +1244,24 @@ static void client_node_resource_error(void *data, int res, const char *message)
struct impl *impl = data;
struct node *this = &impl->node;
pw_log_error("client-node %p: error %d: %s", this, res, message);
if (this->callbacks && this->callbacks->error)
this->callbacks->error(this->callbacks_data, res, message);
}
static void client_node_resource_done(void *data, uint32_t seq)
{
struct impl *impl = data;
struct node *this = &impl->node;
struct spa_pending *p, *t;
pw_log_debug("client-node %p: done %d", this, seq);
if (this->callbacks && this->callbacks->done)
this->callbacks->done(this->callbacks_data, SPA_RESULT_ASYNC_SEQ(seq));
spa_list_for_each_safe(p, t, &this->pending_list, link) {
pw_log_debug("client-node %p: check %d", this, p->seq);
if (p->seq == (int) seq) {
pw_log_debug("client-node %p: found %d", this, p->res);
p->func(p->data, p->res, 0, NULL);
spa_list_remove(&p->link);
}
}
}
void pw_client_node_registered(struct pw_client_node *this, uint32_t node_id)
@ -1318,14 +1394,13 @@ static const struct pw_port_implementation port_impl = {
static int
impl_mix_port_enum_params(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct port *port = SPA_CONTAINER_OF(node, struct port, mix_node);
return impl_node_port_enum_params(&port->node->node, direction, port->id,
id, index, filter, result, builder);
id, start, num, filter, func, data);
}
static int
@ -1597,6 +1672,8 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
support = pw_core_get_support(impl->core, &n_support);
node_init(&impl->node, NULL, support, n_support);
impl->node.impl = impl;
impl->node.resource = resource;
this->flags = do_register ? 0 : 1;
pw_map_init(&impl->io_map, 64, 64);
pw_array_init(&impl->mems, 64);
@ -1610,7 +1687,6 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
pw_resource_get_client(this->resource),
parent,
name,
PW_SPA_NODE_FLAG_ASYNC |
(do_register ? 0 : PW_SPA_NODE_FLAG_NO_REGISTER),
&impl->node.node,
NULL,
@ -1619,6 +1695,7 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
goto error_no_node;
this->node->remote = true;
this->flags = 0;
spa_graph_node_set_callbacks(&this->node->rt.root, &root_impl, this);
@ -1630,13 +1707,10 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
&client_node_methods,
impl);
impl->node.resource = this->resource;
this->node->port_user_data_size = sizeof(struct port);
pw_node_add_listener(this->node, &impl->node_listener, &node_events, impl);
pw_resource_sync(this->resource, 0);
return this;
error_no_node:

View file

@ -41,6 +41,7 @@ struct pw_client_node {
struct pw_resource *resource;
struct pw_global *parent;
uint32_t flags;
};
struct pw_client_node *

View file

@ -34,6 +34,7 @@
#include <sys/eventfd.h>
#include <spa/node/node.h>
#include <spa/node/utils.h>
#include <spa/buffer/alloc.h>
#include <spa/pod/parser.h>
#include <spa/pod/filter.h>
@ -68,8 +69,6 @@ struct node {
const struct spa_node_callbacks *callbacks;
void *callbacks_data;
uint32_t seq;
};
struct impl {
@ -83,7 +82,6 @@ struct impl {
struct spa_hook node_listener;
struct spa_hook client_node_listener;
struct spa_hook resource_listener;
enum spa_direction direction;
@ -110,24 +108,28 @@ struct impl {
/** \endcond */
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct node *this;
struct impl *impl;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
impl = this->impl;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -138,10 +140,10 @@ static int impl_node_enum_params(struct spa_node *node,
SPA_PARAM_EnumFormat,
SPA_PARAM_Format };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
@ -149,8 +151,7 @@ static int impl_node_enum_params(struct spa_node *node,
case SPA_PARAM_Props:
if (impl->adapter != impl->cnode) {
return spa_node_enum_params(impl->adapter,
id, index,
filter, result, builder);
id, start, num, filter, func, data);
}
return 0;
@ -158,18 +159,24 @@ static int impl_node_enum_params(struct spa_node *node,
case SPA_PARAM_Format:
return spa_node_port_enum_params(impl->cnode,
impl->direction, 0,
id, index,
filter, result, builder);
id, start, num,
filter, func, data);
default:
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static void try_link_controls(struct impl *impl)
@ -323,11 +330,11 @@ impl_node_set_callbacks(struct spa_node *node,
if (this->callbacks && impl->adapter && impl->adapter != impl->cnode)
spa_node_set_callbacks(impl->adapter, &adapter_node_callbacks, impl);
return 0;
return spa_node_sync(impl->cnode);
}
static int
impl_node_sync(struct spa_node *node, uint32_t seq)
impl_node_sync(struct spa_node *node)
{
struct node *this;
struct impl *impl;
@ -337,7 +344,22 @@ impl_node_sync(struct spa_node *node, uint32_t seq)
this = SPA_CONTAINER_OF(node, struct node, node);
impl = this->impl;
return spa_node_sync(impl->cnode, seq);
return spa_node_sync(impl->cnode);
}
static int
impl_node_wait(struct spa_node *node, int seq, struct spa_pending *pending,
spa_result_func_t func, void *data)
{
struct node *this;
struct impl *impl;
spa_return_val_if_fail(node != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
impl = this->impl;
return spa_node_wait(impl->cnode, seq, pending, func, data);
}
static int
@ -389,17 +411,16 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
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,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct node *this;
struct impl *impl;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
impl = this->impl;
@ -408,7 +429,7 @@ impl_node_port_enum_params(struct spa_node *node,
return -EINVAL;
return spa_node_port_enum_params(impl->adapter, direction, port_id, id,
index, filter, result, builder);
start, num, filter, func, data);
}
static int debug_params(struct impl *impl, struct spa_node *node,
@ -426,11 +447,11 @@ static int debug_params(struct impl *impl, struct spa_node *node,
state = 0;
while (true) {
spa_pod_builder_init(&b, buffer, sizeof(buffer));
res = spa_node_port_enum_params(node,
res = spa_node_port_enum_params_sync(node,
direction, port_id,
id, &state,
NULL, &param, &b);
if (res <= 0) {
if (res != 1) {
if (res < 0)
spa_log_error(this->log, " error: %s", spa_strerror(res));
break;
@ -460,11 +481,11 @@ static int negotiate_format(struct impl *impl)
spa_log_debug(this->log, NAME "%p: negiotiate", impl);
state = 0;
if ((res = spa_node_port_enum_params(impl->adapter_mix,
if ((res = spa_node_port_enum_params_sync(impl->adapter_mix,
SPA_DIRECTION_REVERSE(impl->direction),
impl->adapter_mix_port,
SPA_PARAM_EnumFormat, &state,
NULL, &format, &b)) <= 0) {
NULL, &format, &b)) != 1) {
debug_params(impl, impl->adapter_mix,
SPA_DIRECTION_REVERSE(impl->direction),
impl->adapter_mix_port,
@ -473,10 +494,10 @@ static int negotiate_format(struct impl *impl)
}
state = 0;
if ((res = spa_node_port_enum_params(impl->cnode,
if ((res = spa_node_port_enum_params_sync(impl->cnode,
impl->direction, 0,
SPA_PARAM_EnumFormat, &state,
format, &format, &b)) <= 0) {
format, &format, &b)) != 1) {
debug_params(impl, impl->cnode, impl->direction, 0,
SPA_PARAM_EnumFormat, format);
return -ENOTSUP;
@ -524,22 +545,22 @@ static int negotiate_buffers(struct impl *impl)
return 0;
state = 0;
if ((res = spa_node_port_enum_params(impl->adapter_mix,
if ((res = spa_node_port_enum_params_sync(impl->adapter_mix,
SPA_DIRECTION_REVERSE(impl->direction),
impl->adapter_mix_port,
SPA_PARAM_Buffers, &state,
param, &param, &b)) <= 0) {
param, &param, &b)) < 0) {
debug_params(impl, impl->adapter_mix,
SPA_DIRECTION_REVERSE(impl->direction),
impl->adapter_mix_port,
SPA_PARAM_Buffers, param);
return -ENOTSUP;
}
if (res == 0)
if (res != 1)
param = NULL;
state = 0;
if ((res = spa_node_port_enum_params(impl->cnode,
if ((res = spa_node_port_enum_params_sync(impl->cnode,
impl->direction, 0,
SPA_PARAM_Buffers, &state,
param, &param, &b)) < 0) {
@ -833,6 +854,7 @@ static const struct spa_node impl_node = {
SPA_VERSION_NODE,
.set_callbacks = impl_node_set_callbacks,
.sync = impl_node_sync,
.wait = impl_node_wait,
.enum_params = impl_node_enum_params,
.set_param = impl_node_set_param,
.set_io = impl_node_set_io,
@ -861,10 +883,7 @@ node_init(struct node *this,
this->log = support[i].data;
}
this->node = impl_node;
this->seq = 1;
return SPA_RESULT_RETURN_ASYNC(this->seq++);
return 0;
}
static int do_port_info(void *data, struct pw_port *port)
@ -957,10 +976,10 @@ static void client_node_initialized(void *data)
state = 0;
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if ((res = spa_node_port_enum_params(impl->cnode,
if ((res = spa_node_port_enum_params_sync(impl->cnode,
impl->direction, 0,
SPA_PARAM_EnumFormat, &state,
NULL, &format, &b)) <= 0) {
NULL, &format, &b)) != 1) {
pw_log_warn("client-stream %p: no format given", &impl->this);
impl->adapter = impl->cnode;
impl->adapter_mix = impl->client_port->mix;
@ -1049,15 +1068,6 @@ static void client_node_initialized(void *data)
items[0] = SPA_DICT_ITEM_INIT("media.class", media_class);
pw_node_update_properties(impl->this.node, &SPA_DICT_INIT(items, 1));
pw_node_register(impl->this.node,
pw_resource_get_client(impl->client_node->resource),
impl->client_node->parent,
NULL);
pw_log_debug("client-stream %p: activating", &impl->this);
pw_node_set_active(impl->this.node, true);
}
static void cleanup(struct impl *impl)
@ -1087,15 +1097,6 @@ static void client_node_destroy(void *data)
cleanup(impl);
}
static void client_node_async_complete(void *data, uint32_t seq, int res)
{
struct impl *impl = data;
struct node *node = &impl->node;
pw_log_debug("client-stream %p: async complete %d %d", &impl->this, seq, res);
node->callbacks->done(node->callbacks_data, seq);
}
static void client_node_active_changed(void *data, bool active)
{
struct impl *impl = data;
@ -1118,7 +1119,6 @@ static const struct pw_node_events client_node_events = {
PW_VERSION_NODE_EVENTS,
.destroy = client_node_destroy,
.initialized = client_node_initialized,
.async_complete = client_node_async_complete,
.active_changed = client_node_active_changed,
.info_changed = client_node_info_changed,
};
@ -1225,7 +1225,7 @@ struct pw_client_stream *pw_client_stream_new(struct pw_resource *resource,
client,
parent,
name,
PW_SPA_NODE_FLAG_ASYNC,
PW_SPA_NODE_FLAG_ACTIVATE,
&impl->node.node,
NULL,
properties, 0);

View file

@ -61,7 +61,7 @@ client_node_marshal_update(void *object,
struct spa_pod_frame f;
uint32_t i;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_UPDATE);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_UPDATE, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -93,7 +93,7 @@ client_node_marshal_port_update(void *object,
struct spa_pod_frame f[2];
uint32_t i, n_items;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE, NULL);
spa_pod_builder_push_struct(b, &f[0]);
spa_pod_builder_add(b,
@ -134,7 +134,7 @@ static int client_node_marshal_set_active(void *object, bool active)
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Bool(active));
@ -147,7 +147,7 @@ static int client_node_marshal_event_method(void *object, struct spa_event *even
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_EVENT);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_EVENT, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Pod(event));
@ -472,7 +472,7 @@ client_node_marshal_add_mem(void *object,
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_ADD_MEM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(mem_id),
@ -488,7 +488,7 @@ static int client_node_marshal_transport(void *object, uint32_t node_id, int rea
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(node_id),
@ -505,7 +505,7 @@ client_node_marshal_set_param(void *object, uint32_t id, uint32_t flags,
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_SET_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -520,7 +520,7 @@ static int client_node_marshal_event_event(void *object, const struct spa_event
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_EVENT);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_EVENT, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Pod(event));
@ -534,7 +534,7 @@ client_node_marshal_command(void *object, 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_COMMAND);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_COMMAND, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Pod(command));
@ -551,7 +551,7 @@ client_node_marshal_add_port(void *object,
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -570,7 +570,7 @@ client_node_marshal_remove_port(void *object,
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_REMOVE_PORT, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(direction),
@ -590,7 +590,7 @@ client_node_marshal_port_set_param(void *object,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(direction),
@ -614,7 +614,7 @@ client_node_marshal_port_use_buffers(void *object,
struct spa_pod_frame f;
uint32_t i, j;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -668,7 +668,7 @@ client_node_marshal_port_set_io(void *object,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(direction),
@ -693,7 +693,7 @@ client_node_marshal_set_activation(void *object,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_ACTIVATION);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_ACTIVATION, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(node_id),
@ -715,7 +715,7 @@ client_node_marshal_set_io(void *object,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_IO);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_IO, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
SPA_POD_Int(memid),

View file

@ -30,6 +30,7 @@
#include <sys/mman.h>
#include <spa/pod/parser.h>
#include <spa/node/utils.h>
#include <spa/debug/types.h>
#include "pipewire/pipewire.h"
@ -413,10 +414,10 @@ static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_
struct spa_pod *param;
spa_pod_builder_init(&b, buf, sizeof(buf));
if (spa_node_port_enum_params(port->node->node,
if (spa_node_port_enum_params_sync(port->node->node,
port->direction, port->port_id,
SPA_PARAM_List, &idx1,
NULL, &param, &b) <= 0)
NULL, &param, &b) != 1)
break;
spa_pod_parse_object(param,
@ -424,18 +425,18 @@ static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_
SPA_PARAM_LIST_id, SPA_POD_Id(&id));
params = realloc(params, sizeof(struct spa_pod *) * (n_params + 1));
params[n_params++] = pw_spa_pod_copy(param);
params[n_params++] = spa_pod_copy(param);
for (idx2 = 0;;) {
spa_pod_builder_init(&b, buf, sizeof(buf));
if (spa_node_port_enum_params(port->node->node,
if (spa_node_port_enum_params_sync(port->node->node,
port->direction, port->port_id,
id, &idx2,
NULL, &param, &b) <= 0)
NULL, &param, &b) != 1)
break;
params = realloc(params, sizeof(struct spa_pod *) * (n_params + 1));
params[n_params++] = pw_spa_pod_copy(param);
params[n_params++] = spa_pod_copy(param);
}
}
}

View file

@ -754,10 +754,10 @@ const static struct pw_protocol_implementaton protocol_impl = {
};
static struct spa_pod_builder *
impl_ext_begin_proxy(struct pw_proxy *proxy, uint8_t opcode)
impl_ext_begin_proxy(struct pw_proxy *proxy, uint8_t opcode, int *res)
{
struct client *impl = SPA_CONTAINER_OF(proxy->remote->conn, struct client, this);
return pw_protocol_native_connection_begin_proxy(impl->connection, proxy, opcode);
return pw_protocol_native_connection_begin(impl->connection, proxy->id, opcode, res);
}
static uint32_t impl_ext_add_proxy_fd(struct pw_proxy *proxy, int fd)
@ -780,10 +780,10 @@ static int impl_ext_end_proxy(struct pw_proxy *proxy,
}
static struct spa_pod_builder *
impl_ext_begin_resource(struct pw_resource *resource, uint8_t opcode)
impl_ext_begin_resource(struct pw_resource *resource, uint8_t opcode, int *res)
{
struct client_data *data = resource->client->user_data;
return pw_protocol_native_connection_begin_resource(data->connection, resource, opcode);
return pw_protocol_native_connection_begin(data->connection, resource->id, opcode, res);
}
static uint32_t impl_ext_add_resource_fd(struct pw_resource *resource, int fd)
@ -803,7 +803,6 @@ static int impl_ext_end_resource(struct pw_resource *resource,
struct client_data *data = resource->client->user_data;
return pw_protocol_native_connection_end(data->connection, builder);
}
const static struct pw_protocol_native_ext protocol_ext_impl = {
PW_VERSION_PROTOCOL_NATIVE_EXT,
impl_ext_begin_proxy,

View file

@ -369,32 +369,17 @@ static const struct spa_pod_builder_callbacks builder_callbacks = {
};
struct spa_pod_builder *
pw_protocol_native_connection_begin_resource(struct pw_protocol_native_connection *conn,
struct pw_resource *resource,
uint8_t opcode)
pw_protocol_native_connection_begin(struct pw_protocol_native_connection *conn,
uint32_t id, uint8_t opcode, int *res)
{
struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this);
impl->dest_id = resource->id;
impl->opcode = opcode;
impl->builder = SPA_POD_BUILDER_INIT(NULL, 0);
impl->builder.callbacks = &builder_callbacks;
impl->builder.callbacks_data = impl;
return &impl->builder;
}
struct spa_pod_builder *
pw_protocol_native_connection_begin_proxy(struct pw_protocol_native_connection *conn,
struct pw_proxy *proxy,
uint8_t opcode)
{
struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this);
impl->dest_id = proxy->id;
impl->dest_id = id;
impl->opcode = opcode;
impl->builder = SPA_POD_BUILDER_INIT(NULL, 0);
impl->builder.callbacks = &builder_callbacks;
impl->builder.callbacks_data = impl;
if (res)
*res = SPA_RESULT_RETURN_ASYNC(impl->seq);
return &impl->builder;
}

View file

@ -82,14 +82,9 @@ uint32_t pw_protocol_native_connection_add_fd(struct pw_protocol_native_connecti
int pw_protocol_native_connection_get_fd(struct pw_protocol_native_connection *conn, uint32_t index);
struct spa_pod_builder *
pw_protocol_native_connection_begin_resource(struct pw_protocol_native_connection *conn,
struct pw_resource *resource,
uint8_t opcode);
pw_protocol_native_connection_begin(struct pw_protocol_native_connection *conn,
uint32_t id, uint8_t opcode, int *res);
struct spa_pod_builder *
pw_protocol_native_connection_begin_proxy(struct pw_protocol_native_connection *conn,
struct pw_proxy *proxy,
uint8_t opcode);
int
pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn,
struct spa_pod_builder *builder);

View file

@ -37,7 +37,7 @@ static int core_method_marshal_hello(void *object, uint32_t version)
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_HELLO);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_HELLO, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(version));
@ -49,12 +49,13 @@ static int core_method_marshal_sync(void *object, uint32_t id, uint32_t seq)
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
int res;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_SYNC);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_SYNC, &res);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
SPA_POD_Int(seq));
SPA_POD_Int(res));
return pw_protocol_native_end_proxy(proxy, b);
}
@ -64,7 +65,7 @@ static int core_method_marshal_done(void *object, uint32_t id, uint32_t seq)
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_DONE);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_DONE, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
@ -78,7 +79,7 @@ static int core_method_marshal_error(void *object, uint32_t id, int res, const c
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_ERROR);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_ERROR, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
@ -93,7 +94,7 @@ static int core_method_marshal_get_registry(void *object, uint32_t version, uint
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_GET_REGISTRY);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_GET_REGISTRY, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(version),
@ -128,7 +129,7 @@ core_method_marshal_create_object(void *object,
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_CREATE_OBJECT);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_CREATE_OBJECT, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -149,7 +150,7 @@ core_method_marshal_destroy(void *object, uint32_t id)
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_DESTROY);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_DESTROY, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id));
@ -263,7 +264,7 @@ static int core_event_marshal_info(void *object, const struct pw_core_info *info
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -286,7 +287,7 @@ static int core_event_marshal_done(void *object, uint32_t id, uint32_t seq)
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_DONE);
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_DONE, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
@ -299,12 +300,13 @@ static int core_event_marshal_sync(void *object, uint32_t id, uint32_t seq)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
int res;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_SYNC);
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_SYNC, &res);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
SPA_POD_Int(seq));
SPA_POD_Int(res));
return pw_protocol_native_end_resource(resource, b);
}
@ -314,7 +316,7 @@ static int core_event_marshal_error(void *object, uint32_t id, int res, const ch
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_ERROR);
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_ERROR, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
@ -329,7 +331,7 @@ static int core_event_marshal_remove_id(void *object, uint32_t id)
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_REMOVE_ID);
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_REMOVE_ID, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id));
@ -475,7 +477,7 @@ static int registry_marshal_global(void *object, uint32_t id, uint32_t parent_id
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL);
b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -496,7 +498,7 @@ static int registry_marshal_global_remove(void *object, uint32_t id)
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL_REMOVE);
b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL_REMOVE, NULL);
spa_pod_builder_add_struct(b, SPA_POD_Int(id));
@ -540,7 +542,7 @@ static int module_marshal_info(void *object, const struct pw_module_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_MODULE_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_MODULE_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -597,7 +599,7 @@ static int device_marshal_info(void *object, const struct pw_device_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -650,7 +652,7 @@ static int device_marshal_param(void *object, uint32_t id, uint32_t index, uint3
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_PARAM);
b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -685,7 +687,7 @@ static int device_marshal_enum_params(void *object, uint32_t id, uint32_t index,
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_ENUM_PARAMS);
b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_ENUM_PARAMS, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -720,7 +722,7 @@ static int device_marshal_set_param(void *object, uint32_t id, uint32_t flags,
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_SET_PARAM);
b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_SET_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -752,7 +754,7 @@ static int factory_marshal_info(void *object, const struct pw_factory_info *info
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_FACTORY_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_FACTORY_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -809,7 +811,7 @@ static int node_marshal_info(void *object, const struct pw_node_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -874,7 +876,7 @@ static int node_marshal_param(void *object, uint32_t id, uint32_t index, uint32_
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_PARAM);
b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -909,7 +911,7 @@ static int node_marshal_enum_params(void *object, uint32_t id, uint32_t index, u
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_ENUM_PARAMS);
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_ENUM_PARAMS, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -944,7 +946,7 @@ static int node_marshal_set_param(void *object, uint32_t id, uint32_t flags,
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SET_PARAM);
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SET_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -975,7 +977,7 @@ static int node_marshal_send_command(void *object, const struct spa_command *com
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SEND_COMMAND);
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SEND_COMMAND, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Pod(command));
return pw_protocol_native_end_proxy(proxy, b);
@ -1001,7 +1003,7 @@ static int port_marshal_info(void *object, const struct pw_port_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -1054,7 +1056,7 @@ static int port_marshal_param(void *object, uint32_t id, uint32_t index, uint32_
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_PARAM);
b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -1089,7 +1091,7 @@ static int port_marshal_enum_params(void *object, uint32_t id, uint32_t index, u
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_PORT_PROXY_METHOD_ENUM_PARAMS);
b = pw_protocol_native_begin_proxy(proxy, PW_PORT_PROXY_METHOD_ENUM_PARAMS, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -1124,7 +1126,7 @@ static int client_marshal_info(void *object, const struct pw_client_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -1177,7 +1179,7 @@ static int client_marshal_permissions(void *object, uint32_t index, uint32_t n_p
struct spa_pod_frame f[2];
uint32_t i, n = 0;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_PERMISSIONS);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_PERMISSIONS, NULL);
for (i = 0; i < n_permissions; i++) {
if (permissions[i].permissions != SPA_ID_INVALID)
@ -1235,7 +1237,7 @@ static int client_marshal_error(void *object, uint32_t id, int res, const char *
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_ERROR);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_ERROR, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
SPA_POD_Int(res),
@ -1265,7 +1267,7 @@ static int client_marshal_get_permissions(void *object, uint32_t index, uint32_t
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_GET_PERMISSIONS);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_GET_PERMISSIONS, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(index),
@ -1280,7 +1282,7 @@ static int client_marshal_update_properties(void *object, const struct spa_dict
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PROPERTIES);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PROPERTIES, NULL);
spa_pod_builder_push_struct(b, &f);
push_dict(b, props);
@ -1338,7 +1340,7 @@ static int client_marshal_update_permissions(void *object, uint32_t n_permission
struct spa_pod_frame f;
uint32_t i;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PERMISSIONS);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PERMISSIONS, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_int(b, n_permissions);
@ -1382,7 +1384,7 @@ static int link_marshal_info(void *object, const struct pw_link_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_LINK_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_LINK_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -1497,7 +1499,7 @@ static int registry_marshal_bind(void *object, uint32_t id,
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_BIND);
b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_BIND, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
@ -1513,7 +1515,7 @@ static int registry_marshal_destroy(void *object, uint32_t id)
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_DESTROY);
b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_DESTROY, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id));
return pw_protocol_native_end_proxy(proxy, b);

View file

@ -31,6 +31,7 @@
#include <dlfcn.h>
#include <spa/node/node.h>
#include <spa/node/utils.h>
#include <spa/param/props.h>
#include <spa/pod/iter.h>
#include <spa/debug/types.h>
@ -48,7 +49,6 @@ struct impl {
struct pw_global *parent;
enum pw_spa_node_flags flags;
bool async_init;
void *hnd;
struct spa_handle *handle;
@ -57,8 +57,11 @@ struct impl {
char *factory_name;
struct spa_hook node_listener;
struct spa_pending init_pending;
void *user_data;
int async_init:1;
};
static void pw_spa_node_free(void *data)
@ -79,7 +82,7 @@ static void pw_spa_node_free(void *data)
dlclose(impl->hnd);
}
static void complete_init(struct impl *impl)
static int complete_init(struct impl *impl)
{
struct pw_node *this = impl->this;
@ -93,24 +96,20 @@ static void complete_init(struct impl *impl)
pw_node_register(this, impl->owner, impl->parent, NULL);
else
pw_node_initialized(this);
return 0;
}
static void on_node_done(void *data, uint32_t seq, int res)
static int on_init_done(void *data, int seq, int res, const void *result)
{
struct impl *impl = data;
struct pw_node *this = impl->this;
if (impl->async_init) {
complete_init(impl);
impl->async_init = false;
}
pw_log_debug("spa-node %p: async complete event %d %d", this, seq, res);
pw_log_debug("spa-node %p: init complete event %d %d", this, seq, res);
return complete_init(impl);
}
static const struct pw_node_events node_events = {
PW_VERSION_NODE_EVENTS,
.free = pw_spa_node_free,
.async_complete = on_node_done,
};
struct pw_node *
@ -126,6 +125,7 @@ pw_spa_node_new(struct pw_core *core,
{
struct pw_node *this;
struct impl *impl;
int res;
this = pw_node_new(core, name, properties, sizeof(struct impl) + user_data_size);
if (this == NULL)
@ -137,18 +137,27 @@ pw_spa_node_new(struct pw_core *core,
impl->parent = parent;
impl->node = node;
impl->flags = flags;
impl->async_init = flags & PW_SPA_NODE_FLAG_ASYNC;
if (user_data_size > 0)
impl->user_data = SPA_MEMBER(impl, sizeof(struct impl), void);
pw_node_add_listener(this, &impl->node_listener, &node_events, impl);
pw_node_set_implementation(this, impl->node);
res = pw_node_set_implementation(this, impl->node);
if (!impl->async_init)
if (res < 0)
goto clean_node;
if (SPA_RESULT_IS_ASYNC(res)) {
spa_node_wait(impl->node, res, &impl->init_pending, on_init_done, impl);
} else {
complete_init(impl);
}
return this;
clean_node:
pw_node_destroy(this);
return NULL;
}
void *pw_spa_node_get_user_data(struct pw_node *node)
@ -169,7 +178,8 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
const struct spa_pod_prop *prop = NULL;
if ((res = spa_node_enum_params(spa_node, SPA_PARAM_Props, &index, NULL, &props, &b)) <= 0) {
if ((res = spa_node_enum_params_sync(spa_node,
SPA_PARAM_Props, &index, NULL, &props, &b)) != 1) {
pw_log_debug("spa_node_get_props failed: %d", res);
return res;
}
@ -290,8 +300,6 @@ struct pw_node *pw_spa_node_load(struct pw_core *core,
pw_log_error("can't make factory instance: %d", res);
goto init_failed;
}
if (SPA_RESULT_IS_ASYNC(res))
flags |= PW_SPA_NODE_FLAG_ASYNC;
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Node, &iface)) < 0) {
pw_log_error("can't get node interface %d", res);

View file

@ -35,10 +35,9 @@ extern "C" {
#endif
enum pw_spa_node_flags {
PW_SPA_NODE_FLAG_ASYNC = (1 << 0),
PW_SPA_NODE_FLAG_DISABLE = (1 << 1),
PW_SPA_NODE_FLAG_ACTIVATE = (1 << 2),
PW_SPA_NODE_FLAG_NO_REGISTER = (1 << 3),
PW_SPA_NODE_FLAG_DISABLE = (1 << 0),
PW_SPA_NODE_FLAG_ACTIVATE = (1 << 1),
PW_SPA_NODE_FLAG_NO_REGISTER = (1 << 2),
};
struct pw_node *

View file

@ -29,6 +29,7 @@
#include <pipewire/log.h>
#include <spa/support/dbus.h>
#include <spa/node/utils.h>
#include <spa/debug/format.h>
#include <spa/debug/types.h>
@ -831,10 +832,10 @@ int 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_enum_params(output->node->node,
if ((res = spa_node_port_enum_params_sync(output->node->node,
output->direction, output->port_id,
SPA_PARAM_Format, &oidx,
NULL, format, builder)) <= 0) {
NULL, format, builder)) != 1) {
if (res == 0)
res = -EBADF;
asprintf(error, "error get output format: %s", spa_strerror(res));
@ -845,10 +846,10 @@ int pw_core_find_format(struct pw_core *core,
spa_debug_format(2, NULL, *format);
} else if (out_state >= PW_PORT_STATE_CONFIGURE && in_state > PW_PORT_STATE_CONFIGURE) {
/* only output needs format */
if ((res = spa_node_port_enum_params(input->node->node,
if ((res = spa_node_port_enum_params_sync(input->node->node,
input->direction, input->port_id,
SPA_PARAM_Format, &iidx,
NULL, format, builder)) <= 0) {
NULL, format, builder)) != 1) {
if (res == 0)
res = -EBADF;
asprintf(error, "error get input format: %s", spa_strerror(res));
@ -865,10 +866,10 @@ int pw_core_find_format(struct pw_core *core,
/* both ports need a format */
pw_log_debug("core %p: do enum input %d", core, iidx);
spa_pod_builder_init(&fb, fbuf, sizeof(fbuf));
if ((res = spa_node_port_enum_params(input->node->node,
if ((res = spa_node_port_enum_params_sync(input->node->node,
input->direction, input->port_id,
SPA_PARAM_EnumFormat, &iidx,
NULL, &filter, &fb)) <= 0) {
NULL, &filter, &fb)) != 1) {
if (res == 0 && iidx == 0) {
asprintf(error, "error input enum formats: %s", spa_strerror(res));
goto error;
@ -880,10 +881,10 @@ int pw_core_find_format(struct pw_core *core,
if (pw_log_level_enabled(SPA_LOG_LEVEL_DEBUG))
spa_debug_format(2, NULL, filter);
if ((res = spa_node_port_enum_params(output->node->node,
if ((res = spa_node_port_enum_params_sync(output->node->node,
output->direction, output->port_id,
SPA_PARAM_EnumFormat, &oidx,
filter, format, builder)) <= 0) {
filter, format, builder)) != 1) {
if (res == 0) {
oidx = 0;
goto again;

View file

@ -177,9 +177,9 @@ pw_core_proxy_hello(struct pw_core_proxy *core, uint32_t version)
}
static inline int
pw_core_proxy_sync(struct pw_core_proxy *core, uint32_t id, uint32_t seq)
pw_core_proxy_sync(struct pw_core_proxy *core, uint32_t id)
{
return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, sync, id, seq);
return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, sync, id, 0);
}
static inline int
@ -326,7 +326,7 @@ pw_core_proxy_add_listener(struct pw_core_proxy *core,
#define pw_core_resource_info(r,...) pw_resource_notify(r,struct pw_core_proxy_events,info,__VA_ARGS__)
#define pw_core_resource_done(r,...) pw_resource_notify(r,struct pw_core_proxy_events,done,__VA_ARGS__)
#define pw_core_resource_sync(r,...) pw_resource_notify(r,struct pw_core_proxy_events,sync,__VA_ARGS__)
#define pw_core_resource_sync(r,id) pw_resource_notify(r,struct pw_core_proxy_events,sync,id,0)
#define pw_core_resource_error(r,...) pw_resource_notify(r,struct pw_core_proxy_events,error,__VA_ARGS__)
#define pw_core_resource_remove_id(r,...) pw_resource_notify(r,struct pw_core_proxy_events,remove_id,__VA_ARGS__)

View file

@ -440,7 +440,7 @@ struct pw_link_info *pw_link_info_update(struct pw_link_info *info,
}
if (update->change_mask & PW_LINK_CHANGE_MASK_FORMAT) {
free(info->format);
info->format = update->format ? pw_spa_pod_copy(update->format) : NULL;
info->format = update->format ? spa_pod_copy(update->format) : NULL;
}
if (update->change_mask & PW_LINK_CHANGE_MASK_PROPS) {
if (info->props)

View file

@ -27,6 +27,7 @@
#include <stdio.h>
#include <time.h>
#include <spa/node/utils.h>
#include <spa/pod/parser.h>
#include <spa/pod/compare.h>
#include <spa/param/param.h>
@ -149,6 +150,28 @@ static void pw_link_update_state(struct pw_link *link, enum pw_link_state state,
}
}
static int complete_output(void *data, int seq, int res, const void *result)
{
struct pw_link *this = data;
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
struct pw_node *node = this->output->node;
seq = SPA_RESULT_ASYNC_SEQ(seq);
pw_log_debug("link %p: node %p async complete %d %d", impl, node, seq, res);
pw_work_queue_complete(impl->work, node, seq, res);
return 0;
}
static int complete_input(void *data, int seq, int res, const void *result)
{
struct pw_link *this = data;
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
struct pw_node *node = this->output->node;
seq = SPA_RESULT_ASYNC_SEQ(seq);
pw_log_debug("link %p: node %p async complete %d %d", impl, node, seq, res);
pw_work_queue_complete(impl->work, node, seq, res);
return 0;
}
static void complete_ready(void *obj, void *data, int res, uint32_t id)
{
struct pw_port_mix *mix = data;
@ -181,6 +204,19 @@ static void complete_paused(void *obj, void *data, int res, uint32_t id)
}
}
static void remove_pending(struct spa_pending *pending)
{
free(pending);
}
static struct spa_pending *make_pending(struct impl *impl)
{
struct spa_pending *pending;
pending = calloc(1, sizeof(struct spa_pending));
pending->removed = remove_pending;
return pending;
}
static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_state)
{
struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this);
@ -214,14 +250,14 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
in_state = input->state;
out_state = output->state;
format = pw_spa_pod_copy(format);
format = spa_pod_copy(format);
spa_pod_fixate(format);
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if (out_state > PW_PORT_STATE_CONFIGURE && output->node->info.state == PW_NODE_STATE_IDLE) {
index = 0;
res = spa_node_port_enum_params(output->node->node,
res = spa_node_port_enum_params_sync(output->node->node,
output->direction, output->port_id,
SPA_PARAM_Format, &index,
NULL, &current, &b);
@ -256,7 +292,7 @@ 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) {
index = 0;
res = spa_node_port_enum_params(input->node->node,
res = spa_node_port_enum_params_sync(input->node->node,
input->direction, input->port_id,
SPA_PARAM_Format, &index,
NULL, &current, &b);
@ -299,7 +335,11 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
goto error;
}
if (SPA_RESULT_IS_ASYNC(res)) {
spa_node_sync(output->node->node, res);
spa_node_wait(output->node->node, res,
make_pending(impl),
complete_output,
this);
pw_work_queue_add(impl->work, output->node, res, complete_ready,
&this->rt.out_mix);
}
@ -314,7 +354,11 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st
goto error;
}
if (SPA_RESULT_IS_ASYNC(res2)) {
spa_node_sync(input->node->node, res2);
spa_node_wait(input->node->node, res2,
make_pending(impl),
complete_input,
this);
pw_work_queue_add(impl->work, input->node, res2, complete_ready,
&this->rt.in_mix);
if (res == 0)
@ -453,12 +497,12 @@ param_filter(struct pw_link *this,
for (iidx = 0;;) {
spa_pod_builder_init(&ib, ibuf, sizeof(ibuf));
pw_log_debug("iparam %d", iidx);
if ((res = spa_node_port_enum_params(in_port->node->node,
if ((res = spa_node_port_enum_params_sync(in_port->node->node,
in_port->direction, in_port->port_id,
id, &iidx, NULL, &iparam, &ib)) < 0)
break;
if (res == 0) {
if (res != 1) {
if (num > 0)
break;
iparam = NULL;
@ -469,9 +513,9 @@ param_filter(struct pw_link *this,
for (oidx = 0;;) {
pw_log_debug("oparam %d", oidx);
if (spa_node_port_enum_params(out_port->node->node, out_port->direction,
if (spa_node_port_enum_params_sync(out_port->node->node, out_port->direction,
out_port->port_id, id, &oidx,
iparam, &oparam, result) <= 0) {
iparam, &oparam, result) != 1) {
break;
}
@ -680,7 +724,7 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
goto error;
}
if (SPA_RESULT_IS_ASYNC(res)) {
spa_node_sync(output->node->node, res);
//spa_node_sync(output->node->node, res);
pw_work_queue_add(impl->work, output->node, res, complete_paused,
&this->rt.out_mix);
}
@ -700,7 +744,7 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
goto error;
}
if (SPA_RESULT_IS_ASYNC(res)) {
spa_node_sync(input->node->node, res);
//spa_node_sync(input->node->node, res);
pw_work_queue_add(impl->work, input->node, res, complete_paused,
&this->rt.in_mix);
}
@ -723,7 +767,10 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
goto error;
}
if (SPA_RESULT_IS_ASYNC(res)) {
spa_node_sync(output->node->node, res);
spa_node_wait(output->node->node, res,
make_pending(impl),
complete_output,
this);
pw_work_queue_add(impl->work, output->node, res, complete_paused,
&this->rt.out_mix);
}
@ -743,7 +790,10 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
goto error;
}
if (SPA_RESULT_IS_ASYNC(res)) {
spa_node_sync(input->node->node, res);
spa_node_wait(input->node->node, res,
make_pending(impl),
complete_input,
this);
pw_work_queue_add(impl->work, input->node, res, complete_paused,
&this->rt.in_mix);
}
@ -870,6 +920,7 @@ static void check_states(void *obj, void *user_data, int res, uint32_t id)
this, -EBUSY, (pw_work_func_t) check_states, this);
}
#if 0
static void
input_node_async_complete(void *data, uint32_t seq, int res)
{
@ -889,6 +940,7 @@ output_node_async_complete(void *data, uint32_t seq, int res)
pw_log_debug("link %p: node %p async complete %d %d", impl, node, seq, res);
pw_work_queue_complete(impl->work, node, seq, res);
}
#endif
static void clear_port_buffers(struct pw_link *link, struct pw_port *port)
{
@ -1126,12 +1178,12 @@ static const struct pw_port_events output_port_events = {
static const struct pw_node_events input_node_events = {
PW_VERSION_NODE_EVENTS,
.async_complete = input_node_async_complete,
// .async_complete = input_node_async_complete,
};
static const struct pw_node_events output_node_events = {
PW_VERSION_NODE_EVENTS,
.async_complete = output_node_async_complete,
// .async_complete = output_node_async_complete,
};
static int find_driver(struct pw_link *this)

View file

@ -31,6 +31,7 @@
#include <sys/eventfd.h>
#include <spa/pod/parser.h>
#include <spa/node/utils.h>
#include "pipewire/interfaces.h"
#include "pipewire/private.h"
@ -61,6 +62,7 @@ struct impl {
uint32_t next_position;
int last_error;
struct spa_pending init_pending;
};
struct resource_data {
@ -154,6 +156,7 @@ static int start_node(struct pw_node *this)
res = spa_node_send_command(this->node,
&SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Start));
if (res < 0)
pw_log_debug("node %p: start node error %s", this, spa_strerror(res));
@ -834,35 +837,55 @@ static int node_port_info(void *data, enum spa_direction direction, uint32_t por
return 0;
}
static int node_error(void *data, int res, const char *message)
{
struct pw_node *node = data;
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
struct node_pending {
struct spa_pending pending;
struct impl *impl;
enum pw_node_state state;
};
pw_log_debug("node %p: error event %d: %s", node, res, message);
impl->last_error = res;
node_update_state(node, PW_NODE_STATE_ERROR, strdup(message));
return 0;
static void remove_pending(struct spa_pending *pending)
{
free(pending);
}
static int node_done(void *data, uint32_t seq)
static struct node_pending *make_pending(struct impl *impl, enum pw_node_state state)
{
struct pw_node *node = data;
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
struct node_pending *pending;
pending = calloc(1, sizeof(struct node_pending));
pending->pending.removed = remove_pending;
pending->impl = impl;
pending->state = state;
return pending;
}
pw_log_debug("node %p: done event %u", node, seq);
pw_work_queue_complete(impl->work, node, seq, impl->last_error);
pw_node_events_async_complete(node, seq, impl->last_error);
impl->last_error = 0;
static int node_complete(void *data, int seq, int res, const void *result)
{
struct node_pending *pending = data;
struct impl *impl = pending->impl;
seq = SPA_RESULT_ASYNC_SEQ(seq);
pw_log_debug("node %p: done event %d %u", impl, res, pending->pending.seq);
impl->last_error = res;
pw_work_queue_complete(impl->work, &impl->this, seq, res);
return 0;
}
static int node_event(void *data, struct spa_event *event)
{
struct pw_node *node = data;
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
pw_log_trace("node %p: event %d", node, SPA_EVENT_TYPE(event));
switch (SPA_NODE_EVENT_ID(event)) {
case SPA_NODE_EVENT_Error:
impl->last_error = -EFAULT;
node_update_state(node, PW_NODE_STATE_ERROR, strdup("error"));
break;
default:
break;
}
pw_node_events_event(node, event);
return 0;
}
@ -903,8 +926,6 @@ static int node_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_id)
static const struct spa_node_callbacks node_callbacks = {
SPA_VERSION_NODE_CALLBACKS,
.done = node_done,
.error = node_error,
.info = node_info,
.port_info = node_port_info,
.event = node_event,
@ -912,14 +933,28 @@ static const struct spa_node_callbacks node_callbacks = {
.reuse_buffer = node_reuse_buffer,
};
SPA_EXPORT
void pw_node_set_implementation(struct pw_node *node,
struct spa_node *spa_node)
static int init_result(void *data, int seq, int res, const void *result)
{
pw_log_debug("node %p: set_callbacks finished", data);
return 0;
}
SPA_EXPORT
int pw_node_set_implementation(struct pw_node *node,
struct spa_node *spa_node)
{
int res;
struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this);
node->node = spa_node;
pw_log_debug("node %p: implementation %p", node, spa_node);
spa_node_set_callbacks(node->node, &node_callbacks, node);
spa_graph_node_set_callbacks(&node->rt.node, &spa_graph_node_impl_default, spa_node);
res = spa_node_set_callbacks(node->node, &node_callbacks, node);
if (SPA_RESULT_IS_ASYNC(res)) {
pw_log_debug("node %p: init is async %d", node, res);
spa_node_wait(node->node, res, &impl->init_pending, init_result, node);
}
if (spa_node_set_io(node->node,
SPA_IO_Position,
@ -935,6 +970,7 @@ void pw_node_set_implementation(struct pw_node *node,
pw_log_debug("node %p: set clock %p", node, &node->rt.activation->position.clock);
node->rt.clock = &node->rt.activation->position.clock;
}
return res;
}
SPA_EXPORT
@ -1068,9 +1104,9 @@ int pw_node_for_each_param(struct pw_node *node,
spa_pod_builder_init(&b, buf, sizeof(buf));
idx = index;
if ((res = spa_node_enum_params(node->node,
if ((res = spa_node_enum_params_sync(node->node,
param_id, &index,
filter, &param, &b)) <= 0)
filter, &param, &b)) != 1)
break;
if ((res = callback(data, param_id, idx, index, param)) != 0)
@ -1232,8 +1268,12 @@ int pw_node_set_state(struct pw_node *node, enum pw_node_state state)
if (SPA_RESULT_IS_ERROR(res))
return res;
if (SPA_RESULT_IS_ASYNC(res))
spa_node_sync(node->node, res);
if (SPA_RESULT_IS_ASYNC(res)) {
struct node_pending *pending = make_pending(impl, state);
spa_node_wait(node->node, res, &pending->pending,
node_complete, pending);
}
pw_work_queue_add(impl->work,
node, res, on_state_complete, SPA_INT_TO_PTR(state));

View file

@ -83,9 +83,6 @@ struct pw_node_events {
void (*state_changed) (void *data, enum pw_node_state old,
enum pw_node_state state, const char *error);
/** an async operation completed on the node */
void (*async_complete) (void *data, uint32_t seq, int res);
/** an event is emited */
void (*event) (void *data, const struct spa_event *event);
@ -147,7 +144,8 @@ const struct pw_properties *pw_node_get_properties(struct pw_node *node);
int pw_node_update_properties(struct pw_node *node, const struct spa_dict *dict);
/** Set the node implementation */
void pw_node_set_implementation(struct pw_node *node, struct spa_node *spa_node);
int pw_node_set_implementation(struct pw_node *node, struct spa_node *spa_node);
/** Get the node implementation */
struct spa_node *pw_node_get_implementation(struct pw_node *node);

View file

@ -27,6 +27,7 @@
#include <errno.h>
#include <spa/pod/parser.h>
#include <spa/node/utils.h>
#include <spa/debug/types.h>
#include "pipewire/pipewire.h"
@ -463,6 +464,7 @@ static const struct pw_resource_events resource_events = {
static int reply_param(void *data, uint32_t id, uint32_t index, uint32_t next, struct spa_pod *param)
{
struct pw_resource *resource = data;
pw_log_debug("resource %p: reply param %d %d %d", resource, id, index, next);
pw_port_resource_param(resource, id, index, next, param);
return 0;
}
@ -474,6 +476,7 @@ static int port_enum_params(void *object, uint32_t id, uint32_t index, uint32_t
struct resource_data *data = pw_resource_get_user_data(resource);
struct pw_port *port = data->port;
int res;
pw_log_debug("resource %p: enum params", resource);
if ((res = pw_port_for_each_param(port, id, index, num, filter,
reply_param, resource)) < 0)
@ -758,15 +761,17 @@ int pw_port_for_each_param(struct pw_port *port,
for (count = 0; count < max; count++) {
spa_pod_builder_init(&b, buf, sizeof(buf));
idx = index;
if ((res = spa_node_port_enum_params(node->node,
if ((res = spa_node_port_enum_params_sync(node->node,
port->direction, port->port_id,
param_id, &index,
filter, &param, &b)) <= 0)
filter, &param, &b)) != 1)
break;
pw_log_debug("port %p: have param %d %u %u", port, param_id, idx, index);
if ((res = callback(data, param_id, idx, index, param)) != 0)
break;
}
pw_log_debug("port %p: res %d", port, res);
return res;
}

View file

@ -147,11 +147,13 @@ void pw_proxy_destroy(struct pw_proxy *proxy)
}
SPA_EXPORT
int pw_proxy_sync(struct pw_proxy *proxy, uint32_t seq)
int pw_proxy_sync(struct pw_proxy *proxy)
{
int res = -EIO;
if (proxy->remote->core_proxy != NULL)
res = pw_core_proxy_sync(proxy->remote->core_proxy, proxy->id, seq);
if (proxy->remote->core_proxy != NULL) {
res = pw_core_proxy_sync(proxy->remote->core_proxy, proxy->id);
pw_log_debug("proxy %p: %u sync %u", proxy, proxy->id, res);
}
return res;
}

View file

@ -151,8 +151,8 @@ uint32_t pw_proxy_get_id(struct pw_proxy *proxy);
struct pw_protocol *pw_proxy_get_protocol(struct pw_proxy *proxy);
/** Generate an sync method for a proxy. This will generate a done event
* with the same \a seq. */
int pw_proxy_sync(struct pw_proxy *proxy, uint32_t seq);
* with the same seq number of the reply. */
int pw_proxy_sync(struct pw_proxy *proxy);
/** Generate an error for a proxy */
int pw_proxy_error(struct pw_proxy *proxy, int result, const char *error, ...);

View file

@ -170,11 +170,13 @@ const struct pw_protocol_marshal *pw_resource_get_marshal(struct pw_resource *re
}
SPA_EXPORT
int pw_resource_sync(struct pw_resource *resource, uint32_t seq)
int pw_resource_sync(struct pw_resource *resource)
{
int res = -EIO;
if (resource->client->core_resource != NULL)
res = pw_core_resource_sync(resource->client->core_resource, resource->id, seq);
if (resource->client->core_resource != NULL) {
res = pw_core_resource_sync(resource->client->core_resource, resource->id);
pw_log_debug("resource %p: %u sync %u", resource, resource->id, res);
}
return res;
}

View file

@ -123,8 +123,8 @@ void pw_resource_add_override(struct pw_resource *resource,
void *data);
/** Generate an sync method for a resource. This will generate a done event
* with the same \a seq. */
int pw_resource_sync(struct pw_resource *resource, uint32_t seq);
* with the same \a sequence number in the return value. */
int pw_resource_sync(struct pw_resource *resource);
/** Generate an error for a resource */
int pw_resource_error(struct pw_resource *resource, int result, const char *error, ...);

View file

@ -142,7 +142,7 @@ static struct param *add_param(struct pw_stream *stream,
struct param *p;
struct spa_pod *copy = NULL;
if (param != NULL && (copy = pw_spa_pod_copy(param)) == NULL)
if (param != NULL && (copy = spa_pod_copy(param)) == NULL)
return NULL;
p = pw_array_add(&impl->params, sizeof(struct param));
@ -378,49 +378,65 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction,
static int impl_port_enum_params(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct stream *d = SPA_CONTAINER_OF(node, struct stream, impl_node);
struct spa_pod *param;
uint32_t last_id = SPA_ID_INVALID;
uint32_t n_params = pw_array_get_len(&d->params, struct param);
struct spa_result_node_enum_params result;
uint8_t buffer[1024];
struct spa_pod_builder b = { 0 };
uint32_t count = 0;
int res;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
while (true) {
if (*index < n_params) {
param = pw_array_get_unchecked(&d->params, *index, struct param)->param;
if (result.next < n_params) {
param = pw_array_get_unchecked(&d->params, result.next, struct param)->param;
}
else if (last_id != SPA_ID_INVALID)
return 1;
break;
else
return 0;
(*index)++;
result.next++;
if (id == SPA_PARAM_List) {
uint32_t new_id = ((struct spa_pod_object *) param)->body.id;
if (last_id == SPA_ID_INVALID){
*result = spa_pod_builder_add_object(builder,
result.param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(new_id));
last_id = new_id;
}
else if (last_id != new_id) {
(*index)--;
result.next--;
break;
}
} else {
if (param == NULL || !spa_pod_is_object_id(param, id))
continue;
if (spa_pod_filter(builder, result, param, filter) == 0)
if (spa_pod_filter(&b, &result.param, param, filter) == 0)
break;
}
}
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int port_set_format(struct spa_node *node,

View file

@ -52,20 +52,6 @@ pw_free_strv(char **str);
char *
pw_strip(char *str, const char *whitespace);
/** Copy a pod structure \memberof pw_utils */
static inline struct spa_pod *
pw_spa_pod_copy(const struct spa_pod *pod)
{
size_t size;
struct spa_pod *c;
size = SPA_POD_SIZE(pod);
if ((c = (struct spa_pod *) malloc(size)) == NULL)
return NULL;
return (struct spa_pod *) memcpy(c, pod, size);
}
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -27,6 +27,7 @@
#include <string.h>
#include <spa/utils/type.h>
#include <spa/utils/result.h>
#include "pipewire/log.h"
#include "pipewire/work-queue.h"

View file

@ -73,6 +73,7 @@ struct remote_data {
struct pw_remote *remote;
struct spa_hook remote_listener;
uint32_t prompt_pending;
struct pw_core_proxy *core_proxy;
struct spa_hook core_listener;
@ -261,13 +262,9 @@ static int on_core_done(void *_data, uint32_t id, uint32_t seq)
{
struct remote_data *rd = _data;
switch (seq) {
case 1:
if (seq == rd->prompt_pending)
show_prompt(rd);
break;
default:
break;
}
return 0;
}
@ -396,7 +393,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old,
pw_registry_proxy_add_listener(rd->registry_proxy,
&rd->registry_listener,
&registry_events, rd);
pw_core_proxy_sync(rd->core_proxy, 0, 1);
rd->prompt_pending = pw_core_proxy_sync(rd->core_proxy, 0);
break;
default:
@ -1390,7 +1387,7 @@ static void do_input(void *data, int fd, enum spa_io mask)
if (d->current == NULL)
pw_main_loop_quit(d->loop);
else if (d->current->core_proxy)
pw_core_proxy_sync(d->current->core_proxy, 0, 1);
d->current->prompt_pending = pw_core_proxy_sync(d->current->core_proxy, 0);
}
}

View file

@ -52,7 +52,6 @@ struct data {
struct pw_registry_proxy *registry_proxy;
struct spa_hook registry_listener;
uint32_t seq;
struct spa_list pending_list;
};
@ -81,8 +80,7 @@ static void add_pending(struct proxy_data *pd)
struct data *d = pd->data;
spa_list_append(&d->pending_list, &pd->pending_link);
pd->pending_seq = ++d->seq;
pw_core_proxy_sync(d->core_proxy, 0, pd->pending_seq);
pd->pending_seq = pw_core_proxy_sync(d->core_proxy, 0);
}
static void remove_pending(struct proxy_data *pd)
@ -126,7 +124,7 @@ static int add_param(struct proxy_data *data, const struct spa_pod *param)
data->params = realloc(data->params, sizeof(struct spa_pod *) * data->n_params);
if (data->params == NULL)
return -ENOMEM;
data->params[idx] = pw_spa_pod_copy(param);
data->params[idx] = spa_pod_copy(param);
return 0;
}
@ -710,7 +708,6 @@ int main(int argc, char *argv[])
if (pw_remote_connect(data.remote) < 0)
return -1;
data.seq = 1;
spa_list_init(&data.pending_list);
pw_main_loop_run(data.loop);