mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
302aaddc26
commit
2f8eabe216
|
@ -235,7 +235,8 @@ static void init_physical_format(struct ao *ao)
|
||||||
&p->original_asbd);
|
&p->original_asbd);
|
||||||
CHECK_CA_WARN("could not get current physical stream format");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -471,6 +471,10 @@ bool ca_change_physical_format_sync(struct ao *ao, AudioStreamID stream,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioStreamBasicDescription prev_format;
|
||||||
|
err = CA_GET(stream, kAudioStreamPropertyPhysicalFormat, &prev_format);
|
||||||
|
CHECK_CA_ERROR("can't get current physical format");
|
||||||
|
|
||||||
/* Install the callback. */
|
/* Install the callback. */
|
||||||
AudioObjectPropertyAddress p_addr = {
|
AudioObjectPropertyAddress p_addr = {
|
||||||
.mSelector = kAudioStreamPropertyPhysicalFormat,
|
.mSelector = kAudioStreamPropertyPhysicalFormat,
|
||||||
|
@ -485,7 +489,7 @@ bool ca_change_physical_format_sync(struct ao *ao, AudioStreamID stream,
|
||||||
|
|
||||||
/* Change the format. */
|
/* Change the format. */
|
||||||
err = CA_SET(stream, kAudioStreamPropertyPhysicalFormat, &change_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,
|
/* The AudioStreamSetProperty is not only asynchronous,
|
||||||
* it is also not Atomic, in its behaviour. */
|
* 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);
|
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,
|
err = AudioObjectRemovePropertyListener(stream, &p_addr,
|
||||||
ca_change_format_listener,
|
ca_change_format_listener,
|
||||||
&wakeup);
|
&wakeup);
|
||||||
|
|
Loading…
Reference in New Issue