Just update from/to pointers and exit on a subsequent MCI_PLAY command
Dmitry Timoshkov
dmitry at baikal.ru
Fri Mar 19 05:26:15 CST 2004
Hello,
PowerPoint XP continuously sends MCI_PLAY commands to MCIWnd window,
which in turn sends asynchronous MCI_PLAY commands to mciavi driver.
That leads to huge amount of new threads each playing the same AVI clip.
A test under Windows shows that mciavi driver simply updates its from/to
pointers without interrupting current play operation.
I've included my previous patch here, it not only helps to avoid a dead lock,
but also makes AVI playback loop react much snappier on the stop command.
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
Just update from/to pointers and exit on a subsequent MCI_PLAY command.
diff -u cvs/hq/wine/dlls/winmm/mciavi/mciavi.c wine/dlls/winmm/mciavi/mciavi.c
--- cvs/hq/wine/dlls/winmm/mciavi/mciavi.c 2004-03-18 21:32:17.000000000 +0800
+++ wine/dlls/winmm/mciavi/mciavi.c 2004-03-19 19:08:00.000000000 +0800
@@ -427,7 +427,6 @@ static DWORD MCIAVI_mciPlay(UINT wDevID,
return MCIERR_NO_WINDOW;
}
- wma->dwStatus = MCI_MODE_PLAY;
LeaveCriticalSection(&wma->cs);
if (!(dwFlags & MCI_WAIT)) {
@@ -435,7 +434,8 @@ static DWORD MCIAVI_mciPlay(UINT wDevID,
(DWORD_PTR)lpParms, sizeof(MCI_PLAY_PARMS));
}
- ShowWindow(wma->hWndPaint, SW_SHOWNA);
+ if (!(GetWindowLongW(wma->hWndPaint, GWL_STYLE) & WS_VISIBLE))
+ ShowWindow(wma->hWndPaint, SW_SHOWNA);
EnterCriticalSection(&wma->cs);
@@ -454,13 +454,23 @@ static DWORD MCIAVI_mciPlay(UINT wDevID,
TRACE("Playing from frame=%lu to frame=%lu\n", dwFromFrame, dwToFrame);
wma->dwCurrVideoFrame = dwFromFrame;
+ wma->dwToVideoFrame = dwToFrame;
- if (dwToFrame <= wma->dwCurrVideoFrame)
+ /* if already playing exit */
+ if (wma->dwStatus == MCI_MODE_PLAY)
+ {
+ LeaveCriticalSection(&wma->cs);
+ return 0;
+ }
+
+ if (wma->dwToVideoFrame <= wma->dwCurrVideoFrame)
{
dwRet = 0;
goto mci_play_done;
}
+ wma->dwStatus = MCI_MODE_PLAY;
+
if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_DGV_PLAY_REVERSE|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN))
FIXME("Unsupported flag %08lx\n", dwFlags);
@@ -610,7 +620,9 @@ static DWORD MCIAVI_mciStop(UINT wDevID,
switch (wma->dwStatus) {
case MCI_MODE_PLAY:
case MCI_MODE_RECORD:
+ LeaveCriticalSection(&wma->cs);
SetEvent(wma->hStopEvent);
+ EnterCriticalSection(&wma->cs);
/* fall through */
case MCI_MODE_PAUSE:
/* Since our wave notification callback takes the lock,
@@ -648,6 +660,8 @@ static DWORD MCIAVI_mciPause(UINT wDevID
{
WINE_MCIAVI *wma;
+ TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
+
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
@@ -660,7 +674,7 @@ static DWORD MCIAVI_mciPause(UINT wDevID
LeaveCriticalSection(&wma->cs);
return waveOutPause(wma->hWave);
}
-
+
LeaveCriticalSection(&wma->cs);
return 0;
}
diff -u cvs/hq/wine/dlls/winmm/mciavi/private_mciavi.h wine/dlls/winmm/mciavi/private_mciavi.h
--- cvs/hq/wine/dlls/winmm/mciavi/private_mciavi.h 2004-03-02 18:40:20.000000000 +0800
+++ wine/dlls/winmm/mciavi/private_mciavi.h 2004-03-19 19:09:12.000000000 +0800
@@ -76,6 +76,7 @@ typedef struct {
HWND hWnd, hWndPaint;
DWORD dwCachedFrame; /* buffered frame */
DWORD dwCurrVideoFrame; /* video frame to display and current position */
+ DWORD dwToVideoFrame; /* play to */
DWORD dwCurrAudioBlock; /* current audio block being played */
RECT source, dest;
/* data for the background mechanism */
More information about the wine-patches
mailing list