Add port direction again

simplify port numbering again by using 0->max_ports for bot input ports
and output ports. This means we need to tall what direction the port is.
Add port_info serialize functions
Copy metadata and data when we are not sharing buffers.
Make pinossink work again.
This commit is contained in:
Wim Taymans 2016-10-03 19:43:42 +02:00
parent b208e8b690
commit d828073bb8
26 changed files with 1104 additions and 648 deletions

View file

@ -54,7 +54,9 @@ typedef struct {
typedef struct {
uint32_t id;
bool used;
void *buf_ptr;
SpaBuffer *buf;
SpaData *datas;
} BufferId;
struct _PinosStreamPrivate
@ -68,13 +70,13 @@ struct _PinosStreamPrivate
PinosStreamState state;
GError *error;
PinosDirection direction;
gchar *path;
SpaNodeState node_state;
GPtrArray *possible_formats;
SpaFormat *format;
SpaPortInfo port_info;
SpaDirection direction;
uint32_t port_id;
uint32_t pending_seq;
@ -628,9 +630,9 @@ add_node_update (PinosStream *stream, SpaControlBuilder *builder, uint32_t chang
nu.change_mask = change_mask;
if (change_mask & SPA_CONTROL_CMD_NODE_UPDATE_MAX_INPUTS)
nu.max_input_ports = priv->direction == PINOS_DIRECTION_INPUT ? 1 : 0;
nu.max_input_ports = priv->direction == SPA_DIRECTION_INPUT ? 1 : 0;
if (change_mask & SPA_CONTROL_CMD_NODE_UPDATE_MAX_OUTPUTS)
nu.max_output_ports = priv->direction == PINOS_DIRECTION_OUTPUT ? 1 : 0;
nu.max_output_ports = priv->direction == SPA_DIRECTION_OUTPUT ? 1 : 0;
nu.props = NULL;
spa_control_builder_add_cmd (builder, SPA_CONTROL_CMD_NODE_UPDATE, &nu);
}
@ -653,6 +655,7 @@ add_port_update (PinosStream *stream, SpaControlBuilder *builder, uint32_t chang
PinosStreamPrivate *priv = stream->priv;
SpaControlCmdPortUpdate pu = { 0, };;
pu.direction = priv->direction;
pu.port_id = priv->port_id;
pu.change_mask = change_mask;
if (change_mask & SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS) {
@ -663,8 +666,10 @@ add_port_update (PinosStream *stream, SpaControlBuilder *builder, uint32_t chang
pu.format = priv->format;
}
pu.props = NULL;
if (change_mask & SPA_CONTROL_CMD_PORT_UPDATE_INFO)
if (change_mask & SPA_CONTROL_CMD_PORT_UPDATE_INFO) {
pu.info = &priv->port_info;
spa_debug_port_info (pu.info);
}
spa_control_builder_add_cmd (builder, SPA_CONTROL_CMD_PORT_UPDATE, &pu);
}
@ -775,6 +780,7 @@ send_process_buffer (PinosStream *stream, uint32_t port_id, uint32_t buffer_id)
SpaNodeEventHaveOutput ho;
control_builder_init (stream, &builder);
pb.direction = priv->direction;
pb.port_id = port_id;
pb.buffer_id = buffer_id;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_PROCESS_BUFFER, &pb);
@ -871,7 +877,7 @@ handle_node_event (PinosStream *stream,
if (p->port_id != priv->port_id)
break;
if (priv->direction != PINOS_DIRECTION_OUTPUT)
if (priv->direction != SPA_DIRECTION_OUTPUT)
break;
if ((bid = find_buffer (stream, p->buffer_id))) {
@ -932,7 +938,7 @@ handle_node_command (PinosStream *stream,
g_debug ("stream %p: start", stream);
control_builder_init (stream, &builder);
if (priv->direction == PINOS_DIRECTION_INPUT)
if (priv->direction == SPA_DIRECTION_INPUT)
add_need_input (stream, &builder, priv->port_id);
add_state_change (stream, &builder, SPA_NODE_STATE_STREAMING);
add_async_complete (stream, &builder, seq, SPA_RESULT_OK);
@ -1072,6 +1078,7 @@ parse_control (PinosStream *stream,
unsigned int i, j;
SpaControlBuilder builder;
SpaControl control;
SpaBuffer *b;
if (spa_control_iter_parse_cmd (&it, &p) < 0)
break;
@ -1095,16 +1102,62 @@ parse_control (PinosStream *stream,
}
}
bid.buf = spa_buffer_deserialize (mid->ptr, p.buffers[i].offset);
bid.id = bid.buf->id;
bid.buf_ptr = SPA_MEMBER (mid->ptr, p.buffers[i].offset, void);
{
size_t size;
unsigned int i;
SpaMeta *m;
b = bid.buf_ptr;
size = sizeof (SpaBuffer);
m = SPA_MEMBER (b, SPA_PTR_TO_INT (b->metas), SpaMeta);
for (i = 0; i < b->n_metas; i++)
size += sizeof (SpaMeta) + m[i].size;
for (i = 0; i < b->n_datas; i++)
size += sizeof (SpaData);
b = bid.buf = g_memdup (bid.buf_ptr, size);
if (b->metas)
b->metas = SPA_MEMBER (b, SPA_PTR_TO_INT (b->metas), SpaMeta);
if (b->datas) {
bid.datas = SPA_MEMBER (bid.buf_ptr, SPA_PTR_TO_INT (b->datas), SpaData);
b->datas = SPA_MEMBER (b, SPA_PTR_TO_INT (b->datas), SpaData);
}
}
bid.id = b->id;
g_debug ("add buffer %d %d %zd", mid->id, bid.id, p.buffers[i].offset);
for (j = 0; j < bid.buf->n_datas; j++) {
SpaData *d = &bid.buf->datas[j];
MemId *bmid = find_mem (stream, SPA_PTR_TO_UINT32 (d->data));
d->data = SPA_INT_TO_PTR (bmid->fd);
g_debug (" data %d %u -> %d", j, bmid->id, bmid->fd);
for (j = 0; j < b->n_metas; j++) {
SpaMeta *m = &b->metas[j];
if (m->data)
m->data = SPA_MEMBER (bid.buf_ptr, SPA_PTR_TO_INT (m->data), void);
}
for (j = 0; j < b->n_datas; j++) {
SpaData *d = &b->datas[j];
switch (d->type) {
case SPA_DATA_TYPE_ID:
{
MemId *bmid = find_mem (stream, SPA_PTR_TO_UINT32 (d->data));
d->type = SPA_DATA_TYPE_FD;
d->data = SPA_INT_TO_PTR (bmid->fd);
g_debug (" data %d %u -> %d", j, bmid->id, bmid->fd);
break;
}
case SPA_DATA_TYPE_MEMPTR:
{
d->data = SPA_MEMBER (bid.buf_ptr, SPA_PTR_TO_INT (d->data), void);
g_debug (" data %d %u -> %p", j, bid.id, d->data);
break;
}
default:
g_warning ("unknown buffer data type %d", d->type);
break;
}
}
if (bid.id != priv->buffer_ids->len) {
@ -1133,16 +1186,23 @@ parse_control (PinosStream *stream,
case SPA_CONTROL_CMD_PROCESS_BUFFER:
{
SpaControlCmdProcessBuffer p;
guint i;
BufferId *bid;
if (priv->direction != PINOS_DIRECTION_INPUT)
if (priv->direction != SPA_DIRECTION_INPUT)
break;
if (spa_control_iter_parse_cmd (&it, &p) < 0)
break;
g_signal_emit (stream, signals[SIGNAL_NEW_BUFFER], 0, p.buffer_id);
if ((bid = find_buffer (stream, p.buffer_id))) {
for (i = 0; i < bid->buf->n_datas; i++) {
bid->buf->datas[i].size = bid->datas[i].size;
}
g_signal_emit (stream, signals[SIGNAL_NEW_BUFFER], 0, p.buffer_id);
send_need_input (stream, priv->port_id);
send_need_input (stream, priv->port_id);
}
break;
}
case SPA_CONTROL_CMD_NODE_EVENT:
@ -1434,8 +1494,8 @@ pinos_stream_connect (PinosStream *stream,
g_return_val_if_fail (pinos_context_get_state (context) == PINOS_CONTEXT_STATE_CONNECTED, FALSE);
g_return_val_if_fail (pinos_stream_get_state (stream) == PINOS_STREAM_STATE_UNCONNECTED, FALSE);
priv->direction = direction;
priv->port_id = direction == PINOS_DIRECTION_INPUT ? 0 : MAX_INPUTS;
priv->direction = direction == PINOS_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
priv->port_id = 0;
priv->mode = mode;
g_free (priv->path);
priv->path = g_strdup (port_path);
@ -1502,6 +1562,9 @@ pinos_stream_finish_format (PinosStream *stream,
add_state_change (stream, &builder, SPA_NODE_STATE_CONFIGURE);
}
}
priv->port_info.params = NULL;
priv->port_info.n_params = 0;
add_async_complete (stream, &builder, priv->pending_seq, res);
spa_control_builder_end (&builder, &control);
@ -1705,7 +1768,7 @@ pinos_stream_get_empty_buffer (PinosStream *stream)
g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE);
priv = stream->priv;
g_return_val_if_fail (priv->direction == PINOS_DIRECTION_OUTPUT, FALSE);
g_return_val_if_fail (priv->direction == SPA_DIRECTION_OUTPUT, FALSE);
for (i = 0; i < priv->buffer_ids->len; i++) {
BufferId *bid = &g_array_index (priv->buffer_ids, BufferId, i);
@ -1733,7 +1796,7 @@ pinos_stream_recycle_buffer (PinosStream *stream,
g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE);
g_return_val_if_fail (id != SPA_ID_INVALID, FALSE);
priv = stream->priv;
g_return_val_if_fail (priv->direction == PINOS_DIRECTION_INPUT, FALSE);
g_return_val_if_fail (priv->direction == SPA_DIRECTION_INPUT, FALSE);
send_reuse_buffer (stream, priv->port_id, id);
@ -1783,14 +1846,18 @@ pinos_stream_send_buffer (PinosStream *stream,
{
PinosStreamPrivate *priv;
BufferId *bid;
guint i;
g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE);
g_return_val_if_fail (id != SPA_ID_INVALID, FALSE);
priv = stream->priv;
g_return_val_if_fail (priv->direction == PINOS_DIRECTION_OUTPUT, FALSE);
g_return_val_if_fail (priv->direction == SPA_DIRECTION_OUTPUT, FALSE);
if ((bid = find_buffer (stream, id))) {
bid->used = TRUE;
for (i = 0; i < bid->buf->n_datas; i++) {
bid->datas[i].size = bid->buf->datas[i].size;
}
send_process_buffer (stream, priv->port_id, id);
return TRUE;
} else {

View file

@ -333,6 +333,7 @@ gst_pinos_sink_get_property (GObject * object, guint prop_id,
typedef struct {
GstPinosSink *sink;
guint id;
SpaBuffer *buf;
SpaMetaHeader *header;
guint flags;
} ProcessMemData;
@ -368,6 +369,7 @@ on_add_buffer (GObject *gobject,
data.sink = gst_object_ref (pinossink);
data.id = id;
data.buf = b;
data.header = NULL;
for (i = 0; i < b->n_metas; i++) {
@ -591,6 +593,7 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
GstPinosSink *pinossink;
gboolean res;
ProcessMemData *data;
guint i;
pinossink = GST_PINOS_SINK (bsink);
@ -599,7 +602,8 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
pinos_main_loop_lock (pinossink->loop);
if (pinos_stream_get_state (pinossink->stream) != PINOS_STREAM_STATE_STREAMING)
goto streaming_error;
goto done;
// goto streaming_error;
if (buffer->pool != GST_BUFFER_POOL_CAST (pinossink->pool)) {
GstBuffer *b = NULL;
@ -613,9 +617,22 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
data = gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buffer),
process_mem_data_quark);
if (data->header) {
data->header->seq = GST_BUFFER_OFFSET (buffer);
data->header->pts = GST_BUFFER_PTS (buffer);
data->header->dts_offset = GST_BUFFER_DTS (buffer);
}
for (i = 0; i < data->buf->n_datas; i++) {
SpaData *d = &data->buf->datas[i];
GstMemory *mem = gst_buffer_get_memory (buffer, i);
d->offset = mem->offset;
d->size = mem->size;
}
if (!(res = pinos_stream_send_buffer (pinossink->stream, data->id)))
g_warning ("can't send buffer");
done:
pinos_main_loop_unlock (pinossink->loop);
return GST_FLOW_OK;
@ -624,11 +641,11 @@ not_negotiated:
{
return GST_FLOW_NOT_NEGOTIATED;
}
streaming_error:
{
pinos_main_loop_unlock (pinossink->loop);
return GST_FLOW_ERROR;
}
//streaming_error:
// {
// pinos_main_loop_unlock (pinossink->loop);
// return GST_FLOW_ERROR;
// }
}
static gboolean

View file

@ -237,6 +237,7 @@ do_negotiate (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
g_debug ("link %p: doing negotiate format", this);
again:
if ((res = spa_node_port_enum_formats (this->input->node->node,
SPA_DIRECTION_INPUT,
this->input->port,
&filter,
NULL,
@ -253,6 +254,7 @@ again:
spa_debug_format (filter);
if ((res = spa_node_port_enum_formats (this->output->node->node,
SPA_DIRECTION_OUTPUT,
this->output->port,
&format,
filter,
@ -273,6 +275,7 @@ again:
} else if (in_state == SPA_NODE_STATE_CONFIGURE && out_state > SPA_NODE_STATE_CONFIGURE) {
/* only input needs format */
if ((res = spa_node_port_get_format (this->output->node->node,
SPA_DIRECTION_OUTPUT,
this->output->port,
(const SpaFormat **)&format)) < 0) {
g_set_error (&error,
@ -284,6 +287,7 @@ again:
} else if (out_state == SPA_NODE_STATE_CONFIGURE && in_state > SPA_NODE_STATE_CONFIGURE) {
/* only output needs format */
if ((res = spa_node_port_get_format (this->input->node->node,
SPA_DIRECTION_INPUT,
this->input->port,
(const SpaFormat **)&format)) < 0) {
g_set_error (&error,
@ -301,6 +305,7 @@ again:
if (out_state == SPA_NODE_STATE_CONFIGURE) {
g_debug ("link %p: doing set format on output", this);
if ((res = spa_node_port_set_format (this->output->node->node,
SPA_DIRECTION_OUTPUT,
this->output->port,
SPA_PORT_FORMAT_FLAG_NEAREST,
format)) < 0) {
@ -313,6 +318,7 @@ again:
} else if (in_state == SPA_NODE_STATE_CONFIGURE) {
g_debug ("link %p: doing set format on input", this);
if ((res = spa_node_port_set_format (this->input->node->node,
SPA_DIRECTION_INPUT,
this->input->port,
SPA_PORT_FORMAT_FLAG_NEAREST,
format)) < 0) {
@ -360,14 +366,20 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
g_debug ("link %p: doing alloc buffers %p %p", this, this->output->node, this->input->node);
/* find out what's possible */
if ((res = spa_node_port_get_info (this->output->node->node, this->output->port, &oinfo)) < 0) {
if ((res = spa_node_port_get_info (this->output->node->node,
SPA_DIRECTION_OUTPUT,
this->output->port,
&oinfo)) < 0) {
g_set_error (&error,
PINOS_ERROR,
PINOS_ERROR_BUFFER_ALLOCATION,
"error get output port info: %d", res);
goto error;
}
if ((res = spa_node_port_get_info (this->input->node->node, this->input->port, &iinfo)) < 0) {
if ((res = spa_node_port_get_info (this->input->node->node,
SPA_DIRECTION_INPUT,
this->input->port,
&iinfo)) < 0) {
g_set_error (&error,
PINOS_ERROR,
PINOS_ERROR_BUFFER_ALLOCATION,
@ -421,16 +433,20 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
if (priv->buffers == NULL) {
SpaAllocParamBuffers *in_alloc, *out_alloc;
guint max_buffers = MAX_BUFFERS;
guint max_buffers = MAX_BUFFERS, min_size = 4096;
gboolean alloc_data = TRUE;
max_buffers = MAX_BUFFERS;
in_alloc = find_param (iinfo, SPA_ALLOC_PARAM_TYPE_BUFFERS);
if (in_alloc)
if (in_alloc) {
max_buffers = in_alloc->max_buffers == 0 ? max_buffers : SPA_MIN (in_alloc->max_buffers, max_buffers);
min_size = SPA_MAX (min_size, in_alloc->minsize);
}
out_alloc = find_param (oinfo, SPA_ALLOC_PARAM_TYPE_BUFFERS);
if (out_alloc)
if (out_alloc) {
max_buffers = out_alloc->max_buffers == 0 ? max_buffers : SPA_MIN (out_alloc->max_buffers, max_buffers);
min_size = SPA_MAX (min_size, out_alloc->minsize);
}
if ((in_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) ||
(out_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS))
@ -445,23 +461,29 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
g_debug ("reusing %d output buffers %p", priv->n_buffers, priv->buffers);
} else {
guint i;
size_t hdr_size;
size_t hdr_size, data_size, buf_size;
void *p;
spa_alloc_params_get_header_size (oinfo->params, oinfo->n_params, 1, &hdr_size);
if (alloc_data)
data_size = min_size;
else
data_size = 0;
buf_size = hdr_size + data_size;
priv->n_buffers = max_buffers;
pinos_memblock_alloc (PINOS_MEMBLOCK_FLAG_WITH_FD |
PINOS_MEMBLOCK_FLAG_MAP_READWRITE |
PINOS_MEMBLOCK_FLAG_SEAL,
priv->n_buffers * (sizeof (SpaBuffer*) + hdr_size),
priv->n_buffers * (sizeof (SpaBuffer*) + buf_size),
&priv->buffer_mem);
priv->buffers = p = priv->buffer_mem.ptr;
p = SPA_MEMBER (p, priv->n_buffers * sizeof (SpaBuffer*), void);
for (i = 0; i < priv->n_buffers; i++)
priv->buffers[i] = SPA_MEMBER (p, hdr_size * i, SpaBuffer);
priv->buffers[i] = SPA_MEMBER (p, buf_size * i, SpaBuffer);
if ((res = spa_buffer_init_headers (oinfo->params,
oinfo->n_params,
@ -474,12 +496,25 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
"error buffer alloc: %d", res);
goto error;
}
for (i = 0; i < priv->n_buffers; i++) {
SpaData *d = &priv->buffers[i]->datas[0];
g_debug (" buffers %p %d", priv->buffers[i], priv->buffers[i]->id);
d->type = SPA_DATA_TYPE_MEMPTR;
d->data = SPA_MEMBER (priv->buffers[i], hdr_size, void);
d->size = data_size;
d->maxsize = data_size;
d->offset = 0;
d->stride = 0;
}
g_debug ("allocated %d buffers %p", priv->n_buffers, priv->buffers);
priv->allocated = TRUE;
}
if (in_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) {
if ((res = spa_node_port_alloc_buffers (this->input->node->node, this->input->port,
if ((res = spa_node_port_alloc_buffers (this->input->node->node,
SPA_DIRECTION_INPUT,
this->input->port,
oinfo->params, oinfo->n_params,
priv->buffers, &priv->n_buffers)) < 0) {
g_set_error (&error,
@ -496,7 +531,9 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
g_debug ("allocated %d buffers %p from input port", priv->n_buffers, priv->buffers);
}
else if (out_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) {
if ((res = spa_node_port_alloc_buffers (this->output->node->node, this->output->port,
if ((res = spa_node_port_alloc_buffers (this->output->node->node,
SPA_DIRECTION_OUTPUT,
this->output->port,
iinfo->params, iinfo->n_params,
priv->buffers, &priv->n_buffers)) < 0) {
g_set_error (&error,
@ -516,8 +553,11 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
if (in_flags & SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS) {
g_debug ("using %d buffers %p on input port", priv->n_buffers, priv->buffers);
if ((res = spa_node_port_use_buffers (this->input->node->node, this->input->port,
priv->buffers, priv->n_buffers)) < 0) {
if ((res = spa_node_port_use_buffers (this->input->node->node,
SPA_DIRECTION_INPUT,
this->input->port,
priv->buffers,
priv->n_buffers)) < 0) {
g_set_error (&error,
PINOS_ERROR,
PINOS_ERROR_BUFFER_ALLOCATION,
@ -530,8 +570,11 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
}
else if (out_flags & SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS) {
g_debug ("using %d buffers %p on output port", priv->n_buffers, priv->buffers);
if ((res = spa_node_port_use_buffers (this->output->node->node, this->output->port,
priv->buffers, priv->n_buffers)) < 0) {
if ((res = spa_node_port_use_buffers (this->output->node->node,
SPA_DIRECTION_OUTPUT,
this->output->port,
priv->buffers,
priv->n_buffers)) < 0) {
g_set_error (&error,
PINOS_ERROR,
PINOS_ERROR_BUFFER_ALLOCATION,

View file

@ -281,7 +281,7 @@ suspend_node (PinosNode *this)
for (walk = priv->input_ports; walk; walk = g_list_next (walk)) {
NodePort *p = walk->data;
if ((res = spa_node_port_set_format (this->node, p->port.port, 0, NULL)) < 0)
if ((res = spa_node_port_set_format (this->node, SPA_DIRECTION_INPUT, p->port.port, 0, NULL)) < 0)
g_warning ("error unset format output: %d", res);
p->port.buffers = NULL;
p->port.n_buffers = 0;
@ -291,7 +291,7 @@ suspend_node (PinosNode *this)
}
for (walk = priv->output_ports; walk; walk = g_list_next (walk)) {
NodePort *p = walk->data;
if ((res = spa_node_port_set_format (this->node, p->port.port, 0, NULL)) < 0)
if ((res = spa_node_port_set_format (this->node, SPA_DIRECTION_OUTPUT, p->port.port, 0, NULL)) < 0)
g_warning ("error unset format output: %d", res);
p->port.buffers = NULL;
p->port.n_buffers = 0;
@ -1132,15 +1132,14 @@ pinos_node_get_free_port (PinosNode *node,
max_ports = priv->max_input_ports;
n_ports = priv->n_input_ports;
ports = priv->input_ports;
free_port = 0;
} else {
max_ports = priv->max_output_ports;
n_ports = priv->n_output_ports;
ports = priv->output_ports;
free_port = priv->max_input_ports;
}
free_port = 0;
g_debug ("node %p: direction %d max %u, n %u", node, direction, max_ports, n_ports);
g_debug ("node %p: direction %d max %u, n %u, free_port %u", node, direction, max_ports, n_ports, free_port);
for (walk = ports; walk; walk = g_list_next (walk)) {
PinosPort *p = walk->data;

View file

@ -94,6 +94,7 @@ typedef struct {
/* SPA_CONTROL_CMD_PORT_UPDATE */
typedef struct {
SpaDirection direction;
uint32_t port_id;
#define SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS (1 << 0)
#define SPA_CONTROL_CMD_PORT_UPDATE_FORMAT (1 << 1)
@ -116,20 +117,23 @@ typedef struct {
/* SPA_CONTROL_CMD_ADD_PORT */
typedef struct {
uint32_t seq;
uint32_t port_id;
uint32_t seq;
SpaDirection direction;
uint32_t port_id;
} SpaControlCmdAddPort;
/* SPA_CONTROL_CMD_REMOVE_PORT */
typedef struct {
uint32_t seq;
uint32_t port_id;
uint32_t seq;
SpaDirection direction;
uint32_t port_id;
} SpaControlCmdRemovePort;
/* SPA_CONTROL_CMD_SET_FORMAT */
typedef struct {
uint32_t seq;
SpaDirection direction;
uint32_t port_id;
SpaPortFormatFlags flags;
SpaFormat *format;
@ -137,11 +141,12 @@ typedef struct {
/* SPA_CONTROL_CMD_SET_PROPERTY */
typedef struct {
uint32_t seq;
uint32_t port_id;
uint32_t id;
size_t size;
void *value;
uint32_t seq;
SpaDirection direction;
uint32_t port_id;
uint32_t id;
size_t size;
void *value;
} SpaControlCmdSetProperty;
/* SPA_CONTROL_CMD_NODE_COMMAND */
@ -152,6 +157,7 @@ typedef struct {
/* SPA_CONTROL_CMD_ADD_MEM */
typedef struct {
SpaDirection direction;
uint32_t port_id;
uint32_t mem_id;
unsigned int fd_index;
@ -162,6 +168,7 @@ typedef struct {
/* SPA_CONTROL_CMD_REMOVE_MEM */
typedef struct {
SpaDirection direction;
uint32_t port_id;
uint32_t mem_id;
} SpaControlCmdRemoveMem;
@ -175,6 +182,7 @@ typedef struct {
/* SPA_CONTROL_CMD_USE_BUFFERS */
typedef struct {
uint32_t seq;
SpaDirection direction;
uint32_t port_id;
unsigned int n_buffers;
SpaControlMemRef *buffers;
@ -182,8 +190,9 @@ typedef struct {
/* SPA_CONTROL_CMD_PROCESS_BUFFER */
typedef struct {
uint32_t port_id;
uint32_t buffer_id;
SpaDirection direction;
uint32_t port_id;
uint32_t buffer_id;
} SpaControlCmdProcessBuffer;
/* SPA_CONTROL_CMD_NODE_EVENT */

View file

@ -74,6 +74,12 @@ typedef enum {
#define SPA_RESULT_ASYNC_SEQ(res) ((res) & SPA_ASYNC_SEQ_MASK)
#define SPA_RESULT_RETURN_ASYNC(seq) (SPA_RESULT_ASYNC | ((seq) & SPA_ASYNC_SEQ_MASK))
typedef enum {
SPA_DIRECTION_INVALID = 0,
SPA_DIRECTION_INPUT,
SPA_DIRECTION_OUTPUT,
} SpaDirection;
typedef void (*SpaNotify) (void *data);
#define SPA_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))

View file

@ -75,14 +75,6 @@ typedef struct {
SpaResult res;
} SpaNodeEventAsyncComplete;
typedef struct {
uint32_t port_id;
} SpaNodeEventPortAdded;
typedef struct {
uint32_t port_id;
} SpaNodeEventPortRemoved;
typedef struct {
SpaNodeState state;
} SpaNodeEventStateChange;

View file

@ -270,8 +270,7 @@ struct _SpaNode {
* @n_output_ports: size of the @output_ids array
* @output_ids: array to store the output stream ids
*
* Get the current number of input and output ports and also the maximum
* number of ports.
* Get the ids of the currently available ports.
*
* Returns: #SPA_RESULT_OK on success
* #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
@ -285,26 +284,28 @@ struct _SpaNode {
/**
* SpaNode::add_port:
* @node: a #SpaNode
* @direction: a #SpaDirection
* @port_id: an unused port id
*
* Make a new port with @port_id. The called should use get_port_ids() to
* find an unused id.
* find an unused id for the given @direction.
*
* Input port ids should be between 0 and max_input_ports and output ports
* between max_input_ports and max_input_ports + max_output_ports as obtained
* from get_port_ids().
* Port ids should be between 0 and max_ports as obtained from get_n_ports().
*
* Returns: #SPA_RESULT_OK on success
* #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
*/
SpaResult (*add_port) (SpaNode *node,
SpaDirection direction,
uint32_t port_id);
SpaResult (*remove_port) (SpaNode *node,
SpaDirection direction,
uint32_t port_id);
/**
* SpaNode::port_enum_formats:
* @node: a #SpaNode
* @direction: a #SpaDirection
* @port_id: the port to query
* @format: pointer to a format
* @filter: a format filter
@ -325,6 +326,7 @@ struct _SpaNode {
* #SPA_RESULT_ENUM_END when no format exists
*/
SpaResult (*port_enum_formats) (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
@ -332,6 +334,7 @@ struct _SpaNode {
/**
* SpaNode::port_set_format:
* @node: a #SpaNode
* @direction: a #SpaDirection
* @port_id: the port to configure
* @flags: flags
* @format: a #SpaFormat with the format
@ -359,13 +362,15 @@ struct _SpaNode {
* is not correct.
* #SPA_RESULT_ASYNC the function is executed asynchronously
*/
SpaResult (*port_set_format) (SpaNode *node,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format);
SpaResult (*port_set_format) (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format);
/**
* SpaNode::port_get_format:
* @node: a #SpaNode
* @direction: a #SpaDirection
* @port_id: the port to query
* @format: a pointer to a location to hold the #SpaFormat
*
@ -378,23 +383,28 @@ struct _SpaNode {
* #SPA_RESULT_INVALID_NO_FORMAT when no format was set
*/
SpaResult (*port_get_format) (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaFormat **format);
SpaResult (*port_get_info) (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortInfo **info);
SpaResult (*port_get_props) (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaProps **props);
SpaResult (*port_set_props) (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaProps *props);
/**
* SpaNode::port_use_buffers:
* @node: a #SpaNode
* @direction: a #SpaDirection
* @port_id: a port id
* @buffers: an array of buffer pointers
* @n_buffers: number of elements in @buffers
@ -420,12 +430,14 @@ struct _SpaNode {
* #SPA_RESULT_ASYNC the function is executed asynchronously
*/
SpaResult (*port_use_buffers) (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaBuffer **buffers,
unsigned int n_buffers);
/**
* SpaNode::port_alloc_buffers:
* @node: a #SpaNode
* @direction: a #SpaDirection
* @port_id: a port id
* @params: allocation parameters
* @n_params: number of elements in @params
@ -456,28 +468,15 @@ struct _SpaNode {
* #SPA_RESULT_ASYNC the function is executed asynchronously
*/
SpaResult (*port_alloc_buffers) (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaAllocParam **params,
unsigned int n_params,
SpaBuffer **buffers,
unsigned int *n_buffers);
/**
* SpaNode::port_reuse_buffer:
* @node: a #SpaNode
* @port_id: a port id
* @buffer_id: a buffer id to reuse
*
* Tell an output port to reuse a buffer.
*
* Returns: #SPA_RESULT_OK on success
* #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
*/
SpaResult (*port_reuse_buffer) (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id);
SpaResult (*port_get_status) (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortStatus **status);
@ -523,8 +522,23 @@ struct _SpaNode {
SpaResult (*port_pull_output) (SpaNode *node,
unsigned int n_info,
SpaPortOutputInfo *info);
/**
* SpaNode::port_reuse_buffer:
* @node: a #SpaNode
* @port_id: a port id
* @buffer_id: a buffer id to reuse
*
* Tell an output port to reuse a buffer.
*
* Returns: #SPA_RESULT_OK on success
* #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL
*/
SpaResult (*port_reuse_buffer) (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id);
SpaResult (*port_push_event) (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event);
@ -546,10 +560,10 @@ struct _SpaNode {
#define spa_node_port_set_props(n,...) (n)->port_set_props((n),__VA_ARGS__)
#define spa_node_port_use_buffers(n,...) (n)->port_use_buffers((n),__VA_ARGS__)
#define spa_node_port_alloc_buffers(n,...) (n)->port_alloc_buffers((n),__VA_ARGS__)
#define spa_node_port_reuse_buffer(n,...) (n)->port_reuse_buffer((n),__VA_ARGS__)
#define spa_node_port_get_status(n,...) (n)->port_get_status((n),__VA_ARGS__)
#define spa_node_port_push_input(n,...) (n)->port_push_input((n),__VA_ARGS__)
#define spa_node_port_pull_output(n,...) (n)->port_pull_output((n),__VA_ARGS__)
#define spa_node_port_reuse_buffer(n,...) (n)->port_reuse_buffer((n),__VA_ARGS__)
#define spa_node_port_push_event(n,...) (n)->port_push_event((n),__VA_ARGS__)
#ifdef __cplusplus

View file

@ -115,6 +115,13 @@ typedef struct {
const char **features;
} SpaPortInfo;
size_t spa_port_info_get_size (const SpaPortInfo *info);
size_t spa_port_info_serialize (void *dest, const SpaPortInfo *info);
SpaPortInfo * spa_port_info_deserialize (void *src, off_t offset);
SpaPortInfo * spa_port_info_copy_into (void *dest, const SpaPortInfo *info);
/**
* SpaPortStatusFlags:
* @SPA_PORT_STATUS_FLAG_NONE: no status flags

View file

@ -369,20 +369,10 @@ iter_parse_port_update (struct stack_iter *si, SpaControlCmdPortUpdate *pu)
}
if (pu->format)
pu->format = spa_format_deserialize (p, SPA_PTR_TO_INT (pu->format));
if (pu->props)
pu->props = spa_props_deserialize (p, SPA_PTR_TO_INT (pu->props));
if (pu->info) {
SpaPortInfo *pi;
pu->info = p = SPA_MEMBER (p, SPA_PTR_TO_INT (pu->info), SpaPortInfo);
pi = (SpaPortInfo *) pu->info;
pi->params = SPA_MEMBER (p, SPA_PTR_TO_INT (pi->params), SpaAllocParam *);
for (i = 0; i < pi->n_params; i++) {
pi->params[i] = SPA_MEMBER (p, SPA_PTR_TO_INT (pi->params[i]), SpaAllocParam);
}
}
if (pu->info)
pu->info = spa_port_info_deserialize (p, SPA_PTR_TO_INT (pu->info));
}
static void
@ -759,39 +749,6 @@ builder_add_cmd (struct stack_builder *sb, SpaControlCmd cmd, size_t size)
return p;
}
static size_t
write_port_info (void *p, const SpaPortInfo *info)
{
SpaPortInfo *tp;
SpaAllocParam **ap;
int i;
size_t len;
if (info == NULL)
return 0;
tp = p;
memcpy (tp, info, sizeof (SpaPortInfo));
p = SPA_MEMBER (tp, sizeof (SpaPortInfo), SpaAllocParam *);
ap = p;
if (info->n_params)
tp->params = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
else
tp->params = 0;
tp->features = 0;
p = SPA_MEMBER (p, sizeof (SpaAllocParam*) * info->n_params, void);
for (i = 0; i < info->n_params; i++) {
len = info->params[i]->size;
memcpy (p, info->params[i], len);
ap[i] = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp));
p = SPA_MEMBER (p, len, void);
}
return SPA_PTRDIFF (p, tp);
}
static void
builder_add_node_update (struct stack_builder *sb, SpaControlCmdNodeUpdate *nu)
{
@ -833,12 +790,8 @@ builder_add_port_update (struct stack_builder *sb, SpaControlCmdPortUpdate *pu)
}
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 *);
for (i = 0; i < pu->info->n_params; i++)
len += pu->info->params[i]->size;
}
if (pu->info)
len += spa_port_info_get_size (pu->info);
p = builder_add_cmd (sb, SPA_CONTROL_CMD_PORT_UPDATE, len);
memcpy (p, pu, sizeof (SpaControlCmdPortUpdate));
@ -873,7 +826,7 @@ builder_add_port_update (struct stack_builder *sb, SpaControlCmdPortUpdate *pu)
d->props = 0;
}
if (pu->info) {
len = write_port_info (p, pu->info);
len = spa_port_info_serialize (p, pu->info);
d->info = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
p = SPA_MEMBER (p, len, void);
} else {

View file

@ -3,6 +3,7 @@ spalib_sources = ['audio-raw.c',
'control.c',
'debug.c',
'format.c',
'port.c',
'props.c',
'ringbuffer.c',
'video-raw.c']

101
spa/lib/port.c Normal file
View file

@ -0,0 +1,101 @@
/* 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.
*/
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <spa/port.h>
#include <spa/debug.h>
size_t
spa_port_info_get_size (const SpaPortInfo *info)
{
size_t len;
unsigned int i;
if (info == NULL)
return 0;
len = sizeof (SpaPortInfo);
len += info->n_params * sizeof (SpaAllocParam *);
for (i = 0; i < info->n_params; i++)
len += info->params[i]->size;
return len;
}
size_t
spa_port_info_serialize (void *p, const SpaPortInfo *info)
{
SpaPortInfo *pi;
SpaAllocParam **ap;
int i;
size_t len;
if (info == NULL)
return 0;
pi = p;
memcpy (pi, info, sizeof (SpaPortInfo));
ap = SPA_MEMBER (pi, sizeof (SpaPortInfo), SpaAllocParam *);
if (info->n_params)
pi->params = SPA_INT_TO_PTR (SPA_PTRDIFF (ap, pi));
else
pi->params = 0;
pi->features = 0;
p = SPA_MEMBER (ap, sizeof (SpaAllocParam*) * info->n_params, void);
for (i = 0; i < info->n_params; i++) {
len = info->params[i]->size;
memcpy (p, info->params[i], len);
ap[i] = SPA_INT_TO_PTR (SPA_PTRDIFF (p, pi));
p = SPA_MEMBER (p, len, void);
}
return SPA_PTRDIFF (p, pi);
}
SpaPortInfo *
spa_port_info_deserialize (void *p, off_t offset)
{
SpaPortInfo *pi;
unsigned int i;
pi = SPA_MEMBER (p, offset, SpaPortInfo);
if (pi->params)
pi->params = SPA_MEMBER (pi, SPA_PTR_TO_INT (pi->params), SpaAllocParam *);
for (i = 0; i < pi->n_params; i++) {
pi->params[i] = SPA_MEMBER (pi, SPA_PTR_TO_INT (pi->params[i]), SpaAllocParam);
}
return pi;
}
SpaPortInfo *
spa_port_info_copy_into (void *dest, const SpaPortInfo *info)
{
if (info == NULL)
return NULL;
spa_port_info_serialize (dest, info);
return spa_port_info_deserialize (dest, 0);
}

View file

@ -26,6 +26,8 @@
#include "alsa-utils.h"
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0)
typedef struct _SpaALSAState SpaALSASink;
static const char default_device[] = "default";
@ -211,10 +213,10 @@ spa_alsa_sink_node_get_n_ports (SpaNode *node,
if (n_input_ports)
*n_input_ports = 1;
if (n_output_ports)
*n_output_ports = 0;
if (max_input_ports)
*max_input_ports = 1;
if (n_output_ports)
*n_output_ports = 0;
if (max_output_ports)
*max_output_ports = 0;
@ -240,6 +242,7 @@ spa_alsa_sink_node_get_port_ids (SpaNode *node,
static SpaResult
spa_alsa_sink_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -247,6 +250,7 @@ spa_alsa_sink_node_add_port (SpaNode *node,
static SpaResult
spa_alsa_sink_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -254,6 +258,7 @@ spa_alsa_sink_node_remove_port (SpaNode *node,
static SpaResult
spa_alsa_sink_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
@ -267,7 +272,7 @@ spa_alsa_sink_node_port_enum_formats (SpaNode *node,
this = (SpaALSASink *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
index = (*state == NULL ? 0 : *(int*)state);
@ -294,6 +299,7 @@ spa_alsa_sink_node_port_enum_formats (SpaNode *node,
static SpaResult
spa_alsa_sink_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
@ -306,7 +312,7 @@ spa_alsa_sink_node_port_set_format (SpaNode *node,
this = (SpaALSASink *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (format == NULL) {
@ -345,6 +351,7 @@ spa_alsa_sink_node_port_set_format (SpaNode *node,
static SpaResult
spa_alsa_sink_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaFormat **format)
{
@ -355,7 +362,7 @@ spa_alsa_sink_node_port_get_format (SpaNode *node,
this = (SpaALSASink *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (!this->have_format)
@ -368,6 +375,7 @@ spa_alsa_sink_node_port_get_format (SpaNode *node,
static SpaResult
spa_alsa_sink_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortInfo **info)
{
@ -378,7 +386,7 @@ spa_alsa_sink_node_port_get_info (SpaNode *node,
this = (SpaALSASink *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
*info = &this->info;
@ -387,15 +395,17 @@ spa_alsa_sink_node_port_get_info (SpaNode *node,
}
static SpaResult
spa_alsa_sink_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
spa_alsa_sink_node_port_get_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaProps **props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_alsa_sink_node_port_set_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaProps *props)
{
@ -404,6 +414,7 @@ spa_alsa_sink_node_port_set_props (SpaNode *node,
static SpaResult
spa_alsa_sink_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@ -413,6 +424,7 @@ spa_alsa_sink_node_port_use_buffers (SpaNode *node,
static SpaResult
spa_alsa_sink_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@ -424,7 +436,7 @@ spa_alsa_sink_node_port_alloc_buffers (SpaNode *node,
if (node == NULL || node->handle == NULL || buffers == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
this = (SpaALSASink *) node->handle;
@ -435,16 +447,9 @@ spa_alsa_sink_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_alsa_sink_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_alsa_sink_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortStatus **status)
{
@ -455,7 +460,7 @@ spa_alsa_sink_node_port_get_status (SpaNode *node,
this = (SpaALSASink *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
*status = &this->status;
@ -516,6 +521,24 @@ spa_alsa_sink_node_port_pull_output (SpaNode *node,
return SPA_RESULT_INVALID_PORT;
}
static SpaResult
spa_alsa_sink_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_alsa_sink_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static const SpaNode alsasink_node = {
NULL,
sizeof (SpaNode),
@ -537,10 +560,11 @@ static const SpaNode alsasink_node = {
spa_alsa_sink_node_port_set_props,
spa_alsa_sink_node_port_use_buffers,
spa_alsa_sink_node_port_alloc_buffers,
spa_alsa_sink_node_port_reuse_buffer,
spa_alsa_sink_node_port_get_status,
spa_alsa_sink_node_port_push_input,
spa_alsa_sink_node_port_pull_output,
spa_alsa_sink_node_port_reuse_buffer,
spa_alsa_sink_node_port_push_event,
};
static SpaResult

View file

@ -27,6 +27,8 @@
#include "alsa-utils.h"
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
typedef struct _SpaALSAState SpaALSASource;
static void
@ -244,20 +246,23 @@ spa_alsa_source_node_get_port_ids (SpaNode *node,
static SpaResult
spa_alsa_source_node_add_port (SpaNode *node,
uint32_t port_id)
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_alsa_source_node_remove_port (SpaNode *node,
uint32_t port_id)
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_alsa_source_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
@ -271,7 +276,7 @@ spa_alsa_source_node_port_enum_formats (SpaNode *node,
this = (SpaALSASource *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
index = (*state == NULL ? 0 : *(int*)state);
@ -326,6 +331,7 @@ spa_alsa_clear_buffers (SpaALSASource *this)
static SpaResult
spa_alsa_source_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
@ -338,7 +344,7 @@ spa_alsa_source_node_port_set_format (SpaNode *node,
this = (SpaALSASource *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (format == NULL) {
@ -379,8 +385,9 @@ spa_alsa_source_node_port_set_format (SpaNode *node,
static SpaResult
spa_alsa_source_node_port_get_format (SpaNode *node,
uint32_t port_id,
const SpaFormat **format)
SpaDirection direction,
uint32_t port_id,
const SpaFormat **format)
{
SpaALSASource *this;
@ -389,7 +396,7 @@ spa_alsa_source_node_port_get_format (SpaNode *node,
this = (SpaALSASource *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (!this->have_format)
@ -402,8 +409,9 @@ spa_alsa_source_node_port_get_format (SpaNode *node,
static SpaResult
spa_alsa_source_node_port_get_info (SpaNode *node,
uint32_t port_id,
const SpaPortInfo **info)
SpaDirection direction,
uint32_t port_id,
const SpaPortInfo **info)
{
SpaALSASource *this;
@ -412,7 +420,7 @@ spa_alsa_source_node_port_get_info (SpaNode *node,
this = (SpaALSASource *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
*info = &this->info;
@ -421,23 +429,26 @@ spa_alsa_source_node_port_get_info (SpaNode *node,
}
static SpaResult
spa_alsa_source_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
spa_alsa_source_node_port_get_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaProps **props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_alsa_source_node_port_set_props (SpaNode *node,
uint32_t port_id,
const SpaProps *props)
SpaDirection direction,
uint32_t port_id,
const SpaProps *props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_alsa_source_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@ -449,7 +460,7 @@ spa_alsa_source_node_port_use_buffers (SpaNode *node,
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
this = (SpaALSASource *) node->handle;
@ -484,6 +495,7 @@ spa_alsa_source_node_port_use_buffers (SpaNode *node,
static SpaResult
spa_alsa_source_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@ -495,7 +507,7 @@ spa_alsa_source_node_port_alloc_buffers (SpaNode *node,
if (node == NULL || node->handle == NULL || buffers == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
this = (SpaALSASource *) node->handle;
@ -506,34 +518,9 @@ spa_alsa_source_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_alsa_source_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
SpaALSASource *this;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = (SpaALSASource *) node->handle;
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
if (!this->have_buffers)
return SPA_RESULT_NO_BUFFERS;
if (buffer_id >= this->n_buffers)
return SPA_RESULT_INVALID_BUFFER_ID;
recycle_buffer (this, buffer_id);
return SPA_RESULT_OK;
}
static SpaResult
spa_alsa_source_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortStatus **status)
{
@ -544,7 +531,7 @@ spa_alsa_source_node_port_get_status (SpaNode *node,
this = (SpaALSASource *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
*status = &this->status;
@ -554,16 +541,16 @@ spa_alsa_source_node_port_get_status (SpaNode *node,
static SpaResult
spa_alsa_source_node_port_push_input (SpaNode *node,
unsigned int n_info,
SpaPortInputInfo *info)
unsigned int n_info,
SpaPortInputInfo *info)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_alsa_source_node_port_pull_output (SpaNode *node,
unsigned int n_info,
SpaPortOutputInfo *info)
unsigned int n_info,
SpaPortOutputInfo *info)
{
SpaALSASource *this;
unsigned int i;
@ -607,6 +594,41 @@ spa_alsa_source_node_port_pull_output (SpaNode *node,
}
static SpaResult
spa_alsa_source_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
SpaALSASource *this;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = (SpaALSASource *) node->handle;
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
if (!this->have_buffers)
return SPA_RESULT_NO_BUFFERS;
if (buffer_id >= this->n_buffers)
return SPA_RESULT_INVALID_BUFFER_ID;
recycle_buffer (this, buffer_id);
return SPA_RESULT_OK;
}
static SpaResult
spa_alsa_source_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static const SpaNode alsasource_node = {
NULL,
sizeof (SpaNode),
@ -628,11 +650,13 @@ static const SpaNode alsasource_node = {
spa_alsa_source_node_port_set_props,
spa_alsa_source_node_port_use_buffers,
spa_alsa_source_node_port_alloc_buffers,
spa_alsa_source_node_port_reuse_buffer,
spa_alsa_source_node_port_get_status,
spa_alsa_source_node_port_push_input,
spa_alsa_source_node_port_pull_output,
spa_alsa_source_node_port_reuse_buffer,
spa_alsa_source_node_port_push_event,
};
static SpaResult
spa_alsa_source_clock_get_props (SpaClock *clock,
SpaProps **props)

View file

@ -73,9 +73,15 @@ struct _SpaAudioMixer {
int port_count;
int port_queued;
SpaAudioMixerPort ports[MAX_PORTS + 1];
SpaAudioMixerPort in_ports[MAX_PORTS];
SpaAudioMixerPort out_ports[1];
};
#define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !this->in_ports[(p)].valid)
#define CHECK_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && this->in_ports[(p)].valid)
#define CHECK_OUT_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
#define CHECK_PORT(this,d,p) (CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p))
enum {
PROP_ID_LAST,
};
@ -198,10 +204,10 @@ spa_audiomixer_node_get_n_ports (SpaNode *node,
if (n_input_ports)
*n_input_ports = 0;
if (n_output_ports)
*n_output_ports = 1;
if (max_input_ports)
*max_input_ports = MAX_PORTS;
if (n_output_ports)
*n_output_ports = 1;
if (max_output_ports)
*max_output_ports = 1;
@ -225,18 +231,19 @@ spa_audiomixer_node_get_port_ids (SpaNode *node,
if (input_ids) {
for (i = 0, idx = 0; i < MAX_PORTS && idx < n_input_ports; i++) {
if (this->ports[i].valid)
if (this->in_ports[i].valid)
input_ids[idx++] = i;
}
}
if (n_output_ports > 0 && output_ids)
output_ids[0] = MAX_PORTS;
output_ids[0] = 0;
return SPA_RESULT_OK;
}
static SpaResult
spa_audiomixer_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
SpaAudioMixer *this;
@ -246,28 +253,26 @@ spa_audiomixer_node_add_port (SpaNode *node,
this = (SpaAudioMixer *) node->handle;
if (port_id >= MAX_PORTS)
if (!CHECK_FREE_IN_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (this->ports[port_id].valid)
return SPA_RESULT_INVALID_PORT;
this->ports[port_id].valid = true;
this->in_ports[port_id].valid = true;
this->port_count++;
this->ports[port_id].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
this->in_ports[port_id].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
SPA_PORT_INFO_FLAG_REMOVABLE |
SPA_PORT_INFO_FLAG_OPTIONAL |
SPA_PORT_INFO_FLAG_IN_PLACE;
this->ports[port_id].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->in_ports[port_id].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[MAX_PORTS].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
return SPA_RESULT_OK;
}
static SpaResult
spa_audiomixer_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
SpaAudioMixer *this;
@ -277,17 +282,17 @@ spa_audiomixer_node_remove_port (SpaNode *node,
this = (SpaAudioMixer *) node->handle;
if (port_id >= MAX_PORTS || !this->ports[port_id].valid)
if (!CHECK_IN_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
this->ports[port_id].valid = false;
this->in_ports[port_id].valid = false;
this->port_count--;
if (this->ports[port_id].buffer) {
this->ports[port_id].buffer = NULL;
if (this->in_ports[port_id].buffer) {
this->in_ports[port_id].buffer = NULL;
this->port_queued--;
}
if (this->port_count == this->port_queued)
this->ports[MAX_PORTS].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
this->out_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
return SPA_RESULT_OK;
}
@ -295,6 +300,7 @@ spa_audiomixer_node_remove_port (SpaNode *node,
static SpaResult
spa_audiomixer_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
@ -309,10 +315,10 @@ spa_audiomixer_node_port_enum_formats (SpaNode *node,
this = (SpaAudioMixer *) node->handle;
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0];
index = (*state == NULL ? 0 : *(int*)state);
@ -333,6 +339,7 @@ spa_audiomixer_node_port_enum_formats (SpaNode *node,
static SpaResult
spa_audiomixer_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
@ -346,10 +353,10 @@ spa_audiomixer_node_port_set_format (SpaNode *node,
this = (SpaAudioMixer *) node->handle;
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0];
if (format == NULL) {
port->have_format = false;
@ -366,6 +373,7 @@ spa_audiomixer_node_port_set_format (SpaNode *node,
static SpaResult
spa_audiomixer_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaFormat **format)
{
@ -377,10 +385,10 @@ spa_audiomixer_node_port_get_format (SpaNode *node,
this = (SpaAudioMixer *) node->handle;
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0];
if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
@ -392,6 +400,7 @@ spa_audiomixer_node_port_get_format (SpaNode *node,
static SpaResult
spa_audiomixer_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortInfo **info)
{
@ -403,25 +412,27 @@ spa_audiomixer_node_port_get_info (SpaNode *node,
this = (SpaAudioMixer *) node->handle;
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0];
*info = &port->info;
return SPA_RESULT_OK;
}
static SpaResult
spa_audiomixer_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
spa_audiomixer_node_port_get_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaProps **props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_audiomixer_node_port_set_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaProps *props)
{
@ -430,6 +441,7 @@ spa_audiomixer_node_port_set_props (SpaNode *node,
static SpaResult
spa_audiomixer_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@ -439,6 +451,7 @@ spa_audiomixer_node_port_use_buffers (SpaNode *node,
static SpaResult
spa_audiomixer_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@ -448,16 +461,9 @@ spa_audiomixer_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_audiomixer_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_audiomixer_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortStatus **status)
{
@ -469,10 +475,10 @@ spa_audiomixer_node_port_get_status (SpaNode *node,
this = (SpaAudioMixer *) node->handle;
if (port_id > MAX_PORTS || !this->ports[port_id].valid)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0];
if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
@ -495,7 +501,7 @@ spa_audiomixer_node_port_push_input (SpaNode *node,
this = (SpaAudioMixer *) node->handle;
if (this->ports[MAX_PORTS].status.flags & SPA_PORT_STATUS_FLAG_HAVE_OUTPUT)
if (this->out_ports[0].status.flags & SPA_PORT_STATUS_FLAG_HAVE_OUTPUT)
return SPA_RESULT_HAVE_ENOUGH_INPUT;
for (i = 0; i < n_info; i++) {
@ -503,12 +509,12 @@ spa_audiomixer_node_port_push_input (SpaNode *node,
SpaAudioMixerPort *port;
int idx = info[i].port_id;
if (idx >= MAX_PORTS || !this->ports[idx].valid) {
if (!CHECK_IN_PORT (this, SPA_DIRECTION_INPUT, idx)) {
info[i].status = SPA_RESULT_INVALID_PORT;
have_error = true;
continue;
}
port = &this->ports[idx];
port = &this->in_ports[idx];
buffer = port->buffers[info[i].buffer_id];
if (buffer == NULL) {
@ -524,19 +530,19 @@ spa_audiomixer_node_port_push_input (SpaNode *node,
continue;
}
if (this->ports[idx].buffer != NULL) {
if (port->buffer != NULL) {
info[i].status = SPA_RESULT_HAVE_ENOUGH_INPUT;
have_error = true;
continue;
}
this->ports[idx].buffer = buffer;
this->ports[idx].buffer_queued = 0;
this->ports[idx].buffer_index = 0;
this->ports[idx].buffer_offset = 0;
port->buffer = buffer;
port->buffer_queued = 0;
port->buffer_index = 0;
port->buffer_offset = 0;
this->port_queued++;
if (this->port_queued == this->port_count)
this->ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
this->out_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
}
info[i].status = SPA_RESULT_OK;
}
@ -592,7 +598,7 @@ add_port_data (SpaAudioMixer *this, SpaBuffer *out, SpaAudioMixerPort *port)
if (++port->buffer_index == port->buffer->n_datas) {
port->buffer = NULL;
port->status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
break;
}
port->buffer_offset = 0;
@ -623,37 +629,37 @@ mix_data (SpaAudioMixer *this, SpaPortOutputInfo *info)
min_size = 0;
min_port = 0;
for (i = 1; i < MAX_PORTS; i++) {
if (!this->ports[i].valid)
for (i = 0; i < MAX_PORTS; i++) {
if (!this->in_ports[i].valid)
continue;
if (this->ports[i].buffer == NULL) {
if (this->in_ports[i].buffer == NULL) {
if (pull_size && info->flags & SPA_PORT_OUTPUT_FLAG_PULL) {
pull_port (this, i, info, pull_size);
}
if (this->ports[i].buffer == NULL)
if (this->in_ports[i].buffer == NULL)
return SPA_RESULT_NEED_MORE_INPUT;
}
if (min_size == 0 || this->ports[i].buffer_queued < min_size) {
min_size = this->ports[i].buffer_queued;
if (min_size == 0 || this->in_ports[i].buffer_queued < min_size) {
min_size = this->in_ports[i].buffer_queued;
min_port = i;
}
}
if (min_port == 0)
return SPA_RESULT_NEED_MORE_INPUT;
buf = this->ports[min_port].buffer;
buf = this->in_ports[min_port].buffer;
info->buffer_id = buf->id;
this->ports[min_port].buffer = NULL;
this->ports[min_port].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
this->in_ports[min_port].buffer = NULL;
this->in_ports[min_port].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
for (i = 1; i < MAX_PORTS; i++) {
if (!this->ports[i].valid || this->ports[i].buffer == NULL)
for (i = 0; i < MAX_PORTS; i++) {
if (!this->in_ports[i].valid || this->in_ports[i].buffer == NULL)
continue;
add_port_data (this, buf, &this->ports[i]);
add_port_data (this, buf, &this->in_ports[i]);
}
return SPA_RESULT_OK;
}
@ -673,10 +679,10 @@ spa_audiomixer_node_port_pull_output (SpaNode *node,
this = (SpaAudioMixer *) node->handle;
if (info->port_id != MAX_PORTS)
if (!CHECK_OUT_PORT (this, SPA_DIRECTION_OUTPUT, info->port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[info->port_id];
port = &this->out_ports[info->port_id];
if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
@ -697,8 +703,17 @@ spa_audiomixer_node_port_pull_output (SpaNode *node,
return SPA_RESULT_OK;
}
static SpaResult
spa_audiomixer_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_audiomixer_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event)
{
@ -726,10 +741,10 @@ static const SpaNode audiomixer_node = {
spa_audiomixer_node_port_set_props,
spa_audiomixer_node_port_use_buffers,
spa_audiomixer_node_port_alloc_buffers,
spa_audiomixer_node_port_reuse_buffer,
spa_audiomixer_node_port_get_status,
spa_audiomixer_node_port_push_input,
spa_audiomixer_node_port_pull_output,
spa_audiomixer_node_port_reuse_buffer,
spa_audiomixer_node_port_push_event,
};
@ -781,10 +796,10 @@ spa_audiomixer_init (const SpaHandleFactory *factory,
this->props[1].props.prop_info = prop_info;
reset_audiomixer_props (&this->props[1]);
this->ports[MAX_PORTS].valid = true;
this->ports[MAX_PORTS].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS |
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
SPA_PORT_INFO_FLAG_NO_REF;
this->out_ports[0].valid = true;
this->out_ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS |
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
SPA_PORT_INFO_FLAG_NO_REF;
return SPA_RESULT_OK;
}

View file

@ -93,6 +93,8 @@ struct _SpaAudioTestSrc {
SpaQueue ready;
};
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
#define DEFAULT_WAVE 0
#define DEFAULT_VOLUME 1.0
#define DEFAULT_FREQ 440.0
@ -470,6 +472,7 @@ spa_audiotestsrc_node_get_port_ids (SpaNode *node,
static SpaResult
spa_audiotestsrc_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -477,6 +480,7 @@ spa_audiotestsrc_node_add_port (SpaNode *node,
static SpaResult
spa_audiotestsrc_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -484,6 +488,7 @@ spa_audiotestsrc_node_remove_port (SpaNode *node,
static SpaResult
spa_audiotestsrc_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
@ -497,7 +502,7 @@ spa_audiotestsrc_node_port_enum_formats (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
index = (*state == NULL ? 0 : *(int*)state);
@ -535,6 +540,7 @@ clear_buffers (SpaAudioTestSrc *this)
static SpaResult
spa_audiotestsrc_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
@ -547,7 +553,7 @@ spa_audiotestsrc_node_port_set_format (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (format == NULL) {
@ -590,6 +596,7 @@ spa_audiotestsrc_node_port_set_format (SpaNode *node,
static SpaResult
spa_audiotestsrc_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaFormat **format)
{
@ -600,7 +607,7 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (!this->have_format)
@ -613,6 +620,7 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node,
static SpaResult
spa_audiotestsrc_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortInfo **info)
{
@ -623,7 +631,7 @@ spa_audiotestsrc_node_port_get_info (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
*info = &this->info;
@ -632,15 +640,17 @@ spa_audiotestsrc_node_port_get_info (SpaNode *node,
}
static SpaResult
spa_audiotestsrc_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
spa_audiotestsrc_node_port_get_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaProps **props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_audiotestsrc_node_port_set_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaProps *props)
{
@ -649,6 +659,7 @@ spa_audiotestsrc_node_port_set_props (SpaNode *node,
static SpaResult
spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@ -660,7 +671,7 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (!this->have_format)
@ -716,6 +727,7 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
static SpaResult
spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@ -729,7 +741,7 @@ spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (!this->have_format)
@ -741,44 +753,9 @@ spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_audiotestsrc_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
SpaAudioTestSrc *this;
ATSBuffer *b;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
if (!this->have_buffers)
return SPA_RESULT_NO_BUFFERS;
if (buffer_id >= this->n_buffers)
return SPA_RESULT_INVALID_BUFFER_ID;
b = &this->buffers[buffer_id];
if (!b->outstanding)
return SPA_RESULT_OK;
b->outstanding = false;
b->next = NULL;
SPA_QUEUE_PUSH_TAIL (&this->empty, ATSBuffer, next, b);
if (this->empty.length == 1 && !this->props[1].live)
update_poll_enabled (this, true);
return SPA_RESULT_OK;
}
static SpaResult
spa_audiotestsrc_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortStatus **status)
{
@ -789,7 +766,7 @@ spa_audiotestsrc_node_port_get_status (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (!this->have_format)
@ -808,6 +785,7 @@ spa_audiotestsrc_node_port_push_input (SpaNode *node,
{
return SPA_RESULT_INVALID_PORT;
}
static SpaResult
spa_audiotestsrc_node_port_pull_output (SpaNode *node,
unsigned int n_info,
@ -854,8 +832,45 @@ spa_audiotestsrc_node_port_pull_output (SpaNode *node,
return SPA_RESULT_OK;
}
static SpaResult
spa_audiotestsrc_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
SpaAudioTestSrc *this;
ATSBuffer *b;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
if (!this->have_buffers)
return SPA_RESULT_NO_BUFFERS;
if (buffer_id >= this->n_buffers)
return SPA_RESULT_INVALID_BUFFER_ID;
b = &this->buffers[buffer_id];
if (!b->outstanding)
return SPA_RESULT_OK;
b->outstanding = false;
b->next = NULL;
SPA_QUEUE_PUSH_TAIL (&this->empty, ATSBuffer, next, b);
if (this->empty.length == 1 && !this->props[1].live)
update_poll_enabled (this, true);
return SPA_RESULT_OK;
}
static SpaResult
spa_audiotestsrc_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event)
{
@ -883,10 +898,10 @@ static const SpaNode audiotestsrc_node = {
spa_audiotestsrc_node_port_set_props,
spa_audiotestsrc_node_port_use_buffers,
spa_audiotestsrc_node_port_alloc_buffers,
spa_audiotestsrc_node_port_reuse_buffer,
spa_audiotestsrc_node_port_get_status,
spa_audiotestsrc_node_port_push_input,
spa_audiotestsrc_node_port_pull_output,
spa_audiotestsrc_node_port_reuse_buffer,
spa_audiotestsrc_node_port_push_event,
};

View file

@ -400,20 +400,6 @@ spa_ffmpeg_dec_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_ffmpeg_dec_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_ffmpeg_dec_node_port_get_status (SpaNode *node,
uint32_t port_id,
@ -478,6 +464,20 @@ spa_ffmpeg_dec_node_port_pull_output (SpaNode *node,
return SPA_RESULT_OK;
}
static SpaResult
spa_ffmpeg_dec_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_ffmpeg_dec_node_port_push_event (SpaNode *node,
uint32_t port_id,
@ -508,10 +508,10 @@ static const SpaNode ffmpeg_dec_node = {
spa_ffmpeg_dec_node_port_set_props,
spa_ffmpeg_dec_node_port_use_buffers,
spa_ffmpeg_dec_node_port_alloc_buffers,
spa_ffmpeg_dec_node_port_reuse_buffer,
spa_ffmpeg_dec_node_port_get_status,
spa_ffmpeg_dec_node_port_push_input,
spa_ffmpeg_dec_node_port_pull_output,
spa_ffmpeg_dec_node_port_reuse_buffer,
spa_ffmpeg_dec_node_port_push_event,
};

View file

@ -403,20 +403,6 @@ spa_ffmpeg_enc_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_ffmpeg_enc_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_ffmpeg_enc_node_port_get_status (SpaNode *node,
uint32_t port_id,
@ -482,6 +468,20 @@ spa_ffmpeg_enc_node_port_pull_output (SpaNode *node,
return SPA_RESULT_OK;
}
static SpaResult
spa_ffmpeg_enc_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
if (!IS_VALID_PORT (port_id))
return SPA_RESULT_INVALID_PORT;
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_ffmpeg_enc_node_port_push_event (SpaNode *node,
uint32_t port_id,
@ -511,10 +511,10 @@ static const SpaNode ffmpeg_enc_node = {
spa_ffmpeg_enc_node_port_set_props,
spa_ffmpeg_enc_node_port_use_buffers,
spa_ffmpeg_enc_node_port_alloc_buffers,
spa_ffmpeg_enc_node_port_reuse_buffer,
spa_ffmpeg_enc_node_port_get_status,
spa_ffmpeg_enc_node_port_push_input,
spa_ffmpeg_enc_node_port_pull_output,
spa_ffmpeg_enc_node_port_reuse_buffer,
spa_ffmpeg_enc_node_port_push_event,
};

View file

@ -37,14 +37,19 @@
#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))
#define CHECK_IN_PORT_ID(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_INPUTS)
#define CHECK_OUT_PORT_ID(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) < MAX_OUTPUTS)
#define CHECK_PORT_ID(this,d,p) (CHECK_IN_PORT_ID(this,d,p) || CHECK_OUT_PORT_ID(this,d,p))
#define CHECK_FREE_IN_PORT(this,d,p) (CHECK_IN_PORT_ID(this,d,p) && !(this)->in_ports[p].valid)
#define CHECK_FREE_OUT_PORT(this,d,p) (CHECK_OUT_PORT_ID(this,d,p) && !(this)->out_ports[p].valid)
#define CHECK_FREE_PORT(this,d,p) (CHECK_FREE_IN_PORT (this,d,p) || CHECK_FREE_OUT_PORT (this,d,p))
#define CHECK_IN_PORT(this,d,p) (CHECK_IN_PORT_ID(this,d,p) && (this)->in_ports[p].valid)
#define CHECK_OUT_PORT(this,d,p) (CHECK_OUT_PORT_ID(this,d,p) && (this)->out_ports[p].valid)
#define CHECK_PORT(this,d,p) (CHECK_IN_PORT (this,d,p) || CHECK_OUT_PORT (this,d,p))
typedef struct _SpaProxy SpaProxy;
typedef struct _ProxyBuffer ProxyBuffer;
@ -65,7 +70,7 @@ typedef struct {
typedef struct {
bool valid;
SpaPortInfo info;
SpaPortInfo *info;
SpaFormat *format;
unsigned int n_formats;
SpaFormat **formats;
@ -99,7 +104,8 @@ struct _SpaProxy {
unsigned int n_inputs;
unsigned int max_outputs;
unsigned int n_outputs;
SpaProxyPort ports[MAX_PORTS];
SpaProxyPort in_ports[MAX_INPUTS];
SpaProxyPort out_ports[MAX_OUTPUTS];
uint32_t seq;
};
@ -331,10 +337,10 @@ spa_proxy_node_get_n_ports (SpaNode *node,
if (n_input_ports)
*n_input_ports = this->n_inputs;
if (n_output_ports)
*n_output_ports = this->n_outputs;
if (max_input_ports)
*max_input_ports = this->max_inputs;
if (n_output_ports)
*n_output_ports = this->n_outputs;
if (max_output_ports)
*max_output_ports = this->max_outputs;
@ -358,14 +364,14 @@ spa_proxy_node_get_port_ids (SpaNode *node,
if (input_ids) {
for (c = 0, i = 0; i < MAX_INPUTS && c < n_input_ports; i++) {
if (this->ports[i].valid)
if (this->in_ports[i].valid)
input_ids[c++] = i;
}
}
if (output_ids) {
for (c = 0, i = 0; i < MAX_OUTPUTS && c < n_output_ports; i++) {
if (this->ports[MAX_INPUTS + i].valid)
output_ids[c++] = MAX_INPUTS + i;
if (this->out_ports[i].valid)
output_ids[c++] = i;
}
}
return SPA_RESULT_OK;
@ -379,7 +385,11 @@ do_update_port (SpaProxy *this,
unsigned int i;
size_t size;
port = &this->ports[pu->port_id];
if (pu->direction == SPA_DIRECTION_INPUT) {
port = &this->in_ports[pu->port_id];
} else {
port = &this->out_ports[pu->port_id];
}
if (pu->change_mask & SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS) {
for (i = 0; i < port->n_formats; i++)
@ -403,7 +413,11 @@ do_update_port (SpaProxy *this,
}
if (pu->change_mask & SPA_CONTROL_CMD_PORT_UPDATE_INFO && pu->info) {
port->info = *pu->info;
if (port->info)
free (port->info);
size = spa_port_info_get_size (pu->info);
port->info = spa_port_info_copy_into (malloc (size), pu->info);
spa_debug_port_info (port->info);
}
if (!port->valid) {
@ -411,7 +425,7 @@ do_update_port (SpaProxy *this,
port->format = NULL;
port->valid = true;
if (pu->port_id < MAX_INPUTS)
if (pu->direction == SPA_DIRECTION_INPUT)
this->n_inputs++;
else
this->n_outputs++;
@ -421,6 +435,7 @@ do_update_port (SpaProxy *this,
static void
clear_port (SpaProxy *this,
SpaProxyPort *port,
SpaDirection direction,
uint32_t port_id)
{
SpaControlCmdPortUpdate pu;
@ -429,6 +444,7 @@ clear_port (SpaProxy *this,
SPA_CONTROL_CMD_PORT_UPDATE_FORMAT |
SPA_CONTROL_CMD_PORT_UPDATE_PROPS |
SPA_CONTROL_CMD_PORT_UPDATE_INFO;
pu.direction = direction;
pu.port_id = port_id;
pu.n_possible_formats = 0;
pu.possible_formats = NULL;
@ -441,24 +457,26 @@ clear_port (SpaProxy *this,
static void
do_uninit_port (SpaProxy *this,
SpaDirection direction,
uint32_t port_id)
{
SpaProxyPort *port;
fprintf (stderr, "proxy %p: removing port %d\n", this, port_id);
port = &this->ports[port_id];
if (port_id < MAX_INPUTS)
if (direction == SPA_DIRECTION_INPUT) {
port = &this->in_ports[port_id];
this->n_inputs--;
else
} else {
port = &this->out_ports[port_id];
this->n_outputs--;
clear_port (this, port, port_id);
}
clear_port (this, port, direction, port_id);
port->valid = false;
}
static SpaResult
spa_proxy_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
SpaProxy *this;
@ -469,17 +487,18 @@ spa_proxy_node_add_port (SpaNode *node,
this = (SpaProxy *) node->handle;
if (!CHECK_FREE_PORT_ID (this, port_id))
if (!CHECK_FREE_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
clear_port (this, port, port_id);
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
clear_port (this, port, direction, port_id);
return SPA_RESULT_OK;
}
static SpaResult
spa_proxy_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
SpaProxy *this;
@ -489,16 +508,17 @@ spa_proxy_node_remove_port (SpaNode *node,
this = (SpaProxy *) node->handle;
if (!CHECK_PORT_ID (this, port_id))
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
do_uninit_port (this, port_id);
do_uninit_port (this, direction, port_id);
return SPA_RESULT_OK;
}
static SpaResult
spa_proxy_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
@ -513,10 +533,10 @@ spa_proxy_node_port_enum_formats (SpaNode *node,
this = (SpaProxy *) node->handle;
if (!CHECK_PORT_ID (this, port_id))
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
index = (*state == NULL ? 0 : *(int*)state);
@ -531,6 +551,7 @@ spa_proxy_node_port_enum_formats (SpaNode *node,
static SpaResult
spa_proxy_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
@ -547,11 +568,13 @@ spa_proxy_node_port_set_format (SpaNode *node,
this = (SpaProxy *) node->handle;
if (!CHECK_PORT_ID (this, port_id))
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0);
sf.seq = this->seq++;
sf.direction = direction;
sf.port_id = port_id;
sf.flags = flags;
sf.format = (SpaFormat *) format;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_SET_FORMAT, &sf);
@ -567,6 +590,7 @@ spa_proxy_node_port_set_format (SpaNode *node,
static SpaResult
spa_proxy_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaFormat **format)
{
@ -578,10 +602,10 @@ spa_proxy_node_port_get_format (SpaNode *node,
this = (SpaProxy *) node->handle;
if (!CHECK_PORT_ID (this, port_id))
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
if (!port->format)
return SPA_RESULT_NO_FORMAT;
@ -593,6 +617,7 @@ spa_proxy_node_port_get_format (SpaNode *node,
static SpaResult
spa_proxy_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortInfo **info)
{
@ -604,26 +629,28 @@ spa_proxy_node_port_get_info (SpaNode *node,
this = (SpaProxy *) node->handle;
if (!CHECK_PORT_ID (this, port_id))
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
*info = &port->info;
*info = port->info;
return SPA_RESULT_OK;
}
static SpaResult
spa_proxy_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
spa_proxy_node_port_get_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaProps **props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_proxy_node_port_set_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaProps *props)
{
@ -632,6 +659,7 @@ spa_proxy_node_port_set_props (SpaNode *node,
static SpaResult
spa_proxy_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortStatus **status)
{
@ -643,10 +671,10 @@ spa_proxy_node_port_get_status (SpaNode *node,
this = (SpaProxy *) node->handle;
if (!CHECK_PORT_ID (this, port_id))
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
if (!port->format)
return SPA_RESULT_NO_FORMAT;
@ -658,6 +686,7 @@ spa_proxy_node_port_get_status (SpaNode *node,
static SpaResult
spa_proxy_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@ -682,10 +711,10 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
this = (SpaProxy *) node->handle;
fprintf (stderr, "proxy %p: use buffers %p %u\n", this, buffers, n_buffers);
if (!CHECK_PORT_ID (this, port_id))
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
if (!port->format)
return SPA_RESULT_NO_FORMAT;
@ -708,9 +737,7 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
b->size = spa_buffer_get_size (buffers[i]);
b->offset = size;
size += b->size;
for (j = 0; j < buffers[i]->n_datas; j++) {
for (j = 0; j < buffers[i]->n_metas; j++) {
memcpy (&b->buffer.metas[j], &buffers[i]->metas[j], sizeof (SpaMeta));
}
@ -719,21 +746,37 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
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->maxsize;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_MEM, &am);
switch (d->type) {
case SPA_DATA_TYPE_FD:
am.direction = direction;
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->maxsize;
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++;
b->buffer.datas[j].type = SPA_DATA_TYPE_ID;
b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem);
n_mem++;
break;
case SPA_DATA_TYPE_MEMPTR:
b->buffer.datas[j].data = SPA_INT_TO_PTR (b->size);
b->size += d->size;
break;
default:
b->buffer.datas[j].type = SPA_DATA_TYPE_INVALID;
b->buffer.datas[j].data = 0;
fprintf (stderr, "invalid memory type %d\n", d->type);
break;
}
}
size += b->size;
}
/* make mem for the buffers */
port->buffer_mem_id = n_mem;
port->buffer_mem_id = n_mem++;
port->buffer_mem_size = size;
port->buffer_mem_fd = memfd_create ("spa-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
@ -754,22 +797,28 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
for (i = 0; i < n_buffers; i++) {
ProxyBuffer *b = &port->buffers[i];
size_t len;
SpaBuffer *sb;
SpaMeta *sbm;
SpaData *sbd;
len = spa_buffer_serialize (p, &b->buffer);
spa_buffer_serialize (p, &b->buffer);
sb = p;
b->buffer.datas = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->datas), SpaData);
sbm = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->metas), SpaMeta);
sbd = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->datas), SpaData);
for (j = 0; j < b->buffer.n_metas; j++)
b->metas[j].data = SPA_MEMBER (sb, SPA_PTR_TO_INT (sbm[j].data), void);
p += len;
for (j = 0; j < b->buffer.n_datas; j++) {
if (b->datas[j].type == SPA_DATA_TYPE_MEMPTR)
b->datas[j].data = SPA_MEMBER (sb, SPA_PTR_TO_INT (sbd[j].data), void);
}
p += b->size;
}
am.direction = direction;
am.port_id = port_id;
am.mem_id = port->buffer_mem_id;
am.fd_index = spa_control_builder_add_fd (&builder, port->buffer_mem_fd, false);
@ -778,18 +827,18 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
am.size = size;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_MEM, &am);
memref = alloca (n_mem * sizeof (SpaControlMemRef));
memref = alloca (n_buffers * 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.direction = direction;
ub.port_id = port_id;
ub.n_buffers = port->n_buffers;
ub.n_buffers = n_buffers;
ub.buffers = memref;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_USE_BUFFERS, &ub);
@ -805,6 +854,7 @@ spa_proxy_node_port_use_buffers (SpaNode *node,
static SpaResult
spa_proxy_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@ -819,10 +869,10 @@ spa_proxy_node_port_alloc_buffers (SpaNode *node,
this = (SpaProxy *) node->handle;
if (!CHECK_PORT_ID (this, port_id))
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
if (!port->format)
return SPA_RESULT_NO_FORMAT;
@ -830,45 +880,24 @@ spa_proxy_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_proxy_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
static void
copy_meta_in (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
{
SpaProxy *this;
SpaControlBuilder builder;
SpaControl control;
uint8_t buf[128];
SpaResult res;
SpaControlCmdNodeEvent cne;
SpaNodeEvent ne;
SpaNodeEventReuseBuffer rb;
ProxyBuffer *b = &port->buffers[buffer_id];
unsigned int i;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = (SpaProxy *) node->handle;
if (!CHECK_PORT_ID (this, port_id))
return SPA_RESULT_INVALID_PORT;
/* send start */
spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0);
cne.event = &ne;
ne.type = SPA_NODE_EVENT_TYPE_REUSE_BUFFER;
ne.data = &rb;
ne.size = sizeof (rb);
rb.port_id = port_id;
rb.buffer_id = buffer_id;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_NODE_EVENT, &cne);
spa_control_builder_end (&builder, &control);
if ((res = spa_control_write (&control, this->fds[0].fd)) < 0)
fprintf (stderr, "proxy %p: error writing control %d\n", this, res);
spa_control_clear (&control);
return res;
for (i = 0; i < b->outbuf->n_metas; i++) {
SpaMeta *sm = &b->metas[i];
SpaMeta *dm = &b->outbuf->metas[i];
memcpy (dm->data, sm->data, dm->size);
}
for (i = 0; i < b->outbuf->n_datas; i++) {
b->outbuf->datas[i].size = b->buffer.datas[i].size;
if (b->outbuf->datas[i].type == SPA_DATA_TYPE_MEMPTR) {
fprintf (stderr, "memcpy in %zd\n", b->buffer.datas[i].size);
memcpy (b->outbuf->datas[i].data, b->datas[i].data, b->buffer.datas[i].size);
}
}
}
static void
@ -884,6 +913,10 @@ copy_meta (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id)
}
for (i = 0; i < b->outbuf->n_datas; i++) {
b->buffer.datas[i].size = b->outbuf->datas[i].size;
if (b->datas[i].type == SPA_DATA_TYPE_MEMPTR) {
fprintf (stderr, "memcpy out %zd\n", b->outbuf->datas[i].size);
memcpy (b->datas[i].data, b->outbuf->datas[i].data, b->outbuf->datas[i].size);
}
}
}
@ -911,13 +944,13 @@ spa_proxy_node_port_push_input (SpaNode *node,
spa_control_builder_init_into (&builder, buf, sizeof(buf), NULL, 0);
for (i = 0; i < n_info; i++) {
if (!CHECK_PORT_ID_IN (this, info[i].port_id)) {
if (!CHECK_IN_PORT (this, SPA_DIRECTION_INPUT, info[i].port_id)) {
printf ("invalid port %d\n", info[i].port_id);
info[i].status = SPA_RESULT_INVALID_PORT;
have_error = true;
continue;
}
port = &this->ports[info[i].port_id];
port = &this->in_ports[info[i].port_id];
if (!port->format) {
info[i].status = SPA_RESULT_NO_FORMAT;
@ -935,6 +968,7 @@ spa_proxy_node_port_push_input (SpaNode *node,
copy_meta (this, port, info[i].buffer_id);
pb.direction = SPA_DIRECTION_INPUT;
pb.port_id = info[i].port_id;
pb.buffer_id = info[i].buffer_id;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_PROCESS_BUFFER, &pb);
@ -973,14 +1007,14 @@ spa_proxy_node_port_pull_output (SpaNode *node,
this = (SpaProxy *) node->handle;
for (i = 0; i < n_info; i++) {
if (!CHECK_PORT_ID_OUT (this, info[i].port_id)) {
if (!CHECK_OUT_PORT (this, SPA_DIRECTION_OUTPUT, info[i].port_id)) {
fprintf (stderr, "invalid port %u\n", info[i].port_id);
info[i].status = SPA_RESULT_INVALID_PORT;
have_error = true;
continue;
}
port = &this->ports[info[i].port_id];
port = &this->out_ports[info[i].port_id];
if (!port->format) {
info[i].status = SPA_RESULT_NO_FORMAT;
@ -1001,8 +1035,50 @@ spa_proxy_node_port_pull_output (SpaNode *node,
return SPA_RESULT_OK;
}
static SpaResult
spa_proxy_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
SpaProxy *this;
SpaControlBuilder builder;
SpaControl control;
uint8_t buf[128];
SpaResult res;
SpaControlCmdNodeEvent cne;
SpaNodeEvent ne;
SpaNodeEventReuseBuffer rb;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = (SpaProxy *) node->handle;
if (!CHECK_OUT_PORT (this, SPA_DIRECTION_OUTPUT, port_id))
return SPA_RESULT_INVALID_PORT;
/* send start */
spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0);
cne.event = &ne;
ne.type = SPA_NODE_EVENT_TYPE_REUSE_BUFFER;
ne.data = &rb;
ne.size = sizeof (rb);
rb.port_id = port_id;
rb.buffer_id = buffer_id;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_NODE_EVENT, &cne);
spa_control_builder_end (&builder, &control);
if ((res = spa_control_write (&control, this->fds[0].fd)) < 0)
fprintf (stderr, "proxy %p: error writing control %d\n", this, res);
spa_control_clear (&control);
return res;
}
static SpaResult
spa_proxy_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event)
{
@ -1092,13 +1168,13 @@ parse_control (SpaProxy *this,
if (spa_control_iter_parse_cmd (&it, &pu) < 0)
break;
if (pu.port_id >= MAX_PORTS)
if (!CHECK_PORT_ID (this, pu.direction, pu.port_id))
break;
remove = (pu.change_mask == 0);
if (remove) {
do_uninit_port (this, pu.port_id);
do_uninit_port (this, pu.direction, pu.port_id);
} else {
do_update_port (this, &pu);
}
@ -1142,10 +1218,16 @@ parse_control (SpaProxy *this,
if (spa_control_iter_parse_cmd (&it, &cmd) < 0)
break;
port = &this->ports[cmd.port_id];
if (!CHECK_PORT (this, cmd.direction, cmd.port_id))
break;
port = cmd.direction == SPA_DIRECTION_INPUT ? &this->in_ports[cmd.port_id] : &this->out_ports[cmd.port_id];
if (port->buffer_id != SPA_ID_INVALID)
fprintf (stderr, "proxy %p: unprocessed buffer: %d\n", this, port->buffer_id);
copy_meta_in (this, port, cmd.buffer_id);
port->buffer_id = cmd.buffer_id;
break;
}
@ -1208,10 +1290,10 @@ static const SpaNode proxy_node = {
spa_proxy_node_port_set_props,
spa_proxy_node_port_use_buffers,
spa_proxy_node_port_alloc_buffers,
spa_proxy_node_port_reuse_buffer,
spa_proxy_node_port_get_status,
spa_proxy_node_port_push_input,
spa_proxy_node_port_pull_output,
spa_proxy_node_port_reuse_buffer,
spa_proxy_node_port_push_event,
};
@ -1247,9 +1329,13 @@ proxy_clear (SpaHandle *handle)
this = (SpaProxy *) handle;
for (i = 0; i < MAX_PORTS; i++) {
if (this->ports[i].valid)
clear_port (this, &this->ports[i], i);
for (i = 0; i < MAX_INPUTS; i++) {
if (this->in_ports[i].valid)
clear_port (this, &this->in_ports[i], SPA_DIRECTION_INPUT, i);
}
for (i = 0; i < MAX_OUTPUTS; i++) {
if (this->out_ports[i].valid)
clear_port (this, &this->out_ports[i], SPA_DIRECTION_OUTPUT, i);
}
return SPA_RESULT_OK;

View file

@ -127,6 +127,7 @@ struct _SpaV4l2Source {
SpaV4l2State state[1];
};
#define CHECK_PORT(this, direction, port_id) ((direction) == SPA_DIRECTION_OUTPUT && (port_id) == 0)
static void
update_state (SpaV4l2Source *this, SpaNodeState state)
@ -324,6 +325,7 @@ spa_v4l2_source_node_get_port_ids (SpaNode *node,
static SpaResult
spa_v4l2_source_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -331,6 +333,7 @@ spa_v4l2_source_node_add_port (SpaNode *node,
static SpaResult
spa_v4l2_source_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -355,6 +358,7 @@ spa_v4l2_format_init (V4l2Format *f)
static SpaResult
spa_v4l2_source_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
@ -368,7 +372,7 @@ spa_v4l2_source_node_port_enum_formats (SpaNode *node,
this = (SpaV4l2Source *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
res = spa_v4l2_enum_format (this, format, filter, state);
@ -378,6 +382,7 @@ spa_v4l2_source_node_port_enum_formats (SpaNode *node,
static SpaResult
spa_v4l2_source_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
@ -393,7 +398,7 @@ spa_v4l2_source_node_port_set_format (SpaNode *node,
this = (SpaV4l2Source *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
state = &this->state[port_id];
@ -450,6 +455,7 @@ spa_v4l2_source_node_port_set_format (SpaNode *node,
static SpaResult
spa_v4l2_source_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaFormat **format)
{
@ -461,7 +467,7 @@ spa_v4l2_source_node_port_get_format (SpaNode *node,
this = (SpaV4l2Source *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
state = &this->state[port_id];
@ -476,6 +482,7 @@ spa_v4l2_source_node_port_get_format (SpaNode *node,
static SpaResult
spa_v4l2_source_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortInfo **info)
{
@ -486,7 +493,7 @@ spa_v4l2_source_node_port_get_info (SpaNode *node,
this = (SpaV4l2Source *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
*info = &this->state[port_id].info;
@ -495,15 +502,17 @@ spa_v4l2_source_node_port_get_info (SpaNode *node,
}
static SpaResult
spa_v4l2_source_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
spa_v4l2_source_node_port_get_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaProps **props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_v4l2_source_node_port_set_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaProps *props)
{
@ -512,6 +521,7 @@ spa_v4l2_source_node_port_set_props (SpaNode *node,
static SpaResult
spa_v4l2_source_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@ -525,7 +535,7 @@ spa_v4l2_source_node_port_use_buffers (SpaNode *node,
this = (SpaV4l2Source *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
state = &this->state[port_id];
@ -552,6 +562,7 @@ spa_v4l2_source_node_port_use_buffers (SpaNode *node,
static SpaResult
spa_v4l2_source_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaAllocParam **params,
unsigned int n_params,
@ -567,7 +578,7 @@ spa_v4l2_source_node_port_alloc_buffers (SpaNode *node,
this = (SpaV4l2Source *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
state = &this->state[port_id];
@ -587,38 +598,9 @@ spa_v4l2_source_node_port_alloc_buffers (SpaNode *node,
return res;
}
static SpaResult
spa_v4l2_source_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
SpaV4l2Source *this;
SpaV4l2State *state;
SpaResult res;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = (SpaV4l2Source *) node->handle;
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
state = &this->state[port_id];
if (state->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (buffer_id >= state->n_buffers)
return SPA_RESULT_INVALID_BUFFER_ID;
res = spa_v4l2_buffer_recycle (this, buffer_id);
return res;
}
static SpaResult
spa_v4l2_source_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortStatus **status)
{
@ -629,7 +611,7 @@ spa_v4l2_source_node_port_get_status (SpaNode *node,
this = (SpaV4l2Source *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
*status = &this->state[port_id].status;
@ -693,8 +675,39 @@ spa_v4l2_source_node_port_pull_output (SpaNode *node,
return SPA_RESULT_OK;
}
static SpaResult
spa_v4l2_source_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
SpaV4l2Source *this;
SpaV4l2State *state;
SpaResult res;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = (SpaV4l2Source *) node->handle;
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
state = &this->state[port_id];
if (state->n_buffers == 0)
return SPA_RESULT_NO_BUFFERS;
if (buffer_id >= state->n_buffers)
return SPA_RESULT_INVALID_BUFFER_ID;
res = spa_v4l2_buffer_recycle (this, buffer_id);
return res;
}
static SpaResult
spa_v4l2_source_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event)
{
@ -723,10 +736,10 @@ static const SpaNode v4l2source_node = {
spa_v4l2_source_node_port_set_props,
spa_v4l2_source_node_port_use_buffers,
spa_v4l2_source_node_port_alloc_buffers,
spa_v4l2_source_node_port_reuse_buffer,
spa_v4l2_source_node_port_get_status,
spa_v4l2_source_node_port_push_input,
spa_v4l2_source_node_port_pull_output,
spa_v4l2_source_node_port_reuse_buffer,
spa_v4l2_source_node_port_push_event,
};

View file

@ -96,6 +96,8 @@ struct _SpaVideoTestSrc {
SpaQueue ready;
};
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
#define DEFAULT_LIVE true
enum {
@ -418,6 +420,7 @@ spa_videotestsrc_node_get_port_ids (SpaNode *node,
static SpaResult
spa_videotestsrc_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -425,6 +428,7 @@ spa_videotestsrc_node_add_port (SpaNode *node,
static SpaResult
spa_videotestsrc_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -432,6 +436,7 @@ spa_videotestsrc_node_remove_port (SpaNode *node,
static SpaResult
spa_videotestsrc_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
@ -445,7 +450,7 @@ spa_videotestsrc_node_port_enum_formats (SpaNode *node,
this = (SpaVideoTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
index = (*state == NULL ? 0 : *(int*)state);
@ -483,6 +488,7 @@ clear_buffers (SpaVideoTestSrc *this)
static SpaResult
spa_videotestsrc_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
@ -495,7 +501,7 @@ spa_videotestsrc_node_port_set_format (SpaNode *node,
this = (SpaVideoTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (format == NULL) {
@ -539,6 +545,7 @@ spa_videotestsrc_node_port_set_format (SpaNode *node,
static SpaResult
spa_videotestsrc_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaFormat **format)
{
@ -549,7 +556,7 @@ spa_videotestsrc_node_port_get_format (SpaNode *node,
this = (SpaVideoTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (!this->have_format)
@ -562,6 +569,7 @@ spa_videotestsrc_node_port_get_format (SpaNode *node,
static SpaResult
spa_videotestsrc_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortInfo **info)
{
@ -572,7 +580,7 @@ spa_videotestsrc_node_port_get_info (SpaNode *node,
this = (SpaVideoTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
*info = &this->info;
@ -581,15 +589,17 @@ spa_videotestsrc_node_port_get_info (SpaNode *node,
}
static SpaResult
spa_videotestsrc_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
spa_videotestsrc_node_port_get_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaProps **props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_videotestsrc_node_port_set_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaProps *props)
{
@ -598,6 +608,7 @@ spa_videotestsrc_node_port_set_props (SpaNode *node,
static SpaResult
spa_videotestsrc_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@ -609,7 +620,7 @@ spa_videotestsrc_node_port_use_buffers (SpaNode *node,
this = (SpaVideoTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (!this->have_format)
@ -667,6 +678,7 @@ spa_videotestsrc_node_port_use_buffers (SpaNode *node,
static SpaResult
spa_videotestsrc_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@ -681,7 +693,7 @@ spa_videotestsrc_node_port_alloc_buffers (SpaNode *node,
this = (SpaVideoTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (!this->have_format)
@ -698,44 +710,9 @@ spa_videotestsrc_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_OK;
}
static SpaResult
spa_videotestsrc_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
SpaVideoTestSrc *this;
VTSBuffer *b;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = (SpaVideoTestSrc *) node->handle;
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
if (!this->have_buffers)
return SPA_RESULT_NO_BUFFERS;
if (buffer_id >= this->n_buffers)
return SPA_RESULT_INVALID_BUFFER_ID;
b = &this->buffers[buffer_id];
if (!b->outstanding)
return SPA_RESULT_OK;
b->outstanding = false;
b->next = NULL;
SPA_QUEUE_PUSH_TAIL (&this->empty, VTSBuffer, next, b);
if (this->empty.length == 1 && !this->props[1].live)
update_poll_enabled (this, true);
return SPA_RESULT_OK;
}
static SpaResult
spa_videotestsrc_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortStatus **status)
{
@ -746,7 +723,7 @@ spa_videotestsrc_node_port_get_status (SpaNode *node,
this = (SpaVideoTestSrc *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (!this->have_format)
@ -811,8 +788,45 @@ spa_videotestsrc_node_port_pull_output (SpaNode *node,
return SPA_RESULT_OK;
}
static SpaResult
spa_videotestsrc_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
SpaVideoTestSrc *this;
VTSBuffer *b;
if (node == NULL || node->handle == NULL)
return SPA_RESULT_INVALID_ARGUMENTS;
this = (SpaVideoTestSrc *) node->handle;
if (port_id != 0)
return SPA_RESULT_INVALID_PORT;
if (!this->have_buffers)
return SPA_RESULT_NO_BUFFERS;
if (buffer_id >= this->n_buffers)
return SPA_RESULT_INVALID_BUFFER_ID;
b = &this->buffers[buffer_id];
if (!b->outstanding)
return SPA_RESULT_OK;
b->outstanding = false;
b->next = NULL;
SPA_QUEUE_PUSH_TAIL (&this->empty, VTSBuffer, next, b);
if (this->empty.length == 1 && !this->props[1].live)
update_poll_enabled (this, true);
return SPA_RESULT_OK;
}
static SpaResult
spa_videotestsrc_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event)
{
@ -840,10 +854,10 @@ static const SpaNode videotestsrc_node = {
spa_videotestsrc_node_port_set_props,
spa_videotestsrc_node_port_use_buffers,
spa_videotestsrc_node_port_alloc_buffers,
spa_videotestsrc_node_port_reuse_buffer,
spa_videotestsrc_node_port_get_status,
spa_videotestsrc_node_port_push_input,
spa_videotestsrc_node_port_pull_output,
spa_videotestsrc_node_port_reuse_buffer,
spa_videotestsrc_node_port_push_event,
};

View file

@ -53,9 +53,14 @@ struct _SpaVolume {
SpaFormatAudio query_format;
SpaFormatAudio current_format;
SpaVolumePort ports[2];
SpaVolumePort in_ports[1];
SpaVolumePort out_ports[1];
};
#define CHECK_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0)
#define CHECK_OUT_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
#define CHECK_PORT(this,d,p) ((p) == 0)
static const double default_volume = 1.0;
static const double min_volume = 0.0;
static const double max_volume = 10.0;
@ -103,7 +108,7 @@ update_state (SpaVolume *this, SpaNodeState state)
static SpaResult
spa_volume_node_get_props (SpaNode *node,
SpaProps **props)
SpaProps **props)
{
SpaVolume *this;
@ -120,7 +125,7 @@ spa_volume_node_get_props (SpaNode *node,
static SpaResult
spa_volume_node_set_props (SpaNode *node,
const SpaProps *props)
const SpaProps *props)
{
SpaVolume *this;
SpaVolumeProps *p;
@ -203,10 +208,10 @@ spa_volume_node_get_n_ports (SpaNode *node,
if (n_input_ports)
*n_input_ports = 1;
if (n_output_ports)
*n_output_ports = 1;
if (max_input_ports)
*max_input_ports = 1;
if (n_output_ports)
*n_output_ports = 1;
if (max_output_ports)
*max_output_ports = 1;
@ -226,7 +231,7 @@ spa_volume_node_get_port_ids (SpaNode *node,
if (n_input_ports > 0 && input_ids)
input_ids[0] = 0;
if (n_output_ports > 0 && output_ids)
output_ids[0] = 1;
output_ids[0] = 0;
return SPA_RESULT_OK;
}
@ -234,6 +239,7 @@ spa_volume_node_get_port_ids (SpaNode *node,
static SpaResult
spa_volume_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -241,6 +247,7 @@ spa_volume_node_add_port (SpaNode *node,
static SpaResult
spa_volume_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -248,6 +255,7 @@ spa_volume_node_remove_port (SpaNode *node,
static SpaResult
spa_volume_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
@ -261,7 +269,7 @@ spa_volume_node_port_enum_formats (SpaNode *node,
this = (SpaVolume *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
index = (*state == NULL ? 0 : *(int*)state);
@ -283,6 +291,7 @@ spa_volume_node_port_enum_formats (SpaNode *node,
static SpaResult
spa_volume_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
@ -296,10 +305,10 @@ spa_volume_node_port_set_format (SpaNode *node,
this = (SpaVolume *) node->handle;
if (port_id >= 2)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
if (format == NULL) {
port->have_format = false;
@ -316,6 +325,7 @@ spa_volume_node_port_set_format (SpaNode *node,
static SpaResult
spa_volume_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaFormat **format)
{
@ -327,10 +337,10 @@ spa_volume_node_port_get_format (SpaNode *node,
this = (SpaVolume *) node->handle;
if (port_id >= 2)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
@ -342,6 +352,7 @@ spa_volume_node_port_get_format (SpaNode *node,
static SpaResult
spa_volume_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortInfo **info)
{
@ -353,33 +364,36 @@ spa_volume_node_port_get_info (SpaNode *node,
this = (SpaVolume *) node->handle;
if (port_id >= 2)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
*info = &port->info;
return SPA_RESULT_OK;
}
static SpaResult
spa_volume_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
spa_volume_node_port_get_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaProps **props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_volume_node_port_set_props (SpaNode *node,
uint32_t port_id,
const SpaProps *props)
spa_volume_node_port_set_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaProps *props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_volume_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@ -389,6 +403,7 @@ spa_volume_node_port_use_buffers (SpaNode *node,
static SpaResult
spa_volume_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@ -398,16 +413,9 @@ spa_volume_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_volume_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_volume_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortStatus **status)
{
@ -419,10 +427,10 @@ spa_volume_node_port_get_status (SpaNode *node,
this = (SpaVolume *) node->handle;
if (port_id >= 2)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
port = &this->ports[port_id];
port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id];
if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
@ -458,7 +466,7 @@ spa_volume_node_port_push_input (SpaNode *node,
continue;
}
port = &this->ports[info[i].port_id];
port = &this->in_ports[info[i].port_id];
buffer = port->buffers[info[i].buffer_id];
if (buffer == NULL) {
@ -481,8 +489,8 @@ spa_volume_node_port_push_input (SpaNode *node,
}
port->buffer = buffer;
this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[1].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
this->in_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->out_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
}
info[i].status = SPA_RESULT_OK;
}
@ -532,19 +540,19 @@ spa_volume_node_port_pull_output (SpaNode *node,
this = (SpaVolume *) node->handle;
if (info->port_id != 1)
if (info[0].port_id != 0)
return SPA_RESULT_INVALID_PORT;
port = &this->ports[info[0].port_id];
port = &this->out_ports[info[0].port_id];
if (!port->have_format)
return SPA_RESULT_NO_FORMAT;
if (this->ports[0].buffer == NULL)
if (this->in_ports[0].buffer == NULL)
return SPA_RESULT_NEED_MORE_INPUT;
volume = this->props[1].volume;
sbuf = this->ports[0].buffer;
sbuf = this->in_ports[0].buffer;
dbuf = find_free_buffer (this, port);
si = di = 0;
@ -582,17 +590,26 @@ spa_volume_node_port_pull_output (SpaNode *node,
if (sbuf != dbuf)
release_buffer (this, sbuf);
this->ports[0].buffer = NULL;
this->in_ports[0].buffer = NULL;
info->buffer_id = dbuf->id;
this->ports[0].status.flags |= SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[1].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
this->in_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
return SPA_RESULT_OK;
}
static SpaResult
spa_volume_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_volume_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event)
{
@ -620,10 +637,10 @@ static const SpaNode volume_node = {
spa_volume_node_port_set_props,
spa_volume_node_port_use_buffers,
spa_volume_node_port_alloc_buffers,
spa_volume_node_port_reuse_buffer,
spa_volume_node_port_get_status,
spa_volume_node_port_push_input,
spa_volume_node_port_pull_output,
spa_volume_node_port_reuse_buffer,
spa_volume_node_port_push_event,
};
@ -676,14 +693,14 @@ volume_init (const SpaHandleFactory *factory,
this->props[1].props.prop_info = prop_info;
reset_volume_props (&this->props[1]);
this->ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
SPA_PORT_INFO_FLAG_IN_PLACE;
this->ports[1].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS |
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
SPA_PORT_INFO_FLAG_NO_REF;
this->in_ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
SPA_PORT_INFO_FLAG_IN_PLACE;
this->out_ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS |
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
SPA_PORT_INFO_FLAG_NO_REF;
this->ports[0].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[1].status.flags = SPA_PORT_STATUS_FLAG_NONE;
this->in_ports[0].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->out_ports[0].status.flags = SPA_PORT_STATUS_FLAG_NONE;
return SPA_RESULT_OK;
}

View file

@ -86,6 +86,8 @@ struct _SpaXvSink {
};
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
#include "xv-utils.c"
enum {
@ -258,6 +260,7 @@ spa_xv_sink_node_get_port_ids (SpaNode *node,
static SpaResult
spa_xv_sink_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -265,6 +268,7 @@ spa_xv_sink_node_add_port (SpaNode *node,
static SpaResult
spa_xv_sink_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
@ -272,6 +276,7 @@ spa_xv_sink_node_remove_port (SpaNode *node,
static SpaResult
spa_xv_sink_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaFormat **format,
const SpaFormat *filter,
@ -285,7 +290,7 @@ spa_xv_sink_node_port_enum_formats (SpaNode *node,
this = (SpaXvSink *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
index = (*state == NULL ? 0 : *(int*)state);
@ -307,6 +312,7 @@ spa_xv_sink_node_port_enum_formats (SpaNode *node,
static SpaResult
spa_xv_sink_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaPortFormatFlags flags,
const SpaFormat *format)
@ -321,7 +327,7 @@ spa_xv_sink_node_port_set_format (SpaNode *node,
this = (SpaXvSink *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (format == NULL) {
@ -355,6 +361,7 @@ spa_xv_sink_node_port_set_format (SpaNode *node,
static SpaResult
spa_xv_sink_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaFormat **format)
{
@ -365,7 +372,7 @@ spa_xv_sink_node_port_get_format (SpaNode *node,
this = (SpaXvSink *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
if (this->current_format == NULL)
@ -378,6 +385,7 @@ spa_xv_sink_node_port_get_format (SpaNode *node,
static SpaResult
spa_xv_sink_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortInfo **info)
{
@ -388,7 +396,7 @@ spa_xv_sink_node_port_get_info (SpaNode *node,
this = (SpaXvSink *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
*info = &this->info;
@ -397,15 +405,17 @@ spa_xv_sink_node_port_get_info (SpaNode *node,
}
static SpaResult
spa_xv_sink_node_port_get_props (SpaNode *node,
uint32_t port_id,
SpaProps **props)
spa_xv_sink_node_port_get_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaProps **props)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_xv_sink_node_port_set_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaProps *props)
{
@ -414,6 +424,7 @@ spa_xv_sink_node_port_set_props (SpaNode *node,
static SpaResult
spa_xv_sink_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaBuffer **buffers,
uint32_t n_buffers)
@ -423,6 +434,7 @@ spa_xv_sink_node_port_use_buffers (SpaNode *node,
static SpaResult
spa_xv_sink_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaAllocParam **params,
uint32_t n_params,
@ -432,16 +444,9 @@ spa_xv_sink_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_xv_sink_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_xv_sink_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
const SpaPortStatus **status)
{
@ -452,7 +457,7 @@ spa_xv_sink_node_port_get_status (SpaNode *node,
this = (SpaXvSink *) node->handle;
if (port_id != 0)
if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT;
*status = &this->status;
@ -476,8 +481,17 @@ spa_xv_sink_node_port_pull_output (SpaNode *node,
return SPA_RESULT_INVALID_PORT;
}
static SpaResult
spa_xv_sink_node_port_reuse_buffer (SpaNode *node,
uint32_t port_id,
uint32_t buffer_id)
{
return SPA_RESULT_NOT_IMPLEMENTED;
}
static SpaResult
spa_xv_sink_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id,
SpaNodeEvent *event)
{
@ -505,10 +519,10 @@ static const SpaNode xvsink_node = {
spa_xv_sink_node_port_set_props,
spa_xv_sink_node_port_use_buffers,
spa_xv_sink_node_port_alloc_buffers,
spa_xv_sink_node_port_reuse_buffer,
spa_xv_sink_node_port_get_status,
spa_xv_sink_node_port_push_input,
spa_xv_sink_node_port_pull_output,
spa_xv_sink_node_port_reuse_buffer,
spa_xv_sink_node_port_push_event,
};

View file

@ -223,7 +223,7 @@ negotiate_formats (AppData *data)
SpaPropValue value;
void *state = NULL;
if ((res = spa_node_port_enum_formats (data->sink, 0, &format, NULL, &state)) < 0)
if ((res = spa_node_port_enum_formats (data->sink, SPA_DIRECTION_INPUT, 0, &format, NULL, &state)) < 0)
return res;
props = &format->props;
@ -244,30 +244,30 @@ negotiate_formats (AppData *data)
if ((res = spa_props_set_value (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_CHANNELS), &value)) < 0)
return res;
if ((res = spa_node_port_set_format (data->sink, 0, false, format)) < 0)
if ((res = spa_node_port_set_format (data->sink, SPA_DIRECTION_INPUT, 0, false, format)) < 0)
return res;
if ((res = spa_node_port_set_format (data->mix, 128, false, format)) < 0)
if ((res = spa_node_port_set_format (data->mix, SPA_DIRECTION_OUTPUT, 0, false, format)) < 0)
return res;
data->mix_ports[0] = 0;
if ((res = spa_node_add_port (data->mix, 0)) < 0)
if ((res = spa_node_add_port (data->mix, SPA_DIRECTION_INPUT, 0)) < 0)
return res;
if ((res = spa_node_port_set_format (data->mix, data->mix_ports[0], false, format)) < 0)
if ((res = spa_node_port_set_format (data->mix, SPA_DIRECTION_INPUT, data->mix_ports[0], false, format)) < 0)
return res;
if ((res = spa_node_port_set_format (data->source1, 0, false, format)) < 0)
if ((res = spa_node_port_set_format (data->source1, SPA_DIRECTION_OUTPUT, 0, false, format)) < 0)
return res;
data->mix_ports[1] = 1;
if ((res = spa_node_add_port (data->mix, 1)) < 0)
if ((res = spa_node_add_port (data->mix, SPA_DIRECTION_INPUT, 1)) < 0)
return res;
if ((res = spa_node_port_set_format (data->mix, data->mix_ports[1], false, format)) < 0)
if ((res = spa_node_port_set_format (data->mix, SPA_DIRECTION_INPUT, data->mix_ports[1], false, format)) < 0)
return res;
if ((res = spa_node_port_set_format (data->source2, 0, false, format)) < 0)
if ((res = spa_node_port_set_format (data->source2, SPA_DIRECTION_OUTPUT, 0, false, format)) < 0)
return res;

View file

@ -273,7 +273,7 @@ alloc_buffers (AppData *data)
}
data->n_buffers = MAX_BUFFERS;
spa_node_port_use_buffers (data->source, 0, data->bp, MAX_BUFFERS);
spa_node_port_use_buffers (data->source, SPA_DIRECTION_OUTPUT, 0, data->bp, MAX_BUFFERS);
}
typedef struct {
@ -320,10 +320,10 @@ negotiate_formats (AppData *data)
f.framerate.denom = 1;
#endif
if ((res = spa_node_port_set_format (data->source, 0, false, &f.fmt)) < 0)
if ((res = spa_node_port_set_format (data->source, SPA_DIRECTION_OUTPUT, 0, false, &f.fmt)) < 0)
return res;
if ((res = spa_node_port_get_info (data->source, 0, &info)) < 0)
if ((res = spa_node_port_get_info (data->source, SPA_DIRECTION_OUTPUT, 0, &info)) < 0)
return res;
spa_debug_port_info (info);
@ -342,7 +342,7 @@ negotiate_formats (AppData *data)
return -1;
}
n_buffers = MAX_BUFFERS;
if ((res = spa_node_port_alloc_buffers (data->source, 0, NULL, 0, data->bp, &n_buffers)) < 0) {
if ((res = spa_node_port_alloc_buffers (data->source, SPA_DIRECTION_OUTPUT, 0, NULL, 0, data->bp, &n_buffers)) < 0) {
printf ("can't allocate buffers: %s\n", SDL_GetError ());
return -1;
}

View file

@ -26,14 +26,37 @@
#include <spa/node.h>
#include <spa/debug.h>
static void
inspect_port (SpaNode *node, SpaDirection direction, uint32_t port_id)
{
SpaResult res;
SpaFormat *format;
void *state = NULL;
SpaProps *props;
while (true) {
if ((res = spa_node_port_enum_formats (node, direction, port_id, &format, NULL, &state)) < 0) {
if (res != SPA_RESULT_ENUM_END)
printf ("got error %d\n", res);
break;
}
if (format)
spa_debug_format (format);
}
if ((res = spa_node_port_get_props (node, direction, port_id, &props)) < 0)
printf ("port_get_props error: %d\n", res);
else
spa_debug_props (props, true);
}
static void
inspect_node (SpaNode *node)
{
SpaResult res;
unsigned int i, n_input, max_input, n_output, max_output;
uint32_t *in_ports, *out_ports;
SpaProps *props;
unsigned int n_input, max_input, n_output, max_output;
SpaFormat *format;
void *state = NULL;
if ((res = spa_node_get_props (node, &props)) < 0)
printf ("can't get properties: %d\n", res);
@ -45,19 +68,21 @@ inspect_node (SpaNode *node)
else
printf ("supported ports %d %d %d %d\n", n_input, max_input, n_output, max_output);
while (true) {
if ((res = spa_node_port_enum_formats (node, 0, &format, NULL, &state)) < 0) {
if (res != SPA_RESULT_ENUM_END)
printf ("got error %d\n", res);
break;
}
if (format)
spa_debug_format (format);
in_ports = alloca (n_input * sizeof (uint32_t));
out_ports = alloca (n_input * sizeof (uint32_t));
if ((res = spa_node_get_port_ids (node, n_input, in_ports, n_output, out_ports)) < 0)
printf ("can't get port ids: %d\n", res);
for (i = 0; i < n_input; i++) {
printf (" input port: %08x\n", in_ports[i]);
inspect_port (node, SPA_DIRECTION_INPUT, in_ports[i]);
}
if ((res = spa_node_port_get_props (node, 0, &props)) < 0)
printf ("port_get_props error: %d\n", res);
else
spa_debug_props (props, true);
for (i = 0; i < n_output; i++) {
printf (" output port: %08x\n", out_ports[i]);
inspect_port (node, SPA_DIRECTION_OUTPUT, out_ports[i]);
}
}
static void