Module: wine Branch: master Commit: b0312eab924277d483c16ab0de235d00a2f26abb URL: http://source.winehq.org/git/wine.git/?a=commit;h=b0312eab924277d483c16ab0de...
Author: Andrew Eikum aeikum@codeweavers.com Date: Wed Aug 15 13:45:07 2012 -0500
mciavi32: Advance video frames based on frame duration, not audio sample rate.
---
dlls/mciavi32/mciavi.c | 45 ++++++++++++++++++++++++--------------- dlls/mciavi32/mmoutput.c | 10 ++++---- dlls/mciavi32/private_mciavi.h | 2 +- 3 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/dlls/mciavi32/mciavi.c b/dlls/mciavi32/mciavi.c index c78ddc0..597359c 100644 --- a/dlls/mciavi32/mciavi.c +++ b/dlls/mciavi32/mciavi.c @@ -391,19 +391,27 @@ static DWORD MCIAVI_mciPlay_async(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PA return 0; }
+static double currenttime_us(void) +{ + LARGE_INTEGER lc, lf; + QueryPerformanceCounter(&lc); + QueryPerformanceFrequency(&lf); + return (lc.QuadPart * 1000000) / lf.QuadPart; +} + /*************************************************************************** * MCIAVI_mciPlay [internal] */ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) { WINE_MCIAVI *wma; - DWORD frameTime; DWORD dwRet; LPWAVEHDR waveHdr = NULL; unsigned i, nHdr = 0; DWORD dwFromFrame, dwToFrame; DWORD numEvents = 1; HANDLE events[2]; + double next_frame_us;
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
@@ -476,9 +484,6 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN)) FIXME("Unsupported flag %08x\n", dwFlags);
- /* time is in microseconds, we should convert it to milliseconds */ - frameTime = (wma->mah.dwMicroSecPerFrame + 500) / 1000; - events[0] = wma->hStopEvent; if (wma->lpWaveFormat) { if (MCIAVI_OpenAudio(wma, &nHdr, &waveHdr) != 0) @@ -496,39 +501,45 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms } }
+ next_frame_us = currenttime_us(); while (wma->dwStatus == MCI_MODE_PLAY) { HDC hDC; - DWORD tc, delta; + double tc, delta; DWORD ret;
- tc = GetTickCount(); + tc = currenttime_us();
hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0; if (hDC) { - MCIAVI_PaintFrame(wma, hDC); + while(next_frame_us <= tc && wma->dwCurrVideoFrame < dwToFrame){ + double dur; + ++wma->dwCurrVideoFrame; + dur = MCIAVI_PaintFrame(wma, hDC); + if(!dur) + break; + next_frame_us += dur; + TRACE("next_frame: %f\n", next_frame_us); + } ReleaseDC(wma->hWndPaint, hDC); } + if(wma->dwCurrVideoFrame >= dwToFrame) + break;
if (wma->lpWaveFormat) - MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr); + MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
- delta = GetTickCount() - tc; - if (delta < frameTime) - delta = frameTime - delta; + tc = currenttime_us(); + if(tc < next_frame_us) + delta = next_frame_us - tc; else delta = 0;
LeaveCriticalSection(&wma->cs); - ret = WaitForMultipleObjects(numEvents, events, FALSE, delta); + ret = WaitForMultipleObjects(numEvents, events, FALSE, delta / 1000); EnterCriticalSection(&wma->cs); if (ret == WAIT_OBJECT_0 || wma->dwStatus != MCI_MODE_PLAY) break; - - if (wma->dwCurrVideoFrame < dwToFrame) - wma->dwCurrVideoFrame++; - else - break; }
if (wma->lpWaveFormat) { diff --git a/dlls/mciavi32/mmoutput.c b/dlls/mciavi32/mmoutput.c index 2cd3339..5d4e092 100644 --- a/dlls/mciavi32/mmoutput.c +++ b/dlls/mciavi32/mmoutput.c @@ -600,20 +600,20 @@ void MCIAVI_PlayAudioBlocks(WINE_MCIAVI* wma, unsigned nHdr, LPWAVEHDR waveHdr) } }
-LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC) +double MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC) { void* pBitmapData; LPBITMAPINFO pBitmapInfo;
if (!hDC || !wma->inbih) - return TRUE; + return 0;
TRACE("Painting frame %u (cached %u)\n", wma->dwCurrVideoFrame, wma->dwCachedFrame);
if (wma->dwCurrVideoFrame != wma->dwCachedFrame) { if (!wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset) - return FALSE; + return 0;
if (wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize) { @@ -626,7 +626,7 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC) wma->outbih, wma->outdata) != ICERR_OK) { WARN("Decompression error\n"); - return FALSE; + return 0; } }
@@ -648,5 +648,5 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC) wma->source.right - wma->source.left, wma->source.bottom - wma->source.top, pBitmapData, pBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
- return TRUE; + return (wma->ash_video.dwScale / (double)wma->ash_video.dwRate) * 1000000; } diff --git a/dlls/mciavi32/private_mciavi.h b/dlls/mciavi32/private_mciavi.h index 1ee0eb3..2b9d6c2 100644 --- a/dlls/mciavi32/private_mciavi.h +++ b/dlls/mciavi32/private_mciavi.h @@ -96,7 +96,7 @@ BOOL MCIAVI_GetInfo(WINE_MCIAVI* wma) DECLSPEC_HIDDEN; DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma, unsigned* nHdr, LPWAVEHDR* pWaveHdr) DECLSPEC_HIDDEN; BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wma) DECLSPEC_HIDDEN; void MCIAVI_PlayAudioBlocks(WINE_MCIAVI* wma, unsigned nHdr, LPWAVEHDR waveHdr) DECLSPEC_HIDDEN; -LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC) DECLSPEC_HIDDEN; +double MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC) DECLSPEC_HIDDEN;
/* mciavi.c */ WINE_MCIAVI* MCIAVI_mciGetOpenDev(UINT wDevID) DECLSPEC_HIDDEN;