mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
mem: remove memory stuff
Remove the memory stuff from the spa API, we can do thing more simple and efficiently if we always allocate buffers outside of the plugins and only implement an alloc function on the node when it can do something clever. Move serialize code to the props/format/buffer code Make it possible to copy a format and properties.
This commit is contained in:
parent
fe37e2bc1b
commit
24108e01c1
46 changed files with 901 additions and 1546 deletions
|
|
@ -288,7 +288,7 @@ spa_format_audio_parse (const SpaFormat *format,
|
|||
|
||||
props = &format->props;
|
||||
idx = spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_INFO);
|
||||
if ((res = spa_props_get_prop (props, idx, &value)) < 0)
|
||||
if ((res = spa_props_get_value (props, idx, &value)) < 0)
|
||||
goto fallback;
|
||||
|
||||
if (props->prop_info[idx].type != SPA_PROP_TYPE_POINTER)
|
||||
|
|
@ -300,7 +300,7 @@ spa_format_audio_parse (const SpaFormat *format,
|
|||
return SPA_RESULT_OK;
|
||||
|
||||
fallback:
|
||||
res = spa_props_copy (props, &aformat->format.props);
|
||||
res = spa_props_copy_values (props, &aformat->format.props);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
115
spa/lib/buffer.c
115
spa/lib/buffer.c
|
|
@ -35,16 +35,16 @@ typedef struct {
|
|||
} Buffer;
|
||||
|
||||
SpaResult
|
||||
spa_buffer_alloc (SpaAllocParam **params,
|
||||
unsigned int n_params,
|
||||
SpaBuffer **buffers,
|
||||
unsigned int *n_buffers)
|
||||
spa_buffer_alloc (SpaBufferAllocFlags flags,
|
||||
SpaAllocParam **params,
|
||||
unsigned int n_params,
|
||||
SpaBuffer **buffers,
|
||||
unsigned int *n_buffers)
|
||||
{
|
||||
unsigned int i, nbufs;
|
||||
size_t size = 0, stride = 0;
|
||||
SpaMemory *bmem, *dmem;
|
||||
void *mem;
|
||||
Buffer *bufs;
|
||||
Buffer *b;
|
||||
bool add_header = false;
|
||||
int n_metas = 0;
|
||||
|
||||
|
|
@ -91,28 +91,26 @@ spa_buffer_alloc (SpaAllocParam **params,
|
|||
|
||||
*n_buffers = nbufs;
|
||||
|
||||
bmem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED,
|
||||
NULL, sizeof (Buffer) * nbufs);
|
||||
dmem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED,
|
||||
NULL, size * nbufs);
|
||||
if (flags & SPA_BUFFER_ALLOC_FLAG_NO_MEM)
|
||||
size = 0;
|
||||
|
||||
bufs = spa_memory_ensure_ptr (bmem);
|
||||
mem = calloc (nbufs, sizeof (Buffer) + size);
|
||||
|
||||
bufs = mem;
|
||||
|
||||
for (i = 0; i < nbufs; i++) {
|
||||
int mi = 0;
|
||||
Buffer *b;
|
||||
|
||||
b = &bufs[i];
|
||||
b->buffer.id = i;
|
||||
b->buffer.mem.mem = bmem->mem;
|
||||
b->buffer.mem.offset = sizeof (Buffer) * i;
|
||||
b->buffer.mem.size = sizeof (Buffer);
|
||||
|
||||
buffers[i] = &b->buffer;
|
||||
|
||||
b->buffer.n_metas = n_metas;
|
||||
b->buffer.metas = offsetof (Buffer, metas);
|
||||
b->buffer.metas = b->metas;
|
||||
b->buffer.n_datas = 1;
|
||||
b->buffer.datas = offsetof (Buffer, datas);
|
||||
b->buffer.datas = b->datas;
|
||||
|
||||
if (add_header) {
|
||||
b->header.flags = 0;
|
||||
|
|
@ -121,15 +119,92 @@ spa_buffer_alloc (SpaAllocParam **params,
|
|||
b->header.dts_offset = 0;
|
||||
|
||||
b->metas[mi].type = SPA_META_TYPE_HEADER;
|
||||
b->metas[mi].offset = offsetof (Buffer, header);
|
||||
b->metas[mi].data = &b->header;
|
||||
b->metas[mi].size = sizeof (b->header);
|
||||
mi++;
|
||||
}
|
||||
|
||||
b->datas[0].mem.mem = dmem->mem;
|
||||
b->datas[0].mem.offset = size * i;
|
||||
b->datas[0].mem.size = size;
|
||||
if (size == 0) {
|
||||
b->datas[0].type = SPA_DATA_TYPE_INVALID;
|
||||
b->datas[0].data = NULL;
|
||||
} else {
|
||||
b->datas[0].type = SPA_DATA_TYPE_MEMPTR;
|
||||
b->datas[0].data = mem + sizeof (Buffer);
|
||||
}
|
||||
b->datas[0].offset = size * i;
|
||||
b->datas[0].size = size;
|
||||
b->datas[0].stride = stride;
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
spa_buffer_get_size (const SpaBuffer *buffer)
|
||||
{
|
||||
size_t size;
|
||||
unsigned int i;
|
||||
|
||||
if (buffer == NULL)
|
||||
return 0;
|
||||
|
||||
size = sizeof (SpaBuffer);
|
||||
for (i = 0; i < buffer->n_metas; i++)
|
||||
size += buffer->metas[i].size * sizeof (SpaMeta);
|
||||
for (i = 0; i < buffer->n_datas; i++)
|
||||
size += sizeof (SpaData);
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t
|
||||
spa_buffer_serialize (void *dest, const SpaBuffer *buffer)
|
||||
{
|
||||
SpaBuffer *tb;
|
||||
SpaMeta *mp;
|
||||
SpaData *dp;
|
||||
void *p;
|
||||
unsigned int i;
|
||||
|
||||
if (buffer == NULL)
|
||||
return 0;
|
||||
|
||||
tb = dest;
|
||||
memcpy (tb, buffer, sizeof (SpaBuffer));
|
||||
mp = SPA_MEMBER (tb, sizeof(SpaBuffer), SpaMeta);
|
||||
dp = SPA_MEMBER (mp, sizeof(SpaMeta) * tb->n_metas, SpaData);
|
||||
p = SPA_MEMBER (dp, sizeof(SpaData) * tb->n_datas, void);
|
||||
|
||||
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++) {
|
||||
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));
|
||||
|
||||
return SPA_PTRDIFF (p, tb);
|
||||
}
|
||||
|
||||
SpaBuffer *
|
||||
spa_buffer_deserialize (void *src, off_t offset)
|
||||
{
|
||||
SpaBuffer *b;
|
||||
unsigned int i;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -340,65 +340,12 @@ spa_control_iter_get_data (SpaControlIter *iter, size_t *size)
|
|||
return si->data;
|
||||
}
|
||||
|
||||
static SpaProps *
|
||||
parse_props (void *p, off_t offset)
|
||||
{
|
||||
SpaProps *tp;
|
||||
unsigned int i, j;
|
||||
SpaPropInfo *pi;
|
||||
SpaPropRangeInfo *ri;
|
||||
|
||||
tp = SPA_MEMBER (p, offset, SpaProps);
|
||||
tp->prop_info = SPA_MEMBER (tp, SPA_PTR_TO_INT (tp->prop_info), SpaPropInfo);
|
||||
|
||||
/* now fix all the pointers */
|
||||
for (i = 0; i < tp->n_prop_info; i++) {
|
||||
pi = (SpaPropInfo *) &tp->prop_info[i];
|
||||
if (pi->name)
|
||||
pi->name = SPA_MEMBER (tp, SPA_PTR_TO_INT (pi->name), char);
|
||||
if (pi->description)
|
||||
pi->description = SPA_MEMBER (tp, SPA_PTR_TO_INT (pi->description), char);
|
||||
if (pi->range_values)
|
||||
pi->range_values = SPA_MEMBER (tp, SPA_PTR_TO_INT (pi->range_values), SpaPropRangeInfo);
|
||||
|
||||
for (j = 0; j < pi->n_range_values; j++) {
|
||||
ri = (SpaPropRangeInfo *) &pi->range_values[j];
|
||||
if (ri->name)
|
||||
ri->name = SPA_MEMBER (tp, SPA_PTR_TO_INT (ri->name), char);
|
||||
if (ri->description)
|
||||
ri->description = SPA_MEMBER (tp, SPA_PTR_TO_INT (ri->description), char);
|
||||
if (ri->val.value)
|
||||
ri->val.value = SPA_MEMBER (tp, SPA_PTR_TO_INT (ri->val.value), void);
|
||||
}
|
||||
}
|
||||
return tp;
|
||||
}
|
||||
|
||||
static SpaFormat *
|
||||
parse_format (void *p, size_t size, off_t offset)
|
||||
{
|
||||
SpaFormat *f;
|
||||
|
||||
if (offset == 0)
|
||||
return NULL;
|
||||
|
||||
f = SPA_MEMBER (p, offset, SpaFormat);
|
||||
f->mem.mem.pool_id = 0;
|
||||
f->mem.mem.id = 0;
|
||||
f->mem.offset = offset;
|
||||
f->mem.size = size - offset;
|
||||
|
||||
parse_props (f, offsetof (SpaFormat, props));
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
static void
|
||||
iter_parse_node_update (struct stack_iter *si, SpaControlCmdNodeUpdate *nu)
|
||||
{
|
||||
memcpy (nu, si->data, sizeof (SpaControlCmdNodeUpdate));
|
||||
if (nu->props)
|
||||
nu->props = parse_props (si->data, SPA_PTR_TO_INT (nu->props));
|
||||
nu->props = spa_props_deserialize (si->data, SPA_PTR_TO_INT (nu->props));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -415,14 +362,16 @@ iter_parse_port_update (struct stack_iter *si, SpaControlCmdPortUpdate *pu)
|
|||
pu->possible_formats = SPA_MEMBER (p,
|
||||
SPA_PTR_TO_INT (pu->possible_formats), SpaFormat *);
|
||||
for (i = 0; i < pu->n_possible_formats; i++) {
|
||||
pu->possible_formats[i] = parse_format (p, si->size,
|
||||
SPA_PTR_TO_INT (pu->possible_formats[i]));
|
||||
if (pu->possible_formats[i]) {
|
||||
pu->possible_formats[i] = spa_format_deserialize (p,
|
||||
SPA_PTR_TO_INT (pu->possible_formats[i]));
|
||||
}
|
||||
}
|
||||
if (pu->format)
|
||||
pu->format = parse_format (p, si->size, SPA_PTR_TO_INT (pu->format));
|
||||
pu->format = spa_format_deserialize (p, SPA_PTR_TO_INT (pu->format));
|
||||
|
||||
if (pu->props)
|
||||
pu->props = parse_props (p, SPA_PTR_TO_INT (pu->props));
|
||||
pu->props = spa_props_deserialize (p, SPA_PTR_TO_INT (pu->props));
|
||||
if (pu->info) {
|
||||
SpaPortInfo *pi;
|
||||
|
||||
|
|
@ -440,28 +389,19 @@ static void
|
|||
iter_parse_set_format (struct stack_iter *si, SpaControlCmdSetFormat *cmd)
|
||||
{
|
||||
memcpy (cmd, si->data, sizeof (SpaControlCmdSetFormat));
|
||||
cmd->format = parse_format (si->data, si->size, SPA_PTR_TO_INT (cmd->format));
|
||||
if (cmd->format)
|
||||
cmd->format = spa_format_deserialize (si->data, SPA_PTR_TO_INT (cmd->format));
|
||||
}
|
||||
|
||||
static void
|
||||
iter_parse_use_buffers (struct stack_iter *si, SpaControlCmdUseBuffers *cmd)
|
||||
{
|
||||
void *p;
|
||||
int i;
|
||||
|
||||
p = si->data;
|
||||
memcpy (cmd, p, sizeof (SpaControlCmdUseBuffers));
|
||||
if (cmd->buffers)
|
||||
cmd->buffers = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers), SpaBuffer *);
|
||||
for (i = 0; i < cmd->n_buffers; i++) {
|
||||
SpaMemoryChunk *mc;
|
||||
SpaMemory *mem;
|
||||
|
||||
mc = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers[i]), SpaMemoryChunk);
|
||||
mem = spa_memory_find (&mc->mem);
|
||||
|
||||
cmd->buffers[i] = mem ? SPA_MEMBER (spa_memory_ensure_ptr (mem), mc->offset, SpaBuffer) : NULL;
|
||||
}
|
||||
cmd->buffers = SPA_MEMBER (p, SPA_PTR_TO_INT (cmd->buffers), SpaControlMemRef);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -819,161 +759,6 @@ builder_add_cmd (struct stack_builder *sb, SpaControlCmd cmd, size_t size)
|
|||
return p;
|
||||
}
|
||||
|
||||
static size_t
|
||||
calc_props_len (const SpaProps *props)
|
||||
{
|
||||
size_t len;
|
||||
unsigned int i, j;
|
||||
SpaPropInfo *pi;
|
||||
SpaPropRangeInfo *ri;
|
||||
|
||||
if (props == NULL)
|
||||
return 0;
|
||||
|
||||
/* props and unset mask */
|
||||
len = sizeof (SpaProps) + sizeof (uint32_t);
|
||||
for (i = 0; i < props->n_prop_info; i++) {
|
||||
pi = (SpaPropInfo *) &props->prop_info[i];
|
||||
len += sizeof (SpaPropInfo);
|
||||
len += pi->name ? strlen (pi->name) + 1 : 0;
|
||||
len += pi->description ? strlen (pi->description) + 1 : 0;
|
||||
/* for the value */
|
||||
len += pi->maxsize;
|
||||
for (j = 0; j < pi->n_range_values; j++) {
|
||||
ri = (SpaPropRangeInfo *)&pi->range_values[j];
|
||||
len += sizeof (SpaPropRangeInfo);
|
||||
len += ri->name ? strlen (ri->name) + 1 : 0;
|
||||
len += ri->description ? strlen (ri->description) + 1 : 0;
|
||||
/* the size of the range value */
|
||||
len += ri->val.size;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static size_t
|
||||
write_props (void *p, const SpaProps *props, off_t offset)
|
||||
{
|
||||
size_t len, slen;
|
||||
unsigned int i, j;
|
||||
SpaProps *tp;
|
||||
SpaPropInfo *pi, *bpi;
|
||||
SpaPropRangeInfo *ri, *bri;
|
||||
|
||||
tp = p;
|
||||
memcpy (tp, props, sizeof (SpaProps));
|
||||
tp->prop_info = SPA_INT_TO_PTR (offset + sizeof (uint32_t));
|
||||
|
||||
/* write propinfo array */
|
||||
bpi = pi = SPA_MEMBER (tp, SPA_PTR_TO_INT (tp->prop_info), SpaPropInfo);
|
||||
for (i = 0; i < tp->n_prop_info; i++) {
|
||||
memcpy (pi, &props->prop_info[i], sizeof (SpaPropInfo));
|
||||
pi++;
|
||||
}
|
||||
bri = ri = (SpaPropRangeInfo *) pi;
|
||||
pi = bpi;
|
||||
/* write range info arrays, adjust offset to it */
|
||||
for (i = 0; i < tp->n_prop_info; i++) {
|
||||
pi->range_values = SPA_INT_TO_PTR (SPA_PTRDIFF (ri, tp));
|
||||
for (j = 0; j < pi->n_range_values; j++) {
|
||||
memcpy (ri, &props->prop_info[i].range_values[j], sizeof (SpaPropRangeInfo));
|
||||
ri++;
|
||||
}
|
||||
pi++;
|
||||
}
|
||||
p = ri;
|
||||
pi = bpi;
|
||||
ri = bri;
|
||||
/* strings and default values from props and ranges */
|
||||
for (i = 0; i < tp->n_prop_info; i++) {
|
||||
if (pi->name) {
|
||||
slen = strlen (pi->name) + 1;
|
||||
memcpy (p, pi->name, slen);
|
||||
pi->name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
|
||||
p += slen;
|
||||
} else {
|
||||
pi->name = 0;
|
||||
}
|
||||
if (pi->description) {
|
||||
slen = strlen (pi->description) + 1;
|
||||
memcpy (p, pi->description, slen);
|
||||
pi->description = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
|
||||
p += slen;
|
||||
} else {
|
||||
pi->description = 0;
|
||||
}
|
||||
for (j = 0; j < pi->n_range_values; j++) {
|
||||
if (ri->name) {
|
||||
slen = strlen (ri->name) + 1;
|
||||
memcpy (p, ri->name, slen);
|
||||
ri->name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
|
||||
p += slen;
|
||||
} else {
|
||||
ri->name = 0;
|
||||
}
|
||||
if (ri->description) {
|
||||
slen = strlen (ri->description) + 1;
|
||||
memcpy (p, ri->description, slen);
|
||||
ri->description = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
|
||||
p += slen;
|
||||
} else {
|
||||
ri->description = 0;
|
||||
}
|
||||
if (ri->val.size) {
|
||||
memcpy (p, ri->val.value, ri->val.size);
|
||||
ri->val.value = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
|
||||
p += ri->val.size;
|
||||
} else {
|
||||
ri->val.value = 0;
|
||||
}
|
||||
ri++;
|
||||
}
|
||||
pi++;
|
||||
}
|
||||
/* and the actual values */
|
||||
pi = bpi;
|
||||
for (i = 0; i < tp->n_prop_info; i++) {
|
||||
if (pi->offset) {
|
||||
memcpy (p, SPA_MEMBER (props, pi->offset, void), pi->maxsize);
|
||||
pi->offset = SPA_PTRDIFF (p, tp);
|
||||
p += pi->maxsize;
|
||||
} else {
|
||||
pi->offset = 0;
|
||||
}
|
||||
pi++;
|
||||
}
|
||||
|
||||
len = SPA_PTRDIFF (p, tp);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static size_t
|
||||
calc_format_len (const SpaFormat *format)
|
||||
{
|
||||
if (format == NULL)
|
||||
return 0;
|
||||
|
||||
return calc_props_len (&format->props) - sizeof (SpaProps) + sizeof (SpaFormat);
|
||||
}
|
||||
|
||||
static size_t
|
||||
write_format (void *p, const SpaFormat *format)
|
||||
{
|
||||
SpaFormat *tf;
|
||||
|
||||
tf = p;
|
||||
tf->media_type = format->media_type;
|
||||
tf->media_subtype = format->media_subtype;
|
||||
tf->mem.mem.pool_id = 0;
|
||||
tf->mem.mem.id = 0;
|
||||
tf->mem.offset = 0;
|
||||
tf->mem.size = 0;
|
||||
|
||||
p = SPA_MEMBER (tf, offsetof (SpaFormat, props), void);
|
||||
return write_props (p, &format->props, sizeof (SpaFormat));
|
||||
}
|
||||
|
||||
static size_t
|
||||
write_port_info (void *p, const SpaPortInfo *info)
|
||||
{
|
||||
|
|
@ -1016,7 +801,7 @@ builder_add_node_update (struct stack_builder *sb, SpaControlCmdNodeUpdate *nu)
|
|||
|
||||
/* calc len */
|
||||
len = sizeof (SpaControlCmdNodeUpdate);
|
||||
len += calc_props_len (nu->props);
|
||||
len += spa_props_get_size (nu->props);
|
||||
|
||||
p = builder_add_cmd (sb, SPA_CONTROL_CMD_NODE_UPDATE, len);
|
||||
memcpy (p, nu, sizeof (SpaControlCmdNodeUpdate));
|
||||
|
|
@ -1024,7 +809,7 @@ builder_add_node_update (struct stack_builder *sb, SpaControlCmdNodeUpdate *nu)
|
|||
|
||||
p = SPA_MEMBER (d, sizeof (SpaControlCmdNodeUpdate), void);
|
||||
if (nu->props) {
|
||||
len = write_props (p, nu->props, sizeof (SpaProps));
|
||||
len = spa_props_serialize (p, nu->props);
|
||||
d->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
|
||||
} else {
|
||||
d->props = 0;
|
||||
|
|
@ -1043,10 +828,11 @@ builder_add_port_update (struct stack_builder *sb, SpaControlCmdPortUpdate *pu)
|
|||
/* calc len */
|
||||
len = sizeof (SpaControlCmdPortUpdate);
|
||||
len += pu->n_possible_formats * sizeof (SpaFormat *);
|
||||
for (i = 0; i < pu->n_possible_formats; i++)
|
||||
len += calc_format_len (pu->possible_formats[i]);
|
||||
len += calc_format_len (pu->format);
|
||||
len += calc_props_len (pu->props);
|
||||
for (i = 0; i < pu->n_possible_formats; i++) {
|
||||
len += spa_format_get_size (pu->possible_formats[i]);
|
||||
}
|
||||
len += spa_format_get_size (pu->format);
|
||||
len += spa_props_get_size (pu->props);
|
||||
if (pu->info) {
|
||||
len += sizeof (SpaPortInfo);
|
||||
len += pu->info->n_params * sizeof (SpaAllocParam *);
|
||||
|
|
@ -1068,19 +854,19 @@ builder_add_port_update (struct stack_builder *sb, SpaControlCmdPortUpdate *pu)
|
|||
p = SPA_MEMBER (p, sizeof (SpaFormat*) * pu->n_possible_formats, void);
|
||||
|
||||
for (i = 0; i < pu->n_possible_formats; i++) {
|
||||
len = write_format (p, pu->possible_formats[i]);
|
||||
len = spa_format_serialize (p, pu->possible_formats[i]);
|
||||
bfa[i] = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
|
||||
p = SPA_MEMBER (p, len, void);
|
||||
}
|
||||
if (pu->format) {
|
||||
len = write_format (p, pu->format);
|
||||
len = spa_format_serialize (p, pu->format);
|
||||
d->format = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
|
||||
p = SPA_MEMBER (p, len, void);
|
||||
} else {
|
||||
d->format = 0;
|
||||
}
|
||||
if (pu->props) {
|
||||
len = write_props (p, pu->props, sizeof (SpaProps));
|
||||
len = spa_props_serialize (p, pu->props);
|
||||
d->props = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
|
||||
p = SPA_MEMBER (p, len, void);
|
||||
} else {
|
||||
|
|
@ -1103,14 +889,14 @@ builder_add_set_format (struct stack_builder *sb, SpaControlCmdSetFormat *sf)
|
|||
|
||||
/* calculate length */
|
||||
/* port_id + format + mask */
|
||||
len = sizeof (SpaControlCmdSetFormat) + calc_format_len (sf->format);
|
||||
len = sizeof (SpaControlCmdSetFormat) + spa_format_get_size (sf->format);
|
||||
p = builder_add_cmd (sb, SPA_CONTROL_CMD_SET_FORMAT, len);
|
||||
memcpy (p, sf, sizeof (SpaControlCmdSetFormat));
|
||||
sf = p;
|
||||
|
||||
p = SPA_MEMBER (sf, sizeof (SpaControlCmdSetFormat), void);
|
||||
if (sf->format) {
|
||||
len = write_format (p, sf->format);
|
||||
len = spa_format_serialize (p, sf->format);
|
||||
sf->format = SPA_INT_TO_PTR (SPA_PTRDIFF (p, sf));
|
||||
} else
|
||||
sf->format = 0;
|
||||
|
|
@ -1120,35 +906,26 @@ static void
|
|||
builder_add_use_buffers (struct stack_builder *sb, SpaControlCmdUseBuffers *ub)
|
||||
{
|
||||
size_t len;
|
||||
void *p;
|
||||
int i;
|
||||
SpaMemoryChunk **bmc;
|
||||
SpaControlCmdUseBuffers *d;
|
||||
SpaControlMemRef *mr;
|
||||
|
||||
/* calculate length */
|
||||
/* port_id + format + mask */
|
||||
len = sizeof (SpaControlCmdUseBuffers);
|
||||
len += ub->n_buffers * sizeof (SpaBuffer *);
|
||||
len += ub->n_buffers * sizeof (SpaMemoryChunk);
|
||||
len += ub->n_buffers * sizeof (SpaControlMemRef);
|
||||
|
||||
p = builder_add_cmd (sb, SPA_CONTROL_CMD_USE_BUFFERS, len);
|
||||
memcpy (p, ub, sizeof (SpaControlCmdUseBuffers));
|
||||
d = p;
|
||||
d = builder_add_cmd (sb, SPA_CONTROL_CMD_USE_BUFFERS, len);
|
||||
memcpy (d, ub, sizeof (SpaControlCmdUseBuffers));
|
||||
|
||||
p = SPA_MEMBER (d, sizeof (SpaControlCmdUseBuffers), void);
|
||||
bmc = p;
|
||||
mr = SPA_MEMBER (d, sizeof (SpaControlCmdUseBuffers), void);
|
||||
|
||||
if (d->n_buffers)
|
||||
d->buffers = SPA_INT_TO_PTR (SPA_PTRDIFF (bmc, d));
|
||||
d->buffers = SPA_INT_TO_PTR (SPA_PTRDIFF (mr, d));
|
||||
else
|
||||
d->buffers = 0;
|
||||
|
||||
p = SPA_MEMBER (p, sizeof (SpaMemoryChunk*) * ub->n_buffers, void);
|
||||
for (i = 0; i < ub->n_buffers; i++) {
|
||||
memcpy (p, &ub->buffers[i]->mem, sizeof (SpaMemoryChunk));
|
||||
bmc[i] = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
|
||||
p = SPA_MEMBER (p, sizeof (SpaMemoryChunk), void);
|
||||
}
|
||||
for (i = 0; i < ub->n_buffers; i++)
|
||||
memcpy (&mr[i], &ub->buffers[i], sizeof (SpaControlMemRef));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "spa/debug.h"
|
||||
#include "spa/memory.h"
|
||||
#include "spa/props.h"
|
||||
#include "spa/format.h"
|
||||
|
||||
|
|
@ -92,18 +91,14 @@ spa_debug_buffer (const SpaBuffer *buffer)
|
|||
|
||||
fprintf (stderr, "SpaBuffer %p:\n", buffer);
|
||||
fprintf (stderr, " id: %08X\n", buffer->id);
|
||||
fprintf (stderr, " pool_id: %08X\n", buffer->mem.mem.pool_id);
|
||||
fprintf (stderr, " mem_id: %08X\n", buffer->mem.mem.id);
|
||||
fprintf (stderr, " offset: %zd\n", buffer->mem.offset);
|
||||
fprintf (stderr, " size: %zd\n", buffer->mem.size);
|
||||
fprintf (stderr, " n_metas: %u (offset %zd)\n", buffer->n_metas, buffer->metas);
|
||||
fprintf (stderr, " n_metas: %u (at %p)\n", buffer->n_metas, buffer->metas);
|
||||
for (i = 0; i < buffer->n_metas; i++) {
|
||||
SpaMeta *m = &SPA_BUFFER_METAS (buffer)[i];
|
||||
fprintf (stderr, " meta %d: type %d, offset %zd, size %zd:\n", i, m->type, m->offset, m->size);
|
||||
SpaMeta *m = &buffer->metas[i];
|
||||
fprintf (stderr, " meta %d: type %d, data %p, size %zd:\n", i, m->type, m->data, m->size);
|
||||
switch (m->type) {
|
||||
case SPA_META_TYPE_HEADER:
|
||||
{
|
||||
SpaMetaHeader *h = SPA_MEMBER (buffer, m->offset, SpaMetaHeader);
|
||||
SpaMetaHeader *h = m->data;
|
||||
fprintf (stderr, " SpaMetaHeader:\n");
|
||||
fprintf (stderr, " flags: %08x\n", h->flags);
|
||||
fprintf (stderr, " seq: %u\n", h->seq);
|
||||
|
|
@ -113,37 +108,24 @@ spa_debug_buffer (const SpaBuffer *buffer)
|
|||
}
|
||||
case SPA_META_TYPE_POINTER:
|
||||
fprintf (stderr, " SpaMetaPointer:\n");
|
||||
spa_debug_dump_mem (SPA_MEMBER (buffer, m->offset, void), m->size);
|
||||
spa_debug_dump_mem (m->data, m->size);
|
||||
break;
|
||||
case SPA_META_TYPE_VIDEO_CROP:
|
||||
fprintf (stderr, " SpaMetaVideoCrop:\n");
|
||||
spa_debug_dump_mem (SPA_MEMBER (buffer, m->offset, void), m->size);
|
||||
spa_debug_dump_mem (m->data, m->size);
|
||||
break;
|
||||
default:
|
||||
spa_debug_dump_mem (SPA_MEMBER (buffer, m->offset, void), m->size);
|
||||
spa_debug_dump_mem (m->data, m->size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf (stderr, " n_datas: \t%u (offset %zd)\n", buffer->n_datas, buffer->datas);
|
||||
fprintf (stderr, " n_datas: \t%u (at %p)\n", buffer->n_datas, buffer->datas);
|
||||
for (i = 0; i < buffer->n_datas; i++) {
|
||||
SpaData *d = &SPA_BUFFER_DATAS (buffer)[i];
|
||||
SpaMemory *mem;
|
||||
|
||||
mem = spa_memory_find (&d->mem.mem);
|
||||
fprintf (stderr, " data %d: (memory %p)\n", i, mem);
|
||||
if (mem) {
|
||||
fprintf (stderr, " pool_id: %u\n", mem->mem.pool_id);
|
||||
fprintf (stderr, " id: %u\n", mem->mem.id);
|
||||
fprintf (stderr, " flags: %08x\n", mem->flags);
|
||||
fprintf (stderr, " type: %s\n", mem->type ? mem->type : "*unknown*");
|
||||
fprintf (stderr, " fd: %d\n", mem->fd);
|
||||
fprintf (stderr, " ptr: %p\n", mem->ptr);
|
||||
fprintf (stderr, " size: %zd\n", mem->size);
|
||||
} else {
|
||||
fprintf (stderr, " invalid memory reference\n");
|
||||
}
|
||||
fprintf (stderr, " offset: %zd\n", d->mem.offset);
|
||||
fprintf (stderr, " size: %zd\n", d->mem.size);
|
||||
SpaData *d = &buffer->datas[i];
|
||||
fprintf (stderr, " type: %d\n", d->type);
|
||||
fprintf (stderr, " data: %p\n", d->data);
|
||||
fprintf (stderr, " offset: %zd\n", d->offset);
|
||||
fprintf (stderr, " size: %zd\n", d->size);
|
||||
fprintf (stderr, " stride: %zd\n", d->stride);
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
|
|
@ -361,7 +343,7 @@ spa_debug_props (const SpaProps *props, bool print_ranges)
|
|||
|
||||
fprintf (stderr, "%-23.23s %s. ", "", prop_type_names[info->type].CCName);
|
||||
|
||||
res = spa_props_get_prop (props, i, &value);
|
||||
res = spa_props_get_value (props, i, &value);
|
||||
|
||||
fprintf (stderr, "Current: ");
|
||||
if (res == SPA_RESULT_OK)
|
||||
|
|
@ -453,7 +435,7 @@ spa_debug_format (const SpaFormat *format)
|
|||
SpaPropValue value;
|
||||
SpaResult res;
|
||||
|
||||
res = spa_props_get_prop (props, i, &value);
|
||||
res = spa_props_get_value (props, i, &value);
|
||||
|
||||
if (info->flags & SPA_PROP_FLAG_INFO)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -23,15 +23,8 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <spa/format.h>
|
||||
#include <spa/debug.h>
|
||||
|
||||
SpaResult
|
||||
spa_format_to_string (const SpaFormat *format, char **result)
|
||||
{
|
||||
if (format == NULL || result == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_format_fixate (SpaFormat *format)
|
||||
|
|
@ -43,3 +36,52 @@ spa_format_fixate (SpaFormat *format)
|
|||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
size_t
|
||||
spa_format_get_size (const SpaFormat *format)
|
||||
{
|
||||
if (format == NULL)
|
||||
return 0;
|
||||
|
||||
return spa_props_get_size (&format->props) - sizeof (SpaProps) + sizeof (SpaFormat);
|
||||
}
|
||||
|
||||
size_t
|
||||
spa_format_serialize (void *dest, const SpaFormat *format)
|
||||
{
|
||||
SpaFormat *tf;
|
||||
size_t size;
|
||||
|
||||
if (format == NULL)
|
||||
return 0;
|
||||
|
||||
tf = dest;
|
||||
tf->media_type = format->media_type;
|
||||
tf->media_subtype = format->media_subtype;
|
||||
|
||||
dest = SPA_MEMBER (tf, offsetof (SpaFormat, props), void);
|
||||
size = spa_props_serialize (dest, &format->props) - sizeof (SpaProps) + sizeof (SpaFormat);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
SpaFormat *
|
||||
spa_format_deserialize (void *src, off_t offset)
|
||||
{
|
||||
SpaFormat *f;
|
||||
|
||||
f = SPA_MEMBER (src, offset, SpaFormat);
|
||||
spa_props_deserialize (f, offsetof (SpaFormat, props));
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
SpaFormat *
|
||||
spa_format_copy_into (void *dest, const SpaFormat *format)
|
||||
{
|
||||
if (format == NULL)
|
||||
return NULL;
|
||||
|
||||
spa_format_serialize (dest, format);
|
||||
return spa_format_deserialize (dest, 0);
|
||||
}
|
||||
|
|
|
|||
341
spa/lib/memory.c
341
spa/lib/memory.c
|
|
@ -1,341 +0,0 @@
|
|||
/* Simple Plugin API
|
||||
* Copyright (C) 2016 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "spa/memory.h"
|
||||
#include "memfd-wrappers.h"
|
||||
|
||||
#undef USE_MEMFD
|
||||
|
||||
#if 1
|
||||
#define SPA_DEBUG_MEMORY(format,args...) fprintf(stderr,format,##args)
|
||||
#else
|
||||
#define SPA_DEBUG_MEMORY(format,args...)
|
||||
#endif
|
||||
|
||||
#define MAX_POOLS 16
|
||||
#define MAX_MEMORIES 1024
|
||||
|
||||
struct _SpaMemoryPool {
|
||||
bool valid;
|
||||
uint32_t id;
|
||||
SpaMemory memories[MAX_MEMORIES];
|
||||
unsigned int n_free;
|
||||
uint32_t free_mem[MAX_MEMORIES];
|
||||
};
|
||||
|
||||
static SpaMemoryPool pools[MAX_POOLS];
|
||||
|
||||
static void
|
||||
spa_memory_pool_init (SpaMemoryPool *pool, uint32_t id)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset (pool, 0, sizeof (SpaMemoryPool));
|
||||
for (i = 0; i < MAX_MEMORIES; i++)
|
||||
pool->free_mem[i] = MAX_MEMORIES - 1 - i;
|
||||
pool->n_free = MAX_MEMORIES - 1;
|
||||
pool->id = id;
|
||||
pool->valid = true;
|
||||
}
|
||||
|
||||
void
|
||||
spa_memory_init (void)
|
||||
{
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized) {
|
||||
spa_memory_pool_init (&pools[0], SPA_MEMORY_POOL_SHARED);
|
||||
spa_memory_pool_init (&pools[1], SPA_MEMORY_POOL_LOCAL);
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
spa_memory_pool_get (uint32_t type)
|
||||
{
|
||||
return pools[type].id;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
spa_memory_pool_new (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_POOLS; i++) {
|
||||
if (!pools[i].valid) {
|
||||
spa_memory_pool_init (&pools[i], i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return SPA_ID_INVALID;
|
||||
}
|
||||
|
||||
void
|
||||
spa_memory_pool_free (uint32_t pool_id)
|
||||
{
|
||||
pools[pool_id].valid = false;
|
||||
}
|
||||
|
||||
SpaMemory *
|
||||
spa_memory_alloc (uint32_t pool_id)
|
||||
{
|
||||
SpaMemory *mem;
|
||||
SpaMemoryPool *pool;
|
||||
uint32_t id;
|
||||
|
||||
if (pool_id >= MAX_POOLS || !pools[pool_id].valid)
|
||||
return NULL;
|
||||
|
||||
pool = &pools[pool_id];
|
||||
|
||||
if (pool->n_free == 0)
|
||||
return NULL;
|
||||
|
||||
id = pool->free_mem[pool->n_free - 1];
|
||||
pool->n_free--;
|
||||
|
||||
mem = &pool->memories[id];
|
||||
mem->refcount = 1;
|
||||
mem->notify = NULL;
|
||||
mem->fd = -1;
|
||||
mem->ptr = NULL;
|
||||
mem->mem.pool_id = pool_id;
|
||||
mem->mem.id = id;
|
||||
|
||||
SPA_DEBUG_MEMORY ("mem %p: alloc %u:%u\n", mem, pool_id, id);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
SpaMemory *
|
||||
spa_memory_alloc_size (uint32_t pool_id, void *data, size_t size)
|
||||
{
|
||||
SpaMemory *mem;
|
||||
|
||||
if (!(mem = spa_memory_alloc (pool_id)))
|
||||
return NULL;
|
||||
|
||||
mem->flags = SPA_MEMORY_FLAG_READWRITE;
|
||||
mem->ptr = malloc (size);
|
||||
mem->size = size;
|
||||
if (data)
|
||||
memcpy (mem->ptr, data, size);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
SpaMemory *
|
||||
spa_memory_alloc_with_fd (uint32_t pool_id, void *data, size_t size)
|
||||
{
|
||||
SpaMemory *mem;
|
||||
|
||||
if (!(mem = spa_memory_alloc (pool_id)))
|
||||
return NULL;
|
||||
|
||||
#ifdef USE_MEMFD
|
||||
mem->fd = memfd_create ("spa-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
|
||||
#else
|
||||
{
|
||||
char filename[] = "/dev/shm/spa-tmpfile.XXXXXX";
|
||||
mem->fd = mkostemp (filename, O_CLOEXEC);
|
||||
if (mem->fd == -1) {
|
||||
fprintf (stderr, "Failed to create temporary file: %s\n", strerror (errno));
|
||||
return NULL;
|
||||
}
|
||||
unlink (filename);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data) {
|
||||
if (write (mem->fd, data, size) != (ssize_t) size) {
|
||||
fprintf (stderr, "Failed to write data: %s\n", strerror (errno));
|
||||
close (mem->fd);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (ftruncate (mem->fd, size) < 0) {
|
||||
fprintf (stderr, "Failed to truncate temporary file: %s\n", strerror (errno));
|
||||
close (mem->fd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#ifdef USE_MEMFD
|
||||
{
|
||||
unsigned int seals;
|
||||
|
||||
seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL;
|
||||
if (fcntl (mem->fd, F_ADD_SEALS, seals) == -1) {
|
||||
fprintf (stderr, "Failed to add seals: %s\n", strerror (errno));
|
||||
close (mem->fd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mem->flags = SPA_MEMORY_FLAG_READWRITE;
|
||||
mem->size = size;
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
SpaMemory *
|
||||
spa_memory_import (SpaMemoryRef *ref)
|
||||
{
|
||||
SpaMemory *mem = NULL;
|
||||
SpaMemoryPool *pool;
|
||||
int i;
|
||||
bool init = false;
|
||||
uint32_t id, pool_id;
|
||||
|
||||
if (ref == NULL || ref->pool_id >= MAX_POOLS || !pools[ref->pool_id].valid)
|
||||
return NULL;
|
||||
|
||||
id = ref->id;
|
||||
pool_id = ref->pool_id;
|
||||
|
||||
pool = &pools[pool_id];
|
||||
|
||||
for (i = 0; i < pool->n_free; i++) {
|
||||
if (pool->free_mem[i] == id) {
|
||||
pool->free_mem[i] = pool->free_mem[pool->n_free - 1];
|
||||
pool->n_free--;
|
||||
init = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mem = &pool->memories[id];
|
||||
if (init) {
|
||||
mem->refcount = 1;
|
||||
mem->notify = NULL;
|
||||
mem->mem = *ref;
|
||||
mem->ptr = NULL;
|
||||
mem->fd = -1;
|
||||
} else {
|
||||
mem->refcount++;
|
||||
}
|
||||
SPA_DEBUG_MEMORY ("mem %p: import %u:%u\n", mem, pool_id, id);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_memory_ref (SpaMemoryRef *ref)
|
||||
{
|
||||
SpaMemory *mem;
|
||||
|
||||
if (!(mem = spa_memory_find (ref)))
|
||||
return SPA_RESULT_ERROR;
|
||||
|
||||
if (mem->mem.id > 0)
|
||||
mem->refcount++;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
spa_memory_free (SpaMemory *mem)
|
||||
{
|
||||
SpaMemoryPool *pool;
|
||||
|
||||
SPA_DEBUG_MEMORY ("mem %p: free %u:%u\n", mem, mem->mem.pool_id, mem->mem.id);
|
||||
|
||||
if (mem->fd != -1) {
|
||||
if (mem->ptr)
|
||||
munmap (mem->ptr, mem->size);
|
||||
close (mem->fd);
|
||||
} else {
|
||||
if (mem->ptr)
|
||||
free (mem->ptr);
|
||||
}
|
||||
pool = &pools[mem->mem.pool_id];
|
||||
pool->free_mem[pool->n_free] = mem->mem.id;
|
||||
pool->n_free++;
|
||||
}
|
||||
|
||||
SpaResult
|
||||
spa_memory_unref (SpaMemoryRef *ref)
|
||||
{
|
||||
SpaMemory *mem;
|
||||
|
||||
if (!(mem = spa_memory_find (ref)))
|
||||
return SPA_RESULT_ERROR;
|
||||
|
||||
if (mem->mem.id > 0 && --mem->refcount == 0) {
|
||||
if (mem->notify)
|
||||
mem->notify (mem);
|
||||
|
||||
if (mem->refcount == 0)
|
||||
spa_memory_free (mem);
|
||||
}
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
SpaMemory *
|
||||
spa_memory_find (SpaMemoryRef *ref)
|
||||
{
|
||||
SpaMemoryPool *pool;
|
||||
|
||||
if (ref == NULL || ref->pool_id >= MAX_POOLS || !pools[ref->pool_id].valid || ref->id <= 0)
|
||||
return NULL;
|
||||
|
||||
pool = &pools[ref->pool_id];
|
||||
|
||||
if (ref->id >= MAX_MEMORIES || pool->memories[ref->id].refcount <= 0) {
|
||||
SPA_DEBUG_MEMORY ("can't find mem %u:%u\n", ref->pool_id, ref->id);
|
||||
}
|
||||
|
||||
return &pool->memories[ref->id];
|
||||
}
|
||||
|
||||
void *
|
||||
spa_memory_ensure_ptr (SpaMemory *mem)
|
||||
{
|
||||
int prot = 0;
|
||||
|
||||
if (mem == NULL)
|
||||
return NULL;
|
||||
|
||||
if (mem->ptr)
|
||||
return mem->ptr;
|
||||
|
||||
if (mem->flags & SPA_MEMORY_FLAG_READABLE)
|
||||
prot |= PROT_READ;
|
||||
if (mem->flags & SPA_MEMORY_FLAG_WRITABLE)
|
||||
prot |= PROT_WRITE;
|
||||
|
||||
mem->ptr = mmap (NULL, mem->size, prot, MAP_SHARED, mem->fd, 0);
|
||||
if (mem->ptr == MAP_FAILED) {
|
||||
mem->ptr = NULL;
|
||||
fprintf (stderr, "Failed to mmap memory %zd %p: %s\n", mem->size, mem, strerror (errno));
|
||||
}
|
||||
return mem->ptr;
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ spalib_sources = ['audio-raw.c',
|
|||
'control.c',
|
||||
'debug.c',
|
||||
'format.c',
|
||||
'memory.c',
|
||||
'props.c',
|
||||
'ringbuffer.c',
|
||||
'video-raw.c']
|
||||
|
|
@ -12,10 +11,6 @@ spalib = shared_library('spa-lib',
|
|||
spalib_sources,
|
||||
include_directories : spa_inc,
|
||||
install : true)
|
||||
#spalibs = static_library('spa-lib',
|
||||
# spalib_sources,
|
||||
# include_directories : spa_inc,
|
||||
# install : true)
|
||||
|
||||
spalib_dep = declare_dependency(link_with : spalib,
|
||||
include_directories : spa_inc,
|
||||
|
|
|
|||
180
spa/lib/props.c
180
spa/lib/props.c
|
|
@ -25,9 +25,9 @@
|
|||
#include <spa/props.h>
|
||||
|
||||
SpaResult
|
||||
spa_props_set_prop (SpaProps *props,
|
||||
unsigned int index,
|
||||
const SpaPropValue *value)
|
||||
spa_props_set_value (SpaProps *props,
|
||||
unsigned int index,
|
||||
const SpaPropValue *value)
|
||||
{
|
||||
const SpaPropInfo *info;
|
||||
|
||||
|
|
@ -51,9 +51,9 @@ spa_props_set_prop (SpaProps *props,
|
|||
|
||||
|
||||
SpaResult
|
||||
spa_props_get_prop (const SpaProps *props,
|
||||
unsigned int index,
|
||||
SpaPropValue *value)
|
||||
spa_props_get_value (const SpaProps *props,
|
||||
unsigned int index,
|
||||
SpaPropValue *value)
|
||||
{
|
||||
const SpaPropInfo *info;
|
||||
|
||||
|
|
@ -76,8 +76,8 @@ spa_props_get_prop (const SpaProps *props,
|
|||
}
|
||||
|
||||
SpaResult
|
||||
spa_props_copy (const SpaProps *src,
|
||||
SpaProps *dest)
|
||||
spa_props_copy_values (const SpaProps *src,
|
||||
SpaProps *dest)
|
||||
{
|
||||
int i;
|
||||
SpaResult res;
|
||||
|
|
@ -91,7 +91,7 @@ spa_props_copy (const SpaProps *src,
|
|||
|
||||
if (!(info->flags & SPA_PROP_FLAG_WRITABLE))
|
||||
continue;
|
||||
if ((res = spa_props_get_prop (src, spa_props_index_for_id (src, info->id), &value)) < 0)
|
||||
if ((res = spa_props_get_value (src, spa_props_index_for_id (src, info->id), &value)) < 0)
|
||||
continue;
|
||||
if (value.size > info->maxsize)
|
||||
return SPA_RESULT_WRONG_PROPERTY_SIZE;
|
||||
|
|
@ -102,3 +102,165 @@ spa_props_copy (const SpaProps *src,
|
|||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
size_t
|
||||
spa_props_get_size (const SpaProps *props)
|
||||
{
|
||||
size_t len;
|
||||
unsigned int i, j;
|
||||
SpaPropInfo *pi;
|
||||
SpaPropRangeInfo *ri;
|
||||
|
||||
if (props == NULL)
|
||||
return 0;
|
||||
|
||||
len = sizeof (SpaProps);
|
||||
for (i = 0; i < props->n_prop_info; i++) {
|
||||
pi = (SpaPropInfo *) &props->prop_info[i];
|
||||
len += sizeof (SpaPropInfo);
|
||||
len += pi->name ? strlen (pi->name) + 1 : 0;
|
||||
len += pi->description ? strlen (pi->description) + 1 : 0;
|
||||
/* for the value */
|
||||
len += pi->maxsize;
|
||||
for (j = 0; j < pi->n_range_values; j++) {
|
||||
ri = (SpaPropRangeInfo *)&pi->range_values[j];
|
||||
len += sizeof (SpaPropRangeInfo);
|
||||
len += ri->name ? strlen (ri->name) + 1 : 0;
|
||||
len += ri->description ? strlen (ri->description) + 1 : 0;
|
||||
/* the size of the range value */
|
||||
len += ri->val.size;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t
|
||||
spa_props_serialize (void *p, const SpaProps *props)
|
||||
{
|
||||
size_t len, slen;
|
||||
unsigned int i, j, c;
|
||||
SpaProps *tp;
|
||||
SpaPropInfo *pi;
|
||||
SpaPropRangeInfo *ri;
|
||||
|
||||
if (props == NULL)
|
||||
return 0;
|
||||
|
||||
tp = p;
|
||||
memcpy (tp, props, sizeof (SpaProps));
|
||||
pi = SPA_MEMBER (tp, sizeof(SpaProps), SpaPropInfo);
|
||||
ri = SPA_MEMBER (pi, sizeof(SpaPropInfo) * tp->n_prop_info, SpaPropRangeInfo);
|
||||
|
||||
tp->prop_info = SPA_INT_TO_PTR (SPA_PTRDIFF (pi, tp));
|
||||
|
||||
/* write propinfo array */
|
||||
for (i = 0, c = 0; i < tp->n_prop_info; i++) {
|
||||
memcpy (&pi[i], &props->prop_info[i], sizeof (SpaPropInfo));
|
||||
pi[i].range_values = SPA_INT_TO_PTR (SPA_PTRDIFF (&ri[c], tp));
|
||||
for (j = 0; j < pi[i].n_range_values; j++, c++) {
|
||||
memcpy (&ri[c], &props->prop_info[i].range_values[j], sizeof (SpaPropRangeInfo));
|
||||
}
|
||||
}
|
||||
p = &ri[c];
|
||||
/* strings and default values from props and ranges */
|
||||
for (i = 0, c = 0; i < tp->n_prop_info; i++) {
|
||||
if (pi[i].name) {
|
||||
slen = strlen (pi[i].name) + 1;
|
||||
memcpy (p, pi[i].name, slen);
|
||||
pi[i].name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
|
||||
p += slen;
|
||||
} else {
|
||||
pi[i].name = 0;
|
||||
}
|
||||
if (pi[i].description) {
|
||||
slen = strlen (pi[i].description) + 1;
|
||||
memcpy (p, pi[i].description, slen);
|
||||
pi[i].description = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
|
||||
p += slen;
|
||||
} else {
|
||||
pi[i].description = 0;
|
||||
}
|
||||
for (j = 0; j < pi[i].n_range_values; j++, c++) {
|
||||
if (ri[c].name) {
|
||||
slen = strlen (ri[c].name) + 1;
|
||||
memcpy (p, ri[c].name, slen);
|
||||
ri[c].name = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
|
||||
p += slen;
|
||||
} else {
|
||||
ri[c].name = 0;
|
||||
}
|
||||
if (ri[c].description) {
|
||||
slen = strlen (ri[c].description) + 1;
|
||||
memcpy (p, ri[c].description, slen);
|
||||
ri[c].description = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
|
||||
p += slen;
|
||||
} else {
|
||||
ri[c].description = 0;
|
||||
}
|
||||
if (ri[c].val.size) {
|
||||
memcpy (p, ri[c].val.value, ri[c].val.size);
|
||||
ri[c].val.value = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
|
||||
p += ri[c].val.size;
|
||||
} else {
|
||||
ri[c].val.value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* and the actual values */
|
||||
for (i = 0; i < tp->n_prop_info; i++) {
|
||||
if (pi[i].offset) {
|
||||
memcpy (p, SPA_MEMBER (props, pi[i].offset, void), pi[i].maxsize);
|
||||
pi[i].offset = SPA_PTRDIFF (p, tp);
|
||||
p += pi[i].maxsize;
|
||||
} else {
|
||||
pi[i].offset = 0;
|
||||
}
|
||||
}
|
||||
len = SPA_PTRDIFF (p, tp);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
SpaProps *
|
||||
spa_props_deserialize (void *p, off_t offset)
|
||||
{
|
||||
SpaProps *tp;
|
||||
unsigned int i, j;
|
||||
SpaPropInfo *pi;
|
||||
SpaPropRangeInfo *ri;
|
||||
|
||||
tp = SPA_MEMBER (p, offset, SpaProps);
|
||||
if (tp->prop_info)
|
||||
tp->prop_info = SPA_MEMBER (tp, SPA_PTR_TO_INT (tp->prop_info), SpaPropInfo);
|
||||
/* now fix all the pointers */
|
||||
for (i = 0; i < tp->n_prop_info; i++) {
|
||||
pi = (SpaPropInfo *) &tp->prop_info[i];
|
||||
if (pi->name)
|
||||
pi->name = SPA_MEMBER (tp, SPA_PTR_TO_INT (pi->name), char);
|
||||
if (pi->description)
|
||||
pi->description = SPA_MEMBER (tp, SPA_PTR_TO_INT (pi->description), char);
|
||||
if (pi->range_values)
|
||||
pi->range_values = SPA_MEMBER (tp, SPA_PTR_TO_INT (pi->range_values), SpaPropRangeInfo);
|
||||
|
||||
for (j = 0; j < pi->n_range_values; j++) {
|
||||
ri = (SpaPropRangeInfo *) &pi->range_values[j];
|
||||
if (ri->name)
|
||||
ri->name = SPA_MEMBER (tp, SPA_PTR_TO_INT (ri->name), char);
|
||||
if (ri->description)
|
||||
ri->description = SPA_MEMBER (tp, SPA_PTR_TO_INT (ri->description), char);
|
||||
if (ri->val.value)
|
||||
ri->val.value = SPA_MEMBER (tp, SPA_PTR_TO_INT (ri->val.value), void);
|
||||
}
|
||||
}
|
||||
return tp;
|
||||
}
|
||||
|
||||
SpaProps *
|
||||
spa_props_copy_into (void *dest, const SpaProps *props)
|
||||
{
|
||||
if (props == NULL)
|
||||
return NULL;
|
||||
|
||||
spa_props_serialize (dest, props);
|
||||
return spa_props_deserialize (dest, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,7 +464,7 @@ spa_prop_info_fill_video (SpaPropInfo *info,
|
|||
return SPA_RESULT_INVALID_PROPERTY_INDEX;
|
||||
|
||||
memcpy (info, &format_prop_info[i], sizeof (SpaPropInfo));
|
||||
info->offset = offset;
|
||||
info->offset = offset - sizeof (SpaFormat) + sizeof (SpaProps);
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
|
@ -619,7 +619,7 @@ spa_format_video_parse (const SpaFormat *format,
|
|||
|
||||
props = &format->props;
|
||||
idx = spa_props_index_for_id (props, SPA_PROP_ID_VIDEO_INFO);
|
||||
if ((res = spa_props_get_prop (props, idx, &value)) < 0)
|
||||
if ((res = spa_props_get_value (props, idx, &value)) < 0)
|
||||
goto fallback;
|
||||
|
||||
if (props->prop_info[idx].type != SPA_PROP_TYPE_POINTER)
|
||||
|
|
@ -631,7 +631,7 @@ spa_format_video_parse (const SpaFormat *format,
|
|||
return SPA_RESULT_OK;
|
||||
|
||||
fallback:
|
||||
res = spa_props_copy (props, &vformat->format.props);
|
||||
res = spa_props_copy_values (props, &vformat->format.props);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue