improve state change

This commit is contained in:
Wim Taymans 2016-09-12 15:25:53 +02:00
parent f86b50d202
commit 36bcdaa4bc
4 changed files with 84 additions and 65 deletions

View file

@ -251,13 +251,13 @@ again:
spa_debug_format (format); spa_debug_format (format);
if (out_state == SPA_NODE_STATE_CONFIGURE) { 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, this->output_port, 0, format)) < 0) { if ((res = spa_node_port_set_format (this->output_node->node, this->output_port, 0, format)) < 0) {
g_warning ("error set format output: %d", res); g_warning ("error set format output: %d", res);
goto error; goto error;
} }
} } else if (in_state == SPA_NODE_STATE_CONFIGURE) {
g_debug ("link %p: doing set format on input", this);
if (in_state == SPA_NODE_STATE_CONFIGURE) {
if ((res = spa_node_port_set_format (this->input_node->node, this->input_port, 0, format)) < 0) { if ((res = spa_node_port_set_format (this->input_node->node, this->input_port, 0, format)) < 0) {
g_warning ("error set format input: %d", res); g_warning ("error set format input: %d", res);
goto error; goto error;
@ -376,6 +376,8 @@ do_start (PinosLink *this, SpaNodeState in_state, SpaNodeState out_state)
SpaResult res = SPA_RESULT_OK; SpaResult res = SPA_RESULT_OK;
cmd.type = SPA_NODE_COMMAND_START; cmd.type = SPA_NODE_COMMAND_START;
cmd.data = NULL;
cmd.size = 0;
if (in_state == SPA_NODE_STATE_PAUSED) { if (in_state == SPA_NODE_STATE_PAUSED) {
if ((res = spa_node_send_command (this->input_node->node, &cmd)) < 0) if ((res = spa_node_send_command (this->input_node->node, &cmd)) < 0)
g_warning ("got error %d", res); g_warning ("got error %d", res);
@ -397,7 +399,7 @@ check_states (PinosLink *this)
in_state = this->input_node->node->state; in_state = this->input_node->node->state;
out_state = this->output_node->node->state; out_state = this->output_node->node->state;
g_debug ("link %p: input %d, output %d", this, in_state, out_state); g_debug ("link %p: input state %d, output state %d", this, in_state, out_state);
if ((res = do_negotiate (this, in_state, out_state)) < 0) if ((res = do_negotiate (this, in_state, out_state)) < 0)
return res; return res;

View file

@ -276,6 +276,8 @@ pause_node (PinosNode *this)
g_debug ("node %p: pause node", this); g_debug ("node %p: pause node", this);
cmd.type = SPA_NODE_COMMAND_PAUSE; cmd.type = SPA_NODE_COMMAND_PAUSE;
cmd.data = NULL;
cmd.size = 0;
if ((res = spa_node_send_command (this->node, &cmd)) < 0) if ((res = spa_node_send_command (this->node, &cmd)) < 0)
g_debug ("got error %d", res); g_debug ("got error %d", res);
} }

View file

@ -97,10 +97,29 @@ struct _SpaALSASink {
unsigned int n_buffers; unsigned int n_buffers;
uint32_t input_buffer; uint32_t input_buffer;
SpaMemory *mem; SpaMemory *alloc_bufmem;
ALSABuffer buffer; SpaMemory *alloc_mem;
ALSABuffer *alloc_buffers;
}; };
static void
update_state (SpaALSASink *this, SpaNodeState state)
{
SpaNodeEvent event;
SpaNodeEventStateChange sc;
if (this->node.state == state)
return;
this->node.state = state;
event.type = SPA_NODE_EVENT_TYPE_STATE_CHANGE;
event.data = &sc;
event.size = sizeof (sc);
sc.state = state;
this->event_cb (&this->node, &event, this->user_data);
}
#include "alsa-utils.c" #include "alsa-utils.c"
static const uint32_t min_uint32 = 1; static const uint32_t min_uint32 = 1;
@ -220,32 +239,12 @@ spa_alsa_sink_node_send_command (SpaNode *node,
case SPA_NODE_COMMAND_START: case SPA_NODE_COMMAND_START:
spa_alsa_start (this); spa_alsa_start (this);
if (this->event_cb) { update_state (this, SPA_NODE_STATE_STREAMING);
SpaNodeEvent event;
SpaNodeEventStateChange sc;
event.type = SPA_NODE_EVENT_TYPE_STATE_CHANGE;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_STREAMING;
this->event_cb (node, &event, this->user_data);
}
break; break;
case SPA_NODE_COMMAND_PAUSE: case SPA_NODE_COMMAND_PAUSE:
spa_alsa_stop (this); spa_alsa_stop (this);
if (this->event_cb) { update_state (this, SPA_NODE_STATE_PAUSED);
SpaNodeEvent event;
SpaNodeEventStateChange sc;
event.type = SPA_NODE_EVENT_TYPE_STATE_CHANGE;
event.data = &sc;
event.size = sizeof (sc);
sc.state = SPA_NODE_STATE_PAUSED;
this->event_cb (node, &event, this->user_data);
}
break; break;
case SPA_NODE_COMMAND_FLUSH: case SPA_NODE_COMMAND_FLUSH:
case SPA_NODE_COMMAND_DRAIN: case SPA_NODE_COMMAND_DRAIN:
@ -271,6 +270,8 @@ spa_alsa_sink_node_set_event_callback (SpaNode *node,
this->event_cb = event; this->event_cb = event;
this->user_data = user_data; this->user_data = user_data;
update_state (this, SPA_NODE_STATE_CONFIGURE);
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }
@ -386,6 +387,7 @@ spa_alsa_sink_node_port_set_format (SpaNode *node,
if (format == NULL) { if (format == NULL) {
this->have_format = false; this->have_format = false;
update_state (this, SPA_NODE_STATE_CONFIGURE);
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }
@ -399,6 +401,7 @@ spa_alsa_sink_node_port_set_format (SpaNode *node,
this->info.maxbuffering = -1; this->info.maxbuffering = -1;
this->info.latency = -1; this->info.latency = -1;
this->info.n_params = 1; this->info.n_params = 1;
this->info.params = this->params;
this->params[0] = &this->param_buffers.param; this->params[0] = &this->param_buffers.param;
this->param_buffers.param.type = SPA_ALLOC_PARAM_TYPE_BUFFERS; this->param_buffers.param.type = SPA_ALLOC_PARAM_TYPE_BUFFERS;
this->param_buffers.param.size = sizeof (this->param_buffers); this->param_buffers.param.size = sizeof (this->param_buffers);
@ -410,6 +413,7 @@ spa_alsa_sink_node_port_set_format (SpaNode *node,
this->info.features = NULL; this->info.features = NULL;
this->have_format = true; this->have_format = true;
update_state (this, SPA_NODE_STATE_READY);
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }
@ -493,6 +497,7 @@ spa_alsa_sink_node_port_alloc_buffers (SpaNode *node,
SpaALSASink *this; SpaALSASink *this;
ALSABuffer *b; ALSABuffer *b;
SpaALSAState *state; SpaALSAState *state;
unsigned int i, n_bufs;
if (node == NULL || node->handle == NULL || buffers == NULL) if (node == NULL || node->handle == NULL || buffers == NULL)
return SPA_RESULT_INVALID_ARGUMENTS; return SPA_RESULT_INVALID_ARGUMENTS;
@ -507,14 +512,20 @@ spa_alsa_sink_node_port_alloc_buffers (SpaNode *node,
state = &this->state; state = &this->state;
if (!this->mem) n_bufs = *n_buffers;
this->mem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED, NULL, state->buffer_size);
b = &this->buffer; if (!this->alloc_bufmem)
b->buffer.id = 0; this->alloc_bufmem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED, NULL, state->buffer_size * n_bufs);
b->buffer.mem.mem.pool_id = -1;
b->buffer.mem.mem.id = -1; if (!this->alloc_mem)
b->buffer.mem.offset = 0; this->alloc_mem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED, NULL, sizeof (ALSABuffer) * n_bufs);
this->alloc_buffers = spa_memory_ensure_ptr (this->alloc_mem);
for (i = 0; i < n_bufs; i++) {
b = &this->alloc_buffers[i];
b->buffer.id = i;
b->buffer.mem.mem = this->alloc_mem->mem;
b->buffer.mem.offset = sizeof (ALSABuffer) * i;
b->buffer.mem.size = sizeof (ALSABuffer); b->buffer.mem.size = sizeof (ALSABuffer);
b->buffer.n_metas = 2; b->buffer.n_metas = 2;
@ -540,13 +551,16 @@ spa_alsa_sink_node_port_alloc_buffers (SpaNode *node,
b->metas[1].offset = offsetof (ALSABuffer, ringbuffer); b->metas[1].offset = offsetof (ALSABuffer, ringbuffer);
b->metas[1].size = sizeof (b->ringbuffer); b->metas[1].size = sizeof (b->ringbuffer);
b->datas[0].mem.mem = this->mem->mem; b->datas[0].mem.mem = this->alloc_bufmem->mem;
b->datas[0].mem.offset = 0; b->datas[0].mem.offset = state->buffer_size * i;
b->datas[0].mem.size = state->buffer_size; b->datas[0].mem.size = state->buffer_size;
b->datas[0].stride = 0; b->datas[0].stride = 0;
buffers[0] = &b->buffer; buffers[i] = &b->buffer;
*n_buffers = 1; }
*n_buffers = n_bufs;
update_state (this, SPA_NODE_STATE_PAUSED);
return SPA_RESULT_OK; return SPA_RESULT_OK;
} }

View file

@ -21,9 +21,9 @@ spa_alsa_open (SpaALSASink *this)
if (state->opened) if (state->opened)
return 0; return 0;
CHECK (snd_output_stdio_attach (&state->output, stdout, 0), "attach failed"); CHECK (snd_output_stdio_attach (&state->output, stderr, 0), "attach failed");
printf ("Playback device is '%s'\n", props->device); printf ("Playback device open '%s'\n", props->device);
CHECK (snd_pcm_open (&state->handle, CHECK (snd_pcm_open (&state->handle,
props->device, props->device,
SND_PCM_STREAM_PLAYBACK, SND_PCM_STREAM_PLAYBACK,
@ -46,6 +46,7 @@ spa_alsa_close (SpaALSASink *this)
if (!state->opened) if (!state->opened)
return 0; return 0;
printf ("Playback device closing\n");
CHECK (snd_pcm_close (state->handle), "close failed"); CHECK (snd_pcm_close (state->handle), "close failed");
state->opened = false; state->opened = false;
@ -265,11 +266,11 @@ mmap_write (SpaALSASink *this)
(uint8_t *)my_areas[0].addr + (offset * sizeof (uint16_t) * 2), (uint8_t *)my_areas[0].addr + (offset * sizeof (uint16_t) * 2),
frames); frames);
if (this->input_buffer) { if (this->input_buffer != SPA_ID_INVALID) {
if (this->input_buffer != this->buffer.buffer.id) { if (this->input_buffer != this->alloc_buffers[0].buffer.id) {
/* FIXME, copy input */ /* FIXME, copy input */
} }
this->input_buffer = -1; this->input_buffer = SPA_ID_INVALID;
} }
commitres = snd_pcm_mmap_commit (handle, offset, frames); commitres = snd_pcm_mmap_commit (handle, offset, frames);