mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
media-session: keep track of seq in pw_*_enum_params
If multiple async enum param are running at the same time, take results only from the latest one.
This commit is contained in:
parent
5c23dd6311
commit
462c50acd6
2 changed files with 46 additions and 13 deletions
|
|
@ -361,7 +361,7 @@ int sm_object_destroy(struct sm_object *obj)
|
|||
}
|
||||
|
||||
static struct param *add_param(struct spa_list *param_list,
|
||||
uint32_t id, const struct spa_pod *param)
|
||||
int seq, int *param_seq, uint32_t id, const struct spa_pod *param)
|
||||
{
|
||||
struct param *p;
|
||||
|
||||
|
|
@ -372,6 +372,19 @@ static struct param *add_param(struct spa_list *param_list,
|
|||
if (id == SPA_ID_INVALID)
|
||||
id = SPA_POD_OBJECT_ID(param);
|
||||
|
||||
if (id >= SM_MAX_PARAMS) {
|
||||
pw_log_error(NAME": too big param id %d", id);
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (seq != param_seq[id]) {
|
||||
pw_log_debug(NAME": ignoring param %d, seq:%d != current_seq:%d",
|
||||
id, seq, param_seq[id]);
|
||||
errno = EBUSY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = malloc(sizeof(struct param) + SPA_POD_SIZE(param));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
|
@ -490,13 +503,21 @@ static void device_event_info(void *object, const struct pw_device_info *info)
|
|||
if (info->params[i].user == 0)
|
||||
continue;
|
||||
|
||||
if (id >= SM_MAX_PARAMS) {
|
||||
pw_log_error(NAME" %p: too big param id %d", impl, id);
|
||||
continue;
|
||||
}
|
||||
|
||||
device->n_params -= clear_params(&device->param_list, id);
|
||||
|
||||
if (info->params[i].flags & SPA_PARAM_INFO_READ) {
|
||||
pw_log_debug(NAME" %p: device %d enum params %d", impl,
|
||||
device->obj.id, id);
|
||||
pw_device_enum_params((struct pw_device*)device->obj.proxy,
|
||||
1, id, 0, UINT32_MAX, NULL);
|
||||
int res;
|
||||
res = pw_device_enum_params((struct pw_device*)device->obj.proxy,
|
||||
++device->param_seq[id], id, 0, UINT32_MAX, NULL);
|
||||
if (SPA_RESULT_IS_ASYNC(res))
|
||||
device->param_seq[id] = res;
|
||||
pw_log_debug(NAME" %p: device %d enum params %d seq:%d", impl,
|
||||
device->obj.id, id, device->param_seq[id]);
|
||||
}
|
||||
info->params[i].user = 0;
|
||||
}
|
||||
|
|
@ -512,8 +533,8 @@ static void device_event_param(void *object, int seq,
|
|||
struct sm_device *device = object;
|
||||
struct impl *impl = SPA_CONTAINER_OF(device->obj.session, struct impl, this);
|
||||
|
||||
pw_log_debug(NAME" %p: device %p param %d index:%d", impl, device, id, index);
|
||||
if (add_param(&device->param_list, id, param) != NULL)
|
||||
pw_log_debug(NAME" %p: device %p param %d index:%d seq:%d", impl, device, id, index, seq);
|
||||
if (add_param(&device->param_list, seq, device->param_seq, id, param) != NULL)
|
||||
device->n_params++;
|
||||
|
||||
device->obj.avail |= SM_DEVICE_CHANGE_MASK_PARAMS;
|
||||
|
|
@ -591,13 +612,21 @@ static void node_event_info(void *object, const struct pw_node_info *info)
|
|||
if (info->params[i].user == 0)
|
||||
continue;
|
||||
|
||||
if (id >= SM_MAX_PARAMS) {
|
||||
pw_log_error(NAME" %p: too big param id %d", impl, id);
|
||||
continue;
|
||||
}
|
||||
|
||||
node->n_params -= clear_params(&node->param_list, id);
|
||||
|
||||
if (info->params[i].flags & SPA_PARAM_INFO_READ) {
|
||||
pw_log_debug(NAME" %p: node %d enum params %d", impl,
|
||||
node->obj.id, id);
|
||||
pw_node_enum_params((struct pw_node*)node->obj.proxy,
|
||||
1, id, 0, UINT32_MAX, NULL);
|
||||
int res;
|
||||
res = pw_node_enum_params((struct pw_node*)node->obj.proxy,
|
||||
++node->param_seq[id], id, 0, UINT32_MAX, NULL);
|
||||
if (SPA_RESULT_IS_ASYNC(res))
|
||||
node->param_seq[id] = res;
|
||||
pw_log_debug(NAME" %p: node %d enum params %d seq:%d", impl,
|
||||
node->obj.id, id, node->param_seq[id]);
|
||||
}
|
||||
info->params[i].user = 0;
|
||||
}
|
||||
|
|
@ -613,8 +642,8 @@ static void node_event_param(void *object, int seq,
|
|||
struct sm_node *node = object;
|
||||
struct impl *impl = SPA_CONTAINER_OF(node->obj.session, struct impl, this);
|
||||
|
||||
pw_log_debug(NAME" %p: node %p param %d index:%d", impl, node, id, index);
|
||||
if (add_param(&node->param_list, id, param) != NULL)
|
||||
pw_log_debug(NAME" %p: node %p param %d index:%d seq:%d", impl, node, id, index, seq);
|
||||
if (add_param(&node->param_list, seq, node->param_seq, id, param) != NULL)
|
||||
node->n_params++;
|
||||
|
||||
node->obj.avail |= SM_NODE_CHANGE_MASK_PARAMS;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ extern "C" {
|
|||
|
||||
#define SM_TYPE_MEDIA_SESSION PW_TYPE_INFO_OBJECT_BASE "SessionManager"
|
||||
|
||||
#define SM_MAX_PARAMS 32
|
||||
|
||||
struct sm_media_session;
|
||||
|
||||
struct sm_object_events {
|
||||
|
|
@ -133,6 +135,7 @@ struct sm_device {
|
|||
#define SM_DEVICE_CHANGE_MASK_NODES (SM_OBJECT_CHANGE_MASK_LAST<<2)
|
||||
uint32_t n_params;
|
||||
struct spa_list param_list; /**< list of sm_param */
|
||||
int param_seq[SM_MAX_PARAMS];
|
||||
struct pw_device_info *info;
|
||||
struct spa_list node_list;
|
||||
};
|
||||
|
|
@ -148,6 +151,7 @@ struct sm_node {
|
|||
#define SM_NODE_CHANGE_MASK_PORTS (SM_OBJECT_CHANGE_MASK_LAST<<2)
|
||||
uint32_t n_params;
|
||||
struct spa_list param_list; /**< list of sm_param */
|
||||
int param_seq[SM_MAX_PARAMS];
|
||||
struct pw_node_info *info;
|
||||
struct spa_list port_list;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue