mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-27 07:00:12 -05:00
Rework buffer memory layout
Move offset, size and stride to separate chunk structure that we can keep in shared memory. Add shared metadata type to hold the memory block holding the metadata.
This commit is contained in:
parent
5e8a3afe17
commit
0d0385b881
13 changed files with 328 additions and 241 deletions
|
|
@ -266,11 +266,18 @@ static void
|
|||
connection_parse_use_buffers (PinosConnection *conn, PinosMessageUseBuffers *cmd)
|
||||
{
|
||||
void *p;
|
||||
unsigned int i;
|
||||
|
||||
p = conn->in.data;
|
||||
memcpy (cmd, p, sizeof (PinosMessageUseBuffers));
|
||||
if (cmd->buffers)
|
||||
cmd->buffers = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers), PinosMessageMemRef);
|
||||
cmd->buffers = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers), PinosMessageBuffer);
|
||||
|
||||
for (i = 0; i < cmd->n_buffers; i++) {
|
||||
if (cmd->buffers[i].buffer)
|
||||
cmd->buffers[i].buffer = pinos_serialize_buffer_deserialize (conn->in.data,
|
||||
SPA_PTR_TO_INT (cmd->buffers[i].buffer));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -751,24 +758,32 @@ connection_add_use_buffers (PinosConnection *conn, uint32_t dest_id, PinosMessag
|
|||
size_t len;
|
||||
int i;
|
||||
PinosMessageUseBuffers *d;
|
||||
PinosMessageMemRef *mr;
|
||||
PinosMessageBuffer *b;
|
||||
void *p;
|
||||
|
||||
/* calculate length */
|
||||
len = sizeof (PinosMessageUseBuffers);
|
||||
len += ub->n_buffers * sizeof (PinosMessageMemRef);
|
||||
len += ub->n_buffers * sizeof (PinosMessageBuffer);
|
||||
for (i = 0; i < ub->n_buffers; i++)
|
||||
len += pinos_serialize_buffer_get_size (ub->buffers[i].buffer);
|
||||
|
||||
d = connection_add_message (conn, dest_id, PINOS_MESSAGE_USE_BUFFERS, len);
|
||||
memcpy (d, ub, sizeof (PinosMessageUseBuffers));
|
||||
|
||||
mr = SPA_MEMBER (d, sizeof (PinosMessageUseBuffers), void);
|
||||
b = SPA_MEMBER (d, sizeof (PinosMessageUseBuffers), void);
|
||||
p = SPA_MEMBER (b, ub->n_buffers * sizeof (PinosMessageBuffer), void);
|
||||
|
||||
if (d->n_buffers)
|
||||
d->buffers = SPA_INT_TO_PTR (SPA_PTRDIFF (mr, d));
|
||||
d->buffers = SPA_INT_TO_PTR (SPA_PTRDIFF (b, d));
|
||||
else
|
||||
d->buffers = 0;
|
||||
|
||||
for (i = 0; i < ub->n_buffers; i++)
|
||||
memcpy (&mr[i], &ub->buffers[i], sizeof (PinosMessageMemRef));
|
||||
for (i = 0; i < ub->n_buffers; i++) {
|
||||
memcpy (&b[i], &ub->buffers[i], sizeof (PinosMessageBuffer));
|
||||
len = pinos_serialize_buffer_serialize (p, b[i].buffer);
|
||||
b[i].buffer = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
|
||||
p += len;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -286,10 +286,11 @@ typedef struct {
|
|||
} PinosMessageAddMem;
|
||||
|
||||
typedef struct {
|
||||
SpaBuffer *buffer;
|
||||
uint32_t mem_id;
|
||||
off_t offset;
|
||||
size_t size;
|
||||
} PinosMessageMemRef;
|
||||
} PinosMessageBuffer;
|
||||
|
||||
/* PINOS_MESSAGE_USE_BUFFERS */
|
||||
typedef struct {
|
||||
|
|
@ -297,7 +298,7 @@ typedef struct {
|
|||
SpaDirection direction;
|
||||
uint32_t port_id;
|
||||
unsigned int n_buffers;
|
||||
PinosMessageMemRef *buffers;
|
||||
PinosMessageBuffer *buffers;
|
||||
} PinosMessageUseBuffers;
|
||||
|
||||
PinosConnection * pinos_connection_new (int fd);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ pinos_serialize_buffer_get_size (const SpaBuffer *buffer)
|
|||
|
||||
size = sizeof (SpaBuffer);
|
||||
for (i = 0; i < buffer->n_metas; i++)
|
||||
size += sizeof (SpaMeta) + buffer->metas[i].size;
|
||||
size += sizeof (SpaMeta);
|
||||
for (i = 0; i < buffer->n_datas; i++)
|
||||
size += sizeof (SpaData);
|
||||
return size;
|
||||
|
|
@ -57,12 +57,8 @@ pinos_serialize_buffer_serialize (void *dest, const SpaBuffer *buffer)
|
|||
tb->metas = SPA_INT_TO_PTR (SPA_PTRDIFF (mp, tb));
|
||||
tb->datas = SPA_INT_TO_PTR (SPA_PTRDIFF (dp, tb));
|
||||
|
||||
for (i = 0; i < tb->n_metas; i++) {
|
||||
for (i = 0; i < tb->n_metas; i++)
|
||||
memcpy (&mp[i], &buffer->metas[i], sizeof (SpaMeta));
|
||||
memcpy (p, mp[i].data, mp[i].size);
|
||||
mp[i].data = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tb));
|
||||
p += mp[i].size;
|
||||
}
|
||||
for (i = 0; i < tb->n_datas; i++)
|
||||
memcpy (&dp[i], &buffer->datas[i], sizeof (SpaData));
|
||||
|
||||
|
|
@ -78,17 +74,21 @@ pinos_serialize_buffer_deserialize (void *src, off_t offset)
|
|||
b = SPA_MEMBER (src, offset, SpaBuffer);
|
||||
if (b->metas)
|
||||
b->metas = SPA_MEMBER (b, SPA_PTR_TO_INT (b->metas), SpaMeta);
|
||||
for (i = 0; i < b->n_metas; i++) {
|
||||
SpaMeta *m = &b->metas[i];
|
||||
if (m->data)
|
||||
m->data = SPA_MEMBER (b, SPA_PTR_TO_INT (m->data), void);
|
||||
}
|
||||
if (b->datas)
|
||||
b->datas = SPA_MEMBER (b, SPA_PTR_TO_INT (b->datas), SpaData);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
SpaBuffer *
|
||||
pinos_serialize_buffer_copy_into (void *dest, const SpaBuffer *buffer)
|
||||
{
|
||||
if (buffer == NULL)
|
||||
return NULL;
|
||||
|
||||
pinos_serialize_buffer_serialize (dest, buffer);
|
||||
return pinos_serialize_buffer_deserialize (dest, 0);
|
||||
}
|
||||
|
||||
size_t
|
||||
pinos_serialize_format_get_size (const SpaFormat *format)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ extern "C" {
|
|||
size_t pinos_serialize_buffer_get_size (const SpaBuffer *buffer);
|
||||
size_t pinos_serialize_buffer_serialize (void *dest, const SpaBuffer *buffer);
|
||||
SpaBuffer * pinos_serialize_buffer_deserialize (void *src, off_t offset);
|
||||
SpaBuffer * pinos_serialize_buffer_copy_into (void *dest, const SpaBuffer *buffer);
|
||||
|
||||
size_t pinos_serialize_format_get_size (const SpaFormat *format);
|
||||
size_t pinos_serialize_format_serialize (void *dest, const SpaFormat *format);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ typedef struct {
|
|||
int fd;
|
||||
uint32_t flags;
|
||||
void *ptr;
|
||||
off_t offset;
|
||||
size_t size;
|
||||
} MemId;
|
||||
|
||||
|
|
@ -453,20 +454,13 @@ on_rtsocket_condition (SpaSource *source,
|
|||
read (impl->rtfd, &cmd, 1);
|
||||
|
||||
if (cmd & PINOS_TRANSPORT_CMD_HAVE_DATA) {
|
||||
BufferId *bid;
|
||||
|
||||
for (i = 0; i < impl->trans->area->n_inputs; i++) {
|
||||
SpaPortInput *input = &impl->trans->inputs[i];
|
||||
|
||||
if (input->buffer_id == SPA_ID_INVALID)
|
||||
continue;
|
||||
|
||||
if ((bid = find_buffer (stream, input->buffer_id))) {
|
||||
for (i = 0; i < bid->buf->n_datas; i++) {
|
||||
bid->buf->datas[i].size = bid->datas[i].size;
|
||||
}
|
||||
pinos_signal_emit (&stream->new_buffer, stream, bid->id);
|
||||
}
|
||||
pinos_signal_emit (&stream->new_buffer, stream, input->buffer_id);
|
||||
input->buffer_id = SPA_ID_INVALID;
|
||||
}
|
||||
send_need_input (stream);
|
||||
|
|
@ -652,15 +646,18 @@ stream_dispatch_func (void *object,
|
|||
|
||||
m = find_mem (stream, p->mem_id);
|
||||
if (m) {
|
||||
pinos_log_debug ("update mem %u, fd %d, flags %d, size %zd", p->mem_id, p->memfd, p->flags, p->size);
|
||||
pinos_log_debug ("update mem %u, fd %d, flags %d, off %zd, size %zd",
|
||||
p->mem_id, p->memfd, p->flags, p->offset, p->size);
|
||||
} else {
|
||||
m = pinos_array_add (&impl->mem_ids, sizeof (MemId));
|
||||
pinos_log_debug ("add mem %u, fd %d, flags %d, size %zd", p->mem_id, p->memfd, p->flags, p->size);
|
||||
pinos_log_debug ("add mem %u, fd %d, flags %d, off %zd, size %zd",
|
||||
p->mem_id, p->memfd, p->flags, p->offset, p->size);
|
||||
}
|
||||
m->id = p->mem_id;
|
||||
m->fd = p->memfd;
|
||||
m->flags = p->flags;
|
||||
m->ptr = NULL;
|
||||
m->offset = p->offset;
|
||||
m->size = p->size;
|
||||
break;
|
||||
}
|
||||
|
|
@ -675,6 +672,8 @@ stream_dispatch_func (void *object,
|
|||
clear_buffers (stream);
|
||||
|
||||
for (i = 0; i < p->n_buffers; i++) {
|
||||
off_t offset = 0;
|
||||
|
||||
MemId *mid = find_mem (stream, p->buffers[i].mem_id);
|
||||
if (mid == NULL) {
|
||||
pinos_log_warn ("unknown memory id %u", mid->id);
|
||||
|
|
@ -682,41 +681,28 @@ stream_dispatch_func (void *object,
|
|||
}
|
||||
|
||||
if (mid->ptr == NULL) {
|
||||
mid->ptr = mmap (NULL, mid->size, PROT_READ | PROT_WRITE, MAP_SHARED, mid->fd, 0);
|
||||
//mid->ptr = mmap (NULL, mid->size, PROT_READ | PROT_WRITE, MAP_SHARED, mid->fd, mid->offset);
|
||||
mid->ptr = mmap (NULL, mid->size + mid->offset, PROT_READ | PROT_WRITE, MAP_SHARED, mid->fd, 0);
|
||||
if (mid->ptr == MAP_FAILED) {
|
||||
mid->ptr = NULL;
|
||||
pinos_log_warn ("Failed to mmap memory %zd %p: %s", mid->size, mid, strerror (errno));
|
||||
continue;
|
||||
}
|
||||
mid->ptr = SPA_MEMBER (mid->ptr, mid->offset, void);
|
||||
}
|
||||
len = pinos_array_get_len (&impl->buffer_ids, BufferId);
|
||||
bid = pinos_array_add (&impl->buffer_ids, sizeof (BufferId));
|
||||
|
||||
b = p->buffers[i].buffer;
|
||||
|
||||
bid->buf_ptr = SPA_MEMBER (mid->ptr, p->buffers[i].offset, void);
|
||||
{
|
||||
size_t size;
|
||||
unsigned int i;
|
||||
SpaMeta *m;
|
||||
|
||||
b = bid->buf_ptr;
|
||||
size = sizeof (SpaBuffer);
|
||||
m = SPA_MEMBER (b, SPA_PTR_TO_INT (b->metas), SpaMeta);
|
||||
for (i = 0; i < b->n_metas; i++)
|
||||
size += sizeof (SpaMeta) + m[i].size;
|
||||
for (i = 0; i < b->n_datas; i++)
|
||||
size += sizeof (SpaData);
|
||||
|
||||
size = pinos_serialize_buffer_get_size (p->buffers[i].buffer);
|
||||
b = bid->buf = malloc (size);
|
||||
memcpy (b, bid->buf_ptr, size);
|
||||
|
||||
if (b->metas)
|
||||
b->metas = SPA_MEMBER (b, SPA_PTR_TO_INT (b->metas), SpaMeta);
|
||||
if (b->datas) {
|
||||
bid->datas = SPA_MEMBER (bid->buf_ptr, SPA_PTR_TO_INT (b->datas), SpaData);
|
||||
b->datas = SPA_MEMBER (b, SPA_PTR_TO_INT (b->datas), SpaData);
|
||||
}
|
||||
pinos_serialize_buffer_copy_into (b, p->buffers[i].buffer);
|
||||
}
|
||||
|
||||
bid->id = b->id;
|
||||
|
||||
if (bid->id != len) {
|
||||
|
|
@ -727,13 +713,15 @@ stream_dispatch_func (void *object,
|
|||
|
||||
for (j = 0; j < b->n_metas; j++) {
|
||||
SpaMeta *m = &b->metas[j];
|
||||
if (m->data)
|
||||
m->data = SPA_MEMBER (bid->buf_ptr, SPA_PTR_TO_INT (m->data), void);
|
||||
m->data = SPA_MEMBER (bid->buf_ptr, offset, void);
|
||||
offset += m->size;
|
||||
}
|
||||
|
||||
for (j = 0; j < b->n_datas; j++) {
|
||||
SpaData *d = &b->datas[j];
|
||||
|
||||
d->chunk = SPA_MEMBER (bid->buf_ptr, offset + sizeof (SpaChunk) * j, SpaChunk);
|
||||
|
||||
switch (d->type) {
|
||||
case SPA_DATA_TYPE_ID:
|
||||
{
|
||||
|
|
@ -757,6 +745,8 @@ stream_dispatch_func (void *object,
|
|||
}
|
||||
}
|
||||
|
||||
spa_debug_buffer (b);
|
||||
|
||||
pinos_signal_emit (&stream->add_buffer, stream, bid->id);
|
||||
}
|
||||
|
||||
|
|
@ -1096,9 +1086,6 @@ pinos_stream_send_buffer (PinosStream *stream,
|
|||
uint8_t cmd = PINOS_TRANSPORT_CMD_HAVE_DATA;
|
||||
|
||||
bid->used = true;
|
||||
for (i = 0; i < bid->buf->n_datas; i++) {
|
||||
bid->datas[i].size = bid->buf->datas[i].size;
|
||||
}
|
||||
impl->trans->outputs[0].buffer_id = id;
|
||||
impl->trans->outputs[0].status = SPA_RESULT_OK;
|
||||
write (impl->rtfd, &cmd, 1);
|
||||
|
|
|
|||
|
|
@ -403,13 +403,13 @@ on_add_buffer (PinosListener *listener,
|
|||
case SPA_DATA_TYPE_DMABUF:
|
||||
{
|
||||
gmem = gst_fd_allocator_alloc (pinossink->allocator, dup (d->fd),
|
||||
d->maxsize, GST_FD_MEMORY_FLAG_NONE);
|
||||
gst_memory_resize (gmem, d->offset, d->size);
|
||||
d->size, GST_FD_MEMORY_FLAG_NONE);
|
||||
gst_memory_resize (gmem, d->chunk->offset, d->chunk->size);
|
||||
break;
|
||||
}
|
||||
case SPA_DATA_TYPE_MEMPTR:
|
||||
gmem = gst_memory_new_wrapped (0, d->data, d->maxsize, d->offset,
|
||||
d->size, NULL, NULL);
|
||||
gmem = gst_memory_new_wrapped (0, d->data, d->size, d->chunk->offset,
|
||||
d->chunk->size, NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -644,8 +644,8 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
|
|||
for (i = 0; i < data->buf->n_datas; i++) {
|
||||
SpaData *d = &data->buf->datas[i];
|
||||
GstMemory *mem = gst_buffer_peek_memory (buffer, i);
|
||||
d->offset = mem->offset;
|
||||
d->size = mem->size;
|
||||
d->chunk->offset = mem->offset;
|
||||
d->chunk->size = mem->size;
|
||||
}
|
||||
gst_buffer_ref (buffer);
|
||||
|
||||
|
|
|
|||
|
|
@ -417,13 +417,13 @@ on_add_buffer (PinosListener *listener,
|
|||
case SPA_DATA_TYPE_DMABUF:
|
||||
{
|
||||
gmem = gst_fd_allocator_alloc (pinossrc->fd_allocator, dup (d->fd),
|
||||
d->maxsize, GST_FD_MEMORY_FLAG_NONE);
|
||||
gst_memory_resize (gmem, d->offset, d->size);
|
||||
d->size, GST_FD_MEMORY_FLAG_NONE);
|
||||
gst_memory_resize (gmem, d->chunk->offset, d->chunk->size);
|
||||
break;
|
||||
}
|
||||
case SPA_DATA_TYPE_MEMPTR:
|
||||
gmem = gst_memory_new_wrapped (0, d->data, d->maxsize, d->offset,
|
||||
d->size, NULL, NULL);
|
||||
gmem = gst_memory_new_wrapped (0, d->data, d->size, d->chunk->offset,
|
||||
d->chunk->size, NULL, NULL);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -488,8 +488,8 @@ on_new_buffer (PinosListener *listener,
|
|||
for (i = 0; i < data->buf->n_datas; i++) {
|
||||
SpaData *d = &data->buf->datas[i];
|
||||
GstMemory *mem = gst_buffer_peek_memory (buf, i);
|
||||
mem->offset = d->offset;
|
||||
mem->size = d->size;
|
||||
mem->offset = d->chunk->offset;
|
||||
mem->size = d->chunk->size;
|
||||
}
|
||||
g_queue_push_tail (&pinossrc->queue, buf);
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ struct _ProxyBuffer {
|
|||
off_t offset;
|
||||
size_t size;
|
||||
bool outstanding;
|
||||
ProxyBuffer *next;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -610,9 +609,9 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
|
|||
unsigned int i, j;
|
||||
PinosMessageAddMem am;
|
||||
PinosMessageUseBuffers ub;
|
||||
size_t size, n_mem;
|
||||
PinosMessageMemRef *memref;
|
||||
void *p;
|
||||
size_t n_mem;
|
||||
PinosMessageBuffer *mb;
|
||||
SpaMetaShared *msh;
|
||||
|
||||
if (node == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
|
@ -630,19 +629,44 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
|
|||
|
||||
clear_buffers (this, port);
|
||||
|
||||
/* find size to store buffers */
|
||||
size = 0;
|
||||
if (n_buffers > 0) {
|
||||
mb = alloca (n_buffers * sizeof (PinosMessageBuffer));
|
||||
} else {
|
||||
mb = NULL;
|
||||
}
|
||||
|
||||
n_mem = 0;
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
ProxyBuffer *b = &port->buffers[i];
|
||||
|
||||
msh = spa_buffer_find_meta (buffers[i], SPA_META_TYPE_SHARED);
|
||||
if (msh == NULL) {
|
||||
spa_log_error (this->log, "missing shared metadata on buffer %d", i);
|
||||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
|
||||
b->outbuf = buffers[i];
|
||||
memcpy (&b->buffer, buffers[i], sizeof (SpaBuffer));
|
||||
b->buffer.datas = b->datas;
|
||||
b->buffer.metas = b->metas;
|
||||
|
||||
b->size = SPA_ROUND_UP_N (pinos_serialize_buffer_get_size (buffers[i]), 64);
|
||||
b->offset = size;
|
||||
am.direction = direction;
|
||||
am.port_id = port_id;
|
||||
am.mem_id = n_mem++;
|
||||
am.type = SPA_DATA_TYPE_MEMFD;
|
||||
am.memfd = msh->fd;
|
||||
am.flags = msh->flags;
|
||||
am.offset = msh->offset;
|
||||
am.size = msh->size;
|
||||
pinos_resource_send_message (this->resource,
|
||||
PINOS_MESSAGE_ADD_MEM,
|
||||
&am,
|
||||
false);
|
||||
|
||||
mb[i].buffer = &b->buffer;
|
||||
mb[i].mem_id = am.mem_id;
|
||||
mb[i].offset = 0;
|
||||
mb[i].size = am.size;
|
||||
|
||||
for (j = 0; j < buffers[i]->n_metas; j++) {
|
||||
memcpy (&b->buffer.metas[j], &buffers[i]->metas[j], sizeof (SpaMeta));
|
||||
|
|
@ -663,7 +687,7 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
|
|||
am.memfd = d->fd;
|
||||
am.flags = d->flags;
|
||||
am.offset = d->offset;
|
||||
am.size = d->maxsize;
|
||||
am.size = d->size;
|
||||
pinos_resource_send_message (this->resource,
|
||||
PINOS_MESSAGE_ADD_MEM,
|
||||
&am,
|
||||
|
|
@ -683,78 +707,20 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
|
|||
break;
|
||||
}
|
||||
}
|
||||
size += b->size;
|
||||
}
|
||||
|
||||
if (n_buffers > 0) {
|
||||
/* make mem for the buffers */
|
||||
port->buffer_mem_id = n_mem++;
|
||||
if (pinos_memblock_alloc (PINOS_MEMBLOCK_FLAG_WITH_FD |
|
||||
PINOS_MEMBLOCK_FLAG_MAP_READWRITE |
|
||||
PINOS_MEMBLOCK_FLAG_SEAL,
|
||||
size,
|
||||
&port->buffer_mem) < 0) {
|
||||
spa_log_error (this->log, "Failed to allocate buffer memory");
|
||||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
p = port->buffer_mem.ptr;
|
||||
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
ProxyBuffer *b = &port->buffers[i];
|
||||
SpaBuffer *sb;
|
||||
SpaMeta *sbm;
|
||||
SpaData *sbd;
|
||||
|
||||
pinos_serialize_buffer_serialize (p, &b->buffer);
|
||||
|
||||
sb = p;
|
||||
b->buffer.datas = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->datas), SpaData);
|
||||
sbm = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->metas), SpaMeta);
|
||||
sbd = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->datas), SpaData);
|
||||
|
||||
for (j = 0; j < b->buffer.n_metas; j++)
|
||||
b->metas[j].data = SPA_MEMBER (sb, SPA_PTR_TO_INT (sbm[j].data), void);
|
||||
|
||||
for (j = 0; j < b->buffer.n_datas; j++) {
|
||||
if (b->datas[j].type == SPA_DATA_TYPE_MEMPTR)
|
||||
b->datas[j].data = SPA_MEMBER (sb, SPA_PTR_TO_INT (sbd[j].data), void);
|
||||
}
|
||||
p += b->size;
|
||||
}
|
||||
|
||||
am.direction = direction;
|
||||
am.port_id = port_id;
|
||||
am.mem_id = port->buffer_mem_id;
|
||||
am.type = SPA_DATA_TYPE_MEMFD;
|
||||
am.memfd = port->buffer_mem.fd;
|
||||
am.flags = 0;
|
||||
am.offset = 0;
|
||||
am.size = size;
|
||||
pinos_resource_send_message (this->resource,
|
||||
PINOS_MESSAGE_ADD_MEM,
|
||||
&am,
|
||||
false);
|
||||
|
||||
memref = alloca (n_buffers * sizeof (PinosMessageMemRef));
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
memref[i].mem_id = port->buffer_mem_id;
|
||||
memref[i].offset = port->buffers[i].offset;
|
||||
memref[i].size = port->buffers[i].size;
|
||||
}
|
||||
} else {
|
||||
memref = NULL;
|
||||
}
|
||||
port->n_buffers = n_buffers;
|
||||
|
||||
ub.seq = this->seq++;
|
||||
ub.direction = direction;
|
||||
ub.port_id = port_id;
|
||||
ub.n_buffers = n_buffers;
|
||||
ub.buffers = memref;
|
||||
ub.buffers = mb;
|
||||
pinos_resource_send_message (this->resource,
|
||||
PINOS_MESSAGE_USE_BUFFERS,
|
||||
&ub,
|
||||
true);
|
||||
|
||||
return SPA_RESULT_RETURN_ASYNC (ub.seq);
|
||||
}
|
||||
|
||||
|
|
@ -789,6 +755,7 @@ spa_proxy_node_port_alloc_buffers (SpaNode *node,
|
|||
static void
|
||||
copy_meta_in (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
|
||||
{
|
||||
#if 0
|
||||
ProxyBuffer *b = &port->buffers[buffer_id];
|
||||
unsigned int i;
|
||||
|
||||
|
|
@ -804,11 +771,13 @@ copy_meta_in (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
|
|||
memcpy (b->outbuf->datas[i].data, b->datas[i].data, b->buffer.datas[i].size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
copy_meta_out (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
|
||||
{
|
||||
#if 0
|
||||
ProxyBuffer *b = &port->buffers[buffer_id];
|
||||
unsigned int i;
|
||||
|
||||
|
|
@ -824,6 +793,7 @@ copy_meta_out (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
|
|||
memcpy (b->datas[i].data, b->outbuf->datas[i].data, b->outbuf->datas[i].size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
|
|
|
|||
|
|
@ -201,6 +201,145 @@ find_meta_enable (const SpaPortInfo *info, SpaMetaType type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static SpaBuffer **
|
||||
alloc_buffers (PinosLink *this,
|
||||
unsigned int n_buffers,
|
||||
unsigned int n_params,
|
||||
SpaAllocParam **params,
|
||||
unsigned int n_datas,
|
||||
size_t *data_sizes,
|
||||
ssize_t *data_strides,
|
||||
PinosMemblock *mem)
|
||||
{
|
||||
SpaBuffer **buffers, *bp;
|
||||
unsigned int i;
|
||||
size_t skel_size, data_size, meta_size;
|
||||
SpaChunk *cdp;
|
||||
void *ddp;
|
||||
unsigned int n_metas;
|
||||
SpaMeta *metas;
|
||||
|
||||
n_metas = data_size = meta_size = 0;
|
||||
|
||||
/* each buffer */
|
||||
skel_size = sizeof (SpaBuffer);
|
||||
|
||||
metas = alloca (sizeof (SpaMeta) * n_params + 1);
|
||||
|
||||
/* add shared metadata */
|
||||
metas[n_metas].type = SPA_META_TYPE_SHARED;
|
||||
metas[n_metas].size = spa_meta_type_get_size (SPA_META_TYPE_SHARED);
|
||||
meta_size += metas[n_metas].size;
|
||||
n_metas++;
|
||||
skel_size += sizeof (SpaMeta);
|
||||
|
||||
/* collect metadata */
|
||||
for (i = 0; i < n_params; i++) {
|
||||
SpaAllocParam *ap = params[i];
|
||||
|
||||
if (ap->type == SPA_ALLOC_PARAM_TYPE_META_ENABLE) {
|
||||
SpaAllocParamMetaEnable *pme = (SpaAllocParamMetaEnable *) ap;
|
||||
|
||||
metas[n_metas].type = pme->type;
|
||||
metas[n_metas].size = spa_meta_type_get_size (pme->type);
|
||||
meta_size += metas[n_metas].size;
|
||||
n_metas++;
|
||||
skel_size += sizeof (SpaMeta);
|
||||
}
|
||||
}
|
||||
data_size += meta_size;
|
||||
|
||||
/* data */
|
||||
for (i = 0; i < n_datas; i++) {
|
||||
data_size += sizeof (SpaChunk);
|
||||
data_size += data_sizes[i];
|
||||
skel_size += sizeof (SpaData);
|
||||
}
|
||||
|
||||
buffers = calloc (n_buffers, skel_size + sizeof (SpaBuffer *));
|
||||
/* pointer to buffer structures */
|
||||
bp = SPA_MEMBER (buffers, n_buffers * sizeof (SpaBuffer *), SpaBuffer);
|
||||
|
||||
pinos_memblock_alloc (PINOS_MEMBLOCK_FLAG_WITH_FD |
|
||||
PINOS_MEMBLOCK_FLAG_MAP_READWRITE |
|
||||
PINOS_MEMBLOCK_FLAG_SEAL,
|
||||
n_buffers * data_size,
|
||||
mem);
|
||||
|
||||
|
||||
for (i = 0; i < n_buffers; i++) {
|
||||
int j;
|
||||
SpaBuffer *b;
|
||||
void *p;
|
||||
|
||||
buffers[i] = b = SPA_MEMBER (bp, skel_size * i, SpaBuffer);
|
||||
|
||||
p = SPA_MEMBER (mem->ptr, data_size * i, void);
|
||||
|
||||
b->id = i;
|
||||
b->n_metas = n_metas;
|
||||
b->metas = SPA_MEMBER (b, sizeof (SpaBuffer), SpaMeta);
|
||||
for (j = 0; j < n_metas; j++) {
|
||||
SpaMeta *m = &b->metas[j];
|
||||
|
||||
m->type = metas[j].type;
|
||||
m->data = p;
|
||||
m->size = metas[j].size;
|
||||
|
||||
switch (m->type) {
|
||||
case SPA_META_TYPE_SHARED:
|
||||
{
|
||||
SpaMetaShared *msh = p;
|
||||
|
||||
msh->type = SPA_DATA_TYPE_MEMFD;
|
||||
msh->flags = 0;
|
||||
msh->fd = mem->fd;
|
||||
msh->offset = data_size * i;
|
||||
msh->size = data_size;
|
||||
break;
|
||||
}
|
||||
case SPA_META_TYPE_RINGBUFFER:
|
||||
{
|
||||
SpaMetaRingbuffer *rb = p;
|
||||
spa_ringbuffer_init (&rb->ringbuffer, data_sizes[0]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
p += m->size;
|
||||
}
|
||||
/* pointer to data structure */
|
||||
b->n_datas = n_datas;
|
||||
b->datas = SPA_MEMBER (b->metas, n_metas * sizeof (SpaMeta), SpaData);
|
||||
|
||||
cdp = p;
|
||||
ddp = SPA_MEMBER (cdp, sizeof (SpaChunk) * n_datas, void);
|
||||
|
||||
for (j = 0; j < n_datas; j++) {
|
||||
SpaData *d = &b->datas[j];
|
||||
|
||||
d->chunk = &cdp[j];
|
||||
if (data_sizes[j] > 0) {
|
||||
d->type = SPA_DATA_TYPE_MEMFD;
|
||||
d->flags = 0;
|
||||
d->fd = mem->fd;
|
||||
d->offset = 0;
|
||||
d->size = mem->size;
|
||||
d->data = mem->ptr;
|
||||
d->chunk->offset = SPA_PTRDIFF (ddp, d->data);
|
||||
d->chunk->size = data_sizes[j];
|
||||
d->chunk->stride = data_strides[j];
|
||||
ddp += data_sizes[j];
|
||||
} else {
|
||||
d->type = SPA_DATA_TYPE_INVALID;
|
||||
d->data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buffers;
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
||||
{
|
||||
|
|
@ -317,98 +456,21 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
|
|||
impl->allocated = false;
|
||||
pinos_log_debug ("reusing %d output buffers %p", impl->n_buffers, impl->buffers);
|
||||
} else {
|
||||
unsigned int i, j;
|
||||
size_t hdr_size, buf_size, arr_size;
|
||||
void *p;
|
||||
unsigned int n_metas, n_datas;
|
||||
size_t data_sizes[1];
|
||||
ssize_t data_strides[1];
|
||||
|
||||
n_metas = 0;
|
||||
n_datas = 1;
|
||||
|
||||
hdr_size = sizeof (SpaBuffer);
|
||||
hdr_size += n_datas * sizeof (SpaData);
|
||||
for (i = 0; i < oinfo->n_params; i++) {
|
||||
SpaAllocParam *ap = oinfo->params[i];
|
||||
|
||||
if (ap->type == SPA_ALLOC_PARAM_TYPE_META_ENABLE) {
|
||||
SpaAllocParamMetaEnable *pme = (SpaAllocParamMetaEnable *) ap;
|
||||
|
||||
hdr_size += spa_meta_type_get_size (pme->type);
|
||||
n_metas++;
|
||||
}
|
||||
}
|
||||
hdr_size += n_metas * sizeof (SpaMeta);
|
||||
|
||||
buf_size = SPA_ROUND_UP_N (hdr_size + (minsize * blocks), 64);
|
||||
data_sizes[0] = minsize;
|
||||
data_strides[0] = stride;
|
||||
|
||||
impl->n_buffers = max_buffers;
|
||||
pinos_memblock_alloc (PINOS_MEMBLOCK_FLAG_WITH_FD |
|
||||
PINOS_MEMBLOCK_FLAG_MAP_READWRITE |
|
||||
PINOS_MEMBLOCK_FLAG_SEAL,
|
||||
impl->n_buffers * (sizeof (SpaBuffer*) + buf_size),
|
||||
&impl->buffer_mem);
|
||||
|
||||
arr_size = impl->n_buffers * sizeof (SpaBuffer*);
|
||||
impl->buffers = p = impl->buffer_mem.ptr;
|
||||
p = SPA_MEMBER (p, arr_size, void);
|
||||
|
||||
for (i = 0; i < impl->n_buffers; i++) {
|
||||
SpaBuffer *b;
|
||||
SpaData *d;
|
||||
void *pd;
|
||||
unsigned int mi;
|
||||
|
||||
b = impl->buffers[i] = SPA_MEMBER (p, buf_size * i, SpaBuffer);
|
||||
|
||||
b->id = i;
|
||||
b->n_metas = n_metas;
|
||||
b->metas = SPA_MEMBER (b, sizeof (SpaBuffer), SpaMeta);
|
||||
b->n_datas = n_datas;
|
||||
b->datas = SPA_MEMBER (b->metas, sizeof (SpaMeta) * n_metas, SpaData);
|
||||
pd = SPA_MEMBER (b->datas, sizeof (SpaData) * n_datas, void);
|
||||
|
||||
for (j = 0, mi = 0; j < oinfo->n_params; j++) {
|
||||
SpaAllocParam *ap = oinfo->params[j];
|
||||
|
||||
if (ap->type == SPA_ALLOC_PARAM_TYPE_META_ENABLE) {
|
||||
SpaAllocParamMetaEnable *pme = (SpaAllocParamMetaEnable *) ap;
|
||||
|
||||
b->metas[mi].type = pme->type;
|
||||
b->metas[mi].data = pd;
|
||||
b->metas[mi].size = spa_meta_type_get_size (pme->type);
|
||||
|
||||
switch (pme->type) {
|
||||
case SPA_META_TYPE_RINGBUFFER:
|
||||
{
|
||||
SpaMetaRingbuffer *rb = pd;
|
||||
spa_ringbuffer_init (&rb->ringbuffer, minsize);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pd = SPA_MEMBER (pd, b->metas[mi].size, void);
|
||||
mi++;
|
||||
}
|
||||
}
|
||||
|
||||
d = &b->datas[0];
|
||||
if (minsize > 0) {
|
||||
d->type = SPA_DATA_TYPE_MEMFD;
|
||||
d->flags = 0;
|
||||
d->data = impl->buffer_mem.ptr;
|
||||
d->fd = impl->buffer_mem.fd;
|
||||
d->maxsize = impl->buffer_mem.size;
|
||||
d->offset = arr_size + hdr_size + (buf_size * i);
|
||||
d->size = minsize;
|
||||
d->stride = stride;
|
||||
} else {
|
||||
d->type = SPA_DATA_TYPE_INVALID;
|
||||
d->data = NULL;
|
||||
}
|
||||
}
|
||||
pinos_log_debug ("allocated %d buffers %p %zd", impl->n_buffers, impl->buffers, minsize);
|
||||
impl->allocated = true;
|
||||
impl->buffers = alloc_buffers (this,
|
||||
impl->n_buffers,
|
||||
oinfo->n_params,
|
||||
oinfo->params,
|
||||
1,
|
||||
data_sizes,
|
||||
data_strides,
|
||||
&impl->buffer_mem);
|
||||
}
|
||||
|
||||
if (out_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue