Module: wine Branch: master Commit: dc0cef3d3b68ae10c80c13846265a9317eecdfd3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=dc0cef3d3b68ae10c80c138462...
Author: Andrew Eikum aeikum@codeweavers.com Date: Mon Dec 3 10:28:11 2012 -0600
wineoss.drv: Improve IsFormatSupported handling.
---
dlls/wineoss.drv/mmdevdrv.c | 37 ++++++++++++++++++++++++++----------- 1 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c index 62ae7ca..9fc6f02 100644 --- a/dlls/wineoss.drv/mmdevdrv.c +++ b/dlls/wineoss.drv/mmdevdrv.c @@ -837,13 +837,12 @@ static WAVEFORMATEX *clone_format(const WAVEFORMATEX *fmt) return ret; }
-static HRESULT setup_oss_device(int fd, const WAVEFORMATEX *fmt, - WAVEFORMATEX **out, BOOL query) +static HRESULT setup_oss_device(AUDCLNT_SHAREMODE mode, int fd, + const WAVEFORMATEX *fmt, WAVEFORMATEX **out) { int tmp, oss_format; double tenth; HRESULT ret = S_OK; - WAVEFORMATEXTENSIBLE *fmtex = (void*)fmt; WAVEFORMATEX *closest = NULL;
tmp = oss_format = get_oss_format(fmt); @@ -858,6 +857,15 @@ static HRESULT setup_oss_device(int fd, const WAVEFORMATEX *fmt, return AUDCLNT_E_UNSUPPORTED_FORMAT; }
+ if(fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE && + (fmt->nAvgBytesPerSec == 0 || + fmt->nBlockAlign == 0 || + ((WAVEFORMATEXTENSIBLE*)fmt)->Samples.wValidBitsPerSample > fmt->wBitsPerSample)) + return E_INVALIDARG; + + if(fmt->nChannels == 0) + return AUDCLNT_E_UNSUPPORTED_FORMAT; + closest = clone_format(fmt); if(!closest) return E_OUTOFMEMORY; @@ -885,14 +893,19 @@ static HRESULT setup_oss_device(int fd, const WAVEFORMATEX *fmt, closest->nChannels = tmp; }
- if(closest->wFormatTag == WAVE_FORMAT_EXTENSIBLE){ - DWORD mask = get_channel_mask(closest->nChannels); + if(closest->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + ((WAVEFORMATEXTENSIBLE*)closest)->dwChannelMask = get_channel_mask(closest->nChannels);
- ((WAVEFORMATEXTENSIBLE*)closest)->dwChannelMask = mask; + if(fmt->nBlockAlign != fmt->nChannels * fmt->wBitsPerSample / 8 || + fmt->nAvgBytesPerSec != fmt->nBlockAlign * fmt->nSamplesPerSec || + (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE && + ((WAVEFORMATEXTENSIBLE*)fmt)->Samples.wValidBitsPerSample < fmt->wBitsPerSample)) + ret = S_FALSE;
- if(query && fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE && - fmtex->dwChannelMask != 0 && - fmtex->dwChannelMask != mask) + if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE && + fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE){ + if(((WAVEFORMATEXTENSIBLE*)fmt)->dwChannelMask == 0 || + ((WAVEFORMATEXTENSIBLE*)fmt)->dwChannelMask & SPEAKER_RESERVED) ret = S_FALSE; }
@@ -904,6 +917,8 @@ static HRESULT setup_oss_device(int fd, const WAVEFORMATEX *fmt, closest->nChannels * closest->wBitsPerSample / 8; closest->nAvgBytesPerSec = closest->nBlockAlign * closest->nSamplesPerSec; + if(closest->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + ((WAVEFORMATEXTENSIBLE*)closest)->Samples.wValidBitsPerSample = closest->wBitsPerSample; *out = closest; } else CoTaskMemFree(closest); @@ -1055,7 +1070,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface, return AUDCLNT_E_ALREADY_INITIALIZED; }
- hr = setup_oss_device(This->fd, fmt, NULL, FALSE); + hr = setup_oss_device(mode, This->fd, fmt, NULL); if(FAILED(hr)){ LeaveCriticalSection(&This->lock); return hr; @@ -1237,7 +1252,7 @@ static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient *iface, return AUDCLNT_E_DEVICE_INVALIDATED; }
- ret = setup_oss_device(fd, pwfx, outpwfx, TRUE); + ret = setup_oss_device(mode, fd, pwfx, outpwfx);
close(fd);