stream: update state based on node

Follow the state of the node and update the stream state accordingly.

The most important part is that Start is async and so it's better to
wait for completion from the node before emiting the STREAMING state.
This commit is contained in:
Wim Taymans 2024-09-19 19:03:38 +02:00
parent 2301d3000b
commit cd68819feb

View file

@ -659,7 +659,7 @@ static int impl_send_command(void *object, const struct spa_command *command)
struct pw_stream *stream = &impl->this; struct pw_stream *stream = &impl->this;
uint32_t id = SPA_NODE_COMMAND_ID(command); uint32_t id = SPA_NODE_COMMAND_ID(command);
pw_log_info("%p: command %s", impl, pw_log_debug("%p: command %s", impl,
spa_debug_type_find_name(spa_type_node_command_id, id)); spa_debug_type_find_name(spa_type_node_command_id, id));
switch (id) { switch (id) {
@ -668,22 +668,17 @@ static int impl_send_command(void *object, const struct spa_command *command)
case SPA_NODE_COMMAND_Pause: case SPA_NODE_COMMAND_Pause:
pw_loop_invoke(impl->main_loop, pw_loop_invoke(impl->main_loop,
NULL, 0, NULL, 0, false, impl); NULL, 0, NULL, 0, false, impl);
if (stream->state == PW_STREAM_STATE_STREAMING) { if (stream->state == PW_STREAM_STATE_STREAMING)
pw_log_debug("%p: pause", stream); pw_log_debug("%p: pause", stream);
stream_set_state(stream, PW_STREAM_STATE_PAUSED, 0, NULL);
}
break; break;
case SPA_NODE_COMMAND_Start: case SPA_NODE_COMMAND_Start:
if (stream->state == PW_STREAM_STATE_PAUSED) { if (stream->state == PW_STREAM_STATE_PAUSED) {
pw_log_debug("%p: start direction:%d", stream, impl->direction); pw_log_debug("%p: start direction:%d", stream, impl->direction);
if (impl->direction == SPA_DIRECTION_INPUT) { if (impl->direction == SPA_DIRECTION_INPUT) {
if (impl->io != NULL) if (impl->io != NULL)
impl->io->status = SPA_STATUS_NEED_DATA; impl->io->status = SPA_STATUS_NEED_DATA;
} }
copy_position(impl, impl->queued.incount); copy_position(impl, impl->queued.incount);
stream_set_state(stream, PW_STREAM_STATE_STREAMING, 0, NULL);
} }
break; break;
default: default:
@ -1388,10 +1383,33 @@ static void node_event_info(void *data, const struct pw_node_info *info)
} }
} }
static void node_state_changed(void *data, enum pw_node_state old,
enum pw_node_state state, const char *error)
{
struct pw_stream *stream = data;
switch (state) {
case PW_NODE_STATE_IDLE:
if (stream->state == PW_STREAM_STATE_STREAMING)
stream_set_state(stream, PW_STREAM_STATE_PAUSED, 0, NULL);
break;
case PW_NODE_STATE_RUNNING:
if (stream->state == PW_STREAM_STATE_PAUSED)
stream_set_state(stream, PW_STREAM_STATE_STREAMING, 0, NULL);
break;
case PW_NODE_STATE_ERROR:
stream_set_state(stream, PW_STREAM_STATE_ERROR, -EIO, error);
break;
default:
break;
}
}
static const struct pw_impl_node_events node_events = { static const struct pw_impl_node_events node_events = {
PW_VERSION_IMPL_NODE_EVENTS, PW_VERSION_IMPL_NODE_EVENTS,
.destroy = node_event_destroy, .destroy = node_event_destroy,
.info_changed = node_event_info, .info_changed = node_event_info,
.state_changed = node_state_changed,
}; };
static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message) static void on_core_error(void *data, uint32_t id, int seq, int res, const char *message)