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 { typedef struct {
uint32_t id; uint32_t id;
bool used; bool used;
void *buf_ptr;
SpaBuffer *buf; SpaBuffer *buf;
SpaData *datas;
} BufferId; } BufferId;
struct _PinosStreamPrivate struct _PinosStreamPrivate
@ -68,13 +70,13 @@ struct _PinosStreamPrivate
PinosStreamState state; PinosStreamState state;
GError *error; GError *error;
PinosDirection direction;
gchar *path; gchar *path;
SpaNodeState node_state; SpaNodeState node_state;
GPtrArray *possible_formats; GPtrArray *possible_formats;
SpaFormat *format; SpaFormat *format;
SpaPortInfo port_info; SpaPortInfo port_info;
SpaDirection direction;
uint32_t port_id; uint32_t port_id;
uint32_t pending_seq; uint32_t pending_seq;
@ -628,9 +630,9 @@ add_node_update (PinosStream *stream, SpaControlBuilder *builder, uint32_t chang
nu.change_mask = change_mask; nu.change_mask = change_mask;
if (change_mask & SPA_CONTROL_CMD_NODE_UPDATE_MAX_INPUTS) 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) 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; nu.props = NULL;
spa_control_builder_add_cmd (builder, SPA_CONTROL_CMD_NODE_UPDATE, &nu); 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; PinosStreamPrivate *priv = stream->priv;
SpaControlCmdPortUpdate pu = { 0, };; SpaControlCmdPortUpdate pu = { 0, };;
pu.direction = priv->direction;
pu.port_id = priv->port_id; pu.port_id = priv->port_id;
pu.change_mask = change_mask; pu.change_mask = change_mask;
if (change_mask & SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS) { 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.format = priv->format;
} }
pu.props = NULL; 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; pu.info = &priv->port_info;
spa_debug_port_info (pu.info);
}
spa_control_builder_add_cmd (builder, SPA_CONTROL_CMD_PORT_UPDATE, &pu); 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; SpaNodeEventHaveOutput ho;
control_builder_init (stream, &builder); control_builder_init (stream, &builder);
pb.direction = priv->direction;
pb.port_id = port_id; pb.port_id = port_id;
pb.buffer_id = buffer_id; pb.buffer_id = buffer_id;
spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_PROCESS_BUFFER, &pb); 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) if (p->port_id != priv->port_id)
break; break;
if (priv->direction != PINOS_DIRECTION_OUTPUT) if (priv->direction != SPA_DIRECTION_OUTPUT)
break; break;
if ((bid = find_buffer (stream, p->buffer_id))) { if ((bid = find_buffer (stream, p->buffer_id))) {
@ -932,7 +938,7 @@ handle_node_command (PinosStream *stream,
g_debug ("stream %p: start", stream); g_debug ("stream %p: start", stream);
control_builder_init (stream, &builder); 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_need_input (stream, &builder, priv->port_id);
add_state_change (stream, &builder, SPA_NODE_STATE_STREAMING); add_state_change (stream, &builder, SPA_NODE_STATE_STREAMING);
add_async_complete (stream, &builder, seq, SPA_RESULT_OK); add_async_complete (stream, &builder, seq, SPA_RESULT_OK);
@ -1072,6 +1078,7 @@ parse_control (PinosStream *stream,
unsigned int i, j; unsigned int i, j;
SpaControlBuilder builder; SpaControlBuilder builder;
SpaControl control; SpaControl control;
SpaBuffer *b;
if (spa_control_iter_parse_cmd (&it, &p) < 0) if (spa_control_iter_parse_cmd (&it, &p) < 0)
break; break;
@ -1095,16 +1102,62 @@ parse_control (PinosStream *stream,
} }
} }
bid.buf = spa_buffer_deserialize (mid->ptr, p.buffers[i].offset); bid.buf_ptr = SPA_MEMBER (mid->ptr, p.buffers[i].offset, void);
bid.id = bid.buf->id; {
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); g_debug ("add buffer %d %d %zd", mid->id, bid.id, p.buffers[i].offset);
for (j = 0; j < bid.buf->n_datas; j++) { for (j = 0; j < b->n_metas; j++) {
SpaData *d = &bid.buf->datas[j]; SpaMeta *m = &b->metas[j];
MemId *bmid = find_mem (stream, SPA_PTR_TO_UINT32 (d->data)); if (m->data)
d->data = SPA_INT_TO_PTR (bmid->fd); m->data = SPA_MEMBER (bid.buf_ptr, SPA_PTR_TO_INT (m->data), void);
g_debug (" data %d %u -> %d", j, bmid->id, bmid->fd); }
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) { if (bid.id != priv->buffer_ids->len) {
@ -1133,16 +1186,23 @@ parse_control (PinosStream *stream,
case SPA_CONTROL_CMD_PROCESS_BUFFER: case SPA_CONTROL_CMD_PROCESS_BUFFER:
{ {
SpaControlCmdProcessBuffer p; SpaControlCmdProcessBuffer p;
guint i;
BufferId *bid;
if (priv->direction != PINOS_DIRECTION_INPUT) if (priv->direction != SPA_DIRECTION_INPUT)
break; break;
if (spa_control_iter_parse_cmd (&it, &p) < 0) if (spa_control_iter_parse_cmd (&it, &p) < 0)
break; 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; break;
} }
case SPA_CONTROL_CMD_NODE_EVENT: 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_context_get_state (context) == PINOS_CONTEXT_STATE_CONNECTED, FALSE);
g_return_val_if_fail (pinos_stream_get_state (stream) == PINOS_STREAM_STATE_UNCONNECTED, FALSE); g_return_val_if_fail (pinos_stream_get_state (stream) == PINOS_STREAM_STATE_UNCONNECTED, FALSE);
priv->direction = direction; priv->direction = direction == PINOS_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
priv->port_id = direction == PINOS_DIRECTION_INPUT ? 0 : MAX_INPUTS; priv->port_id = 0;
priv->mode = mode; priv->mode = mode;
g_free (priv->path); g_free (priv->path);
priv->path = g_strdup (port_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); 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); add_async_complete (stream, &builder, priv->pending_seq, res);
spa_control_builder_end (&builder, &control); 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); g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE);
priv = stream->priv; 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++) { for (i = 0; i < priv->buffer_ids->len; i++) {
BufferId *bid = &g_array_index (priv->buffer_ids, BufferId, 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 (PINOS_IS_STREAM (stream), FALSE);
g_return_val_if_fail (id != SPA_ID_INVALID, FALSE); g_return_val_if_fail (id != SPA_ID_INVALID, FALSE);
priv = stream->priv; 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); send_reuse_buffer (stream, priv->port_id, id);
@ -1783,14 +1846,18 @@ pinos_stream_send_buffer (PinosStream *stream,
{ {
PinosStreamPrivate *priv; PinosStreamPrivate *priv;
BufferId *bid; BufferId *bid;
guint i;
g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE); g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE);
g_return_val_if_fail (id != SPA_ID_INVALID, FALSE); g_return_val_if_fail (id != SPA_ID_INVALID, FALSE);
priv = stream->priv; 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))) { if ((bid = find_buffer (stream, id))) {
bid->used = TRUE; 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); send_process_buffer (stream, priv->port_id, id);
return TRUE; return TRUE;
} else { } else {

View file

@ -333,6 +333,7 @@ gst_pinos_sink_get_property (GObject * object, guint prop_id,
typedef struct { typedef struct {
GstPinosSink *sink; GstPinosSink *sink;
guint id; guint id;
SpaBuffer *buf;
SpaMetaHeader *header; SpaMetaHeader *header;
guint flags; guint flags;
} ProcessMemData; } ProcessMemData;
@ -368,6 +369,7 @@ on_add_buffer (GObject *gobject,
data.sink = gst_object_ref (pinossink); data.sink = gst_object_ref (pinossink);
data.id = id; data.id = id;
data.buf = b;
data.header = NULL; data.header = NULL;
for (i = 0; i < b->n_metas; i++) { for (i = 0; i < b->n_metas; i++) {
@ -591,6 +593,7 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
GstPinosSink *pinossink; GstPinosSink *pinossink;
gboolean res; gboolean res;
ProcessMemData *data; ProcessMemData *data;
guint i;
pinossink = GST_PINOS_SINK (bsink); pinossink = GST_PINOS_SINK (bsink);
@ -599,7 +602,8 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
pinos_main_loop_lock (pinossink->loop); pinos_main_loop_lock (pinossink->loop);
if (pinos_stream_get_state (pinossink->stream) != PINOS_STREAM_STATE_STREAMING) 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)) { if (buffer->pool != GST_BUFFER_POOL_CAST (pinossink->pool)) {
GstBuffer *b = NULL; 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), data = gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buffer),
process_mem_data_quark); 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))) if (!(res = pinos_stream_send_buffer (pinossink->stream, data->id)))
g_warning ("can't send buffer"); g_warning ("can't send buffer");
done:
pinos_main_loop_unlock (pinossink->loop); pinos_main_loop_unlock (pinossink->loop);
return GST_FLOW_OK; return GST_FLOW_OK;
@ -624,11 +641,11 @@ not_negotiated:
{ {
return GST_FLOW_NOT_NEGOTIATED; return GST_FLOW_NOT_NEGOTIATED;
} }
streaming_error: //streaming_error:
{ // {
pinos_main_loop_unlock (pinossink->loop); // pinos_main_loop_unlock (pinossink->loop);
return GST_FLOW_ERROR; // return GST_FLOW_ERROR;
} // }
} }
static gboolean 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); g_debug ("link %p: doing negotiate format", this);
again: again:
if ((res = spa_node_port_enum_formats (this->input->node->node, if ((res = spa_node_port_enum_formats (this->input->node->node,
SPA_DIRECTION_INPUT,
this->input->port, this->input->port,
&filter, &filter,
NULL, NULL,
@ -253,6 +254,7 @@ again:
spa_debug_format (filter); spa_debug_format (filter);
if ((res = spa_node_port_enum_formats (this->output->node->node, if ((res = spa_node_port_enum_formats (this->output->node->node,
SPA_DIRECTION_OUTPUT,
this->output->port, this->output->port,
&format, &format,
filter, filter,
@ -273,6 +275,7 @@ again:
} else if (in_state == SPA_NODE_STATE_CONFIGURE && out_state > SPA_NODE_STATE_CONFIGURE) { } else if (in_state == SPA_NODE_STATE_CONFIGURE && out_state > SPA_NODE_STATE_CONFIGURE) {
/* only input needs format */ /* only input needs format */
if ((res = spa_node_port_get_format (this->output->node->node, if ((res = spa_node_port_get_format (this->output->node->node,
SPA_DIRECTION_OUTPUT,
this->output->port, this->output->port,
(const SpaFormat **)&format)) < 0) { (const SpaFormat **)&format)) < 0) {
g_set_error (&error, g_set_error (&error,
@ -284,6 +287,7 @@ again:
} else if (out_state == SPA_NODE_STATE_CONFIGURE && in_state > SPA_NODE_STATE_CONFIGURE) { } else if (out_state == SPA_NODE_STATE_CONFIGURE && in_state > SPA_NODE_STATE_CONFIGURE) {
/* only output needs format */ /* only output needs format */
if ((res = spa_node_port_get_format (this->input->node->node, if ((res = spa_node_port_get_format (this->input->node->node,
SPA_DIRECTION_INPUT,
this->input->port, this->input->port,
(const SpaFormat **)&format)) < 0) { (const SpaFormat **)&format)) < 0) {
g_set_error (&error, g_set_error (&error,
@ -301,6 +305,7 @@ again:
if (out_state == SPA_NODE_STATE_CONFIGURE) { if (out_state == SPA_NODE_STATE_CONFIGURE) {
g_debug ("link %p: doing set format on output", this); g_debug ("link %p: doing set format on output", this);
if ((res = spa_node_port_set_format (this->output->node->node, if ((res = spa_node_port_set_format (this->output->node->node,
SPA_DIRECTION_OUTPUT,
this->output->port, this->output->port,
SPA_PORT_FORMAT_FLAG_NEAREST, SPA_PORT_FORMAT_FLAG_NEAREST,
format)) < 0) { format)) < 0) {
@ -313,6 +318,7 @@ again:
} else if (in_state == SPA_NODE_STATE_CONFIGURE) { } else if (in_state == SPA_NODE_STATE_CONFIGURE) {
g_debug ("link %p: doing set format on input", this); g_debug ("link %p: doing set format on input", this);
if ((res = spa_node_port_set_format (this->input->node->node, if ((res = spa_node_port_set_format (this->input->node->node,
SPA_DIRECTION_INPUT,
this->input->port, this->input->port,
SPA_PORT_FORMAT_FLAG_NEAREST, SPA_PORT_FORMAT_FLAG_NEAREST,
format)) < 0) { 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); g_debug ("link %p: doing alloc buffers %p %p", this, this->output->node, this->input->node);
/* find out what's possible */ /* 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, g_set_error (&error,
PINOS_ERROR, PINOS_ERROR,
PINOS_ERROR_BUFFER_ALLOCATION, PINOS_ERROR_BUFFER_ALLOCATION,
"error get output port info: %d", res); "error get output port info: %d", res);
goto error; 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, g_set_error (&error,
PINOS_ERROR, PINOS_ERROR,
PINOS_ERROR_BUFFER_ALLOCATION, PINOS_ERROR_BUFFER_ALLOCATION,
@ -421,16 +433,20 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
if (priv->buffers == NULL) { if (priv->buffers == NULL) {
SpaAllocParamBuffers *in_alloc, *out_alloc; SpaAllocParamBuffers *in_alloc, *out_alloc;
guint max_buffers = MAX_BUFFERS; guint max_buffers = MAX_BUFFERS, min_size = 4096;
gboolean alloc_data = TRUE; gboolean alloc_data = TRUE;
max_buffers = MAX_BUFFERS; max_buffers = MAX_BUFFERS;
in_alloc = find_param (iinfo, SPA_ALLOC_PARAM_TYPE_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); 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); 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); 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) || if ((in_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) ||
(out_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); g_debug ("reusing %d output buffers %p", priv->n_buffers, priv->buffers);
} else { } else {
guint i; guint i;
size_t hdr_size; size_t hdr_size, data_size, buf_size;
void *p; void *p;
spa_alloc_params_get_header_size (oinfo->params, oinfo->n_params, 1, &hdr_size); 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; priv->n_buffers = max_buffers;
pinos_memblock_alloc (PINOS_MEMBLOCK_FLAG_WITH_FD | pinos_memblock_alloc (PINOS_MEMBLOCK_FLAG_WITH_FD |
PINOS_MEMBLOCK_FLAG_MAP_READWRITE | PINOS_MEMBLOCK_FLAG_MAP_READWRITE |
PINOS_MEMBLOCK_FLAG_SEAL, PINOS_MEMBLOCK_FLAG_SEAL,
priv->n_buffers * (sizeof (SpaBuffer*) + hdr_size), priv->n_buffers * (sizeof (SpaBuffer*) + buf_size),
&priv->buffer_mem); &priv->buffer_mem);
priv->buffers = p = priv->buffer_mem.ptr; priv->buffers = p = priv->buffer_mem.ptr;
p = SPA_MEMBER (p, priv->n_buffers * sizeof (SpaBuffer*), void); p = SPA_MEMBER (p, priv->n_buffers * sizeof (SpaBuffer*), void);
for (i = 0; i < priv->n_buffers; i++) 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, if ((res = spa_buffer_init_headers (oinfo->params,
oinfo->n_params, oinfo->n_params,
@ -474,12 +496,25 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
"error buffer alloc: %d", res); "error buffer alloc: %d", res);
goto error; 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); g_debug ("allocated %d buffers %p", priv->n_buffers, priv->buffers);
priv->allocated = TRUE; priv->allocated = TRUE;
} }
if (in_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) { 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, oinfo->params, oinfo->n_params,
priv->buffers, &priv->n_buffers)) < 0) { priv->buffers, &priv->n_buffers)) < 0) {
g_set_error (&error, 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); 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) { 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, iinfo->params, iinfo->n_params,
priv->buffers, &priv->n_buffers)) < 0) { priv->buffers, &priv->n_buffers)) < 0) {
g_set_error (&error, 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) { if (in_flags & SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS) {
g_debug ("using %d buffers %p on input port", priv->n_buffers, priv->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, if ((res = spa_node_port_use_buffers (this->input->node->node,
priv->buffers, priv->n_buffers)) < 0) { SPA_DIRECTION_INPUT,
this->input->port,
priv->buffers,
priv->n_buffers)) < 0) {
g_set_error (&error, g_set_error (&error,
PINOS_ERROR, PINOS_ERROR,
PINOS_ERROR_BUFFER_ALLOCATION, 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) { 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); 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, if ((res = spa_node_port_use_buffers (this->output->node->node,
priv->buffers, priv->n_buffers)) < 0) { SPA_DIRECTION_OUTPUT,
this->output->port,
priv->buffers,
priv->n_buffers)) < 0) {
g_set_error (&error, g_set_error (&error,
PINOS_ERROR, PINOS_ERROR,
PINOS_ERROR_BUFFER_ALLOCATION, 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)) { for (walk = priv->input_ports; walk; walk = g_list_next (walk)) {
NodePort *p = walk->data; 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); g_warning ("error unset format output: %d", res);
p->port.buffers = NULL; p->port.buffers = NULL;
p->port.n_buffers = 0; p->port.n_buffers = 0;
@ -291,7 +291,7 @@ suspend_node (PinosNode *this)
} }
for (walk = priv->output_ports; walk; walk = g_list_next (walk)) { for (walk = priv->output_ports; walk; walk = g_list_next (walk)) {
NodePort *p = walk->data; 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); g_warning ("error unset format output: %d", res);
p->port.buffers = NULL; p->port.buffers = NULL;
p->port.n_buffers = 0; p->port.n_buffers = 0;
@ -1132,15 +1132,14 @@ pinos_node_get_free_port (PinosNode *node,
max_ports = priv->max_input_ports; max_ports = priv->max_input_ports;
n_ports = priv->n_input_ports; n_ports = priv->n_input_ports;
ports = priv->input_ports; ports = priv->input_ports;
free_port = 0;
} else { } else {
max_ports = priv->max_output_ports; max_ports = priv->max_output_ports;
n_ports = priv->n_output_ports; n_ports = priv->n_output_ports;
ports = priv->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)) { for (walk = ports; walk; walk = g_list_next (walk)) {
PinosPort *p = walk->data; PinosPort *p = walk->data;

View file

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

View file

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

View file

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

View file

@ -115,6 +115,13 @@ typedef struct {
const char **features; const char **features;
} SpaPortInfo; } 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: * SpaPortStatusFlags:
* @SPA_PORT_STATUS_FLAG_NONE: no status flags * @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) if (pu->format)
pu->format = spa_format_deserialize (p, SPA_PTR_TO_INT (pu->format)); pu->format = spa_format_deserialize (p, SPA_PTR_TO_INT (pu->format));
if (pu->props) if (pu->props)
pu->props = spa_props_deserialize (p, SPA_PTR_TO_INT (pu->props)); pu->props = spa_props_deserialize (p, SPA_PTR_TO_INT (pu->props));
if (pu->info) { if (pu->info)
SpaPortInfo *pi; pu->info = spa_port_info_deserialize (p, SPA_PTR_TO_INT (pu->info));
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);
}
}
} }
static void static void
@ -759,39 +749,6 @@ builder_add_cmd (struct stack_builder *sb, SpaControlCmd cmd, size_t size)
return p; 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 static void
builder_add_node_update (struct stack_builder *sb, SpaControlCmdNodeUpdate *nu) 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_format_get_size (pu->format);
len += spa_props_get_size (pu->props); len += spa_props_get_size (pu->props);
if (pu->info) { if (pu->info)
len += sizeof (SpaPortInfo); len += spa_port_info_get_size (pu->info);
len += pu->info->n_params * sizeof (SpaAllocParam *);
for (i = 0; i < pu->info->n_params; i++)
len += pu->info->params[i]->size;
}
p = builder_add_cmd (sb, SPA_CONTROL_CMD_PORT_UPDATE, len); p = builder_add_cmd (sb, SPA_CONTROL_CMD_PORT_UPDATE, len);
memcpy (p, pu, sizeof (SpaControlCmdPortUpdate)); memcpy (p, pu, sizeof (SpaControlCmdPortUpdate));
@ -873,7 +826,7 @@ builder_add_port_update (struct stack_builder *sb, SpaControlCmdPortUpdate *pu)
d->props = 0; d->props = 0;
} }
if (pu->info) { 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)); d->info = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d));
p = SPA_MEMBER (p, len, void); p = SPA_MEMBER (p, len, void);
} else { } else {

View file

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

View file

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

View file

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

View file

@ -93,6 +93,8 @@ struct _SpaAudioTestSrc {
SpaQueue ready; SpaQueue ready;
}; };
#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0)
#define DEFAULT_WAVE 0 #define DEFAULT_WAVE 0
#define DEFAULT_VOLUME 1.0 #define DEFAULT_VOLUME 1.0
#define DEFAULT_FREQ 440.0 #define DEFAULT_FREQ 440.0
@ -470,6 +472,7 @@ spa_audiotestsrc_node_get_port_ids (SpaNode *node,
static SpaResult static SpaResult
spa_audiotestsrc_node_add_port (SpaNode *node, spa_audiotestsrc_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id) uint32_t port_id)
{ {
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
@ -477,6 +480,7 @@ spa_audiotestsrc_node_add_port (SpaNode *node,
static SpaResult static SpaResult
spa_audiotestsrc_node_remove_port (SpaNode *node, spa_audiotestsrc_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id) uint32_t port_id)
{ {
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
@ -484,6 +488,7 @@ spa_audiotestsrc_node_remove_port (SpaNode *node,
static SpaResult static SpaResult
spa_audiotestsrc_node_port_enum_formats (SpaNode *node, spa_audiotestsrc_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaFormat **format, SpaFormat **format,
const SpaFormat *filter, const SpaFormat *filter,
@ -497,7 +502,7 @@ spa_audiotestsrc_node_port_enum_formats (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle; this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
index = (*state == NULL ? 0 : *(int*)state); index = (*state == NULL ? 0 : *(int*)state);
@ -535,6 +540,7 @@ clear_buffers (SpaAudioTestSrc *this)
static SpaResult static SpaResult
spa_audiotestsrc_node_port_set_format (SpaNode *node, spa_audiotestsrc_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaPortFormatFlags flags, SpaPortFormatFlags flags,
const SpaFormat *format) const SpaFormat *format)
@ -547,7 +553,7 @@ spa_audiotestsrc_node_port_set_format (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle; this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
if (format == NULL) { if (format == NULL) {
@ -590,6 +596,7 @@ spa_audiotestsrc_node_port_set_format (SpaNode *node,
static SpaResult static SpaResult
spa_audiotestsrc_node_port_get_format (SpaNode *node, spa_audiotestsrc_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaFormat **format) const SpaFormat **format)
{ {
@ -600,7 +607,7 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle; this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
if (!this->have_format) if (!this->have_format)
@ -613,6 +620,7 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node,
static SpaResult static SpaResult
spa_audiotestsrc_node_port_get_info (SpaNode *node, spa_audiotestsrc_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaPortInfo **info) const SpaPortInfo **info)
{ {
@ -623,7 +631,7 @@ spa_audiotestsrc_node_port_get_info (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle; this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
*info = &this->info; *info = &this->info;
@ -632,15 +640,17 @@ spa_audiotestsrc_node_port_get_info (SpaNode *node,
} }
static SpaResult static SpaResult
spa_audiotestsrc_node_port_get_props (SpaNode *node, spa_audiotestsrc_node_port_get_props (SpaNode *node,
uint32_t port_id, SpaDirection direction,
SpaProps **props) uint32_t port_id,
SpaProps **props)
{ {
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
} }
static SpaResult static SpaResult
spa_audiotestsrc_node_port_set_props (SpaNode *node, spa_audiotestsrc_node_port_set_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaProps *props) const SpaProps *props)
{ {
@ -649,6 +659,7 @@ spa_audiotestsrc_node_port_set_props (SpaNode *node,
static SpaResult static SpaResult
spa_audiotestsrc_node_port_use_buffers (SpaNode *node, spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaBuffer **buffers, SpaBuffer **buffers,
uint32_t n_buffers) uint32_t n_buffers)
@ -660,7 +671,7 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle; this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
if (!this->have_format) if (!this->have_format)
@ -716,6 +727,7 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode *node,
static SpaResult static SpaResult
spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node, spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaAllocParam **params, SpaAllocParam **params,
uint32_t n_params, uint32_t n_params,
@ -729,7 +741,7 @@ spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle; this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
if (!this->have_format) if (!this->have_format)
@ -741,44 +753,9 @@ spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED; 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 static SpaResult
spa_audiotestsrc_node_port_get_status (SpaNode *node, spa_audiotestsrc_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaPortStatus **status) const SpaPortStatus **status)
{ {
@ -789,7 +766,7 @@ spa_audiotestsrc_node_port_get_status (SpaNode *node,
this = (SpaAudioTestSrc *) node->handle; this = (SpaAudioTestSrc *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
if (!this->have_format) if (!this->have_format)
@ -808,6 +785,7 @@ spa_audiotestsrc_node_port_push_input (SpaNode *node,
{ {
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
} }
static SpaResult static SpaResult
spa_audiotestsrc_node_port_pull_output (SpaNode *node, spa_audiotestsrc_node_port_pull_output (SpaNode *node,
unsigned int n_info, unsigned int n_info,
@ -854,8 +832,45 @@ spa_audiotestsrc_node_port_pull_output (SpaNode *node,
return SPA_RESULT_OK; 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 static SpaResult
spa_audiotestsrc_node_port_push_event (SpaNode *node, spa_audiotestsrc_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaNodeEvent *event) SpaNodeEvent *event)
{ {
@ -883,10 +898,10 @@ static const SpaNode audiotestsrc_node = {
spa_audiotestsrc_node_port_set_props, spa_audiotestsrc_node_port_set_props,
spa_audiotestsrc_node_port_use_buffers, spa_audiotestsrc_node_port_use_buffers,
spa_audiotestsrc_node_port_alloc_buffers, spa_audiotestsrc_node_port_alloc_buffers,
spa_audiotestsrc_node_port_reuse_buffer,
spa_audiotestsrc_node_port_get_status, spa_audiotestsrc_node_port_get_status,
spa_audiotestsrc_node_port_push_input, spa_audiotestsrc_node_port_push_input,
spa_audiotestsrc_node_port_pull_output, spa_audiotestsrc_node_port_pull_output,
spa_audiotestsrc_node_port_reuse_buffer,
spa_audiotestsrc_node_port_push_event, 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; 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 static SpaResult
spa_ffmpeg_dec_node_port_get_status (SpaNode *node, spa_ffmpeg_dec_node_port_get_status (SpaNode *node,
uint32_t port_id, uint32_t port_id,
@ -478,6 +464,20 @@ spa_ffmpeg_dec_node_port_pull_output (SpaNode *node,
return SPA_RESULT_OK; 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 static SpaResult
spa_ffmpeg_dec_node_port_push_event (SpaNode *node, spa_ffmpeg_dec_node_port_push_event (SpaNode *node,
uint32_t port_id, 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_set_props,
spa_ffmpeg_dec_node_port_use_buffers, spa_ffmpeg_dec_node_port_use_buffers,
spa_ffmpeg_dec_node_port_alloc_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_get_status,
spa_ffmpeg_dec_node_port_push_input, spa_ffmpeg_dec_node_port_push_input,
spa_ffmpeg_dec_node_port_pull_output, spa_ffmpeg_dec_node_port_pull_output,
spa_ffmpeg_dec_node_port_reuse_buffer,
spa_ffmpeg_dec_node_port_push_event, 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; 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 static SpaResult
spa_ffmpeg_enc_node_port_get_status (SpaNode *node, spa_ffmpeg_enc_node_port_get_status (SpaNode *node,
uint32_t port_id, uint32_t port_id,
@ -482,6 +468,20 @@ spa_ffmpeg_enc_node_port_pull_output (SpaNode *node,
return SPA_RESULT_OK; 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 static SpaResult
spa_ffmpeg_enc_node_port_push_event (SpaNode *node, spa_ffmpeg_enc_node_port_push_event (SpaNode *node,
uint32_t port_id, 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_set_props,
spa_ffmpeg_enc_node_port_use_buffers, spa_ffmpeg_enc_node_port_use_buffers,
spa_ffmpeg_enc_node_port_alloc_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_get_status,
spa_ffmpeg_enc_node_port_push_input, spa_ffmpeg_enc_node_port_push_input,
spa_ffmpeg_enc_node_port_pull_output, spa_ffmpeg_enc_node_port_pull_output,
spa_ffmpeg_enc_node_port_reuse_buffer,
spa_ffmpeg_enc_node_port_push_event, spa_ffmpeg_enc_node_port_push_event,
}; };

View file

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

View file

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

View file

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

View file

@ -53,9 +53,14 @@ struct _SpaVolume {
SpaFormatAudio query_format; SpaFormatAudio query_format;
SpaFormatAudio current_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 default_volume = 1.0;
static const double min_volume = 0.0; static const double min_volume = 0.0;
static const double max_volume = 10.0; static const double max_volume = 10.0;
@ -103,7 +108,7 @@ update_state (SpaVolume *this, SpaNodeState state)
static SpaResult static SpaResult
spa_volume_node_get_props (SpaNode *node, spa_volume_node_get_props (SpaNode *node,
SpaProps **props) SpaProps **props)
{ {
SpaVolume *this; SpaVolume *this;
@ -120,7 +125,7 @@ spa_volume_node_get_props (SpaNode *node,
static SpaResult static SpaResult
spa_volume_node_set_props (SpaNode *node, spa_volume_node_set_props (SpaNode *node,
const SpaProps *props) const SpaProps *props)
{ {
SpaVolume *this; SpaVolume *this;
SpaVolumeProps *p; SpaVolumeProps *p;
@ -203,10 +208,10 @@ spa_volume_node_get_n_ports (SpaNode *node,
if (n_input_ports) if (n_input_ports)
*n_input_ports = 1; *n_input_ports = 1;
if (n_output_ports)
*n_output_ports = 1;
if (max_input_ports) if (max_input_ports)
*max_input_ports = 1; *max_input_ports = 1;
if (n_output_ports)
*n_output_ports = 1;
if (max_output_ports) if (max_output_ports)
*max_output_ports = 1; *max_output_ports = 1;
@ -226,7 +231,7 @@ spa_volume_node_get_port_ids (SpaNode *node,
if (n_input_ports > 0 && input_ids) if (n_input_ports > 0 && input_ids)
input_ids[0] = 0; input_ids[0] = 0;
if (n_output_ports > 0 && output_ids) if (n_output_ports > 0 && output_ids)
output_ids[0] = 1; output_ids[0] = 0;
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }
@ -234,6 +239,7 @@ spa_volume_node_get_port_ids (SpaNode *node,
static SpaResult static SpaResult
spa_volume_node_add_port (SpaNode *node, spa_volume_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id) uint32_t port_id)
{ {
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
@ -241,6 +247,7 @@ spa_volume_node_add_port (SpaNode *node,
static SpaResult static SpaResult
spa_volume_node_remove_port (SpaNode *node, spa_volume_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id) uint32_t port_id)
{ {
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
@ -248,6 +255,7 @@ spa_volume_node_remove_port (SpaNode *node,
static SpaResult static SpaResult
spa_volume_node_port_enum_formats (SpaNode *node, spa_volume_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaFormat **format, SpaFormat **format,
const SpaFormat *filter, const SpaFormat *filter,
@ -261,7 +269,7 @@ spa_volume_node_port_enum_formats (SpaNode *node,
this = (SpaVolume *) node->handle; this = (SpaVolume *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
index = (*state == NULL ? 0 : *(int*)state); index = (*state == NULL ? 0 : *(int*)state);
@ -283,6 +291,7 @@ spa_volume_node_port_enum_formats (SpaNode *node,
static SpaResult static SpaResult
spa_volume_node_port_set_format (SpaNode *node, spa_volume_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaPortFormatFlags flags, SpaPortFormatFlags flags,
const SpaFormat *format) const SpaFormat *format)
@ -296,10 +305,10 @@ spa_volume_node_port_set_format (SpaNode *node,
this = (SpaVolume *) node->handle; this = (SpaVolume *) node->handle;
if (port_id >= 2) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; 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) { if (format == NULL) {
port->have_format = false; port->have_format = false;
@ -316,6 +325,7 @@ spa_volume_node_port_set_format (SpaNode *node,
static SpaResult static SpaResult
spa_volume_node_port_get_format (SpaNode *node, spa_volume_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaFormat **format) const SpaFormat **format)
{ {
@ -327,10 +337,10 @@ spa_volume_node_port_get_format (SpaNode *node,
this = (SpaVolume *) node->handle; this = (SpaVolume *) node->handle;
if (port_id >= 2) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; 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) if (!port->have_format)
return SPA_RESULT_NO_FORMAT; return SPA_RESULT_NO_FORMAT;
@ -342,6 +352,7 @@ spa_volume_node_port_get_format (SpaNode *node,
static SpaResult static SpaResult
spa_volume_node_port_get_info (SpaNode *node, spa_volume_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaPortInfo **info) const SpaPortInfo **info)
{ {
@ -353,33 +364,36 @@ spa_volume_node_port_get_info (SpaNode *node,
this = (SpaVolume *) node->handle; this = (SpaVolume *) node->handle;
if (port_id >= 2) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; 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; return SPA_RESULT_OK;
} }
static SpaResult static SpaResult
spa_volume_node_port_get_props (SpaNode *node, spa_volume_node_port_get_props (SpaNode *node,
uint32_t port_id, SpaDirection direction,
SpaProps **props) uint32_t port_id,
SpaProps **props)
{ {
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
} }
static SpaResult static SpaResult
spa_volume_node_port_set_props (SpaNode *node, spa_volume_node_port_set_props (SpaNode *node,
uint32_t port_id, SpaDirection direction,
const SpaProps *props) uint32_t port_id,
const SpaProps *props)
{ {
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
} }
static SpaResult static SpaResult
spa_volume_node_port_use_buffers (SpaNode *node, spa_volume_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaBuffer **buffers, SpaBuffer **buffers,
uint32_t n_buffers) uint32_t n_buffers)
@ -389,6 +403,7 @@ spa_volume_node_port_use_buffers (SpaNode *node,
static SpaResult static SpaResult
spa_volume_node_port_alloc_buffers (SpaNode *node, spa_volume_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaAllocParam **params, SpaAllocParam **params,
uint32_t n_params, uint32_t n_params,
@ -398,16 +413,9 @@ spa_volume_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED; 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 static SpaResult
spa_volume_node_port_get_status (SpaNode *node, spa_volume_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaPortStatus **status) const SpaPortStatus **status)
{ {
@ -419,10 +427,10 @@ spa_volume_node_port_get_status (SpaNode *node,
this = (SpaVolume *) node->handle; this = (SpaVolume *) node->handle;
if (port_id >= 2) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; 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) if (!port->have_format)
return SPA_RESULT_NO_FORMAT; return SPA_RESULT_NO_FORMAT;
@ -458,7 +466,7 @@ spa_volume_node_port_push_input (SpaNode *node,
continue; continue;
} }
port = &this->ports[info[i].port_id]; port = &this->in_ports[info[i].port_id];
buffer = port->buffers[info[i].buffer_id]; buffer = port->buffers[info[i].buffer_id];
if (buffer == NULL) { if (buffer == NULL) {
@ -481,8 +489,8 @@ spa_volume_node_port_push_input (SpaNode *node,
} }
port->buffer = buffer; port->buffer = buffer;
this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_NEED_INPUT; this->in_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[1].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; info[i].status = SPA_RESULT_OK;
} }
@ -532,19 +540,19 @@ spa_volume_node_port_pull_output (SpaNode *node,
this = (SpaVolume *) node->handle; this = (SpaVolume *) node->handle;
if (info->port_id != 1) if (info[0].port_id != 0)
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
port = &this->ports[info[0].port_id]; port = &this->out_ports[info[0].port_id];
if (!port->have_format) if (!port->have_format)
return SPA_RESULT_NO_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; return SPA_RESULT_NEED_MORE_INPUT;
volume = this->props[1].volume; volume = this->props[1].volume;
sbuf = this->ports[0].buffer; sbuf = this->in_ports[0].buffer;
dbuf = find_free_buffer (this, port); dbuf = find_free_buffer (this, port);
si = di = 0; si = di = 0;
@ -582,17 +590,26 @@ spa_volume_node_port_pull_output (SpaNode *node,
if (sbuf != dbuf) if (sbuf != dbuf)
release_buffer (this, sbuf); release_buffer (this, sbuf);
this->ports[0].buffer = NULL; this->in_ports[0].buffer = NULL;
info->buffer_id = dbuf->id; info->buffer_id = dbuf->id;
this->ports[0].status.flags |= SPA_PORT_STATUS_FLAG_NEED_INPUT; this->in_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[1].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT;
return SPA_RESULT_OK; 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 static SpaResult
spa_volume_node_port_push_event (SpaNode *node, spa_volume_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaNodeEvent *event) SpaNodeEvent *event)
{ {
@ -620,10 +637,10 @@ static const SpaNode volume_node = {
spa_volume_node_port_set_props, spa_volume_node_port_set_props,
spa_volume_node_port_use_buffers, spa_volume_node_port_use_buffers,
spa_volume_node_port_alloc_buffers, spa_volume_node_port_alloc_buffers,
spa_volume_node_port_reuse_buffer,
spa_volume_node_port_get_status, spa_volume_node_port_get_status,
spa_volume_node_port_push_input, spa_volume_node_port_push_input,
spa_volume_node_port_pull_output, spa_volume_node_port_pull_output,
spa_volume_node_port_reuse_buffer,
spa_volume_node_port_push_event, spa_volume_node_port_push_event,
}; };
@ -676,14 +693,14 @@ volume_init (const SpaHandleFactory *factory,
this->props[1].props.prop_info = prop_info; this->props[1].props.prop_info = prop_info;
reset_volume_props (&this->props[1]); reset_volume_props (&this->props[1]);
this->ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | this->in_ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
SPA_PORT_INFO_FLAG_IN_PLACE; SPA_PORT_INFO_FLAG_IN_PLACE;
this->ports[1].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS | this->out_ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS |
SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS |
SPA_PORT_INFO_FLAG_NO_REF; SPA_PORT_INFO_FLAG_NO_REF;
this->ports[0].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT; this->in_ports[0].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT;
this->ports[1].status.flags = SPA_PORT_STATUS_FLAG_NONE; this->out_ports[0].status.flags = SPA_PORT_STATUS_FLAG_NONE;
return SPA_RESULT_OK; 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" #include "xv-utils.c"
enum { enum {
@ -258,6 +260,7 @@ spa_xv_sink_node_get_port_ids (SpaNode *node,
static SpaResult static SpaResult
spa_xv_sink_node_add_port (SpaNode *node, spa_xv_sink_node_add_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id) uint32_t port_id)
{ {
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
@ -265,6 +268,7 @@ spa_xv_sink_node_add_port (SpaNode *node,
static SpaResult static SpaResult
spa_xv_sink_node_remove_port (SpaNode *node, spa_xv_sink_node_remove_port (SpaNode *node,
SpaDirection direction,
uint32_t port_id) uint32_t port_id)
{ {
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
@ -272,6 +276,7 @@ spa_xv_sink_node_remove_port (SpaNode *node,
static SpaResult static SpaResult
spa_xv_sink_node_port_enum_formats (SpaNode *node, spa_xv_sink_node_port_enum_formats (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaFormat **format, SpaFormat **format,
const SpaFormat *filter, const SpaFormat *filter,
@ -285,7 +290,7 @@ spa_xv_sink_node_port_enum_formats (SpaNode *node,
this = (SpaXvSink *) node->handle; this = (SpaXvSink *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
index = (*state == NULL ? 0 : *(int*)state); index = (*state == NULL ? 0 : *(int*)state);
@ -307,6 +312,7 @@ spa_xv_sink_node_port_enum_formats (SpaNode *node,
static SpaResult static SpaResult
spa_xv_sink_node_port_set_format (SpaNode *node, spa_xv_sink_node_port_set_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaPortFormatFlags flags, SpaPortFormatFlags flags,
const SpaFormat *format) const SpaFormat *format)
@ -321,7 +327,7 @@ spa_xv_sink_node_port_set_format (SpaNode *node,
this = (SpaXvSink *) node->handle; this = (SpaXvSink *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
if (format == NULL) { if (format == NULL) {
@ -355,6 +361,7 @@ spa_xv_sink_node_port_set_format (SpaNode *node,
static SpaResult static SpaResult
spa_xv_sink_node_port_get_format (SpaNode *node, spa_xv_sink_node_port_get_format (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaFormat **format) const SpaFormat **format)
{ {
@ -365,7 +372,7 @@ spa_xv_sink_node_port_get_format (SpaNode *node,
this = (SpaXvSink *) node->handle; this = (SpaXvSink *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
if (this->current_format == NULL) if (this->current_format == NULL)
@ -378,6 +385,7 @@ spa_xv_sink_node_port_get_format (SpaNode *node,
static SpaResult static SpaResult
spa_xv_sink_node_port_get_info (SpaNode *node, spa_xv_sink_node_port_get_info (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaPortInfo **info) const SpaPortInfo **info)
{ {
@ -388,7 +396,7 @@ spa_xv_sink_node_port_get_info (SpaNode *node,
this = (SpaXvSink *) node->handle; this = (SpaXvSink *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
*info = &this->info; *info = &this->info;
@ -397,15 +405,17 @@ spa_xv_sink_node_port_get_info (SpaNode *node,
} }
static SpaResult static SpaResult
spa_xv_sink_node_port_get_props (SpaNode *node, spa_xv_sink_node_port_get_props (SpaNode *node,
uint32_t port_id, SpaDirection direction,
SpaProps **props) uint32_t port_id,
SpaProps **props)
{ {
return SPA_RESULT_NOT_IMPLEMENTED; return SPA_RESULT_NOT_IMPLEMENTED;
} }
static SpaResult static SpaResult
spa_xv_sink_node_port_set_props (SpaNode *node, spa_xv_sink_node_port_set_props (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaProps *props) const SpaProps *props)
{ {
@ -414,6 +424,7 @@ spa_xv_sink_node_port_set_props (SpaNode *node,
static SpaResult static SpaResult
spa_xv_sink_node_port_use_buffers (SpaNode *node, spa_xv_sink_node_port_use_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaBuffer **buffers, SpaBuffer **buffers,
uint32_t n_buffers) uint32_t n_buffers)
@ -423,6 +434,7 @@ spa_xv_sink_node_port_use_buffers (SpaNode *node,
static SpaResult static SpaResult
spa_xv_sink_node_port_alloc_buffers (SpaNode *node, spa_xv_sink_node_port_alloc_buffers (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaAllocParam **params, SpaAllocParam **params,
uint32_t n_params, uint32_t n_params,
@ -432,16 +444,9 @@ spa_xv_sink_node_port_alloc_buffers (SpaNode *node,
return SPA_RESULT_NOT_IMPLEMENTED; 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 static SpaResult
spa_xv_sink_node_port_get_status (SpaNode *node, spa_xv_sink_node_port_get_status (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
const SpaPortStatus **status) const SpaPortStatus **status)
{ {
@ -452,7 +457,7 @@ spa_xv_sink_node_port_get_status (SpaNode *node,
this = (SpaXvSink *) node->handle; this = (SpaXvSink *) node->handle;
if (port_id != 0) if (!CHECK_PORT (this, direction, port_id))
return SPA_RESULT_INVALID_PORT; return SPA_RESULT_INVALID_PORT;
*status = &this->status; *status = &this->status;
@ -476,8 +481,17 @@ spa_xv_sink_node_port_pull_output (SpaNode *node,
return SPA_RESULT_INVALID_PORT; 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 static SpaResult
spa_xv_sink_node_port_push_event (SpaNode *node, spa_xv_sink_node_port_push_event (SpaNode *node,
SpaDirection direction,
uint32_t port_id, uint32_t port_id,
SpaNodeEvent *event) SpaNodeEvent *event)
{ {
@ -505,10 +519,10 @@ static const SpaNode xvsink_node = {
spa_xv_sink_node_port_set_props, spa_xv_sink_node_port_set_props,
spa_xv_sink_node_port_use_buffers, spa_xv_sink_node_port_use_buffers,
spa_xv_sink_node_port_alloc_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_get_status,
spa_xv_sink_node_port_push_input, spa_xv_sink_node_port_push_input,
spa_xv_sink_node_port_pull_output, spa_xv_sink_node_port_pull_output,
spa_xv_sink_node_port_reuse_buffer,
spa_xv_sink_node_port_push_event, spa_xv_sink_node_port_push_event,
}; };

View file

@ -223,7 +223,7 @@ negotiate_formats (AppData *data)
SpaPropValue value; SpaPropValue value;
void *state = NULL; 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; return res;
props = &format->props; 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) if ((res = spa_props_set_value (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_CHANNELS), &value)) < 0)
return res; 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; 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; return res;
data->mix_ports[0] = 0; 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; 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; 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; return res;
data->mix_ports[1] = 1; 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; 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; 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; return res;

View file

@ -273,7 +273,7 @@ alloc_buffers (AppData *data)
} }
data->n_buffers = MAX_BUFFERS; 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 { typedef struct {
@ -320,10 +320,10 @@ negotiate_formats (AppData *data)
f.framerate.denom = 1; f.framerate.denom = 1;
#endif #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; 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; return res;
spa_debug_port_info (info); spa_debug_port_info (info);
@ -342,7 +342,7 @@ negotiate_formats (AppData *data)
return -1; return -1;
} }
n_buffers = MAX_BUFFERS; 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 ()); printf ("can't allocate buffers: %s\n", SDL_GetError ());
return -1; return -1;
} }

View file

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