From 65a5272a9f3124c6f3ef429547d742ba49441c11 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 17 May 2023 11:00:52 +0200 Subject: [PATCH] stream: keep error res around So that we can return it when there is an error instead of the generic -EIO. --- src/pipewire/filter.c | 30 ++++++++++++++++-------------- src/pipewire/private.h | 2 ++ src/pipewire/stream.c | 30 ++++++++++++++++-------------- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/pipewire/filter.c b/src/pipewire/filter.c index 3d25d8011..df2592466 100644 --- a/src/pipewire/filter.c +++ b/src/pipewire/filter.c @@ -357,26 +357,28 @@ static inline void clear_queue(struct port *port, struct queue *queue) spa_ringbuffer_init(&queue->ring); } -static bool filter_set_state(struct pw_filter *filter, enum pw_filter_state state, const char *error) +static bool filter_set_state(struct pw_filter *filter, enum pw_filter_state state, + int res, const char *error) { enum pw_filter_state old = filter->state; - bool res = old != state; + bool changed = old != state; if (res) { free(filter->error); filter->error = error ? strdup(error) : NULL; + filter->error_res = res; - pw_log_debug("%p: update state from %s -> %s (%s)", filter, + pw_log_debug("%p: update state from %s -> %s: (%d) %s", filter, pw_filter_state_as_string(old), - pw_filter_state_as_string(state), filter->error); + pw_filter_state_as_string(state), res, error); if (state == PW_FILTER_STATE_ERROR) - pw_log_error("%p: error %s", filter, error); + pw_log_error("%p: error (%d) %s", filter, res, error); filter->state = state; pw_filter_emit_state_changed(filter, old, state, error); } - return res; + return changed; } static int enum_params(struct filter *d, struct spa_list *param_list, int seq, @@ -490,13 +492,13 @@ static int impl_send_command(void *object, const struct spa_command *command) NULL, 0, NULL, 0, false, impl); if (filter->state == PW_FILTER_STATE_STREAMING) { pw_log_debug("%p: pause", filter); - filter_set_state(filter, PW_FILTER_STATE_PAUSED, NULL); + filter_set_state(filter, PW_FILTER_STATE_PAUSED, 0, NULL); } break; case SPA_NODE_COMMAND_Start: if (filter->state == PW_FILTER_STATE_PAUSED) { pw_log_debug("%p: start", filter); - filter_set_state(filter, PW_FILTER_STATE_STREAMING, NULL); + filter_set_state(filter, PW_FILTER_STATE_STREAMING, 0, NULL); } break; default: @@ -849,7 +851,7 @@ static int impl_port_set_param(void *object, pw_filter_emit_param_changed(filter, port->user_data, id, param); if (filter->state == PW_FILTER_STATE_ERROR) - return -EIO; + return filter->error_res; emit_port_info(impl, port, false); @@ -1094,7 +1096,7 @@ static void proxy_removed(void *_data) pw_log_debug("%p: removed", filter); spa_hook_remove(&filter->proxy_listener); filter->node_id = SPA_ID_INVALID; - filter_set_state(filter, PW_FILTER_STATE_UNCONNECTED, NULL); + filter_set_state(filter, PW_FILTER_STATE_UNCONNECTED, 0, NULL); } static void proxy_destroy(void *_data) @@ -1120,7 +1122,7 @@ static void proxy_bound_props(void *_data, uint32_t global_id, const struct spa_ filter->node_id = global_id; if (props) pw_properties_update(filter->properties, props); - filter_set_state(filter, PW_FILTER_STATE_PAUSED, NULL); + filter_set_state(filter, PW_FILTER_STATE_PAUSED, 0, NULL); } static const struct pw_proxy_events proxy_events = { @@ -1139,7 +1141,7 @@ static void on_core_error(void *_data, uint32_t id, int seq, int res, const char id, seq, res, spa_strerror(res), message); if (id == PW_ID_CORE && res == -EPIPE) { - filter_set_state(filter, PW_FILTER_STATE_UNCONNECTED, message); + filter_set_state(filter, PW_FILTER_STATE_UNCONNECTED, res, message); } } @@ -1587,7 +1589,7 @@ pw_filter_connect(struct pw_filter *filter, impl->disconnecting = false; impl->draining = false; impl->driving = false; - filter_set_state(filter, PW_FILTER_STATE_CONNECTING, NULL); + filter_set_state(filter, PW_FILTER_STATE_CONNECTING, 0, NULL); if (flags & PW_FILTER_FLAG_DRIVER) pw_properties_set(filter->properties, PW_KEY_NODE_DRIVER, "true"); @@ -1840,7 +1842,7 @@ int pw_filter_set_error(struct pw_filter *filter, if (filter->proxy) pw_proxy_error(filter->proxy, res, value); - filter_set_state(filter, PW_FILTER_STATE_ERROR, value); + filter_set_state(filter, PW_FILTER_STATE_ERROR, res, value); free(value); } diff --git a/src/pipewire/private.h b/src/pipewire/private.h index ff9d2bad1..541d4c426 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -1088,6 +1088,7 @@ struct pw_stream { * CONFIGURE state and higher */ enum pw_stream_state state; /**< stream state */ char *error; /**< error reason when state is in error */ + int error_res; /**< error code when in error */ struct spa_hook_list listener_list; @@ -1125,6 +1126,7 @@ struct pw_filter { * CONFIGURE state and higher */ enum pw_filter_state state; /**< filter state */ char *error; /**< error reason when state is in error */ + int error_res; /**< error code when in error */ struct spa_hook_list listener_list; diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index a6cb08615..8efddb4eb 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -352,26 +352,28 @@ static inline void clear_queue(struct stream *stream, struct queue *queue) queue->incount = queue->outcount; } -static bool stream_set_state(struct pw_stream *stream, enum pw_stream_state state, const char *error) +static bool stream_set_state(struct pw_stream *stream, enum pw_stream_state state, + int res, const char *error) { enum pw_stream_state old = stream->state; - bool res = old != state; + bool changed = old != state; if (res) { free(stream->error); stream->error = error ? strdup(error) : NULL; + stream->error_res = res; - pw_log_debug("%p: update state from %s -> %s (%s)", stream, + pw_log_debug("%p: update state from %s -> %s (%d) %s", stream, pw_stream_state_as_string(old), - pw_stream_state_as_string(state), stream->error); + pw_stream_state_as_string(state), res, stream->error); if (state == PW_STREAM_STATE_ERROR) - pw_log_error("%p: error %s", stream, error); + pw_log_error("%p: error (%d) %s", stream, res, error); stream->state = state; pw_stream_emit_state_changed(stream, old, state, error); } - return res; + return changed; } static struct buffer *get_buffer(struct pw_stream *stream, uint32_t id) @@ -613,7 +615,7 @@ static int impl_send_command(void *object, const struct spa_command *command) if (stream->state == PW_STREAM_STATE_STREAMING) { pw_log_debug("%p: pause", stream); - stream_set_state(stream, PW_STREAM_STATE_PAUSED, NULL); + stream_set_state(stream, PW_STREAM_STATE_PAUSED, 0, NULL); } break; case SPA_NODE_COMMAND_Start: @@ -629,7 +631,7 @@ static int impl_send_command(void *object, const struct spa_command *command) call_process(impl); } - stream_set_state(stream, PW_STREAM_STATE_STREAMING, NULL); + stream_set_state(stream, PW_STREAM_STATE_STREAMING, 0, NULL); } break; default: @@ -884,7 +886,7 @@ static int impl_port_set_param(void *object, pw_stream_emit_param_changed(stream, id, param); if (stream->state == PW_STREAM_STATE_ERROR) - return -EIO; + return stream->error_res; emit_node_info(impl, false); emit_port_info(impl, false); @@ -1120,7 +1122,7 @@ static void proxy_removed(void *_data) pw_log_debug("%p: removed", stream); spa_hook_remove(&stream->proxy_listener); stream->node_id = SPA_ID_INVALID; - stream_set_state(stream, PW_STREAM_STATE_UNCONNECTED, NULL); + stream_set_state(stream, PW_STREAM_STATE_UNCONNECTED, 0, NULL); } static void proxy_destroy(void *_data) @@ -1146,7 +1148,7 @@ static void proxy_bound_props(void *data, uint32_t global_id, const struct spa_d stream->node_id = global_id; if (props) pw_properties_update(stream->properties, props); - stream_set_state(stream, PW_STREAM_STATE_PAUSED, NULL); + stream_set_state(stream, PW_STREAM_STATE_PAUSED, 0, NULL); } static const struct pw_proxy_events proxy_events = { @@ -1382,7 +1384,7 @@ static void on_core_error(void *data, uint32_t id, int seq, int res, const char id, seq, res, spa_strerror(res), message); if (id == PW_ID_CORE && res == -EPIPE) { - stream_set_state(stream, PW_STREAM_STATE_UNCONNECTED, message); + stream_set_state(stream, PW_STREAM_STATE_UNCONNECTED, res, message); } } @@ -1943,7 +1945,7 @@ pw_stream_connect(struct pw_stream *stream, impl->driving = false; impl->trigger = false; impl->using_trigger = false; - stream_set_state(stream, PW_STREAM_STATE_CONNECTING, NULL); + stream_set_state(stream, PW_STREAM_STATE_CONNECTING, 0, NULL); if ((str = getenv("PIPEWIRE_NODE")) != NULL) pw_properties_set(stream->properties, PW_KEY_TARGET_OBJECT, str); @@ -2114,7 +2116,7 @@ int pw_stream_set_error(struct pw_stream *stream, if (stream->proxy) pw_proxy_error(stream->proxy, res, value); - stream_set_state(stream, PW_STREAM_STATE_ERROR, value); + stream_set_state(stream, PW_STREAM_STATE_ERROR, res, value); free(value); }