From: Giovanni Mascellani <gmascellani@codeweavers.com> --- dlls/mmdevapi/client.c | 216 ++++++++++++++++------------------ dlls/mmdevapi/tests/capture.c | 48 ++++++-- dlls/mmdevapi/tests/render.c | 20 ++-- 3 files changed, 155 insertions(+), 129 deletions(-) diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index deab9cb0050..ef3e319fb89 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -359,122 +359,69 @@ skip: return wcsdup(name); } -static HRESULT validate_wfx(const WAVEFORMATEX *fmt, AUDCLNT_SHAREMODE share_mode) -{ - BOOL exclusive = (share_mode == AUDCLNT_SHAREMODE_EXCLUSIVE); - const WAVEFORMATEXTENSIBLE *fmtx = (const void *)fmt; - HRESULT ret = S_OK; +HRESULT validate_fmt(const WAVEFORMATEXTENSIBLE *fmt, BOOL compatible) +{ + WAVEFORMATEXTENSIBLE fmt2 = *fmt; + HRESULT ret; + + /* Reduce non-extensible formats to extensible ones. */ + if (fmt2.Format.wFormatTag != WAVE_FORMAT_EXTENSIBLE) + { + switch (fmt2.Format.wFormatTag) + { + case WAVE_FORMAT_PCM: fmt2.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; break; + case WAVE_FORMAT_IEEE_FLOAT: fmt2.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; break; + default: return AUDCLNT_E_UNSUPPORTED_FORMAT; + } - if (share_mode != AUDCLNT_SHAREMODE_SHARED && share_mode != AUDCLNT_SHAREMODE_EXCLUSIVE) - return E_INVALIDARG; + if (fmt2.Format.nChannels > 2) + return E_INVALIDARG; - if (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - if (fmt->cbSize < sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)) - ret = E_INVALIDARG; - else if (fmt->nAvgBytesPerSec == 0 || fmt->nBlockAlign == 0 || - (fmtx->Samples.wValidBitsPerSample > fmt->wBitsPerSample)) - ret = E_INVALIDARG; - else if (fmt->nChannels == 0) - ret = AUDCLNT_E_UNSUPPORTED_FORMAT; + fmt2.dwChannelMask = (1u << fmt2.Format.nChannels) - 1; + fmt2.Samples.wValidBitsPerSample = fmt2.Format.wBitsPerSample; + fmt2.Format.cbSize = sizeof(fmt2) - sizeof(fmt2.Format); } - if (FAILED(ret)) - return ret; - - if (fmt->nSamplesPerSec == 0 || fmt->nBlockAlign == 0) + if (fmt2.Format.cbSize < sizeof(fmt2) - sizeof(fmt2.Format)) ret = E_INVALIDARG; - - switch (fmt->wFormatTag) { - case WAVE_FORMAT_EXTENSIBLE: - if ((fmt->cbSize != sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX) && - fmt->cbSize != sizeof(WAVEFORMATEXTENSIBLE)) || - fmt->nBlockAlign != fmt->wBitsPerSample / 8 * fmt->nChannels || - fmtx->Samples.wValidBitsPerSample > fmt->wBitsPerSample || - fmt->nAvgBytesPerSec != fmt->nBlockAlign * fmt->nSamplesPerSec) { - ret = E_INVALIDARG; - } - - if (exclusive) { - UINT32 mask = 0, i, channels = 0; - - if (!(fmtx->dwChannelMask & (SPEAKER_ALL | SPEAKER_RESERVED))) { - for (i = 1; !(i & SPEAKER_RESERVED); i <<= 1) { - if (i & fmtx->dwChannelMask) { - mask |= i; - ++channels; - } - } - - if (channels != fmt->nChannels || (fmtx->dwChannelMask & ~mask)) { - ret = AUDCLNT_E_UNSUPPORTED_FORMAT; - break; - } - } else { - ret = AUDCLNT_E_UNSUPPORTED_FORMAT; - break; - } - } - - if (IsEqualGUID(&fmtx->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) { - if (fmt->wBitsPerSample != 32) { - ret = E_INVALIDARG; - break; - } - - if (fmtx->Samples.wValidBitsPerSample != fmt->wBitsPerSample) { - ret = S_FALSE; - } - } else if (IsEqualGUID(&fmtx->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) { - if (!fmt->wBitsPerSample || fmt->wBitsPerSample > 32 || fmt->wBitsPerSample % 8) { - ret = E_INVALIDARG; - break; - } - - if (fmtx->Samples.wValidBitsPerSample != fmt->wBitsPerSample && - !(fmt->wBitsPerSample == 32 && - fmtx->Samples.wValidBitsPerSample == 24)) { - ret = S_FALSE; - break; - } - } else { - ret = AUDCLNT_E_UNSUPPORTED_FORMAT; - break; - } - break; - - case WAVE_FORMAT_ALAW: - case WAVE_FORMAT_MULAW: - if (fmt->wBitsPerSample != 8) { - ret = E_INVALIDARG; - break; - } - /* Fall-through */ - case WAVE_FORMAT_IEEE_FLOAT: - if (fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT && fmt->wBitsPerSample != 32) { - ret = E_INVALIDARG; - break; - } - /* Fall-through */ - case WAVE_FORMAT_PCM: - if (fmt->wFormatTag == WAVE_FORMAT_PCM && - (!fmt->wBitsPerSample || fmt->wBitsPerSample > 32 || fmt->wBitsPerSample % 8)) { - ret = E_INVALIDARG; - break; - } - - if (fmt->nChannels > 2) { - ret = AUDCLNT_E_UNSUPPORTED_FORMAT; - break; - } - - /* fmt->cbSize, fmt->nBlockAlign and fmt->nAvgBytesPerSec seem to be - * ignored, invalid values are happily accepted. */ - break; - - default: + else if (fmt2.Format.nChannels == 0 || fmt2.Format.nSamplesPerSec == 0) + ret = E_INVALIDARG; + else if (fmt2.Format.nBlockAlign != fmt2.Format.nChannels * fmt2.Format.wBitsPerSample / 8) + ret = E_INVALIDARG; + else if (fmt2.Format.nAvgBytesPerSec != fmt2.Format.nBlockAlign * fmt2.Format.nSamplesPerSec) + ret = E_INVALIDARG; + else if (fmt2.Samples.wValidBitsPerSample == 0) + ret = E_INVALIDARG; + else if (fmt2.Samples.wValidBitsPerSample > fmt2.Format.wBitsPerSample) + ret = E_INVALIDARG; + else if (IsEqualGUID(&fmt2.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) + { + if (fmt2.Format.wBitsPerSample != 8 && fmt2.Format.wBitsPerSample != 16 + && fmt2.Format.wBitsPerSample != 24 && fmt2.Format.wBitsPerSample != 32) + ret = E_INVALIDARG; + else if (fmt2.Format.wBitsPerSample == 32 && fmt2.Samples.wValidBitsPerSample == 24) + ret = S_OK; + else if (fmt2.Samples.wValidBitsPerSample != fmt2.Format.wBitsPerSample) ret = AUDCLNT_E_UNSUPPORTED_FORMAT; - break; + else + ret = S_OK; } + else if (IsEqualGUID(&fmt2.SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) + { + if (fmt2.Format.wBitsPerSample != 32 && fmt2.Format.wBitsPerSample != 64) + ret = E_INVALIDARG; + else if (fmt2.Format.wBitsPerSample != 32) + ret = AUDCLNT_E_UNSUPPORTED_FORMAT; + else if (fmt2.Samples.wValidBitsPerSample != fmt2.Format.wBitsPerSample) + ret = AUDCLNT_E_UNSUPPORTED_FORMAT; + else + ret = S_OK; + } + else + ret = AUDCLNT_E_UNSUPPORTED_FORMAT; + + if (!compatible && ret == S_OK) + ret = AUDCLNT_E_UNSUPPORTED_FORMAT; return ret; } @@ -487,6 +434,7 @@ static HRESULT stream_init(struct audio_client *client, const BOOLEAN force_def_ struct create_stream_params params; UINT32 i, channel_count; stream_handle stream; + BOOL compatible; WCHAR *name; HRESULT hr; @@ -514,10 +462,32 @@ static HRESULT stream_init(struct audio_client *client, const BOOLEAN force_def_ if (flags & AUDCLNT_STREAMFLAGS_CROSSPROCESS) FIXME("Cross-process sessions not supported\n"); - hr = validate_wfx(fmt, mode); + if (mode != AUDCLNT_SHAREMODE_SHARED && mode != AUDCLNT_SHAREMODE_EXCLUSIVE) + return E_INVALIDARG; + + if (mode == AUDCLNT_SHAREMODE_EXCLUSIVE) { + if (flags & AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM) + return E_INVALIDARG; + + compatible = TRUE; + } else { + WAVEFORMATEX *mix_fmt; + + if (FAILED(hr = IAudioClient3_GetMixFormat(&client->IAudioClient3_iface, &mix_fmt))) + return hr; + + if (flags & AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM) + compatible = TRUE; + else if (flags & AUDCLNT_STREAMFLAGS_RATEADJUST) + compatible = fmt->nChannels == mix_fmt->nChannels; + else + compatible = fmt->nSamplesPerSec == mix_fmt->nSamplesPerSec && fmt->nChannels == mix_fmt->nChannels; + + CoTaskMemFree(mix_fmt); + } + + hr = validate_fmt((const WAVEFORMATEXTENSIBLE *)fmt, compatible); - if (hr == S_FALSE) - hr = AUDCLNT_E_UNSUPPORTED_FORMAT; if (hr != S_OK) return hr; @@ -880,6 +850,7 @@ static HRESULT WINAPI client_IsFormatSupported(IAudioClient3 *iface, AUDCLNT_SHA { struct audio_client *This = impl_from_IAudioClient3(iface); struct is_format_supported_params params; + BOOL compatible; HRESULT hr; TRACE("(%p)->(%x, %p, %p)\n", This, mode, fmt, out); @@ -892,7 +863,26 @@ static HRESULT WINAPI client_IsFormatSupported(IAudioClient3 *iface, AUDCLNT_SHA dump_fmt(fmt); - hr = validate_wfx(fmt, mode); + if (mode != AUDCLNT_SHAREMODE_SHARED && mode != AUDCLNT_SHAREMODE_EXCLUSIVE) + return E_INVALIDARG; + + if (mode == AUDCLNT_SHAREMODE_EXCLUSIVE) { + compatible = TRUE; + } else { + WAVEFORMATEX *mix_fmt; + + if (FAILED(hr = IAudioClient3_GetMixFormat(iface, &mix_fmt))) + return hr; + + compatible = fmt->nSamplesPerSec == mix_fmt->nSamplesPerSec && fmt->nChannels == mix_fmt->nChannels; + + CoTaskMemFree(mix_fmt); + } + + hr = validate_fmt((const WAVEFORMATEXTENSIBLE *)fmt, TRUE); + + if (hr == S_OK && !compatible) + hr = S_FALSE; if (FAILED(hr)) return hr; diff --git a/dlls/mmdevapi/tests/capture.c b/dlls/mmdevapi/tests/capture.c index 34e47b56fb1..f14882997f4 100644 --- a/dlls/mmdevapi/tests/capture.c +++ b/dlls/mmdevapi/tests/capture.c @@ -563,10 +563,41 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) IAudioClient *ac; HRESULT hr, hrs, expected; WAVEFORMATEX *pwfx, *pwfx2; - BOOL compatible, extensible; + BOOL compatible, extensible, channel_mismatch = FALSE, fmt24on32; extensible = fmt->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE; + if (extensible) + { + switch (fmt->Format.nChannels) + { + case 1: + channel_mismatch = fmt->dwChannelMask != KSAUDIO_SPEAKER_MONO; + break; + + case 2: + channel_mismatch = fmt->dwChannelMask != KSAUDIO_SPEAKER_STEREO; + break; + + case 4: + channel_mismatch = fmt->dwChannelMask != KSAUDIO_SPEAKER_QUAD; + break; + + case 6: + channel_mismatch = fmt->dwChannelMask != KSAUDIO_SPEAKER_5POINT1; + break; + + case 8: + channel_mismatch = fmt->dwChannelMask != KSAUDIO_SPEAKER_7POINT1_SURROUND + && fmt->dwChannelMask != KSAUDIO_SPEAKER_7POINT1; + break; + } + } + + /* Some Wine drivers do not support 24-on-32 bits. */ + fmt24on32 = fmt->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE && fmt->Format.wBitsPerSample == 32 + && fmt->Samples.wValidBitsPerSample == 24; + hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac); ok(hr == S_OK, "Activation failed with %08lx\n", hr); @@ -598,14 +629,12 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) /* Correct formats should be accepted, possibly with S_FALSE if they are not compatible. */ if (!compatible) expected = S_FALSE; - todo_wine_if(hr != expected) ok(hr == expected, "IsFormatSupported() returns %08lx, expected %08lx\n", hr, expected); } else { /* With incorrect formats it's a mess. Native emits all sorts of possible * error codes, including S_OK and S_FALSE, without any apparent logic. * I tried to find some regularity, but it seems hopeless. Also different * drivers do wildly different things. */ - todo_wine_if(SUCCEEDED(hr)) ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == E_INVALIDARG || broken(hr == S_OK || hr == S_FALSE), "IsFormatSupported() returns %08lx\n", hr); } @@ -630,7 +659,7 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) if (mode == AUDCLNT_SHAREMODE_SHARED) { compatible = fmt->Format.nSamplesPerSec == pwfx->nSamplesPerSec && fmt->Format.nChannels == pwfx->nChannels; expected = validate_fmt(fmt, compatible); - todo_wine_if(hr != expected) + todo_wine_if(hr != expected && fmt24on32) ok(hr == expected, "Initialize() returns %08lx, expected %08lx\n", hr, expected); } else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) /* Unsupported format implies "create failed" and shadows "not allowed" */ @@ -638,7 +667,8 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) "Initialize() returns %08lx(%08lx)\n", hr, hrs); else /* For some drivers Initialize() doesn't match IsFormatSupported(). */ - todo_wine_if(hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED || (hr == S_OK && hrs != S_OK)) + todo_wine_if(hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED + || (hr == AUDCLNT_E_UNSUPPORTED_FORMAT && hrs == S_OK && channel_mismatch)) ok(hrs == S_OK ? hr == S_OK || broken(hr == E_INVALIDARG) : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == E_INVALIDARG, "Initialize() returns %08lx\n", hr); @@ -659,7 +689,7 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) if (mode == AUDCLNT_SHAREMODE_SHARED) { compatible = fmt->Format.nChannels == pwfx->nChannels; expected = validate_fmt(fmt, compatible); - todo_wine_if(hr != expected) + todo_wine_if(hr != expected && fmt24on32) ok(hr == expected, "Initialize(RATEADJUST) returns %08lx, expected %08lx\n", hr, expected); } else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) /* Unsupported format implies "create failed" and shadows "not allowed" */ @@ -667,7 +697,8 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) "Initialize() returns %08lx(%08lx)\n", hr, hrs); else /* For some drivers Initialize() doesn't match IsFormatSupported(). */ - todo_wine_if(hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED || (hr == S_OK && hrs != S_OK)) + todo_wine_if(hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED + || (hr == AUDCLNT_E_UNSUPPORTED_FORMAT && hrs == S_OK && channel_mismatch)) ok(hrs == S_OK ? hr == S_OK || broken(hr == E_INVALIDARG) : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == E_INVALIDARG, "Initialize() returns %08lx\n", hr); @@ -684,10 +715,9 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) hr = IAudioClient_Initialize(ac, mode, AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM, 5000000, 0, (WAVEFORMATEX*)fmt, NULL); if (mode == AUDCLNT_SHAREMODE_SHARED) { expected = validate_fmt(fmt, TRUE); - todo_wine_if(hr != expected) + todo_wine_if(hr != expected && (channel_mismatch || fmt24on32)) ok(hr == expected, "Initialize(AUTOCONVERTPCM) returns %08lx\n", hr); } else { - todo_wine_if(hr != E_INVALIDARG) ok(hr == E_INVALIDARG, "Initialize(AUTOCONVERTPCM) returns %08lx\n", hr); } diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 790a33a73a8..bc3f7f22fca 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -789,6 +789,7 @@ void fill_wave_formats(const WAVEFORMATEXTENSIBLE *base_fmt) fmt->Format.cbSize -= 1; } +/* Identical to dlls/mmdevapi/client.c. */ HRESULT validate_fmt(const WAVEFORMATEXTENSIBLE *fmt, BOOL compatible) { WAVEFORMATEXTENSIBLE fmt2 = *fmt; @@ -861,7 +862,7 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) IAudioClient *ac; HRESULT hr, hrs, expected; WAVEFORMATEX *pwfx, *pwfx2; - BOOL compatible, channel_mismatch = FALSE; + BOOL compatible, channel_mismatch = FALSE, fmt24on32; if (fmt->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) { @@ -890,6 +891,10 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) } } + /* Some Wine drivers do not support 24-on-32 bits. */ + fmt24on32 = fmt->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE && fmt->Format.wBitsPerSample == 32 + && fmt->Samples.wValidBitsPerSample == 24; + hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac); ok(hr == S_OK, "Activation failed with %08lx\n", hr); @@ -911,7 +916,6 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) /* Correct formats should be accepted, possibly with S_FALSE if they are not compatible. */ if (!compatible) expected = S_FALSE; - todo_wine_if(hr != expected) ok(hr == expected || broken(hr == S_OK || (hr == S_FALSE && channel_mismatch)) /* Some drivers are more relaxed. */, "IsFormatSupported() returns %08lx, expected %08lx\n", hr, expected); } else { @@ -919,7 +923,6 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) * error codes, including S_OK and S_FALSE, without any apparent logic. * I tried to find some regularity, but it seems hopeless. Also different * drivers do wildly different things. */ - todo_wine_if(SUCCEEDED(hr)) ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == E_INVALIDARG || broken(hr == S_OK || hr == S_FALSE), "IsFormatSupported() returns %08lx\n", hr); } @@ -944,15 +947,17 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) if (mode == AUDCLNT_SHAREMODE_SHARED) { compatible = fmt->Format.nSamplesPerSec == pwfx->nSamplesPerSec && fmt->Format.nChannels == pwfx->nChannels; expected = validate_fmt(fmt, compatible); - todo_wine_if(hr != expected) + todo_wine_if(hr != expected && (channel_mismatch || fmt24on32)) ok(hr == expected || broken(hr == S_OK) /* Some drivers are more relaxed. */, "Initialize() returns %08lx, expected %08lx\n", hr, expected); } else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) /* Unsupported format implies "create failed" and shadows "not allowed" */ + todo_wine_if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && channel_mismatch) ok(hrs == hexcl && (hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == hrs), "Initialize() returns %08lx(%08lx)\n", hr, hrs); else /* For some drivers Initialize() doesn't match IsFormatSupported(). */ + todo_wine_if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && hrs == S_OK && channel_mismatch) ok(hrs == S_OK ? hr == S_OK || broken(hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == E_INVALIDARG) : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == E_INVALIDARG || broken(hr == S_OK), @@ -974,15 +979,17 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) if (mode == AUDCLNT_SHAREMODE_SHARED) { compatible = fmt->Format.nChannels == pwfx->nChannels; expected = validate_fmt(fmt, compatible); - todo_wine_if(hr != expected) + todo_wine_if(hr != expected && (channel_mismatch || fmt24on32)) ok(hr == expected || broken(hr == S_OK || (hr == AUDCLNT_E_UNSUPPORTED_FORMAT && channel_mismatch)) /* Some drivers are more relaxed. */, "Initialize(RATEADJUST) returns %08lx, expected %08lx\n", hr, expected); } else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) /* Unsupported format implies "create failed" and shadows "not allowed" */ + todo_wine_if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && channel_mismatch) ok(hrs == hexcl && (hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == hrs), "Initialize(RATEADJUST) returns %08lx(%08lx)\n", hr, hrs); else /* For some drivers Initialize() doesn't match IsFormatSupported(). */ + todo_wine_if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && hrs == S_OK && channel_mismatch) ok(hrs == S_OK ? hr == S_OK || broken(hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == E_INVALIDARG) : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == E_INVALIDARG || broken(hr == S_OK), @@ -1000,10 +1007,9 @@ static void test_format(AUDCLNT_SHAREMODE mode, WAVEFORMATEXTENSIBLE *fmt) hr = IAudioClient_Initialize(ac, mode, AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM, 5000000, 0, (WAVEFORMATEX*)fmt, NULL); if (mode == AUDCLNT_SHAREMODE_SHARED) { expected = validate_fmt(fmt, TRUE); - todo_wine_if(hr != expected) + todo_wine_if(hr != expected && (channel_mismatch || fmt24on32)) ok(hr == expected, "Initialize(AUTOCONVERTPCM) returns %08lx, expected %08lx\n", hr, expected); } else { - todo_wine_if(hr != E_INVALIDARG) ok(hr == E_INVALIDARG, "Initialize(AUTOCONVERTPCM) returns %08lx\n", hr); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10243