mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-16 08:56:45 -05:00
improve state change
This commit is contained in:
parent
f86b50d202
commit
36bcdaa4bc
4 changed files with 84 additions and 65 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 = ≻
|
||||||
|
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 = ≻
|
|
||||||
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 = ≻
|
|
||||||
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,46 +512,55 @@ 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;
|
|
||||||
b->buffer.mem.offset = 0;
|
|
||||||
b->buffer.mem.size = sizeof (ALSABuffer);
|
|
||||||
|
|
||||||
b->buffer.n_metas = 2;
|
if (!this->alloc_mem)
|
||||||
b->buffer.metas = offsetof (ALSABuffer, metas);
|
this->alloc_mem = spa_memory_alloc_with_fd (SPA_MEMORY_POOL_SHARED, NULL, sizeof (ALSABuffer) * n_bufs);
|
||||||
b->buffer.n_datas = 1;
|
this->alloc_buffers = spa_memory_ensure_ptr (this->alloc_mem);
|
||||||
b->buffer.datas = offsetof (ALSABuffer, datas);
|
|
||||||
|
|
||||||
b->header.flags = 0;
|
for (i = 0; i < n_bufs; i++) {
|
||||||
b->header.seq = 0;
|
b = &this->alloc_buffers[i];
|
||||||
b->header.pts = 0;
|
b->buffer.id = i;
|
||||||
b->header.dts_offset = 0;
|
b->buffer.mem.mem = this->alloc_mem->mem;
|
||||||
|
b->buffer.mem.offset = sizeof (ALSABuffer) * i;
|
||||||
|
b->buffer.mem.size = sizeof (ALSABuffer);
|
||||||
|
|
||||||
b->metas[0].type = SPA_META_TYPE_HEADER;
|
b->buffer.n_metas = 2;
|
||||||
b->metas[0].offset = offsetof (ALSABuffer, header);
|
b->buffer.metas = offsetof (ALSABuffer, metas);
|
||||||
b->metas[0].size = sizeof (b->header);
|
b->buffer.n_datas = 1;
|
||||||
|
b->buffer.datas = offsetof (ALSABuffer, datas);
|
||||||
|
|
||||||
b->ringbuffer.readindex = 0;
|
b->header.flags = 0;
|
||||||
b->ringbuffer.writeindex = 0;
|
b->header.seq = 0;
|
||||||
b->ringbuffer.size = 0;
|
b->header.pts = 0;
|
||||||
b->ringbuffer.size_mask = 0;
|
b->header.dts_offset = 0;
|
||||||
|
|
||||||
b->metas[1].type = SPA_META_TYPE_RINGBUFFER;
|
b->metas[0].type = SPA_META_TYPE_HEADER;
|
||||||
b->metas[1].offset = offsetof (ALSABuffer, ringbuffer);
|
b->metas[0].offset = offsetof (ALSABuffer, header);
|
||||||
b->metas[1].size = sizeof (b->ringbuffer);
|
b->metas[0].size = sizeof (b->header);
|
||||||
|
|
||||||
b->datas[0].mem.mem = this->mem->mem;
|
b->ringbuffer.readindex = 0;
|
||||||
b->datas[0].mem.offset = 0;
|
b->ringbuffer.writeindex = 0;
|
||||||
b->datas[0].mem.size = state->buffer_size;
|
b->ringbuffer.size = 0;
|
||||||
b->datas[0].stride = 0;
|
b->ringbuffer.size_mask = 0;
|
||||||
|
|
||||||
buffers[0] = &b->buffer;
|
b->metas[1].type = SPA_META_TYPE_RINGBUFFER;
|
||||||
*n_buffers = 1;
|
b->metas[1].offset = offsetof (ALSABuffer, ringbuffer);
|
||||||
|
b->metas[1].size = sizeof (b->ringbuffer);
|
||||||
|
|
||||||
|
b->datas[0].mem.mem = this->alloc_bufmem->mem;
|
||||||
|
b->datas[0].mem.offset = state->buffer_size * i;
|
||||||
|
b->datas[0].mem.size = state->buffer_size;
|
||||||
|
b->datas[0].stride = 0;
|
||||||
|
|
||||||
|
buffers[i] = &b->buffer;
|
||||||
|
}
|
||||||
|
*n_buffers = n_bufs;
|
||||||
|
|
||||||
|
update_state (this, SPA_NODE_STATE_PAUSED);
|
||||||
|
|
||||||
return SPA_RESULT_OK;
|
return SPA_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue