=?UTF-8?Q?J=C3=B6rg=20H=C3=B6hle=20?=: mmdevapi: Enforce limits on period and duration.
Alexandre Julliard
julliard at winehq.org
Mon Dec 19 13:39:22 CST 2011
Module: wine
Branch: master
Commit: 38f9ba0070f9b72d8c94d8124b488921078f8018
URL: http://source.winehq.org/git/wine.git/?a=commit;h=38f9ba0070f9b72d8c94d8124b488921078f8018
Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date: Thu Dec 15 23:07:41 2011 +0100
mmdevapi: Enforce limits on period and duration.
---
dlls/winealsa.drv/mmdevdrv.c | 31 +++++++++++++++++++++----------
dlls/winecoreaudio.drv/mmdevdrv.c | 32 +++++++++++++++++++++-----------
dlls/wineoss.drv/mmdevdrv.c | 30 +++++++++++++++++++++---------
3 files changed, 63 insertions(+), 30 deletions(-)
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index 359997e..994628e 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -835,14 +835,28 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
return E_INVALIDARG;
}
- if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE && flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){
- FIXME("EXCLUSIVE mode with EVENTCALLBACK\n");
- return AUDCLNT_E_DEVICE_IN_USE;
+ if(mode == AUDCLNT_SHAREMODE_SHARED){
+ period = DefaultPeriod;
+ if( duration < 3 * period)
+ duration = 3 * period;
+ }else{
+ if(!period)
+ period = DefaultPeriod; /* not minimum */
+ if(period < MinimumPeriod || period > 5000000)
+ return AUDCLNT_E_INVALID_DEVICE_PERIOD;
+ if(duration > 20000000) /* the smaller the period, the lower this limit */
+ return AUDCLNT_E_BUFFER_SIZE_ERROR;
+ if(flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){
+ if(duration != period)
+ return AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL;
+ FIXME("EXCLUSIVE mode with EVENTCALLBACK\n");
+ return AUDCLNT_E_DEVICE_IN_USE;
+ }else{
+ if( duration < 8 * period)
+ duration = 8 * period; /* may grow above 2s */
+ }
}
- if(!duration)
- duration = 300000; /* 0.03s */
-
EnterCriticalSection(&This->lock);
if(This->initted){
@@ -1001,10 +1015,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
goto exit;
}
- if(period)
- This->mmdev_period_rt = period;
- else
- This->mmdev_period_rt = DefaultPeriod;
+ This->mmdev_period_rt = period;
/* Check if the ALSA buffer is so small that it will run out before
* the next MMDevAPI period tick occurs. Allow a little wiggle room
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index a648429..a2c72da 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -961,9 +961,26 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
return E_INVALIDARG;
}
- if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE && flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){
- FIXME("EXCLUSIVE mode with EVENTCALLBACK\n");
- return AUDCLNT_E_DEVICE_IN_USE;
+ if(mode == AUDCLNT_SHAREMODE_SHARED){
+ period = DefaultPeriod;
+ if( duration < 3 * period)
+ duration = 3 * period;
+ }else{
+ if(!period)
+ period = DefaultPeriod; /* not minimum */
+ if(period < MinimumPeriod || period > 5000000)
+ return AUDCLNT_E_INVALID_DEVICE_PERIOD;
+ if(duration > 20000000) /* the smaller the period, the lower this limit */
+ return AUDCLNT_E_BUFFER_SIZE_ERROR;
+ if(flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){
+ if(duration != period)
+ return AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL;
+ FIXME("EXCLUSIVE mode with EVENTCALLBACK\n");
+ return AUDCLNT_E_DEVICE_IN_USE;
+ }else{
+ if( duration < 8 * period)
+ duration = 8 * period; /* may grow above 2s */
+ }
}
OSSpinLockLock(&This->lock);
@@ -987,15 +1004,8 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
return E_OUTOFMEMORY;
}
- if(period){
- This->period_ms = period / 10000;
- if(This->period_ms == 0)
- This->period_ms = 1;
- }else
- This->period_ms = MinimumPeriod / 10000;
+ This->period_ms = period / 10000;
- if(!duration)
- duration = 300000; /* 0.03s */
This->bufsize_frames = ceil(fmt->nSamplesPerSec * (duration / 10000000.));
if(This->dataflow == eCapture){
diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c
index 571495d..dbbcd9f 100644
--- a/dlls/wineoss.drv/mmdevdrv.c
+++ b/dlls/wineoss.drv/mmdevdrv.c
@@ -906,9 +906,26 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
return E_INVALIDARG;
}
- if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE && flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){
- FIXME("EXCLUSIVE mode with EVENTCALLBACK\n");
- return AUDCLNT_E_DEVICE_IN_USE;
+ if(mode == AUDCLNT_SHAREMODE_SHARED){
+ period = DefaultPeriod;
+ if( duration < 3 * period)
+ duration = 3 * period;
+ }else{
+ if(!period)
+ period = DefaultPeriod; /* not minimum */
+ if(period < MinimumPeriod || period > 5000000)
+ return AUDCLNT_E_INVALID_DEVICE_PERIOD;
+ if(duration > 20000000) /* the smaller the period, the lower this limit */
+ return AUDCLNT_E_BUFFER_SIZE_ERROR;
+ if(flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK){
+ if(duration != period)
+ return AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL;
+ FIXME("EXCLUSIVE mode with EVENTCALLBACK\n");
+ return AUDCLNT_E_DEVICE_IN_USE;
+ }else{
+ if( duration < 8 * period)
+ duration = 8 * period; /* may grow above 2s */
+ }
}
EnterCriticalSection(&This->lock);
@@ -937,13 +954,8 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient *iface,
return E_OUTOFMEMORY;
}
- if(period)
- This->period_us = period / 10;
- else
- This->period_us = DefaultPeriod / 10;
+ This->period_us = period / 10;
- if(!duration)
- duration = 300000; /* 0.03s */
This->bufsize_frames = ceil(fmt->nSamplesPerSec * (duration / 10000000.));
This->local_buffer = HeapAlloc(GetProcessHeap(), 0,
This->bufsize_frames * fmt->nBlockAlign);
More information about the wine-cvs
mailing list