diff --git a/pipewire-jack b/pipewire-jack index 65f9c4652..1887f17cc 160000 --- a/pipewire-jack +++ b/pipewire-jack @@ -1 +1 @@ -Subproject commit 65f9c4652514675b5cc6769d17853aee9542c63f +Subproject commit 1887f17cc8e829c3bca74bc3d4e37c267654b377 diff --git a/pipewire-pulseaudio b/pipewire-pulseaudio index 71e5c1319..bf91b8c00 160000 --- a/pipewire-pulseaudio +++ b/pipewire-pulseaudio @@ -1 +1 @@ -Subproject commit 71e5c131917b0cad04911f6cb868d44691dbae8d +Subproject commit bf91b8c002b51cf9af1c7be4b0e1e50bcc83cc1a diff --git a/spa/examples/example-control.c b/spa/examples/example-control.c index 2aaa56114..f38b14ef9 100644 --- a/spa/examples/example-control.c +++ b/spa/examples/example-control.c @@ -97,6 +97,8 @@ struct data { bool rebuild_fds; struct pollfd fds[16]; unsigned int n_fds; + + struct spa_pending_queue pending; }; #define MIN_LATENCY 1024 @@ -375,7 +377,8 @@ static int negotiate_formats(struct data *data) if ((res = spa_node_port_enum_params_sync(data->sink, SPA_DIRECTION_INPUT, 0, SPA_PARAM_EnumFormat, &state, - filter, &format, &b)) != 1) + filter, &format, &b, + &data->pending)) != 1) return -EBADF; spa_log_debug(&default_log.log, "sink set_param"); @@ -511,6 +514,8 @@ int main(int argc, char *argv[]) data.data_loop.remove_source = do_remove_source; data.data_loop.invoke = do_invoke; + spa_pending_queue_init(&data.pending); + if ((str = getenv("SPA_DEBUG"))) data.log->level = atoi(str); diff --git a/spa/examples/local-v4l2.c b/spa/examples/local-v4l2.c index 00af70e24..3e64855e0 100644 --- a/spa/examples/local-v4l2.c +++ b/spa/examples/local-v4l2.c @@ -89,6 +89,8 @@ struct data { struct spa_buffer *bp[MAX_BUFFERS]; struct buffer buffers[MAX_BUFFERS]; unsigned int n_buffers; + + struct spa_pending_queue pending; }; static int load_handle(struct data *data, struct spa_handle **handle, const char *lib, const char *name) @@ -240,9 +242,16 @@ static int on_source_ready(void *_data, int status) return 0; } +static int on_source_result(void *_data, int seq, int res, const void *result) +{ + struct data *data = _data; + return spa_pending_queue_complete(&data->pending, seq, res, result); +} + static const struct spa_node_callbacks source_callbacks = { SPA_VERSION_NODE_CALLBACKS, - .ready = on_source_ready + .ready = on_source_ready, + .result = on_source_result, }; static int make_nodes(struct data *data, const char *device) @@ -264,7 +273,7 @@ static int make_nodes(struct data *data, const char *device) 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) { + &index, NULL, &props, &b, &data->pending)) == 1) { spa_debug_pod(0, NULL, props); } @@ -468,6 +477,8 @@ int main(int argc, char *argv[]) struct spa_handle *handle = NULL; void *iface; + spa_pending_queue_init(&data.pending); + if ((res = load_handle(&data, &handle, PATH "support/libspa-support.so", "loop")) < 0) return res; diff --git a/spa/include/spa/monitor/device.h b/spa/include/spa/monitor/device.h index 77ddce100..2f3792182 100644 --- a/spa/include/spa/monitor/device.h +++ b/spa/include/spa/monitor/device.h @@ -65,6 +65,14 @@ struct spa_device_object_info { #define SPA_DEVICE_OBJECT_INFO_INIT() (struct spa_device_object_info){ SPA_VERSION_DEVICE_OBJECT_INFO, } +/** the result of spa_device_enum_params() */ +struct spa_result_device_params { + uint32_t id; + uint32_t index; + uint32_t next; + struct spa_pod *param; +}; + /** * spa_device_callbacks: */ @@ -76,6 +84,9 @@ struct spa_device_callbacks { /** notify extra information about the device */ int (*info) (void *data, const struct spa_device_info *info); + /** notify a result */ + int (*result) (void *data, int seq, int res, const void *result); + /** a device event */ int (*event) (void *data, struct spa_event *event); @@ -121,25 +132,27 @@ struct spa_device { * * This function must be called from the main thread. * + * The result callback will be called at most \num times with a + * struct spa_result_device_params as the result. If the result + * callback returns anything other than 0, this function will stop + * and return that value. + * * \param device a \ref spa_device + * \param seq a sequence numeber to pass to the result function * \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 index the index of enumeration, pass 0 for the first item. + * \param num the maximum number of items to iterate * \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 + * \return 0 when there are no more parameters to enumerate * -EINVAL when invalid arguments are given * -ENOENT the parameter \a id is unknown * -ENOTSUP when there are no parameters * implemented on \a device */ - int (*enum_params) (struct spa_device *device, - uint32_t id, uint32_t *index, - const struct spa_pod *filter, - struct spa_pod **param, - struct spa_pod_builder *builder); + int (*enum_params) (struct spa_device *device, int seq, + uint32_t id, uint32_t index, uint32_t num, + const struct spa_pod *filter); + /** * Set the configurable parameter in \a device. * diff --git a/spa/include/spa/node/node.h b/spa/include/spa/node/node.h index 136772d96..49590b775 100644 --- a/spa/include/spa/node/node.h +++ b/spa/include/spa/node/node.h @@ -94,6 +94,19 @@ struct spa_port_info { #define SPA_PORT_INFO_INIT() (struct spa_port_info) { 0, } +/** an error result */ +struct spa_result_node_error { + const char *message; +}; + +/** the result of enum_param. */ +struct spa_result_node_params { + uint32_t id; /**< id of parameter */ + uint32_t index; /**< index of parameter */ + uint32_t next; /**< next index of iteration */ + struct spa_pod *param; /**< the result param */ +}; + struct spa_node_callbacks { #define SPA_VERSION_NODE_CALLBACKS 0 uint32_t version; /**< version of this structure */ @@ -106,6 +119,22 @@ struct spa_node_callbacks { enum spa_direction direction, uint32_t port, const struct spa_port_info *info); + /** notify a result. + * + * Some method will return an async return value when called. Depending + * on the method, this can then trigger a result callback with an + * optional result. Look at the documentation of the method to know + * when to expect a result value. + * + * The result callback can be called synchronously, as a callback + * called from inside the method itself, in which case the seq + * number passed to the method will be passed. + * + * Users of the API will usually use a struct spa_pending_queue + * to dispatch result values to listeners. + */ + int (*result) (void *data, int seq, int res, const void *result); + /** * \param node a spa_node * \param event the event that was emited @@ -149,11 +178,6 @@ 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. @@ -181,46 +205,19 @@ struct spa_node { /** * Perform a sync operation. * - * This method will complete when all previous methods on the node - * are completed. + * This method will emit the result callback with the given sequence + * number synchronously or with the returned async return value + * asynchronously. * * 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. - * + * \param seq a sequence number * \return 0 on success * -EINVAL when node is NULL * an async result */ - 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 seq 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 seq, struct spa_pending *pending, - spa_pending_func_t func, void *data); + int (*sync) (struct spa_node *node, int seq); /** * Enumerate the parameters of a node. @@ -238,7 +235,7 @@ struct spa_node { * \param num the number of parameters to enumerate * \param filter and optional filter to use * \param func the callback with the result. The result will be - * of type struct spa_result_node_enum_params. The next field + * of type struct spa_result_node_params. The next field * can be used to continue the enumeration. * \param data first argument to \a func * @@ -249,10 +246,9 @@ struct spa_node { * -ENOTSUP when there are no parameters * implemented on \a node */ - int (*enum_params) (struct spa_node *node, + int (*enum_params) (struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t max, - const struct spa_pod *filter, - spa_result_func_t func, void *data); + const struct spa_pod *filter); /** * Set the configurable parameter in \a node. @@ -341,24 +337,22 @@ struct spa_node { * Enumerate all possible parameters of \a id on \a port_id of \a node * that are compatible with \a filter. * - * Use \a index to retrieve the parameters one by one until the function - * returns 0. - * * The result parameters can be queried and modified and ultimately be used * to call port_set_param. * * This function must be called from the main thread. * + * The result callback will be called with a struct spa_result_node_params. + * * \param node a spa_node * \param direction an spa_direction * \param port_id the port to query + * \param seq a sequence number to pass to the synchronous result callback * \param id the parameter id to query * \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 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 func the callback with the result. * \param data first argument to \a func * * \return the return value of \a func or 0 when no more @@ -367,11 +361,10 @@ struct spa_node { * -EINVAL when invalid parameters are given * -ENOENT when \a id is unknown */ - int (*port_enum_params) (struct spa_node *node, + int (*port_enum_params) (struct spa_node *node, int seq, 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); + const struct spa_pod *filter); /** * Set a parameter on \a port_id of \a node. * @@ -535,8 +528,7 @@ struct spa_node { }; #define spa_node_set_callbacks(n,...) (n)->set_callbacks((n),__VA_ARGS__) -#define spa_node_sync(n) (n)->sync((n)) -#define spa_node_wait(n,...) (n)->wait((n),__VA_ARGS__) +#define spa_node_sync(n,...) (n)->sync((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__) diff --git a/spa/include/spa/node/utils.h b/spa/include/spa/node/utils.h index b0adbcdf7..ec060578f 100644 --- a/spa/include/spa/node/utils.h +++ b/spa/include/spa/node/utils.h @@ -31,39 +31,48 @@ extern "C" { #include -struct spa_result_node_enum_params_data { +struct spa_result_node_params_data { struct spa_pod_builder *builder; - struct spa_result_node_enum_params data; + struct spa_result_node_params data; }; -static inline int spa_result_func_node_enum_params(void *data, - uint32_t count, const void *result) +static inline int spa_result_func_node_params(struct spa_pending *pending, + 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; + struct spa_result_node_params_data *d = + (struct spa_result_node_params_data *)pending->data; + const struct spa_result_node_params *r = + (const struct spa_result_node_params *)result; 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 1; + return 0; } 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_pod_builder *builder, + struct spa_pending_queue *queue) { - struct spa_result_node_enum_params_data data = { builder, }; - int res; + struct spa_result_node_params_data data = { builder, }; + struct spa_pending pending; + int res = 0; - 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; + spa_pending_queue_add(queue, 0, &pending, + spa_result_func_node_params, &data); + res = spa_node_enum_params(node, 0, id, *index, 1, filter); + if (data.data.param == NULL) { + spa_pending_remove(&pending); + if (res > 0) + res = 0; + } else { + *index = data.data.next; + *param = data.data.param; + res = 1; + } return res; } @@ -72,16 +81,26 @@ static inline int spa_node_port_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_pod_builder *builder, + struct spa_pending_queue *queue) { - struct spa_result_node_enum_params_data data = { builder, }; + struct spa_result_node_params_data data = { builder, }; + struct spa_pending pending; 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; + spa_pending_queue_add(queue, 0, &pending, + spa_result_func_node_params, &data); + res = spa_node_port_enum_params(node, 0, direction, port_id, + id, *index, 1, filter); + if (data.data.param == NULL) { + spa_pending_remove(&pending); + if (res > 0) + res = 0; + } else { + *index = data.data.next; + *param = data.data.param; + res = 1; + } return res; } diff --git a/spa/include/spa/utils/result.h b/spa/include/spa/utils/result.h index e32c22931..06e876502 100644 --- a/spa/include/spa/utils/result.h +++ b/spa/include/spa/utils/result.h @@ -43,8 +43,6 @@ extern "C" { #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, uint32_t count, const void *result); - struct spa_pending; typedef int (*spa_pending_func_t) (struct spa_pending *pending, const void *result); @@ -52,11 +50,49 @@ typedef int (*spa_pending_func_t) (struct spa_pending *pending, const void *resu struct spa_pending { struct spa_list link; /**< link used internally */ int seq; /**< sequence number of pending result */ - int res; /**< result code of operation */ + int res; /**< result code of operation, valid in callback */ spa_pending_func_t func; /**< callback function */ void *data; /**< extra user data */ }; +static inline void spa_pending_remove(struct spa_pending *pending) +{ + spa_list_remove(&pending->link); +} + +struct spa_pending_queue { + struct spa_list pending; + int seq; +}; + +static inline void spa_pending_queue_init(struct spa_pending_queue *queue) +{ + spa_list_init(&queue->pending); +} + +static inline void spa_pending_queue_add(struct spa_pending_queue *queue, + int seq, struct spa_pending *pending, spa_pending_func_t func, void *data) +{ + pending->seq = seq; + pending->func = func; + pending->data = data; + spa_list_append(&queue->pending, &pending->link); +} + +static inline int spa_pending_queue_complete(struct spa_pending_queue *queue, + int seq, int res, const void *result) +{ + struct spa_pending *p, *t; + spa_list_for_each_safe(p, t, &queue->pending, link) { + if (p->seq == seq) { + p->res = res; + spa_pending_remove(p); + p->func(p, result); + } + } + return 0; +} + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/spa/plugins/alsa/alsa-device.c b/spa/plugins/alsa/alsa-device.c index 997cc24ff..913efe687 100644 --- a/spa/plugins/alsa/alsa-device.c +++ b/spa/plugins/alsa/alsa-device.c @@ -277,24 +277,29 @@ static int impl_set_callbacks(struct spa_device *device, } -static int impl_enum_params(struct spa_device *device, - uint32_t id, uint32_t *index, - const struct spa_pod *filter, - struct spa_pod **result, - struct spa_pod_builder *builder) +static int impl_enum_params(struct spa_device *device, int seq, + uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter) { struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; + struct spa_result_device_params result; + uint32_t count = 0; + int res; spa_return_val_if_fail(device != 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); this = SPA_CONTAINER_OF(device, struct impl, device); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; + result.next = start; next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -303,17 +308,17 @@ static int impl_enum_params(struct spa_device *device, uint32_t list[] = { SPA_PARAM_EnumProfile, SPA_PARAM_Profile }; - if (*index < SPA_N_ELEMENTS(list)) + if (result.index < 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.index])); else return 0; break; } case SPA_PARAM_EnumProfile: { - switch (*index) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamProfile, id, @@ -333,7 +338,7 @@ static int impl_enum_params(struct spa_device *device, } case SPA_PARAM_Profile: { - switch (*index) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamProfile, id, @@ -348,12 +353,16 @@ static int impl_enum_params(struct spa_device *device, return -ENOENT; } - (*index)++; - - 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 = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) + return res; + + if (++count != num) + goto next; + + return 0; } static int impl_set_param(struct spa_device *device, diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c index daeb85d30..dc284dba5 100644 --- a/spa/plugins/alsa/alsa-sink.c +++ b/spa/plugins/alsa/alsa-sink.c @@ -48,28 +48,29 @@ static void reset_props(struct props *props) props->max_latency = default_max_latency; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct state *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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 state, node); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -78,10 +79,10 @@ static int impl_node_enum_params(struct spa_node *node, uint32_t list[] = { SPA_PARAM_PropInfo, SPA_PARAM_Props }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; @@ -90,7 +91,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, @@ -135,7 +136,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, @@ -154,12 +155,10 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -274,12 +273,6 @@ static void emit_port_info(struct state *this) } } -static int -impl_node_sync(struct spa_node *node) -{ - return 0; -} - static int impl_node_set_callbacks(struct spa_node *node, const struct spa_node_callbacks *callbacks, @@ -312,32 +305,33 @@ 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, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { struct state *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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 state, node); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -349,21 +343,21 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO, }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: - return spa_alsa_enum_format(this, start, num, filter, func, data); + return spa_alsa_enum_format(this, seq, start, num, filter); case SPA_PARAM_Format: if (!this->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw); @@ -372,7 +366,7 @@ impl_node_port_enum_params(struct spa_node *node, case SPA_PARAM_Buffers: if (!this->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -391,7 +385,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!this->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -404,7 +398,7 @@ impl_node_port_enum_params(struct spa_node *node, break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -432,12 +426,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -665,7 +657,6 @@ 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, - .sync = impl_node_sync, .enum_params = impl_node_enum_params, .set_param = impl_node_set_param, .set_io = impl_node_set_io, diff --git a/spa/plugins/alsa/alsa-source.c b/spa/plugins/alsa/alsa-source.c index ffc09303c..fb10f3664 100644 --- a/spa/plugins/alsa/alsa-source.c +++ b/spa/plugins/alsa/alsa-source.c @@ -48,30 +48,31 @@ static void reset_props(struct props *props) props->max_latency = default_max_latency; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { 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; + struct spa_result_node_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 state, node); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); p = &this->props; + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -80,16 +81,16 @@ static int impl_node_enum_params(struct spa_node *node, uint32_t list[] = { SPA_PARAM_PropInfo, SPA_PARAM_Props, }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_PropInfo: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, @@ -131,7 +132,7 @@ static int impl_node_enum_params(struct spa_node *node, break; case SPA_PARAM_Props: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, @@ -150,12 +151,10 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -317,31 +316,33 @@ static void recycle_buffer(struct state *this, uint32_t buffer_id) } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { struct state *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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 state, node); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); - result.next = start; + result.id = id; + result.next = start; next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -352,21 +353,21 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Buffers, SPA_PARAM_Meta }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: - return spa_alsa_enum_format(this, start, num, filter, func, data); + return spa_alsa_enum_format(this, seq, start, num, filter); case SPA_PARAM_Format: if (!this->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw); @@ -375,7 +376,7 @@ impl_node_port_enum_params(struct spa_node *node, case SPA_PARAM_Buffers: if (!this->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -394,7 +395,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!this->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -407,7 +408,7 @@ impl_node_port_enum_params(struct spa_node *node, break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -429,12 +430,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/alsa/alsa-utils.c b/spa/plugins/alsa/alsa-utils.c index 219448cd9..bf6f1cef0 100644 --- a/spa/plugins/alsa/alsa-utils.c +++ b/spa/plugins/alsa/alsa-utils.c @@ -217,9 +217,8 @@ static void sanitize_map(snd_pcm_chmap_t* map) } int -spa_alsa_enum_format(struct state *state, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) +spa_alsa_enum_format(struct state *state, int seq, uint32_t start, uint32_t num, + const struct spa_pod *filter) { snd_pcm_t *hndl; snd_pcm_hw_params_t *params; @@ -236,7 +235,7 @@ spa_alsa_enum_format(struct state *state, uint32_t start, uint32_t num, int res; bool opened; struct spa_pod_frame f[2]; - struct spa_result_node_enum_params result; + struct spa_result_node_params result; uint32_t count = 0; opened = state->opened; @@ -246,6 +245,8 @@ spa_alsa_enum_format(struct state *state, uint32_t start, uint32_t num, result.next = start; next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); hndl = state->hndl; @@ -316,11 +317,11 @@ spa_alsa_enum_format(struct state *state, uint32_t start, uint32_t num, uint32_t channel; snd_pcm_chmap_t* map; - if (maps[result.next] == NULL) { + if (maps[result.index] == NULL) { snd_pcm_free_chmaps(maps); goto enum_end; } - map = &maps[result.next]->map; + map = &maps[result.index]->map; spa_log_debug(state->log, "map %d channels", map->channels); sanitize_map(map); @@ -338,7 +339,7 @@ spa_alsa_enum_format(struct state *state, uint32_t start, uint32_t num, snd_pcm_free_chmaps(maps); } else { - if (result.next > 0) + if (result.index > 0) goto enum_end; spa_pod_builder_push_choice(&b, &f[1], SPA_CHOICE_None, 0); @@ -354,12 +355,10 @@ spa_alsa_enum_format(struct state *state, uint32_t start, uint32_t num, fmt = spa_pod_builder_pop(&b, &f[0]); - result.next++; - if ((res = spa_pod_filter(&b, &result.param, fmt, filter)) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = state->callbacks->result(state->callbacks_data, seq, 0, &result)) != 0) goto exit; if (++count != num) diff --git a/spa/plugins/alsa/alsa-utils.h b/spa/plugins/alsa/alsa-utils.h index 1f2cef610..552689610 100644 --- a/spa/plugins/alsa/alsa-utils.h +++ b/spa/plugins/alsa/alsa-utils.h @@ -143,10 +143,9 @@ struct state { }; int -spa_alsa_enum_format(struct state *state, +spa_alsa_enum_format(struct state *state, int seq, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data); + const struct spa_pod *filter); int spa_alsa_set_format(struct state *state, struct spa_audio_info *info, uint32_t flags); diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c index 16731e094..48c95dd09 100644 --- a/spa/plugins/audioconvert/audioconvert.c +++ b/spa/plugins/audioconvert/audioconvert.c @@ -88,6 +88,8 @@ struct impl { struct spa_node *fmt[2]; struct spa_node *channelmix; struct spa_node *resample; + + struct spa_pending_queue pending; }; static int make_link(struct impl *this, @@ -149,7 +151,8 @@ static int debug_params(struct impl *this, struct spa_node *node, res = spa_node_port_enum_params_sync(node, direction, port_id, id, &state, - NULL, ¶m, &b); + NULL, ¶m, &b, + &this->pending); if (res != 1) break; @@ -181,7 +184,8 @@ static int negotiate_link_format(struct impl *this, struct link *link) if ((res = spa_node_port_enum_params_sync(link->out_node, SPA_DIRECTION_OUTPUT, link->out_port, SPA_PARAM_EnumFormat, &state, - filter, &format, &b)) != 1) { + filter, &format, &b, + &this->pending)) != 1) { debug_params(this, link->out_node, SPA_DIRECTION_OUTPUT, link->out_port, SPA_PARAM_EnumFormat, filter); return -ENOTSUP; @@ -191,7 +195,8 @@ static int negotiate_link_format(struct impl *this, struct link *link) if ((res = spa_node_port_enum_params_sync(link->in_node, SPA_DIRECTION_INPUT, link->in_port, SPA_PARAM_EnumFormat, &state, - filter, &format, &b)) != 1) { + filter, &format, &b, + &this->pending)) != 1) { debug_params(this, link->in_node, SPA_DIRECTION_INPUT, link->in_port, SPA_PARAM_EnumFormat, filter); return -ENOTSUP; @@ -240,8 +245,10 @@ static int setup_convert(struct impl *this) make_link(this, this->nodes[i], 0, this->nodes[i+1], 0, NULL); for (i = 0, j = this->n_links - 1; j >= i; i++, j--) { + spa_log_debug(this->log, "negotiate %d", i); if ((res = negotiate_link_format(this, &this->links[i])) < 0) return res; + spa_log_debug(this->log, "negotiate %d", j); if ((res = negotiate_link_format(this, &this->links[j])) < 0) return res; } @@ -267,7 +274,8 @@ static int negotiate_link_buffers(struct impl *this, struct link *link) if ((res = spa_node_port_enum_params_sync(link->in_node, SPA_DIRECTION_INPUT, link->in_port, SPA_PARAM_Buffers, &state, - param, ¶m, &b)) != 1) { + param, ¶m, &b, + &this->pending)) != 1) { debug_params(this, link->out_node, SPA_DIRECTION_OUTPUT, link->out_port, SPA_PARAM_Buffers, param); return -ENOTSUP; @@ -276,7 +284,8 @@ static int negotiate_link_buffers(struct impl *this, struct link *link) if ((res = spa_node_port_enum_params_sync(link->out_node, SPA_DIRECTION_OUTPUT, link->out_port, SPA_PARAM_Buffers, &state, - param, ¶m, &b)) != 1) { + param, ¶m, &b, + &this->pending)) != 1) { debug_params(this, link->in_node, SPA_DIRECTION_INPUT, link->in_port, SPA_PARAM_Buffers, param); return -ENOTSUP; @@ -384,33 +393,34 @@ static int setup_buffers(struct impl *this, enum spa_direction direction) return 0; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { case SPA_PARAM_EnumProfile: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamProfile, id, @@ -426,10 +436,9 @@ static int impl_node_enum_params(struct spa_node *node, } break; case SPA_PARAM_Props: - switch (result.next) { + switch (result.index) { case 0: - return spa_node_enum_params(this->channelmix, - id, start, num, filter, func, data); + return spa_node_enum_params(this->channelmix, seq, id, start, num, filter); default: return 0; } @@ -438,12 +447,11 @@ static int impl_node_enum_params(struct spa_node *node, default: return -ENOENT; } - result.next++; if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -553,6 +561,16 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman return 0; } +static int on_node_result(void *data, int seq, int res, const void *result) +{ + struct impl *this = data; + int r; + r = spa_pending_queue_complete(&this->pending, seq, res, result); + if (r == 0) + r = this->callbacks->result(this->user_data, seq, res, result); + return r; +} + static void emit_port_info(struct impl *this, enum spa_direction direction, uint32_t port, const struct spa_port_info *info) @@ -577,7 +595,8 @@ static int fmt_input_port_info(void *data, static struct spa_node_callbacks fmt_input_callbacks = { SPA_VERSION_NODE_CALLBACKS, - .port_info = fmt_input_port_info + .port_info = fmt_input_port_info, + .result = on_node_result, }; static int fmt_output_port_info(void *data, @@ -595,7 +614,13 @@ static int fmt_output_port_info(void *data, static struct spa_node_callbacks fmt_output_callbacks = { SPA_VERSION_NODE_CALLBACKS, - .port_info = fmt_output_port_info + .port_info = fmt_output_port_info, + .result = on_node_result, +}; + +static struct spa_node_callbacks node_callbacks = { + SPA_VERSION_NODE_CALLBACKS, + .result = on_node_result, }; static int @@ -613,6 +638,8 @@ impl_node_set_callbacks(struct spa_node *node, this->user_data = user_data; spa_node_set_callbacks(this->fmt[SPA_DIRECTION_INPUT], &fmt_input_callbacks, this); + spa_node_set_callbacks(this->channelmix, &node_callbacks, this); + spa_node_set_callbacks(this->resample, &node_callbacks, this); spa_node_set_callbacks(this->fmt[SPA_DIRECTION_OUTPUT], &fmt_output_callbacks, this); return 0; @@ -643,34 +670,35 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3 } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { case SPA_PARAM_PropInfo: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, @@ -683,7 +711,7 @@ impl_node_port_enum_params(struct spa_node *node, break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -707,15 +735,15 @@ impl_node_port_enum_params(struct spa_node *node, } break; default: - return spa_node_port_enum_params(this->fmt[direction], direction, port_id, - id, start, num, filter, func, data); + return spa_node_port_enum_params(this->fmt[direction], seq, direction, port_id, + id, start, num, filter); } - result.next++; if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + spa_log_debug(this->log, "%p: %d callback %u", this, seq, count); + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -982,6 +1010,7 @@ impl_init(const struct spa_handle_factory *factory, this->log = support[i].data; } this->node = impl_node; + spa_pending_queue_init(&this->pending); if (info == NULL || (str = spa_dict_lookup(info, "factory.mode")) == NULL) str = "convert"; diff --git a/spa/plugins/audioconvert/channelmix.c b/spa/plugins/audioconvert/channelmix.c index 0584e9f53..b62bfa20e 100644 --- a/spa/plugins/audioconvert/channelmix.c +++ b/spa/plugins/audioconvert/channelmix.c @@ -431,28 +431,29 @@ static int setup_convert(struct impl *this, return make_matrix(this, src_chan, src_mask, dst_chan, dst_mask); } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -461,10 +462,10 @@ static int impl_node_enum_params(struct spa_node *node, uint32_t list[] = { SPA_PARAM_PropInfo, SPA_PARAM_Props }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; @@ -473,7 +474,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, @@ -497,7 +498,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, @@ -513,12 +514,10 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -671,35 +670,36 @@ static int port_enum_formats(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = GET_PORT(this, direction, port_id); other = GET_PORT(this, SPA_DIRECTION_REVERSE(direction), port_id); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -711,24 +711,24 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(node, direction, port_id, - result.next, ¶m, &b)) <= 0) + result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &port->format.info.raw); @@ -740,7 +740,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; if (other->n_buffers > 0) { @@ -767,7 +767,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!port->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -780,7 +780,7 @@ impl_node_port_enum_params(struct spa_node *node, break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -801,12 +801,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/audioconvert/fmtconvert.c b/spa/plugins/audioconvert/fmtconvert.c index 638614d65..0cb9d1cc4 100644 --- a/spa/plugins/audioconvert/fmtconvert.c +++ b/spa/plugins/audioconvert/fmtconvert.c @@ -187,10 +187,9 @@ static int setup_convert(struct impl *this) return 0; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { return -ENOTSUP; } @@ -357,24 +356,22 @@ static int port_enum_formats(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_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); @@ -383,9 +380,11 @@ 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.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -397,24 +396,24 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(node, direction, port_id, - result.next, ¶m, &b)) <= 0) + result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &port->format.info.raw); @@ -427,7 +426,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; if (other->n_buffers > 0) { @@ -455,7 +454,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!port->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -468,7 +467,7 @@ impl_node_port_enum_params(struct spa_node *node, break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -484,12 +483,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/audioconvert/merger.c b/spa/plugins/audioconvert/merger.c index abd403712..9860528f7 100644 --- a/spa/plugins/audioconvert/merger.c +++ b/spa/plugins/audioconvert/merger.c @@ -104,6 +104,8 @@ struct impl { float empty[MAX_SAMPLES + 15]; }; +#define emit_callback(this,name,...) this->callbacks->name(this->user_data, __VA_ARGS__) + #define CHECK_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < this->port_count) #define CHECK_OUT_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) <= this->monitor_count) #define CHECK_PORT(this,d,p) (CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p)) @@ -168,23 +170,28 @@ static int init_port(struct impl *this, enum spa_direction direction, uint32_t p return 0; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { + struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_params result; uint32_t count = 0; int res; spa_return_val_if_fail(node != NULL, -EINVAL); + spa_return_val_if_fail(num != 0, -EINVAL); + this = SPA_CONTAINER_OF(node, struct impl, node); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -192,10 +199,10 @@ static int impl_node_enum_params(struct spa_node *node, { uint32_t list[] = { SPA_PARAM_Profile }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; @@ -203,12 +210,11 @@ static int impl_node_enum_params(struct spa_node *node, default: return 0; } - result.next++; if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = emit_callback(this, result, seq, 0, &result)) != 0) return res; if (++count != num) @@ -400,36 +406,38 @@ static int port_enum_formats(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = GET_PORT(this, direction, port_id); + + spa_log_debug(this->log, "%p: enum params %d %u", this, seq, id); + + result.id = id; result.next = start; - next: - spa_pod_builder_init(&b, buffer, sizeof(buffer)); + result.index = result.next++; - spa_log_debug(this->log, NAME " %p: enum param %d %d", this, id, port->have_format); + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { case SPA_PARAM_List: @@ -440,22 +448,22 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO, }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: - if ((res = port_enum_formats(node, direction, port_id, result.next, ¶m, &b)) <= 0) + if ((res = port_enum_formats(node, direction, port_id, result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &port->format.info.raw); @@ -463,7 +471,7 @@ impl_node_port_enum_params(struct spa_node *node, case SPA_PARAM_Buffers: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -481,7 +489,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!port->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -493,7 +501,7 @@ impl_node_port_enum_params(struct spa_node *node, } break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -508,12 +516,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -655,7 +661,8 @@ static int port_set_format(struct spa_node *node, port->stride *= info.info.raw.channels; port->blocks = 1; } - spa_log_debug(this->log, NAME " %p: %d %d %d", this, port_id, port->stride, port->blocks); + spa_log_debug(this->log, NAME " %p: %d %d %d", this, + port_id, port->stride, port->blocks); if (!PORT_IS_DSP(direction, port_id)) setup_convert(this); diff --git a/spa/plugins/audioconvert/resample.c b/spa/plugins/audioconvert/resample.c index c88545660..6afd5ba9e 100644 --- a/spa/plugins/audioconvert/resample.c +++ b/spa/plugins/audioconvert/resample.c @@ -156,10 +156,9 @@ static int setup_convert(struct impl *this, return err; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { return -ENOTSUP; } @@ -317,35 +316,36 @@ static int port_enum_formats(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = GET_PORT(this, direction, port_id); other = GET_PORT(this, SPA_DIRECTION_REVERSE(direction), port_id); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -357,23 +357,23 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(node, direction, port_id, - result.next, ¶m, &b)) <= 0) + result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &port->format.info.raw); @@ -384,7 +384,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; if (other->n_buffers > 0) { @@ -412,7 +412,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!port->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -424,7 +424,7 @@ impl_node_port_enum_params(struct spa_node *node, } break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -445,12 +445,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/audioconvert/splitter.c b/spa/plugins/audioconvert/splitter.c index e8e478da0..5a4a3ffd4 100644 --- a/spa/plugins/audioconvert/splitter.c +++ b/spa/plugins/audioconvert/splitter.c @@ -164,25 +164,29 @@ static int init_port(struct impl *this, enum spa_direction direction, return 0; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { + struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -190,10 +194,10 @@ static int impl_node_enum_params(struct spa_node *node, { uint32_t list[] = { SPA_PARAM_Profile }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; @@ -201,12 +205,11 @@ static int impl_node_enum_params(struct spa_node *node, default: return 0; } - result.next++; if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -394,37 +397,38 @@ static int port_enum_formats(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = GET_PORT(this, direction, port_id); + spa_log_debug(this->log, "%p: enum params %d %u", this, seq, id); + + result.id = id; result.next = start; - next: - spa_pod_builder_init(&b, buffer, sizeof(buffer)); + result.index = result.next++; - spa_log_debug(this->log, NAME " %p: enum param %d", this, id); + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { case SPA_PARAM_List: @@ -435,23 +439,23 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(node, direction, port_id, - result.next, ¶m, &b)) <= 0) + result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &port->format.info.raw); @@ -459,7 +463,7 @@ impl_node_port_enum_params(struct spa_node *node, case SPA_PARAM_Buffers: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -478,7 +482,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!port->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -490,7 +494,7 @@ impl_node_port_enum_params(struct spa_node *node, } break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -505,12 +509,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/audiomixer/audiomixer.c b/spa/plugins/audiomixer/audiomixer.c index 64d36408e..30c7884b8 100644 --- a/spa/plugins/audiomixer/audiomixer.c +++ b/spa/plugins/audiomixer/audiomixer.c @@ -126,10 +126,9 @@ struct impl { #define GET_OUT_PORT(this,p) (&this->out_ports[p]) #define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p)) -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { return -ENOTSUP; } @@ -313,24 +312,22 @@ static int port_enum_formats(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_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); @@ -338,9 +335,11 @@ impl_node_port_enum_params(struct spa_node *node, port = GET_PORT(this, direction, port_id); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -352,23 +351,23 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO, }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(node, direction, port_id, - result.next, ¶m, &b)) <= 0) + result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &this->format.info.raw); @@ -376,7 +375,7 @@ impl_node_port_enum_params(struct spa_node *node, case SPA_PARAM_Buffers: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -394,7 +393,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!port->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -406,7 +405,7 @@ impl_node_port_enum_params(struct spa_node *node, } break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -433,12 +432,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index 6c9672bbb..4d36e828c 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -125,28 +125,29 @@ 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, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -155,10 +156,10 @@ static int impl_node_enum_params(struct spa_node *node, uint32_t list[] = { SPA_PARAM_PropInfo, SPA_PARAM_Props }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; @@ -168,7 +169,7 @@ static int impl_node_enum_params(struct spa_node *node, struct props *p = &this->props; struct spa_pod_frame f[2]; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, @@ -215,7 +216,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, @@ -233,12 +234,10 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -541,31 +540,32 @@ port_enum_formats(struct impl *this, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { struct impl *this; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; struct spa_pod *param; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -577,24 +577,24 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO, }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(this, direction, port_id, - result.next, ¶m, &b)) <= 0) + result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if (!this->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw); @@ -603,7 +603,7 @@ impl_node_port_enum_params(struct spa_node *node, case SPA_PARAM_Buffers: if (!this->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -621,7 +621,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!this->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -633,7 +633,7 @@ impl_node_port_enum_params(struct spa_node *node, } break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -660,12 +660,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/bluez5/a2dp-sink.c b/spa/plugins/bluez5/a2dp-sink.c index cb9b9bc8c..2ef970b3a 100644 --- a/spa/plugins/bluez5/a2dp-sink.c +++ b/spa/plugins/bluez5/a2dp-sink.c @@ -145,28 +145,29 @@ static void reset_props(struct props *props) props->max_latency = default_max_latency; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -175,10 +176,10 @@ static int impl_node_enum_params(struct spa_node *node, uint32_t list[] = { SPA_PARAM_PropInfo, SPA_PARAM_Props }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; @@ -187,7 +188,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, @@ -211,7 +212,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, @@ -227,12 +228,10 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -910,32 +909,33 @@ 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, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -946,16 +946,16 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Buffers, SPA_PARAM_Meta }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: - if (result.next > 0) + if (result.index > 0) return 0; switch (this->transport->codec) { @@ -1001,7 +1001,7 @@ impl_node_port_enum_params(struct spa_node *node, case SPA_PARAM_Format: if (!this->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw); @@ -1010,7 +1010,7 @@ impl_node_port_enum_params(struct spa_node *node, case SPA_PARAM_Buffers: if (!this->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -1029,7 +1029,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!this->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -1045,12 +1045,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/bluez5/bluez5-device.c b/spa/plugins/bluez5/bluez5-device.c index 98c5d4fd4..4cc450010 100644 --- a/spa/plugins/bluez5/bluez5-device.c +++ b/spa/plugins/bluez5/bluez5-device.c @@ -149,11 +149,9 @@ static int impl_set_callbacks(struct spa_device *device, } -static int impl_enum_params(struct spa_device *device, - uint32_t id, uint32_t *index, - const struct spa_pod *filter, - struct spa_pod **param, - struct spa_pod_builder *builder) +static int impl_enum_params(struct spa_device *device, int seq, + uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter) { return -ENOTSUP; } diff --git a/spa/plugins/ffmpeg/ffmpeg-dec.c b/spa/plugins/ffmpeg/ffmpeg-dec.c index c36d08365..f1f038380 100644 --- a/spa/plugins/ffmpeg/ffmpeg-dec.c +++ b/spa/plugins/ffmpeg/ffmpeg-dec.c @@ -72,10 +72,9 @@ struct impl { bool started; }; -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { return -ENOTSUP; } @@ -208,22 +207,24 @@ static int port_get_format(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { + struct impl *this = SPA_CONTAINER_OF(node, struct impl, node); struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; struct spa_pod *param; - struct spa_result_node_enum_params result; + struct spa_result_node_params result; uint32_t count = 0; int res; + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -232,23 +233,23 @@ impl_node_port_enum_params(struct spa_node *node, uint32_t list[] = { SPA_PARAM_EnumFormat, SPA_PARAM_Format }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + result.index, filter, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if ((res = port_get_format(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + result.index, filter, ¶m, &b)) <= 0) return res; break; @@ -256,12 +257,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/ffmpeg/ffmpeg-enc.c b/spa/plugins/ffmpeg/ffmpeg-enc.c index 90fafa76e..907491365 100644 --- a/spa/plugins/ffmpeg/ffmpeg-enc.c +++ b/spa/plugins/ffmpeg/ffmpeg-enc.c @@ -75,10 +75,9 @@ struct impl { bool started; }; -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { return -ENOTSUP; } @@ -162,20 +161,13 @@ 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, - const struct spa_pod *filter, - struct spa_pod **param, - struct spa_pod_builder *builder) + 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) { - switch (index) { - case 0: - *param = NULL; - break; - default: - return 0; - } - return 1; + return -ENOTSUP; } static int port_get_format(struct spa_node *node, @@ -202,22 +194,26 @@ static int port_get_format(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { + struct impl *this; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; struct spa_pod *param; - struct spa_result_node_enum_params result; + struct spa_result_node_params result; uint32_t count = 0; int res; - result.next = start; + this = SPA_CONTAINER_OF(node, struct impl, node); + result.id = id; + result.next = start; next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -226,23 +222,23 @@ impl_node_port_enum_params(struct spa_node *node, uint32_t list[] = { SPA_PARAM_EnumFormat, SPA_PARAM_Format }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + result.index, filter, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if ((res = port_get_format(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + result.index, filter, ¶m, &b)) <= 0) return res; break; @@ -250,12 +246,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/test/fakesink.c b/spa/plugins/test/fakesink.c index 381206cdb..2a2d1e737 100644 --- a/spa/plugins/test/fakesink.c +++ b/spa/plugins/test/fakesink.c @@ -97,33 +97,34 @@ static void reset_props(struct impl *this, struct props *props) props->live = DEFAULT_LIVE; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct impl *this; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; struct spa_pod *param; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { case SPA_PARAM_List: - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -131,7 +132,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 (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -142,12 +143,10 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -377,14 +376,14 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3 return -ENOTSUP; } -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) +static int port_enum_formats(struct spa_node *node, int seq, + 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) { - return 0; + return -ENOTSUP; } static int port_get_format(struct spa_node *node, @@ -408,28 +407,31 @@ static int port_get_format(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { + struct impl *this; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; struct spa_pod *param; - struct spa_result_node_enum_params result; + struct spa_result_node_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); spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -440,26 +442,26 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Buffers, SPA_PARAM_Meta }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: - if ((res = port_enum_formats(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + if ((res = port_enum_formats(node, seq, direction, port_id, + result.index, filter, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if ((res = port_get_format(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + result.index, filter, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Buffers: - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -471,7 +473,7 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_BUFFERS_align, SPA_POD_Int(16)); break; case SPA_PARAM_Meta: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -486,12 +488,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/test/fakesrc.c b/spa/plugins/test/fakesrc.c index af126fd19..b43061c71 100644 --- a/spa/plugins/test/fakesrc.c +++ b/spa/plugins/test/fakesrc.c @@ -101,33 +101,34 @@ static void reset_props(struct impl *this, struct props *props) props->pattern = DEFAULT_PATTERN; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct impl *this; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; struct spa_pod *param; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { case SPA_PARAM_List: - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -139,7 +140,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -152,12 +153,10 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -422,28 +421,32 @@ static int port_get_format(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { + struct impl *this; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; struct spa_pod *param; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(node, direction, port_id), -EINVAL); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -454,26 +457,26 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Buffers, SPA_PARAM_Meta }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + result.index, filter, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if ((res = port_get_format(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + result.index, filter, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Buffers: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamBuffers, id, @@ -488,7 +491,7 @@ impl_node_port_enum_params(struct spa_node *node, } break; case SPA_PARAM_Meta: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -503,12 +506,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/v4l2/v4l2-device.c b/spa/plugins/v4l2/v4l2-device.c index 28d88437e..d4037e238 100644 --- a/spa/plugins/v4l2/v4l2-device.c +++ b/spa/plugins/v4l2/v4l2-device.c @@ -135,11 +135,9 @@ static int impl_set_callbacks(struct spa_device *device, return res; } -static int impl_enum_params(struct spa_device *device, - uint32_t id, uint32_t *index, - const struct spa_pod *filter, - struct spa_pod **param, - struct spa_pod_builder *builder) +static int impl_enum_params(struct spa_device *device, int seq, + uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter) { return -ENOTSUP; } diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c index 79bfe4e76..e76477b0f 100644 --- a/spa/plugins/v4l2/v4l2-source.c +++ b/spa/plugins/v4l2/v4l2-source.c @@ -146,34 +146,29 @@ struct impl { #include "v4l2-utils.c" -static int impl_node_wait(struct spa_node *node, int seq, struct spa_pending *pending, - spa_pending_func_t func, void *data) -{ - return -ENOTSUP; -} - -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -182,10 +177,10 @@ static int impl_node_enum_params(struct spa_node *node, uint32_t list[] = { SPA_PARAM_PropInfo, SPA_PARAM_Props }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; @@ -194,7 +189,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, @@ -225,7 +220,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, @@ -242,12 +237,10 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -453,12 +446,11 @@ static int port_get_format(struct spa_node *node, return 1; } -static int impl_node_port_enum_params(struct spa_node *node, +static int impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { struct impl *this; @@ -466,23 +458,25 @@ 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; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = GET_PORT(this, direction, port_id); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -495,29 +489,29 @@ static int impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_PropInfo: - return spa_v4l2_enum_controls(this, start, num, filter, func, data); + return spa_v4l2_enum_controls(this, seq, start, num, filter); case SPA_PARAM_EnumFormat: - return spa_v4l2_enum_format(this, start, num, filter, func, data); + return spa_v4l2_enum_format(this, seq, start, num, filter); case SPA_PARAM_Format: if((res = port_get_format(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + result.index, filter, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Buffers: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -530,7 +524,7 @@ static int impl_node_port_enum_params(struct spa_node *node, break; case SPA_PARAM_Meta: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -542,7 +536,7 @@ static int impl_node_port_enum_params(struct spa_node *node, } break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -569,12 +563,10 @@ static int impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -907,7 +899,6 @@ 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, diff --git a/spa/plugins/v4l2/v4l2-utils.c b/spa/plugins/v4l2/v4l2-utils.c index 6c6f22999..81f72f36b 100644 --- a/spa/plugins/v4l2/v4l2-utils.c +++ b/spa/plugins/v4l2/v4l2-utils.c @@ -520,10 +520,9 @@ filter_framerate(struct v4l2_frmivalenum *frmival, #define FOURCC_ARGS(f) (f)&0x7f,((f)>>8)&0x7f,((f)>>16)&0x7f,((f)>>24)&0x7f static int -spa_v4l2_enum_format(struct impl *this, +spa_v4l2_enum_format(struct impl *this, int seq, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct port *port = &this->out_ports[0]; int res, n_fractions; @@ -534,7 +533,7 @@ spa_v4l2_enum_format(struct impl *this, uint8_t buffer[1024]; struct spa_pod_builder b = { 0 }; struct spa_pod_frame f[2]; - struct spa_result_node_enum_params result; + struct spa_result_node_params result; uint32_t count = 0; if ((res = spa_v4l2_open(dev, this->props.device)) < 0) @@ -564,6 +563,8 @@ spa_v4l2_enum_format(struct impl *this, } next: + result.index = result.next++; + while (port->next_fmtdesc) { if (filter) { video_format = enum_filter_format(filter_media_type, @@ -810,9 +811,8 @@ spa_v4l2_enum_format(struct impl *this, spa_pod_builder_pop(&b, &f[1]); result.param = spa_pod_builder_pop(&b, &f[0]); - result.next++; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) goto exit; if (++count != num) @@ -1005,10 +1005,9 @@ static uint32_t control_to_prop_id(struct impl *impl, uint32_t control_id) } static int -spa_v4l2_enum_controls(struct impl *this, +spa_v4l2_enum_controls(struct impl *this, int seq, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct port *port = &this->out_ports[0]; struct spa_v4l2_device *dev = &port->dev; @@ -1020,15 +1019,16 @@ 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; + struct spa_result_node_params result; uint32_t count = 0; if ((res = spa_v4l2_open(dev, this->props.device)) < 0) return res; result.next = start; - next: + result.index = result.next; + spa_zero(queryctrl); if (result.next == 0) { @@ -1142,7 +1142,7 @@ spa_v4l2_enum_controls(struct impl *this, if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) goto exit; if (++count != num) diff --git a/spa/plugins/videotestsrc/videotestsrc.c b/spa/plugins/videotestsrc/videotestsrc.c index a939c2ddc..f4c47727d 100644 --- a/spa/plugins/videotestsrc/videotestsrc.c +++ b/spa/plugins/videotestsrc/videotestsrc.c @@ -110,28 +110,29 @@ 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, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct impl *this; struct spa_pod *param; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -140,10 +141,10 @@ static int impl_node_enum_params(struct spa_node *node, uint32_t list[] = { SPA_PARAM_PropInfo, SPA_PARAM_Props }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; @@ -153,7 +154,7 @@ static int impl_node_enum_params(struct spa_node *node, struct props *p = &this->props; struct spa_pod_frame f[2]; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, @@ -186,7 +187,7 @@ static int impl_node_enum_params(struct spa_node *node, { struct props *p = &this->props; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, @@ -202,12 +203,10 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -490,31 +489,32 @@ static int port_enum_formats(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { struct impl *this; struct spa_pod_builder b = { 0 }; uint8_t buffer[1024]; struct spa_pod *param; - struct spa_result_node_enum_params result; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -525,24 +525,24 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Buffers, SPA_PARAM_Meta }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + result.index, filter, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if (!this->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_video_raw_build(&b, id, &this->current_format.info.raw); @@ -554,7 +554,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!this->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -570,7 +570,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!this->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -586,12 +586,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/plugins/volume/volume.c b/spa/plugins/volume/volume.c index 84ae5c866..6f1dc4a9b 100644 --- a/spa/plugins/volume/volume.c +++ b/spa/plugins/volume/volume.c @@ -102,30 +102,31 @@ struct impl { #define GET_OUT_PORT(this,p) (&this->out_ports[p]) #define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p)) -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { 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; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); p = &this->props; + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -134,16 +135,16 @@ static int impl_node_enum_params(struct spa_node *node, uint32_t list[] = { SPA_PARAM_PropInfo, SPA_PARAM_Props }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_PropInfo: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_PropInfo, id, @@ -163,7 +164,7 @@ static int impl_node_enum_params(struct spa_node *node, } break; case SPA_PARAM_Props: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_Props, id, @@ -178,12 +179,10 @@ static int impl_node_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -318,32 +317,35 @@ static int port_enum_formats(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = GET_PORT(this, direction, port_id); + result.id = id; + result.next = start; next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -355,24 +357,24 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: if ((res = port_enum_formats(node, direction, port_id, - result.next, filter, ¶m, &b)) <= 0) + result.index, filter, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &this->current_format.info.raw); @@ -381,7 +383,7 @@ impl_node_port_enum_params(struct spa_node *node, case SPA_PARAM_Buffers: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -396,7 +398,7 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_BUFFERS_align, SPA_POD_Int(16)); break; case SPA_PARAM_Meta: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -408,7 +410,7 @@ impl_node_port_enum_params(struct spa_node *node, } break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -429,12 +431,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/spa/tools/spa-inspect.c b/spa/tools/spa-inspect.c index 7dc7aace3..7d7fa26ce 100644 --- a/spa/tools/spa-inspect.c +++ b/spa/tools/spa-inspect.c @@ -49,6 +49,7 @@ struct data { struct spa_log *log; struct spa_loop loop; struct spa_node *node; + struct spa_pending_queue pending; }; static void @@ -66,7 +67,8 @@ inspect_node_params(struct data *data, struct spa_node *node) spa_pod_builder_init(&b, buffer, sizeof(buffer)); if ((res = spa_node_enum_params_sync(node, SPA_PARAM_List, &idx1, - NULL, ¶m, &b)) != 1) { + NULL, ¶m, &b, + &data->pending)) != 1) { if (res != 0) error(0, -res, "enum_params"); break; @@ -81,7 +83,8 @@ inspect_node_params(struct data *data, struct spa_node *node) spa_pod_builder_init(&b, buffer, sizeof(buffer)); if ((res = spa_node_enum_params_sync(node, id, &idx2, - NULL, ¶m, &b)) != 1) { + NULL, ¶m, &b, + &data->pending)) != 1) { if (res != 0) error(0, -res, "enum_params %d", id); break; @@ -108,7 +111,8 @@ inspect_port_params(struct data *data, struct spa_node *node, if ((res = spa_node_port_enum_params_sync(node, direction, port_id, SPA_PARAM_List, &idx1, - NULL, ¶m, &b)) != 1) { + NULL, ¶m, &b, + &data->pending)) != 1) { if (res != 0) error(0, -res, "port_enum_params"); break; @@ -123,7 +127,8 @@ inspect_port_params(struct data *data, struct spa_node *node, if ((res = spa_node_port_enum_params_sync(node, direction, port_id, id, &idx2, - NULL, ¶m, &b)) != 1) { + NULL, ¶m, &b, + &data->pending)) != 1) { if (res != 0) error(0, -res, "port_enum_params"); break; @@ -169,11 +174,18 @@ static int node_port_info(void *_data, enum spa_direction direction, uint32_t id return 0; } +static int node_result(void *_data, int seq, int res, const void *result) +{ + struct data *data = _data; + return spa_pending_queue_complete(&data->pending, seq, res, result); +} + static const struct spa_node_callbacks node_callbacks = { SPA_VERSION_NODE_CALLBACKS, .info = node_info, .port_info = node_port_info, + .result = node_result, }; static void inspect_node(struct data *data, struct spa_node *node) @@ -281,6 +293,8 @@ int main(int argc, char *argv[]) data.support[2] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DataLoop, &data.loop); data.n_support = 3; + spa_pending_queue_init(&data.pending); + if ((handle = dlopen(argv[1], RTLD_NOW)) == NULL) { printf("can't load %s\n", argv[1]); return -1; diff --git a/src/examples/export-sink.c b/src/examples/export-sink.c index 53b06c249..0455d7400 100644 --- a/src/examples/export-sink.c +++ b/src/examples/export-sink.c @@ -180,23 +180,24 @@ static int impl_port_set_io(struct spa_node *node, return 0; } -static int impl_port_enum_params(struct spa_node *node, +static int impl_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_params result; uint32_t count = 0; int res; + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -208,10 +209,10 @@ static int impl_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; @@ -220,7 +221,7 @@ static int impl_port_enum_params(struct spa_node *node, { SDL_RendererInfo info; - if (result.next != 0) + if (result.index != 0) return 0; SDL_GetRendererInfo(d->renderer, &info); @@ -228,13 +229,13 @@ static int impl_port_enum_params(struct spa_node *node, break; } case SPA_PARAM_Format: - if (result.next != 0 || d->format.format == 0) + if (result.index != 0 || d->format.format == 0) return 0; param = spa_format_video_raw_build(&b, id, &d->format); break; case SPA_PARAM_Buffers: - if (result.next != 0) + if (result.index != 0) return 0; param = spa_pod_builder_add_object(&b, @@ -247,7 +248,7 @@ static int impl_port_enum_params(struct spa_node *node, break; case SPA_PARAM_Meta: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -266,7 +267,7 @@ static int impl_port_enum_params(struct spa_node *node, break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -286,12 +287,11 @@ static int impl_port_enum_params(struct spa_node *node, default: return -ENOENT; } - result.next++; if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = d->callbacks->result(d->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/src/examples/export-source.c b/src/examples/export-source.c index 08465d4a0..9e10c9919 100644 --- a/src/examples/export-source.c +++ b/src/examples/export-source.c @@ -148,23 +148,24 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction, return 0; } -static int impl_port_enum_params(struct spa_node *node, +static int impl_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_params result; uint32_t count = 0; int res; + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -176,16 +177,16 @@ static int impl_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: - if (result.next != 0) + if (result.index != 0) return 0; param = spa_pod_builder_add_object(&b, @@ -203,7 +204,7 @@ static int impl_port_enum_params(struct spa_node *node, break; case SPA_PARAM_Format: - if (result.next != 0) + if (result.index != 0) return 0; if (d->format.format == 0) return 0; @@ -211,7 +212,7 @@ static int impl_port_enum_params(struct spa_node *node, break; case SPA_PARAM_Buffers: - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -224,7 +225,7 @@ static int impl_port_enum_params(struct spa_node *node, break; case SPA_PARAM_Meta: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -236,7 +237,7 @@ static int impl_port_enum_params(struct spa_node *node, } break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -257,12 +258,10 @@ static int impl_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = d->callbacks->result(d->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/src/examples/local-v4l2.c b/src/examples/local-v4l2.c index 538c13a69..66b370970 100644 --- a/src/examples/local-v4l2.c +++ b/src/examples/local-v4l2.c @@ -122,23 +122,24 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction, return 0; } -static int impl_port_enum_params(struct spa_node *node, +static int impl_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_params result; uint32_t count = 0; int res; + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -146,7 +147,7 @@ static int impl_port_enum_params(struct spa_node *node, { SDL_RendererInfo info; - if (result.next > 0) + if (result.index > 0) return 0; SDL_GetRendererInfo(d->renderer, &info); @@ -154,7 +155,7 @@ static int impl_port_enum_params(struct spa_node *node, break; } case SPA_PARAM_Buffers: - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -167,7 +168,7 @@ static int impl_port_enum_params(struct spa_node *node, break; case SPA_PARAM_Meta: - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -180,12 +181,10 @@ static int impl_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = d->callbacks->result(d->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/src/examples/media-session.c b/src/examples/media-session.c index 8937cf005..4b4b48313 100644 --- a/src/examples/media-session.c +++ b/src/examples/media-session.c @@ -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) - impl->seq = pw_core_proxy_sync(impl->core_proxy, 0); + impl->seq = pw_core_proxy_sync(impl->core_proxy, 0, impl->seq); } static void remove_idle_timeout(struct session *sess) @@ -367,7 +367,7 @@ static int node_event_info(void *object, const struct pw_node_info *info) return 0; } -static int node_event_param(void *object, +static int node_event_param(void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { @@ -588,7 +588,7 @@ static int port_event_info(void *object, const struct pw_port_info *info) return 0; } -static int port_event_param(void *object, +static int port_event_param(void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { @@ -1171,11 +1171,16 @@ static int rescan_node(struct impl *impl, struct node *node) if (!exclusive && session->dsp) { do_link_profile: audio_info = peer->profile_format; + if (direction == PW_DIRECTION_INPUT) audio_info.channels = SPA_MIN(peer->format.channels, node->format.channels); else audio_info.channels = SPA_MAX(peer->format.channels, node->format.channels); + pw_log_debug(NAME" %p: channels: %d %d -> %d", impl, + peer->format.channels, node->format.channels, + audio_info.channels); + node->profile_format = audio_info; spa_pod_builder_init(&b, buf, sizeof(buf)); diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index f43bda41c..2da5d9b0f 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -280,7 +280,7 @@ static void add_pending(GstPipeWireDeviceProvider *self, struct pending *p, p->callback = callback; p->data = data; pw_log_debug("add pending %d", p->seq); - self->seq = p->seq = pw_core_proxy_sync(self->core_proxy, 0); + self->seq = p->seq = pw_core_proxy_sync(self->core_proxy, 0, self->seq); } static void remove_pending(struct pending *p) @@ -379,8 +379,8 @@ static int port_event_info(void *data, const struct pw_port_info *info) return 0; } -static int port_event_param(void *data, uint32_t id, uint32_t index, uint32_t next, - const struct spa_pod *param) +static int port_event_param(void *data, uint32_t seq, uint32_t id, + uint32_t index, uint32_t next, const struct spa_pod *param) { struct port_data *port_data = data; struct node_data *node_data = port_data->node_data; @@ -589,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, ®istry_events, data); - self->seq = pw_core_proxy_sync(self->core_proxy, 0); + pw_core_proxy_sync(self->core_proxy, 0, self->seq++); for (;;) { if (pw_remote_get_state(r, NULL) <= 0) @@ -678,7 +678,7 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider) data->registry = self->registry; pw_registry_proxy_add_listener(self->registry, &data->registry_listener, ®istry_events, data); - self->seq = pw_core_proxy_sync(self->core_proxy, 0); + pw_core_proxy_sync(self->core_proxy, 0, self->seq++); for (;;) { if (self->end) diff --git a/src/modules/module-audio-dsp/floatmix.c b/src/modules/module-audio-dsp/floatmix.c index b57c5d9ec..9b0b3fdeb 100644 --- a/src/modules/module-audio-dsp/floatmix.c +++ b/src/modules/module-audio-dsp/floatmix.c @@ -121,10 +121,9 @@ struct impl { #define GET_OUT_PORT(this,p) (&this->out_ports[p]) #define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p)) -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { return -ENOTSUP; } @@ -301,34 +300,35 @@ static int port_enum_formats(struct spa_node *node, } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_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); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = GET_PORT(this, direction, port_id); + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -340,23 +340,23 @@ impl_node_port_enum_params(struct spa_node *node, SPA_PARAM_Meta, SPA_PARAM_IO }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_EnumFormat: - if ((res = port_enum_formats(node, direction, port_id, result.next, ¶m, &b)) <= 0) + if ((res = port_enum_formats(node, direction, port_id, result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_format_audio_raw_build(&b, id, &this->format.info.raw); @@ -365,7 +365,7 @@ impl_node_port_enum_params(struct spa_node *node, case SPA_PARAM_Buffers: if (!port->have_format) return -EIO; - if (result.next > 0) + if (result.index > 0) return 0; param = spa_pod_builder_add_object(&b, @@ -384,7 +384,7 @@ impl_node_port_enum_params(struct spa_node *node, if (!port->have_format) return -EIO; - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamMeta, id, @@ -397,7 +397,7 @@ impl_node_port_enum_params(struct spa_node *node, break; case SPA_PARAM_IO: - switch (result.next) { + switch (result.index) { case 0: param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamIO, id, @@ -424,12 +424,10 @@ impl_node_port_enum_params(struct spa_node *node, return -ENOENT; } - result.next++; - if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->user_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 7748c1a9c..8e6e38711 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -354,33 +354,34 @@ static void mix_clear(struct node *this, struct mix *mix) mix->valid = false; } -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { struct node *this; uint8_t buffer[1024]; struct spa_pod_builder b = { 0 }; - struct spa_result_node_enum_params result; + struct spa_result_node_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 node, node); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); + result.id = id; result.next = start; while (true) { struct spa_pod *param; - if (result.next >= this->n_params) + result.index = result.next++; + if (result.index >= this->n_params) return 0; - param = this->params[result.next++]; + param = this->params[result.index]; if (param == NULL || !spa_pod_is_object_id(param, id)) continue; @@ -389,7 +390,7 @@ static int impl_node_enum_params(struct spa_node *node, if (spa_pod_filter(&b, &result.param, param, filter) != 0) continue; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -490,8 +491,8 @@ impl_node_set_callbacks(struct spa_node *node, void *data) { struct node *this; - int res = 0; uint32_t i; + int res = 0; spa_return_val_if_fail(node != NULL, -EINVAL); @@ -510,13 +511,13 @@ impl_node_set_callbacks(struct spa_node *node, emit_port_info(this, this->out_ports[i]); } if (callbacks && this->resource) - res = pw_resource_sync(this->resource); + res = pw_resource_sync(this->resource, 0); return res; } static int -impl_node_sync(struct spa_node *node) +impl_node_sync(struct spa_node *node, int seq) { struct node *this; spa_return_val_if_fail(node != NULL, -EINVAL); @@ -524,35 +525,7 @@ impl_node_sync(struct spa_node *node) 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_pending_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; + return pw_resource_sync(this->resource, seq); } static void @@ -661,42 +634,43 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3 } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { struct node *this; struct port *port; uint8_t buffer[1024]; struct spa_pod_builder b = { 0 }; - struct spa_result_node_enum_params result; + struct spa_result_node_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 node, node); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); port = GET_PORT(this, direction, port_id); - pw_log_debug("client-node %p: port %d.%d", this, - direction, port_id); + pw_log_debug("client-node %p: %d port %d.%d %u %u %u", this, seq, + direction, port_id, id, start, num); + result.id = id; result.next = start; while (true) { struct spa_pod *param; - if (result.next >= port->n_params) + result.index = result.next++; + if (result.index >= port->n_params) return 0; - param = port->params[result.next++]; + param = port->params[result.index]; if (param == NULL || !spa_pod_is_object_id(param, id)) continue; @@ -705,7 +679,8 @@ impl_node_port_enum_params(struct spa_node *node, if (spa_pod_filter(&b, &result.param, param, filter) < 0) continue; - if ((res = func(data, count, &result)) != 0) + pw_log_debug("client-node %p: %d param %u", this, seq, result.index); + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -1136,7 +1111,6 @@ 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, @@ -1250,21 +1224,9 @@ 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; - uint32_t count = 0; - spa_list_for_each_safe(p, t, &this->pending_list, link) { - if (p->seq == (int) seq) { - pw_log_debug("client-node %p: do callback %d", this, p->res); - spa_list_remove(&p->link); - p->seq = p->res; - p->res = 0; - p->func(p, NULL); - count++; - } - } - if (count == 0) - pw_log_warn("client-node %p: unhandled done %d", this, seq); + pw_log_debug("client-node %p: emit result %d", this, seq); + this->callbacks->result(this->callbacks_data, seq, 0, NULL); } void pw_client_node_registered(struct pw_client_node *this, uint32_t node_id) @@ -1395,15 +1357,14 @@ static const struct pw_port_implementation port_impl = { }; static int -impl_mix_port_enum_params(struct spa_node *node, +impl_mix_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { struct port *port = SPA_CONTAINER_OF(node, struct port, mix_node); - return impl_node_port_enum_params(&port->node->node, direction, port->id, - id, start, num, filter, func, data); + return impl_node_port_enum_params(&port->node->node, seq, direction, port->id, + id, start, num, filter); } static int diff --git a/src/modules/module-client-node/client-stream.c b/src/modules/module-client-node/client-stream.c index 5075ff020..fb8c7a6c1 100644 --- a/src/modules/module-client-node/client-stream.c +++ b/src/modules/module-client-node/client-stream.c @@ -103,34 +103,37 @@ struct impl { struct spa_buffer **buffers; uint32_t n_buffers; struct pw_memblock *mem; + + struct spa_pending client_node_pending; }; /** \endcond */ -static int impl_node_enum_params(struct spa_node *node, +static int impl_node_enum_params(struct spa_node *node, int seq, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter, - spa_result_func_t func, void *data) + const struct spa_pod *filter) { 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; + struct spa_result_node_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 node, node); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); impl = this->impl; + result.id = id; result.next = start; - next: + result.index = result.next++; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); switch (id) { @@ -140,37 +143,41 @@ static int impl_node_enum_params(struct spa_node *node, SPA_PARAM_EnumFormat, SPA_PARAM_Format }; - if (result.next < SPA_N_ELEMENTS(list)) + if (result.index < SPA_N_ELEMENTS(list)) param = spa_pod_builder_add_object(&b, SPA_TYPE_OBJECT_ParamList, id, - SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next])); + SPA_PARAM_LIST_id, SPA_POD_Id(list[result.index])); else return 0; break; } case SPA_PARAM_Props: - if (impl->adapter != impl->cnode) { - return spa_node_enum_params(impl->adapter, - id, start, num, filter, func, data); - } - return 0; + if (impl->adapter == impl->cnode) + return 0; + + if ((res = spa_node_enum_params_sync(impl->adapter, + id, &start, filter, ¶m, &b, + impl->this.node->pending)) != 1) + return res; + break; case SPA_PARAM_EnumFormat: case SPA_PARAM_Format: - return spa_node_port_enum_params(impl->cnode, + if ((res = spa_node_port_enum_params_sync(impl->cnode, impl->direction, 0, - id, start, num, - filter, func, data); + id, &start, filter, ¶m, &b, + impl->client_node->node->pending)) != 1) + return res; + break; default: return -ENOENT; } - result.next++; if (spa_pod_filter(&b, &result.param, param, filter) < 0) goto next; - if ((res = func(data, count, &result)) != 0) + if ((res = this->callbacks->result(this->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) @@ -306,10 +313,17 @@ static int adapter_port_info(void *data, } return 0; } +static int adapter_result(void *data, int seq, int res, const void *result) +{ + struct impl *impl = data; + struct node *this = &impl->node; + return this->callbacks->result(this->callbacks_data, seq, res, result); +} static const struct spa_node_callbacks adapter_node_callbacks = { SPA_VERSION_NODE_CALLBACKS, .port_info = adapter_port_info, + .result = adapter_result, }; static int @@ -331,11 +345,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 spa_node_sync(impl->cnode); + return spa_node_sync(impl->cnode, 0); } static int -impl_node_sync(struct spa_node *node) +impl_node_sync(struct spa_node *node, int seq) { struct node *this; struct impl *impl; @@ -345,22 +359,7 @@ impl_node_sync(struct spa_node *node) this = SPA_CONTAINER_OF(node, struct node, node); impl = this->impl; - return spa_node_sync(impl->cnode); -} - -static int -impl_node_wait(struct spa_node *node, int seq, struct spa_pending *pending, - spa_pending_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); + return spa_node_sync(impl->cnode, seq); } static int @@ -410,27 +409,28 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3 } static int -impl_node_port_enum_params(struct spa_node *node, +impl_node_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { struct node *this; struct impl *impl; 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 node, node); + spa_return_val_if_fail(this->callbacks && this->callbacks->result, -EIO); impl = this->impl; if (direction != impl->direction) return -EINVAL; - return spa_node_port_enum_params(impl->adapter, direction, port_id, id, - start, num, filter, func, data); + pw_log_debug("%p: %d %u", this, seq, id); + + return spa_node_port_enum_params(impl->adapter, seq, direction, port_id, id, + start, num, filter); } static int debug_params(struct impl *impl, struct spa_node *node, @@ -451,7 +451,8 @@ static int debug_params(struct impl *impl, struct spa_node *node, res = spa_node_port_enum_params_sync(node, direction, port_id, id, &state, - NULL, ¶m, &b); + NULL, ¶m, &b, + impl->this.node->pending); if (res != 1) { if (res < 0) spa_log_error(this->log, " error: %s", spa_strerror(res)); @@ -486,7 +487,8 @@ static int negotiate_format(struct impl *impl) SPA_DIRECTION_REVERSE(impl->direction), impl->adapter_mix_port, SPA_PARAM_EnumFormat, &state, - NULL, &format, &b)) != 1) { + NULL, &format, &b, + impl->this.node->pending)) != 1) { debug_params(impl, impl->adapter_mix, SPA_DIRECTION_REVERSE(impl->direction), impl->adapter_mix_port, @@ -496,9 +498,10 @@ static int negotiate_format(struct impl *impl) state = 0; if ((res = spa_node_port_enum_params_sync(impl->cnode, - impl->direction, 0, - SPA_PARAM_EnumFormat, &state, - format, &format, &b)) != 1) { + impl->direction, 0, + SPA_PARAM_EnumFormat, &state, + format, &format, &b, + impl->client_node->node->pending)) != 1) { debug_params(impl, impl->cnode, impl->direction, 0, SPA_PARAM_EnumFormat, format); return -ENOTSUP; @@ -547,10 +550,11 @@ static int negotiate_buffers(struct impl *impl) state = 0; 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, ¶m, &b)) < 0) { + SPA_DIRECTION_REVERSE(impl->direction), + impl->adapter_mix_port, + SPA_PARAM_Buffers, &state, + param, ¶m, &b, + impl->this.node->pending)) != 1) { debug_params(impl, impl->adapter_mix, SPA_DIRECTION_REVERSE(impl->direction), impl->adapter_mix_port, @@ -562,9 +566,10 @@ static int negotiate_buffers(struct impl *impl) state = 0; if ((res = spa_node_port_enum_params_sync(impl->cnode, - impl->direction, 0, - SPA_PARAM_Buffers, &state, - param, ¶m, &b)) < 0) { + impl->direction, 0, + SPA_PARAM_Buffers, &state, + param, ¶m, &b, + impl->client_node->node->pending)) < 0) { debug_params(impl, impl->cnode, impl->direction, 0, SPA_PARAM_Buffers, param); return res; @@ -855,7 +860,6 @@ 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, @@ -980,7 +984,8 @@ static void client_node_initialized(void *data) if ((res = spa_node_port_enum_params_sync(impl->cnode, impl->direction, 0, SPA_PARAM_EnumFormat, &state, - NULL, &format, &b)) != 1) { + NULL, &format, &b, + impl->client_node->node->pending)) != 1) { pw_log_warn("client-stream %p: no format given", &impl->this); impl->adapter = impl->cnode; impl->adapter_mix = impl->client_port->mix; @@ -1098,6 +1103,14 @@ static void client_node_destroy(void *data) cleanup(impl); } +static void client_node_result(void *data, int seq, int res, const void *result) +{ + struct impl *impl = data; + struct node *node = &impl->node; + pw_log_debug("client-stream %p: result %d %d", &impl->this, seq, res); + node->callbacks->result(node->callbacks_data, seq, res, result); +} + static void client_node_active_changed(void *data, bool active) { struct impl *impl = data; @@ -1106,7 +1119,7 @@ static void client_node_active_changed(void *data, bool active) impl->active = active; } -static void client_node_info_changed (void *data, const struct pw_node_info *info) +static void client_node_info_changed(void *data, const struct pw_node_info *info) { struct impl *impl = data; struct pw_client_stream *this = &impl->this; @@ -1120,6 +1133,7 @@ static const struct pw_node_events client_node_events = { PW_VERSION_NODE_EVENTS, .destroy = client_node_destroy, .initialized = client_node_initialized, + .result = client_node_result, .active_changed = client_node_active_changed, .info_changed = client_node_info_changed, }; @@ -1145,13 +1159,13 @@ static void node_initialized(void *data) static void node_peer_added(void *data, struct pw_node *peer) { struct impl *impl = data; - pw_node_events_peer_added(impl->client_node->node, peer); + pw_node_emit_peer_added(impl->client_node->node, peer); } static void node_peer_removed(void *data, struct pw_node *peer) { struct impl *impl = data; - pw_node_events_peer_removed(impl->client_node->node, peer); + pw_node_emit_peer_removed(impl->client_node->node, peer); } static void node_driver_changed(void *data, struct pw_node *old, struct pw_node *driver) @@ -1159,7 +1173,7 @@ static void node_driver_changed(void *data, struct pw_node *old, struct pw_node struct impl *impl = data; pw_log_debug("client-stream %p: driver changed %p->%p", &impl->this, old, driver); impl->client_node->node->driver_node = driver; - pw_node_events_driver_changed(impl->client_node->node, old, driver); + pw_node_emit_driver_changed(impl->client_node->node, old, driver); } static const struct pw_node_events node_events = { diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index 5a56244a6..d57cb0db8 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -415,9 +415,10 @@ static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_ spa_pod_builder_init(&b, buf, sizeof(buf)); if (spa_node_port_enum_params_sync(port->node->node, - port->direction, port->port_id, - SPA_PARAM_List, &idx1, - NULL, ¶m, &b) != 1) + port->direction, port->port_id, + SPA_PARAM_List, &idx1, + NULL, ¶m, &b, + port->node->pending) != 1) break; spa_pod_parse_object(param, @@ -430,9 +431,10 @@ static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_ for (idx2 = 0;;) { spa_pod_builder_init(&b, buf, sizeof(buf)); if (spa_node_port_enum_params_sync(port->node->node, - port->direction, port->port_id, - id, &idx2, - NULL, ¶m, &b) != 1) + port->direction, port->port_id, + id, &idx2, + NULL, ¶m, &b, + port->node->pending) != 1) break; params = realloc(params, sizeof(struct spa_pod *) * (n_params + 1)); diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index de68ce6a3..bb6d61cf4 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -127,8 +127,9 @@ process_messages(struct client_data *data) const struct pw_protocol_native_demarshal *demarshal; const struct pw_protocol_marshal *marshal; uint32_t permissions, required; + int seq; - if (!pw_protocol_native_connection_get_next(conn, &opcode, &id, &message, &size)) + if (!pw_protocol_native_connection_get_next(conn, &opcode, &id, &message, &size, &seq)) break; pw_log_trace("protocol-native %p: got message %d from %u", client->protocol, @@ -147,6 +148,7 @@ process_messages(struct client_data *data) -EINVAL, "unknown resource %u", id); continue; } + resource->seq = seq; marshal = pw_resource_get_marshal(resource); if (marshal == NULL || opcode >= marshal->n_methods) @@ -478,17 +480,20 @@ on_remote_data(void *data, int fd, enum spa_io mask) uint8_t opcode; uint32_t id, size; void *message; + int seq; while (!impl->disconnecting - && pw_protocol_native_connection_get_next(conn, &opcode, &id, &message, &size)) { + && pw_protocol_native_connection_get_next(conn, + &opcode, &id, &message, &size, &seq)) { struct pw_proxy *proxy; const struct pw_protocol_native_demarshal *demarshal; const struct pw_protocol_marshal *marshal; - pw_log_trace("protocol-native %p: got message %d from %u", this, opcode, id); + pw_log_trace("protocol-native %p: got message %d from %u seq:%d", + this, opcode, id, seq); if (debug_messages) { - fprintf(stderr, "<<<<<<<<< in: %d %d %d\n", id, opcode, size); + fprintf(stderr, "<<<<<<<<< in: %d %d %d %d\n", id, opcode, size, seq); spa_debug_pod(0, NULL, (struct spa_pod *)message); } @@ -498,6 +503,7 @@ on_remote_data(void *data, int fd, enum spa_io mask) pw_log_error("protocol-native %p: could not find proxy %u", this, id); continue; } + proxy->seq = seq; marshal = pw_proxy_get_marshal(proxy); if (marshal == NULL || opcode >= marshal->n_events) { diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c index 549c8e01c..8ea64976e 100644 --- a/src/modules/module-protocol-native/connection.c +++ b/src/modules/module-protocol-native/connection.c @@ -41,6 +41,8 @@ #define MAX_FDS 1024 #define MAX_FDS_MSG 28 +#define HDR_SIZE 16 + static bool debug_messages = 0; struct buffer { @@ -277,7 +279,8 @@ pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *con uint8_t *opcode, uint32_t *dest_id, void **dt, - uint32_t *sz) + uint32_t *sz, + int *seq) { struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this); size_t len, size; @@ -310,19 +313,20 @@ pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *con data += buf->offset; size -= buf->offset; - if (size < 8) { - if (connection_ensure_size(conn, buf, 8) == NULL) + if (size < HDR_SIZE) { + if (connection_ensure_size(conn, buf, HDR_SIZE) == NULL) return false; buf->update = true; goto again; } p = (uint32_t *) data; - data += 8; - size -= 8; + data += HDR_SIZE; + size -= HDR_SIZE; *dest_id = p[0]; *opcode = p[1] >> 24; len = p[1] & 0xffffff; + *seq = p[2]; if (len > size) { if (connection_ensure_size(conn, buf, len) == NULL) @@ -332,7 +336,7 @@ pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *con } buf->size = len; buf->data = data; - buf->offset += 8; + buf->offset += HDR_SIZE; *dt = buf->data; *sz = buf->size; @@ -345,11 +349,11 @@ static inline void *begin_write(struct pw_protocol_native_connection *conn, uint struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this); uint32_t *p; struct buffer *buf = &impl->out; - /* 4 for dest_id, 1 for opcode, 3 for size and size for payload */ - if ((p = connection_ensure_size(conn, buf, 8 + size)) == NULL) + /* header and size for payload */ + if ((p = connection_ensure_size(conn, buf, HDR_SIZE + size)) == NULL) return NULL; - return p + 2; + return SPA_MEMBER(p, HDR_SIZE, void); } static int builder_overflow(void *callbacks_data, uint32_t size) @@ -392,20 +396,21 @@ pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn, struct buffer *buf = &impl->out; uint32_t seq; - if ((p = connection_ensure_size(conn, buf, 8 + size)) == NULL) + if ((p = connection_ensure_size(conn, buf, HDR_SIZE + size)) == NULL) return -ENOMEM; seq = impl->seq; impl->seq = (impl->seq + 1) & SPA_ASYNC_SEQ_MASK; - *p++ = impl->dest_id; - *p++ = (impl->opcode << 24) | (size & 0xffffff); + p[0] = impl->dest_id; + p[1] = (impl->opcode << 24) | (size & 0xffffff); + p[2] = seq; - buf->buffer_size += 8 + size; + buf->buffer_size += HDR_SIZE + size; if (debug_messages) { fprintf(stderr, ">>>>>>>>> out: %d %d %d\n", impl->dest_id, impl->opcode, size); - spa_debug_pod(0, NULL, (struct spa_pod *)p); + spa_debug_pod(0, NULL, SPA_MEMBER(p, HDR_SIZE, struct spa_pod)); } spa_hook_list_call(&conn->listener_list, diff --git a/src/modules/module-protocol-native/connection.h b/src/modules/module-protocol-native/connection.h index 7ff0566e2..14cfd1d76 100644 --- a/src/modules/module-protocol-native/connection.h +++ b/src/modules/module-protocol-native/connection.h @@ -75,7 +75,7 @@ bool pw_protocol_native_connection_get_next(struct pw_protocol_native_connection *conn, uint8_t *opcode, uint32_t *dest_id, - void **data, uint32_t *size); + void **data, uint32_t *size, int *seq); uint32_t pw_protocol_native_connection_add_fd(struct pw_protocol_native_connection *conn, int fd); diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index eac6d6c7f..16d122030 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -646,7 +646,7 @@ static int device_demarshal_info(void *object, void *data, size_t size) return pw_proxy_notify(proxy, struct pw_device_proxy_events, info, 0, &info); } -static int device_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next, +static int device_marshal_param(void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { struct pw_resource *resource = object; @@ -655,6 +655,7 @@ static int device_marshal_param(void *object, uint32_t id, uint32_t index, uint3 b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_PARAM, NULL); spa_pod_builder_add_struct(b, + SPA_POD_Int(seq), SPA_POD_Id(id), SPA_POD_Int(index), SPA_POD_Int(next), @@ -667,29 +668,33 @@ static int device_demarshal_param(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; - uint32_t id, index, next; + uint32_t seq, id, index, next; struct spa_pod *param; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&seq), SPA_POD_Id(&id), SPA_POD_Int(&index), SPA_POD_Int(&next), SPA_POD_Pod(¶m)) < 0) return -EINVAL; - return pw_proxy_notify(proxy, struct pw_device_proxy_events, param, 0, id, index, next, param); + return pw_proxy_notify(proxy, struct pw_device_proxy_events, param, 0, + seq, id, index, next, param); } -static int device_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, - const struct spa_pod *filter) +static int device_marshal_enum_params(void *object, uint32_t seq, + uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; + int res; - b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_ENUM_PARAMS, NULL); + b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_ENUM_PARAMS, &res); spa_pod_builder_add_struct(b, + SPA_POD_Int(res), SPA_POD_Id(id), SPA_POD_Int(index), SPA_POD_Int(num), @@ -702,18 +707,20 @@ static int device_demarshal_enum_params(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_pod_parser prs; - uint32_t id, index, num; + uint32_t id, index, num, seq; struct spa_pod *filter; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&seq), SPA_POD_Id(&id), SPA_POD_Int(&index), SPA_POD_Int(&num), SPA_POD_Pod(&filter)) < 0) return -EINVAL; - return pw_resource_do(resource, struct pw_device_proxy_methods, enum_params, 0, id, index, num, filter); + return pw_resource_do(resource, struct pw_device_proxy_methods, enum_params, 0, + seq, id, index, num, filter); } static int device_marshal_set_param(void *object, uint32_t id, uint32_t flags, @@ -870,8 +877,8 @@ static int node_demarshal_info(void *object, void *data, size_t size) return pw_proxy_notify(proxy, struct pw_node_proxy_events, info, 0, &info); } -static int node_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next, - const struct spa_pod *param) +static int node_marshal_param(void *object, uint32_t seq, uint32_t id, + uint32_t index, uint32_t next, const struct spa_pod *param) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -879,6 +886,7 @@ static int node_marshal_param(void *object, uint32_t id, uint32_t index, uint32_ b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_PARAM, NULL); spa_pod_builder_add_struct(b, + SPA_POD_Int(seq), SPA_POD_Id(id), SPA_POD_Int(index), SPA_POD_Int(next), @@ -891,29 +899,33 @@ static int node_demarshal_param(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; - uint32_t id, index, next; + uint32_t seq, id, index, next; struct spa_pod *param; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&seq), SPA_POD_Id(&id), SPA_POD_Int(&index), SPA_POD_Int(&next), SPA_POD_Pod(¶m)) < 0) return -EINVAL; - return pw_proxy_notify(proxy, struct pw_node_proxy_events, param, 0, id, index, next, param); + return pw_proxy_notify(proxy, struct pw_node_proxy_events, param, 0, + seq, id, index, next, param); } -static int node_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, - const struct spa_pod *filter) +static int node_marshal_enum_params(void *object, uint32_t seq, uint32_t id, + uint32_t index, uint32_t num, const struct spa_pod *filter) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; + int res; - b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_ENUM_PARAMS, NULL); + b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_ENUM_PARAMS, &res); spa_pod_builder_add_struct(b, + SPA_POD_Int(res), SPA_POD_Id(id), SPA_POD_Int(index), SPA_POD_Int(num), @@ -926,18 +938,20 @@ static int node_demarshal_enum_params(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_pod_parser prs; - uint32_t id, index, num; + uint32_t seq, id, index, num; struct spa_pod *filter; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&seq), SPA_POD_Id(&id), SPA_POD_Int(&index), SPA_POD_Int(&num), SPA_POD_Pod(&filter)) < 0) return -EINVAL; - return pw_resource_do(resource, struct pw_node_proxy_methods, enum_params, 0, id, index, num, filter); + return pw_resource_do(resource, struct pw_node_proxy_methods, enum_params, 0, + seq, id, index, num, filter); } static int node_marshal_set_param(void *object, uint32_t id, uint32_t flags, @@ -1050,8 +1064,8 @@ static int port_demarshal_info(void *object, void *data, size_t size) return pw_proxy_notify(proxy, struct pw_port_proxy_events, info, 0, &info); } -static int port_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next, - const struct spa_pod *param) +static int port_marshal_param(void *object, uint32_t seq, uint32_t id, + uint32_t index, uint32_t next, const struct spa_pod *param) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -1059,6 +1073,7 @@ static int port_marshal_param(void *object, uint32_t id, uint32_t index, uint32_ b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_PARAM, NULL); spa_pod_builder_add_struct(b, + SPA_POD_Int(seq), SPA_POD_Id(id), SPA_POD_Int(index), SPA_POD_Int(next), @@ -1071,29 +1086,33 @@ static int port_demarshal_param(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; - uint32_t id, index, next; + uint32_t seq, id, index, next; struct spa_pod *param; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&seq), SPA_POD_Id(&id), SPA_POD_Int(&index), SPA_POD_Int(&next), SPA_POD_Pod(¶m)) < 0) return -EINVAL; - return pw_proxy_notify(proxy, struct pw_port_proxy_events, param, 0, id, index, next, param); + return pw_proxy_notify(proxy, struct pw_port_proxy_events, param, 0, + seq, id, index, next, param); } -static int port_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, - const struct spa_pod *filter) +static int port_marshal_enum_params(void *object, uint32_t seq, uint32_t id, + uint32_t index, uint32_t num, const struct spa_pod *filter) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; + int res; - b = pw_protocol_native_begin_proxy(proxy, PW_PORT_PROXY_METHOD_ENUM_PARAMS, NULL); + b = pw_protocol_native_begin_proxy(proxy, PW_PORT_PROXY_METHOD_ENUM_PARAMS, &res); spa_pod_builder_add_struct(b, + SPA_POD_Int(res), SPA_POD_Id(id), SPA_POD_Int(index), SPA_POD_Int(num), @@ -1106,18 +1125,20 @@ static int port_demarshal_enum_params(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_pod_parser prs; - uint32_t id, index, num; + uint32_t seq, id, index, num; struct spa_pod *filter; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&seq), SPA_POD_Id(&id), SPA_POD_Int(&index), SPA_POD_Int(&num), SPA_POD_Pod(&filter)) < 0) return -EINVAL; - return pw_resource_do(resource, struct pw_port_proxy_methods, enum_params, 0, id, index, num, filter); + return pw_resource_do(resource, struct pw_port_proxy_methods, enum_params, 0, + seq, id, index, num, filter); } static int client_marshal_info(void *object, const struct pw_client_info *info) diff --git a/src/modules/spa/spa-node.c b/src/modules/spa/spa-node.c index 9540f3df9..3a66233a3 100644 --- a/src/modules/spa/spa-node.c +++ b/src/modules/spa/spa-node.c @@ -57,14 +57,14 @@ struct impl { char *factory_name; struct spa_hook node_listener; - struct spa_pending init_pending; + int init_pending; void *user_data; int async_init:1; }; -static void pw_spa_node_free(void *data) +static void spa_node_free(void *data) { struct impl *impl = data; struct pw_node *node = impl->this; @@ -82,10 +82,11 @@ static void pw_spa_node_free(void *data) dlclose(impl->hnd); } -static int complete_init(struct impl *impl) +static void complete_init(struct impl *impl) { struct pw_node *this = impl->this; + impl->init_pending = SPA_ID_INVALID; if (SPA_FLAG_CHECK(impl->flags, PW_SPA_NODE_FLAG_DISABLE)) pw_node_set_enabled(this, false); @@ -96,20 +97,23 @@ static int complete_init(struct impl *impl) pw_node_register(this, impl->owner, impl->parent, NULL); else pw_node_initialized(this); - return 0; } -static int on_init_done(struct spa_pending *pending, const void *result) +static void spa_node_result(void *data, int seq, int res, const void *result) { - struct impl *impl = pending->data; - struct pw_node *this = impl->this; - pw_log_debug("spa-node %p: init complete event %d %d", this, pending->seq, pending->res); - return complete_init(impl); + struct impl *impl = data; + struct pw_node *node = impl->this; + + if (seq == impl->init_pending) { + pw_log_debug("spa-node %p: init complete event %d %d", node, seq, res); + complete_init(impl); + } } static const struct pw_node_events node_events = { PW_VERSION_NODE_EVENTS, - .free = pw_spa_node_free, + .free = spa_node_free, + .result = spa_node_result, }; struct pw_node * @@ -148,7 +152,7 @@ pw_spa_node_new(struct pw_core *core, goto clean_node; if (SPA_RESULT_IS_ASYNC(res)) { - spa_node_wait(impl->node, res, &impl->init_pending, on_init_done, impl); + impl->init_pending = spa_node_sync(impl->node, res); } else { complete_init(impl); } @@ -166,6 +170,17 @@ void *pw_spa_node_get_user_data(struct pw_node *node) return impl->user_data; } +static int on_node_result(void *data, int seq, int res, const void *result) +{ + struct spa_pending_queue *pending = data; + return spa_pending_queue_complete(pending, seq, res, result); +} + +static const struct spa_node_callbacks node_callbacks = { + SPA_VERSION_NODE_CALLBACKS, + .result = on_node_result, +}; + static int setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_properties *pw_props) { @@ -177,10 +192,17 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie uint8_t buf[2048]; struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf)); const struct spa_pod_prop *prop = NULL; + struct spa_pending_queue pending; + + spa_pending_queue_init(&pending); + + spa_node_set_callbacks(spa_node, &node_callbacks, &pending); 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); + SPA_PARAM_Props, &index, NULL, &props, + &b, &pending)) != 1) { + if (res < 0) + pw_log_debug("spa_node_get_props failed: %d", res); return res; } diff --git a/src/pipewire/core.c b/src/pipewire/core.c index 0d8511525..db4ce9b91 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -835,7 +835,8 @@ int pw_core_find_format(struct pw_core *core, if ((res = spa_node_port_enum_params_sync(output->node->node, output->direction, output->port_id, SPA_PARAM_Format, &oidx, - NULL, format, builder)) != 1) { + NULL, format, builder, + output->node->pending)) != 1) { if (res == 0) res = -EBADF; asprintf(error, "error get output format: %s", spa_strerror(res)); @@ -849,7 +850,8 @@ int pw_core_find_format(struct pw_core *core, if ((res = spa_node_port_enum_params_sync(input->node->node, input->direction, input->port_id, SPA_PARAM_Format, &iidx, - NULL, format, builder)) != 1) { + NULL, format, builder, + input->node->pending)) != 1) { if (res == 0) res = -EBADF; asprintf(error, "error get input format: %s", spa_strerror(res)); @@ -869,7 +871,8 @@ int pw_core_find_format(struct pw_core *core, if ((res = spa_node_port_enum_params_sync(input->node->node, input->direction, input->port_id, SPA_PARAM_EnumFormat, &iidx, - NULL, &filter, &fb)) != 1) { + NULL, &filter, &fb, + input->node->pending)) != 1) { if (res == 0 && iidx == 0) { asprintf(error, "error input enum formats: %s", spa_strerror(res)); goto error; @@ -884,7 +887,8 @@ int pw_core_find_format(struct pw_core *core, if ((res = spa_node_port_enum_params_sync(output->node->node, output->direction, output->port_id, SPA_PARAM_EnumFormat, &oidx, - filter, format, builder)) != 1) { + filter, format, builder, + output->node->pending)) != 1) { if (res == 0) { oidx = 0; goto again; diff --git a/src/pipewire/device.c b/src/pipewire/device.c index 48b83965c..2727f8f95 100644 --- a/src/pipewire/device.c +++ b/src/pipewire/device.c @@ -25,15 +25,24 @@ #include #include +#include #include "pipewire/device.h" #include "pipewire/private.h" #include "pipewire/interfaces.h" #include "pipewire/type.h" +struct impl { + struct pw_device this; + + struct spa_pending_queue pending; +}; + struct resource_data { struct spa_hook resource_listener; struct pw_device *device; + struct pw_resource *resource; + uint32_t seq; }; struct node_data { @@ -50,12 +59,17 @@ struct pw_device *pw_device_new(struct pw_core *core, struct pw_properties *properties, size_t user_data_size) { + struct impl *impl; struct pw_device *this; - this = calloc(1, sizeof(*this) + user_data_size); - if (this == NULL) + impl = calloc(1, sizeof(struct impl) + user_data_size); + if (impl == NULL) return NULL; + spa_pending_queue_init(&impl->pending); + + this = &impl->this; + if (properties == NULL) properties = pw_properties_new(NULL, NULL); if (properties == NULL) @@ -71,14 +85,14 @@ struct pw_device *pw_device_new(struct pw_core *core, spa_list_init(&this->node_list); if (user_data_size > 0) - this->user_data = SPA_MEMBER(this, sizeof(*this), void); + this->user_data = SPA_MEMBER(this, sizeof(struct impl), void); pw_log_debug("device %p: new %s", this, name); return this; no_mem: - free(this); + free(impl); return NULL; } @@ -127,6 +141,7 @@ int pw_device_for_each_param(struct pw_device *device, struct spa_pod *param), void *data) { + struct impl *impl = SPA_CONTAINER_OF(device, struct impl, this); int res = 0; uint32_t idx, count; uint8_t buf[4096]; @@ -140,9 +155,10 @@ int pw_device_for_each_param(struct pw_device *device, spa_pod_builder_init(&b, buf, sizeof(buf)); idx = index; - if ((res = spa_device_enum_params(device->implementation, + if ((res = spa_device_enum_params_sync(device->implementation, param_id, &index, - filter, ¶m, &b)) <= 0) + filter, ¶m, &b, + &impl->pending)) != 1) break; if ((res = callback(data, param_id, idx, index, param)) != 0) @@ -153,21 +169,22 @@ int pw_device_for_each_param(struct pw_device *device, 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_device_resource_param(resource, id, index, next, param); + struct resource_data *d = data; + pw_device_resource_param(d->resource, d->seq, id, index, next, param); return 0; } -static int device_enum_params(void *object, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter) +static int device_enum_params(void *object, uint32_t seq, uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter) { - struct pw_resource *resource = object; - struct resource_data *data = pw_resource_get_user_data(resource); + struct resource_data *data = object; + struct pw_resource *resource = data->resource; struct pw_device *device = data->device; int res; + data->seq = seq; if ((res = pw_device_for_each_param(device, id, start, num, - filter, reply_param, resource)) < 0) + filter, reply_param, data)) < 0) pw_core_resource_error(resource->client->core_resource, resource->id, res, spa_strerror(res)); return res; @@ -176,8 +193,8 @@ static int device_enum_params(void *object, uint32_t id, uint32_t start, uint32_ static int device_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) { - struct pw_resource *resource = object; - struct resource_data *data = pw_resource_get_user_data(resource); + struct resource_data *data = object; + struct pw_resource *resource = data->resource; struct pw_device *device = data->device; int res; @@ -208,9 +225,10 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions, data = pw_resource_get_user_data(resource); data->device = this; + data->resource = resource; pw_resource_add_listener(resource, &data->resource_listener, &resource_events, resource); - pw_resource_set_implementation(resource, &device_methods, resource); + pw_resource_set_implementation(resource, &device_methods, data); pw_log_debug("device %p: bound to %d", this, resource->id); @@ -396,11 +414,18 @@ static int device_object_info(void *data, uint32_t id, return 0; } +static int device_result(void *data, int seq, int res, const void *result) +{ + struct pw_device *device = data; + struct impl *impl = SPA_CONTAINER_OF(device, struct impl, this); + return spa_pending_queue_complete(&impl->pending, seq, res, result); +} static const struct spa_device_callbacks device_callbacks = { SPA_VERSION_DEVICE_CALLBACKS, .info = device_info, .object_info = device_object_info, + .result = device_result, }; SPA_EXPORT diff --git a/src/pipewire/interfaces.h b/src/pipewire/interfaces.h index 6a5f66645..c7eaccf83 100644 --- a/src/pipewire/interfaces.h +++ b/src/pipewire/interfaces.h @@ -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) +pw_core_proxy_sync(struct pw_core_proxy *core, uint32_t id, uint32_t seq) { - return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, sync, id, 0); + return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, sync, id, seq); } static inline int @@ -189,13 +189,16 @@ pw_core_proxy_done(struct pw_core_proxy *core, uint32_t id, uint32_t seq) } static inline int -pw_core_proxy_error(struct pw_core_proxy *core, uint32_t id, int res, const char *message) +pw_core_proxy_error(struct pw_core_proxy *core, uint32_t id, + int res, const char *message) { - return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, error, id, res, message); + return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, error, + id, res, message); } static inline int -pw_core_proxy_errorv(struct pw_core_proxy *core, uint32_t id, int res, const char *message, va_list args) +pw_core_proxy_errorv(struct pw_core_proxy *core, uint32_t id, + int res, const char *message, va_list args) { char buffer[1024]; vsnprintf(buffer, sizeof(buffer), message, args); @@ -204,7 +207,8 @@ pw_core_proxy_errorv(struct pw_core_proxy *core, uint32_t id, int res, const cha } static inline int -pw_core_proxy_errorf(struct pw_core_proxy *core, uint32_t id, int res, const char *message, ...) +pw_core_proxy_errorf(struct pw_core_proxy *core, uint32_t id, + int res, const char *message, ...) { va_list args; int r; @@ -326,7 +330,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,id) pw_resource_notify(r,struct pw_core_proxy_events,sync,id,0) +#define pw_core_resource_sync(r,...) pw_resource_notify(r,struct pw_core_proxy_events,sync,__VA_ARGS__) #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__) @@ -535,12 +539,13 @@ struct pw_device_proxy_methods { * Start enumeration of device parameters. For each param, a * param event will be emited. * + * \param seq a sequence number to place in the reply * \param id the parameter id to enum or SPA_ID_INVALID for all * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL */ - int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, + int (*enum_params) (void *object, uint32_t seq, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter); /** * Set a parameter on the device @@ -558,7 +563,7 @@ pw_device_proxy_enum_params(struct pw_device_proxy *device, uint32_t id, uint32_ uint32_t num, const struct spa_pod *filter) { return pw_proxy_do((struct pw_proxy*)device, struct pw_device_proxy_methods, enum_params, - id, index, num, filter); + 0, id, index, num, filter); } static inline int @@ -588,12 +593,13 @@ struct pw_device_proxy_events { * * Event emited as a result of the enum_params method. * + * \param seq the sequence number of the request * \param id the param id * \param index the param index * \param next the param index of the next param * \param param the parameter */ - int (*param) (void *object, + int (*param) (void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); }; @@ -627,12 +633,14 @@ struct pw_node_proxy_methods { * Start enumeration of node parameters. For each param, a * param event will be emited. * + * \param seq a sequence number to place in the reply * \param id the parameter id to enum or SPA_ID_INVALID for all * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL */ - int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, + int (*enum_params) (void *object, uint32_t seq, uint32_t id, + uint32_t start, uint32_t num, const struct spa_pod *filter); /** @@ -659,7 +667,7 @@ pw_node_proxy_enum_params(struct pw_node_proxy *node, uint32_t id, uint32_t inde uint32_t num, const struct spa_pod *filter) { return pw_proxy_do((struct pw_proxy*)node, struct pw_node_proxy_methods, enum_params, - id, index, num, filter); + 0, id, index, num, filter); } static inline int @@ -696,12 +704,13 @@ struct pw_node_proxy_events { * * Event emited as a result of the enum_params method. * + * \param seq the sequence number of the request * \param id the param id * \param index the param index * \param next the param index of the next param * \param param the parameter */ - int (*param) (void *object, + int (*param) (void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); }; @@ -734,12 +743,14 @@ struct pw_port_proxy_methods { * Start enumeration of port parameters. For each param, a * param event will be emited. * + * \param seq a sequence number returned in the reply * \param id the parameter id to enumerate * \param start the start index or 0 for the first param * \param num the maximum number of params to retrieve * \param filter a param filter or NULL */ - int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, + int (*enum_params) (void *object, uint32_t seq, + uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter); }; @@ -749,7 +760,7 @@ pw_port_proxy_enum_params(struct pw_port_proxy *port, uint32_t id, uint32_t inde uint32_t num, const struct spa_pod *filter) { return pw_proxy_do((struct pw_proxy*)port, struct pw_port_proxy_methods, enum_params, - id, index, num, filter); + 0, id, index, num, filter); } #define PW_PORT_PROXY_EVENT_INFO 0 @@ -771,12 +782,13 @@ struct pw_port_proxy_events { * * Event emited as a result of the enum_params method. * + * \param seq the sequence number of the request * \param id the param id * \param index the param index * \param next the param index of the next param * \param param the parameter */ - int (*param) (void *object, + int (*param) (void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); }; diff --git a/src/pipewire/link.c b/src/pipewire/link.c index 2ee7269f3..941c6cae3 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -69,9 +69,6 @@ struct impl { struct spa_io_buffers io; struct pw_node *inode, *onode; - - struct spa_pending input_pending; - struct spa_pending output_pending; }; struct resource_data { @@ -153,32 +150,6 @@ static void pw_link_update_state(struct pw_link *link, enum pw_link_state state, } } -static int complete_output(struct spa_pending *pending, const void *result) -{ - struct pw_link *this = pending->data; - struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); - struct pw_node *node = this->output->node; - uint32_t seq = SPA_RESULT_ASYNC_SEQ(pending->seq); - int res = pending->res; - pw_log_debug("link %p: node %p async complete %d %d", impl, node, seq, res); - pending->res = 0; - pw_work_queue_complete(impl->work, node, seq, res); - return 0; -} - -static int complete_input(struct spa_pending *pending, const void *result) -{ - struct pw_link *this = pending->data; - struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); - struct pw_node *node = this->input->node; - uint32_t seq = SPA_RESULT_ASYNC_SEQ(pending->seq); - int res = pending->res; - pw_log_debug("link %p: node %p async complete %d %d", impl, node, seq, res); - pending->res = 0; - 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; @@ -211,16 +182,6 @@ static void complete_paused(void *obj, void *data, int res, uint32_t id) } } -static struct spa_pending *prepare_pending(struct impl *impl, struct spa_pending *pending) -{ - if (pending->res != 0) { - pw_log_warn("link %p: remove pending %d", impl, pending->res); - spa_list_remove(&pending->link); - pending->res = 0; - } - 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); @@ -238,7 +199,7 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st in_mix_state = this->rt.in_mix.state; out_mix_state = this->rt.out_mix.state; - pw_log_debug("%d %d", in_mix_state, out_mix_state); + pw_log_debug("in_state:%d out_state:%d", in_mix_state, out_mix_state); if (in_mix_state != PW_PORT_STATE_CONFIGURE && out_mix_state != PW_PORT_STATE_CONFIGURE) return 0; @@ -262,9 +223,10 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st if (out_state > PW_PORT_STATE_CONFIGURE && output->node->info.state == PW_NODE_STATE_IDLE) { index = 0; res = spa_node_port_enum_params_sync(output->node->node, - output->direction, output->port_id, - SPA_PARAM_Format, &index, - NULL, ¤t, &b); + output->direction, output->port_id, + SPA_PARAM_Format, &index, + NULL, ¤t, &b, + output->node->pending); switch (res) { case -EIO: current = NULL; @@ -297,9 +259,10 @@ 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_sync(input->node->node, - input->direction, input->port_id, - SPA_PARAM_Format, &index, - NULL, ¤t, &b); + input->direction, input->port_id, + SPA_PARAM_Format, &index, + NULL, ¤t, &b, + input->node->pending); switch (res) { case -EIO: current = NULL; @@ -339,12 +302,9 @@ 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_wait(output->node->node, res, - prepare_pending(impl, &impl->output_pending), - complete_output, - this); + res = spa_node_sync(output->node->node, res), pw_work_queue_add(impl->work, output->node, res, complete_ready, - &this->rt.out_mix); + &this->rt.out_mix); } } if (in_mix_state == PW_PORT_STATE_CONFIGURE) { @@ -357,13 +317,9 @@ 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_wait(input->node->node, res2, - prepare_pending(impl, &impl->input_pending), - complete_input, - this); - + res2 = spa_node_sync(input->node->node, res2), pw_work_queue_add(impl->work, input->node, res2, complete_ready, - &this->rt.in_mix); + &this->rt.in_mix); if (res == 0) res = res2; } @@ -501,8 +457,9 @@ param_filter(struct pw_link *this, spa_pod_builder_init(&ib, ibuf, sizeof(ibuf)); pw_log_debug("iparam %d", iidx); 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) + in_port->direction, in_port->port_id, + id, &iidx, NULL, &iparam, &ib, + in_port->node->pending)) < 0) break; if (res != 1) { @@ -516,9 +473,10 @@ param_filter(struct pw_link *this, for (oidx = 0;;) { pw_log_debug("oparam %d", oidx); - if (spa_node_port_enum_params_sync(out_port->node->node, out_port->direction, - out_port->port_id, id, &oidx, - iparam, &oparam, result) != 1) { + if (spa_node_port_enum_params_sync(out_port->node->node, + out_port->direction, out_port->port_id, + id, &oidx, iparam, &oparam, result, + out_port->node->pending) != 1) { break; } @@ -719,20 +677,17 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s if (out_flags & SPA_PORT_FLAG_CAN_ALLOC_BUFFERS) { if ((res = pw_port_alloc_buffers(output, - this->rt.out_mix.port.port_id, - params, n_params, - allocation.buffers, - &allocation.n_buffers)) < 0) { + this->rt.out_mix.port.port_id, + params, n_params, + allocation.buffers, + &allocation.n_buffers)) < 0) { asprintf(&error, "error alloc output buffers: %d", res); goto error; } if (SPA_RESULT_IS_ASYNC(res)) { - spa_node_wait(output->node->node, res, - prepare_pending(impl, &impl->output_pending), - complete_output, - this); + res = spa_node_sync(output->node->node, res), pw_work_queue_add(impl->work, output->node, res, complete_paused, - &this->rt.out_mix); + &this->rt.out_mix); } out_flags &= ~SPA_PORT_FLAG_CAN_USE_BUFFERS; @@ -742,20 +697,17 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s allocation.n_buffers, allocation.buffers); } else if (in_flags & SPA_PORT_FLAG_CAN_ALLOC_BUFFERS) { if ((res = pw_port_alloc_buffers(input, - this->rt.in_mix.port.port_id, - params, n_params, - allocation.buffers, - &allocation.n_buffers)) < 0) { + this->rt.in_mix.port.port_id, + params, n_params, + allocation.buffers, + &allocation.n_buffers)) < 0) { asprintf(&error, "error alloc input buffers: %d", res); goto error; } if (SPA_RESULT_IS_ASYNC(res)) { - spa_node_wait(input->node->node, res, - prepare_pending(impl, &impl->input_pending), - complete_input, - this); + res = spa_node_sync(input->node->node, res), pw_work_queue_add(impl->work, input->node, res, complete_paused, - &this->rt.in_mix); + &this->rt.in_mix); } in_flags &= ~SPA_PORT_FLAG_CAN_USE_BUFFERS; @@ -776,12 +728,9 @@ 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_wait(output->node->node, res, - prepare_pending(impl, &impl->output_pending), - complete_output, - this); + res = spa_node_sync(output->node->node, res), pw_work_queue_add(impl->work, output->node, res, complete_paused, - &this->rt.out_mix); + &this->rt.out_mix); } move_allocation(&allocation, &output->allocation); @@ -791,20 +740,17 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s pw_log_debug("link %p: using %d buffers %p on input port", this, allocation.n_buffers, allocation.buffers); if ((res = pw_port_use_buffers(input, - this->rt.in_mix.port.port_id, - allocation.buffers, - allocation.n_buffers)) < 0) { + this->rt.in_mix.port.port_id, + allocation.buffers, + allocation.n_buffers)) < 0) { asprintf(&error, "link %p: error use input buffers: %s", this, spa_strerror(res)); goto error; } if (SPA_RESULT_IS_ASYNC(res)) { - spa_node_wait(input->node->node, res, - prepare_pending(impl, &impl->input_pending), - complete_input, - this); + res = spa_node_sync(input->node->node, res), pw_work_queue_add(impl->work, input->node, res, complete_paused, - &this->rt.in_mix); + &this->rt.in_mix); } } else { @@ -959,8 +905,6 @@ static void input_remove(struct pw_link *this, struct pw_port *port) spa_hook_remove(&impl->input_port_listener); spa_hook_remove(&impl->input_node_listener); - prepare_pending(impl, &impl->input_pending); - spa_list_remove(&this->input_link); pw_port_events_link_removed(this->input, this); @@ -980,8 +924,6 @@ static void output_remove(struct pw_link *this, struct pw_port *port) spa_hook_remove(&impl->output_port_listener); spa_hook_remove(&impl->output_node_listener); - prepare_pending(impl, &impl->output_pending); - spa_list_remove(&this->output_link); pw_port_events_link_removed(this->output, this); @@ -1167,14 +1109,30 @@ static const struct pw_port_events output_port_events = { .destroy = output_port_destroy, }; +static void input_node_result(void *data, int seq, int res, const void *result) +{ + struct impl *impl = data; + struct pw_node *node = impl->this.input->node; + pw_log_debug("link %p: input node %p result %d %d", impl, node, seq, res); + pw_work_queue_complete(impl->work, node, SPA_RESULT_ASYNC_SEQ(seq), res); +} + +static void output_node_result(void *data, int seq, int res, const void *result) +{ + struct impl *impl = data; + struct pw_node *node = impl->this.output->node; + pw_log_debug("link %p: output node %p result %d %d", impl, node, seq, res); + pw_work_queue_complete(impl->work, node, SPA_RESULT_ASYNC_SEQ(seq), res); +} + static const struct pw_node_events input_node_events = { PW_VERSION_NODE_EVENTS, -// .async_complete = input_node_async_complete, + .result = input_node_result, }; static const struct pw_node_events output_node_events = { PW_VERSION_NODE_EVENTS, -// .async_complete = output_node_async_complete, + .result = output_node_result, }; static int find_driver(struct pw_link *this) @@ -1375,7 +1333,7 @@ struct pw_link *pw_link_new(struct pw_core *core, try_link_controls(impl, output, input); - pw_node_events_peer_added(output_node, input_node); + pw_node_emit_peer_added(output_node, input_node); return this; @@ -1470,7 +1428,7 @@ void pw_link_destroy(struct pw_link *link) if (link->registered) spa_list_remove(&link->link); - pw_node_events_peer_removed(link->output->node, link->input->node); + pw_node_emit_peer_removed(link->output->node, link->input->node); try_unlink_controls(impl, link->input, link->output); diff --git a/src/pipewire/node.c b/src/pipewire/node.c index 76f0535f8..f5bbf600d 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -32,6 +32,7 @@ #include #include +#include #include "pipewire/interfaces.h" #include "pipewire/private.h" @@ -62,13 +63,15 @@ struct impl { uint32_t next_position; int last_error; - struct spa_pending pending_state; + struct spa_pending_queue pending; int pause_on_idle:1; }; struct resource_data { struct spa_hook resource_listener; struct pw_node *node; + struct pw_resource *resource; + uint32_t seq; }; /** \endcond */ @@ -193,10 +196,10 @@ static void node_update_state(struct pw_node *node, enum pw_node_state state, ch break; } - pw_node_events_state_changed(node, old, state, error); + pw_node_emit_state_changed(node, old, state, error); node->info.change_mask |= PW_NODE_CHANGE_MASK_STATE; - pw_node_events_info_changed(node, &node->info); + pw_node_emit_info_changed(node, &node->info); if (node->global) spa_list_for_each(resource, &node->global->resource_list, link) @@ -249,21 +252,26 @@ 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_node_resource_param(resource, id, index, next, param); + struct resource_data *d = data; + pw_log_debug("resource %p: reply param %d", d->resource, d->seq); + pw_node_resource_param(d->resource, d->seq, id, index, next, param); return 0; } -static int node_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, - const struct spa_pod *filter) +static int node_enum_params(void *object, uint32_t seq, uint32_t id, + uint32_t index, uint32_t num, const struct spa_pod *filter) { struct pw_resource *resource = object; struct resource_data *data = pw_resource_get_user_data(resource); struct pw_node *node = data->node; int res; + pw_log_debug("resource %p: enum params %d %s %u %u", resource, seq, + spa_debug_type_find_name(spa_type_param, id), index, num); + + data->seq = seq; if ((res = pw_node_for_each_param(node, id, index, num, - filter, reply_param, resource)) < 0) { + filter, reply_param, data)) < 0) { pw_log_error("resource %p: %d error %d (%s)", resource, resource->id, res, spa_strerror(res)); pw_core_resource_error(resource->client->core_resource, @@ -328,6 +336,7 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions, data = pw_resource_get_user_data(resource); data->node = this; + data->resource = resource; pw_resource_add_listener(resource, &data->resource_listener, &resource_events, resource); pw_resource_set_implementation(resource, &node_methods, resource); @@ -426,7 +435,7 @@ SPA_EXPORT int pw_node_initialized(struct pw_node *this) { pw_log_debug("node %p initialized", this); - pw_node_events_initialized(this); + pw_node_emit_initialized(this); node_update_state(this, PW_NODE_STATE_SUSPENDED, NULL); return 0; } @@ -505,7 +514,7 @@ int pw_node_set_driver(struct pw_node *node, struct pw_node *driver) spa_list_remove(&n->driver_link); spa_list_append(&driver->driver_list, &n->driver_link); n->driver_node = driver; - pw_node_events_driver_changed(n, old, driver); + pw_node_emit_driver_changed(n, old, driver); if ((res = spa_node_set_io(n->node, SPA_IO_Position, @@ -670,6 +679,9 @@ struct pw_node *pw_node_new(struct pw_core *core, &this->activation) < 0) goto clean_impl; + spa_pending_queue_init(&impl->pending); + this->pending = &impl->pending; + impl->work = pw_work_queue_new(this->core->main_loop); if (impl->work == NULL) goto clean_impl; @@ -774,7 +786,7 @@ int pw_node_update_properties(struct pw_node *node, const struct spa_dict *dict) node->info.props = &node->properties->dict; node->info.change_mask |= PW_NODE_CHANGE_MASK_PROPS; - pw_node_events_info_changed(node, &node->info); + pw_node_emit_info_changed(node, &node->info); if (node->global) spa_list_for_each(resource, &node->global->resource_list, link) @@ -838,15 +850,17 @@ static int node_port_info(void *data, enum spa_direction direction, uint32_t por return 0; } -static int node_complete(struct spa_pending *pending, const void *result) +static int node_result(void *data, int seq, int res, const void *result) { - struct impl *impl = pending->data; - uint32_t seq = SPA_RESULT_ASYNC_SEQ(pending->seq); - int res = pending->res; - pending->res = 0; - pw_log_debug("node %p: done event %d %u", impl, res, pending->seq); + struct pw_node *node = data; + struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this); + + pw_log_trace("node %p: result seq:%d res:%d", node, seq, res); impl->last_error = res; - pw_work_queue_complete(impl->work, &impl->this, seq, res); + spa_pending_queue_complete(&impl->pending, seq, res, result); + pw_work_queue_complete(impl->work, &impl->this, SPA_RESULT_ASYNC_SEQ(seq), res); + pw_node_emit_result(node, seq, res, result); + return 0; } @@ -865,7 +879,7 @@ static int node_event(void *data, struct spa_event *event) default: break; } - pw_node_events_event(node, event); + pw_node_emit_event(node, event); return 0; } @@ -909,6 +923,7 @@ static const struct spa_node_callbacks node_callbacks = { SPA_VERSION_NODE_CALLBACKS, .info = node_info, .port_info = node_port_info, + .result = node_result, .event = node_event, .ready = node_ready, .reuse_buffer = node_reuse_buffer, @@ -973,7 +988,7 @@ void pw_node_destroy(struct pw_node *node) struct pw_port *port; pw_log_debug("node %p: destroy", impl); - pw_node_events_destroy(node); + pw_node_emit_destroy(node); pause_node(node); suspend_node(node); @@ -994,11 +1009,6 @@ void pw_node_destroy(struct pw_node *node) if (node->registered) spa_list_remove(&node->link); - if (impl->pending_state.res != 0) { - pw_log_debug("remove pending state %d", impl->pending_state.res); - spa_list_remove(&impl->pending_state.link); - impl->pending_state.res = 0; - } spa_node_set_callbacks(node->node, NULL, NULL); pw_log_debug("node %p: unlink ports", node); @@ -1019,7 +1029,7 @@ void pw_node_destroy(struct pw_node *node) } pw_log_debug("node %p: free", node); - pw_node_events_free(node); + pw_node_emit_free(node); pw_work_queue_destroy(impl->work); @@ -1065,6 +1075,7 @@ int pw_node_for_each_param(struct pw_node *node, struct spa_pod *param), void *data) { + struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this); int res = 0; uint32_t idx, count; uint8_t buf[4096]; @@ -1074,13 +1085,18 @@ int pw_node_for_each_param(struct pw_node *node, if (max == 0) max = UINT32_MAX; + pw_log_debug("node %p: params %s %u %u", impl, + spa_debug_type_find_name(spa_type_param, param_id), + index, max); + for (count = 0; count < max; count++) { spa_pod_builder_init(&b, buf, sizeof(buf)); idx = index; if ((res = spa_node_enum_params_sync(node->node, param_id, &index, - filter, ¶m, &b)) != 1) + filter, ¶m, &b, + &impl->pending)) != 1) break; if ((res = callback(data, param_id, idx, index, param)) != 0) @@ -1215,7 +1231,7 @@ int pw_node_set_state(struct pw_node *node, enum pw_node_state state) if (old == state) return 0; - pw_node_events_state_request(node, state); + pw_node_emit_state_request(node, state); switch (state) { case PW_NODE_STATE_CREATING: @@ -1244,13 +1260,7 @@ int pw_node_set_state(struct pw_node *node, enum pw_node_state state) return res; if (SPA_RESULT_IS_ASYNC(res)) { - if (impl->pending_state.res != 0) { - pw_log_warn("remove pending state %d", impl->pending_state.res); - spa_list_remove(&impl->pending_state.link); - } - - spa_node_wait(node->node, res, &impl->pending_state, - node_complete, impl); + res = spa_node_sync(node->node, res); } pw_work_queue_add(impl->work, @@ -1267,7 +1277,7 @@ int pw_node_set_active(struct pw_node *node, bool active) if (old != active) { pw_log_debug("node %p: %s", node, active ? "activate" : "deactivate"); node->active = active; - pw_node_events_active_changed(node, active); + pw_node_emit_active_changed(node, active); if (active) { if (node->enabled) node_activate(node); @@ -1296,7 +1306,7 @@ int pw_node_set_enabled(struct pw_node *node, bool enabled) if (old != enabled) { pw_log_debug("node %p: %s", node, enabled ? "enable" : "disable"); node->enabled = enabled; - pw_node_events_enabled_changed(node, enabled); + pw_node_emit_enabled_changed(node, enabled); if (enabled) { if (node->active) diff --git a/src/pipewire/node.h b/src/pipewire/node.h index 9d489dccc..904d37206 100644 --- a/src/pipewire/node.h +++ b/src/pipewire/node.h @@ -83,6 +83,9 @@ struct pw_node_events { void (*state_changed) (void *data, enum pw_node_state old, enum pw_node_state state, const char *error); + /** a result was received */ + void (*result) (void *data, int seq, int res, const void *result); + /** an event is emited */ void (*event) (void *data, const struct spa_event *event); diff --git a/src/pipewire/port.c b/src/pipewire/port.c index b05df9c10..08a4c403c 100644 --- a/src/pipewire/port.c +++ b/src/pipewire/port.c @@ -45,6 +45,8 @@ struct impl { struct resource_data { struct spa_hook resource_listener; struct pw_port *port; + struct pw_resource *resource; + uint32_t seq; }; /** \endcond */ @@ -307,7 +309,6 @@ struct pw_port *pw_port_new(enum pw_direction direction, 0); this->rt.io.status = SPA_STATUS_NEED_BUFFER; - return this; no_mem: @@ -463,23 +464,26 @@ 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; + struct resource_data *d = data; + struct pw_resource *resource = d->resource; pw_log_debug("resource %p: reply param %d %d %d", resource, id, index, next); - pw_port_resource_param(resource, id, index, next, param); + pw_port_resource_param(resource, d->seq, id, index, next, param); return 0; } -static int port_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, +static int port_enum_params(void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { struct pw_resource *resource = object; 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); + pw_log_debug("resource %p: enum params %d %s %u %u", resource, seq, + spa_debug_type_find_name(spa_type_param, id), index, num); + data->seq = seq; if ((res = pw_port_for_each_param(port, id, index, num, filter, - reply_param, resource)) < 0) + reply_param, data)) < 0) pw_core_resource_error(resource->client->core_resource, resource->id, res, spa_strerror(res)); return res; @@ -505,6 +509,7 @@ global_bind(void *_data, struct pw_client *client, uint32_t permissions, data = pw_resource_get_user_data(resource); data->port = this; + data->resource = resource; pw_resource_add_listener(resource, &data->resource_listener, &resource_events, resource); pw_resource_set_implementation(resource, &port_methods, resource); @@ -585,7 +590,7 @@ int pw_port_add(struct pw_port *port, struct pw_node *node) port->node = node; - pw_node_events_port_init(node, port); + pw_node_emit_port_init(node, port); pw_port_for_each_param(port, SPA_PARAM_IO, 0, 0, NULL, check_param_io, port); @@ -647,7 +652,7 @@ int pw_port_add(struct pw_port *port, struct pw_node *node) if (port->state <= PW_PORT_STATE_INIT) pw_port_update_state(port, PW_PORT_STATE_CONFIGURE); - pw_node_events_port_added(node, port); + pw_node_emit_port_added(node, port); return 0; } @@ -703,7 +708,7 @@ static void pw_port_remove(struct pw_port *port) node->info.n_output_ports--; } spa_list_remove(&port->link); - pw_node_events_port_removed(node, port); + pw_node_emit_port_removed(node, port); } void pw_port_destroy(struct pw_port *port) @@ -758,20 +763,25 @@ int pw_port_for_each_param(struct pw_port *port, if (max == 0) max = UINT32_MAX; + pw_log_debug("port %p: params %s %u %u", port, + spa_debug_type_find_name(spa_type_param, param_id), + index, max); + for (count = 0; count < max; count++) { spa_pod_builder_init(&b, buf, sizeof(buf)); idx = index; if ((res = spa_node_port_enum_params_sync(node->node, - port->direction, port->port_id, - param_id, &index, - filter, ¶m, &b)) != 1) + port->direction, port->port_id, + param_id, &index, + filter, ¶m, &b, + node->pending)) != 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); + pw_log_debug("port %p: res %d: (%s)", port, res, spa_strerror(res)); return res; } diff --git a/src/pipewire/private.h b/src/pipewire/private.h index b9dbadfc8..458b60185 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -304,23 +304,24 @@ struct pw_node_activation { struct spa_graph_state state[2]; /* one current state and one next state */ }; -#define pw_node_events_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_node_events, m, v, ##__VA_ARGS__) -#define pw_node_events_destroy(n) pw_node_events_emit(n, destroy, 0) -#define pw_node_events_free(n) pw_node_events_emit(n, free, 0) -#define pw_node_events_initialized(n) pw_node_events_emit(n, initialized, 0) -#define pw_node_events_port_init(n,p) pw_node_events_emit(n, port_init, 0, p) -#define pw_node_events_port_added(n,p) pw_node_events_emit(n, port_added, 0, p) -#define pw_node_events_port_removed(n,p) pw_node_events_emit(n, port_removed, 0, p) -#define pw_node_events_info_changed(n,i) pw_node_events_emit(n, info_changed, 0, i) -#define pw_node_events_active_changed(n,a) pw_node_events_emit(n, active_changed, 0, a) -#define pw_node_events_enabled_changed(n,e) pw_node_events_emit(n, enabled_changed, 0, e) -#define pw_node_events_state_request(n,s) pw_node_events_emit(n, state_request, 0, s) -#define pw_node_events_state_changed(n,o,s,e) pw_node_events_emit(n, state_changed, 0, o, s, e) -#define pw_node_events_async_complete(n,s,r) pw_node_events_emit(n, async_complete, 0, s, r) -#define pw_node_events_event(n,e) pw_node_events_emit(n, event, 0, e) -#define pw_node_events_driver_changed(n,o,d) pw_node_events_emit(n, driver_changed, 0, o, d) -#define pw_node_events_peer_added(n,p) pw_node_events_emit(n, peer_added, 0, p) -#define pw_node_events_peer_removed(n,p) pw_node_events_emit(n, peer_removed, 0, p) +#define pw_node_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_node_events, m, v, ##__VA_ARGS__) +#define pw_node_emit_destroy(n) pw_node_emit(n, destroy, 0) +#define pw_node_emit_free(n) pw_node_emit(n, free, 0) +#define pw_node_emit_initialized(n) pw_node_emit(n, initialized, 0) +#define pw_node_emit_port_init(n,p) pw_node_emit(n, port_init, 0, p) +#define pw_node_emit_port_added(n,p) pw_node_emit(n, port_added, 0, p) +#define pw_node_emit_port_removed(n,p) pw_node_emit(n, port_removed, 0, p) +#define pw_node_emit_info_changed(n,i) pw_node_emit(n, info_changed, 0, i) +#define pw_node_emit_active_changed(n,a) pw_node_emit(n, active_changed, 0, a) +#define pw_node_emit_enabled_changed(n,e) pw_node_emit(n, enabled_changed, 0, e) +#define pw_node_emit_state_request(n,s) pw_node_emit(n, state_request, 0, s) +#define pw_node_emit_state_changed(n,o,s,e) pw_node_emit(n, state_changed, 0, o, s, e) +#define pw_node_emit_async_complete(n,s,r) pw_node_emit(n, async_complete, 0, s, r) +#define pw_node_emit_result(n,s,r,result) pw_node_emit(n, result, 0, s, r, result) +#define pw_node_emit_event(n,e) pw_node_emit(n, event, 0, e) +#define pw_node_emit_driver_changed(n,o,d) pw_node_emit(n, driver_changed, 0, o, d) +#define pw_node_emit_peer_added(n,p) pw_node_emit(n, peer_added, 0, p) +#define pw_node_emit_peer_removed(n,p) pw_node_emit(n, peer_removed, 0, p) struct pw_node { struct pw_core *core; /**< core object */ @@ -367,6 +368,8 @@ struct pw_node { struct pw_loop *data_loop; /**< the data loop for this node */ + struct spa_pending_queue *pending; + uint32_t quantum_size; /**< desired quantum */ struct spa_source source; /**< source to remotely trigger this node */ struct pw_memblock *activation; @@ -534,6 +537,7 @@ struct pw_resource { struct spa_hook_list listener_list; const struct pw_protocol_marshal *marshal; + int seq; void *access_private; /**< private data for access control */ void *user_data; /**< extra user data */ @@ -554,6 +558,7 @@ struct pw_proxy { struct spa_hook_list proxy_listener_list; const struct pw_protocol_marshal *marshal; /**< protocol specific marshal functions */ + int seq; void *user_data; /**< extra user data */ }; diff --git a/src/pipewire/proxy.c b/src/pipewire/proxy.c index b37d342a4..43320781c 100644 --- a/src/pipewire/proxy.c +++ b/src/pipewire/proxy.c @@ -147,12 +147,12 @@ void pw_proxy_destroy(struct pw_proxy *proxy) } SPA_EXPORT -int pw_proxy_sync(struct pw_proxy *proxy) +int pw_proxy_sync(struct pw_proxy *proxy, int seq) { int res = -EIO; 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); + res = pw_core_proxy_sync(proxy->remote->core_proxy, proxy->id, seq); + pw_log_debug("proxy %p: %u %d sync %u", proxy, proxy->id, seq, res); } return res; } @@ -164,7 +164,8 @@ int pw_proxy_error(struct pw_proxy *proxy, int result, const char *error, ...) int res = -EIO; va_start(ap, error); if (proxy->remote->core_proxy != NULL) - res = pw_core_proxy_errorv(proxy->remote->core_proxy, proxy->id, result, error, ap); + res = pw_core_proxy_errorv(proxy->remote->core_proxy, proxy->id, + result, error, ap); va_end(ap); return res; } diff --git a/src/pipewire/proxy.h b/src/pipewire/proxy.h index f1088c023..f91ec2021 100644 --- a/src/pipewire/proxy.h +++ b/src/pipewire/proxy.h @@ -152,7 +152,7 @@ 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 seq number of the reply. */ -int pw_proxy_sync(struct pw_proxy *proxy); +int pw_proxy_sync(struct pw_proxy *proxy, int seq); /** Generate an error for a proxy */ int pw_proxy_error(struct pw_proxy *proxy, int result, const char *error, ...); diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index ecb156358..f6a033381 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -123,7 +123,7 @@ static int core_event_error(void *data, uint32_t id, int res, const char *messag struct pw_remote *this = data; struct pw_proxy *proxy; - pw_log_debug("remote %p: object error %u: %d (%s): %s", this, id, + pw_log_error("remote %p: object error %u: %d (%s): %s", this, id, res, spa_strerror(res), message); proxy = pw_map_lookup(&this->objects, id); diff --git a/src/pipewire/resource.c b/src/pipewire/resource.c index 9ab34ef03..e085707a7 100644 --- a/src/pipewire/resource.c +++ b/src/pipewire/resource.c @@ -170,12 +170,12 @@ const struct pw_protocol_marshal *pw_resource_get_marshal(struct pw_resource *re } SPA_EXPORT -int pw_resource_sync(struct pw_resource *resource) +int pw_resource_sync(struct pw_resource *resource, uint32_t seq) { int res = -EIO; 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); + res = pw_core_resource_sync(resource->client->core_resource, resource->id, seq); + pw_log_debug("resource %p: %u %u sync %u", resource, resource->id, seq, res); } return res; } diff --git a/src/pipewire/resource.h b/src/pipewire/resource.h index 555565ed3..9672d3897 100644 --- a/src/pipewire/resource.h +++ b/src/pipewire/resource.h @@ -124,7 +124,7 @@ void pw_resource_add_override(struct pw_resource *resource, /** Generate an sync method for a resource. This will generate a done event * with the same \a sequence number in the return value. */ -int pw_resource_sync(struct pw_resource *resource); +int pw_resource_sync(struct pw_resource *resource, uint32_t seq); /** Generate an error for a resource */ int pw_resource_error(struct pw_resource *resource, int result, const char *error, ...); diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 52877a3ec..a056bde1e 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -376,25 +376,26 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction, return 0; } -static int impl_port_enum_params(struct spa_node *node, +static int impl_port_enum_params(struct spa_node *node, int seq, 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) + const struct spa_pod *filter) { 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; + struct spa_result_node_params result; uint8_t buffer[1024]; struct spa_pod_builder b = { 0 }; uint32_t count = 0; int res; + result.id = id; result.next = start; - next: + result.index = result.next; + spa_pod_builder_init(&b, buffer, sizeof(buffer)); while (true) { @@ -430,7 +431,7 @@ static int impl_port_enum_params(struct spa_node *node, } } - if ((res = func(data, count, &result)) != 0) + if ((res = d->callbacks->result(d->callbacks_data, seq, 0, &result)) != 0) return res; if (++count != num) diff --git a/src/tests/test-interfaces.c b/src/tests/test-interfaces.c index 50325a964..4084f3246 100644 --- a/src/tests/test-interfaces.c +++ b/src/tests/test-interfaces.c @@ -138,7 +138,8 @@ static void test_device_abi(void) struct pw_device_proxy_events e; struct { uint32_t version; - int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, + int (*enum_params) (void *object, uint32_t seq, uint32_t id, + uint32_t start, uint32_t num, const struct spa_pod *filter); int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); @@ -146,7 +147,7 @@ static void test_device_abi(void) struct { uint32_t version; int (*info) (void *object, const struct pw_device_info *info); - int (*param) (void *object, + int (*param) (void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); } events = { PW_VERSION_DEVICE_PROXY_EVENTS, }; @@ -170,8 +171,8 @@ static void test_node_abi(void) struct pw_node_proxy_events e; struct { uint32_t version; - int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter); + int (*enum_params) (void *object, uint32_t seq, uint32_t id, + uint32_t start, uint32_t num, const struct spa_pod *filter); int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); int (*send_command) (void *object, const struct spa_command *command); @@ -179,7 +180,7 @@ static void test_node_abi(void) struct { uint32_t version; int (*info) (void *object, const struct pw_node_info *info); - int (*param) (void *object, + int (*param) (void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); } events = { PW_VERSION_NODE_PROXY_EVENTS, }; @@ -204,13 +205,13 @@ static void test_port_abi(void) struct pw_port_proxy_events e; struct { uint32_t version; - int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter); + int (*enum_params) (void *object, uint32_t seq, uint32_t id, + uint32_t start, uint32_t num, const struct spa_pod *filter); } methods = { PW_VERSION_PORT_PROXY_METHODS, }; struct { uint32_t version; int (*info) (void *object, const struct pw_port_info *info); - int (*param) (void *object, + int (*param) (void *object, uint32_t seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); } events = { PW_VERSION_PORT_PROXY_EVENTS, }; diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c index 288e91ddb..8f6ee1fc0 100644 --- a/src/tools/pipewire-cli.c +++ b/src/tools/pipewire-cli.c @@ -393,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, ®istry_events, rd); - rd->prompt_pending = pw_core_proxy_sync(rd->core_proxy, 0); + pw_core_proxy_sync(rd->core_proxy, 0, ++rd->prompt_pending); break; default: @@ -687,8 +687,8 @@ static int node_event_info(void *object, const struct pw_node_info *info) return 0; } -static int node_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, - const struct spa_pod *param) +static int node_event_param(void *object, uint32_t seq, uint32_t id, + uint32_t index, uint32_t next, const struct spa_pod *param) { struct proxy_data *data = object; struct remote_data *rd = data->rd; @@ -726,8 +726,8 @@ static int port_event_info(void *object, const struct pw_port_info *info) return 0; } -static int port_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, - const struct spa_pod *param) +static int port_event_param(void *object, uint32_t seq, uint32_t id, + uint32_t index, uint32_t next, const struct spa_pod *param) { struct proxy_data *data = object; struct remote_data *rd = data->rd; @@ -1386,8 +1386,11 @@ 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) - d->current->prompt_pending = pw_core_proxy_sync(d->current->core_proxy, 0); + else { + struct remote_data *rd = d->current; + if (rd->core_proxy) + pw_core_proxy_sync(rd->core_proxy, 0, ++rd->prompt_pending); + } } } diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c index 3e5c2083e..54d8427e5 100644 --- a/src/tools/pipewire-monitor.c +++ b/src/tools/pipewire-monitor.c @@ -48,6 +48,7 @@ struct data { struct pw_core_proxy *core_proxy; struct spa_hook core_listener; + uint32_t seq; struct pw_registry_proxy *registry_proxy; struct spa_hook registry_listener; @@ -80,7 +81,8 @@ 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 = pw_core_proxy_sync(d->core_proxy, 0); + pd->pending_seq = d->seq++; + pw_core_proxy_sync(d->core_proxy, 0, d->seq); } static void remove_pending(struct proxy_data *pd) @@ -268,8 +270,8 @@ static int node_event_info(void *object, const struct pw_node_info *info) return 0; } -static int node_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, - const struct spa_pod *param) +static int node_event_param(void *object, uint32_t seq, uint32_t id, + uint32_t index, uint32_t next, const struct spa_pod *param) { struct proxy_data *data = object; return add_param(data, param); @@ -336,8 +338,8 @@ static int port_event_info(void *object, const struct pw_port_info *info) return 0; } -static int port_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, - const struct spa_pod *param) +static int port_event_param(void *object, uint32_t seq, uint32_t id, + uint32_t index, uint32_t next, const struct spa_pod *param) { struct proxy_data *data = object; return add_param(data, param);