summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-06-02 21:07:13 +0200
committerwm4 <wm4@nowhere>2015-06-02 22:25:30 +0200
commit7c0d3b9a50d282c91efc3a4c84a443aa1d1ff4a6 (patch)
tree79dac491ca686b32103491bb246a824f03d2960d /audio
parent87a94a56556d44388ea50a69fe46e829a5d87eb8 (diff)
downloadmpv-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.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_coreaudio_exclusive.c39
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(