mirror of
https://github.com/mpv-player/mpv
synced 2024-12-25 16:33:02 +00:00
ao_wasapi: do not pass nonsense to drivers with double
This tried to use AF_FORMAT_DOUBLE as KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, with wBitsPerSample==64. This is probably not allowed, and drivers appear to react inconsistently to it. (With one user, the format was accepted during format negotiation, but then rejected on actual init.) Remove it, which essentially forces it to fall back to some other format. (Looks like it'll use af_select_best_samplerate(), which would probably make it try S32 next.) The af_fmt_from_planar() is so that we don't have to care about AF_FORMAT_FLOATP. Wasapi always requires packed data anyway. This should actually handle other potentially unknown sample formats better. This changes that set_waveformat() always set the exact format. Now it might set a "close" format instead. But all callers seem to deal with this well. Although in theory, callers should probably handle the fallback. The next cleanup (if ever) can take care of this.
This commit is contained in:
parent
4d07fce041
commit
c68be80a63
@ -88,10 +88,12 @@ static const GUID *format_to_subtype(int format)
|
||||
return wasapi_fmt_table[i].subtype;
|
||||
}
|
||||
return &KSDATAFORMAT_SPECIFIER_NONE;
|
||||
} else if (af_fmt_is_float(format)) {
|
||||
} else if (format == AF_FORMAT_FLOAT) {
|
||||
return &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
|
||||
} else if (af_fmt_is_int(format)) {
|
||||
return &KSDATAFORMAT_SUBTYPE_PCM;
|
||||
}
|
||||
return &KSDATAFORMAT_SUBTYPE_PCM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// "solve" the under-determined inverse of format_to_subtype by assuming the
|
||||
@ -124,13 +126,27 @@ static void set_waveformat(WAVEFORMATEXTENSIBLE *wformat,
|
||||
int format, WORD valid_bits,
|
||||
DWORD samplerate, struct mp_chmap *channels)
|
||||
{
|
||||
// First find a format that is actually representable.
|
||||
// (Notably excludes AF_FORMAT_DOUBLE.)
|
||||
const GUID *sub_format = &KSDATAFORMAT_SPECIFIER_NONE;
|
||||
int alt_formats[AF_FORMAT_COUNT];
|
||||
af_get_best_sample_formats(format, alt_formats);
|
||||
for (int n = 0; alt_formats[n]; n++) {
|
||||
const GUID *guid = format_to_subtype(alt_formats[n]);
|
||||
if (guid) {
|
||||
format = alt_formats[n];
|
||||
sub_format = guid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wformat->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
wformat->Format.nChannels = channels->num;
|
||||
wformat->Format.nSamplesPerSec = samplerate;
|
||||
wformat->Format.wBitsPerSample = af_fmt_to_bytes(format) * 8;
|
||||
wformat->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
|
||||
|
||||
wformat->SubFormat = *format_to_subtype(format);
|
||||
wformat->SubFormat = *sub_format;
|
||||
wformat->Samples.wValidBitsPerSample =
|
||||
valid_bits ? valid_bits : wformat->Format.wBitsPerSample;
|
||||
wformat->dwChannelMask = mp_chmap_to_waveext(channels);
|
||||
@ -318,10 +334,10 @@ static bool search_sample_formats(struct ao *ao, WAVEFORMATEXTENSIBLE *wformat,
|
||||
int samplerate, struct mp_chmap *channels)
|
||||
{
|
||||
// some common bit depths / container sizes (requests welcome)
|
||||
int try[] = {AF_FORMAT_DOUBLE, AF_FORMAT_FLOAT, AF_FORMAT_S32,
|
||||
int try[] = {AF_FORMAT_FLOAT , AF_FORMAT_S32 ,
|
||||
AF_FORMAT_S24 , AF_FORMAT_S32 , AF_FORMAT_S16,
|
||||
AF_FORMAT_U8 , 0};
|
||||
unsigned valid[] = {0 , 0, 0,
|
||||
unsigned valid[] = {0 , 0,
|
||||
0 , 24, 0,
|
||||
0 };
|
||||
for (int i = 0; try[i]; i++) {
|
||||
@ -596,6 +612,8 @@ static HRESULT fix_format(struct ao *ao)
|
||||
bufferPeriod = bufferDuration = devicePeriod;
|
||||
}
|
||||
|
||||
ao->format = af_fmt_from_planar(ao->format);
|
||||
|
||||
// handle unsupported buffer size hopefully this shouldn't happen because of
|
||||
// the above integer device period
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd370875%28v=vs.85%29.aspx
|
||||
|
Loading…
Reference in New Issue
Block a user