mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-01-11 11:08:42 -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue