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_FORMAT (1 << 2)
|
||||
int type;
|
||||
struct spa_list link;
|
||||
struct spa_pod *param;
|
||||
};
|
||||
|
||||
|
|
@ -117,7 +118,8 @@ struct stream {
|
|||
uint32_t io_control_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];
|
||||
uint32_t n_buffers;
|
||||
|
|
@ -136,39 +138,66 @@ struct stream {
|
|||
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,
|
||||
int type, const struct spa_pod *param)
|
||||
{
|
||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||
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;
|
||||
|
||||
p = pw_array_add(&impl->params, sizeof(struct param));
|
||||
if (p == NULL) {
|
||||
free(copy);
|
||||
if (!spa_pod_is_object(param))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = malloc(sizeof(struct param) + SPA_POD_SIZE(param));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void clear_params(struct pw_stream *stream, int type)
|
||||
{
|
||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||
struct param *p;
|
||||
struct param *p, *t;
|
||||
|
||||
p = pw_array_first(&impl->params);
|
||||
while (pw_array_check(&impl->params, p)) {
|
||||
spa_list_for_each_safe(p, t, &impl->param_list, link) {
|
||||
if ((p->type & type) != 0) {
|
||||
free(p->param);
|
||||
pw_array_remove(&impl->params, p);
|
||||
spa_list_remove(&p->link);
|
||||
free(p);
|
||||
}
|
||||
else
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -334,18 +363,12 @@ static void emit_node_info(struct stream *d)
|
|||
static void emit_port_info(struct stream *d)
|
||||
{
|
||||
struct spa_port_info info;
|
||||
struct spa_param_info params[5];
|
||||
|
||||
info = SPA_PORT_INFO_INIT();
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_FLAGS;
|
||||
info.flags = SPA_PORT_FLAG_CAN_USE_BUFFERS;
|
||||
info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, SPA_PARAM_INFO_READ);
|
||||
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.params = d->params;
|
||||
info.n_params = 5;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
uint8_t buffer[1024];
|
||||
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);
|
||||
|
||||
result.id = id;
|
||||
result.next = start;
|
||||
|
||||
while (true) {
|
||||
spa_list_for_each(p, &d->param_list, link) {
|
||||
struct spa_pod *param;
|
||||
|
||||
if (idx++ < start)
|
||||
continue;
|
||||
|
||||
result.index = result.next++;
|
||||
|
||||
if (result.index >= n_params)
|
||||
break;
|
||||
|
||||
param = pw_array_get_unchecked(&d->params, result.index, struct param)->param;
|
||||
|
||||
param = p->param;
|
||||
if (param == NULL || !spa_pod_is_object_id(param, id))
|
||||
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->queued.ring);
|
||||
pw_array_init(&impl->params, sizeof(struct param) * 8);
|
||||
spa_list_init(&impl->param_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);
|
||||
|
||||
clear_params(stream, PARAM_TYPE_INIT | PARAM_TYPE_OTHER | PARAM_TYPE_FORMAT);
|
||||
pw_array_clear(&impl->params);
|
||||
|
||||
free(stream->error);
|
||||
|
||||
|
|
@ -1155,7 +1176,13 @@ pw_stream_connect(struct pw_stream *stream,
|
|||
direction == PW_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
|
||||
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++)
|
||||
add_param(stream, PARAM_TYPE_INIT, params[i]);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue