mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-16 08:56:45 -05:00
alloc: improve alignment in alloactor
link: use buffer allocator Add more tests
This commit is contained in:
parent
30ecf66561
commit
93e8074b2c
5 changed files with 89 additions and 103 deletions
|
|
@ -41,10 +41,12 @@ struct spa_buffer_alloc_info {
|
||||||
uint32_t n_datas;
|
uint32_t n_datas;
|
||||||
struct spa_data *datas;
|
struct spa_data *datas;
|
||||||
uint32_t *data_aligns;
|
uint32_t *data_aligns;
|
||||||
|
uint32_t max_align; /**< max of all alignments */
|
||||||
size_t skel_size; /**< size of the struct spa_buffer and inlined meta/chunk/data */
|
size_t skel_size; /**< size of the struct spa_buffer and inlined meta/chunk/data */
|
||||||
size_t meta_size; /**< size of the meta if not inlined */
|
size_t meta_size; /**< size of the meta if not inlined */
|
||||||
size_t chunk_size; /**< size of the chunk if not inlined */
|
size_t chunk_size; /**< size of the chunk if not inlined */
|
||||||
size_t data_size; /**< size of the data if not inlined */
|
size_t data_size; /**< size of the data if not inlined */
|
||||||
|
size_t mem_size; /**< size of the total memory if not inlined */
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
||||||
|
|
@ -60,6 +62,8 @@ static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
||||||
info->n_datas = n_datas;
|
info->n_datas = n_datas;
|
||||||
info->datas = datas;
|
info->datas = datas;
|
||||||
info->data_aligns = data_aligns;
|
info->data_aligns = data_aligns;
|
||||||
|
info->max_align = 16;
|
||||||
|
info->mem_size = 0;
|
||||||
|
|
||||||
info->skel_size = sizeof(struct spa_buffer);
|
info->skel_size = sizeof(struct spa_buffer);
|
||||||
info->skel_size += n_metas * sizeof(struct spa_meta);
|
info->skel_size += n_metas * sizeof(struct spa_meta);
|
||||||
|
|
@ -71,12 +75,17 @@ static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
||||||
|
|
||||||
if (SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_META))
|
if (SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_META))
|
||||||
info->skel_size += info->meta_size;
|
info->skel_size += info->meta_size;
|
||||||
|
else
|
||||||
|
info->mem_size += info->meta_size;
|
||||||
|
|
||||||
info->chunk_size = n_datas * sizeof(struct spa_chunk);
|
info->chunk_size = n_datas * sizeof(struct spa_chunk);
|
||||||
if (SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_CHUNK))
|
if (SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_CHUNK))
|
||||||
info->skel_size += info->chunk_size;
|
info->skel_size += info->chunk_size;
|
||||||
|
else
|
||||||
|
info->mem_size += info->chunk_size;
|
||||||
|
|
||||||
for (i = 0, size = 0; i < n_datas; i++) {
|
for (i = 0, size = 0; i < n_datas; i++) {
|
||||||
|
info->max_align = SPA_MAX(info->max_align, data_aligns[i]);
|
||||||
size = SPA_ROUND_UP_N(size, data_aligns[i]);
|
size = SPA_ROUND_UP_N(size, data_aligns[i]);
|
||||||
size += datas[i].maxsize;
|
size += datas[i].maxsize;
|
||||||
}
|
}
|
||||||
|
|
@ -84,10 +93,15 @@ static inline int spa_buffer_alloc_fill_info(struct spa_buffer_alloc_info *info,
|
||||||
|
|
||||||
if (!SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_NO_DATA) &&
|
if (!SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_NO_DATA) &&
|
||||||
SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_DATA)) {
|
SPA_FLAG_CHECK(info->flags, SPA_BUFFER_ALLOC_FLAG_INLINE_DATA)) {
|
||||||
info->skel_size += n_datas ? data_aligns[0] - 1 : 0;
|
info->skel_size = SPA_ROUND_UP_N(info->skel_size, n_datas ? data_aligns[0] : 1);
|
||||||
info->skel_size += info->data_size;
|
info->skel_size += info->data_size;
|
||||||
|
info->skel_size = SPA_ROUND_UP_N(info->skel_size, info->max_align);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
info->mem_size = SPA_ROUND_UP_N(info->mem_size, n_datas ? data_aligns[0] : 1);
|
||||||
|
info->mem_size += info->data_size;
|
||||||
|
info->mem_size = SPA_ROUND_UP_N(info->mem_size, info->max_align);
|
||||||
}
|
}
|
||||||
info->skel_size = SPA_ROUND_UP_N(info->skel_size, 8);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -157,11 +171,10 @@ spa_buffer_alloc_layout_array(struct spa_buffer_alloc_info *info,
|
||||||
void *skel_mem, void *data_mem)
|
void *skel_mem, void *data_mem)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
size_t data_size = info->data_size + info->meta_size + info->chunk_size;
|
|
||||||
for (i = 0; i < n_buffers; i++) {
|
for (i = 0; i < n_buffers; i++) {
|
||||||
buffers[i] = spa_buffer_alloc_layout(info, skel_mem, data_mem);
|
buffers[i] = spa_buffer_alloc_layout(info, skel_mem, data_mem);
|
||||||
skel_mem = SPA_MEMBER(skel_mem, info->skel_size, void);
|
skel_mem = SPA_MEMBER(skel_mem, info->skel_size, void);
|
||||||
data_mem = SPA_MEMBER(data_mem, data_size, void);
|
data_mem = SPA_MEMBER(data_mem, info->mem_size, void);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -179,9 +192,11 @@ spa_buffer_alloc_array(uint32_t n_buffers, uint32_t flags,
|
||||||
|
|
||||||
spa_buffer_alloc_fill_info(&info, n_metas, metas, n_datas, datas, data_aligns);
|
spa_buffer_alloc_fill_info(&info, n_metas, metas, n_datas, datas, data_aligns);
|
||||||
|
|
||||||
buffers = (struct spa_buffer **)calloc(n_buffers, sizeof(struct spa_buffer *) + info.skel_size);
|
buffers = (struct spa_buffer **)calloc(1, info.max_align +
|
||||||
|
n_buffers * (sizeof(struct spa_buffer *) + info.skel_size));
|
||||||
|
|
||||||
skel = SPA_MEMBER(buffers, sizeof(struct spa_buffer *) * n_buffers, void);
|
skel = SPA_MEMBER(buffers, sizeof(struct spa_buffer *) * n_buffers, void);
|
||||||
|
skel = SPA_PTR_ALIGN(skel, info.max_align, void);
|
||||||
|
|
||||||
spa_buffer_alloc_layout_array(&info, n_buffers, buffers, skel, NULL);
|
spa_buffer_alloc_layout_array(&info, n_buffers, buffers, skel, NULL);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,9 @@ static void test_alloc(void)
|
||||||
{
|
{
|
||||||
struct spa_buffer **buffers;
|
struct spa_buffer **buffers;
|
||||||
struct spa_meta metas[4];
|
struct spa_meta metas[4];
|
||||||
struct spa_data datas[4];
|
struct spa_data datas[2];
|
||||||
uint32_t aligns[4];
|
uint32_t aligns[2];
|
||||||
int i, j;
|
uint32_t i, j;
|
||||||
|
|
||||||
metas[0].type = SPA_META_Header;
|
metas[0].type = SPA_META_Header;
|
||||||
metas[0].size = sizeof(struct spa_meta_header);
|
metas[0].size = sizeof(struct spa_meta_header);
|
||||||
|
|
@ -72,28 +72,40 @@ static void test_alloc(void)
|
||||||
sizeof(struct spa_meta_bitmap) + w * h * bpp)
|
sizeof(struct spa_meta_bitmap) + w * h * bpp)
|
||||||
metas[2].type = SPA_META_Cursor;
|
metas[2].type = SPA_META_Cursor;
|
||||||
metas[2].size = CURSOR_META_SIZE(64,64,4);
|
metas[2].size = CURSOR_META_SIZE(64,64,4);
|
||||||
|
metas[3].type = 101;
|
||||||
|
metas[3].size = 11;
|
||||||
|
|
||||||
datas[0].maxsize = 4096;
|
datas[0].maxsize = 4000;
|
||||||
datas[1].maxsize = 2048;
|
datas[1].maxsize = 2011;
|
||||||
|
|
||||||
aligns[0] = 16;
|
aligns[0] = 32;
|
||||||
aligns[1] = 16;
|
aligns[1] = 16;
|
||||||
|
|
||||||
buffers = spa_buffer_alloc_array(16, 0, 3, metas, 2, datas, aligns);
|
buffers = spa_buffer_alloc_array(16, 0,
|
||||||
|
SPA_N_ELEMENTS(metas), metas,
|
||||||
|
SPA_N_ELEMENTS(datas), datas, aligns);
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
fprintf(stderr, "buffers %p\n", buffers);
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
struct spa_buffer *b = buffers[i];
|
struct spa_buffer *b = buffers[i];
|
||||||
|
fprintf(stderr, "buffer %d %p\n", i, b);
|
||||||
|
|
||||||
spa_assert(b->n_metas == 3);
|
spa_assert(b->n_metas == SPA_N_ELEMENTS(metas));
|
||||||
spa_assert(b->n_datas == 2);
|
spa_assert(b->n_datas == SPA_N_ELEMENTS(datas));
|
||||||
|
|
||||||
for (j = 0; j < 3; j++) {
|
for (j = 0; j < SPA_N_ELEMENTS(metas); j++) {
|
||||||
spa_assert(b->metas[j].type == metas[j].type);
|
spa_assert(b->metas[j].type == metas[j].type);
|
||||||
spa_assert(b->metas[j].size == metas[j].size);
|
spa_assert(b->metas[j].size == metas[j].size);
|
||||||
|
fprintf(stderr, " meta %d %p\n", j, b->metas[j].data);
|
||||||
|
spa_assert(SPA_IS_ALIGNED(b->metas[j].data, 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < 2; j++) {
|
for (j = 0; j < SPA_N_ELEMENTS(datas); j++) {
|
||||||
spa_assert(b->datas[j].maxsize == datas[j].maxsize);
|
spa_assert(b->datas[j].maxsize == datas[j].maxsize);
|
||||||
|
fprintf(stderr, " data %d %p %p\n", j, b->datas[j].chunk, b->datas[j].data);
|
||||||
|
spa_assert(SPA_IS_ALIGNED(b->datas[j].chunk, 8));
|
||||||
|
spa_assert(SPA_IS_ALIGNED(b->datas[j].data, aligns[j]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(buffers);
|
free(buffers);
|
||||||
|
|
|
||||||
|
|
@ -817,7 +817,7 @@ do_port_use_buffers(struct impl *impl,
|
||||||
struct buffer *b = &mix->buffers[i];
|
struct buffer *b = &mix->buffers[i];
|
||||||
struct pw_memblock *mem;
|
struct pw_memblock *mem;
|
||||||
struct mem *m;
|
struct mem *m;
|
||||||
size_t data_size, size;
|
size_t data_size;
|
||||||
void *baseptr;
|
void *baseptr;
|
||||||
|
|
||||||
b->outbuf = buffers[i];
|
b->outbuf = buffers[i];
|
||||||
|
|
@ -835,13 +835,12 @@ do_port_use_buffers(struct impl *impl,
|
||||||
if ((mem = pw_memblock_find(baseptr)) == NULL)
|
if ((mem = pw_memblock_find(baseptr)) == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
data_size = 0;
|
data_size = buffers[i]->n_datas * sizeof(struct spa_chunk);
|
||||||
for (j = 0; j < buffers[i]->n_metas; j++) {
|
for (j = 0; j < buffers[i]->n_metas; j++) {
|
||||||
data_size += SPA_ROUND_UP_N(buffers[i]->metas[j].size, 8);
|
data_size += SPA_ROUND_UP_N(buffers[i]->metas[j].size, 8);
|
||||||
}
|
}
|
||||||
for (j = 0; j < buffers[i]->n_datas; j++) {
|
for (j = 0; j < buffers[i]->n_datas; j++) {
|
||||||
struct spa_data *d = buffers[i]->datas;
|
struct spa_data *d = buffers[i]->datas;
|
||||||
data_size += sizeof(struct spa_chunk);
|
|
||||||
if (d->type == SPA_DATA_MemPtr)
|
if (d->type == SPA_DATA_MemPtr)
|
||||||
data_size += d->maxsize;
|
data_size += d->maxsize;
|
||||||
}
|
}
|
||||||
|
|
@ -853,12 +852,13 @@ do_port_use_buffers(struct impl *impl,
|
||||||
mb[i].mem_id = b->memid;
|
mb[i].mem_id = b->memid;
|
||||||
mb[i].offset = SPA_PTRDIFF(baseptr, SPA_MEMBER(mem->ptr, mem->offset, void));
|
mb[i].offset = SPA_PTRDIFF(baseptr, SPA_MEMBER(mem->ptr, mem->offset, void));
|
||||||
mb[i].size = data_size;
|
mb[i].size = data_size;
|
||||||
|
spa_log_debug(this->log, "buffer %d %d %d %d", i, mb[i].mem_id,
|
||||||
|
mb[i].offset, mb[i].size);
|
||||||
|
|
||||||
for (j = 0; j < buffers[i]->n_metas; j++)
|
for (j = 0; j < buffers[i]->n_metas; j++)
|
||||||
memcpy(&b->buffer.metas[j], &buffers[i]->metas[j], sizeof(struct spa_meta));
|
memcpy(&b->buffer.metas[j], &buffers[i]->metas[j], sizeof(struct spa_meta));
|
||||||
b->buffer.n_metas = j;
|
b->buffer.n_metas = j;
|
||||||
|
|
||||||
size = buffers[i]->n_datas * sizeof(struct spa_chunk);
|
|
||||||
for (j = 0; j < buffers[i]->n_datas; j++) {
|
for (j = 0; j < buffers[i]->n_datas; j++) {
|
||||||
struct spa_data *d = &buffers[i]->datas[j];
|
struct spa_data *d = &buffers[i]->datas[j];
|
||||||
|
|
||||||
|
|
@ -869,8 +869,8 @@ do_port_use_buffers(struct impl *impl,
|
||||||
m = ensure_mem(impl, d->fd, d->type, d->flags);
|
m = ensure_mem(impl, d->fd, d->type, d->flags);
|
||||||
b->buffer.datas[j].data = SPA_UINT32_TO_PTR(m->id);
|
b->buffer.datas[j].data = SPA_UINT32_TO_PTR(m->id);
|
||||||
} else if (d->type == SPA_DATA_MemPtr) {
|
} else if (d->type == SPA_DATA_MemPtr) {
|
||||||
b->buffer.datas[j].data = SPA_INT_TO_PTR(size);
|
spa_log_debug(this->log, "mem %d %zd", j, SPA_PTRDIFF(d->data, baseptr));
|
||||||
size += d->maxsize;
|
b->buffer.datas[j].data = SPA_INT_TO_PTR(SPA_PTRDIFF(d->data, baseptr));
|
||||||
} else {
|
} else {
|
||||||
b->buffer.datas[j].type = SPA_ID_INVALID;
|
b->buffer.datas[j].type = SPA_ID_INVALID;
|
||||||
b->buffer.datas[j].data = NULL;
|
b->buffer.datas[j].data = NULL;
|
||||||
|
|
|
||||||
|
|
@ -543,7 +543,7 @@ static int negotiate_buffers(struct impl *impl)
|
||||||
int res, i;
|
int res, i;
|
||||||
bool in_alloc, out_alloc;
|
bool in_alloc, out_alloc;
|
||||||
int32_t size, buffers, blocks, align, flags;
|
int32_t size, buffers, blocks, align, flags;
|
||||||
uint32_t *aligns, data_size;
|
uint32_t *aligns;
|
||||||
struct spa_data *datas;
|
struct spa_data *datas;
|
||||||
const struct spa_port_info *in_info, *out_info;
|
const struct spa_port_info *in_info, *out_info;
|
||||||
struct spa_buffer_alloc_info info = { 0, };
|
struct spa_buffer_alloc_info info = { 0, };
|
||||||
|
|
@ -622,7 +622,6 @@ static int negotiate_buffers(struct impl *impl)
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_buffer_alloc_fill_info(&info, 0, NULL, blocks, datas, aligns);
|
spa_buffer_alloc_fill_info(&info, 0, NULL, blocks, datas, aligns);
|
||||||
info.skel_size = SPA_ROUND_UP_N(info.skel_size, 16);
|
|
||||||
|
|
||||||
free(impl->buffers);
|
free(impl->buffers);
|
||||||
impl->buffers = calloc(buffers, sizeof(struct spa_buffer *) + info.skel_size);
|
impl->buffers = calloc(buffers, sizeof(struct spa_buffer *) + info.skel_size);
|
||||||
|
|
@ -630,7 +629,6 @@ static int negotiate_buffers(struct impl *impl)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
skel = SPA_MEMBER(impl->buffers, sizeof(struct spa_buffer *) * buffers, void);
|
skel = SPA_MEMBER(impl->buffers, sizeof(struct spa_buffer *) * buffers, void);
|
||||||
data_size = info.meta_size + info.chunk_size + info.data_size;
|
|
||||||
|
|
||||||
if (impl->mem) {
|
if (impl->mem) {
|
||||||
pw_memblock_free(impl->mem);
|
pw_memblock_free(impl->mem);
|
||||||
|
|
@ -639,7 +637,7 @@ static int negotiate_buffers(struct impl *impl)
|
||||||
|
|
||||||
if ((res = pw_memblock_alloc(PW_MEMBLOCK_FLAG_WITH_FD |
|
if ((res = pw_memblock_alloc(PW_MEMBLOCK_FLAG_WITH_FD |
|
||||||
PW_MEMBLOCK_FLAG_MAP_READWRITE |
|
PW_MEMBLOCK_FLAG_MAP_READWRITE |
|
||||||
PW_MEMBLOCK_FLAG_SEAL, buffers * data_size,
|
PW_MEMBLOCK_FLAG_SEAL, buffers * info.mem_size,
|
||||||
&impl->mem)) < 0)
|
&impl->mem)) < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include <spa/pod/parser.h>
|
#include <spa/pod/parser.h>
|
||||||
#include <spa/pod/compare.h>
|
#include <spa/pod/compare.h>
|
||||||
#include <spa/param/param.h>
|
#include <spa/param/param.h>
|
||||||
|
#include <spa/buffer/alloc.h>
|
||||||
|
|
||||||
#include "pipewire/private.h"
|
#include "pipewire/private.h"
|
||||||
#include "pipewire/interfaces.h"
|
#include "pipewire/interfaces.h"
|
||||||
|
|
@ -417,26 +418,24 @@ static int alloc_buffers(struct pw_link *this,
|
||||||
uint32_t n_params,
|
uint32_t n_params,
|
||||||
struct spa_pod **params,
|
struct spa_pod **params,
|
||||||
uint32_t n_datas,
|
uint32_t n_datas,
|
||||||
size_t *data_sizes,
|
uint32_t *data_sizes,
|
||||||
ssize_t *data_strides,
|
int32_t *data_strides,
|
||||||
size_t *data_aligns,
|
uint32_t *data_aligns,
|
||||||
struct allocation *allocation)
|
struct allocation *allocation)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
struct spa_buffer **buffers, *bp;
|
struct spa_buffer **buffers, *bp;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
size_t skel_size, data_size, meta_size;
|
|
||||||
struct spa_chunk *cdp;
|
|
||||||
void *ddp;
|
|
||||||
uint32_t n_metas;
|
uint32_t n_metas;
|
||||||
struct spa_meta *metas;
|
struct spa_meta *metas;
|
||||||
|
struct spa_data *datas;
|
||||||
struct pw_memblock *m;
|
struct pw_memblock *m;
|
||||||
|
struct spa_buffer_alloc_info info = { 0, };
|
||||||
|
|
||||||
n_metas = data_size = meta_size = 0;
|
n_metas = 0;
|
||||||
|
|
||||||
skel_size = sizeof(struct spa_buffer);
|
|
||||||
|
|
||||||
metas = alloca(sizeof(struct spa_meta) * n_params);
|
metas = alloca(sizeof(struct spa_meta) * n_params);
|
||||||
|
datas = alloca(sizeof(struct spa_data) * n_datas);
|
||||||
|
|
||||||
/* collect metadata */
|
/* collect metadata */
|
||||||
for (i = 0; i < n_params; i++) {
|
for (i = 0; i < n_params; i++) {
|
||||||
|
|
@ -453,78 +452,40 @@ static int alloc_buffers(struct pw_link *this,
|
||||||
|
|
||||||
metas[n_metas].type = type;
|
metas[n_metas].type = type;
|
||||||
metas[n_metas].size = size;
|
metas[n_metas].size = size;
|
||||||
meta_size += SPA_ROUND_UP_N(metas[n_metas].size, 8);
|
|
||||||
n_metas++;
|
n_metas++;
|
||||||
skel_size += sizeof(struct spa_meta);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data_size += meta_size;
|
|
||||||
data_size = SPA_ROUND_UP_N(data_size, data_aligns[0]);
|
|
||||||
|
|
||||||
/* data */
|
|
||||||
for (i = 0; i < n_datas; i++) {
|
for (i = 0; i < n_datas; i++) {
|
||||||
data_size += sizeof(struct spa_chunk);
|
struct spa_data *d = &datas[i];
|
||||||
data_size += data_sizes[i];
|
|
||||||
skel_size += sizeof(struct spa_data);
|
if (data_sizes[i] > 0) {
|
||||||
|
d->type = SPA_DATA_MemPtr;
|
||||||
|
d->maxsize = data_sizes[i];
|
||||||
|
} else {
|
||||||
|
d->type = SPA_ID_INVALID;
|
||||||
|
d->maxsize = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buffers = calloc(n_buffers, skel_size + sizeof(struct spa_buffer *));
|
spa_buffer_alloc_fill_info(&info, n_metas, metas, n_datas, datas, data_aligns);
|
||||||
|
|
||||||
|
buffers = calloc(n_buffers, info.skel_size + sizeof(struct spa_buffer *));
|
||||||
|
if (buffers == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
/* pointer to buffer structures */
|
/* pointer to buffer structures */
|
||||||
bp = SPA_MEMBER(buffers, n_buffers * sizeof(struct spa_buffer *), struct spa_buffer);
|
bp = SPA_MEMBER(buffers, n_buffers * sizeof(struct spa_buffer *), struct spa_buffer);
|
||||||
|
|
||||||
if ((res = pw_memblock_alloc(PW_MEMBLOCK_FLAG_WITH_FD |
|
if ((res = pw_memblock_alloc(PW_MEMBLOCK_FLAG_WITH_FD |
|
||||||
PW_MEMBLOCK_FLAG_MAP_READWRITE |
|
PW_MEMBLOCK_FLAG_MAP_READWRITE |
|
||||||
PW_MEMBLOCK_FLAG_SEAL, n_buffers * data_size, &m)) < 0)
|
PW_MEMBLOCK_FLAG_SEAL, n_buffers * info.mem_size,
|
||||||
|
&m)) < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
for (i = 0; i < n_buffers; i++) {
|
pw_log_debug("layout buffers %p data %p", bp, m->ptr);
|
||||||
uint32_t j;
|
spa_buffer_alloc_layout_array(&info, n_buffers, buffers, bp, m->ptr);
|
||||||
struct spa_buffer *b;
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
buffers[i] = b = SPA_MEMBER(bp, skel_size * i, struct spa_buffer);
|
|
||||||
|
|
||||||
p = SPA_MEMBER(m->ptr, data_size * i, void);
|
|
||||||
|
|
||||||
b->n_metas = n_metas;
|
|
||||||
b->metas = SPA_MEMBER(b, sizeof(struct spa_buffer), struct spa_meta);
|
|
||||||
for (j = 0; j < n_metas; j++) {
|
|
||||||
struct spa_meta *m = &b->metas[j];
|
|
||||||
|
|
||||||
m->type = metas[j].type;
|
|
||||||
m->size = metas[j].size;
|
|
||||||
m->data = p;
|
|
||||||
p = SPA_MEMBER(p, SPA_ROUND_UP_N(m->size, 8), void);
|
|
||||||
}
|
|
||||||
/* pointer to data structure */
|
|
||||||
b->n_datas = n_datas;
|
|
||||||
b->datas = SPA_MEMBER(b->metas, n_metas * sizeof(struct spa_meta), struct spa_data);
|
|
||||||
|
|
||||||
cdp = p;
|
|
||||||
ddp = SPA_MEMBER(cdp, sizeof(struct spa_chunk) * n_datas, void);
|
|
||||||
|
|
||||||
for (j = 0; j < n_datas; j++) {
|
|
||||||
struct spa_data *d = &b->datas[j];
|
|
||||||
|
|
||||||
d->chunk = &cdp[j];
|
|
||||||
if (data_sizes[j] > 0) {
|
|
||||||
d->type = SPA_DATA_MemFd;
|
|
||||||
d->flags = 0;
|
|
||||||
d->fd = m->fd;
|
|
||||||
d->mapoffset = SPA_ROUND_UP_N(SPA_PTRDIFF(ddp, m->ptr), data_aligns[i]);
|
|
||||||
d->maxsize = data_sizes[j];
|
|
||||||
d->data = SPA_MEMBER(m->ptr, d->mapoffset, void);
|
|
||||||
d->chunk->offset = 0;
|
|
||||||
d->chunk->size = 0;
|
|
||||||
d->chunk->stride = data_strides[j];
|
|
||||||
ddp = SPA_MEMBER(ddp, data_sizes[j], void);
|
|
||||||
} else {
|
|
||||||
/* needs to be allocated by a node */
|
|
||||||
d->type = SPA_ID_INVALID;
|
|
||||||
d->data = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
allocation->mem = m;
|
allocation->mem = m;
|
||||||
allocation->n_buffers = n_buffers;
|
allocation->n_buffers = n_buffers;
|
||||||
allocation->buffers = buffers;
|
allocation->buffers = buffers;
|
||||||
|
|
@ -704,9 +665,9 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s
|
||||||
uint32_t i, offset, n_params;
|
uint32_t i, offset, n_params;
|
||||||
uint32_t max_buffers;
|
uint32_t max_buffers;
|
||||||
size_t minsize = 8192, stride = 0, align;
|
size_t minsize = 8192, stride = 0, align;
|
||||||
size_t data_sizes[1];
|
uint32_t data_sizes[1];
|
||||||
ssize_t data_strides[1];
|
int32_t data_strides[1];
|
||||||
size_t data_aligns[1];
|
uint32_t data_aligns[1];
|
||||||
|
|
||||||
n_params = param_filter(this, input, output, SPA_PARAM_Buffers, &b);
|
n_params = param_filter(this, input, output, SPA_PARAM_Buffers, &b);
|
||||||
n_params += param_filter(this, input, output, SPA_PARAM_Meta, &b);
|
n_params += param_filter(this, input, output, SPA_PARAM_Meta, &b);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue