From d828073bb81544354af17951cb51669f0cab626b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 3 Oct 2016 19:43:42 +0200 Subject: [PATCH] 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. --- pinos/client/stream.c | 109 +++++++-- pinos/gst/gstpinossink.c | 29 ++- pinos/server/link.c | 71 ++++-- pinos/server/node.c | 9 +- spa/include/spa/control.h | 31 ++- spa/include/spa/defs.h | 6 + spa/include/spa/node-event.h | 8 - spa/include/spa/node.h | 66 +++-- spa/include/spa/port.h | 7 + spa/lib/control.c | 57 +---- spa/lib/meson.build | 1 + spa/lib/port.c | 101 ++++++++ spa/plugins/alsa/alsa-sink.c | 64 +++-- spa/plugins/alsa/alsa-source.c | 122 ++++++---- spa/plugins/audiomixer/audiomixer.c | 153 ++++++------ spa/plugins/audiotestsrc/audiotestsrc.c | 109 +++++---- spa/plugins/ffmpeg/ffmpeg-dec.c | 30 +-- spa/plugins/ffmpeg/ffmpeg-enc.c | 30 +-- spa/plugins/remote/proxy.c | 306 +++++++++++++++--------- spa/plugins/v4l2/v4l2-source.c | 95 ++++---- spa/plugins/videotestsrc/videotestsrc.c | 108 +++++---- spa/plugins/volume/volume.c | 111 +++++---- spa/plugins/xv/xv-sink.c | 48 ++-- spa/tests/test-mixer.c | 18 +- spa/tests/test-v4l2.c | 8 +- spa/tools/spa-inspect.c | 55 +++-- 26 files changed, 1104 insertions(+), 648 deletions(-) create mode 100644 spa/lib/port.c diff --git a/pinos/client/stream.c b/pinos/client/stream.c index b0899f96a..5de84f5da 100644 --- a/pinos/client/stream.c +++ b/pinos/client/stream.c @@ -54,7 +54,9 @@ typedef struct { typedef struct { uint32_t id; bool used; + void *buf_ptr; SpaBuffer *buf; + SpaData *datas; } BufferId; struct _PinosStreamPrivate @@ -68,13 +70,13 @@ struct _PinosStreamPrivate PinosStreamState state; GError *error; - PinosDirection direction; gchar *path; SpaNodeState node_state; GPtrArray *possible_formats; SpaFormat *format; SpaPortInfo port_info; + SpaDirection direction; uint32_t port_id; uint32_t pending_seq; @@ -628,9 +630,9 @@ add_node_update (PinosStream *stream, SpaControlBuilder *builder, uint32_t chang nu.change_mask = change_mask; if (change_mask & SPA_CONTROL_CMD_NODE_UPDATE_MAX_INPUTS) - nu.max_input_ports = priv->direction == PINOS_DIRECTION_INPUT ? 1 : 0; + nu.max_input_ports = priv->direction == SPA_DIRECTION_INPUT ? 1 : 0; if (change_mask & SPA_CONTROL_CMD_NODE_UPDATE_MAX_OUTPUTS) - nu.max_output_ports = priv->direction == PINOS_DIRECTION_OUTPUT ? 1 : 0; + nu.max_output_ports = priv->direction == SPA_DIRECTION_OUTPUT ? 1 : 0; nu.props = NULL; spa_control_builder_add_cmd (builder, SPA_CONTROL_CMD_NODE_UPDATE, &nu); } @@ -653,6 +655,7 @@ add_port_update (PinosStream *stream, SpaControlBuilder *builder, uint32_t chang PinosStreamPrivate *priv = stream->priv; SpaControlCmdPortUpdate pu = { 0, };; + pu.direction = priv->direction; pu.port_id = priv->port_id; pu.change_mask = change_mask; if (change_mask & SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS) { @@ -663,8 +666,10 @@ add_port_update (PinosStream *stream, SpaControlBuilder *builder, uint32_t chang pu.format = priv->format; } pu.props = NULL; - if (change_mask & SPA_CONTROL_CMD_PORT_UPDATE_INFO) + if (change_mask & SPA_CONTROL_CMD_PORT_UPDATE_INFO) { pu.info = &priv->port_info; + spa_debug_port_info (pu.info); + } spa_control_builder_add_cmd (builder, SPA_CONTROL_CMD_PORT_UPDATE, &pu); } @@ -775,6 +780,7 @@ send_process_buffer (PinosStream *stream, uint32_t port_id, uint32_t buffer_id) SpaNodeEventHaveOutput ho; control_builder_init (stream, &builder); + pb.direction = priv->direction; pb.port_id = port_id; pb.buffer_id = buffer_id; spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_PROCESS_BUFFER, &pb); @@ -871,7 +877,7 @@ handle_node_event (PinosStream *stream, if (p->port_id != priv->port_id) break; - if (priv->direction != PINOS_DIRECTION_OUTPUT) + if (priv->direction != SPA_DIRECTION_OUTPUT) break; if ((bid = find_buffer (stream, p->buffer_id))) { @@ -932,7 +938,7 @@ handle_node_command (PinosStream *stream, g_debug ("stream %p: start", stream); control_builder_init (stream, &builder); - if (priv->direction == PINOS_DIRECTION_INPUT) + if (priv->direction == SPA_DIRECTION_INPUT) add_need_input (stream, &builder, priv->port_id); add_state_change (stream, &builder, SPA_NODE_STATE_STREAMING); add_async_complete (stream, &builder, seq, SPA_RESULT_OK); @@ -1072,6 +1078,7 @@ parse_control (PinosStream *stream, unsigned int i, j; SpaControlBuilder builder; SpaControl control; + SpaBuffer *b; if (spa_control_iter_parse_cmd (&it, &p) < 0) break; @@ -1095,16 +1102,62 @@ parse_control (PinosStream *stream, } } - bid.buf = spa_buffer_deserialize (mid->ptr, p.buffers[i].offset); - bid.id = bid.buf->id; + bid.buf_ptr = SPA_MEMBER (mid->ptr, p.buffers[i].offset, void); + { + size_t size; + unsigned int i; + SpaMeta *m; + + b = bid.buf_ptr; + size = sizeof (SpaBuffer); + m = SPA_MEMBER (b, SPA_PTR_TO_INT (b->metas), SpaMeta); + for (i = 0; i < b->n_metas; i++) + size += sizeof (SpaMeta) + m[i].size; + for (i = 0; i < b->n_datas; i++) + size += sizeof (SpaData); + + b = bid.buf = g_memdup (bid.buf_ptr, size); + + if (b->metas) + b->metas = SPA_MEMBER (b, SPA_PTR_TO_INT (b->metas), SpaMeta); + if (b->datas) { + bid.datas = SPA_MEMBER (bid.buf_ptr, SPA_PTR_TO_INT (b->datas), SpaData); + b->datas = SPA_MEMBER (b, SPA_PTR_TO_INT (b->datas), SpaData); + } + } + + bid.id = b->id; g_debug ("add buffer %d %d %zd", mid->id, bid.id, p.buffers[i].offset); - for (j = 0; j < bid.buf->n_datas; j++) { - SpaData *d = &bid.buf->datas[j]; - MemId *bmid = find_mem (stream, SPA_PTR_TO_UINT32 (d->data)); - d->data = SPA_INT_TO_PTR (bmid->fd); - g_debug (" data %d %u -> %d", j, bmid->id, bmid->fd); + for (j = 0; j < b->n_metas; j++) { + SpaMeta *m = &b->metas[j]; + if (m->data) + m->data = SPA_MEMBER (bid.buf_ptr, SPA_PTR_TO_INT (m->data), void); + } + + for (j = 0; j < b->n_datas; j++) { + SpaData *d = &b->datas[j]; + + switch (d->type) { + case SPA_DATA_TYPE_ID: + { + MemId *bmid = find_mem (stream, SPA_PTR_TO_UINT32 (d->data)); + d->type = SPA_DATA_TYPE_FD; + d->data = SPA_INT_TO_PTR (bmid->fd); + g_debug (" data %d %u -> %d", j, bmid->id, bmid->fd); + break; + } + case SPA_DATA_TYPE_MEMPTR: + { + d->data = SPA_MEMBER (bid.buf_ptr, SPA_PTR_TO_INT (d->data), void); + g_debug (" data %d %u -> %p", j, bid.id, d->data); + break; + } + default: + g_warning ("unknown buffer data type %d", d->type); + break; + } } if (bid.id != priv->buffer_ids->len) { @@ -1133,16 +1186,23 @@ parse_control (PinosStream *stream, case SPA_CONTROL_CMD_PROCESS_BUFFER: { SpaControlCmdProcessBuffer p; + guint i; + BufferId *bid; - if (priv->direction != PINOS_DIRECTION_INPUT) + if (priv->direction != SPA_DIRECTION_INPUT) break; if (spa_control_iter_parse_cmd (&it, &p) < 0) break; - g_signal_emit (stream, signals[SIGNAL_NEW_BUFFER], 0, p.buffer_id); + if ((bid = find_buffer (stream, p.buffer_id))) { + for (i = 0; i < bid->buf->n_datas; i++) { + bid->buf->datas[i].size = bid->datas[i].size; + } + g_signal_emit (stream, signals[SIGNAL_NEW_BUFFER], 0, p.buffer_id); - send_need_input (stream, priv->port_id); + send_need_input (stream, priv->port_id); + } break; } case SPA_CONTROL_CMD_NODE_EVENT: @@ -1434,8 +1494,8 @@ pinos_stream_connect (PinosStream *stream, g_return_val_if_fail (pinos_context_get_state (context) == PINOS_CONTEXT_STATE_CONNECTED, FALSE); g_return_val_if_fail (pinos_stream_get_state (stream) == PINOS_STREAM_STATE_UNCONNECTED, FALSE); - priv->direction = direction; - priv->port_id = direction == PINOS_DIRECTION_INPUT ? 0 : MAX_INPUTS; + priv->direction = direction == PINOS_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT; + priv->port_id = 0; priv->mode = mode; g_free (priv->path); priv->path = g_strdup (port_path); @@ -1502,6 +1562,9 @@ pinos_stream_finish_format (PinosStream *stream, add_state_change (stream, &builder, SPA_NODE_STATE_CONFIGURE); } } + priv->port_info.params = NULL; + priv->port_info.n_params = 0; + add_async_complete (stream, &builder, priv->pending_seq, res); spa_control_builder_end (&builder, &control); @@ -1705,7 +1768,7 @@ pinos_stream_get_empty_buffer (PinosStream *stream) g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE); priv = stream->priv; - g_return_val_if_fail (priv->direction == PINOS_DIRECTION_OUTPUT, FALSE); + g_return_val_if_fail (priv->direction == SPA_DIRECTION_OUTPUT, FALSE); for (i = 0; i < priv->buffer_ids->len; i++) { BufferId *bid = &g_array_index (priv->buffer_ids, BufferId, i); @@ -1733,7 +1796,7 @@ pinos_stream_recycle_buffer (PinosStream *stream, g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE); g_return_val_if_fail (id != SPA_ID_INVALID, FALSE); priv = stream->priv; - g_return_val_if_fail (priv->direction == PINOS_DIRECTION_INPUT, FALSE); + g_return_val_if_fail (priv->direction == SPA_DIRECTION_INPUT, FALSE); send_reuse_buffer (stream, priv->port_id, id); @@ -1783,14 +1846,18 @@ pinos_stream_send_buffer (PinosStream *stream, { PinosStreamPrivate *priv; BufferId *bid; + guint i; g_return_val_if_fail (PINOS_IS_STREAM (stream), FALSE); g_return_val_if_fail (id != SPA_ID_INVALID, FALSE); priv = stream->priv; - g_return_val_if_fail (priv->direction == PINOS_DIRECTION_OUTPUT, FALSE); + g_return_val_if_fail (priv->direction == SPA_DIRECTION_OUTPUT, FALSE); if ((bid = find_buffer (stream, id))) { bid->used = TRUE; + for (i = 0; i < bid->buf->n_datas; i++) { + bid->datas[i].size = bid->buf->datas[i].size; + } send_process_buffer (stream, priv->port_id, id); return TRUE; } else { diff --git a/pinos/gst/gstpinossink.c b/pinos/gst/gstpinossink.c index d3367428b..f0f57ab24 100644 --- a/pinos/gst/gstpinossink.c +++ b/pinos/gst/gstpinossink.c @@ -333,6 +333,7 @@ gst_pinos_sink_get_property (GObject * object, guint prop_id, typedef struct { GstPinosSink *sink; guint id; + SpaBuffer *buf; SpaMetaHeader *header; guint flags; } ProcessMemData; @@ -368,6 +369,7 @@ on_add_buffer (GObject *gobject, data.sink = gst_object_ref (pinossink); data.id = id; + data.buf = b; data.header = NULL; for (i = 0; i < b->n_metas; i++) { @@ -591,6 +593,7 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer) GstPinosSink *pinossink; gboolean res; ProcessMemData *data; + guint i; pinossink = GST_PINOS_SINK (bsink); @@ -599,7 +602,8 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer) pinos_main_loop_lock (pinossink->loop); if (pinos_stream_get_state (pinossink->stream) != PINOS_STREAM_STATE_STREAMING) - goto streaming_error; + goto done; +// goto streaming_error; if (buffer->pool != GST_BUFFER_POOL_CAST (pinossink->pool)) { GstBuffer *b = NULL; @@ -613,9 +617,22 @@ gst_pinos_sink_render (GstBaseSink * bsink, GstBuffer * buffer) data = gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buffer), process_mem_data_quark); + if (data->header) { + data->header->seq = GST_BUFFER_OFFSET (buffer); + data->header->pts = GST_BUFFER_PTS (buffer); + data->header->dts_offset = GST_BUFFER_DTS (buffer); + } + for (i = 0; i < data->buf->n_datas; i++) { + SpaData *d = &data->buf->datas[i]; + GstMemory *mem = gst_buffer_get_memory (buffer, i); + d->offset = mem->offset; + d->size = mem->size; + } + if (!(res = pinos_stream_send_buffer (pinossink->stream, data->id))) g_warning ("can't send buffer"); +done: pinos_main_loop_unlock (pinossink->loop); return GST_FLOW_OK; @@ -624,11 +641,11 @@ not_negotiated: { return GST_FLOW_NOT_NEGOTIATED; } -streaming_error: - { - pinos_main_loop_unlock (pinossink->loop); - return GST_FLOW_ERROR; - } +//streaming_error: +// { +// pinos_main_loop_unlock (pinossink->loop); +// return GST_FLOW_ERROR; +// } } static gboolean diff --git a/pinos/server/link.c b/pinos/server/link.c index 86a77853a..cd9042d05 100644 --- a/pinos/server/link.c +++ b/pinos/server/link.c @@ -237,6 +237,7 @@ do_negotiate (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state) g_debug ("link %p: doing negotiate format", this); again: if ((res = spa_node_port_enum_formats (this->input->node->node, + SPA_DIRECTION_INPUT, this->input->port, &filter, NULL, @@ -253,6 +254,7 @@ again: spa_debug_format (filter); if ((res = spa_node_port_enum_formats (this->output->node->node, + SPA_DIRECTION_OUTPUT, this->output->port, &format, filter, @@ -273,6 +275,7 @@ again: } else if (in_state == SPA_NODE_STATE_CONFIGURE && out_state > SPA_NODE_STATE_CONFIGURE) { /* only input needs format */ if ((res = spa_node_port_get_format (this->output->node->node, + SPA_DIRECTION_OUTPUT, this->output->port, (const SpaFormat **)&format)) < 0) { g_set_error (&error, @@ -284,6 +287,7 @@ again: } else if (out_state == SPA_NODE_STATE_CONFIGURE && in_state > SPA_NODE_STATE_CONFIGURE) { /* only output needs format */ if ((res = spa_node_port_get_format (this->input->node->node, + SPA_DIRECTION_INPUT, this->input->port, (const SpaFormat **)&format)) < 0) { g_set_error (&error, @@ -301,6 +305,7 @@ again: if (out_state == SPA_NODE_STATE_CONFIGURE) { g_debug ("link %p: doing set format on output", this); if ((res = spa_node_port_set_format (this->output->node->node, + SPA_DIRECTION_OUTPUT, this->output->port, SPA_PORT_FORMAT_FLAG_NEAREST, format)) < 0) { @@ -313,6 +318,7 @@ again: } else if (in_state == SPA_NODE_STATE_CONFIGURE) { g_debug ("link %p: doing set format on input", this); if ((res = spa_node_port_set_format (this->input->node->node, + SPA_DIRECTION_INPUT, this->input->port, SPA_PORT_FORMAT_FLAG_NEAREST, format)) < 0) { @@ -360,14 +366,20 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state) g_debug ("link %p: doing alloc buffers %p %p", this, this->output->node, this->input->node); /* find out what's possible */ - if ((res = spa_node_port_get_info (this->output->node->node, this->output->port, &oinfo)) < 0) { + if ((res = spa_node_port_get_info (this->output->node->node, + SPA_DIRECTION_OUTPUT, + this->output->port, + &oinfo)) < 0) { g_set_error (&error, PINOS_ERROR, PINOS_ERROR_BUFFER_ALLOCATION, "error get output port info: %d", res); goto error; } - if ((res = spa_node_port_get_info (this->input->node->node, this->input->port, &iinfo)) < 0) { + if ((res = spa_node_port_get_info (this->input->node->node, + SPA_DIRECTION_INPUT, + this->input->port, + &iinfo)) < 0) { g_set_error (&error, PINOS_ERROR, PINOS_ERROR_BUFFER_ALLOCATION, @@ -421,16 +433,20 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state) if (priv->buffers == NULL) { SpaAllocParamBuffers *in_alloc, *out_alloc; - guint max_buffers = MAX_BUFFERS; + guint max_buffers = MAX_BUFFERS, min_size = 4096; gboolean alloc_data = TRUE; max_buffers = MAX_BUFFERS; in_alloc = find_param (iinfo, SPA_ALLOC_PARAM_TYPE_BUFFERS); - if (in_alloc) + if (in_alloc) { max_buffers = in_alloc->max_buffers == 0 ? max_buffers : SPA_MIN (in_alloc->max_buffers, max_buffers); + min_size = SPA_MAX (min_size, in_alloc->minsize); + } out_alloc = find_param (oinfo, SPA_ALLOC_PARAM_TYPE_BUFFERS); - if (out_alloc) + if (out_alloc) { max_buffers = out_alloc->max_buffers == 0 ? max_buffers : SPA_MIN (out_alloc->max_buffers, max_buffers); + min_size = SPA_MAX (min_size, out_alloc->minsize); + } if ((in_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) || (out_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS)) @@ -445,23 +461,29 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state) g_debug ("reusing %d output buffers %p", priv->n_buffers, priv->buffers); } else { guint i; - size_t hdr_size; + size_t hdr_size, data_size, buf_size; void *p; spa_alloc_params_get_header_size (oinfo->params, oinfo->n_params, 1, &hdr_size); + if (alloc_data) + data_size = min_size; + else + data_size = 0; + + buf_size = hdr_size + data_size; priv->n_buffers = max_buffers; pinos_memblock_alloc (PINOS_MEMBLOCK_FLAG_WITH_FD | PINOS_MEMBLOCK_FLAG_MAP_READWRITE | PINOS_MEMBLOCK_FLAG_SEAL, - priv->n_buffers * (sizeof (SpaBuffer*) + hdr_size), + priv->n_buffers * (sizeof (SpaBuffer*) + buf_size), &priv->buffer_mem); priv->buffers = p = priv->buffer_mem.ptr; p = SPA_MEMBER (p, priv->n_buffers * sizeof (SpaBuffer*), void); for (i = 0; i < priv->n_buffers; i++) - priv->buffers[i] = SPA_MEMBER (p, hdr_size * i, SpaBuffer); + priv->buffers[i] = SPA_MEMBER (p, buf_size * i, SpaBuffer); if ((res = spa_buffer_init_headers (oinfo->params, oinfo->n_params, @@ -474,12 +496,25 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state) "error buffer alloc: %d", res); goto error; } + for (i = 0; i < priv->n_buffers; i++) { + SpaData *d = &priv->buffers[i]->datas[0]; + + g_debug (" buffers %p %d", priv->buffers[i], priv->buffers[i]->id); + d->type = SPA_DATA_TYPE_MEMPTR; + d->data = SPA_MEMBER (priv->buffers[i], hdr_size, void); + d->size = data_size; + d->maxsize = data_size; + d->offset = 0; + d->stride = 0; + } g_debug ("allocated %d buffers %p", priv->n_buffers, priv->buffers); priv->allocated = TRUE; } if (in_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) { - if ((res = spa_node_port_alloc_buffers (this->input->node->node, this->input->port, + if ((res = spa_node_port_alloc_buffers (this->input->node->node, + SPA_DIRECTION_INPUT, + this->input->port, oinfo->params, oinfo->n_params, priv->buffers, &priv->n_buffers)) < 0) { g_set_error (&error, @@ -496,7 +531,9 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state) g_debug ("allocated %d buffers %p from input port", priv->n_buffers, priv->buffers); } else if (out_flags & SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS) { - if ((res = spa_node_port_alloc_buffers (this->output->node->node, this->output->port, + if ((res = spa_node_port_alloc_buffers (this->output->node->node, + SPA_DIRECTION_OUTPUT, + this->output->port, iinfo->params, iinfo->n_params, priv->buffers, &priv->n_buffers)) < 0) { g_set_error (&error, @@ -516,8 +553,11 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state) if (in_flags & SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS) { g_debug ("using %d buffers %p on input port", priv->n_buffers, priv->buffers); - if ((res = spa_node_port_use_buffers (this->input->node->node, this->input->port, - priv->buffers, priv->n_buffers)) < 0) { + if ((res = spa_node_port_use_buffers (this->input->node->node, + SPA_DIRECTION_INPUT, + this->input->port, + priv->buffers, + priv->n_buffers)) < 0) { g_set_error (&error, PINOS_ERROR, PINOS_ERROR_BUFFER_ALLOCATION, @@ -530,8 +570,11 @@ do_allocation (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state) } else if (out_flags & SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS) { g_debug ("using %d buffers %p on output port", priv->n_buffers, priv->buffers); - if ((res = spa_node_port_use_buffers (this->output->node->node, this->output->port, - priv->buffers, priv->n_buffers)) < 0) { + if ((res = spa_node_port_use_buffers (this->output->node->node, + SPA_DIRECTION_OUTPUT, + this->output->port, + priv->buffers, + priv->n_buffers)) < 0) { g_set_error (&error, PINOS_ERROR, PINOS_ERROR_BUFFER_ALLOCATION, diff --git a/pinos/server/node.c b/pinos/server/node.c index b9e047359..2a4e9f550 100644 --- a/pinos/server/node.c +++ b/pinos/server/node.c @@ -281,7 +281,7 @@ suspend_node (PinosNode *this) for (walk = priv->input_ports; walk; walk = g_list_next (walk)) { NodePort *p = walk->data; - if ((res = spa_node_port_set_format (this->node, p->port.port, 0, NULL)) < 0) + if ((res = spa_node_port_set_format (this->node, SPA_DIRECTION_INPUT, p->port.port, 0, NULL)) < 0) g_warning ("error unset format output: %d", res); p->port.buffers = NULL; p->port.n_buffers = 0; @@ -291,7 +291,7 @@ suspend_node (PinosNode *this) } for (walk = priv->output_ports; walk; walk = g_list_next (walk)) { NodePort *p = walk->data; - if ((res = spa_node_port_set_format (this->node, p->port.port, 0, NULL)) < 0) + if ((res = spa_node_port_set_format (this->node, SPA_DIRECTION_OUTPUT, p->port.port, 0, NULL)) < 0) g_warning ("error unset format output: %d", res); p->port.buffers = NULL; p->port.n_buffers = 0; @@ -1132,15 +1132,14 @@ pinos_node_get_free_port (PinosNode *node, max_ports = priv->max_input_ports; n_ports = priv->n_input_ports; ports = priv->input_ports; - free_port = 0; } else { max_ports = priv->max_output_ports; n_ports = priv->n_output_ports; ports = priv->output_ports; - free_port = priv->max_input_ports; } + free_port = 0; - g_debug ("node %p: direction %d max %u, n %u", node, direction, max_ports, n_ports); + g_debug ("node %p: direction %d max %u, n %u, free_port %u", node, direction, max_ports, n_ports, free_port); for (walk = ports; walk; walk = g_list_next (walk)) { PinosPort *p = walk->data; diff --git a/spa/include/spa/control.h b/spa/include/spa/control.h index 8cd6ee533..761674b55 100644 --- a/spa/include/spa/control.h +++ b/spa/include/spa/control.h @@ -94,6 +94,7 @@ typedef struct { /* SPA_CONTROL_CMD_PORT_UPDATE */ typedef struct { + SpaDirection direction; uint32_t port_id; #define SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS (1 << 0) #define SPA_CONTROL_CMD_PORT_UPDATE_FORMAT (1 << 1) @@ -116,20 +117,23 @@ typedef struct { /* SPA_CONTROL_CMD_ADD_PORT */ typedef struct { - uint32_t seq; - uint32_t port_id; + uint32_t seq; + SpaDirection direction; + uint32_t port_id; } SpaControlCmdAddPort; /* SPA_CONTROL_CMD_REMOVE_PORT */ typedef struct { - uint32_t seq; - uint32_t port_id; + uint32_t seq; + SpaDirection direction; + uint32_t port_id; } SpaControlCmdRemovePort; /* SPA_CONTROL_CMD_SET_FORMAT */ typedef struct { uint32_t seq; + SpaDirection direction; uint32_t port_id; SpaPortFormatFlags flags; SpaFormat *format; @@ -137,11 +141,12 @@ typedef struct { /* SPA_CONTROL_CMD_SET_PROPERTY */ typedef struct { - uint32_t seq; - uint32_t port_id; - uint32_t id; - size_t size; - void *value; + uint32_t seq; + SpaDirection direction; + uint32_t port_id; + uint32_t id; + size_t size; + void *value; } SpaControlCmdSetProperty; /* SPA_CONTROL_CMD_NODE_COMMAND */ @@ -152,6 +157,7 @@ typedef struct { /* SPA_CONTROL_CMD_ADD_MEM */ typedef struct { + SpaDirection direction; uint32_t port_id; uint32_t mem_id; unsigned int fd_index; @@ -162,6 +168,7 @@ typedef struct { /* SPA_CONTROL_CMD_REMOVE_MEM */ typedef struct { + SpaDirection direction; uint32_t port_id; uint32_t mem_id; } SpaControlCmdRemoveMem; @@ -175,6 +182,7 @@ typedef struct { /* SPA_CONTROL_CMD_USE_BUFFERS */ typedef struct { uint32_t seq; + SpaDirection direction; uint32_t port_id; unsigned int n_buffers; SpaControlMemRef *buffers; @@ -182,8 +190,9 @@ typedef struct { /* SPA_CONTROL_CMD_PROCESS_BUFFER */ typedef struct { - uint32_t port_id; - uint32_t buffer_id; + SpaDirection direction; + uint32_t port_id; + uint32_t buffer_id; } SpaControlCmdProcessBuffer; /* SPA_CONTROL_CMD_NODE_EVENT */ diff --git a/spa/include/spa/defs.h b/spa/include/spa/defs.h index 584aabf24..0a42687ae 100644 --- a/spa/include/spa/defs.h +++ b/spa/include/spa/defs.h @@ -74,6 +74,12 @@ typedef enum { #define SPA_RESULT_ASYNC_SEQ(res) ((res) & SPA_ASYNC_SEQ_MASK) #define SPA_RESULT_RETURN_ASYNC(seq) (SPA_RESULT_ASYNC | ((seq) & SPA_ASYNC_SEQ_MASK)) +typedef enum { + SPA_DIRECTION_INVALID = 0, + SPA_DIRECTION_INPUT, + SPA_DIRECTION_OUTPUT, +} SpaDirection; + typedef void (*SpaNotify) (void *data); #define SPA_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) diff --git a/spa/include/spa/node-event.h b/spa/include/spa/node-event.h index f9b6714e3..35991093d 100644 --- a/spa/include/spa/node-event.h +++ b/spa/include/spa/node-event.h @@ -75,14 +75,6 @@ typedef struct { SpaResult res; } SpaNodeEventAsyncComplete; -typedef struct { - uint32_t port_id; -} SpaNodeEventPortAdded; - -typedef struct { - uint32_t port_id; -} SpaNodeEventPortRemoved; - typedef struct { SpaNodeState state; } SpaNodeEventStateChange; diff --git a/spa/include/spa/node.h b/spa/include/spa/node.h index 2b8a2784d..85375b978 100644 --- a/spa/include/spa/node.h +++ b/spa/include/spa/node.h @@ -270,8 +270,7 @@ struct _SpaNode { * @n_output_ports: size of the @output_ids array * @output_ids: array to store the output stream ids * - * Get the current number of input and output ports and also the maximum - * number of ports. + * Get the ids of the currently available ports. * * Returns: #SPA_RESULT_OK on success * #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL @@ -285,26 +284,28 @@ struct _SpaNode { /** * SpaNode::add_port: * @node: a #SpaNode + * @direction: a #SpaDirection * @port_id: an unused port id * * Make a new port with @port_id. The called should use get_port_ids() to - * find an unused id. + * find an unused id for the given @direction. * - * Input port ids should be between 0 and max_input_ports and output ports - * between max_input_ports and max_input_ports + max_output_ports as obtained - * from get_port_ids(). + * Port ids should be between 0 and max_ports as obtained from get_n_ports(). * * Returns: #SPA_RESULT_OK on success * #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL */ SpaResult (*add_port) (SpaNode *node, + SpaDirection direction, uint32_t port_id); SpaResult (*remove_port) (SpaNode *node, + SpaDirection direction, uint32_t port_id); /** * SpaNode::port_enum_formats: * @node: a #SpaNode + * @direction: a #SpaDirection * @port_id: the port to query * @format: pointer to a format * @filter: a format filter @@ -325,6 +326,7 @@ struct _SpaNode { * #SPA_RESULT_ENUM_END when no format exists */ SpaResult (*port_enum_formats) (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaFormat **format, const SpaFormat *filter, @@ -332,6 +334,7 @@ struct _SpaNode { /** * SpaNode::port_set_format: * @node: a #SpaNode + * @direction: a #SpaDirection * @port_id: the port to configure * @flags: flags * @format: a #SpaFormat with the format @@ -359,13 +362,15 @@ struct _SpaNode { * is not correct. * #SPA_RESULT_ASYNC the function is executed asynchronously */ - SpaResult (*port_set_format) (SpaNode *node, - uint32_t port_id, - SpaPortFormatFlags flags, - const SpaFormat *format); + SpaResult (*port_set_format) (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaPortFormatFlags flags, + const SpaFormat *format); /** * SpaNode::port_get_format: * @node: a #SpaNode + * @direction: a #SpaDirection * @port_id: the port to query * @format: a pointer to a location to hold the #SpaFormat * @@ -378,23 +383,28 @@ struct _SpaNode { * #SPA_RESULT_INVALID_NO_FORMAT when no format was set */ SpaResult (*port_get_format) (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaFormat **format); SpaResult (*port_get_info) (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortInfo **info); SpaResult (*port_get_props) (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaProps **props); SpaResult (*port_set_props) (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaProps *props); /** * SpaNode::port_use_buffers: * @node: a #SpaNode + * @direction: a #SpaDirection * @port_id: a port id * @buffers: an array of buffer pointers * @n_buffers: number of elements in @buffers @@ -420,12 +430,14 @@ struct _SpaNode { * #SPA_RESULT_ASYNC the function is executed asynchronously */ SpaResult (*port_use_buffers) (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaBuffer **buffers, unsigned int n_buffers); /** * SpaNode::port_alloc_buffers: * @node: a #SpaNode + * @direction: a #SpaDirection * @port_id: a port id * @params: allocation parameters * @n_params: number of elements in @params @@ -456,28 +468,15 @@ struct _SpaNode { * #SPA_RESULT_ASYNC the function is executed asynchronously */ SpaResult (*port_alloc_buffers) (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaAllocParam **params, unsigned int n_params, SpaBuffer **buffers, unsigned int *n_buffers); - /** - * SpaNode::port_reuse_buffer: - * @node: a #SpaNode - * @port_id: a port id - * @buffer_id: a buffer id to reuse - * - * Tell an output port to reuse a buffer. - * - * Returns: #SPA_RESULT_OK on success - * #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL - */ - SpaResult (*port_reuse_buffer) (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id); - SpaResult (*port_get_status) (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortStatus **status); @@ -523,8 +522,23 @@ struct _SpaNode { SpaResult (*port_pull_output) (SpaNode *node, unsigned int n_info, SpaPortOutputInfo *info); + /** + * SpaNode::port_reuse_buffer: + * @node: a #SpaNode + * @port_id: a port id + * @buffer_id: a buffer id to reuse + * + * Tell an output port to reuse a buffer. + * + * Returns: #SPA_RESULT_OK on success + * #SPA_RESULT_INVALID_ARGUMENTS when node is %NULL + */ + SpaResult (*port_reuse_buffer) (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id); SpaResult (*port_push_event) (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaNodeEvent *event); @@ -546,10 +560,10 @@ struct _SpaNode { #define spa_node_port_set_props(n,...) (n)->port_set_props((n),__VA_ARGS__) #define spa_node_port_use_buffers(n,...) (n)->port_use_buffers((n),__VA_ARGS__) #define spa_node_port_alloc_buffers(n,...) (n)->port_alloc_buffers((n),__VA_ARGS__) -#define spa_node_port_reuse_buffer(n,...) (n)->port_reuse_buffer((n),__VA_ARGS__) #define spa_node_port_get_status(n,...) (n)->port_get_status((n),__VA_ARGS__) #define spa_node_port_push_input(n,...) (n)->port_push_input((n),__VA_ARGS__) #define spa_node_port_pull_output(n,...) (n)->port_pull_output((n),__VA_ARGS__) +#define spa_node_port_reuse_buffer(n,...) (n)->port_reuse_buffer((n),__VA_ARGS__) #define spa_node_port_push_event(n,...) (n)->port_push_event((n),__VA_ARGS__) #ifdef __cplusplus diff --git a/spa/include/spa/port.h b/spa/include/spa/port.h index 78d02f362..75fa41ab7 100644 --- a/spa/include/spa/port.h +++ b/spa/include/spa/port.h @@ -115,6 +115,13 @@ typedef struct { const char **features; } SpaPortInfo; + +size_t spa_port_info_get_size (const SpaPortInfo *info); +size_t spa_port_info_serialize (void *dest, const SpaPortInfo *info); +SpaPortInfo * spa_port_info_deserialize (void *src, off_t offset); + +SpaPortInfo * spa_port_info_copy_into (void *dest, const SpaPortInfo *info); + /** * SpaPortStatusFlags: * @SPA_PORT_STATUS_FLAG_NONE: no status flags diff --git a/spa/lib/control.c b/spa/lib/control.c index 86de3eb5f..57de3adbb 100644 --- a/spa/lib/control.c +++ b/spa/lib/control.c @@ -369,20 +369,10 @@ iter_parse_port_update (struct stack_iter *si, SpaControlCmdPortUpdate *pu) } if (pu->format) pu->format = spa_format_deserialize (p, SPA_PTR_TO_INT (pu->format)); - if (pu->props) pu->props = spa_props_deserialize (p, SPA_PTR_TO_INT (pu->props)); - if (pu->info) { - SpaPortInfo *pi; - - pu->info = p = SPA_MEMBER (p, SPA_PTR_TO_INT (pu->info), SpaPortInfo); - - pi = (SpaPortInfo *) pu->info; - pi->params = SPA_MEMBER (p, SPA_PTR_TO_INT (pi->params), SpaAllocParam *); - for (i = 0; i < pi->n_params; i++) { - pi->params[i] = SPA_MEMBER (p, SPA_PTR_TO_INT (pi->params[i]), SpaAllocParam); - } - } + if (pu->info) + pu->info = spa_port_info_deserialize (p, SPA_PTR_TO_INT (pu->info)); } static void @@ -759,39 +749,6 @@ builder_add_cmd (struct stack_builder *sb, SpaControlCmd cmd, size_t size) return p; } -static size_t -write_port_info (void *p, const SpaPortInfo *info) -{ - SpaPortInfo *tp; - SpaAllocParam **ap; - int i; - size_t len; - - if (info == NULL) - return 0; - - tp = p; - memcpy (tp, info, sizeof (SpaPortInfo)); - - p = SPA_MEMBER (tp, sizeof (SpaPortInfo), SpaAllocParam *); - ap = p; - if (info->n_params) - tp->params = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp)); - else - tp->params = 0; - tp->features = 0; - - p = SPA_MEMBER (p, sizeof (SpaAllocParam*) * info->n_params, void); - - for (i = 0; i < info->n_params; i++) { - len = info->params[i]->size; - memcpy (p, info->params[i], len); - ap[i] = SPA_INT_TO_PTR (SPA_PTRDIFF (p, tp)); - p = SPA_MEMBER (p, len, void); - } - return SPA_PTRDIFF (p, tp); -} - static void builder_add_node_update (struct stack_builder *sb, SpaControlCmdNodeUpdate *nu) { @@ -833,12 +790,8 @@ builder_add_port_update (struct stack_builder *sb, SpaControlCmdPortUpdate *pu) } len += spa_format_get_size (pu->format); len += spa_props_get_size (pu->props); - if (pu->info) { - len += sizeof (SpaPortInfo); - len += pu->info->n_params * sizeof (SpaAllocParam *); - for (i = 0; i < pu->info->n_params; i++) - len += pu->info->params[i]->size; - } + if (pu->info) + len += spa_port_info_get_size (pu->info); p = builder_add_cmd (sb, SPA_CONTROL_CMD_PORT_UPDATE, len); memcpy (p, pu, sizeof (SpaControlCmdPortUpdate)); @@ -873,7 +826,7 @@ builder_add_port_update (struct stack_builder *sb, SpaControlCmdPortUpdate *pu) d->props = 0; } if (pu->info) { - len = write_port_info (p, pu->info); + len = spa_port_info_serialize (p, pu->info); d->info = SPA_INT_TO_PTR (SPA_PTRDIFF (p, d)); p = SPA_MEMBER (p, len, void); } else { diff --git a/spa/lib/meson.build b/spa/lib/meson.build index 9738f3f8b..e34f5e554 100644 --- a/spa/lib/meson.build +++ b/spa/lib/meson.build @@ -3,6 +3,7 @@ spalib_sources = ['audio-raw.c', 'control.c', 'debug.c', 'format.c', + 'port.c', 'props.c', 'ringbuffer.c', 'video-raw.c'] diff --git a/spa/lib/port.c b/spa/lib/port.c new file mode 100644 index 000000000..2687c5d18 --- /dev/null +++ b/spa/lib/port.c @@ -0,0 +1,101 @@ +/* Simple Plugin API + * Copyright (C) 2016 Wim Taymans + * + * 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 +#include +#include +#include + +#include +#include + + +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); +} diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c index ab33051a0..cac435f11 100644 --- a/spa/plugins/alsa/alsa-sink.c +++ b/spa/plugins/alsa/alsa-sink.c @@ -26,6 +26,8 @@ #include "alsa-utils.h" +#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0) + typedef struct _SpaALSAState SpaALSASink; static const char default_device[] = "default"; @@ -211,10 +213,10 @@ spa_alsa_sink_node_get_n_ports (SpaNode *node, if (n_input_ports) *n_input_ports = 1; - if (n_output_ports) - *n_output_ports = 0; if (max_input_ports) *max_input_ports = 1; + if (n_output_ports) + *n_output_ports = 0; if (max_output_ports) *max_output_ports = 0; @@ -240,6 +242,7 @@ spa_alsa_sink_node_get_port_ids (SpaNode *node, static SpaResult spa_alsa_sink_node_add_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -247,6 +250,7 @@ spa_alsa_sink_node_add_port (SpaNode *node, static SpaResult spa_alsa_sink_node_remove_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -254,6 +258,7 @@ spa_alsa_sink_node_remove_port (SpaNode *node, static SpaResult spa_alsa_sink_node_port_enum_formats (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaFormat **format, const SpaFormat *filter, @@ -267,7 +272,7 @@ spa_alsa_sink_node_port_enum_formats (SpaNode *node, this = (SpaALSASink *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; index = (*state == NULL ? 0 : *(int*)state); @@ -294,6 +299,7 @@ spa_alsa_sink_node_port_enum_formats (SpaNode *node, static SpaResult spa_alsa_sink_node_port_set_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaPortFormatFlags flags, const SpaFormat *format) @@ -306,7 +312,7 @@ spa_alsa_sink_node_port_set_format (SpaNode *node, this = (SpaALSASink *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (format == NULL) { @@ -345,6 +351,7 @@ spa_alsa_sink_node_port_set_format (SpaNode *node, static SpaResult spa_alsa_sink_node_port_get_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaFormat **format) { @@ -355,7 +362,7 @@ spa_alsa_sink_node_port_get_format (SpaNode *node, this = (SpaALSASink *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (!this->have_format) @@ -368,6 +375,7 @@ spa_alsa_sink_node_port_get_format (SpaNode *node, static SpaResult spa_alsa_sink_node_port_get_info (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortInfo **info) { @@ -378,7 +386,7 @@ spa_alsa_sink_node_port_get_info (SpaNode *node, this = (SpaALSASink *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; *info = &this->info; @@ -387,15 +395,17 @@ spa_alsa_sink_node_port_get_info (SpaNode *node, } static SpaResult -spa_alsa_sink_node_port_get_props (SpaNode *node, - uint32_t port_id, - SpaProps **props) +spa_alsa_sink_node_port_get_props (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaProps **props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_alsa_sink_node_port_set_props (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaProps *props) { @@ -404,6 +414,7 @@ spa_alsa_sink_node_port_set_props (SpaNode *node, static SpaResult spa_alsa_sink_node_port_use_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaBuffer **buffers, uint32_t n_buffers) @@ -413,6 +424,7 @@ spa_alsa_sink_node_port_use_buffers (SpaNode *node, static SpaResult spa_alsa_sink_node_port_alloc_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaAllocParam **params, uint32_t n_params, @@ -424,7 +436,7 @@ spa_alsa_sink_node_port_alloc_buffers (SpaNode *node, if (node == NULL || node->handle == NULL || buffers == NULL) return SPA_RESULT_INVALID_ARGUMENTS; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; this = (SpaALSASink *) node->handle; @@ -435,16 +447,9 @@ spa_alsa_sink_node_port_alloc_buffers (SpaNode *node, return SPA_RESULT_NOT_IMPLEMENTED; } -static SpaResult -spa_alsa_sink_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) -{ - return SPA_RESULT_NOT_IMPLEMENTED; -} - static SpaResult spa_alsa_sink_node_port_get_status (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortStatus **status) { @@ -455,7 +460,7 @@ spa_alsa_sink_node_port_get_status (SpaNode *node, this = (SpaALSASink *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; *status = &this->status; @@ -516,6 +521,24 @@ spa_alsa_sink_node_port_pull_output (SpaNode *node, return SPA_RESULT_INVALID_PORT; } +static SpaResult +spa_alsa_sink_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + return SPA_RESULT_NOT_IMPLEMENTED; +} + +static SpaResult +spa_alsa_sink_node_port_push_event (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaNodeEvent *event) +{ + return SPA_RESULT_NOT_IMPLEMENTED; +} + + static const SpaNode alsasink_node = { NULL, sizeof (SpaNode), @@ -537,10 +560,11 @@ static const SpaNode alsasink_node = { spa_alsa_sink_node_port_set_props, spa_alsa_sink_node_port_use_buffers, spa_alsa_sink_node_port_alloc_buffers, - spa_alsa_sink_node_port_reuse_buffer, spa_alsa_sink_node_port_get_status, spa_alsa_sink_node_port_push_input, spa_alsa_sink_node_port_pull_output, + spa_alsa_sink_node_port_reuse_buffer, + spa_alsa_sink_node_port_push_event, }; static SpaResult diff --git a/spa/plugins/alsa/alsa-source.c b/spa/plugins/alsa/alsa-source.c index bbf27e634..fd9ffe4a8 100644 --- a/spa/plugins/alsa/alsa-source.c +++ b/spa/plugins/alsa/alsa-source.c @@ -27,6 +27,8 @@ #include "alsa-utils.h" +#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) + typedef struct _SpaALSAState SpaALSASource; static void @@ -244,20 +246,23 @@ spa_alsa_source_node_get_port_ids (SpaNode *node, static SpaResult spa_alsa_source_node_add_port (SpaNode *node, - uint32_t port_id) + SpaDirection direction, + uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_alsa_source_node_remove_port (SpaNode *node, - uint32_t port_id) + SpaDirection direction, + uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_alsa_source_node_port_enum_formats (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaFormat **format, const SpaFormat *filter, @@ -271,7 +276,7 @@ spa_alsa_source_node_port_enum_formats (SpaNode *node, this = (SpaALSASource *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; index = (*state == NULL ? 0 : *(int*)state); @@ -326,6 +331,7 @@ spa_alsa_clear_buffers (SpaALSASource *this) static SpaResult spa_alsa_source_node_port_set_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaPortFormatFlags flags, const SpaFormat *format) @@ -338,7 +344,7 @@ spa_alsa_source_node_port_set_format (SpaNode *node, this = (SpaALSASource *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (format == NULL) { @@ -379,8 +385,9 @@ spa_alsa_source_node_port_set_format (SpaNode *node, static SpaResult spa_alsa_source_node_port_get_format (SpaNode *node, - uint32_t port_id, - const SpaFormat **format) + SpaDirection direction, + uint32_t port_id, + const SpaFormat **format) { SpaALSASource *this; @@ -389,7 +396,7 @@ spa_alsa_source_node_port_get_format (SpaNode *node, this = (SpaALSASource *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (!this->have_format) @@ -402,8 +409,9 @@ spa_alsa_source_node_port_get_format (SpaNode *node, static SpaResult spa_alsa_source_node_port_get_info (SpaNode *node, - uint32_t port_id, - const SpaPortInfo **info) + SpaDirection direction, + uint32_t port_id, + const SpaPortInfo **info) { SpaALSASource *this; @@ -412,7 +420,7 @@ spa_alsa_source_node_port_get_info (SpaNode *node, this = (SpaALSASource *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; *info = &this->info; @@ -421,23 +429,26 @@ spa_alsa_source_node_port_get_info (SpaNode *node, } static SpaResult -spa_alsa_source_node_port_get_props (SpaNode *node, - uint32_t port_id, - SpaProps **props) +spa_alsa_source_node_port_get_props (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaProps **props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_alsa_source_node_port_set_props (SpaNode *node, - uint32_t port_id, - const SpaProps *props) + SpaDirection direction, + uint32_t port_id, + const SpaProps *props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_alsa_source_node_port_use_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaBuffer **buffers, uint32_t n_buffers) @@ -449,7 +460,7 @@ spa_alsa_source_node_port_use_buffers (SpaNode *node, if (node == NULL || node->handle == NULL) return SPA_RESULT_INVALID_ARGUMENTS; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; this = (SpaALSASource *) node->handle; @@ -484,6 +495,7 @@ spa_alsa_source_node_port_use_buffers (SpaNode *node, static SpaResult spa_alsa_source_node_port_alloc_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaAllocParam **params, uint32_t n_params, @@ -495,7 +507,7 @@ spa_alsa_source_node_port_alloc_buffers (SpaNode *node, if (node == NULL || node->handle == NULL || buffers == NULL) return SPA_RESULT_INVALID_ARGUMENTS; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; this = (SpaALSASource *) node->handle; @@ -506,34 +518,9 @@ spa_alsa_source_node_port_alloc_buffers (SpaNode *node, return SPA_RESULT_NOT_IMPLEMENTED; } -static SpaResult -spa_alsa_source_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) -{ - SpaALSASource *this; - - if (node == NULL || node->handle == NULL) - return SPA_RESULT_INVALID_ARGUMENTS; - - this = (SpaALSASource *) node->handle; - - if (port_id != 0) - return SPA_RESULT_INVALID_PORT; - - if (!this->have_buffers) - return SPA_RESULT_NO_BUFFERS; - - if (buffer_id >= this->n_buffers) - return SPA_RESULT_INVALID_BUFFER_ID; - - recycle_buffer (this, buffer_id); - - return SPA_RESULT_OK; -} - static SpaResult spa_alsa_source_node_port_get_status (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortStatus **status) { @@ -544,7 +531,7 @@ spa_alsa_source_node_port_get_status (SpaNode *node, this = (SpaALSASource *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; *status = &this->status; @@ -554,16 +541,16 @@ spa_alsa_source_node_port_get_status (SpaNode *node, static SpaResult spa_alsa_source_node_port_push_input (SpaNode *node, - unsigned int n_info, - SpaPortInputInfo *info) + unsigned int n_info, + SpaPortInputInfo *info) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_alsa_source_node_port_pull_output (SpaNode *node, - unsigned int n_info, - SpaPortOutputInfo *info) + unsigned int n_info, + SpaPortOutputInfo *info) { SpaALSASource *this; unsigned int i; @@ -607,6 +594,41 @@ spa_alsa_source_node_port_pull_output (SpaNode *node, } +static SpaResult +spa_alsa_source_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + SpaALSASource *this; + + if (node == NULL || node->handle == NULL) + return SPA_RESULT_INVALID_ARGUMENTS; + + this = (SpaALSASource *) node->handle; + + if (port_id != 0) + return SPA_RESULT_INVALID_PORT; + + if (!this->have_buffers) + return SPA_RESULT_NO_BUFFERS; + + if (buffer_id >= this->n_buffers) + return SPA_RESULT_INVALID_BUFFER_ID; + + recycle_buffer (this, buffer_id); + + return SPA_RESULT_OK; +} + +static SpaResult +spa_alsa_source_node_port_push_event (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaNodeEvent *event) +{ + return SPA_RESULT_NOT_IMPLEMENTED; +} + static const SpaNode alsasource_node = { NULL, sizeof (SpaNode), @@ -628,11 +650,13 @@ static const SpaNode alsasource_node = { spa_alsa_source_node_port_set_props, spa_alsa_source_node_port_use_buffers, spa_alsa_source_node_port_alloc_buffers, - spa_alsa_source_node_port_reuse_buffer, spa_alsa_source_node_port_get_status, spa_alsa_source_node_port_push_input, spa_alsa_source_node_port_pull_output, + spa_alsa_source_node_port_reuse_buffer, + spa_alsa_source_node_port_push_event, }; + static SpaResult spa_alsa_source_clock_get_props (SpaClock *clock, SpaProps **props) diff --git a/spa/plugins/audiomixer/audiomixer.c b/spa/plugins/audiomixer/audiomixer.c index 80e36d681..5d33fb76c 100644 --- a/spa/plugins/audiomixer/audiomixer.c +++ b/spa/plugins/audiomixer/audiomixer.c @@ -73,9 +73,15 @@ struct _SpaAudioMixer { int port_count; int port_queued; - SpaAudioMixerPort ports[MAX_PORTS + 1]; + SpaAudioMixerPort in_ports[MAX_PORTS]; + SpaAudioMixerPort out_ports[1]; }; +#define CHECK_FREE_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && !this->in_ports[(p)].valid) +#define CHECK_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_PORTS && this->in_ports[(p)].valid) +#define CHECK_OUT_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) +#define CHECK_PORT(this,d,p) (CHECK_OUT_PORT(this,d,p) || CHECK_IN_PORT (this,d,p)) + enum { PROP_ID_LAST, }; @@ -198,10 +204,10 @@ spa_audiomixer_node_get_n_ports (SpaNode *node, if (n_input_ports) *n_input_ports = 0; - if (n_output_ports) - *n_output_ports = 1; if (max_input_ports) *max_input_ports = MAX_PORTS; + if (n_output_ports) + *n_output_ports = 1; if (max_output_ports) *max_output_ports = 1; @@ -225,18 +231,19 @@ spa_audiomixer_node_get_port_ids (SpaNode *node, if (input_ids) { for (i = 0, idx = 0; i < MAX_PORTS && idx < n_input_ports; i++) { - if (this->ports[i].valid) + if (this->in_ports[i].valid) input_ids[idx++] = i; } } if (n_output_ports > 0 && output_ids) - output_ids[0] = MAX_PORTS; + output_ids[0] = 0; return SPA_RESULT_OK; } static SpaResult spa_audiomixer_node_add_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { SpaAudioMixer *this; @@ -246,28 +253,26 @@ spa_audiomixer_node_add_port (SpaNode *node, this = (SpaAudioMixer *) node->handle; - if (port_id >= MAX_PORTS) + if (!CHECK_FREE_IN_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - if (this->ports[port_id].valid) - return SPA_RESULT_INVALID_PORT; - - this->ports[port_id].valid = true; + this->in_ports[port_id].valid = true; this->port_count++; - this->ports[port_id].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | + this->in_ports[port_id].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | SPA_PORT_INFO_FLAG_REMOVABLE | SPA_PORT_INFO_FLAG_OPTIONAL | SPA_PORT_INFO_FLAG_IN_PLACE; - this->ports[port_id].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT; + this->in_ports[port_id].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT; - this->ports[MAX_PORTS].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; + this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; return SPA_RESULT_OK; } static SpaResult spa_audiomixer_node_remove_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { SpaAudioMixer *this; @@ -277,17 +282,17 @@ spa_audiomixer_node_remove_port (SpaNode *node, this = (SpaAudioMixer *) node->handle; - if (port_id >= MAX_PORTS || !this->ports[port_id].valid) + if (!CHECK_IN_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - this->ports[port_id].valid = false; + this->in_ports[port_id].valid = false; this->port_count--; - if (this->ports[port_id].buffer) { - this->ports[port_id].buffer = NULL; + if (this->in_ports[port_id].buffer) { + this->in_ports[port_id].buffer = NULL; this->port_queued--; } if (this->port_count == this->port_queued) - this->ports[MAX_PORTS].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; + this->out_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; return SPA_RESULT_OK; } @@ -295,6 +300,7 @@ spa_audiomixer_node_remove_port (SpaNode *node, static SpaResult spa_audiomixer_node_port_enum_formats (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaFormat **format, const SpaFormat *filter, @@ -309,10 +315,10 @@ spa_audiomixer_node_port_enum_formats (SpaNode *node, this = (SpaAudioMixer *) node->handle; - if (port_id > MAX_PORTS || !this->ports[port_id].valid) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0]; index = (*state == NULL ? 0 : *(int*)state); @@ -333,6 +339,7 @@ spa_audiomixer_node_port_enum_formats (SpaNode *node, static SpaResult spa_audiomixer_node_port_set_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaPortFormatFlags flags, const SpaFormat *format) @@ -346,10 +353,10 @@ spa_audiomixer_node_port_set_format (SpaNode *node, this = (SpaAudioMixer *) node->handle; - if (port_id > MAX_PORTS || !this->ports[port_id].valid) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0]; if (format == NULL) { port->have_format = false; @@ -366,6 +373,7 @@ spa_audiomixer_node_port_set_format (SpaNode *node, static SpaResult spa_audiomixer_node_port_get_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaFormat **format) { @@ -377,10 +385,10 @@ spa_audiomixer_node_port_get_format (SpaNode *node, this = (SpaAudioMixer *) node->handle; - if (port_id > MAX_PORTS || !this->ports[port_id].valid) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0]; if (!port->have_format) return SPA_RESULT_NO_FORMAT; @@ -392,6 +400,7 @@ spa_audiomixer_node_port_get_format (SpaNode *node, static SpaResult spa_audiomixer_node_port_get_info (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortInfo **info) { @@ -403,25 +412,27 @@ spa_audiomixer_node_port_get_info (SpaNode *node, this = (SpaAudioMixer *) node->handle; - if (port_id > MAX_PORTS || !this->ports[port_id].valid) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0]; *info = &port->info; return SPA_RESULT_OK; } static SpaResult -spa_audiomixer_node_port_get_props (SpaNode *node, - uint32_t port_id, - SpaProps **props) +spa_audiomixer_node_port_get_props (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaProps **props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_audiomixer_node_port_set_props (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaProps *props) { @@ -430,6 +441,7 @@ spa_audiomixer_node_port_set_props (SpaNode *node, static SpaResult spa_audiomixer_node_port_use_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaBuffer **buffers, uint32_t n_buffers) @@ -439,6 +451,7 @@ spa_audiomixer_node_port_use_buffers (SpaNode *node, static SpaResult spa_audiomixer_node_port_alloc_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaAllocParam **params, uint32_t n_params, @@ -448,16 +461,9 @@ spa_audiomixer_node_port_alloc_buffers (SpaNode *node, return SPA_RESULT_NOT_IMPLEMENTED; } -static SpaResult -spa_audiomixer_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) -{ - return SPA_RESULT_NOT_IMPLEMENTED; -} - static SpaResult spa_audiomixer_node_port_get_status (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortStatus **status) { @@ -469,10 +475,10 @@ spa_audiomixer_node_port_get_status (SpaNode *node, this = (SpaAudioMixer *) node->handle; - if (port_id > MAX_PORTS || !this->ports[port_id].valid) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[0]; if (!port->have_format) return SPA_RESULT_NO_FORMAT; @@ -495,7 +501,7 @@ spa_audiomixer_node_port_push_input (SpaNode *node, this = (SpaAudioMixer *) node->handle; - if (this->ports[MAX_PORTS].status.flags & SPA_PORT_STATUS_FLAG_HAVE_OUTPUT) + if (this->out_ports[0].status.flags & SPA_PORT_STATUS_FLAG_HAVE_OUTPUT) return SPA_RESULT_HAVE_ENOUGH_INPUT; for (i = 0; i < n_info; i++) { @@ -503,12 +509,12 @@ spa_audiomixer_node_port_push_input (SpaNode *node, SpaAudioMixerPort *port; int idx = info[i].port_id; - if (idx >= MAX_PORTS || !this->ports[idx].valid) { + if (!CHECK_IN_PORT (this, SPA_DIRECTION_INPUT, idx)) { info[i].status = SPA_RESULT_INVALID_PORT; have_error = true; continue; } - port = &this->ports[idx]; + port = &this->in_ports[idx]; buffer = port->buffers[info[i].buffer_id]; if (buffer == NULL) { @@ -524,19 +530,19 @@ spa_audiomixer_node_port_push_input (SpaNode *node, continue; } - if (this->ports[idx].buffer != NULL) { + if (port->buffer != NULL) { info[i].status = SPA_RESULT_HAVE_ENOUGH_INPUT; have_error = true; continue; } - this->ports[idx].buffer = buffer; - this->ports[idx].buffer_queued = 0; - this->ports[idx].buffer_index = 0; - this->ports[idx].buffer_offset = 0; + port->buffer = buffer; + port->buffer_queued = 0; + port->buffer_index = 0; + port->buffer_offset = 0; this->port_queued++; if (this->port_queued == this->port_count) - this->ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; + this->out_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; } info[i].status = SPA_RESULT_OK; } @@ -592,7 +598,7 @@ add_port_data (SpaAudioMixer *this, SpaBuffer *out, SpaAudioMixerPort *port) if (++port->buffer_index == port->buffer->n_datas) { port->buffer = NULL; port->status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT; - this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; + this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; break; } port->buffer_offset = 0; @@ -623,37 +629,37 @@ mix_data (SpaAudioMixer *this, SpaPortOutputInfo *info) min_size = 0; min_port = 0; - for (i = 1; i < MAX_PORTS; i++) { - if (!this->ports[i].valid) + for (i = 0; i < MAX_PORTS; i++) { + if (!this->in_ports[i].valid) continue; - if (this->ports[i].buffer == NULL) { + if (this->in_ports[i].buffer == NULL) { if (pull_size && info->flags & SPA_PORT_OUTPUT_FLAG_PULL) { pull_port (this, i, info, pull_size); } - if (this->ports[i].buffer == NULL) + if (this->in_ports[i].buffer == NULL) return SPA_RESULT_NEED_MORE_INPUT; } - if (min_size == 0 || this->ports[i].buffer_queued < min_size) { - min_size = this->ports[i].buffer_queued; + if (min_size == 0 || this->in_ports[i].buffer_queued < min_size) { + min_size = this->in_ports[i].buffer_queued; min_port = i; } } if (min_port == 0) return SPA_RESULT_NEED_MORE_INPUT; - buf = this->ports[min_port].buffer; + buf = this->in_ports[min_port].buffer; info->buffer_id = buf->id; - this->ports[min_port].buffer = NULL; - this->ports[min_port].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT; - this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; + this->in_ports[min_port].buffer = NULL; + this->in_ports[min_port].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT; + this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; - for (i = 1; i < MAX_PORTS; i++) { - if (!this->ports[i].valid || this->ports[i].buffer == NULL) + for (i = 0; i < MAX_PORTS; i++) { + if (!this->in_ports[i].valid || this->in_ports[i].buffer == NULL) continue; - add_port_data (this, buf, &this->ports[i]); + add_port_data (this, buf, &this->in_ports[i]); } return SPA_RESULT_OK; } @@ -673,10 +679,10 @@ spa_audiomixer_node_port_pull_output (SpaNode *node, this = (SpaAudioMixer *) node->handle; - if (info->port_id != MAX_PORTS) + if (!CHECK_OUT_PORT (this, SPA_DIRECTION_OUTPUT, info->port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[info->port_id]; + port = &this->out_ports[info->port_id]; if (!port->have_format) return SPA_RESULT_NO_FORMAT; @@ -697,8 +703,17 @@ spa_audiomixer_node_port_pull_output (SpaNode *node, return SPA_RESULT_OK; } +static SpaResult +spa_audiomixer_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + return SPA_RESULT_NOT_IMPLEMENTED; +} + static SpaResult spa_audiomixer_node_port_push_event (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaNodeEvent *event) { @@ -726,10 +741,10 @@ static const SpaNode audiomixer_node = { spa_audiomixer_node_port_set_props, spa_audiomixer_node_port_use_buffers, spa_audiomixer_node_port_alloc_buffers, - spa_audiomixer_node_port_reuse_buffer, spa_audiomixer_node_port_get_status, spa_audiomixer_node_port_push_input, spa_audiomixer_node_port_pull_output, + spa_audiomixer_node_port_reuse_buffer, spa_audiomixer_node_port_push_event, }; @@ -781,10 +796,10 @@ spa_audiomixer_init (const SpaHandleFactory *factory, this->props[1].props.prop_info = prop_info; reset_audiomixer_props (&this->props[1]); - this->ports[MAX_PORTS].valid = true; - this->ports[MAX_PORTS].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS | - SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | - SPA_PORT_INFO_FLAG_NO_REF; + this->out_ports[0].valid = true; + this->out_ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS | + SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | + SPA_PORT_INFO_FLAG_NO_REF; return SPA_RESULT_OK; } diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index f2c43edf1..dfa699ac3 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -93,6 +93,8 @@ struct _SpaAudioTestSrc { SpaQueue ready; }; +#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) + #define DEFAULT_WAVE 0 #define DEFAULT_VOLUME 1.0 #define DEFAULT_FREQ 440.0 @@ -470,6 +472,7 @@ spa_audiotestsrc_node_get_port_ids (SpaNode *node, static SpaResult spa_audiotestsrc_node_add_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -477,6 +480,7 @@ spa_audiotestsrc_node_add_port (SpaNode *node, static SpaResult spa_audiotestsrc_node_remove_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -484,6 +488,7 @@ spa_audiotestsrc_node_remove_port (SpaNode *node, static SpaResult spa_audiotestsrc_node_port_enum_formats (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaFormat **format, const SpaFormat *filter, @@ -497,7 +502,7 @@ spa_audiotestsrc_node_port_enum_formats (SpaNode *node, this = (SpaAudioTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; index = (*state == NULL ? 0 : *(int*)state); @@ -535,6 +540,7 @@ clear_buffers (SpaAudioTestSrc *this) static SpaResult spa_audiotestsrc_node_port_set_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaPortFormatFlags flags, const SpaFormat *format) @@ -547,7 +553,7 @@ spa_audiotestsrc_node_port_set_format (SpaNode *node, this = (SpaAudioTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (format == NULL) { @@ -590,6 +596,7 @@ spa_audiotestsrc_node_port_set_format (SpaNode *node, static SpaResult spa_audiotestsrc_node_port_get_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaFormat **format) { @@ -600,7 +607,7 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node, this = (SpaAudioTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (!this->have_format) @@ -613,6 +620,7 @@ spa_audiotestsrc_node_port_get_format (SpaNode *node, static SpaResult spa_audiotestsrc_node_port_get_info (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortInfo **info) { @@ -623,7 +631,7 @@ spa_audiotestsrc_node_port_get_info (SpaNode *node, this = (SpaAudioTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; *info = &this->info; @@ -632,15 +640,17 @@ spa_audiotestsrc_node_port_get_info (SpaNode *node, } static SpaResult -spa_audiotestsrc_node_port_get_props (SpaNode *node, - uint32_t port_id, - SpaProps **props) +spa_audiotestsrc_node_port_get_props (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaProps **props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_audiotestsrc_node_port_set_props (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaProps *props) { @@ -649,6 +659,7 @@ spa_audiotestsrc_node_port_set_props (SpaNode *node, static SpaResult spa_audiotestsrc_node_port_use_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaBuffer **buffers, uint32_t n_buffers) @@ -660,7 +671,7 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode *node, this = (SpaAudioTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (!this->have_format) @@ -716,6 +727,7 @@ spa_audiotestsrc_node_port_use_buffers (SpaNode *node, static SpaResult spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaAllocParam **params, uint32_t n_params, @@ -729,7 +741,7 @@ spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node, this = (SpaAudioTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (!this->have_format) @@ -741,44 +753,9 @@ spa_audiotestsrc_node_port_alloc_buffers (SpaNode *node, return SPA_RESULT_NOT_IMPLEMENTED; } -static SpaResult -spa_audiotestsrc_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) -{ - SpaAudioTestSrc *this; - ATSBuffer *b; - - if (node == NULL || node->handle == NULL) - return SPA_RESULT_INVALID_ARGUMENTS; - - this = (SpaAudioTestSrc *) node->handle; - - if (port_id != 0) - return SPA_RESULT_INVALID_PORT; - - if (!this->have_buffers) - return SPA_RESULT_NO_BUFFERS; - - if (buffer_id >= this->n_buffers) - return SPA_RESULT_INVALID_BUFFER_ID; - - b = &this->buffers[buffer_id]; - if (!b->outstanding) - return SPA_RESULT_OK; - - b->outstanding = false; - b->next = NULL; - SPA_QUEUE_PUSH_TAIL (&this->empty, ATSBuffer, next, b); - - if (this->empty.length == 1 && !this->props[1].live) - update_poll_enabled (this, true); - - return SPA_RESULT_OK; -} - static SpaResult spa_audiotestsrc_node_port_get_status (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortStatus **status) { @@ -789,7 +766,7 @@ spa_audiotestsrc_node_port_get_status (SpaNode *node, this = (SpaAudioTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (!this->have_format) @@ -808,6 +785,7 @@ spa_audiotestsrc_node_port_push_input (SpaNode *node, { return SPA_RESULT_INVALID_PORT; } + static SpaResult spa_audiotestsrc_node_port_pull_output (SpaNode *node, unsigned int n_info, @@ -854,8 +832,45 @@ spa_audiotestsrc_node_port_pull_output (SpaNode *node, return SPA_RESULT_OK; } +static SpaResult +spa_audiotestsrc_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + SpaAudioTestSrc *this; + ATSBuffer *b; + + if (node == NULL || node->handle == NULL) + return SPA_RESULT_INVALID_ARGUMENTS; + + this = (SpaAudioTestSrc *) node->handle; + + if (port_id != 0) + return SPA_RESULT_INVALID_PORT; + + if (!this->have_buffers) + return SPA_RESULT_NO_BUFFERS; + + if (buffer_id >= this->n_buffers) + return SPA_RESULT_INVALID_BUFFER_ID; + + b = &this->buffers[buffer_id]; + if (!b->outstanding) + return SPA_RESULT_OK; + + b->outstanding = false; + b->next = NULL; + SPA_QUEUE_PUSH_TAIL (&this->empty, ATSBuffer, next, b); + + if (this->empty.length == 1 && !this->props[1].live) + update_poll_enabled (this, true); + + return SPA_RESULT_OK; +} + static SpaResult spa_audiotestsrc_node_port_push_event (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaNodeEvent *event) { @@ -883,10 +898,10 @@ static const SpaNode audiotestsrc_node = { spa_audiotestsrc_node_port_set_props, spa_audiotestsrc_node_port_use_buffers, spa_audiotestsrc_node_port_alloc_buffers, - spa_audiotestsrc_node_port_reuse_buffer, spa_audiotestsrc_node_port_get_status, spa_audiotestsrc_node_port_push_input, spa_audiotestsrc_node_port_pull_output, + spa_audiotestsrc_node_port_reuse_buffer, spa_audiotestsrc_node_port_push_event, }; diff --git a/spa/plugins/ffmpeg/ffmpeg-dec.c b/spa/plugins/ffmpeg/ffmpeg-dec.c index 58b8ec58c..f116a3516 100644 --- a/spa/plugins/ffmpeg/ffmpeg-dec.c +++ b/spa/plugins/ffmpeg/ffmpeg-dec.c @@ -400,20 +400,6 @@ spa_ffmpeg_dec_node_port_alloc_buffers (SpaNode *node, return SPA_RESULT_NOT_IMPLEMENTED; } -static SpaResult -spa_ffmpeg_dec_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) -{ - if (node == NULL || node->handle == NULL) - return SPA_RESULT_INVALID_ARGUMENTS; - - if (!IS_VALID_PORT (port_id)) - return SPA_RESULT_INVALID_PORT; - - return SPA_RESULT_NOT_IMPLEMENTED; -} - static SpaResult spa_ffmpeg_dec_node_port_get_status (SpaNode *node, uint32_t port_id, @@ -478,6 +464,20 @@ spa_ffmpeg_dec_node_port_pull_output (SpaNode *node, return SPA_RESULT_OK; } +static SpaResult +spa_ffmpeg_dec_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + if (node == NULL || node->handle == NULL) + return SPA_RESULT_INVALID_ARGUMENTS; + + if (!IS_VALID_PORT (port_id)) + return SPA_RESULT_INVALID_PORT; + + return SPA_RESULT_NOT_IMPLEMENTED; +} + static SpaResult spa_ffmpeg_dec_node_port_push_event (SpaNode *node, uint32_t port_id, @@ -508,10 +508,10 @@ static const SpaNode ffmpeg_dec_node = { spa_ffmpeg_dec_node_port_set_props, spa_ffmpeg_dec_node_port_use_buffers, spa_ffmpeg_dec_node_port_alloc_buffers, - spa_ffmpeg_dec_node_port_reuse_buffer, spa_ffmpeg_dec_node_port_get_status, spa_ffmpeg_dec_node_port_push_input, spa_ffmpeg_dec_node_port_pull_output, + spa_ffmpeg_dec_node_port_reuse_buffer, spa_ffmpeg_dec_node_port_push_event, }; diff --git a/spa/plugins/ffmpeg/ffmpeg-enc.c b/spa/plugins/ffmpeg/ffmpeg-enc.c index ba5d0b68b..94a7f4ecb 100644 --- a/spa/plugins/ffmpeg/ffmpeg-enc.c +++ b/spa/plugins/ffmpeg/ffmpeg-enc.c @@ -403,20 +403,6 @@ spa_ffmpeg_enc_node_port_alloc_buffers (SpaNode *node, return SPA_RESULT_NOT_IMPLEMENTED; } -static SpaResult -spa_ffmpeg_enc_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) -{ - if (node == NULL || node->handle == NULL) - return SPA_RESULT_INVALID_ARGUMENTS; - - if (!IS_VALID_PORT (port_id)) - return SPA_RESULT_INVALID_PORT; - - return SPA_RESULT_NOT_IMPLEMENTED; -} - static SpaResult spa_ffmpeg_enc_node_port_get_status (SpaNode *node, uint32_t port_id, @@ -482,6 +468,20 @@ spa_ffmpeg_enc_node_port_pull_output (SpaNode *node, return SPA_RESULT_OK; } +static SpaResult +spa_ffmpeg_enc_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + if (node == NULL || node->handle == NULL) + return SPA_RESULT_INVALID_ARGUMENTS; + + if (!IS_VALID_PORT (port_id)) + return SPA_RESULT_INVALID_PORT; + + return SPA_RESULT_NOT_IMPLEMENTED; +} + static SpaResult spa_ffmpeg_enc_node_port_push_event (SpaNode *node, uint32_t port_id, @@ -511,10 +511,10 @@ static const SpaNode ffmpeg_enc_node = { spa_ffmpeg_enc_node_port_set_props, spa_ffmpeg_enc_node_port_use_buffers, spa_ffmpeg_enc_node_port_alloc_buffers, - spa_ffmpeg_enc_node_port_reuse_buffer, spa_ffmpeg_enc_node_port_get_status, spa_ffmpeg_enc_node_port_push_input, spa_ffmpeg_enc_node_port_pull_output, + spa_ffmpeg_enc_node_port_reuse_buffer, spa_ffmpeg_enc_node_port_push_event, }; diff --git a/spa/plugins/remote/proxy.c b/spa/plugins/remote/proxy.c index 6a58cef81..3a95fc54c 100644 --- a/spa/plugins/remote/proxy.c +++ b/spa/plugins/remote/proxy.c @@ -37,14 +37,19 @@ #define MAX_INPUTS 64 #define MAX_OUTPUTS 64 -#define MAX_PORTS (MAX_INPUTS + MAX_OUTPUTS) #define MAX_BUFFERS 16 -#define CHECK_FREE_PORT_ID(this,id) ((id) < MAX_PORTS && !(this)->ports[id].valid) -#define CHECK_PORT_ID(this,id) ((id) < MAX_PORTS && (this)->ports[id].valid) -#define CHECK_PORT_ID_IN(this,id) (CHECK_PORT_ID(this,id) && (id < this->max_inputs)) -#define CHECK_PORT_ID_OUT(this,id) (CHECK_PORT_ID(this,id) && (id >= this->max_inputs)) +#define CHECK_IN_PORT_ID(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) < MAX_INPUTS) +#define CHECK_OUT_PORT_ID(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) < MAX_OUTPUTS) +#define CHECK_PORT_ID(this,d,p) (CHECK_IN_PORT_ID(this,d,p) || CHECK_OUT_PORT_ID(this,d,p)) +#define CHECK_FREE_IN_PORT(this,d,p) (CHECK_IN_PORT_ID(this,d,p) && !(this)->in_ports[p].valid) +#define CHECK_FREE_OUT_PORT(this,d,p) (CHECK_OUT_PORT_ID(this,d,p) && !(this)->out_ports[p].valid) +#define CHECK_FREE_PORT(this,d,p) (CHECK_FREE_IN_PORT (this,d,p) || CHECK_FREE_OUT_PORT (this,d,p)) +#define CHECK_IN_PORT(this,d,p) (CHECK_IN_PORT_ID(this,d,p) && (this)->in_ports[p].valid) +#define CHECK_OUT_PORT(this,d,p) (CHECK_OUT_PORT_ID(this,d,p) && (this)->out_ports[p].valid) +#define CHECK_PORT(this,d,p) (CHECK_IN_PORT (this,d,p) || CHECK_OUT_PORT (this,d,p)) + typedef struct _SpaProxy SpaProxy; typedef struct _ProxyBuffer ProxyBuffer; @@ -65,7 +70,7 @@ typedef struct { typedef struct { bool valid; - SpaPortInfo info; + SpaPortInfo *info; SpaFormat *format; unsigned int n_formats; SpaFormat **formats; @@ -99,7 +104,8 @@ struct _SpaProxy { unsigned int n_inputs; unsigned int max_outputs; unsigned int n_outputs; - SpaProxyPort ports[MAX_PORTS]; + SpaProxyPort in_ports[MAX_INPUTS]; + SpaProxyPort out_ports[MAX_OUTPUTS]; uint32_t seq; }; @@ -331,10 +337,10 @@ spa_proxy_node_get_n_ports (SpaNode *node, if (n_input_ports) *n_input_ports = this->n_inputs; - if (n_output_ports) - *n_output_ports = this->n_outputs; if (max_input_ports) *max_input_ports = this->max_inputs; + if (n_output_ports) + *n_output_ports = this->n_outputs; if (max_output_ports) *max_output_ports = this->max_outputs; @@ -358,14 +364,14 @@ spa_proxy_node_get_port_ids (SpaNode *node, if (input_ids) { for (c = 0, i = 0; i < MAX_INPUTS && c < n_input_ports; i++) { - if (this->ports[i].valid) + if (this->in_ports[i].valid) input_ids[c++] = i; } } if (output_ids) { for (c = 0, i = 0; i < MAX_OUTPUTS && c < n_output_ports; i++) { - if (this->ports[MAX_INPUTS + i].valid) - output_ids[c++] = MAX_INPUTS + i; + if (this->out_ports[i].valid) + output_ids[c++] = i; } } return SPA_RESULT_OK; @@ -379,7 +385,11 @@ do_update_port (SpaProxy *this, unsigned int i; size_t size; - port = &this->ports[pu->port_id]; + if (pu->direction == SPA_DIRECTION_INPUT) { + port = &this->in_ports[pu->port_id]; + } else { + port = &this->out_ports[pu->port_id]; + } if (pu->change_mask & SPA_CONTROL_CMD_PORT_UPDATE_POSSIBLE_FORMATS) { for (i = 0; i < port->n_formats; i++) @@ -403,7 +413,11 @@ do_update_port (SpaProxy *this, } if (pu->change_mask & SPA_CONTROL_CMD_PORT_UPDATE_INFO && pu->info) { - port->info = *pu->info; + if (port->info) + free (port->info); + size = spa_port_info_get_size (pu->info); + port->info = spa_port_info_copy_into (malloc (size), pu->info); + spa_debug_port_info (port->info); } if (!port->valid) { @@ -411,7 +425,7 @@ do_update_port (SpaProxy *this, port->format = NULL; port->valid = true; - if (pu->port_id < MAX_INPUTS) + if (pu->direction == SPA_DIRECTION_INPUT) this->n_inputs++; else this->n_outputs++; @@ -421,6 +435,7 @@ do_update_port (SpaProxy *this, static void clear_port (SpaProxy *this, SpaProxyPort *port, + SpaDirection direction, uint32_t port_id) { SpaControlCmdPortUpdate pu; @@ -429,6 +444,7 @@ clear_port (SpaProxy *this, SPA_CONTROL_CMD_PORT_UPDATE_FORMAT | SPA_CONTROL_CMD_PORT_UPDATE_PROPS | SPA_CONTROL_CMD_PORT_UPDATE_INFO; + pu.direction = direction; pu.port_id = port_id; pu.n_possible_formats = 0; pu.possible_formats = NULL; @@ -441,24 +457,26 @@ clear_port (SpaProxy *this, static void do_uninit_port (SpaProxy *this, + SpaDirection direction, uint32_t port_id) { SpaProxyPort *port; fprintf (stderr, "proxy %p: removing port %d\n", this, port_id); - port = &this->ports[port_id]; - - if (port_id < MAX_INPUTS) + if (direction == SPA_DIRECTION_INPUT) { + port = &this->in_ports[port_id]; this->n_inputs--; - else + } else { + port = &this->out_ports[port_id]; this->n_outputs--; - - clear_port (this, port, port_id); + } + clear_port (this, port, direction, port_id); port->valid = false; } static SpaResult spa_proxy_node_add_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { SpaProxy *this; @@ -469,17 +487,18 @@ spa_proxy_node_add_port (SpaNode *node, this = (SpaProxy *) node->handle; - if (!CHECK_FREE_PORT_ID (this, port_id)) + if (!CHECK_FREE_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; - clear_port (this, port, port_id); + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; + clear_port (this, port, direction, port_id); return SPA_RESULT_OK; } static SpaResult spa_proxy_node_remove_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { SpaProxy *this; @@ -489,16 +508,17 @@ spa_proxy_node_remove_port (SpaNode *node, this = (SpaProxy *) node->handle; - if (!CHECK_PORT_ID (this, port_id)) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - do_uninit_port (this, port_id); + do_uninit_port (this, direction, port_id); return SPA_RESULT_OK; } static SpaResult spa_proxy_node_port_enum_formats (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaFormat **format, const SpaFormat *filter, @@ -513,10 +533,10 @@ spa_proxy_node_port_enum_formats (SpaNode *node, this = (SpaProxy *) node->handle; - if (!CHECK_PORT_ID (this, port_id)) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; index = (*state == NULL ? 0 : *(int*)state); @@ -531,6 +551,7 @@ spa_proxy_node_port_enum_formats (SpaNode *node, static SpaResult spa_proxy_node_port_set_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaPortFormatFlags flags, const SpaFormat *format) @@ -547,11 +568,13 @@ spa_proxy_node_port_set_format (SpaNode *node, this = (SpaProxy *) node->handle; - if (!CHECK_PORT_ID (this, port_id)) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0); sf.seq = this->seq++; + sf.direction = direction; + sf.port_id = port_id; sf.flags = flags; sf.format = (SpaFormat *) format; spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_SET_FORMAT, &sf); @@ -567,6 +590,7 @@ spa_proxy_node_port_set_format (SpaNode *node, static SpaResult spa_proxy_node_port_get_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaFormat **format) { @@ -578,10 +602,10 @@ spa_proxy_node_port_get_format (SpaNode *node, this = (SpaProxy *) node->handle; - if (!CHECK_PORT_ID (this, port_id)) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; if (!port->format) return SPA_RESULT_NO_FORMAT; @@ -593,6 +617,7 @@ spa_proxy_node_port_get_format (SpaNode *node, static SpaResult spa_proxy_node_port_get_info (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortInfo **info) { @@ -604,26 +629,28 @@ spa_proxy_node_port_get_info (SpaNode *node, this = (SpaProxy *) node->handle; - if (!CHECK_PORT_ID (this, port_id)) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; - *info = &port->info; + *info = port->info; return SPA_RESULT_OK; } static SpaResult -spa_proxy_node_port_get_props (SpaNode *node, - uint32_t port_id, - SpaProps **props) +spa_proxy_node_port_get_props (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaProps **props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_proxy_node_port_set_props (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaProps *props) { @@ -632,6 +659,7 @@ spa_proxy_node_port_set_props (SpaNode *node, static SpaResult spa_proxy_node_port_get_status (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortStatus **status) { @@ -643,10 +671,10 @@ spa_proxy_node_port_get_status (SpaNode *node, this = (SpaProxy *) node->handle; - if (!CHECK_PORT_ID (this, port_id)) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; if (!port->format) return SPA_RESULT_NO_FORMAT; @@ -658,6 +686,7 @@ spa_proxy_node_port_get_status (SpaNode *node, static SpaResult spa_proxy_node_port_use_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaBuffer **buffers, uint32_t n_buffers) @@ -682,10 +711,10 @@ spa_proxy_node_port_use_buffers (SpaNode *node, this = (SpaProxy *) node->handle; fprintf (stderr, "proxy %p: use buffers %p %u\n", this, buffers, n_buffers); - if (!CHECK_PORT_ID (this, port_id)) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; if (!port->format) return SPA_RESULT_NO_FORMAT; @@ -708,9 +737,7 @@ spa_proxy_node_port_use_buffers (SpaNode *node, b->size = spa_buffer_get_size (buffers[i]); b->offset = size; - size += b->size; - - for (j = 0; j < buffers[i]->n_datas; j++) { + for (j = 0; j < buffers[i]->n_metas; j++) { memcpy (&b->buffer.metas[j], &buffers[i]->metas[j], sizeof (SpaMeta)); } @@ -719,21 +746,37 @@ spa_proxy_node_port_use_buffers (SpaNode *node, memcpy (&b->buffer.datas[j], d, sizeof (SpaData)); - am.port_id = port_id; - am.mem_id = n_mem; - am.fd_index = spa_control_builder_add_fd (&builder, SPA_PTR_TO_INT (d->data), false); - am.flags = 0; - am.offset = d->offset; - am.size = d->maxsize; - spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_MEM, &am); + switch (d->type) { + case SPA_DATA_TYPE_FD: + am.direction = direction; + am.port_id = port_id; + am.mem_id = n_mem; + am.fd_index = spa_control_builder_add_fd (&builder, SPA_PTR_TO_INT (d->data), false); + am.flags = 0; + am.offset = d->offset; + am.size = d->maxsize; + spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_MEM, &am); - b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem); - n_mem++; + b->buffer.datas[j].type = SPA_DATA_TYPE_ID; + b->buffer.datas[j].data = SPA_UINT32_TO_PTR (n_mem); + n_mem++; + break; + case SPA_DATA_TYPE_MEMPTR: + b->buffer.datas[j].data = SPA_INT_TO_PTR (b->size); + b->size += d->size; + break; + default: + b->buffer.datas[j].type = SPA_DATA_TYPE_INVALID; + b->buffer.datas[j].data = 0; + fprintf (stderr, "invalid memory type %d\n", d->type); + break; + } } + size += b->size; } /* make mem for the buffers */ - port->buffer_mem_id = n_mem; + port->buffer_mem_id = n_mem++; port->buffer_mem_size = size; port->buffer_mem_fd = memfd_create ("spa-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING); @@ -754,22 +797,28 @@ spa_proxy_node_port_use_buffers (SpaNode *node, for (i = 0; i < n_buffers; i++) { ProxyBuffer *b = &port->buffers[i]; - size_t len; SpaBuffer *sb; SpaMeta *sbm; + SpaData *sbd; - len = spa_buffer_serialize (p, &b->buffer); + spa_buffer_serialize (p, &b->buffer); sb = p; b->buffer.datas = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->datas), SpaData); sbm = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->metas), SpaMeta); + sbd = SPA_MEMBER (sb, SPA_PTR_TO_INT (sb->datas), SpaData); for (j = 0; j < b->buffer.n_metas; j++) b->metas[j].data = SPA_MEMBER (sb, SPA_PTR_TO_INT (sbm[j].data), void); - p += len; + for (j = 0; j < b->buffer.n_datas; j++) { + if (b->datas[j].type == SPA_DATA_TYPE_MEMPTR) + b->datas[j].data = SPA_MEMBER (sb, SPA_PTR_TO_INT (sbd[j].data), void); + } + p += b->size; } + am.direction = direction; am.port_id = port_id; am.mem_id = port->buffer_mem_id; am.fd_index = spa_control_builder_add_fd (&builder, port->buffer_mem_fd, false); @@ -778,18 +827,18 @@ spa_proxy_node_port_use_buffers (SpaNode *node, am.size = size; spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_ADD_MEM, &am); - memref = alloca (n_mem * sizeof (SpaControlMemRef)); + memref = alloca (n_buffers * sizeof (SpaControlMemRef)); for (i = 0; i < n_buffers; i++) { memref[i].mem_id = port->buffer_mem_id; memref[i].offset = port->buffers[i].offset; memref[i].size = port->buffers[i].size; } - port->n_buffers = n_buffers; ub.seq = this->seq++; + ub.direction = direction; ub.port_id = port_id; - ub.n_buffers = port->n_buffers; + ub.n_buffers = n_buffers; ub.buffers = memref; spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_USE_BUFFERS, &ub); @@ -805,6 +854,7 @@ spa_proxy_node_port_use_buffers (SpaNode *node, static SpaResult spa_proxy_node_port_alloc_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaAllocParam **params, uint32_t n_params, @@ -819,10 +869,10 @@ spa_proxy_node_port_alloc_buffers (SpaNode *node, this = (SpaProxy *) node->handle; - if (!CHECK_PORT_ID (this, port_id)) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; if (!port->format) return SPA_RESULT_NO_FORMAT; @@ -830,45 +880,24 @@ spa_proxy_node_port_alloc_buffers (SpaNode *node, return SPA_RESULT_NOT_IMPLEMENTED; } -static SpaResult -spa_proxy_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) +static void +copy_meta_in (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id) { - SpaProxy *this; - SpaControlBuilder builder; - SpaControl control; - uint8_t buf[128]; - SpaResult res; - SpaControlCmdNodeEvent cne; - SpaNodeEvent ne; - SpaNodeEventReuseBuffer rb; + ProxyBuffer *b = &port->buffers[buffer_id]; + unsigned int i; - if (node == NULL || node->handle == NULL) - return SPA_RESULT_INVALID_ARGUMENTS; - - this = (SpaProxy *) node->handle; - - if (!CHECK_PORT_ID (this, port_id)) - return SPA_RESULT_INVALID_PORT; - - /* send start */ - spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0); - cne.event = ≠ - ne.type = SPA_NODE_EVENT_TYPE_REUSE_BUFFER; - ne.data = &rb; - ne.size = sizeof (rb); - rb.port_id = port_id; - rb.buffer_id = buffer_id; - spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_NODE_EVENT, &cne); - spa_control_builder_end (&builder, &control); - - if ((res = spa_control_write (&control, this->fds[0].fd)) < 0) - fprintf (stderr, "proxy %p: error writing control %d\n", this, res); - - spa_control_clear (&control); - - return res; + for (i = 0; i < b->outbuf->n_metas; i++) { + SpaMeta *sm = &b->metas[i]; + SpaMeta *dm = &b->outbuf->metas[i]; + memcpy (dm->data, sm->data, dm->size); + } + for (i = 0; i < b->outbuf->n_datas; i++) { + b->outbuf->datas[i].size = b->buffer.datas[i].size; + if (b->outbuf->datas[i].type == SPA_DATA_TYPE_MEMPTR) { + fprintf (stderr, "memcpy in %zd\n", b->buffer.datas[i].size); + memcpy (b->outbuf->datas[i].data, b->datas[i].data, b->buffer.datas[i].size); + } + } } static void @@ -884,6 +913,10 @@ copy_meta (SpaProxy *this, SpaProxyPort *port, uint32_t buffer_id) } for (i = 0; i < b->outbuf->n_datas; i++) { b->buffer.datas[i].size = b->outbuf->datas[i].size; + if (b->datas[i].type == SPA_DATA_TYPE_MEMPTR) { + fprintf (stderr, "memcpy out %zd\n", b->outbuf->datas[i].size); + memcpy (b->datas[i].data, b->outbuf->datas[i].data, b->outbuf->datas[i].size); + } } } @@ -911,13 +944,13 @@ spa_proxy_node_port_push_input (SpaNode *node, spa_control_builder_init_into (&builder, buf, sizeof(buf), NULL, 0); for (i = 0; i < n_info; i++) { - if (!CHECK_PORT_ID_IN (this, info[i].port_id)) { + if (!CHECK_IN_PORT (this, SPA_DIRECTION_INPUT, info[i].port_id)) { printf ("invalid port %d\n", info[i].port_id); info[i].status = SPA_RESULT_INVALID_PORT; have_error = true; continue; } - port = &this->ports[info[i].port_id]; + port = &this->in_ports[info[i].port_id]; if (!port->format) { info[i].status = SPA_RESULT_NO_FORMAT; @@ -935,6 +968,7 @@ spa_proxy_node_port_push_input (SpaNode *node, copy_meta (this, port, info[i].buffer_id); + pb.direction = SPA_DIRECTION_INPUT; pb.port_id = info[i].port_id; pb.buffer_id = info[i].buffer_id; spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_PROCESS_BUFFER, &pb); @@ -973,14 +1007,14 @@ spa_proxy_node_port_pull_output (SpaNode *node, this = (SpaProxy *) node->handle; for (i = 0; i < n_info; i++) { - if (!CHECK_PORT_ID_OUT (this, info[i].port_id)) { + if (!CHECK_OUT_PORT (this, SPA_DIRECTION_OUTPUT, info[i].port_id)) { fprintf (stderr, "invalid port %u\n", info[i].port_id); info[i].status = SPA_RESULT_INVALID_PORT; have_error = true; continue; } - port = &this->ports[info[i].port_id]; + port = &this->out_ports[info[i].port_id]; if (!port->format) { info[i].status = SPA_RESULT_NO_FORMAT; @@ -1001,8 +1035,50 @@ spa_proxy_node_port_pull_output (SpaNode *node, return SPA_RESULT_OK; } +static SpaResult +spa_proxy_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + SpaProxy *this; + SpaControlBuilder builder; + SpaControl control; + uint8_t buf[128]; + SpaResult res; + SpaControlCmdNodeEvent cne; + SpaNodeEvent ne; + SpaNodeEventReuseBuffer rb; + + if (node == NULL || node->handle == NULL) + return SPA_RESULT_INVALID_ARGUMENTS; + + this = (SpaProxy *) node->handle; + + if (!CHECK_OUT_PORT (this, SPA_DIRECTION_OUTPUT, port_id)) + return SPA_RESULT_INVALID_PORT; + + /* send start */ + spa_control_builder_init_into (&builder, buf, sizeof (buf), NULL, 0); + cne.event = ≠ + ne.type = SPA_NODE_EVENT_TYPE_REUSE_BUFFER; + ne.data = &rb; + ne.size = sizeof (rb); + rb.port_id = port_id; + rb.buffer_id = buffer_id; + spa_control_builder_add_cmd (&builder, SPA_CONTROL_CMD_NODE_EVENT, &cne); + spa_control_builder_end (&builder, &control); + + if ((res = spa_control_write (&control, this->fds[0].fd)) < 0) + fprintf (stderr, "proxy %p: error writing control %d\n", this, res); + + spa_control_clear (&control); + + return res; +} + static SpaResult spa_proxy_node_port_push_event (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaNodeEvent *event) { @@ -1092,13 +1168,13 @@ parse_control (SpaProxy *this, if (spa_control_iter_parse_cmd (&it, &pu) < 0) break; - if (pu.port_id >= MAX_PORTS) + if (!CHECK_PORT_ID (this, pu.direction, pu.port_id)) break; remove = (pu.change_mask == 0); if (remove) { - do_uninit_port (this, pu.port_id); + do_uninit_port (this, pu.direction, pu.port_id); } else { do_update_port (this, &pu); } @@ -1142,10 +1218,16 @@ parse_control (SpaProxy *this, if (spa_control_iter_parse_cmd (&it, &cmd) < 0) break; - port = &this->ports[cmd.port_id]; + if (!CHECK_PORT (this, cmd.direction, cmd.port_id)) + break; + + port = cmd.direction == SPA_DIRECTION_INPUT ? &this->in_ports[cmd.port_id] : &this->out_ports[cmd.port_id]; if (port->buffer_id != SPA_ID_INVALID) fprintf (stderr, "proxy %p: unprocessed buffer: %d\n", this, port->buffer_id); + + copy_meta_in (this, port, cmd.buffer_id); + port->buffer_id = cmd.buffer_id; break; } @@ -1208,10 +1290,10 @@ static const SpaNode proxy_node = { spa_proxy_node_port_set_props, spa_proxy_node_port_use_buffers, spa_proxy_node_port_alloc_buffers, - spa_proxy_node_port_reuse_buffer, spa_proxy_node_port_get_status, spa_proxy_node_port_push_input, spa_proxy_node_port_pull_output, + spa_proxy_node_port_reuse_buffer, spa_proxy_node_port_push_event, }; @@ -1247,9 +1329,13 @@ proxy_clear (SpaHandle *handle) this = (SpaProxy *) handle; - for (i = 0; i < MAX_PORTS; i++) { - if (this->ports[i].valid) - clear_port (this, &this->ports[i], i); + for (i = 0; i < MAX_INPUTS; i++) { + if (this->in_ports[i].valid) + clear_port (this, &this->in_ports[i], SPA_DIRECTION_INPUT, i); + } + for (i = 0; i < MAX_OUTPUTS; i++) { + if (this->out_ports[i].valid) + clear_port (this, &this->out_ports[i], SPA_DIRECTION_OUTPUT, i); } return SPA_RESULT_OK; diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c index 069de19cd..0304f9d0f 100644 --- a/spa/plugins/v4l2/v4l2-source.c +++ b/spa/plugins/v4l2/v4l2-source.c @@ -127,6 +127,7 @@ struct _SpaV4l2Source { SpaV4l2State state[1]; }; +#define CHECK_PORT(this, direction, port_id) ((direction) == SPA_DIRECTION_OUTPUT && (port_id) == 0) static void update_state (SpaV4l2Source *this, SpaNodeState state) @@ -324,6 +325,7 @@ spa_v4l2_source_node_get_port_ids (SpaNode *node, static SpaResult spa_v4l2_source_node_add_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -331,6 +333,7 @@ spa_v4l2_source_node_add_port (SpaNode *node, static SpaResult spa_v4l2_source_node_remove_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -355,6 +358,7 @@ spa_v4l2_format_init (V4l2Format *f) static SpaResult spa_v4l2_source_node_port_enum_formats (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaFormat **format, const SpaFormat *filter, @@ -368,7 +372,7 @@ spa_v4l2_source_node_port_enum_formats (SpaNode *node, this = (SpaV4l2Source *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; res = spa_v4l2_enum_format (this, format, filter, state); @@ -378,6 +382,7 @@ spa_v4l2_source_node_port_enum_formats (SpaNode *node, static SpaResult spa_v4l2_source_node_port_set_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaPortFormatFlags flags, const SpaFormat *format) @@ -393,7 +398,7 @@ spa_v4l2_source_node_port_set_format (SpaNode *node, this = (SpaV4l2Source *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; state = &this->state[port_id]; @@ -450,6 +455,7 @@ spa_v4l2_source_node_port_set_format (SpaNode *node, static SpaResult spa_v4l2_source_node_port_get_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaFormat **format) { @@ -461,7 +467,7 @@ spa_v4l2_source_node_port_get_format (SpaNode *node, this = (SpaV4l2Source *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; state = &this->state[port_id]; @@ -476,6 +482,7 @@ spa_v4l2_source_node_port_get_format (SpaNode *node, static SpaResult spa_v4l2_source_node_port_get_info (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortInfo **info) { @@ -486,7 +493,7 @@ spa_v4l2_source_node_port_get_info (SpaNode *node, this = (SpaV4l2Source *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; *info = &this->state[port_id].info; @@ -495,15 +502,17 @@ spa_v4l2_source_node_port_get_info (SpaNode *node, } static SpaResult -spa_v4l2_source_node_port_get_props (SpaNode *node, - uint32_t port_id, - SpaProps **props) +spa_v4l2_source_node_port_get_props (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaProps **props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_v4l2_source_node_port_set_props (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaProps *props) { @@ -512,6 +521,7 @@ spa_v4l2_source_node_port_set_props (SpaNode *node, static SpaResult spa_v4l2_source_node_port_use_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaBuffer **buffers, uint32_t n_buffers) @@ -525,7 +535,7 @@ spa_v4l2_source_node_port_use_buffers (SpaNode *node, this = (SpaV4l2Source *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; state = &this->state[port_id]; @@ -552,6 +562,7 @@ spa_v4l2_source_node_port_use_buffers (SpaNode *node, static SpaResult spa_v4l2_source_node_port_alloc_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaAllocParam **params, unsigned int n_params, @@ -567,7 +578,7 @@ spa_v4l2_source_node_port_alloc_buffers (SpaNode *node, this = (SpaV4l2Source *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; state = &this->state[port_id]; @@ -587,38 +598,9 @@ spa_v4l2_source_node_port_alloc_buffers (SpaNode *node, return res; } -static SpaResult -spa_v4l2_source_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) -{ - SpaV4l2Source *this; - SpaV4l2State *state; - SpaResult res; - - if (node == NULL || node->handle == NULL) - return SPA_RESULT_INVALID_ARGUMENTS; - - this = (SpaV4l2Source *) node->handle; - - if (port_id != 0) - return SPA_RESULT_INVALID_PORT; - - state = &this->state[port_id]; - - if (state->n_buffers == 0) - return SPA_RESULT_NO_BUFFERS; - - if (buffer_id >= state->n_buffers) - return SPA_RESULT_INVALID_BUFFER_ID; - - res = spa_v4l2_buffer_recycle (this, buffer_id); - - return res; -} - static SpaResult spa_v4l2_source_node_port_get_status (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortStatus **status) { @@ -629,7 +611,7 @@ spa_v4l2_source_node_port_get_status (SpaNode *node, this = (SpaV4l2Source *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; *status = &this->state[port_id].status; @@ -693,8 +675,39 @@ spa_v4l2_source_node_port_pull_output (SpaNode *node, return SPA_RESULT_OK; } +static SpaResult +spa_v4l2_source_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + SpaV4l2Source *this; + SpaV4l2State *state; + SpaResult res; + + if (node == NULL || node->handle == NULL) + return SPA_RESULT_INVALID_ARGUMENTS; + + this = (SpaV4l2Source *) node->handle; + + if (port_id != 0) + return SPA_RESULT_INVALID_PORT; + + state = &this->state[port_id]; + + if (state->n_buffers == 0) + return SPA_RESULT_NO_BUFFERS; + + if (buffer_id >= state->n_buffers) + return SPA_RESULT_INVALID_BUFFER_ID; + + res = spa_v4l2_buffer_recycle (this, buffer_id); + + return res; +} + static SpaResult spa_v4l2_source_node_port_push_event (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaNodeEvent *event) { @@ -723,10 +736,10 @@ static const SpaNode v4l2source_node = { spa_v4l2_source_node_port_set_props, spa_v4l2_source_node_port_use_buffers, spa_v4l2_source_node_port_alloc_buffers, - spa_v4l2_source_node_port_reuse_buffer, spa_v4l2_source_node_port_get_status, spa_v4l2_source_node_port_push_input, spa_v4l2_source_node_port_pull_output, + spa_v4l2_source_node_port_reuse_buffer, spa_v4l2_source_node_port_push_event, }; diff --git a/spa/plugins/videotestsrc/videotestsrc.c b/spa/plugins/videotestsrc/videotestsrc.c index 6283119b9..b6ebf202f 100644 --- a/spa/plugins/videotestsrc/videotestsrc.c +++ b/spa/plugins/videotestsrc/videotestsrc.c @@ -96,6 +96,8 @@ struct _SpaVideoTestSrc { SpaQueue ready; }; +#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) + #define DEFAULT_LIVE true enum { @@ -418,6 +420,7 @@ spa_videotestsrc_node_get_port_ids (SpaNode *node, static SpaResult spa_videotestsrc_node_add_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -425,6 +428,7 @@ spa_videotestsrc_node_add_port (SpaNode *node, static SpaResult spa_videotestsrc_node_remove_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -432,6 +436,7 @@ spa_videotestsrc_node_remove_port (SpaNode *node, static SpaResult spa_videotestsrc_node_port_enum_formats (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaFormat **format, const SpaFormat *filter, @@ -445,7 +450,7 @@ spa_videotestsrc_node_port_enum_formats (SpaNode *node, this = (SpaVideoTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; index = (*state == NULL ? 0 : *(int*)state); @@ -483,6 +488,7 @@ clear_buffers (SpaVideoTestSrc *this) static SpaResult spa_videotestsrc_node_port_set_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaPortFormatFlags flags, const SpaFormat *format) @@ -495,7 +501,7 @@ spa_videotestsrc_node_port_set_format (SpaNode *node, this = (SpaVideoTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (format == NULL) { @@ -539,6 +545,7 @@ spa_videotestsrc_node_port_set_format (SpaNode *node, static SpaResult spa_videotestsrc_node_port_get_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaFormat **format) { @@ -549,7 +556,7 @@ spa_videotestsrc_node_port_get_format (SpaNode *node, this = (SpaVideoTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (!this->have_format) @@ -562,6 +569,7 @@ spa_videotestsrc_node_port_get_format (SpaNode *node, static SpaResult spa_videotestsrc_node_port_get_info (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortInfo **info) { @@ -572,7 +580,7 @@ spa_videotestsrc_node_port_get_info (SpaNode *node, this = (SpaVideoTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; *info = &this->info; @@ -581,15 +589,17 @@ spa_videotestsrc_node_port_get_info (SpaNode *node, } static SpaResult -spa_videotestsrc_node_port_get_props (SpaNode *node, - uint32_t port_id, - SpaProps **props) +spa_videotestsrc_node_port_get_props (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaProps **props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_videotestsrc_node_port_set_props (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaProps *props) { @@ -598,6 +608,7 @@ spa_videotestsrc_node_port_set_props (SpaNode *node, static SpaResult spa_videotestsrc_node_port_use_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaBuffer **buffers, uint32_t n_buffers) @@ -609,7 +620,7 @@ spa_videotestsrc_node_port_use_buffers (SpaNode *node, this = (SpaVideoTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (!this->have_format) @@ -667,6 +678,7 @@ spa_videotestsrc_node_port_use_buffers (SpaNode *node, static SpaResult spa_videotestsrc_node_port_alloc_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaAllocParam **params, uint32_t n_params, @@ -681,7 +693,7 @@ spa_videotestsrc_node_port_alloc_buffers (SpaNode *node, this = (SpaVideoTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (!this->have_format) @@ -698,44 +710,9 @@ spa_videotestsrc_node_port_alloc_buffers (SpaNode *node, return SPA_RESULT_OK; } -static SpaResult -spa_videotestsrc_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) -{ - SpaVideoTestSrc *this; - VTSBuffer *b; - - if (node == NULL || node->handle == NULL) - return SPA_RESULT_INVALID_ARGUMENTS; - - this = (SpaVideoTestSrc *) node->handle; - - if (port_id != 0) - return SPA_RESULT_INVALID_PORT; - - if (!this->have_buffers) - return SPA_RESULT_NO_BUFFERS; - - if (buffer_id >= this->n_buffers) - return SPA_RESULT_INVALID_BUFFER_ID; - - b = &this->buffers[buffer_id]; - if (!b->outstanding) - return SPA_RESULT_OK; - - b->outstanding = false; - b->next = NULL; - SPA_QUEUE_PUSH_TAIL (&this->empty, VTSBuffer, next, b); - - if (this->empty.length == 1 && !this->props[1].live) - update_poll_enabled (this, true); - - return SPA_RESULT_OK; -} - static SpaResult spa_videotestsrc_node_port_get_status (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortStatus **status) { @@ -746,7 +723,7 @@ spa_videotestsrc_node_port_get_status (SpaNode *node, this = (SpaVideoTestSrc *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (!this->have_format) @@ -811,8 +788,45 @@ spa_videotestsrc_node_port_pull_output (SpaNode *node, return SPA_RESULT_OK; } +static SpaResult +spa_videotestsrc_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + SpaVideoTestSrc *this; + VTSBuffer *b; + + if (node == NULL || node->handle == NULL) + return SPA_RESULT_INVALID_ARGUMENTS; + + this = (SpaVideoTestSrc *) node->handle; + + if (port_id != 0) + return SPA_RESULT_INVALID_PORT; + + if (!this->have_buffers) + return SPA_RESULT_NO_BUFFERS; + + if (buffer_id >= this->n_buffers) + return SPA_RESULT_INVALID_BUFFER_ID; + + b = &this->buffers[buffer_id]; + if (!b->outstanding) + return SPA_RESULT_OK; + + b->outstanding = false; + b->next = NULL; + SPA_QUEUE_PUSH_TAIL (&this->empty, VTSBuffer, next, b); + + if (this->empty.length == 1 && !this->props[1].live) + update_poll_enabled (this, true); + + return SPA_RESULT_OK; +} + static SpaResult spa_videotestsrc_node_port_push_event (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaNodeEvent *event) { @@ -840,10 +854,10 @@ static const SpaNode videotestsrc_node = { spa_videotestsrc_node_port_set_props, spa_videotestsrc_node_port_use_buffers, spa_videotestsrc_node_port_alloc_buffers, - spa_videotestsrc_node_port_reuse_buffer, spa_videotestsrc_node_port_get_status, spa_videotestsrc_node_port_push_input, spa_videotestsrc_node_port_pull_output, + spa_videotestsrc_node_port_reuse_buffer, spa_videotestsrc_node_port_push_event, }; diff --git a/spa/plugins/volume/volume.c b/spa/plugins/volume/volume.c index 2f9a6b79b..7116cd6cc 100644 --- a/spa/plugins/volume/volume.c +++ b/spa/plugins/volume/volume.c @@ -53,9 +53,14 @@ struct _SpaVolume { SpaFormatAudio query_format; SpaFormatAudio current_format; - SpaVolumePort ports[2]; + SpaVolumePort in_ports[1]; + SpaVolumePort out_ports[1]; }; +#define CHECK_IN_PORT(this,d,p) ((d) == SPA_DIRECTION_INPUT && (p) == 0) +#define CHECK_OUT_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) +#define CHECK_PORT(this,d,p) ((p) == 0) + static const double default_volume = 1.0; static const double min_volume = 0.0; static const double max_volume = 10.0; @@ -103,7 +108,7 @@ update_state (SpaVolume *this, SpaNodeState state) static SpaResult spa_volume_node_get_props (SpaNode *node, - SpaProps **props) + SpaProps **props) { SpaVolume *this; @@ -120,7 +125,7 @@ spa_volume_node_get_props (SpaNode *node, static SpaResult spa_volume_node_set_props (SpaNode *node, - const SpaProps *props) + const SpaProps *props) { SpaVolume *this; SpaVolumeProps *p; @@ -203,10 +208,10 @@ spa_volume_node_get_n_ports (SpaNode *node, if (n_input_ports) *n_input_ports = 1; - if (n_output_ports) - *n_output_ports = 1; if (max_input_ports) *max_input_ports = 1; + if (n_output_ports) + *n_output_ports = 1; if (max_output_ports) *max_output_ports = 1; @@ -226,7 +231,7 @@ spa_volume_node_get_port_ids (SpaNode *node, if (n_input_ports > 0 && input_ids) input_ids[0] = 0; if (n_output_ports > 0 && output_ids) - output_ids[0] = 1; + output_ids[0] = 0; return SPA_RESULT_OK; } @@ -234,6 +239,7 @@ spa_volume_node_get_port_ids (SpaNode *node, static SpaResult spa_volume_node_add_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -241,6 +247,7 @@ spa_volume_node_add_port (SpaNode *node, static SpaResult spa_volume_node_remove_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -248,6 +255,7 @@ spa_volume_node_remove_port (SpaNode *node, static SpaResult spa_volume_node_port_enum_formats (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaFormat **format, const SpaFormat *filter, @@ -261,7 +269,7 @@ spa_volume_node_port_enum_formats (SpaNode *node, this = (SpaVolume *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; index = (*state == NULL ? 0 : *(int*)state); @@ -283,6 +291,7 @@ spa_volume_node_port_enum_formats (SpaNode *node, static SpaResult spa_volume_node_port_set_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaPortFormatFlags flags, const SpaFormat *format) @@ -296,10 +305,10 @@ spa_volume_node_port_set_format (SpaNode *node, this = (SpaVolume *) node->handle; - if (port_id >= 2) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; if (format == NULL) { port->have_format = false; @@ -316,6 +325,7 @@ spa_volume_node_port_set_format (SpaNode *node, static SpaResult spa_volume_node_port_get_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaFormat **format) { @@ -327,10 +337,10 @@ spa_volume_node_port_get_format (SpaNode *node, this = (SpaVolume *) node->handle; - if (port_id >= 2) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; if (!port->have_format) return SPA_RESULT_NO_FORMAT; @@ -342,6 +352,7 @@ spa_volume_node_port_get_format (SpaNode *node, static SpaResult spa_volume_node_port_get_info (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortInfo **info) { @@ -353,33 +364,36 @@ spa_volume_node_port_get_info (SpaNode *node, this = (SpaVolume *) node->handle; - if (port_id >= 2) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; *info = &port->info; return SPA_RESULT_OK; } static SpaResult -spa_volume_node_port_get_props (SpaNode *node, - uint32_t port_id, - SpaProps **props) +spa_volume_node_port_get_props (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaProps **props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult -spa_volume_node_port_set_props (SpaNode *node, - uint32_t port_id, - const SpaProps *props) +spa_volume_node_port_set_props (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + const SpaProps *props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_volume_node_port_use_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaBuffer **buffers, uint32_t n_buffers) @@ -389,6 +403,7 @@ spa_volume_node_port_use_buffers (SpaNode *node, static SpaResult spa_volume_node_port_alloc_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaAllocParam **params, uint32_t n_params, @@ -398,16 +413,9 @@ spa_volume_node_port_alloc_buffers (SpaNode *node, return SPA_RESULT_NOT_IMPLEMENTED; } -static SpaResult -spa_volume_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) -{ - return SPA_RESULT_NOT_IMPLEMENTED; -} - static SpaResult spa_volume_node_port_get_status (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortStatus **status) { @@ -419,10 +427,10 @@ spa_volume_node_port_get_status (SpaNode *node, this = (SpaVolume *) node->handle; - if (port_id >= 2) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; - port = &this->ports[port_id]; + port = direction == SPA_DIRECTION_INPUT ? &this->in_ports[port_id] : &this->out_ports[port_id]; if (!port->have_format) return SPA_RESULT_NO_FORMAT; @@ -458,7 +466,7 @@ spa_volume_node_port_push_input (SpaNode *node, continue; } - port = &this->ports[info[i].port_id]; + port = &this->in_ports[info[i].port_id]; buffer = port->buffers[info[i].buffer_id]; if (buffer == NULL) { @@ -481,8 +489,8 @@ spa_volume_node_port_push_input (SpaNode *node, } port->buffer = buffer; - this->ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_NEED_INPUT; - this->ports[1].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; + this->in_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_NEED_INPUT; + this->out_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; } info[i].status = SPA_RESULT_OK; } @@ -532,19 +540,19 @@ spa_volume_node_port_pull_output (SpaNode *node, this = (SpaVolume *) node->handle; - if (info->port_id != 1) + if (info[0].port_id != 0) return SPA_RESULT_INVALID_PORT; - port = &this->ports[info[0].port_id]; + port = &this->out_ports[info[0].port_id]; if (!port->have_format) return SPA_RESULT_NO_FORMAT; - if (this->ports[0].buffer == NULL) + if (this->in_ports[0].buffer == NULL) return SPA_RESULT_NEED_MORE_INPUT; volume = this->props[1].volume; - sbuf = this->ports[0].buffer; + sbuf = this->in_ports[0].buffer; dbuf = find_free_buffer (this, port); si = di = 0; @@ -582,17 +590,26 @@ spa_volume_node_port_pull_output (SpaNode *node, if (sbuf != dbuf) release_buffer (this, sbuf); - this->ports[0].buffer = NULL; + this->in_ports[0].buffer = NULL; info->buffer_id = dbuf->id; - this->ports[0].status.flags |= SPA_PORT_STATUS_FLAG_NEED_INPUT; - this->ports[1].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; + this->in_ports[0].status.flags |= SPA_PORT_STATUS_FLAG_NEED_INPUT; + this->out_ports[0].status.flags &= ~SPA_PORT_STATUS_FLAG_HAVE_OUTPUT; return SPA_RESULT_OK; } +static SpaResult +spa_volume_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + return SPA_RESULT_NOT_IMPLEMENTED; +} + static SpaResult spa_volume_node_port_push_event (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaNodeEvent *event) { @@ -620,10 +637,10 @@ static const SpaNode volume_node = { spa_volume_node_port_set_props, spa_volume_node_port_use_buffers, spa_volume_node_port_alloc_buffers, - spa_volume_node_port_reuse_buffer, spa_volume_node_port_get_status, spa_volume_node_port_push_input, spa_volume_node_port_pull_output, + spa_volume_node_port_reuse_buffer, spa_volume_node_port_push_event, }; @@ -676,14 +693,14 @@ volume_init (const SpaHandleFactory *factory, this->props[1].props.prop_info = prop_info; reset_volume_props (&this->props[1]); - this->ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | - SPA_PORT_INFO_FLAG_IN_PLACE; - this->ports[1].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS | - SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | - SPA_PORT_INFO_FLAG_NO_REF; + this->in_ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | + SPA_PORT_INFO_FLAG_IN_PLACE; + this->out_ports[0].info.flags = SPA_PORT_INFO_FLAG_CAN_ALLOC_BUFFERS | + SPA_PORT_INFO_FLAG_CAN_USE_BUFFERS | + SPA_PORT_INFO_FLAG_NO_REF; - this->ports[0].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT; - this->ports[1].status.flags = SPA_PORT_STATUS_FLAG_NONE; + this->in_ports[0].status.flags = SPA_PORT_STATUS_FLAG_NEED_INPUT; + this->out_ports[0].status.flags = SPA_PORT_STATUS_FLAG_NONE; return SPA_RESULT_OK; } diff --git a/spa/plugins/xv/xv-sink.c b/spa/plugins/xv/xv-sink.c index d95abf760..bd25deef1 100644 --- a/spa/plugins/xv/xv-sink.c +++ b/spa/plugins/xv/xv-sink.c @@ -86,6 +86,8 @@ struct _SpaXvSink { }; +#define CHECK_PORT(this,d,p) ((d) == SPA_DIRECTION_OUTPUT && (p) == 0) + #include "xv-utils.c" enum { @@ -258,6 +260,7 @@ spa_xv_sink_node_get_port_ids (SpaNode *node, static SpaResult spa_xv_sink_node_add_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -265,6 +268,7 @@ spa_xv_sink_node_add_port (SpaNode *node, static SpaResult spa_xv_sink_node_remove_port (SpaNode *node, + SpaDirection direction, uint32_t port_id) { return SPA_RESULT_NOT_IMPLEMENTED; @@ -272,6 +276,7 @@ spa_xv_sink_node_remove_port (SpaNode *node, static SpaResult spa_xv_sink_node_port_enum_formats (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaFormat **format, const SpaFormat *filter, @@ -285,7 +290,7 @@ spa_xv_sink_node_port_enum_formats (SpaNode *node, this = (SpaXvSink *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; index = (*state == NULL ? 0 : *(int*)state); @@ -307,6 +312,7 @@ spa_xv_sink_node_port_enum_formats (SpaNode *node, static SpaResult spa_xv_sink_node_port_set_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaPortFormatFlags flags, const SpaFormat *format) @@ -321,7 +327,7 @@ spa_xv_sink_node_port_set_format (SpaNode *node, this = (SpaXvSink *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (format == NULL) { @@ -355,6 +361,7 @@ spa_xv_sink_node_port_set_format (SpaNode *node, static SpaResult spa_xv_sink_node_port_get_format (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaFormat **format) { @@ -365,7 +372,7 @@ spa_xv_sink_node_port_get_format (SpaNode *node, this = (SpaXvSink *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; if (this->current_format == NULL) @@ -378,6 +385,7 @@ spa_xv_sink_node_port_get_format (SpaNode *node, static SpaResult spa_xv_sink_node_port_get_info (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortInfo **info) { @@ -388,7 +396,7 @@ spa_xv_sink_node_port_get_info (SpaNode *node, this = (SpaXvSink *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; *info = &this->info; @@ -397,15 +405,17 @@ spa_xv_sink_node_port_get_info (SpaNode *node, } static SpaResult -spa_xv_sink_node_port_get_props (SpaNode *node, - uint32_t port_id, - SpaProps **props) +spa_xv_sink_node_port_get_props (SpaNode *node, + SpaDirection direction, + uint32_t port_id, + SpaProps **props) { return SPA_RESULT_NOT_IMPLEMENTED; } static SpaResult spa_xv_sink_node_port_set_props (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaProps *props) { @@ -414,6 +424,7 @@ spa_xv_sink_node_port_set_props (SpaNode *node, static SpaResult spa_xv_sink_node_port_use_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaBuffer **buffers, uint32_t n_buffers) @@ -423,6 +434,7 @@ spa_xv_sink_node_port_use_buffers (SpaNode *node, static SpaResult spa_xv_sink_node_port_alloc_buffers (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaAllocParam **params, uint32_t n_params, @@ -432,16 +444,9 @@ spa_xv_sink_node_port_alloc_buffers (SpaNode *node, return SPA_RESULT_NOT_IMPLEMENTED; } -static SpaResult -spa_xv_sink_node_port_reuse_buffer (SpaNode *node, - uint32_t port_id, - uint32_t buffer_id) -{ - return SPA_RESULT_NOT_IMPLEMENTED; -} - static SpaResult spa_xv_sink_node_port_get_status (SpaNode *node, + SpaDirection direction, uint32_t port_id, const SpaPortStatus **status) { @@ -452,7 +457,7 @@ spa_xv_sink_node_port_get_status (SpaNode *node, this = (SpaXvSink *) node->handle; - if (port_id != 0) + if (!CHECK_PORT (this, direction, port_id)) return SPA_RESULT_INVALID_PORT; *status = &this->status; @@ -476,8 +481,17 @@ spa_xv_sink_node_port_pull_output (SpaNode *node, return SPA_RESULT_INVALID_PORT; } +static SpaResult +spa_xv_sink_node_port_reuse_buffer (SpaNode *node, + uint32_t port_id, + uint32_t buffer_id) +{ + return SPA_RESULT_NOT_IMPLEMENTED; +} + static SpaResult spa_xv_sink_node_port_push_event (SpaNode *node, + SpaDirection direction, uint32_t port_id, SpaNodeEvent *event) { @@ -505,10 +519,10 @@ static const SpaNode xvsink_node = { spa_xv_sink_node_port_set_props, spa_xv_sink_node_port_use_buffers, spa_xv_sink_node_port_alloc_buffers, - spa_xv_sink_node_port_reuse_buffer, spa_xv_sink_node_port_get_status, spa_xv_sink_node_port_push_input, spa_xv_sink_node_port_pull_output, + spa_xv_sink_node_port_reuse_buffer, spa_xv_sink_node_port_push_event, }; diff --git a/spa/tests/test-mixer.c b/spa/tests/test-mixer.c index 62b8efa58..d4506a82a 100644 --- a/spa/tests/test-mixer.c +++ b/spa/tests/test-mixer.c @@ -223,7 +223,7 @@ negotiate_formats (AppData *data) SpaPropValue value; void *state = NULL; - if ((res = spa_node_port_enum_formats (data->sink, 0, &format, NULL, &state)) < 0) + if ((res = spa_node_port_enum_formats (data->sink, SPA_DIRECTION_INPUT, 0, &format, NULL, &state)) < 0) return res; props = &format->props; @@ -244,30 +244,30 @@ negotiate_formats (AppData *data) if ((res = spa_props_set_value (props, spa_props_index_for_id (props, SPA_PROP_ID_AUDIO_CHANNELS), &value)) < 0) return res; - if ((res = spa_node_port_set_format (data->sink, 0, false, format)) < 0) + if ((res = spa_node_port_set_format (data->sink, SPA_DIRECTION_INPUT, 0, false, format)) < 0) return res; - if ((res = spa_node_port_set_format (data->mix, 128, false, format)) < 0) + if ((res = spa_node_port_set_format (data->mix, SPA_DIRECTION_OUTPUT, 0, false, format)) < 0) return res; data->mix_ports[0] = 0; - if ((res = spa_node_add_port (data->mix, 0)) < 0) + if ((res = spa_node_add_port (data->mix, SPA_DIRECTION_INPUT, 0)) < 0) return res; - if ((res = spa_node_port_set_format (data->mix, data->mix_ports[0], false, format)) < 0) + if ((res = spa_node_port_set_format (data->mix, SPA_DIRECTION_INPUT, data->mix_ports[0], false, format)) < 0) return res; - if ((res = spa_node_port_set_format (data->source1, 0, false, format)) < 0) + if ((res = spa_node_port_set_format (data->source1, SPA_DIRECTION_OUTPUT, 0, false, format)) < 0) return res; data->mix_ports[1] = 1; - if ((res = spa_node_add_port (data->mix, 1)) < 0) + if ((res = spa_node_add_port (data->mix, SPA_DIRECTION_INPUT, 1)) < 0) return res; - if ((res = spa_node_port_set_format (data->mix, data->mix_ports[1], false, format)) < 0) + if ((res = spa_node_port_set_format (data->mix, SPA_DIRECTION_INPUT, data->mix_ports[1], false, format)) < 0) return res; - if ((res = spa_node_port_set_format (data->source2, 0, false, format)) < 0) + if ((res = spa_node_port_set_format (data->source2, SPA_DIRECTION_OUTPUT, 0, false, format)) < 0) return res; diff --git a/spa/tests/test-v4l2.c b/spa/tests/test-v4l2.c index 8a3a3b941..67eb12461 100644 --- a/spa/tests/test-v4l2.c +++ b/spa/tests/test-v4l2.c @@ -273,7 +273,7 @@ alloc_buffers (AppData *data) } data->n_buffers = MAX_BUFFERS; - spa_node_port_use_buffers (data->source, 0, data->bp, MAX_BUFFERS); + spa_node_port_use_buffers (data->source, SPA_DIRECTION_OUTPUT, 0, data->bp, MAX_BUFFERS); } typedef struct { @@ -320,10 +320,10 @@ negotiate_formats (AppData *data) f.framerate.denom = 1; #endif - if ((res = spa_node_port_set_format (data->source, 0, false, &f.fmt)) < 0) + if ((res = spa_node_port_set_format (data->source, SPA_DIRECTION_OUTPUT, 0, false, &f.fmt)) < 0) return res; - if ((res = spa_node_port_get_info (data->source, 0, &info)) < 0) + if ((res = spa_node_port_get_info (data->source, SPA_DIRECTION_OUTPUT, 0, &info)) < 0) return res; spa_debug_port_info (info); @@ -342,7 +342,7 @@ negotiate_formats (AppData *data) return -1; } n_buffers = MAX_BUFFERS; - if ((res = spa_node_port_alloc_buffers (data->source, 0, NULL, 0, data->bp, &n_buffers)) < 0) { + if ((res = spa_node_port_alloc_buffers (data->source, SPA_DIRECTION_OUTPUT, 0, NULL, 0, data->bp, &n_buffers)) < 0) { printf ("can't allocate buffers: %s\n", SDL_GetError ()); return -1; } diff --git a/spa/tools/spa-inspect.c b/spa/tools/spa-inspect.c index c9d3278a4..c657a540b 100644 --- a/spa/tools/spa-inspect.c +++ b/spa/tools/spa-inspect.c @@ -26,14 +26,37 @@ #include #include + +static void +inspect_port (SpaNode *node, SpaDirection direction, uint32_t port_id) +{ + SpaResult res; + SpaFormat *format; + void *state = NULL; + SpaProps *props; + + while (true) { + if ((res = spa_node_port_enum_formats (node, direction, port_id, &format, NULL, &state)) < 0) { + if (res != SPA_RESULT_ENUM_END) + printf ("got error %d\n", res); + break; + } + if (format) + spa_debug_format (format); + } + if ((res = spa_node_port_get_props (node, direction, port_id, &props)) < 0) + printf ("port_get_props error: %d\n", res); + else + spa_debug_props (props, true); +} + static void inspect_node (SpaNode *node) { SpaResult res; + unsigned int i, n_input, max_input, n_output, max_output; + uint32_t *in_ports, *out_ports; SpaProps *props; - unsigned int n_input, max_input, n_output, max_output; - SpaFormat *format; - void *state = NULL; if ((res = spa_node_get_props (node, &props)) < 0) printf ("can't get properties: %d\n", res); @@ -45,19 +68,21 @@ inspect_node (SpaNode *node) else printf ("supported ports %d %d %d %d\n", n_input, max_input, n_output, max_output); - while (true) { - if ((res = spa_node_port_enum_formats (node, 0, &format, NULL, &state)) < 0) { - if (res != SPA_RESULT_ENUM_END) - printf ("got error %d\n", res); - break; - } - if (format) - spa_debug_format (format); + in_ports = alloca (n_input * sizeof (uint32_t)); + out_ports = alloca (n_input * sizeof (uint32_t)); + + if ((res = spa_node_get_port_ids (node, n_input, in_ports, n_output, out_ports)) < 0) + printf ("can't get port ids: %d\n", res); + + for (i = 0; i < n_input; i++) { + printf (" input port: %08x\n", in_ports[i]); + inspect_port (node, SPA_DIRECTION_INPUT, in_ports[i]); } - if ((res = spa_node_port_get_props (node, 0, &props)) < 0) - printf ("port_get_props error: %d\n", res); - else - spa_debug_props (props, true); + for (i = 0; i < n_output; i++) { + printf (" output port: %08x\n", out_ports[i]); + inspect_port (node, SPA_DIRECTION_OUTPUT, out_ports[i]); + } + } static void