diff --git a/spa/include/spa/node/node.h b/spa/include/spa/node/node.h index f3eb6c027..44e45da83 100644 --- a/spa/include/spa/node/node.h +++ b/spa/include/spa/node/node.h @@ -450,6 +450,9 @@ struct spa_node_methods { * Enumerate all possible parameters of \a id on \a port_id of \a node * that are compatible with \a filter. * + * When SPA_ID_INVALID is given as the port_id, the node will reply with + * the params that would be returned for a new port in the given direction. + * * The result parameters can be queried and modified and ultimately be used * to call port_set_param. * @@ -464,7 +467,7 @@ struct spa_node_methods { * \param seq a sequence number to pass to the result event when * this method is executed synchronously. * \param direction an spa_direction - * \param port_id the port to query + * \param port_id the port to query or SPA_ID_INVALID * \param id the parameter id to query * \param start the first index to query, 0 to get the first item * \param max the maximum number of params to query diff --git a/spa/plugins/audiomixer/audiomixer.c b/spa/plugins/audiomixer/audiomixer.c index ed10f1a70..99d197f79 100644 --- a/spa/plugins/audiomixer/audiomixer.c +++ b/spa/plugins/audiomixer/audiomixer.c @@ -120,13 +120,16 @@ struct impl { }; #define PORT_VALID(p) ((p) != NULL && (p)->valid) +#define CHECK_ANY_IN(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == SPA_ID_INVALID) #define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !PORT_VALID(this->in_ports[(p)])) #define CHECK_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && PORT_VALID(this->in_ports[(p)])) #define CHECK_OUT_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) #define CHECK_PORT(this,d,p) (CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p)) +#define CHECK_PORT_ANY(this,d,p) (CHECK_ANY_IN(this,d,p) || CHECK_PORT(this,d,p)) #define GET_IN_PORT(this,p) (this->in_ports[p]) #define GET_OUT_PORT(this,p) (&this->out_ports[p]) #define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p)) +#define GET_PORT_ANY(this,d,p) (CHECK_ANY_IN(this,d,p) ? NULL : GET_PORT(this,d,p)) static int impl_node_enum_params(void *object, int seq, uint32_t id, uint32_t start, uint32_t num, @@ -307,8 +310,7 @@ impl_node_remove_port(void *object, enum spa_direction direction, uint32_t port_ return 0; } -static int port_enum_formats(void *object, - enum spa_direction direction, uint32_t port_id, +static int port_enum_formats(void *object, struct port *port, uint32_t index, struct spa_pod **param, struct spa_pod_builder *builder) @@ -372,9 +374,9 @@ impl_node_port_enum_params(void *object, int seq, spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL); - spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); + spa_return_val_if_fail(CHECK_PORT_ANY(this, direction, port_id), -EINVAL); - port = GET_PORT(this, direction, port_id); + port = GET_PORT_ANY(this, direction, port_id); result.id = id; result.next = start; @@ -385,12 +387,12 @@ impl_node_port_enum_params(void *object, int seq, switch (id) { case SPA_PARAM_EnumFormat: - if ((res = port_enum_formats(this, direction, port_id, result.index, ¶m, &b)) <= 0) + if ((res = port_enum_formats(this, port, result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: - if (!port->have_format) + if (port == NULL || !port->have_format) return -EIO; if (result.index > 0) return 0; @@ -399,7 +401,7 @@ impl_node_port_enum_params(void *object, int seq, break; case SPA_PARAM_Buffers: - if (!port->have_format) + if (port == NULL || !port->have_format) return -EIO; if (result.index > 0) return 0; diff --git a/spa/plugins/audiomixer/mixer-dsp.c b/spa/plugins/audiomixer/mixer-dsp.c index 420586a69..cb80379bc 100644 --- a/spa/plugins/audiomixer/mixer-dsp.c +++ b/spa/plugins/audiomixer/mixer-dsp.c @@ -115,13 +115,16 @@ struct impl { }; #define PORT_VALID(p) ((p) != NULL && (p)->valid) +#define CHECK_ANY_IN(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == SPA_ID_INVALID) #define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !PORT_VALID(this->in_ports[(p)])) #define CHECK_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && PORT_VALID(this->in_ports[(p)])) #define CHECK_OUT_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) #define CHECK_PORT(this,d,p) (CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p)) +#define CHECK_PORT_ANY(this,d,p) (CHECK_ANY_IN(this,d,p) || CHECK_PORT(this,d,p)) #define GET_IN_PORT(this,p) (this->in_ports[p]) #define GET_OUT_PORT(this,p) (&this->out_ports[p]) #define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p)) +#define GET_PORT_ANY(this,d,p) (CHECK_ANY_IN(this,d,p) ? NULL : GET_PORT(this,d,p)) static int impl_node_enum_params(void *object, int seq, uint32_t id, uint32_t start, uint32_t num, @@ -303,8 +306,7 @@ impl_node_remove_port(void *object, enum spa_direction direction, uint32_t port_ return 0; } -static int port_enum_formats(void *object, - enum spa_direction direction, uint32_t port_id, +static int port_enum_formats(void *object, struct port *port, uint32_t index, struct spa_pod **param, struct spa_pod_builder *builder) @@ -347,9 +349,9 @@ impl_node_port_enum_params(void *object, int seq, spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(num != 0, -EINVAL); - spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); + spa_return_val_if_fail(CHECK_PORT_ANY(this, direction, port_id), -EINVAL); - port = GET_PORT(this, direction, port_id); + port = GET_PORT_ANY(this, direction, port_id); result.id = id; result.next = start; @@ -360,12 +362,12 @@ next: switch (id) { case SPA_PARAM_EnumFormat: - if ((res = port_enum_formats(this, direction, port_id, result.index, ¶m, &b)) <= 0) + if ((res = port_enum_formats(this, port, result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: - if (!port->have_format) + if (port == NULL || !port->have_format) return -EIO; if (result.index > 0) return 0; @@ -374,7 +376,7 @@ next: break; case SPA_PARAM_Buffers: - if (!port->have_format) + if (port == NULL || !port->have_format) return -EIO; if (result.index > 0) return 0; diff --git a/spa/plugins/control/mixer.c b/spa/plugins/control/mixer.c index ec7237978..d744ca714 100644 --- a/spa/plugins/control/mixer.c +++ b/spa/plugins/control/mixer.c @@ -85,13 +85,16 @@ struct impl { }; #define PORT_VALID(p) ((p) != NULL && (p)->valid) +#define CHECK_ANY_IN(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == SPA_ID_INVALID) #define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !PORT_VALID(this->in_ports[(p)])) #define CHECK_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && PORT_VALID(this->in_ports[(p)])) #define CHECK_OUT_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) #define CHECK_PORT(this,d,p) (CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p)) +#define CHECK_PORT_ANY(this,d,p) (CHECK_ANY_IN(this,d,p) || CHECK_PORT(this,d,p)) #define GET_IN_PORT(this,p) (this->in_ports[p]) #define GET_OUT_PORT(this,p) (&this->out_ports[p]) #define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p)) +#define GET_PORT_ANY(this,d,p) (CHECK_ANY_IN(this,d,p) ? NULL : GET_PORT(this,d,p)) static int impl_node_enum_params(void *object, int seq, uint32_t id, uint32_t start, uint32_t num, @@ -269,8 +272,7 @@ impl_node_remove_port(void *object, enum spa_direction direction, uint32_t port_ return 0; } -static int port_enum_formats(void *object, - enum spa_direction direction, uint32_t port_id, +static int port_enum_formats(void *object, struct port *port, uint32_t index, struct spa_pod **param, struct spa_pod_builder *builder) @@ -318,19 +320,19 @@ next: switch (id) { case SPA_PARAM_EnumFormat: - if ((res = port_enum_formats(this, direction, port_id, result.index, ¶m, &b)) <= 0) + if ((res = port_enum_formats(this, port, result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Format: - if (!port->have_format) + if (port == NULL || !port->have_format) return -EIO; - if ((res = port_enum_formats(this, direction, port_id, result.index, ¶m, &b)) <= 0) + if ((res = port_enum_formats(this, port, result.index, ¶m, &b)) <= 0) return res; break; case SPA_PARAM_Buffers: - if (!port->have_format) + if (port == NULL || !port->have_format) return -EIO; if (result.index > 0) return 0; diff --git a/src/pipewire/impl-port.c b/src/pipewire/impl-port.c index d0afcaa01..722f7b0ee 100644 --- a/src/pipewire/impl-port.c +++ b/src/pipewire/impl-port.c @@ -827,7 +827,8 @@ static int setup_mixer(struct pw_impl_port *port, const struct spa_pod *param) return res; } - pw_log_debug("mix node handle:%p iface:%p", handle, iface); + pw_log_debug("mix node %s (%s) handle:%p iface:%p", factory_name, fallback_lib, + handle, iface); pw_impl_port_set_mix(port, (struct spa_node*)iface, PW_IMPL_PORT_MIX_FLAG_MULTI | PW_IMPL_PORT_MIX_FLAG_NEGOTIATE);