diff options
author | wm4 <wm4@nowhere> | 2015-06-02 21:07:13 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-06-02 22:25:30 +0200 |
commit | 7c0d3b9a50d282c91efc3a4c84a443aa1d1ff4a6 (patch) | |
tree | 79dac491ca686b32103491bb246a824f03d2960d | |
parent | 87a94a56556d44388ea50a69fe46e829a5d87eb8 (diff) | |
download | mpv-7c0d3b9a50d282c91efc3a4c84a443aa1d1ff4a6.tar.bz2 mpv-7c0d3b9a50d282c91efc3a4c84a443aa1d1ff4a6.tar.xz |
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.
-rw-r--r-- | audio/out/ao_coreaudio_exclusive.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/audio/out/ao_coreaudio_exclusive.c b/audio/out/ao_coreaudio_exclusive.c index dd476458aa..a08db7622d 100644 --- a/audio/out/ao_coreaudio_exclusive.c +++ b/audio/out/ao_coreaudio_exclusive.c @@ -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, - .mScope = kAudioObjectPropertyScopeGlobal, - .mElement = kAudioObjectPropertyElementMaster, - }; - - if (enabled) { - return AudioObjectAddPropertyListener( - p->device, &p_addr, property_listener_cb, ao); - } else { - return AudioObjectRemovePropertyListener( - p->device, &p_addr, property_listener_cb, ao); + 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) { + status2 = AudioObjectAddPropertyListener( + device, &addr, property_listener_cb, ao); + } else { + status2 = AudioObjectRemovePropertyListener( + device, &addr, property_listener_cb, ao); + } + if (status == noErr) + status = status2; } + + return status; } static OSStatus render_cb_compressed( |