summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-06-29 23:59:41 +0200
committerwm4 <wm4@nowhere>2015-06-30 00:02:12 +0200
commit2f8eabe2166f897b9290ff154c882e87fee16746 (patch)
treeef2326bab605b5a4f411f886dd0aadc646c8d4f5 /audio
parent302aaddc262140ef1cbd962aa3177ded670f39bb (diff)
downloadmpv-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.c3
-rw-r--r--audio/out/ao_coreaudio_utils.c13
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);