meta: remove shared meta data

Make a method to find the memory block for the given ptr. We can
use this to find the memfd of the memory if there is any. We can
then remove the Shared metadata on buffers.
This commit is contained in:
Wim Taymans 2017-11-28 18:23:44 +01:00
parent 75cdd20207
commit 140c3959ab
10 changed files with 161 additions and 132 deletions

View file

@ -550,10 +550,9 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
struct proxy *this;
struct impl *impl;
struct port *port;
uint32_t i, j, k;
uint32_t i, j;
size_t n_mem;
struct pw_client_node_buffer *mb;
struct spa_meta_shared *msh;
struct pw_type *t;
this = SPA_CONTAINER_OF(node, struct proxy, node);
@ -586,35 +585,53 @@ spa_proxy_node_port_use_buffers(struct spa_node *node,
n_mem = 0;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &port->buffers[i];
msh = spa_buffer_find_meta(buffers[i], t->meta.Shared);
if (msh == NULL) {
spa_log_error(this->log, "missing shared metadata on buffer %d", i);
return -EINVAL;
}
struct pw_memblock *m;
size_t data_size;
void *baseptr;
b->outbuf = buffers[i];
memcpy(&b->buffer, buffers[i], sizeof(struct spa_buffer));
b->buffer.datas = b->datas;
b->buffer.metas = b->metas;
if (buffers[i]->n_metas > 0)
baseptr = buffers[i]->metas[0].data;
else if (buffers[i]->n_datas > 0)
baseptr = buffers[i]->datas[0].chunk;
else
return -EINVAL;
if ((m = pw_memblock_find(baseptr)) == NULL)
return -EINVAL;
data_size = 0;
for (j = 0; j < buffers[i]->n_metas; j++) {
data_size += buffers[i]->metas[j].size;
}
for (j = 0; j < buffers[i]->n_datas; j++) {
struct spa_data *d = buffers[i]->datas;
data_size += sizeof(struct spa_chunk);
if (d->type == t->data.MemPtr)
data_size += d->maxsize;
}
mb[i].buffer = &b->buffer;
mb[i].mem_id = n_mem++;
mb[i].offset = 0;
mb[i].size = msh->size;
mb[i].size = data_size;
pw_client_node_resource_port_add_mem(this->resource,
direction,
port_id,
mb[i].mem_id,
t->data.MemFd,
msh->fd, msh->flags, msh->offset, msh->size);
m->fd, m->flags,
SPA_PTRDIFF(baseptr, m->ptr + m->offset),
data_size);
for (j = 0, k = 0; j < buffers[i]->n_metas; j++) {
if (buffers[i]->metas[j].type != t->meta.Shared)
memcpy(&b->buffer.metas[k++], &buffers[i]->metas[j], sizeof(struct spa_meta));
}
b->buffer.n_metas = k;
for (j = 0; j < buffers[i]->n_metas; j++)
memcpy(&b->buffer.metas[j], &buffers[i]->metas[j], sizeof(struct spa_meta));
b->buffer.n_metas = j;
for (j = 0; j < buffers[i]->n_datas; j++) {
struct spa_data *d = &buffers[i]->datas[j];

View file

@ -36,7 +36,7 @@
struct transport {
struct pw_client_node_transport trans;
struct pw_memblock mem;
struct pw_memblock *mem;
size_t offset;
struct pw_client_node_message current;
@ -106,7 +106,7 @@ static void destroy(struct pw_client_node_transport *trans)
pw_log_debug("transport %p: destroy", trans);
pw_memblock_free(&impl->mem);
pw_memblock_free(impl->mem);
free(impl);
}
@ -184,7 +184,7 @@ pw_client_node_transport_new(uint32_t max_input_ports, uint32_t max_output_ports
{
struct transport *impl;
struct pw_client_node_transport *trans;
struct pw_client_node_area area;
struct pw_client_node_area area = { 0 };
area.max_input_ports = max_input_ports;
area.n_input_ports = 0;
@ -198,12 +198,14 @@ pw_client_node_transport_new(uint32_t max_input_ports, uint32_t max_output_ports
trans = &impl->trans;
impl->offset = 0;
pw_memblock_alloc(PW_MEMBLOCK_FLAG_WITH_FD |
if (pw_memblock_alloc(PW_MEMBLOCK_FLAG_WITH_FD |
PW_MEMBLOCK_FLAG_MAP_READWRITE |
PW_MEMBLOCK_FLAG_SEAL, area_get_size(&area), &impl->mem);
PW_MEMBLOCK_FLAG_SEAL, area_get_size(&area),
&impl->mem) < 0)
return NULL;
memcpy(impl->mem.ptr, &area, sizeof(struct pw_client_node_area));
transport_setup_area(impl->mem.ptr, trans);
memcpy(impl->mem->ptr, &area, sizeof(struct pw_client_node_area));
transport_setup_area(impl->mem->ptr, trans);
transport_reset_area(trans);
trans->destroy = destroy;
@ -220,6 +222,7 @@ pw_client_node_transport_new_from_info(struct pw_client_node_transport_info *inf
struct transport *impl;
struct pw_client_node_transport *trans;
void *tmp;
int res;
impl = calloc(1, sizeof(struct transport));
if (impl == NULL)
@ -227,19 +230,19 @@ pw_client_node_transport_new_from_info(struct pw_client_node_transport_info *inf
trans = &impl->trans;
impl->mem.flags = PW_MEMBLOCK_FLAG_MAP_READWRITE | PW_MEMBLOCK_FLAG_WITH_FD;
impl->mem.fd = info->memfd;
impl->mem.offset = info->offset;
impl->mem.size = info->size;
if (pw_memblock_map(&impl->mem) < 0) {
if ((res = pw_memblock_import(PW_MEMBLOCK_FLAG_MAP_READWRITE |
PW_MEMBLOCK_FLAG_WITH_FD,
info->memfd,
info->offset,
info->size, &impl->mem)) < 0) {
pw_log_warn("transport %p: failed to map fd %d: %s", impl, info->memfd,
strerror(errno));
spa_strerror(res));
goto mmap_failed;
}
impl->offset = info->offset;
transport_setup_area(impl->mem.ptr, trans);
transport_setup_area(impl->mem->ptr, trans);
tmp = trans->output_buffer;
trans->output_buffer = trans->input_buffer;
@ -258,6 +261,7 @@ pw_client_node_transport_new_from_info(struct pw_client_node_transport_info *inf
mmap_failed:
free(impl);
errno = -res;
return NULL;
}
@ -276,9 +280,9 @@ int pw_client_node_transport_get_info(struct pw_client_node_transport *trans,
{
struct transport *impl = (struct transport *) trans;
info->memfd = impl->mem.fd;
info->memfd = impl->mem->fd;
info->offset = impl->offset;
info->size = impl->mem.size;
info->size = impl->mem->size;
return 0;
}