stream: generate PeerCapbility for old servers

Automatically make an empty PeerCapability param when we receive a
Latency event without a PeerCapability. This makes new client always
receive a PeerCapability param, even when the other side did not provide
anything or when the server is too old to collect them.
This commit is contained in:
Wim Taymans 2025-11-14 12:30:56 +01:00
parent 941fc5f51c
commit 3f292e3ce3
3 changed files with 26 additions and 1 deletions

View file

@ -1130,6 +1130,8 @@ follows:
|<----------------------------------------|
| ClientNode::PortSetMixInfo | mixer inputs for each linked port
|<----------------------------------------|
| ClientNode::PortSetParam | PeerCapability of the ports
|<----------------------------------------|
| ClientNode::PortSetParam | Latency of the ports
|<----------------------------------------|
| ClientNode::SetActivation | activation of port peers

View file

@ -277,6 +277,7 @@ static void parse_peer_capability(struct data *data, const struct spa_pod *param
struct spa_peer_param_info info;
void *state = NULL;
fprintf(stderr, "peer capability\n");
while (spa_peer_param_parse(param, &info, sizeof(info), &state) == 1) {
struct spa_param_dict_info di;

View file

@ -11,6 +11,7 @@
#include <spa/buffer/alloc.h>
#include <spa/param/props.h>
#include <spa/param/format-utils.h>
#include <spa/param/peer-utils.h>
#include <spa/node/io.h>
#include <spa/node/utils.h>
#include <spa/utils/cleanup.h>
@ -146,6 +147,7 @@ struct stream {
struct spa_callbacks rt_callbacks;
unsigned int have_peer_capability:1;
unsigned int disconnecting:1;
unsigned int disconnect_core:1;
unsigned int draining:1;
@ -915,6 +917,21 @@ static int parse_latency(struct pw_stream *stream, const struct spa_pod *param,
return 0;
}
static void emit_dummy_peer_capability(struct stream *impl, bool empty)
{
struct spa_pod *param = NULL;
uint8_t buffer[1024];
if (!empty) {
struct spa_pod_frame f;
struct spa_pod_builder b;
spa_pod_builder_init(&b, buffer, sizeof(buffer));
spa_peer_param_build_start(&b, &f, SPA_PARAM_PeerCapability);
spa_peer_param_build_add_param(&b, SPA_ID_INVALID, NULL);
param = spa_peer_param_build_end(&b, &f);
}
emit_param_changed(impl, SPA_PARAM_PeerCapability, param);
}
static int impl_port_set_param(void *object,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t flags,
@ -922,7 +939,7 @@ static int impl_port_set_param(void *object,
{
struct stream *impl = object;
struct pw_stream *stream = &impl->this;
uint32_t user, fl = 0;
uint32_t user = 0, fl = 0;
int res;
const struct spa_pod *params[1];
uint32_t n_params = 0;
@ -942,7 +959,12 @@ static int impl_port_set_param(void *object,
n_params = param ? 1 : 0;
switch (id) {
case SPA_PARAM_PeerCapability:
impl->have_peer_capability = true;
break;
case SPA_PARAM_Latency:
if (!impl->have_peer_capability)
emit_dummy_peer_capability(impl, param == NULL);
parse_latency(stream, param, &fl);
break;
}