mirror of https://github.com/encounter/SDL.git
audio: pipewire: Block while waiting on stream state info
Initializing streams, particularly capture streams, can take many milliseconds, which is a bit much for a busy wait. Use a blocking wait instead.
This commit is contained in:
parent
8deb406300
commit
5f9effaa7e
|
@ -983,8 +983,23 @@ input_callback(void *data)
|
||||||
PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf);
|
PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pw_stream_events stream_output_events = { PW_VERSION_STREAM_EVENTS, .process = output_callback };
|
static void
|
||||||
static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_EVENTS, .process = input_callback };
|
stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error)
|
||||||
|
{
|
||||||
|
_THIS = data;
|
||||||
|
|
||||||
|
if (state == PW_STREAM_STATE_STREAMING || state == PW_STREAM_STATE_ERROR) {
|
||||||
|
SDL_AtomicSet(&this->hidden->stream_initialized, 1);
|
||||||
|
PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pw_stream_events stream_output_events = { PW_VERSION_STREAM_EVENTS,
|
||||||
|
.state_changed = stream_state_changed_callback,
|
||||||
|
.process = output_callback };
|
||||||
|
static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_EVENTS,
|
||||||
|
.state_changed = stream_state_changed_callback,
|
||||||
|
.process = input_callback };
|
||||||
|
|
||||||
static int
|
static int
|
||||||
PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||||
|
@ -1005,7 +1020,7 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||||
const struct spa_pod * params = NULL;
|
const struct spa_pod * params = NULL;
|
||||||
struct SDL_PrivateAudioData *priv;
|
struct SDL_PrivateAudioData *priv;
|
||||||
struct pw_properties * props;
|
struct pw_properties * props;
|
||||||
const char * app_name, *stream_name, *stream_role;
|
const char * app_name, *stream_name, *stream_role, *error;
|
||||||
const Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
|
const Uint32 node_id = this->handle == NULL ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle);
|
||||||
enum pw_stream_state state;
|
enum pw_stream_state state;
|
||||||
int res;
|
int res;
|
||||||
|
@ -1120,14 +1135,17 @@ PIPEWIRE_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait until the stream is either running or failed */
|
/* Wait until the stream is either running or failed */
|
||||||
do {
|
PIPEWIRE_pw_thread_loop_lock(priv->loop);
|
||||||
const char *error;
|
if (!SDL_AtomicGet(&priv->stream_initialized)) {
|
||||||
state = PIPEWIRE_pw_stream_get_state(priv->stream, &error);
|
PIPEWIRE_pw_thread_loop_wait(priv->loop);
|
||||||
|
}
|
||||||
|
PIPEWIRE_pw_thread_loop_unlock(priv->loop);
|
||||||
|
|
||||||
if (state == PW_STREAM_STATE_ERROR) {
|
state = PIPEWIRE_pw_stream_get_state(priv->stream, &error);
|
||||||
return SDL_SetError("Pipewire: Stream error: %s", error);
|
|
||||||
}
|
if (state == PW_STREAM_STATE_ERROR) {
|
||||||
} while (state != PW_STREAM_STATE_STREAMING);
|
return SDL_SetError("Pipewire: Stream error: %s", error);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,9 @@ struct SDL_PrivateAudioData
|
||||||
struct pw_context *context;
|
struct pw_context *context;
|
||||||
struct SDL_DataQueue *buffer;
|
struct SDL_DataQueue *buffer;
|
||||||
|
|
||||||
size_t buffer_period_size;
|
size_t buffer_period_size;
|
||||||
Sint32 stride; /* Bytes-per-frame */
|
Sint32 stride; /* Bytes-per-frame */
|
||||||
|
SDL_atomic_t stream_initialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SDL_pipewire_h_ */
|
#endif /* SDL_pipewire_h_ */
|
||||||
|
|
Loading…
Reference in New Issue