summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorThomas Weißschuh <thomas@t-8ch.de>2022-08-29 20:52:02 +0200
committerPhilip Langdale <github.philipl@overt.org>2022-09-11 20:24:42 -0700
commit013ec877f6e0d2483a864e963d7f5ccfc1f31973 (patch)
tree68c4dc1ccff6e609230e2e276f49886ad4aa195d /audio
parenta9155c6f97e02b09c93ff940e76db422cab7f894 (diff)
downloadmpv-013ec877f6e0d2483a864e963d7f5ccfc1f31973.tar.bz2
mpv-013ec877f6e0d2483a864e963d7f5ccfc1f31973.tar.xz
audio: try to use playback AO as hotplug AO first
When a platform has multiple valid AOs that can provide hotplug events we should try to use the one that also provides playback. Concretely this will help when introducing hotplug support for ao_pipewire. Currently ao_pulse is probed by ao_hotplug_get_device_list() before ao_pipewire and on the common setups where both AOs could work pulse will be selected for hotplug handling. This means that hotplug_init() of ao_pipewire will never be called and list_devs() has to do its own initialization. But if ao_pulse is non-functional or not compiled-in suddenly ao_pipewire *must* implement hotplug_init() for hotplugging events to work for all. Also if the hotplug ao_pulse connects to a PulseAudio instance that is not emulated by the same PipeWire instance as the playback ao_pipewire the hotplug events are useless.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao.c26
-rw-r--r--audio/out/ao.h4
2 files changed, 23 insertions, 7 deletions
diff --git a/audio/out/ao.c b/audio/out/ao.c
index 4eb115194b..4dddd7dc2b 100644
--- a/audio/out/ao.c
+++ b/audio/out/ao.c
@@ -453,8 +453,9 @@ struct ao_hotplug {
void *wakeup_ctx;
// A single AO instance is used to listen to hotplug events. It wouldn't
// make much sense to allow multiple AO drivers; all sane platforms have
- // a single such audio API.
- // This is _not_ the same AO instance as used for playing audio.
+ // a single audio API providing all events.
+ // This is _not_ necessarily the same AO instance as used for playing
+ // audio.
struct ao *ao;
// cached
struct ao_device_list *list;
@@ -494,7 +495,8 @@ bool ao_hotplug_check_update(struct ao_hotplug *hp)
}
// The return value is valid until the next call to this API.
-struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp)
+struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp,
+ struct ao *playback_ao)
{
if (hp->list && !hp->needs_update)
return hp->list;
@@ -506,6 +508,19 @@ struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp)
MP_TARRAY_APPEND(list, list->devices, list->num_devices,
(struct ao_device_desc){"auto", "Autoselect device"});
+ // Try to use the same AO for hotplug handling as for playback.
+ // Different AOs may not agree and the playback one is the only one the
+ // user knows about and may even have configured explicitly.
+ if (!hp->ao && playback_ao && playback_ao->driver->hotplug_init) {
+ struct ao *ao = ao_alloc(true, hp->global, hp->wakeup_cb, hp->wakeup_ctx,
+ (char *)playback_ao->driver->name);
+ if (playback_ao->driver->hotplug_init(ao) >= 0) {
+ hp->ao = ao;
+ } else {
+ talloc_free(ao);
+ }
+ }
+
for (int n = 0; audio_out_drivers[n]; n++) {
const struct ao_driver *d = audio_out_drivers[n];
if (d == &audio_out_null)
@@ -569,10 +584,11 @@ static void dummy_wakeup(void *ctx)
{
}
-void ao_print_devices(struct mpv_global *global, struct mp_log *log)
+void ao_print_devices(struct mpv_global *global, struct mp_log *log,
+ struct ao *playback_ao)
{
struct ao_hotplug *hp = ao_hotplug_create(global, dummy_wakeup, NULL);
- struct ao_device_list *list = ao_hotplug_get_device_list(hp);
+ struct ao_device_list *list = ao_hotplug_get_device_list(hp, playback_ao);
mp_info(log, "List of detected audio devices:\n");
for (int n = 0; n < list->num_devices; n++) {
struct ao_device_desc *desc = &list->devices[n];
diff --git a/audio/out/ao.h b/audio/out/ao.h
index 7d111c46ff..1bca124599 100644
--- a/audio/out/ao.h
+++ b/audio/out/ao.h
@@ -126,8 +126,8 @@ struct ao_hotplug *ao_hotplug_create(struct mpv_global *global,
void *wakeup_ctx);
void ao_hotplug_destroy(struct ao_hotplug *hp);
bool ao_hotplug_check_update(struct ao_hotplug *hp);
-struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp);
+struct ao_device_list *ao_hotplug_get_device_list(struct ao_hotplug *hp, struct ao *playback_ao);
-void ao_print_devices(struct mpv_global *global, struct mp_log *log);
+void ao_print_devices(struct mpv_global *global, struct mp_log *log, struct ao *playback_ao);
#endif /* MPLAYER_AUDIO_OUT_H */