node: remove node state

Remove the node state. The state of the node is based on the state
of the ports, which can be derived directly from calling the port
methods. Track this state in the Port instead.
Add a mixer module that puts a mixer in from of audio sinks. This allows
multiple clients to play on one sink (still has some bugs). do some
fixes in the mixer and the scheduler to make this work.
This commit is contained in:
Wim Taymans 2017-04-08 20:33:54 +02:00
parent 28389e05f3
commit d3682067fa
30 changed files with 618 additions and 509 deletions

View file

@ -41,13 +41,6 @@ reset_alsa_sink_props (SpaALSAProps *props)
props->min_latency = default_min_latency;
}
static void
update_state (SpaALSASink *this, SpaNodeState state)
{
spa_log_info (this->log, "update state %d", state);
this->node.state = state;
}
static SpaResult
spa_alsa_sink_node_get_props (SpaNode *node,
SpaProps **props)
@ -348,11 +341,7 @@ spa_alsa_sink_node_port_set_format (SpaNode *node,
PROP (&f[1], this->type.alloc_param_meta_enable.ringbufferAlign, SPA_POD_TYPE_INT, 16));
this->params[2] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam);
this->info.extra = NULL;
update_state (this, SPA_NODE_STATE_READY);
}
else
update_state (this, SPA_NODE_STATE_CONFIGURE);
return SPA_RESULT_OK;
}
@ -451,7 +440,6 @@ spa_alsa_sink_node_port_use_buffers (SpaNode *node,
if (n_buffers == 0) {
spa_alsa_pause (this, false);
spa_alsa_clear_buffers (this);
update_state (this, SPA_NODE_STATE_READY);
return SPA_RESULT_OK;
}
@ -480,8 +468,6 @@ spa_alsa_sink_node_port_use_buffers (SpaNode *node,
}
this->n_buffers = n_buffers;
update_state (this, SPA_NODE_STATE_PAUSED);
return SPA_RESULT_OK;
}
@ -552,14 +538,10 @@ spa_alsa_sink_node_port_send_command (SpaNode *node,
spa_return_val_if_fail (CHECK_PORT (this, direction, port_id), SPA_RESULT_INVALID_PORT);
if (SPA_COMMAND_TYPE (command) == this->type.command_node.Pause) {
if (SPA_RESULT_IS_OK (res = spa_alsa_pause (this, false))) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
res = spa_alsa_pause (this, false);
}
else if (SPA_COMMAND_TYPE (command) == this->type.command_node.Start) {
if (SPA_RESULT_IS_OK (res = spa_alsa_start (this, false))) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
res = spa_alsa_start (this, false);
}
else
res = SPA_RESULT_NOT_IMPLEMENTED;
@ -578,21 +560,25 @@ spa_alsa_sink_node_process_input (SpaNode *node)
this = SPA_CONTAINER_OF (node, SpaALSASink, node);
if ((input = this->io) == NULL)
if ((input = this->io) == NULL) {
return SPA_RESULT_OK;
}
if (!this->have_format) {
spa_log_error (this->log, "alsa-sink %p: no format", this);
input->status = SPA_RESULT_NO_FORMAT;
return SPA_RESULT_ERROR;
}
if (input->buffer_id >= this->n_buffers) {
spa_log_error (this->log, "alsa-sink %p: invalid buffer %u", this, input->buffer_id);
input->status = SPA_RESULT_INVALID_BUFFER_ID;
return SPA_RESULT_ERROR;
}
b = &this->buffers[input->buffer_id];
if (!b->outstanding) {
spa_log_error (this->log, "alsa-sink %p: buffer %u in use", this, input->buffer_id);
input->buffer_id = SPA_ID_INVALID;
input->status = SPA_RESULT_INVALID_BUFFER_ID;
return SPA_RESULT_ERROR;
@ -621,7 +607,6 @@ spa_alsa_sink_node_process_output (SpaNode *node)
static const SpaNode alsasink_node = {
sizeof (SpaNode),
NULL,
SPA_NODE_STATE_INIT,
spa_alsa_sink_node_get_props,
spa_alsa_sink_node_set_props,
spa_alsa_sink_node_send_command,
@ -725,8 +710,6 @@ alsa_sink_init (const SpaHandleFactory *factory,
}
}
update_state (this, SPA_NODE_STATE_CONFIGURE);
return SPA_RESULT_OK;
}

View file

@ -32,12 +32,6 @@
typedef struct _SpaALSAState SpaALSASource;
static void
update_state (SpaALSASource *this, SpaNodeState state)
{
this->node.state = state;
}
static const char default_device[] = "hw:0";
static const uint32_t default_min_latency = 1024;
@ -123,9 +117,7 @@ do_start (SpaLoop *loop,
SpaALSASource *this = user_data;
SpaResult res;
if (SPA_RESULT_IS_OK (res = spa_alsa_start (this, false))) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
res = spa_alsa_start (this, false);
if (async) {
SpaEventNodeAsyncComplete ac = SPA_EVENT_NODE_ASYNC_COMPLETE_INIT (this->type.event_node.AsyncComplete,
@ -151,9 +143,7 @@ do_pause (SpaLoop *loop,
SpaALSASource *this = user_data;
SpaResult res;
if (SPA_RESULT_IS_OK (res = spa_alsa_pause (this, false))) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
res = spa_alsa_pause (this, false);
if (async) {
SpaEventNodeAsyncComplete ac = SPA_EVENT_NODE_ASYNC_COMPLETE_INIT (this->type.event_node.AsyncComplete,
@ -390,10 +380,6 @@ spa_alsa_source_node_port_set_format (SpaNode *node,
this->params[1] = SPA_POD_BUILDER_DEREF (&b, f[0].ref, SpaAllocParam);
this->info.extra = NULL;
update_state (this, SPA_NODE_STATE_READY);
} else {
update_state (this, SPA_NODE_STATE_CONFIGURE);
}
return SPA_RESULT_OK;
@ -517,11 +503,6 @@ spa_alsa_source_node_port_use_buffers (SpaNode *node,
}
this->n_buffers = n_buffers;
if (this->n_buffers > 0)
update_state (this, SPA_NODE_STATE_PAUSED);
else
update_state (this, SPA_NODE_STATE_READY);
return SPA_RESULT_OK;
}
@ -609,13 +590,9 @@ spa_alsa_source_node_port_send_command (SpaNode *node,
spa_return_val_if_fail (CHECK_PORT (this, direction, port_id), SPA_RESULT_INVALID_PORT);
if (SPA_COMMAND_TYPE (command) == this->type.command_node.Pause) {
if (SPA_RESULT_IS_OK (res = spa_alsa_pause (this, false))) {
update_state (this, SPA_NODE_STATE_PAUSED);
}
res = spa_alsa_pause (this, false);
} else if (SPA_COMMAND_TYPE (command) == this->type.command_node.Start) {
if (SPA_RESULT_IS_OK (res = spa_alsa_start (this, false))) {
update_state (this, SPA_NODE_STATE_STREAMING);
}
res = spa_alsa_start (this, false);
} else
res = SPA_RESULT_NOT_IMPLEMENTED;
@ -648,7 +625,6 @@ spa_alsa_source_node_process_output (SpaNode *node)
static const SpaNode alsasource_node = {
sizeof (SpaNode),
NULL,
SPA_NODE_STATE_INIT,
spa_alsa_source_node_get_props,
spa_alsa_source_node_set_props,
spa_alsa_source_node_send_command,
@ -800,9 +776,6 @@ alsa_source_init (const SpaHandleFactory *factory,
snprintf (this->props.device, 63, "%s", info->items[i].value);
}
}
update_state (this, SPA_NODE_STATE_CONFIGURE);
return SPA_RESULT_OK;
}

View file

@ -332,18 +332,16 @@ pull_frames_queue (SpaALSAState *state,
snd_pcm_uframes_t frames)
{
snd_pcm_uframes_t total_frames = 0, to_write = frames;
SpaPortIO *io = state->io;
if (spa_list_is_empty (&state->ready)) {
SpaEvent event = SPA_EVENT_INIT (state->type.event_node.NeedInput);
SpaPortIO *io;
if ((io = state->io)) {
io->flags = SPA_PORT_IO_FLAG_RANGE;
io->status = SPA_RESULT_OK;
io->range.offset = state->sample_count * state->frame_size;
io->range.min_size = state->threshold * state->frame_size;
io->range.max_size = frames * state->frame_size;
}
io->flags = SPA_PORT_IO_FLAG_RANGE;
io->status = SPA_RESULT_OK;
io->range.offset = state->sample_count * state->frame_size;
io->range.min_size = state->threshold * state->frame_size;
io->range.max_size = frames * state->frame_size;
state->event_cb (&state->node, &event, state->user_data);
}
while (!spa_list_is_empty (&state->ready) && to_write > 0) {
@ -375,7 +373,6 @@ pull_frames_queue (SpaALSAState *state,
spa_log_trace (state->log, "alsa-util %p: reuse buffer %u", state, b->outbuf->id);
state->event_cb (&state->node, (SpaEvent *)&rb, state->user_data);
state->ready_offset = 0;
}
total_frames += n_frames;