1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-11 17:39:38 +00:00

ao_coreaudio_exclusive: react to device removal

Listening to kAudioDevicePropertyDeviceHasChanged does not send any
property change notifications when the device dies. Makes no sense,
but I suppose in CoreAudio logic a dead/removed device can't send
any notifications.

This caused the player to essentially pause playback if the audio
device was removed during playback.

Fix by listening to the kAudioHardwarePropertyDevices property too,
which will actually be sent in this specific case. Then, if
querying the already dead device fails, we know we have to reload.
This commit is contained in:
wm4 2015-06-02 21:07:13 +02:00
parent 87a94a5655
commit 7c0d3b9a50

View File

@ -305,19 +305,34 @@ static OSStatus enable_property_listener(struct ao *ao, bool enabled)
{
struct priv *p = ao->priv;
AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) {
.mSelector = kAudioDevicePropertyDeviceHasChanged,
uint32_t selectors[] = {kAudioDevicePropertyDeviceHasChanged,
kAudioHardwarePropertyDevices};
AudioDeviceID devs[] = {p->device,
kAudioObjectSystemObject};
assert(MP_ARRAY_SIZE(selectors) == MP_ARRAY_SIZE(devs));
OSStatus status = noErr;
for (int n = 0; n < MP_ARRAY_SIZE(devs); n++) {
AudioObjectPropertyAddress addr = {
.mScope = kAudioObjectPropertyScopeGlobal,
.mElement = kAudioObjectPropertyElementMaster,
.mSelector = selectors[n],
};
AudioDeviceID device = devs[n];
OSStatus status2;
if (enabled) {
return AudioObjectAddPropertyListener(
p->device, &p_addr, property_listener_cb, ao);
status2 = AudioObjectAddPropertyListener(
device, &addr, property_listener_cb, ao);
} else {
return AudioObjectRemovePropertyListener(
p->device, &p_addr, property_listener_cb, ao);
status2 = AudioObjectRemovePropertyListener(
device, &addr, property_listener_cb, ao);
}
if (status == noErr)
status = status2;
}
return status;
}
static OSStatus render_cb_compressed(