Andrew Eikum : wineoss.drv: Improve IsFormatSupported handling.

Alexandre Julliard julliard at winehq.org
Tue Dec 4 13:48:53 CST 2012


Module: wine
Branch: master
Commit: dc0cef3d3b68ae10c80c13846265a9317eecdfd3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=dc0cef3d3b68ae10c80c13846265a9317eecdfd3

Author: Andrew Eikum <aeikum at 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);
 




More information about the wine-cvs mailing list