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:
Wim Taymans 2016-09-29 18:18:59 +02:00
parent fe37e2bc1b
commit 24108e01c1
46 changed files with 901 additions and 1546 deletions

View file

@ -28,7 +28,6 @@
#include <spa/poll.h>
#include <spa/monitor.h>
#include <spa/memory.h>
#include <spa/debug.h>
extern const SpaHandleFactory spa_alsa_source_factory;

View file

@ -142,7 +142,7 @@ spa_alsa_sink_node_set_props (SpaNode *node,
return SPA_RESULT_OK;
}
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
return res;
}
@ -420,10 +420,6 @@ spa_alsa_sink_node_port_alloc_buffers (SpaNode *node,
uint32_t *n_buffers)
{
SpaALSASink *this;
SpaALSABuffer *b;
unsigned int i, n_bufs;
size_t buffer_size;
uint8_t *bufmem;
if (node == NULL || node->handle == NULL || buffers == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
@ -436,63 +432,7 @@ spa_alsa_sink_node_port_alloc_buffers (SpaNode *node,
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
n_bufs = *n_buffers;
buffer_size = this->buffer_frames * this->frame_size;
if (!this->alloc_bufmem)
this->alloc_bufmem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED, NULL, buffer_size * n_bufs);
bufmem = spa_memory_ensure_ptr (this->alloc_bufmem);
if (!this->alloc_mem)
this->alloc_mem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED, NULL, sizeof (SpaALSABuffer) * n_bufs);
this->alloc_buffers = spa_memory_ensure_ptr (this->alloc_mem);
this->n_buffers = n_bufs;
for (i = 0; i < n_bufs; i++) {
b = &this->alloc_buffers[i];
b->buffer.id = i;
b->buffer.mem.mem = this->alloc_mem->mem;
b->buffer.mem.offset = sizeof (SpaALSABuffer) * i;
b->buffer.mem.size = sizeof (SpaALSABuffer);
b->buffer.n_metas = 2;
b->buffer.metas = offsetof (SpaALSABuffer, metas);
b->buffer.n_datas = 1;
b->buffer.datas = offsetof (SpaALSABuffer, datas);
b->header.flags = 0;
b->header.seq = 0;
b->header.pts = 0;
b->header.dts_offset = 0;
b->metas[0].type = SPA_META_TYPE_HEADER;
b->metas[0].offset = offsetof (SpaALSABuffer, header);
b->metas[0].size = sizeof (b->header);
b->ringbuffer.readindex = 0;
b->ringbuffer.writeindex = 0;
b->ringbuffer.size = 0;
b->ringbuffer.size_mask = 0;
b->metas[1].type = SPA_META_TYPE_RINGBUFFER;
b->metas[1].offset = offsetof (SpaALSABuffer, ringbuffer);
b->metas[1].size = sizeof (b->ringbuffer);
b->datas[0].mem.mem = this->alloc_bufmem->mem;
b->datas[0].mem.offset = buffer_size * i;
b->datas[0].mem.size = buffer_size;
b->datas[0].stride = 0;
b->ptr = bufmem + buffer_size * i;
buffers[i] = &b->buffer;
}
*n_buffers = n_bufs;
this->have_buffers = true;
update_state (this, SPA_NODE_STATE_PAUSED);
return SPA_RESULT_OK;
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
@ -556,7 +496,7 @@ spa_alsa_sink_node_port_push_input (SpaNode *node,
have_enough = true;
continue;
}
SPA_QUEUE_PUSH_TAIL (&this->ready, SpaALSABuffer, next, &this->alloc_buffers[info[i].buffer_id]);
SPA_QUEUE_PUSH_TAIL (&this->ready, SpaALSABuffer, next, &this->buffers[info[i].buffer_id]);
}
info[i].status = SPA_RESULT_OK;
}

View file

@ -144,7 +144,7 @@ spa_alsa_source_node_set_props (SpaNode *node,
return SPA_RESULT_OK;
}
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
return res;
}
@ -301,38 +301,23 @@ recycle_buffer (SpaALSASource *this, uint32_t buffer_id)
{
SpaALSABuffer *b;
b = &this->alloc_buffers[buffer_id];
b = &this->buffers[buffer_id];
if (!b->outstanding)
return;
b->outstanding = false;
b->next = NULL;
SPA_QUEUE_PUSH_TAIL (&this->free, SpaALSABuffer, next, b);
}
static SpaResult
spa_alsa_clear_buffers (SpaALSASource *this)
{
int i;
if (!this->have_buffers)
return SPA_RESULT_OK;
for (i = 0; i < this->n_buffers; i++) {
SpaALSABuffer *b;
b = &this->alloc_buffers[i];
if (b->outstanding) {
fprintf (stderr, "queueing outstanding buffer %p\n", b);
recycle_buffer (this, i);
}
}
if (this->alloc_bufmem)
spa_memory_unref (&this->alloc_bufmem->mem);
if (this->alloc_mem)
spa_memory_unref (&this->alloc_mem->mem);
this->alloc_mem = NULL;
this->alloc_bufmem = NULL;
SPA_QUEUE_INIT (&this->free);
SPA_QUEUE_INIT (&this->ready);
this->n_buffers = 0;
this->have_buffers = false;
@ -459,6 +444,7 @@ spa_alsa_source_node_port_use_buffers (SpaNode *node,
{
SpaALSASource *this;
SpaResult res;
int i;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
@ -475,8 +461,17 @@ spa_alsa_source_node_port_use_buffers (SpaNode *node,
if ((res = spa_alsa_clear_buffers (this)) < 0)
return res;
}
if (buffers != NULL)
return SPA_RESULT_NOT_IMPLEMENTED;
if (n_buffers > 0) {
for (i = 0; i < n_buffers; i++) {
SpaALSABuffer *b = &this->buffers[i];
b->outbuf = buffers[i];
b->outstanding = false;
b->next = NULL;
SPA_QUEUE_PUSH_TAIL (&this->free, SpaALSABuffer, next, b);
}
this->n_buffers = n_buffers;
this->have_buffers = true;
}
if (this->have_buffers)
update_state (this, SPA_NODE_STATE_PAUSED);
@ -496,10 +491,6 @@ spa_alsa_source_node_port_alloc_buffers (SpaNode *node,
uint32_t *n_buffers)
{
SpaALSASource *this;
SpaALSABuffer *b;
unsigned int i, n_bufs;
uint8_t *bufmem;
size_t buffer_size;
if (node == NULL || node->handle == NULL || buffers == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
@ -512,73 +503,7 @@ spa_alsa_source_node_port_alloc_buffers (SpaNode *node,
if (!this->have_format)
return SPA_RESULT_NO_FORMAT;
n_bufs = *n_buffers;
SPA_QUEUE_INIT (&this->free);
SPA_QUEUE_INIT (&this->ready);
buffer_size = this->buffer_frames * this->frame_size;
if (!this->alloc_bufmem)
this->alloc_bufmem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED,
NULL,
buffer_size * n_bufs);
bufmem = spa_memory_ensure_ptr (this->alloc_bufmem);
if (!this->alloc_mem)
this->alloc_mem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED, NULL, sizeof (SpaALSABuffer) * n_bufs);
this->alloc_buffers = spa_memory_ensure_ptr (this->alloc_mem);
this->n_buffers = n_bufs;
for (i = 0; i < n_bufs; i++) {
b = &this->alloc_buffers[i];
b->buffer.id = i;
b->buffer.mem.mem = this->alloc_mem->mem;
b->buffer.mem.offset = sizeof (SpaALSABuffer) * i;
b->buffer.mem.size = sizeof (SpaALSABuffer);
b->buffer.n_metas = 2;
b->buffer.metas = offsetof (SpaALSABuffer, metas);
b->buffer.n_datas = 1;
b->buffer.datas = offsetof (SpaALSABuffer, datas);
b->header.flags = 0;
b->header.seq = 0;
b->header.pts = 0;
b->header.dts_offset = 0;
b->metas[0].type = SPA_META_TYPE_HEADER;
b->metas[0].offset = offsetof (SpaALSABuffer, header);
b->metas[0].size = sizeof (b->header);
b->ringbuffer.readindex = 0;
b->ringbuffer.writeindex = 0;
b->ringbuffer.size = 0;
b->ringbuffer.size_mask = 0;
b->metas[1].type = SPA_META_TYPE_RINGBUFFER;
b->metas[1].offset = offsetof (SpaALSABuffer, ringbuffer);
b->metas[1].size = sizeof (b->ringbuffer);
b->datas[0].mem.mem = this->alloc_bufmem->mem;
b->datas[0].mem.offset = buffer_size * i;
b->datas[0].mem.size = buffer_size;
b->datas[0].stride = 0;
b->ptr = bufmem + buffer_size * i;
b->h = &b->header;
buffers[i] = b->outbuf = &b->buffer;
b->outstanding = true;
recycle_buffer (this, b->outbuf->id);
}
*n_buffers = n_bufs;
this->have_buffers = true;
update_state (this, SPA_NODE_STATE_PAUSED);
return SPA_RESULT_OK;
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult

View file

@ -309,7 +309,7 @@ mmap_read (SpaALSAState *state)
SpaALSABuffer *b;
snd_htimestamp_t htstamp = { 0, 0 };
int64_t now;
uint8_t *dest;
uint8_t *dest = NULL;
snd_pcm_status_alloca(&status);
@ -374,8 +374,8 @@ mmap_read (SpaALSAState *state)
SpaNodeEventHaveOutput ho;
SpaData *d;
d = SPA_BUFFER_DATAS (b->outbuf);
d[0].mem.size = avail * state->frame_size;
d = b->outbuf->datas;
d[0].size = avail * state->frame_size;
b->next = NULL;
SPA_QUEUE_PUSH_TAIL (&state->ready, SpaALSABuffer, next, b);

View file

@ -45,12 +45,9 @@ typedef struct {
bool period_event;
} SpaALSAProps;
#define MAX_BUFFERS 16
struct _SpaALSABuffer {
SpaBuffer buffer;
SpaMeta metas[2];
SpaMetaHeader header;
SpaMetaRingbuffer ringbuffer;
SpaData datas[1];
SpaBuffer *outbuf;
SpaMetaHeader *h;
void *ptr;
@ -90,9 +87,7 @@ struct _SpaALSAState {
SpaPortStatus status;
bool have_buffers;
SpaMemory *alloc_bufmem;
SpaMemory *alloc_mem;
SpaALSABuffer *alloc_buffers;
SpaALSABuffer buffers[MAX_BUFFERS];
unsigned int n_buffers;
SpaQueue free;

View file

@ -21,7 +21,6 @@
#include <stdio.h>
#include <spa/node.h>
#include <spa/memory.h>
#include <spa/audio/format.h>
#define MAX_PORTS 128
@ -126,7 +125,7 @@ spa_audiomixer_node_set_props (SpaNode *node,
reset_audiomixer_props (p);
return SPA_RESULT_OK;
}
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
return res;
}
@ -531,7 +530,7 @@ spa_audiomixer_node_port_push_input (SpaNode *node,
continue;
}
this->ports[idx].buffer = buffer;
this->ports[idx].buffer_queued = buffer->mem.size;
this->ports[idx].buffer_queued = 0;
this->ports[idx].buffer_index = 0;
this->ports[idx].buffer_offset = 0;
this->port_queued++;
@ -567,22 +566,19 @@ add_port_data (SpaAudioMixer *this, SpaBuffer *out, SpaAudioMixerPort *port)
int i, oi = 0;
uint8_t *op, *ip;
size_t os, is, chunk;
SpaData *odatas = SPA_BUFFER_DATAS (out);
SpaData *idatas = SPA_BUFFER_DATAS (port->buffer);
SpaMemory *mem;
SpaData *odatas = out->datas;
SpaData *idatas = port->buffer->datas;
op = ip = NULL;
while (true) {
if (op == NULL) {
mem = spa_memory_find (&odatas[oi].mem.mem);
op = (uint8_t*)mem->ptr + odatas[oi].mem.offset;
os = odatas[oi].mem.size;
op = (uint8_t*)odatas[oi].data + odatas[oi].offset;
os = odatas[oi].size;
}
if (ip == NULL) {
mem = spa_memory_find (&idatas[port->buffer_index].mem.mem);
ip = (uint8_t*)mem->ptr + odatas[oi].mem.offset;
is = idatas[port->buffer_index].mem.size;
ip = (uint8_t*)idatas[port->buffer_index].data + idatas[port->buffer_index].offset;
is = idatas[port->buffer_index].size;
ip += port->buffer_offset;
is -= port->buffer_offset;
}

View file

@ -42,13 +42,11 @@ typedef struct {
bool live;
} SpaAudioTestSrcProps;
#define MAX_BUFFERS 16
typedef struct _ATSBuffer ATSBuffer;
struct _ATSBuffer {
SpaBuffer buffer;
SpaMeta metas[1];
SpaMetaHeader header;
SpaData datas[1];
SpaBuffer *outbuf;
bool outstanding;
ATSBuffer *next;
@ -83,8 +81,7 @@ struct _SpaAudioTestSrc {
size_t bpf;
bool have_buffers;
SpaMemory *alloc_mem;
ATSBuffer *alloc_buffers;
ATSBuffer buffers[MAX_BUFFERS];
unsigned int n_buffers;
bool started;
@ -205,7 +202,7 @@ spa_audiotestsrc_node_set_props (SpaNode *node,
if (props == NULL) {
res = reset_audiotestsrc_props (p);
} else {
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
}
if (this->props[1].live)
@ -528,13 +525,8 @@ clear_buffers (SpaAudioTestSrc *this)
{
if (this->have_buffers) {
fprintf (stderr, "audiotestsrc %p: clear buffers\n", this);
if (this->alloc_mem)
spa_memory_unref (&this->alloc_mem->mem);
this->alloc_mem = NULL;
this->alloc_buffers = NULL;
this->n_buffers = 0;
this->have_buffers = false;
this->info.flags &= ~SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS;
SPA_QUEUE_INIT (&this->empty);
SPA_QUEUE_INIT (&this->ready);
}
@ -675,26 +667,16 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
return SPA_RESULT_NO_FORMAT;
clear_buffers (this);
if (buffers != NULL && n_buffers != 0) {
unsigned int i, j;
this->alloc_mem = spa_memory_alloc_size (SPA_MEMORY_POOL_LOCAL,
NULL,
sizeof (ATSBuffer) * n_buffers);
this->alloc_buffers = spa_memory_ensure_ptr (this->alloc_mem);
for (i = 0; i < n_buffers; i++) {
ATSBuffer *b;
SpaMemoryRef *mem_ref;
SpaMemory *mem;
SpaData *d = SPA_BUFFER_DATAS (buffers[i]);
SpaMeta *m = SPA_BUFFER_METAS (buffers[i]);
SpaData *d = buffers[i]->datas;
SpaMeta *m = buffers[i]->metas;
b = &this->alloc_buffers[i];
b->buffer.mem.mem = this->alloc_mem->mem;
b->buffer.mem.offset = sizeof (ATSBuffer) * i;
b->buffer.mem.size = sizeof (ATSBuffer);
b->buffer.id = SPA_ID_INVALID;
b = &this->buffers[i];
b->outbuf = buffers[i];
b->outstanding = true;
b->h = NULL;
@ -702,29 +684,25 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
for (j = 0; j < buffers[i]->n_metas; j++) {
switch (m[j].type) {
case SPA_META_TYPE_HEADER:
b->h = SPA_MEMBER (buffers[i], m[j].offset, SpaMetaHeader);
b->h = m[j].data;
break;
default:
break;
}
}
mem_ref = &d[0].mem.mem;
if (!(mem = spa_memory_find (mem_ref))) {
if (buffers[i]->n_datas < 1 || d[0].type != SPA_DATA_TYPE_MEMPTR) {
fprintf (stderr, "audiotestsrc %p: invalid memory on buffer %p\n", this, buffers[i]);
continue;
}
b->ptr = SPA_MEMBER (spa_memory_ensure_ptr (mem), d[0].mem.offset, void);
b->size = d[0].mem.size;
b->ptr = SPA_MEMBER (d[0].data, d[0].offset, void);
b->size = d[0].size;
b->next = NULL;
SPA_QUEUE_PUSH_TAIL (&this->empty, ATSBuffer, next, b);
}
this->n_buffers = n_buffers;
this->have_buffers = true;
this->info.flags |= SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS;
} else {
this->info.flags &= ~SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS;
}
if (this->have_buffers) {
@ -745,7 +723,6 @@ spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node,
uint32_t *n_buffers)
{
SpaAudioTestSrc *this;
unsigned int i;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
@ -761,12 +738,7 @@ spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node,
if (!this->have_buffers)
return SPA_RESULT_NO_BUFFERS;
*n_buffers = SPA_MIN (*n_buffers, this->n_buffers);
for (i = 0; i < *n_buffers; i++)
buffers[i] = this->alloc_buffers[i].outbuf;
return SPA_RESULT_OK;
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
@ -791,7 +763,7 @@ spa_audiotestsrc_node_port_reuse_buffer (SpaNode *node,
if (buffer_id >= this->n_buffers)
return SPA_RESULT_INVALID_BUFFER_ID;
b = &this->alloc_buffers[buffer_id];
b = &this->buffers[buffer_id];
if (!b->outstanding)
return SPA_RESULT_OK;

View file

@ -122,7 +122,7 @@ spa_ffmpeg_dec_node_set_props (SpaNode *node,
return SPA_RESULT_OK;
}
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
return res;
}

View file

@ -128,7 +128,7 @@ spa_ffmpeg_enc_node_set_props (SpaNode *node,
return SPA_RESULT_OK;
}
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
return res;
}

View file

@ -116,7 +116,7 @@ spa_libva_dec_node_set_props (SpaHandle *handle,
return SPA_RESULT_OK;
}
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
return res;
}

View file

@ -116,7 +116,7 @@ spa_libva_enc_node_set_props (SpaHandle *handle,
return SPA_RESULT_OK;
}
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
return res;
}

View file

@ -30,19 +30,33 @@
#include <spa/control.h>
#include <spa/debug.h>
#include <spa/memory.h>
#include <spa/node.h>
#include <spa/queue.h>
#include <spa/queue.h>
#include "../lib/memfd-wrappers.h"
#define MAX_INPUTS 64
#define MAX_OUTPUTS 64
#define MAX_PORTS (MAX_INPUTS + MAX_OUTPUTS)
#define MAX_BUFFERS 16
#define CHECK_FREE_PORT_ID(this,id) ((id) < MAX_PORTS && !(this)->ports[id].valid)
#define CHECK_PORT_ID(this,id) ((id) < MAX_PORTS && (this)->ports[id].valid)
#define CHECK_PORT_ID_IN(this,id) (CHECK_PORT_ID(this,id) && (id < this->max_inputs))
#define CHECK_PORT_ID_OUT(this,id) (CHECK_PORT_ID(this,id) && (id >= this->max_inputs))
typedef struct _SpaProxy SpaProxy;
typedef struct _ProxyBuffer ProxyBuffer;
struct _ProxyBuffer {
SpaBuffer *outbuf;
SpaBuffer buffer;
SpaData datas[4];
off_t offset;
size_t size;
};
typedef struct {
SpaProps props;
@ -56,9 +70,17 @@ typedef struct {
unsigned int n_formats;
SpaFormat **formats;
SpaPortStatus status;
unsigned int n_buffers;
SpaBuffer **buffers;
ProxyBuffer buffers[MAX_BUFFERS];
uint32_t buffer_mem_id;
int buffer_mem_fd;
size_t buffer_mem_size;
void *buffer_mem_ptr;
uint32_t buffer_id;
SpaQueue ready;
} SpaProxyPort;
struct _SpaProxy {
@ -144,6 +166,19 @@ send_async_complete (SpaProxy *this, uint32_t seq, SpaResult res)
this->event_cb (&this->node, &event, this->user_data);
}
static SpaResult
clear_buffers (SpaProxy *this, SpaProxyPort *port)
{
if (port->n_buffers) {
fprintf (stderr, "proxy %p: clear buffers\n", this);
port->n_buffers = 0;
SPA_QUEUE_INIT (&port->ready);
}
return SPA_RESULT_OK;
}
static SpaResult
spa_proxy_node_get_props (SpaNode *node,
SpaProps **props)
@ -183,7 +218,7 @@ spa_proxy_node_set_props (SpaNode *node,
}
/* copy new properties */
res = spa_props_copy (props, &np->props);
res = spa_props_copy_values (props, &np->props);
/* compare changes */
if (op->socketfd != np->socketfd)
@ -340,15 +375,26 @@ do_update_port (SpaProxy *this,
{
SpaProxyPort *port;
unsigned int i;
size_t size;
port = &this->ports[pu->port_id];
if (pu->change_mask & SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS) {
port->n_formats = pu->n_possible_formats;
port->formats = pu->possible_formats;
for (i = 0; i < port->n_formats; i++)
free (port->formats[i]);
port->n_formats = pu->n_possible_formats;
port->formats = realloc (port->formats, port->n_formats * sizeof (SpaFormat *));
for (i = 0; i < port->n_formats; i++) {
size = spa_format_get_size (pu->possible_formats[i]);
port->formats[i] = spa_format_copy_into (malloc (size), pu->possible_formats[i]);
spa_debug_format (port->formats[i]);
}
}
if (pu->change_mask & SPA_CONTROL_CMD_PORT_UPDATE_FORMAT) {
if (port->format)
free (port->format);
size = spa_format_get_size (pu->format);
port->format = spa_format_copy_into (malloc (size), pu->format);
}
if (pu->change_mask & SPA_CONTROL_CMD_PORT_UPDATE_PROPS) {
@ -386,7 +432,7 @@ do_uninit_port (SpaProxy *this,
port->valid = false;
if (port->format)
spa_format_unref (port->format);
free (port->format);
port->format = NULL;
}
@ -406,11 +452,13 @@ spa_proxy_node_add_port (SpaNode *node,
return SPA_RESULT_INVALID_PORT;
pu.change_mask = SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS |
SPA_CONTROL_CMD_PORT_UPDATE_FORMAT |
SPA_CONTROL_CMD_PORT_UPDATE_PROPS |
SPA_CONTROL_CMD_PORT_UPDATE_INFO;
pu.port_id = port_id;
pu.n_possible_formats = 0;
pu.possible_formats = NULL;
pu.format = NULL;
pu.props = NULL;
pu.info = NULL;
do_update_port (this, &pu);
@ -476,7 +524,6 @@ spa_proxy_node_port_set_format (SpaNode *node,
const SpaFormat *format)
{
SpaProxy *this;
SpaProxyPort *port;
SpaControl control;
SpaControlBuilder builder;
SpaControlCmdSetFormat sf;
@ -491,11 +538,8 @@ spa_proxy_node_port_set_format (SpaNode *node,
if (!CHECK_PORT_ID (this, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0);
sf.seq = this->seq++;
sf.port_id = port_id;
sf.flags = flags;
sf.format = (SpaFormat *) format;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_SET_FORMAT, &sf);
@ -506,8 +550,6 @@ spa_proxy_node_port_set_format (SpaNode *node,
spa_control_clear (&control);
port->format = format;
return SPA_RESULT_RETURN_ASYNC (sf.seq);
}
@ -602,58 +644,6 @@ spa_proxy_node_port_get_status (SpaNode *node,
return SPA_RESULT_OK;
}
static SpaResult
add_buffer_mem (SpaProxy *this, SpaControlBuilder *builder, uint32_t port_id, SpaBuffer *buffer)
{
SpaControlCmdAddMem am;
int i;
SpaBuffer *b;
SpaMemory *bmem;
if (buffer->mem.mem.id == SPA_ID_INVALID) {
fprintf (stderr, "proxy %p: alloc buffer space %zd\n", this, buffer->mem.size);
bmem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED, buffer, buffer->mem.size);
b = spa_memory_ensure_ptr (bmem);
b->mem.mem = bmem->mem;
b->mem.offset = 0;
} else {
bmem = spa_memory_find (&buffer->mem.mem);
b = buffer;
}
am.port_id = port_id;
am.mem = bmem->mem;
am.mem_type = 0;
am.fd_index = spa_control_builder_add_fd (builder, bmem->fd, false);
am.flags = bmem->flags;
am.size = bmem->size;
spa_control_builder_add_cmd (builder, SPA_CONTROL_CMD_ADD_MEM, &am);
for (i = 0; i < b->n_datas; i++) {
SpaData *d = &SPA_BUFFER_DATAS (b)[i];
SpaMemory *mem;
if (!(mem = spa_memory_find (&d->mem.mem))) {
fprintf (stderr, "proxy %p: error invalid memory\n", this);
continue;
}
if (mem->fd == -1) {
fprintf (stderr, "proxy %p: error memory without fd\n", this);
continue;
}
am.port_id = port_id;
am.mem = mem->mem;
am.mem_type = 0;
am.fd_index = spa_control_builder_add_fd (builder, mem->fd, false);
am.flags = mem->flags;
am.size = mem->size;
spa_control_builder_add_cmd (builder, SPA_CONTROL_CMD_ADD_MEM, &am);
}
return SPA_RESULT_OK;
}
static SpaResult
spa_proxy_node_port_use_buffers (SpaNode *node,
uint32_t port_id,
@ -662,13 +652,17 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
{
SpaProxy *this;
SpaProxyPort *port;
unsigned int i;
unsigned int i, j;
SpaControl control;
SpaControlBuilder builder;
uint8_t buf[4096];
int fds[32];
SpaResult res;
SpaControlCmdAddMem am;
SpaControlCmdUseBuffers ub;
size_t size, n_mem;
SpaControlMemRef *memref;
void *p;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
@ -684,25 +678,85 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
if (!port->format)
return SPA_RESULT_NO_FORMAT;
if (port->n_buffers == n_buffers && port->buffers == buffers)
return SPA_RESULT_OK;
clear_buffers (this, port);
spa_control_builder_init_into (&builder, buf, sizeof (buf), fds, SPA_N_ELEMENTS (fds));
if (buffers == NULL || n_buffers == 0) {
port->buffers = NULL;
port->n_buffers = 0;
} else {
port->buffers = buffers;
port->n_buffers = n_buffers;
/* find size to store buffers */
size = 0;
n_mem = 0;
for (i = 0; i < n_buffers; i++) {
ProxyBuffer *b = &port->buffers[i];
b->outbuf = buffers[i];
memcpy (&b->buffer, buffers[i], sizeof (SpaBuffer));
b->buffer.datas = b->datas;
b->size = spa_buffer_get_size (buffers[i]);
b->offset = size;
size += b->size;
for (j = 0; j < buffers[i]->n_datas; j++) {
SpaData *d = &buffers[i]->datas[j];
memcpy (&b->buffer.datas[j], d, sizeof (SpaData));
am.port_id = port_id;
am.mem_id = n_mem;
am.fd_index = spa_control_builder_add_fd (&builder, SPA_PTR_TO_INT (d->data), false);
am.flags = 0;
am.offset = d->offset;
am.size = d->size;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_MEM, &am);
b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem);
n_mem++;
}
}
for (i = 0; i < port->n_buffers; i++)
add_buffer_mem (this, &builder, port_id, port->buffers[i]);
/* make mem for the buffers */
port->buffer_mem_id = n_mem;
port->buffer_mem_size = size;
port->buffer_mem_fd = memfd_create ("spa-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (ftruncate (port->buffer_mem_fd, size) < 0) {
fprintf (stderr, "Failed to truncate temporary file: %s\n", strerror (errno));
close (port->buffer_mem_fd);
}
{
unsigned int seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL;
if (fcntl (port->buffer_mem_fd, F_ADD_SEALS, seals) == -1) {
fprintf (stderr, "Failed to add seals: %s\n", strerror (errno));
close (port->buffer_mem_fd);
}
}
p = port->buffer_mem_ptr = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, port->buffer_mem_fd, 0);
for (i = 0; i < n_buffers; i++)
p += spa_buffer_serialize (p, &port->buffers[i].buffer);
am.port_id = port_id;
am.mem_id = port->buffer_mem_id;
am.fd_index = spa_control_builder_add_fd (&builder, port->buffer_mem_fd, false);
am.flags = 0;
am.offset = 0;
am.size = size;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_MEM, &am);
memref = alloca (n_mem * sizeof (SpaControlMemRef));
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;
}
port->n_buffers = n_buffers;
ub.seq = this->seq++;
ub.port_id = port_id;
ub.n_buffers = port->n_buffers;
ub.buffers = port->buffers;
ub.buffers = memref;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_USE_BUFFERS, &ub);
spa_control_builder_end (&builder, &control);
@ -981,24 +1035,13 @@ parse_control (SpaProxy *this,
{
SpaControlCmdPortUpdate pu;
bool remove;
SpaMemory *mem;
void *data;
size_t size;
data = spa_control_iter_get_data (&it, &size);
mem = spa_memory_alloc_size (SPA_MEMORY_POOL_LOCAL, data, size);
spa_control_iter_set_data (&it, spa_memory_ensure_ptr (mem), size);
fprintf (stderr, "proxy %p: got port update %d\n", this, cmd);
if (spa_control_iter_parse_cmd (&it, &pu) < 0) {
spa_memory_unref (&mem->mem);
if (spa_control_iter_parse_cmd (&it, &pu) < 0)
break;
}
if (pu.port_id >= MAX_PORTS) {
spa_memory_unref (&mem->mem);
if (pu.port_id >= MAX_PORTS)
break;
}
remove = (pu.change_mask == 0);

View file

@ -28,7 +28,6 @@
#include <spa/poll.h>
#include <spa/monitor.h>
#include <spa/memory.h>
#include <spa/debug.h>
extern const SpaHandleFactory spa_v4l2_source_factory;

View file

@ -25,7 +25,6 @@
#include <linux/videodev2.h>
#include <spa/node.h>
#include <spa/memory.h>
#include <spa/video/format.h>
#include <spa/debug.h>
#include <spa/queue.h>
@ -53,15 +52,11 @@ reset_v4l2_source_props (SpaV4l2SourceProps *props)
typedef struct _V4l2Buffer V4l2Buffer;
struct _V4l2Buffer {
SpaBuffer buffer;
SpaMeta metas[1];
SpaMetaHeader header;
SpaData datas[1];
SpaBuffer *outbuf;
SpaMetaHeader *h;
bool outstanding;
struct v4l2_buffer v4l2_buffer;
V4l2Buffer *next;
int dmafd;
};
typedef struct _V4l2Format V4l2Format;
@ -104,8 +99,7 @@ typedef struct {
enum v4l2_memory memtype;
struct v4l2_requestbuffers reqbuf;
SpaMemory *alloc_mem;
V4l2Buffer *alloc_buffers;
V4l2Buffer buffers[MAX_BUFFERS];
SpaQueue ready;
SpaPollFd fds[1];
@ -206,7 +200,7 @@ spa_v4l2_source_node_set_props (SpaNode *node,
return SPA_RESULT_OK;
}
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
return res;
}
@ -421,7 +415,7 @@ spa_v4l2_source_node_port_set_format (SpaNode *node,
spa_v4l2_format_init (f);
f->fmt.media_type = format->media_type;
f->fmt.media_subtype = format->media_subtype;
if ((res = spa_props_copy (&format->props, &f->fmt.props) < 0))
if ((res = spa_props_copy_values (&format->props, &f->fmt.props) < 0))
return res;
} else {
f = (V4l2Format*)format;

View file

@ -75,7 +75,7 @@ static SpaResult
spa_v4l2_buffer_recycle (SpaV4l2Source *this, uint32_t buffer_id)
{
SpaV4l2State *state = &this->state[0];
V4l2Buffer *b = &state->alloc_buffers[buffer_id];
V4l2Buffer *b = &state->buffers[buffer_id];
if (!b->outstanding)
return SPA_RESULT_OK;
@ -100,18 +100,13 @@ spa_v4l2_clear_buffers (SpaV4l2Source *this)
for (i = 0; i < state->reqbuf.count; i++) {
V4l2Buffer *b;
b = &state->alloc_buffers[i];
b = &state->buffers[i];
if (b->outstanding) {
fprintf (stderr, "queueing outstanding buffer %p\n", b);
spa_v4l2_buffer_recycle (this, i);
}
if (b->buffer.n_datas > 0)
spa_memory_unref (&b->datas[0].mem.mem);
}
if (state->alloc_mem)
spa_memory_unref (&state->alloc_mem->mem);
state->alloc_mem = NULL;
state->have_buffers = false;
return SPA_RESULT_OK;
@ -317,7 +312,7 @@ enum_filter_format (const SpaFormat *filter, unsigned int index)
if (pi->type != SPA_PROP_TYPE_UINT32)
return SPA_VIDEO_FORMAT_UNKNOWN;
res = spa_props_get_prop (&filter->props, idx, &val);
res = spa_props_get_value (&filter->props, idx, &val);
if (res >= 0) {
if (index == 0)
video_format = *((SpaVideoFormat *)val.value);
@ -501,7 +496,7 @@ next_frmsize:
if (pi->type != SPA_PROP_TYPE_RECTANGLE)
return SPA_RESULT_ENUM_END;
res = spa_props_get_prop (&filter->props, idx, &val);
res = spa_props_get_value (&filter->props, idx, &val);
if (res >= 0) {
const SpaRectangle *size = val.value;
@ -588,7 +583,6 @@ have_size:
fmt->fmt.props.prop_info = fmt->infos;
fmt->fmt.props.n_prop_info = pi = 0;
fmt->fmt.props.unset_mask = 0;
fmt->fmt.mem.mem.pool_id = SPA_ID_INVALID;
if (info->media_subtype == SPA_MEDIA_SUBTYPE_RAW) {
spa_prop_info_fill_video (&fmt->infos[pi],
@ -642,7 +636,7 @@ have_size:
if (pi->type != SPA_PROP_TYPE_FRACTION)
return SPA_RESULT_ENUM_END;
res = spa_props_get_prop (&filter->props, idx, &val);
res = spa_props_get_value (&filter->props, idx, &val);
if (res == 0) {
if (filter_framerate (&state->frmival, val.value,
val.value,
@ -814,6 +808,7 @@ mmap_read (SpaV4l2Source *this)
struct v4l2_buffer buf;
V4l2Buffer *b;
SpaData *d;
int64_t pts;
CLEAR(buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@ -830,24 +825,27 @@ mmap_read (SpaV4l2Source *this)
}
}
b = &state->alloc_buffers[buf.index];
b->header.flags = SPA_BUFFER_FLAG_NONE;
if (buf.flags & V4L2_BUF_FLAG_ERROR)
b->header.flags |= SPA_BUFFER_FLAG_CORRUPTED;
state->last_ticks = (int64_t)buf.timestamp.tv_sec * SPA_USEC_PER_SEC + (uint64_t)buf.timestamp.tv_usec;
b->header.seq = buf.sequence;
b->header.pts = state->last_ticks * 1000;
pts = state->last_ticks * 1000;
if (buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC)
state->last_monotonic = b->header.pts;
state->last_monotonic = pts;
else
state->last_monotonic = SPA_TIME_INVALID;
d = SPA_BUFFER_DATAS (b->outbuf);
d[0].mem.size = buf.bytesused;
b = &state->buffers[buf.index];
if (b->h) {
b->h->flags = SPA_BUFFER_FLAG_NONE;
if (buf.flags & V4L2_BUF_FLAG_ERROR)
b->h->flags |= SPA_BUFFER_FLAG_CORRUPTED;
b->h->seq = buf.sequence;
b->h->pts = pts;
}
d = b->outbuf->datas;
d[0].size = buf.bytesused;
b->next = NULL;
SPA_QUEUE_PUSH_TAIL (&state->ready, V4l2Buffer, next, b);
return SPA_RESULT_OK;
@ -900,49 +898,28 @@ spa_v4l2_use_buffers (SpaV4l2Source *this, SpaBuffer **buffers, uint32_t n_buffe
}
state->reqbuf = reqbuf;
if (state->alloc_mem)
spa_memory_unref (&state->alloc_mem->mem);
state->alloc_mem = spa_memory_alloc_size (SPA_MEMORY_POOL_LOCAL,
NULL,
sizeof (V4l2Buffer) * reqbuf.count);
state->alloc_buffers = spa_memory_ensure_ptr (state->alloc_mem);
for (i = 0; i < reqbuf.count; i++) {
V4l2Buffer *b;
SpaMemoryRef *mem_ref;
SpaMemory *mem;
SpaData *d;
b = &state->alloc_buffers[i];
b->buffer.mem.mem = state->alloc_mem->mem;
b->buffer.mem.offset = sizeof (V4l2Buffer) * i;
b->buffer.mem.size = sizeof (V4l2Buffer);
b->buffer.id = SPA_ID_INVALID;
b->buffer.n_metas = 0;
b->buffer.n_datas = 0;
b = &state->buffers[i];
b->outbuf = buffers[i];
b->outstanding = true;
fprintf (stderr, "import buffer %p\n", buffers[i]);
d = SPA_BUFFER_DATAS (buffers[i]);
mem_ref = &d[0].mem.mem;
if (!(mem = spa_memory_find (mem_ref))) {
fprintf (stderr, "invalid memory on buffer %p\n", buffers[i]);
continue;
}
if (buffers[i]->n_datas < 1) {
fprintf (stderr, "invalid memory on buffer %p\n", buffers[i]);
continue;
}
d = buffers[i]->datas;
CLEAR (b->v4l2_buffer);
b->v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
b->v4l2_buffer.memory = state->memtype;
b->v4l2_buffer.index = i;
b->v4l2_buffer.m.userptr = (unsigned long) SPA_MEMBER (mem->ptr, d[0].mem.offset, void *);
b->v4l2_buffer.length = d[0].mem.size;
b->v4l2_buffer.m.userptr = (unsigned long) SPA_MEMBER (d[0].data, d[0].offset, void *);
b->v4l2_buffer.length = d[0].size;
spa_v4l2_buffer_recycle (this, buffers[i]->id);
}
@ -986,57 +963,33 @@ mmap_init (SpaV4l2Source *this,
state->reqbuf = reqbuf;
if (state->alloc_mem)
spa_memory_unref (&state->alloc_mem->mem);
state->alloc_mem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED,
NULL,
sizeof (V4l2Buffer) * reqbuf.count);
state->alloc_buffers = spa_memory_ensure_ptr (state->alloc_mem);
for (i = 0; i < reqbuf.count; i++) {
struct v4l2_buffer buf;
V4l2Buffer *b;
SpaMemory *mem;
SpaData *d;
CLEAR (buf);
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = state->memtype;
buf.index = i;
if (buffers[i]->n_datas < 1) {
fprintf (stderr, "invalid buffer data\n");
return SPA_RESULT_ERROR;
}
if (xioctl (state->fd, VIDIOC_QUERYBUF, &buf) < 0) {
b = &state->buffers[i];
b->outbuf = buffers[i];
b->outstanding = true;
CLEAR (b->v4l2_buffer);
b->v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
b->v4l2_buffer.memory = state->memtype;
b->v4l2_buffer.index = i;
if (xioctl (state->fd, VIDIOC_QUERYBUF, &b->v4l2_buffer) < 0) {
perror ("VIDIOC_QUERYBUF");
return SPA_RESULT_ERROR;
}
b = &state->alloc_buffers[i];
b->buffer.id = i;
b->buffer.mem.mem = state->alloc_mem->mem;
b->buffer.mem.offset = sizeof (V4l2Buffer) * i;
b->buffer.mem.size = sizeof (V4l2Buffer);
buffers[i] = &b->buffer;
b->buffer.n_metas = 1;
b->buffer.metas = offsetof (V4l2Buffer, metas);
b->buffer.n_datas = 1;
b->buffer.datas = offsetof (V4l2Buffer, datas);
b->header.flags = 0;
b->header.seq = 0;
b->header.pts = 0;
b->header.dts_offset = 0;
b->metas[0].type = SPA_META_TYPE_HEADER;
b->metas[0].offset = offsetof (V4l2Buffer, header);
b->metas[0].size = sizeof (b->header);
mem = spa_memory_alloc (SPA_MEMORY_POOL_SHARED);
mem->flags = SPA_MEMORY_FLAG_READABLE;
mem->size = buf.length;
b->datas[0].mem.mem = mem->mem;
b->datas[0].mem.offset = 0;
b->datas[0].mem.size = buf.length;
b->datas[0].stride = state->fmt.fmt.pix.bytesperline;
d = buffers[i]->datas;
d[0].offset = 0;
d[0].size = b->v4l2_buffer.length;
d[0].stride = state->fmt.fmt.pix.bytesperline;
if (state->export_buf) {
struct v4l2_exportbuffer expbuf;
@ -1048,33 +1001,21 @@ mmap_init (SpaV4l2Source *this,
perror("VIDIOC_EXPBUF");
continue;
}
mem->fd = expbuf.fd;
mem->type = "dmabuf";
mem->ptr = NULL;
b->dmafd = expbuf.fd;
d[0].type = SPA_DATA_TYPE_FD;
d[0].data = SPA_INT_TO_PTR (expbuf.fd);
} else {
mem->fd = -1;
mem->type = "sysmem";
mem->ptr = mmap (NULL,
buf.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
state->fd,
buf.m.offset);
if (mem->ptr == MAP_FAILED) {
d[0].type = SPA_DATA_TYPE_MEMPTR;
d[0].data = mmap (NULL,
b->v4l2_buffer.length,
PROT_READ | PROT_WRITE,
MAP_SHARED,
state->fd,
b->v4l2_buffer.m.offset);
if (d[0].data == MAP_FAILED) {
perror ("mmap");
continue;
}
}
b->outbuf = &b->buffer;
b->outstanding = true;
CLEAR (b->v4l2_buffer);
b->v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
b->v4l2_buffer.memory = state->memtype;
b->v4l2_buffer.index = i;
spa_v4l2_buffer_recycle (this, i);
}
state->have_buffers = true;
@ -1103,18 +1044,9 @@ spa_v4l2_alloc_buffers (SpaV4l2Source *this,
{
SpaResult res;
SpaV4l2State *state = &this->state[0];
unsigned int i;
if (state->have_buffers) {
if (*n_buffers < state->reqbuf.count)
return SPA_RESULT_NO_BUFFERS;
*n_buffers = state->reqbuf.count;
for (i = 0; i < state->reqbuf.count; i++) {
buffers[i] = &state->alloc_buffers[i].buffer;
}
return SPA_RESULT_OK;
}
if (state->have_buffers)
return SPA_RESULT_ERROR;
if (state->cap.capabilities & V4L2_CAP_STREAMING) {
if ((res = mmap_init (this, params, n_params, buffers, n_buffers)) < 0)
@ -1194,7 +1126,7 @@ spa_v4l2_pause (SpaV4l2Source *this)
for (i = 0; i < state->reqbuf.count; i++) {
V4l2Buffer *b;
b = &state->alloc_buffers[i];
b = &state->buffers[i];
if (!b->outstanding)
if (xioctl (state->fd, VIDIOC_QBUF, &b->v4l2_buffer) < 0)
perror ("VIDIOC_QBUF");

View file

@ -45,13 +45,11 @@ typedef struct {
bool live;
} SpaVideoTestSrcProps;
#define MAX_BUFFERS 16
typedef struct _VTSBuffer VTSBuffer;
struct _VTSBuffer {
SpaBuffer buffer;
SpaMeta metas[1];
SpaMetaHeader header;
SpaData datas[1];
SpaBuffer *outbuf;
bool outstanding;
VTSBuffer *next;
@ -86,8 +84,7 @@ struct _SpaVideoTestSrc {
size_t bpp;
bool have_buffers;
SpaMemory *alloc_mem;
VTSBuffer *alloc_buffers;
VTSBuffer buffers[MAX_BUFFERS];
unsigned int n_buffers;
bool started;
@ -158,7 +155,7 @@ spa_videotestsrc_node_set_props (SpaNode *node,
if (props == NULL) {
res = reset_videotestsrc_props (p);
} else {
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
}
if (this->props[1].live)
@ -476,13 +473,8 @@ clear_buffers (SpaVideoTestSrc *this)
{
if (this->have_buffers) {
fprintf (stderr, "videotestsrc %p: clear buffers\n", this);
if (this->alloc_mem)
spa_memory_unref (&this->alloc_mem->mem);
this->alloc_mem = NULL;
this->alloc_buffers = NULL;
this->n_buffers = 0;
this->have_buffers = false;
this->info.flags &= ~SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS;
SPA_QUEUE_INIT (&this->empty);
SPA_QUEUE_INIT (&this->ready);
}
@ -627,23 +619,12 @@ spa_videotestsrc_node_port_use_buffers (SpaNode *node,
if (buffers != NULL && n_buffers != 0) {
unsigned int i, j;
this->alloc_mem = spa_memory_alloc_size (SPA_MEMORY_POOL_LOCAL,
NULL,
sizeof (VTSBuffer) * n_buffers);
this->alloc_buffers = spa_memory_ensure_ptr (this->alloc_mem);
for (i = 0; i < n_buffers; i++) {
VTSBuffer *b;
SpaMemoryRef *mem_ref;
SpaMemory *mem;
SpaData *d = SPA_BUFFER_DATAS (buffers[i]);
SpaMeta *m = SPA_BUFFER_METAS (buffers[i]);
VTSBuffer *b = &this->buffers[i];
SpaData *d = buffers[i]->datas;
SpaMeta *m = buffers[i]->metas;
b = &this->alloc_buffers[i];
b->buffer.mem.mem = this->alloc_mem->mem;
b->buffer.mem.offset = sizeof (VTSBuffer) * i;
b->buffer.mem.size = sizeof (VTSBuffer);
b->buffer.id = SPA_ID_INVALID;
b = &this->buffers[i];
b->outbuf = buffers[i];
b->outstanding = true;
b->h = NULL;
@ -651,19 +632,18 @@ spa_videotestsrc_node_port_use_buffers (SpaNode *node,
for (j = 0; j < buffers[i]->n_metas; j++) {
switch (m[j].type) {
case SPA_META_TYPE_HEADER:
b->h = SPA_MEMBER (buffers[i], m[j].offset, SpaMetaHeader);
b->h = m[j].data;
break;
default:
break;
}
}
mem_ref = &d[0].mem.mem;
if (!(mem = spa_memory_find (mem_ref))) {
if (d[0].type != SPA_DATA_TYPE_MEMPTR) {
fprintf (stderr, "videotestsrc %p: invalid memory on buffer %p\n", this, buffers[i]);
continue;
}
b->ptr = SPA_MEMBER (spa_memory_ensure_ptr (mem), d[0].mem.offset, void);
b->ptr = SPA_MEMBER (d[0].data, d[0].offset, void);
b->stride = d[0].stride;
b->next = NULL;
@ -713,7 +693,7 @@ spa_videotestsrc_node_port_alloc_buffers (SpaNode *node,
*n_buffers = SPA_MIN (*n_buffers, this->n_buffers);
for (i = 0; i < *n_buffers; i++)
buffers[i] = this->alloc_buffers[i].outbuf;
buffers[i] = this->buffers[i].outbuf;
return SPA_RESULT_OK;
}
@ -740,7 +720,7 @@ spa_videotestsrc_node_port_reuse_buffer (SpaNode *node,
if (buffer_id >= this->n_buffers)
return SPA_RESULT_INVALID_BUFFER_ID;
b = &this->alloc_buffers[buffer_id];
b = &this->buffers[buffer_id];
if (!b->outstanding)
return SPA_RESULT_OK;

View file

@ -21,7 +21,6 @@
#include <stddef.h>
#include <spa/node.h>
#include <spa/memory.h>
#include <spa/audio/format.h>
typedef struct _SpaVolume SpaVolume;
@ -137,7 +136,7 @@ spa_volume_node_set_props (SpaNode *node,
reset_volume_props (p);
return SPA_RESULT_OK;
}
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
return res;
}
@ -527,7 +526,6 @@ spa_volume_node_port_pull_output (SpaNode *node,
SpaData *sd, *dd;
uint16_t *src, *dst;
double volume;
SpaMemory *sm, *dm;
if (node == NULL || node->handle == NULL || n_info == 0 || info == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
@ -556,16 +554,13 @@ spa_volume_node_port_pull_output (SpaNode *node,
if (si == sbuf->n_datas || di == dbuf->n_datas)
break;
sd = &SPA_BUFFER_DATAS (sbuf)[si];
dd = &SPA_BUFFER_DATAS (dbuf)[di];
sd = &sbuf->datas[si];
dd = &dbuf->datas[di];
sm = spa_memory_find (&sd->mem.mem);
dm = spa_memory_find (&dd->mem.mem);
src = (uint16_t*) ((uint8_t*)sd->data + sd->offset + soff);
dst = (uint16_t*) ((uint8_t*)dd->data + dd->offset + doff);
src = (uint16_t*) ((uint8_t*)sm->ptr + sd->mem.offset + soff);
dst = (uint16_t*) ((uint8_t*)dm->ptr + dd->mem.offset + doff);
n_bytes = SPA_MIN (sd->mem.size - soff, dd->mem.size - doff);
n_bytes = SPA_MIN (sd->size - soff, dd->size - doff);
n_samples = n_bytes / sizeof (uint16_t);
for (i = 0; i < n_samples; i++)
@ -574,11 +569,11 @@ spa_volume_node_port_pull_output (SpaNode *node,
soff += n_bytes;
doff += n_bytes;
if (soff >= sd->mem.size) {
if (soff >= sd->size) {
si++;
soff = 0;
}
if (doff >= dd->mem.size) {
if (doff >= dd->size) {
di++;
doff = 0;
}

View file

@ -159,7 +159,7 @@ spa_xv_sink_node_set_props (SpaNode *node,
return SPA_RESULT_OK;
}
res = spa_props_copy (props, &p->props);
res = spa_props_copy_values (props, &p->props);
return res;
}