mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
control: add control objects
Add control objects for all controllable properties on ports. Try to link compatible control properties in autolink. Allocate shared memory for the output property memory and configure the io area on the ports when the controls are linked. Send the shared memfd to clients when the io area is configured. Add port_set_io support in remote.c, mmap the control io area and set on the port. Add some param helpers Add volume control to export-source update the volume before sending each buffer.
This commit is contained in:
parent
91a3670610
commit
541553be1c
19 changed files with 577 additions and 34 deletions
|
|
@ -113,7 +113,7 @@ struct proxy {
|
|||
uint32_t n_params;
|
||||
struct spa_pod **params;
|
||||
|
||||
uint8_t format_buffer[1024];
|
||||
uint32_t membase;
|
||||
uint32_t seq;
|
||||
};
|
||||
|
||||
|
|
@ -337,7 +337,6 @@ do_update_port(struct proxy *this,
|
|||
if (spa_pod_is_object_id(port->params[i], t->param.idFormat))
|
||||
port->have_format = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_INFO && info)
|
||||
|
|
@ -534,9 +533,27 @@ spa_proxy_node_port_set_io(struct spa_node *node,
|
|||
|
||||
if (id == t->io.Buffers)
|
||||
port->io = data;
|
||||
else
|
||||
return -ENOENT;
|
||||
else {
|
||||
struct pw_memblock *mem;
|
||||
uint32_t memid = this->membase++;
|
||||
|
||||
if ((mem = pw_memblock_find(data)) == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
pw_client_node_resource_port_add_mem(this->resource,
|
||||
direction, port_id,
|
||||
memid,
|
||||
t->data.MemFd,
|
||||
mem->fd, mem->flags,
|
||||
0, mem->offset + mem->size);
|
||||
|
||||
pw_client_node_resource_port_set_io(this->resource,
|
||||
this->seq,
|
||||
direction, port_id,
|
||||
id,
|
||||
memid,
|
||||
mem->offset, mem->size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -582,7 +599,7 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
|
|||
if (this->resource == NULL)
|
||||
return 0;
|
||||
|
||||
n_mem = 0;
|
||||
n_mem = this->membase;
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
struct buffer *b = &port->buffers[i];
|
||||
struct pw_memblock *m;
|
||||
|
|
@ -1109,10 +1126,13 @@ static void node_initialized(void *data)
|
|||
impl->other_fds[1] = impl->fds[0];
|
||||
|
||||
spa_loop_add_source(impl->proxy.data_loop, &impl->proxy.data_source);
|
||||
pw_log_debug("client-node %p: add data fd %d", node, impl->proxy.data_source.fd);
|
||||
pw_log_debug("client-node %p: transport fd %d %d", node, impl->fds[0], impl->fds[1]);
|
||||
|
||||
pw_client_node_resource_transport(this->resource, pw_global_get_id(pw_node_get_global(node)),
|
||||
impl->other_fds[0], impl->other_fds[1], impl->transport);
|
||||
pw_client_node_resource_transport(this->resource,
|
||||
pw_global_get_id(pw_node_get_global(node)),
|
||||
impl->other_fds[0],
|
||||
impl->other_fds[1],
|
||||
impl->transport);
|
||||
}
|
||||
|
||||
static void node_free(void *data)
|
||||
|
|
|
|||
|
|
@ -408,6 +408,32 @@ static bool client_node_demarshal_port_command(void *object, void *data, size_t
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool client_node_demarshal_port_set_io(void *object, void *data, size_t size)
|
||||
{
|
||||
struct pw_proxy *proxy = object;
|
||||
struct spa_pod_parser prs;
|
||||
uint32_t seq, direction, port_id, id, memid, off, sz;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
if (spa_pod_parser_get(&prs,
|
||||
"["
|
||||
"i", &seq,
|
||||
"i", &direction,
|
||||
"i", &port_id,
|
||||
"I", &id,
|
||||
"i", &memid,
|
||||
"i", &off,
|
||||
"i", &sz, NULL) < 0)
|
||||
return false;
|
||||
|
||||
pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_set_io,
|
||||
seq,
|
||||
direction, port_id,
|
||||
id, memid,
|
||||
off, sz);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd,
|
||||
struct pw_client_node_transport *transport)
|
||||
{
|
||||
|
|
@ -629,6 +655,33 @@ client_node_marshal_port_command(void *object,
|
|||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
static void
|
||||
client_node_marshal_port_set_io(void *object,
|
||||
uint32_t seq,
|
||||
uint32_t direction,
|
||||
uint32_t port_id,
|
||||
uint32_t id,
|
||||
uint32_t memid,
|
||||
uint32_t offset,
|
||||
uint32_t size)
|
||||
{
|
||||
struct pw_resource *resource = object;
|
||||
struct spa_pod_builder *b;
|
||||
|
||||
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO);
|
||||
|
||||
spa_pod_builder_struct(b,
|
||||
"i", seq,
|
||||
"i", direction,
|
||||
"i", port_id,
|
||||
"I", id,
|
||||
"i", memid,
|
||||
"i", offset,
|
||||
"i", size);
|
||||
|
||||
pw_protocol_native_end_resource(resource, b);
|
||||
}
|
||||
|
||||
|
||||
static bool client_node_demarshal_done(void *object, void *data, size_t size)
|
||||
{
|
||||
|
|
@ -683,7 +736,7 @@ static bool client_node_demarshal_port_update(void *object, void *data, size_t s
|
|||
struct spa_pod_parser prs;
|
||||
uint32_t i, direction, port_id, change_mask, n_params;
|
||||
const struct spa_pod **params = NULL;
|
||||
struct spa_port_info info, *infop = NULL;
|
||||
struct spa_port_info info = { 0 }, *infop = NULL;
|
||||
struct spa_pod *ipod;
|
||||
|
||||
spa_pod_parser_init(&prs, data, size, 0);
|
||||
|
|
@ -799,6 +852,7 @@ static const struct pw_client_node_proxy_events pw_protocol_native_client_node_e
|
|||
&client_node_marshal_port_add_mem,
|
||||
&client_node_marshal_port_use_buffers,
|
||||
&client_node_marshal_port_command,
|
||||
&client_node_marshal_port_set_io,
|
||||
};
|
||||
|
||||
static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_event_demarshal[] = {
|
||||
|
|
@ -812,6 +866,7 @@ static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_
|
|||
{ &client_node_demarshal_port_add_mem, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_port_use_buffers, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_port_command, PW_PROTOCOL_NATIVE_REMAP },
|
||||
{ &client_node_demarshal_port_set_io, PW_PROTOCOL_NATIVE_REMAP },
|
||||
};
|
||||
|
||||
const struct pw_protocol_marshal pw_protocol_native_client_node_marshal = {
|
||||
|
|
|
|||
|
|
@ -195,12 +195,15 @@ pw_client_node_transport_new(uint32_t max_input_ports, uint32_t max_output_ports
|
|||
if (impl == NULL)
|
||||
return NULL;
|
||||
|
||||
pw_log_debug("transport %p: new %d %d", impl, max_input_ports, max_output_ports);
|
||||
|
||||
trans = &impl->trans;
|
||||
impl->offset = 0;
|
||||
|
||||
if (pw_memblock_alloc(PW_MEMBLOCK_FLAG_WITH_FD |
|
||||
PW_MEMBLOCK_FLAG_MAP_READWRITE |
|
||||
PW_MEMBLOCK_FLAG_SEAL, area_get_size(&area),
|
||||
PW_MEMBLOCK_FLAG_SEAL,
|
||||
area_get_size(&area),
|
||||
&impl->mem) < 0)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -229,6 +232,7 @@ pw_client_node_transport_new_from_info(struct pw_client_node_transport_info *inf
|
|||
return NULL;
|
||||
|
||||
trans = &impl->trans;
|
||||
pw_log_debug("transport %p: new from info", impl);
|
||||
|
||||
if ((res = pw_memblock_import(PW_MEMBLOCK_FLAG_MAP_READWRITE |
|
||||
PW_MEMBLOCK_FLAG_WITH_FD,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue