mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
stream: keep track of param ids and emit changes
This commit is contained in:
parent
936dcbea2e
commit
1d907412e5
1 changed files with 60 additions and 33 deletions
|
|
@ -74,6 +74,7 @@ struct param {
|
||||||
#define PARAM_TYPE_OTHER (1 << 1)
|
#define PARAM_TYPE_OTHER (1 << 1)
|
||||||
#define PARAM_TYPE_FORMAT (1 << 2)
|
#define PARAM_TYPE_FORMAT (1 << 2)
|
||||||
int type;
|
int type;
|
||||||
|
struct spa_list link;
|
||||||
struct spa_pod *param;
|
struct spa_pod *param;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -117,7 +118,8 @@ struct stream {
|
||||||
uint32_t io_control_size;
|
uint32_t io_control_size;
|
||||||
uint32_t io_notify_size;
|
uint32_t io_notify_size;
|
||||||
|
|
||||||
struct pw_array params;
|
struct spa_list param_list;
|
||||||
|
struct spa_param_info params[5];
|
||||||
|
|
||||||
struct buffer buffers[MAX_BUFFERS];
|
struct buffer buffers[MAX_BUFFERS];
|
||||||
uint32_t n_buffers;
|
uint32_t n_buffers;
|
||||||
|
|
@ -136,39 +138,66 @@ struct stream {
|
||||||
int free_data:1;
|
int free_data:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int get_param_index(uint32_t id)
|
||||||
|
{
|
||||||
|
switch (id) {
|
||||||
|
case SPA_PARAM_EnumFormat:
|
||||||
|
return 0;
|
||||||
|
case SPA_PARAM_Meta:
|
||||||
|
return 1;
|
||||||
|
case SPA_PARAM_IO:
|
||||||
|
return 2;
|
||||||
|
case SPA_PARAM_Format:
|
||||||
|
return 3;
|
||||||
|
case SPA_PARAM_Buffers:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct param *add_param(struct pw_stream *stream,
|
static struct param *add_param(struct pw_stream *stream,
|
||||||
int type, const struct spa_pod *param)
|
int type, const struct spa_pod *param)
|
||||||
{
|
{
|
||||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||||
struct param *p;
|
struct param *p;
|
||||||
struct spa_pod *copy = NULL;
|
uint32_t id;
|
||||||
|
int idx;
|
||||||
|
|
||||||
if (param != NULL && (copy = spa_pod_copy(param)) == NULL)
|
if (param == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
p = pw_array_add(&impl->params, sizeof(struct param));
|
if (!spa_pod_is_object(param))
|
||||||
if (p == NULL) {
|
|
||||||
free(copy);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
p = malloc(sizeof(struct param) + SPA_POD_SIZE(param));
|
||||||
|
if (p == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
p->type = type;
|
p->type = type;
|
||||||
p->param = copy;
|
p->param = SPA_MEMBER(p, sizeof(struct param), struct spa_pod);
|
||||||
|
memcpy(p->param, param, SPA_POD_SIZE(param));
|
||||||
|
|
||||||
|
spa_list_append(&impl->param_list, &p->link);
|
||||||
|
|
||||||
|
id = ((const struct spa_pod_object *)param)->body.id;
|
||||||
|
idx = get_param_index(id);
|
||||||
|
if (idx != -1)
|
||||||
|
impl->params[idx].flags |= SPA_PARAM_INFO_READ;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_params(struct pw_stream *stream, int type)
|
static void clear_params(struct pw_stream *stream, int type)
|
||||||
{
|
{
|
||||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||||
struct param *p;
|
struct param *p, *t;
|
||||||
|
|
||||||
p = pw_array_first(&impl->params);
|
spa_list_for_each_safe(p, t, &impl->param_list, link) {
|
||||||
while (pw_array_check(&impl->params, p)) {
|
|
||||||
if ((p->type & type) != 0) {
|
if ((p->type & type) != 0) {
|
||||||
free(p->param);
|
spa_list_remove(&p->link);
|
||||||
pw_array_remove(&impl->params, p);
|
free(p);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -334,18 +363,12 @@ static void emit_node_info(struct stream *d)
|
||||||
static void emit_port_info(struct stream *d)
|
static void emit_port_info(struct stream *d)
|
||||||
{
|
{
|
||||||
struct spa_port_info info;
|
struct spa_port_info info;
|
||||||
struct spa_param_info params[5];
|
|
||||||
|
|
||||||
info = SPA_PORT_INFO_INIT();
|
info = SPA_PORT_INFO_INIT();
|
||||||
info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
||||||
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||||
info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
info.params = d->params;
|
||||||
params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, SPA_PARAM_INFO_READ);
|
|
||||||
params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, SPA_PARAM_INFO_READ);
|
|
||||||
params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
|
||||||
params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
|
||||||
info.params = params;
|
|
||||||
info.n_params = 5;
|
info.n_params = 5;
|
||||||
spa_node_emit_port_info(&d->hooks, d->direction, 0, &info);
|
spa_node_emit_port_info(&d->hooks, d->direction, 0, &info);
|
||||||
}
|
}
|
||||||
|
|
@ -424,27 +447,26 @@ static int impl_port_enum_params(struct spa_node *node, int seq,
|
||||||
const struct spa_pod *filter)
|
const struct spa_pod *filter)
|
||||||
{
|
{
|
||||||
struct stream *d = SPA_CONTAINER_OF(node, struct stream, impl_node);
|
struct stream *d = SPA_CONTAINER_OF(node, struct stream, impl_node);
|
||||||
uint32_t n_params = pw_array_get_len(&d->params, struct param);
|
|
||||||
struct spa_result_node_params result;
|
struct spa_result_node_params result;
|
||||||
uint8_t buffer[1024];
|
uint8_t buffer[1024];
|
||||||
struct spa_pod_builder b = { 0 };
|
struct spa_pod_builder b = { 0 };
|
||||||
uint32_t count = 0;
|
uint32_t idx = 0, count = 0;
|
||||||
|
struct param *p;
|
||||||
|
|
||||||
spa_return_val_if_fail(num != 0, -EINVAL);
|
spa_return_val_if_fail(num != 0, -EINVAL);
|
||||||
|
|
||||||
result.id = id;
|
result.id = id;
|
||||||
result.next = start;
|
result.next = start;
|
||||||
|
|
||||||
while (true) {
|
spa_list_for_each(p, &d->param_list, link) {
|
||||||
struct spa_pod *param;
|
struct spa_pod *param;
|
||||||
|
|
||||||
|
if (idx++ < start)
|
||||||
|
continue;
|
||||||
|
|
||||||
result.index = result.next++;
|
result.index = result.next++;
|
||||||
|
|
||||||
if (result.index >= n_params)
|
param = p->param;
|
||||||
break;
|
|
||||||
|
|
||||||
param = pw_array_get_unchecked(&d->params, result.index, struct param)->param;
|
|
||||||
|
|
||||||
if (param == NULL || !spa_pod_is_object_id(param, id))
|
if (param == NULL || !spa_pod_is_object_id(param, id))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -954,7 +976,7 @@ struct pw_stream * pw_stream_new(struct pw_remote *remote, const char *name,
|
||||||
|
|
||||||
spa_ringbuffer_init(&impl->dequeued.ring);
|
spa_ringbuffer_init(&impl->dequeued.ring);
|
||||||
spa_ringbuffer_init(&impl->queued.ring);
|
spa_ringbuffer_init(&impl->queued.ring);
|
||||||
pw_array_init(&impl->params, sizeof(struct param) * 8);
|
spa_list_init(&impl->param_list);
|
||||||
|
|
||||||
spa_hook_list_init(&this->listener_list);
|
spa_hook_list_init(&this->listener_list);
|
||||||
|
|
||||||
|
|
@ -1046,7 +1068,6 @@ void pw_stream_destroy(struct pw_stream *stream)
|
||||||
spa_list_remove(&stream->link);
|
spa_list_remove(&stream->link);
|
||||||
|
|
||||||
clear_params(stream, PARAM_TYPE_INIT | PARAM_TYPE_OTHER | PARAM_TYPE_FORMAT);
|
clear_params(stream, PARAM_TYPE_INIT | PARAM_TYPE_OTHER | PARAM_TYPE_FORMAT);
|
||||||
pw_array_clear(&impl->params);
|
|
||||||
|
|
||||||
free(stream->error);
|
free(stream->error);
|
||||||
|
|
||||||
|
|
@ -1155,7 +1176,13 @@ pw_stream_connect(struct pw_stream *stream,
|
||||||
direction == PW_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
|
direction == PW_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
|
||||||
impl->flags = flags;
|
impl->flags = flags;
|
||||||
|
|
||||||
clear_params(stream, PARAM_TYPE_INIT);
|
impl->params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, 0);
|
||||||
|
impl->params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, 0);
|
||||||
|
impl->params[2] = SPA_PARAM_INFO(SPA_PARAM_IO, 0);
|
||||||
|
impl->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_WRITE);
|
||||||
|
impl->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0);
|
||||||
|
|
||||||
|
clear_params(stream, PARAM_TYPE_INIT | PARAM_TYPE_OTHER | PARAM_TYPE_FORMAT);
|
||||||
for (i = 0; i < n_params; i++)
|
for (i = 0; i < n_params; i++)
|
||||||
add_param(stream, PARAM_TYPE_INIT, params[i]);
|
add_param(stream, PARAM_TYPE_INIT, params[i]);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue