diff options
author | wm4 <wm4@nowhere> | 2015-06-29 23:59:41 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-06-30 00:02:12 +0200 |
commit | 2f8eabe2166f897b9290ff154c882e87fee16746 (patch) | |
tree | ef2326bab605b5a4f411f886dd0aadc646c8d4f5 /audio | |
parent | 302aaddc262140ef1cbd962aa3177ded670f39bb (diff) | |
download | mpv-2f8eabe2166f897b9290ff154c882e87fee16746.tar.bz2 mpv-2f8eabe2166f897b9290ff154c882e87fee16746.tar.xz |
ao_coreaudio: restore physical format if it can't be set exactly
May help with (supposedly) bad drivers, which can put the device into
some sort of broken state when trying to set a different physical
format. When the previous format is restored, it apparently recovers.
This might make the change-physical-format suboption more robust.
Diffstat (limited to 'audio')
-rw-r--r-- | audio/out/ao_coreaudio.c | 3 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_utils.c | 13 |
2 files changed, 14 insertions, 2 deletions
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c index b39cebc2e4..8fba7a944c 100644 --- a/audio/out/ao_coreaudio.c +++ b/audio/out/ao_coreaudio.c @@ -235,7 +235,8 @@ static void init_physical_format(struct ao *ao) &p->original_asbd); CHECK_CA_WARN("could not get current physical stream format"); - ca_change_physical_format_sync(ao, streams[i], best_asbd); + if (!ca_change_physical_format_sync(ao, streams[i], best_asbd)) + p->original_asbd = (AudioStreamBasicDescription){0}; break; } } diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c index 77e87b7c23..c94cd73483 100644 --- a/audio/out/ao_coreaudio_utils.c +++ b/audio/out/ao_coreaudio_utils.c @@ -471,6 +471,10 @@ bool ca_change_physical_format_sync(struct ao *ao, AudioStreamID stream, return false; } + AudioStreamBasicDescription prev_format; + err = CA_GET(stream, kAudioStreamPropertyPhysicalFormat, &prev_format); + CHECK_CA_ERROR("can't get current physical format"); + /* Install the callback. */ AudioObjectPropertyAddress p_addr = { .mSelector = kAudioStreamPropertyPhysicalFormat, @@ -485,7 +489,7 @@ bool ca_change_physical_format_sync(struct ao *ao, AudioStreamID stream, /* Change the format. */ err = CA_SET(stream, kAudioStreamPropertyPhysicalFormat, &change_format); - CHECK_CA_ERROR("error changing physical format"); + CHECK_CA_WARN("error changing physical format"); /* The AudioStreamSetProperty is not only asynchronous, * it is also not Atomic, in its behaviour. */ @@ -508,6 +512,13 @@ bool ca_change_physical_format_sync(struct ao *ao, AudioStreamID stream, ca_print_asbd(ao, "actual format in use:", &actual_format); + if (!format_set) { + // Some drivers just fuck up and get into a broken state. Restore the + // old format in this case. + err = CA_SET(stream, kAudioStreamPropertyPhysicalFormat, &prev_format); + CHECK_CA_WARN("error restoring physical format"); + } + err = AudioObjectRemovePropertyListener(stream, &p_addr, ca_change_format_listener, &wakeup); |