From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/mmdevapi/tests/capture.c | 8 +++++++- dlls/mmdevapi/tests/render.c | 7 ++++++- 2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/dlls/mmdevapi/tests/capture.c b/dlls/mmdevapi/tests/capture.c index 24a9c7d4efb..918a6d0c2f6 100644 --- a/dlls/mmdevapi/tests/capture.c +++ b/dlls/mmdevapi/tests/capture.c @@ -473,20 +473,26 @@ static void test_audioclient(void) &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)?"FLOAT":"Other")); }
+ pwfx2 = (WAVEFORMATEX*)0xDEADF00D; hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2); ok(hr == S_OK, "Valid IsFormatSupported(Shared) call returns %08lx\n", hr); ok(pwfx2 == NULL, "pwfx2 is non-null\n"); - CoTaskMemFree(pwfx2);
hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, NULL, NULL); ok(hr == E_POINTER, "IsFormatSupported(NULL) call returns %08lx\n", hr);
+ pwfx2 = (WAVEFORMATEX*)0xDEADF00D; + hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, NULL, &pwfx2); + ok(hr == E_POINTER, "IsFormatSupported(NULL) call returns %08lx\n", hr); + ok(pwfx2 == NULL, "pwfx2 is non-null\n"); + hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, NULL); ok(hr == E_POINTER, "IsFormatSupported(Shared,NULL) call returns %08lx\n", hr);
hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL); ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "IsFormatSupported(Exclusive) call returns %08lx\n", hr);
+ pwfx2 = (WAVEFORMATEX*)0xDEADF00D; hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, &pwfx2); ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "IsFormatSupported(Exclusive) call returns %08lx\n", hr); ok(pwfx2 == NULL, "pwfx2 non-null on exclusive IsFormatSupported\n"); diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index f0dc29dd1ed..1f8b2655074 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -259,14 +259,19 @@ static void test_audioclient(void) CoTaskMemFree(pwfx2); }
+ pwfx2 = (WAVEFORMATEX*)0xDEADF00D; hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2); ok(hr == S_OK, "Valid IsFormatSupported(Shared) call returns %08lx\n", hr); ok(pwfx2 == NULL, "pwfx2 is non-null\n"); - CoTaskMemFree(pwfx2);
hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, NULL, NULL); ok(hr == E_POINTER, "IsFormatSupported(NULL) call returns %08lx\n", hr);
+ pwfx2 = (WAVEFORMATEX*)0xDEADF00D; + hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, NULL, &pwfx2); + ok(hr == E_POINTER, "IsFormatSupported(NULL) call returns %08lx\n", hr); + ok(pwfx2 == NULL, "pwfx2 is non-null\n"); + hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, NULL); ok(hr == E_POINTER, "IsFormatSupported(Shared,NULL) call returns %08lx\n", hr);
From: Giovanni Mascellani gmascellani@codeweavers.com
The formal validation of the audio format is the same for all drivers, there is no point having duplicated and different validation code in each driver.
The code I copied here is from the Pulse driver, which looks the most complete. It probably can be improved, but so far I'm just refactoring.
Not all driver-specific validation code is removed yet, because the suggested format output must be handled before. --- dlls/mmdevapi/client.c | 145 +++++++++++++++++++++++++++-- dlls/winealsa.drv/alsa.c | 21 ----- dlls/winecoreaudio.drv/coreaudio.c | 18 +--- dlls/winepulse.drv/pulse.c | 23 +---- 4 files changed, 144 insertions(+), 63 deletions(-)
diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index 39cbae27b34..fc3a0208f71 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -366,6 +366,123 @@ 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; + + if (share_mode != AUDCLNT_SHAREMODE_SHARED && share_mode != AUDCLNT_SHAREMODE_EXCLUSIVE) + 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; + } + + if (FAILED(ret)) + return ret; + + 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: + ret = AUDCLNT_E_UNSUPPORTED_FORMAT; + break; + } + + return ret; +} + static HRESULT stream_init(struct audio_client *client, const BOOLEAN force_def_period, const AUDCLNT_SHAREMODE mode, const DWORD flags, REFERENCE_TIME duration, REFERENCE_TIME period, @@ -375,6 +492,7 @@ static HRESULT stream_init(struct audio_client *client, const BOOLEAN force_def_ UINT32 i, channel_count; stream_handle stream; WCHAR *name; + HRESULT hr;
if (!fmt) return E_POINTER; @@ -398,6 +516,13 @@ static HRESULT stream_init(struct audio_client *client, const BOOLEAN force_def_ return E_INVALIDARG; }
+ hr = validate_wfx(fmt, mode); + + if (hr == S_FALSE) + hr = AUDCLNT_E_UNSUPPORTED_FORMAT; + if (hr != S_OK) + return hr; + sessions_lock();
if (client->stream) { @@ -757,11 +882,20 @@ static HRESULT WINAPI client_IsFormatSupported(IAudioClient3 *iface, AUDCLNT_SHA { struct audio_client *This = impl_from_IAudioClient3(iface); struct is_format_supported_params params; + HRESULT hr;
TRACE("(%p)->(%x, %p, %p)\n", This, mode, fmt, out);
- if (fmt) - dump_fmt(fmt); + if (out) + *out = NULL; + + if (!fmt || (mode == AUDCLNT_SHAREMODE_SHARED && !out)) + return E_POINTER; + + dump_fmt(fmt); + + if (FAILED(hr = validate_wfx(fmt, mode))) + return hr;
params.device = This->device_name; params.flow = This->dataflow; @@ -769,11 +903,8 @@ static HRESULT WINAPI client_IsFormatSupported(IAudioClient3 *iface, AUDCLNT_SHA params.fmt_in = fmt; params.fmt_out = NULL;
- if (out) { - *out = NULL; - if (mode == AUDCLNT_SHAREMODE_SHARED) - params.fmt_out = CoTaskMemAlloc(sizeof(*params.fmt_out)); - } + if (out && mode == AUDCLNT_SHAREMODE_SHARED) + params.fmt_out = CoTaskMemAlloc(sizeof(*params.fmt_out));
wine_unix_call(is_format_supported, ¶ms);
diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c index 5bd1d71d837..15805d2a1e9 100644 --- a/dlls/winealsa.drv/alsa.c +++ b/dlls/winealsa.drv/alsa.c @@ -1873,27 +1873,6 @@ static NTSTATUS alsa_is_format_supported(void *args) int err; int alsa_channels, alsa_channel_map[32];
- params->result = S_OK; - - if(!params->fmt_in || (params->share == AUDCLNT_SHAREMODE_SHARED && !params->fmt_out)) - params->result = E_POINTER; - else if(params->share != AUDCLNT_SHAREMODE_SHARED && params->share != AUDCLNT_SHAREMODE_EXCLUSIVE) - params->result = E_INVALIDARG; - else if(params->fmt_in->wFormatTag == WAVE_FORMAT_EXTENSIBLE){ - if(params->fmt_in->cbSize < sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)) - params->result = E_INVALIDARG; - else if(params->fmt_in->nAvgBytesPerSec == 0 || params->fmt_in->nBlockAlign == 0 || - (fmtex->Samples.wValidBitsPerSample > params->fmt_in->wBitsPerSample)) - params->result = E_INVALIDARG; - } - if(FAILED(params->result)) - return STATUS_SUCCESS; - - if(params->fmt_in->nChannels == 0){ - params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; - return STATUS_SUCCESS; - } - params->result = alsa_open_device(params->device, params->flow, &pcm_handle, &hw_params); if(FAILED(params->result)) return STATUS_SUCCESS; diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index ced8f3838fb..b19f7ba3854 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -1100,30 +1100,20 @@ static NTSTATUS unix_is_format_supported(void *args) AudioComponentInstance unit; const AudioDeviceID dev_id = dev_id_from_device(params->device);
- params->result = S_OK; - - if(!params->fmt_in || (params->share == AUDCLNT_SHAREMODE_SHARED && !params->fmt_out)) - params->result = E_POINTER; - else if(params->share != AUDCLNT_SHAREMODE_SHARED && params->share != AUDCLNT_SHAREMODE_EXCLUSIVE) - params->result = E_INVALIDARG; - else if(params->fmt_in->wFormatTag == WAVE_FORMAT_EXTENSIBLE){ - if(params->fmt_in->cbSize < sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)) - params->result = E_INVALIDARG; - else if(params->fmt_in->nAvgBytesPerSec == 0 || params->fmt_in->nBlockAlign == 0 || - fmtex->Samples.wValidBitsPerSample > params->fmt_in->wBitsPerSample) - params->result = E_INVALIDARG; - else if(fmtex->Samples.wValidBitsPerSample < params->fmt_in->wBitsPerSample) + if(params->fmt_in->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { + if (fmtex->Samples.wValidBitsPerSample < params->fmt_in->wBitsPerSample) goto unsupported; else if(params->share == AUDCLNT_SHAREMODE_EXCLUSIVE && (fmtex->dwChannelMask == 0 || fmtex->dwChannelMask & SPEAKER_RESERVED)) goto unsupported; } - if(FAILED(params->result)) return STATUS_SUCCESS;
if(params->fmt_in->nBlockAlign != params->fmt_in->nChannels * params->fmt_in->wBitsPerSample / 8 || params->fmt_in->nAvgBytesPerSec != params->fmt_in->nBlockAlign * params->fmt_in->nSamplesPerSec) goto unsupported;
+ params->result = S_OK; + if(params->fmt_in->nChannels == 0){ params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; return STATUS_SUCCESS; diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index 9a218e75c1b..9129b224c44 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -2076,27 +2076,8 @@ static NTSTATUS pulse_is_format_supported(void *args)
params->result = S_OK;
- if (!params->fmt_in || (params->share == AUDCLNT_SHAREMODE_SHARED && !params->fmt_out)) - params->result = E_POINTER; - else if (params->share != AUDCLNT_SHAREMODE_SHARED && params->share != AUDCLNT_SHAREMODE_EXCLUSIVE) - params->result = E_INVALIDARG; - else { - memcpy(&in, params->fmt_in, params->fmt_in->wFormatTag == WAVE_FORMAT_EXTENSIBLE ? - sizeof(in) : sizeof(in.Format)); - - if (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - if (fmt->cbSize < sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)) - params->result = E_INVALIDARG; - else if (fmt->nAvgBytesPerSec == 0 || fmt->nBlockAlign == 0 || - (in.Samples.wValidBitsPerSample > fmt->wBitsPerSample)) - params->result = E_INVALIDARG; - else if (fmt->nChannels == 0) - params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; - } - } - - if (FAILED(params->result)) - return STATUS_SUCCESS; + memcpy(&in, params->fmt_in, params->fmt_in->wFormatTag == WAVE_FORMAT_EXTENSIBLE ? + sizeof(in) : sizeof(in.Format));
if (exclusive) out = ∈
From: Giovanni Mascellani gmascellani@codeweavers.com
According to the tests, it doesn't seem that the format suggested by IsFormatSupported() depends on the format supplied by the caller. It's just the mix format, so there is no need to have specialized handling for each driver. --- dlls/mmdevapi/client.c | 39 +++++---- dlls/mmdevapi/unixlib.h | 1 - dlls/winealsa.drv/alsa.c | 45 +--------- dlls/winecoreaudio.drv/coreaudio.c | 38 --------- dlls/winepulse.drv/pulse.c | 127 ++--------------------------- 5 files changed, 33 insertions(+), 217 deletions(-)
diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index fc3a0208f71..94d831370ab 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -894,26 +894,37 @@ static HRESULT WINAPI client_IsFormatSupported(IAudioClient3 *iface, AUDCLNT_SHA
dump_fmt(fmt);
- if (FAILED(hr = validate_wfx(fmt, mode))) + hr = validate_wfx(fmt, mode); + + if (FAILED(hr)) return hr;
- params.device = This->device_name; - params.flow = This->dataflow; - params.share = mode; - params.fmt_in = fmt; - params.fmt_out = NULL; + if (hr == S_OK) { + params.device = This->device_name; + params.flow = This->dataflow; + params.share = mode; + params.fmt_in = fmt;
- if (out && mode == AUDCLNT_SHAREMODE_SHARED) - params.fmt_out = CoTaskMemAlloc(sizeof(*params.fmt_out)); + wine_unix_call(is_format_supported, ¶ms);
- wine_unix_call(is_format_supported, ¶ms); + hr = params.result; + }
- if (params.result == S_FALSE) - *out = ¶ms.fmt_out->Format; - else - CoTaskMemFree(params.fmt_out); + if (hr == S_FALSE) { + if (mode == AUDCLNT_SHAREMODE_EXCLUSIVE) { + return AUDCLNT_E_UNSUPPORTED_FORMAT; + } else { + if (FAILED(hr = IAudioClient3_GetMixFormat(iface, out))) + return hr; + return S_FALSE; + } + } + + if (hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED && This->dataflow == eCapture) + hr = AUDCLNT_E_UNSUPPORTED_FORMAT; + + return hr;
- return params.result; }
static HRESULT WINAPI client_GetMixFormat(IAudioClient3 *iface, WAVEFORMATEX **pwfx) diff --git a/dlls/mmdevapi/unixlib.h b/dlls/mmdevapi/unixlib.h index 033cd2085ea..3df13e93b39 100644 --- a/dlls/mmdevapi/unixlib.h +++ b/dlls/mmdevapi/unixlib.h @@ -136,7 +136,6 @@ struct is_format_supported_params EDataFlow flow; AUDCLNT_SHAREMODE share; const WAVEFORMATEX *fmt_in; - WAVEFORMATEXTENSIBLE *fmt_out; HRESULT result; };
diff --git a/dlls/winealsa.drv/alsa.c b/dlls/winealsa.drv/alsa.c index 15805d2a1e9..524ede37172 100644 --- a/dlls/winealsa.drv/alsa.c +++ b/dlls/winealsa.drv/alsa.c @@ -1863,12 +1863,10 @@ static NTSTATUS alsa_release_capture_buffer(void *args) static NTSTATUS alsa_is_format_supported(void *args) { struct is_format_supported_params *params = args; - const WAVEFORMATEXTENSIBLE *fmtex = (const WAVEFORMATEXTENSIBLE *)params->fmt_in; snd_pcm_t *pcm_handle; snd_pcm_hw_params_t *hw_params; snd_pcm_format_mask_t *formats = NULL; snd_pcm_format_t format; - WAVEFORMATEXTENSIBLE *closest = NULL; unsigned int max = 0, min = 0; int err; int alsa_channels, alsa_channel_map[32]; @@ -1896,12 +1894,6 @@ static NTSTATUS alsa_is_format_supported(void *args) goto exit; }
- closest = clone_format(params->fmt_in); - if(!closest){ - params->result = E_OUTOFMEMORY; - goto exit; - } - if((err = snd_pcm_hw_params_get_rate_min(hw_params, &min, NULL)) < 0){ params->result = AUDCLNT_E_DEVICE_INVALIDATED; WARN("Unable to get min rate: %d (%s)\n", err, snd_strerror(err)); @@ -1930,47 +1922,17 @@ static NTSTATUS alsa_is_format_supported(void *args) WARN("Unable to get max channels: %d (%s)\n", err, snd_strerror(err)); goto exit; } - if(params->fmt_in->nChannels > max){ + if(params->fmt_in->nChannels > max) params->result = S_FALSE; - closest->Format.nChannels = max; - }else if(params->fmt_in->nChannels < min){ + else if(params->fmt_in->nChannels < min) params->result = S_FALSE; - closest->Format.nChannels = min; - }
map_channels(params->flow, params->fmt_in, &alsa_channels, alsa_channel_map);
- if(alsa_channels > max){ - params->result = S_FALSE; - closest->Format.nChannels = max; - } - - if(closest->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) - closest->dwChannelMask = get_channel_mask(closest->Format.nChannels); - - if(params->fmt_in->nBlockAlign != params->fmt_in->nChannels * params->fmt_in->wBitsPerSample / 8 || - params->fmt_in->nAvgBytesPerSec != params->fmt_in->nBlockAlign * params->fmt_in->nSamplesPerSec || - (params->fmt_in->wFormatTag == WAVE_FORMAT_EXTENSIBLE && - fmtex->Samples.wValidBitsPerSample < params->fmt_in->wBitsPerSample)) + if(alsa_channels > max) params->result = S_FALSE;
- if(params->share == AUDCLNT_SHAREMODE_EXCLUSIVE && params->fmt_in->wFormatTag == WAVE_FORMAT_EXTENSIBLE){ - if(fmtex->dwChannelMask == 0 || fmtex->dwChannelMask & SPEAKER_RESERVED) - params->result = S_FALSE; - } - exit: - if(params->result == S_FALSE && !params->fmt_out) - params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; - - if(params->result == S_FALSE) { - closest->Format.nBlockAlign = closest->Format.nChannels * closest->Format.wBitsPerSample / 8; - closest->Format.nAvgBytesPerSec = closest->Format.nBlockAlign * closest->Format.nSamplesPerSec; - if(closest->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) - closest->Samples.wValidBitsPerSample = closest->Format.wBitsPerSample; - memcpy(params->fmt_out, closest, closest->Format.cbSize); - } - free(closest); free(formats); free(hw_params); snd_pcm_close(pcm_handle); @@ -2657,7 +2619,6 @@ static NTSTATUS alsa_wow64_is_format_supported(void *args) .flow = params32->flow, .share = params32->share, .fmt_in = ULongToPtr(params32->fmt_in), - .fmt_out = ULongToPtr(params32->fmt_out) }; alsa_is_format_supported(¶ms); params32->result = params.result; diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index b19f7ba3854..947cf441f10 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -1094,55 +1094,18 @@ static NTSTATUS unix_get_mix_format(void *args) static NTSTATUS unix_is_format_supported(void *args) { struct is_format_supported_params *params = args; - const WAVEFORMATEXTENSIBLE *fmtex = (const WAVEFORMATEXTENSIBLE *)params->fmt_in; AudioStreamBasicDescription dev_desc; AudioConverterRef converter; AudioComponentInstance unit; const AudioDeviceID dev_id = dev_id_from_device(params->device);
- if(params->fmt_in->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - if (fmtex->Samples.wValidBitsPerSample < params->fmt_in->wBitsPerSample) - goto unsupported; - else if(params->share == AUDCLNT_SHAREMODE_EXCLUSIVE && - (fmtex->dwChannelMask == 0 || fmtex->dwChannelMask & SPEAKER_RESERVED)) - goto unsupported; - } - - if(params->fmt_in->nBlockAlign != params->fmt_in->nChannels * params->fmt_in->wBitsPerSample / 8 || - params->fmt_in->nAvgBytesPerSec != params->fmt_in->nBlockAlign * params->fmt_in->nSamplesPerSec) - goto unsupported; - - params->result = S_OK; - - if(params->fmt_in->nChannels == 0){ - params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; - return STATUS_SUCCESS; - } unit = get_audiounit(params->flow, dev_id);
converter = NULL; params->result = ca_setup_audiounit(params->flow, unit, params->fmt_in, &dev_desc, &converter); AudioComponentInstanceDispose(unit); - if(FAILED(params->result)) goto unsupported; if(converter) AudioConverterDispose(converter);
- params->result = S_OK; - return STATUS_SUCCESS; - -unsupported: - if(params->fmt_out){ - struct get_mix_format_params get_mix_params = - { - .device = params->device, - .flow = params->flow, - .fmt = params->fmt_out, - }; - - unix_get_mix_format(&get_mix_params); - params->result = get_mix_params.result; - if(SUCCEEDED(params->result)) params->result = S_FALSE; - } - else params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; return STATUS_SUCCESS; }
@@ -2007,7 +1970,6 @@ static NTSTATUS unix_wow64_is_format_supported(void *args) .flow = params32->flow, .share = params32->share, .fmt_in = ULongToPtr(params32->fmt_in), - .fmt_out = ULongToPtr(params32->fmt_out) }; unix_is_format_supported(¶ms); params32->result = params.result; diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index 9129b224c44..6fabc396ebe 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -2069,128 +2069,12 @@ static NTSTATUS pulse_release_capture_buffer(void *args) static NTSTATUS pulse_is_format_supported(void *args) { struct is_format_supported_params *params = args; - WAVEFORMATEXTENSIBLE in; - WAVEFORMATEXTENSIBLE *out; - const WAVEFORMATEX *fmt = &in.Format; - const BOOLEAN exclusive = params->share == AUDCLNT_SHAREMODE_EXCLUSIVE;
- params->result = S_OK; - - memcpy(&in, params->fmt_in, params->fmt_in->wFormatTag == WAVE_FORMAT_EXTENSIBLE ? - sizeof(in) : sizeof(in.Format)); - - if (exclusive) - out = ∈ - else { - out = params->fmt_out; - memcpy(out, fmt, fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE ? - sizeof(*out) : sizeof((*out).Format)); - } - - 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 || - in.Samples.wValidBitsPerSample > fmt->wBitsPerSample || - fmt->nAvgBytesPerSec != fmt->nBlockAlign * fmt->nSamplesPerSec) { - params->result = E_INVALIDARG; - break; - } - - if (exclusive) { - UINT32 mask = 0, i, channels = 0; - - if (!(in.dwChannelMask & (SPEAKER_ALL | SPEAKER_RESERVED))) { - for (i = 1; !(i & SPEAKER_RESERVED); i <<= 1) { - if (i & in.dwChannelMask) { - mask |= i; - ++channels; - } - } - - if (channels != fmt->nChannels || (in.dwChannelMask & ~mask)) { - params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; - break; - } - } else { - params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; - break; - } - } - - if (IsEqualGUID(&in.SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) { - if (fmt->wBitsPerSample != 32) { - params->result = E_INVALIDARG; - break; - } - - if (in.Samples.wValidBitsPerSample != fmt->wBitsPerSample) { - params->result = S_FALSE; - out->Samples.wValidBitsPerSample = fmt->wBitsPerSample; - } - } else if (IsEqualGUID(&in.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) { - if (!fmt->wBitsPerSample || fmt->wBitsPerSample > 32 || fmt->wBitsPerSample % 8) { - params->result = E_INVALIDARG; - break; - } - - if (in.Samples.wValidBitsPerSample != fmt->wBitsPerSample && - !(fmt->wBitsPerSample == 32 && - in.Samples.wValidBitsPerSample == 24)) { - params->result = S_FALSE; - out->Samples.wValidBitsPerSample = fmt->wBitsPerSample; - break; - } - } else { - params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; - break; - } - - break; - } - case WAVE_FORMAT_ALAW: - case WAVE_FORMAT_MULAW: - if (fmt->wBitsPerSample != 8) { - params->result = E_INVALIDARG; - break; - } - /* Fall-through */ - case WAVE_FORMAT_IEEE_FLOAT: - if (fmt->wFormatTag == WAVE_FORMAT_IEEE_FLOAT && fmt->wBitsPerSample != 32) { - params->result = E_INVALIDARG; - break; - } - /* Fall-through */ - case WAVE_FORMAT_PCM: { - if (fmt->wFormatTag == WAVE_FORMAT_PCM && - (!fmt->wBitsPerSample || fmt->wBitsPerSample > 32 || fmt->wBitsPerSample % 8)) { - params->result = E_INVALIDARG; - break; - } - - if (fmt->nChannels > 2) { - params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; - break; - } - - /* fmt->cbSize, fmt->nBlockAlign and fmt->nAvgBytesPerSec seem to be - * ignored, invalid values are happily accepted. */ - break; - } - default: - params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; - break; - } - - if (exclusive) { /* This driver does not support exclusive mode. */ - if (params->result == S_OK) - params->result = params->flow == eCapture ? - AUDCLNT_E_UNSUPPORTED_FORMAT : - AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED; - else if (params->result == S_FALSE) - params->result = AUDCLNT_E_UNSUPPORTED_FORMAT; - } + /* This driver does not support exclusive mode. */ + if (params->share == AUDCLNT_SHAREMODE_EXCLUSIVE) + params->result = AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED; + else + params->result = S_OK;
return STATUS_SUCCESS; } @@ -2838,7 +2722,6 @@ static NTSTATUS pulse_wow64_is_format_supported(void *args) .flow = params32->flow, .share = params32->share, .fmt_in = ULongToPtr(params32->fmt_in), - .fmt_out = ULongToPtr(params32->fmt_out) }; pulse_is_format_supported(¶ms); params32->result = params.result;