mirror of https://github.com/mpv-player/mpv
ao_pipewire: report linking errors from init()
This commit is contained in:
parent
83681de3c1
commit
e439ddc051
|
@ -55,12 +55,19 @@ static inline int pw_stream_get_time_n(struct pw_stream *stream, struct pw_time
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum init_state {
|
||||||
|
INIT_STATE_NONE,
|
||||||
|
INIT_STATE_SUCCESS,
|
||||||
|
INIT_STATE_ERROR,
|
||||||
|
};
|
||||||
|
|
||||||
struct priv {
|
struct priv {
|
||||||
struct pw_thread_loop *loop;
|
struct pw_thread_loop *loop;
|
||||||
struct pw_stream *stream;
|
struct pw_stream *stream;
|
||||||
struct pw_core *core;
|
struct pw_core *core;
|
||||||
struct spa_hook stream_listener;
|
struct spa_hook stream_listener;
|
||||||
struct spa_hook core_listener;
|
struct spa_hook core_listener;
|
||||||
|
enum init_state init_state;
|
||||||
|
|
||||||
bool muted;
|
bool muted;
|
||||||
float volume;
|
float volume;
|
||||||
|
@ -194,6 +201,14 @@ static void on_param_changed(void *userdata, uint32_t id, const struct spa_pod *
|
||||||
uint8_t buffer[1024];
|
uint8_t buffer[1024];
|
||||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
/* We want to know when our node is linked.
|
||||||
|
* As there is no proper callback for this we use the Latency param for this
|
||||||
|
*/
|
||||||
|
if (id == SPA_PARAM_Latency) {
|
||||||
|
p->init_state = INIT_STATE_SUCCESS;
|
||||||
|
pw_thread_loop_signal(p->loop, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (param == NULL || id != SPA_PARAM_Format)
|
if (param == NULL || id != SPA_PARAM_Format)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -218,11 +233,14 @@ static void on_param_changed(void *userdata, uint32_t id, const struct spa_pod *
|
||||||
static void on_state_changed(void *userdata, enum pw_stream_state old, enum pw_stream_state state, const char *error)
|
static void on_state_changed(void *userdata, enum pw_stream_state old, enum pw_stream_state state, const char *error)
|
||||||
{
|
{
|
||||||
struct ao *ao = userdata;
|
struct ao *ao = userdata;
|
||||||
|
struct priv *p = ao->priv;
|
||||||
MP_DBG(ao, "Stream state changed: old_state=%s state=%s error=%s\n",
|
MP_DBG(ao, "Stream state changed: old_state=%s state=%s error=%s\n",
|
||||||
pw_stream_state_as_string(old), pw_stream_state_as_string(state), error);
|
pw_stream_state_as_string(old), pw_stream_state_as_string(state), error);
|
||||||
|
|
||||||
if (state == PW_STREAM_STATE_ERROR) {
|
if (state == PW_STREAM_STATE_ERROR) {
|
||||||
MP_WARN(ao, "Stream in error state, trying to reload...\n");
|
MP_WARN(ao, "Stream in error state, trying to reload...\n");
|
||||||
|
p->init_state = INIT_STATE_ERROR;
|
||||||
|
pw_thread_loop_signal(p->loop, false);
|
||||||
ao_request_reload(ao);
|
ao_request_reload(ao);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,6 +503,27 @@ error:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wait_for_init_done(struct ao *ao)
|
||||||
|
{
|
||||||
|
struct priv *p = ao->priv;
|
||||||
|
struct timespec abstime;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = pw_thread_loop_get_time(p->loop, &abstime, 50 * SPA_NSEC_PER_MSEC);
|
||||||
|
if (r < 0) {
|
||||||
|
MP_WARN(ao, "Could not get timeout for initialization: %s\n", spa_strerror(r));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (p->init_state == INIT_STATE_NONE) {
|
||||||
|
r = pw_thread_loop_timed_wait_full(p->loop, &abstime);
|
||||||
|
if (r < 0) {
|
||||||
|
MP_WARN(ao, "Could not wait for initialization: %s\n", spa_strerror(r));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int init(struct ao *ao)
|
static int init(struct ao *ao)
|
||||||
{
|
{
|
||||||
struct priv *p = ao->priv;
|
struct priv *p = ao->priv;
|
||||||
|
@ -563,8 +602,13 @@ static int init(struct ao *ao)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wait_for_init_done(ao);
|
||||||
|
|
||||||
pw_thread_loop_unlock(p->loop);
|
pw_thread_loop_unlock(p->loop);
|
||||||
|
|
||||||
|
if (p->init_state == INIT_STATE_ERROR)
|
||||||
|
goto error;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_props:
|
error_props:
|
||||||
|
@ -808,6 +852,7 @@ const struct ao_driver audio_out_pipewire = {
|
||||||
{
|
{
|
||||||
.loop = NULL,
|
.loop = NULL,
|
||||||
.stream = NULL,
|
.stream = NULL,
|
||||||
|
.init_state = INIT_STATE_NONE,
|
||||||
.options.buffer_msec = 20,
|
.options.buffer_msec = 20,
|
||||||
},
|
},
|
||||||
.options_prefix = "pipewire",
|
.options_prefix = "pipewire",
|
||||||
|
|
Loading…
Reference in New Issue