diff --git a/src/modules/module-media-session/floatmix.c b/src/modules/module-media-session/floatmix.c index aa00f15f3..d36ee6e67 100644 --- a/src/modules/module-media-session/floatmix.c +++ b/src/modules/module-media-session/floatmix.c @@ -759,7 +759,7 @@ static int impl_node_process(struct spa_node *node) outio = outport->io; spa_return_val_if_fail(outio != NULL, -EIO); - spa_log_trace(this->log, NAME " %p: status %d %d", this, outio->status, outio->buffer_id); + spa_log_trace(this->log, NAME " %p: status %p %d %d", this, outio, outio->status, outio->buffer_id); if (outio->status == SPA_STATUS_HAVE_BUFFER) return outio->status; diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index 55247f36b..257c831c3 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -764,6 +764,64 @@ static int node_demarshal_enum_params(void *object, void *data, size_t size) return 0; } +static void node_marshal_set_param(void *object, uint32_t id, uint32_t flags, + const struct spa_pod *param) +{ + struct pw_proxy *proxy = object; + struct spa_pod_builder *b; + + b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SET_PARAM); + + spa_pod_builder_add_struct(b, + "I", id, + "i", flags, + "P", param); + pw_protocol_native_end_proxy(proxy, b); +} + +static int node_demarshal_set_param(void *object, void *data, size_t size) +{ + struct pw_resource *resource = object; + struct spa_pod_parser prs; + uint32_t id, flags; + struct spa_pod *param; + + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[ I", &id, + "i", &flags, + "P", ¶m, NULL) < 0) + return -EINVAL; + + pw_resource_do(resource, struct pw_node_proxy_methods, set_param, 0, id, flags, param); + return 0; +} + +static void node_marshal_send_command(void *object, const struct spa_command *command) +{ + struct pw_proxy *proxy = object; + struct spa_pod_builder *b; + + b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SEND_COMMAND); + spa_pod_builder_add_struct(b, "P", command); + pw_protocol_native_end_proxy(proxy, b); +} + +static int node_demarshal_send_command(void *object, void *data, size_t size) +{ + struct pw_resource *resource = object; + struct spa_pod_parser prs; + struct spa_command *command; + + spa_pod_parser_init(&prs, data, size, 0); + if (spa_pod_parser_get(&prs, + "[ P", &command, NULL) < 0) + return -EINVAL; + + pw_resource_do(resource, struct pw_node_proxy_methods, send_command, 0, command); + return 0; +} + static void port_marshal_info(void *object, struct pw_port_info *info) { struct pw_resource *resource = object; @@ -1186,10 +1244,14 @@ const struct pw_protocol_marshal pw_protocol_native_factory_marshal = { static const struct pw_node_proxy_methods pw_protocol_native_node_method_marshal = { PW_VERSION_NODE_PROXY_METHODS, &node_marshal_enum_params, + &node_marshal_set_param, + &node_marshal_send_command, }; static const struct pw_protocol_native_demarshal pw_protocol_native_node_method_demarshal[] = { { &node_demarshal_enum_params, 0, }, + { &node_demarshal_set_param, PW_PROTOCOL_NATIVE_PERM_W, }, + { &node_demarshal_send_command, PW_PROTOCOL_NATIVE_PERM_W, }, }; static const struct pw_node_proxy_events pw_protocol_native_node_event_marshal = { diff --git a/src/pipewire/interfaces.h b/src/pipewire/interfaces.h index 7081f8d06..b31c7cba9 100644 --- a/src/pipewire/interfaces.h +++ b/src/pipewire/interfaces.h @@ -490,7 +490,9 @@ pw_node_proxy_add_listener(struct pw_node_proxy *node, #define pw_node_resource_param(r,...) pw_resource_notify(r,struct pw_node_proxy_events,param,__VA_ARGS__) #define PW_NODE_PROXY_METHOD_ENUM_PARAMS 0 -#define PW_NODE_PROXY_METHOD_NUM 1 +#define PW_NODE_PROXY_METHOD_SET_PARAM 1 +#define PW_NODE_PROXY_METHOD_SEND_COMMAND 2 +#define PW_NODE_PROXY_METHOD_NUM 3 /** Node methods */ struct pw_node_proxy_methods { @@ -509,9 +511,26 @@ struct pw_node_proxy_methods { */ void (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter); + + /** + * Set a parameter on the node + * + * \param id the parameter id to set + * \param flags extra parameter flags + * \param param the parameter to set + */ + void (*set_param) (void *object, uint32_t id, uint32_t flags, + const struct spa_pod *param); + + /** + * Send a command to the node + * + * \param command the command to send + */ + void (*send_command) (void *object, const struct spa_command *command); }; -/** Registry */ +/** Node */ static inline void pw_node_proxy_enum_params(struct pw_node_proxy *node, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) @@ -520,6 +539,21 @@ pw_node_proxy_enum_params(struct pw_node_proxy *node, uint32_t id, uint32_t inde id, index, num, filter); } +static inline void +pw_node_proxy_set_param(struct pw_node_proxy *node, uint32_t id, uint32_t flags, + const struct spa_pod *param) +{ + pw_proxy_do((struct pw_proxy*)node, struct pw_node_proxy_methods, set_param, + id, flags, param); +} + +static inline void +pw_node_proxy_send_command(struct pw_node_proxy *node, const struct spa_command *command) +{ + pw_proxy_do((struct pw_proxy*)node, struct pw_node_proxy_methods, send_command, + command); +} + #define PW_VERSION_PORT 0 #define PW_PORT_PROXY_EVENT_INFO 0 diff --git a/src/pipewire/node.c b/src/pipewire/node.c index 0e5aae9f2..daf673dce 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -256,9 +256,37 @@ static void node_enum_params(void *object, uint32_t id, uint32_t index, uint32_t pw_node_for_each_param(node, id, index, num, filter, reply_param, resource); } +static void node_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 pw_node *node = data->node; + + spa_node_set_param(node->node, id, flags, param); +} + +static void node_send_command(void *object, const struct spa_command *command) +{ + struct pw_resource *resource = object; + struct resource_data *data = pw_resource_get_user_data(resource); + struct pw_node *node = data->node; + + switch (SPA_NODE_COMMAND_ID(command)) { + case SPA_NODE_COMMAND_Suspend: + suspend_node(node); + break; + default: + spa_node_send_command(node->node, command); + break; + } +} + static const struct pw_node_proxy_methods node_methods = { PW_VERSION_NODE_PROXY_METHODS, - .enum_params = node_enum_params + .enum_params = node_enum_params, + .set_param = node_set_param, + .send_command = node_send_command }; static void