Commit b0312eab authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

mciavi32: Advance video frames based on frame duration, not audio sample rate.

parent b522dc66
...@@ -391,19 +391,27 @@ static DWORD MCIAVI_mciPlay_async(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PA ...@@ -391,19 +391,27 @@ static DWORD MCIAVI_mciPlay_async(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PA
return 0; return 0;
} }
static double currenttime_us(void)
{
LARGE_INTEGER lc, lf;
QueryPerformanceCounter(&lc);
QueryPerformanceFrequency(&lf);
return (lc.QuadPart * 1000000) / lf.QuadPart;
}
/*************************************************************************** /***************************************************************************
* MCIAVI_mciPlay [internal] * MCIAVI_mciPlay [internal]
*/ */
static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
{ {
WINE_MCIAVI *wma; WINE_MCIAVI *wma;
DWORD frameTime;
DWORD dwRet; DWORD dwRet;
LPWAVEHDR waveHdr = NULL; LPWAVEHDR waveHdr = NULL;
unsigned i, nHdr = 0; unsigned i, nHdr = 0;
DWORD dwFromFrame, dwToFrame; DWORD dwFromFrame, dwToFrame;
DWORD numEvents = 1; DWORD numEvents = 1;
HANDLE events[2]; HANDLE events[2];
double next_frame_us;
TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms); TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
...@@ -476,9 +484,6 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS 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)) if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN))
FIXME("Unsupported flag %08x\n", dwFlags); 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; events[0] = wma->hStopEvent;
if (wma->lpWaveFormat) { if (wma->lpWaveFormat) {
if (MCIAVI_OpenAudio(wma, &nHdr, &waveHdr) != 0) if (MCIAVI_OpenAudio(wma, &nHdr, &waveHdr) != 0)
...@@ -496,39 +501,45 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms ...@@ -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) while (wma->dwStatus == MCI_MODE_PLAY)
{ {
HDC hDC; HDC hDC;
DWORD tc, delta; double tc, delta;
DWORD ret; DWORD ret;
tc = GetTickCount(); tc = currenttime_us();
hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0; hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0;
if (hDC) 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); ReleaseDC(wma->hWndPaint, hDC);
} }
if(wma->dwCurrVideoFrame >= dwToFrame)
break;
if (wma->lpWaveFormat) if (wma->lpWaveFormat)
MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr); MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
delta = GetTickCount() - tc; tc = currenttime_us();
if (delta < frameTime) if(tc < next_frame_us)
delta = frameTime - delta; delta = next_frame_us - tc;
else else
delta = 0; delta = 0;
LeaveCriticalSection(&wma->cs); LeaveCriticalSection(&wma->cs);
ret = WaitForMultipleObjects(numEvents, events, FALSE, delta); ret = WaitForMultipleObjects(numEvents, events, FALSE, delta / 1000);
EnterCriticalSection(&wma->cs); EnterCriticalSection(&wma->cs);
if (ret == WAIT_OBJECT_0 || wma->dwStatus != MCI_MODE_PLAY) break; if (ret == WAIT_OBJECT_0 || wma->dwStatus != MCI_MODE_PLAY) break;
if (wma->dwCurrVideoFrame < dwToFrame)
wma->dwCurrVideoFrame++;
else
break;
} }
if (wma->lpWaveFormat) { if (wma->lpWaveFormat) {
......
...@@ -600,20 +600,20 @@ void MCIAVI_PlayAudioBlocks(WINE_MCIAVI* wma, unsigned nHdr, LPWAVEHDR waveHdr) ...@@ -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; void* pBitmapData;
LPBITMAPINFO pBitmapInfo; LPBITMAPINFO pBitmapInfo;
if (!hDC || !wma->inbih) if (!hDC || !wma->inbih)
return TRUE; return 0;
TRACE("Painting frame %u (cached %u)\n", wma->dwCurrVideoFrame, wma->dwCachedFrame); TRACE("Painting frame %u (cached %u)\n", wma->dwCurrVideoFrame, wma->dwCachedFrame);
if (wma->dwCurrVideoFrame != wma->dwCachedFrame) if (wma->dwCurrVideoFrame != wma->dwCachedFrame)
{ {
if (!wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset) if (!wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset)
return FALSE; return 0;
if (wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize) if (wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize)
{ {
...@@ -626,7 +626,7 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC) ...@@ -626,7 +626,7 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC)
wma->outbih, wma->outdata) != ICERR_OK) wma->outbih, wma->outdata) != ICERR_OK)
{ {
WARN("Decompression error\n"); WARN("Decompression error\n");
return FALSE; return 0;
} }
} }
...@@ -648,5 +648,5 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC) ...@@ -648,5 +648,5 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC)
wma->source.right - wma->source.left, wma->source.bottom - wma->source.top, wma->source.right - wma->source.left, wma->source.bottom - wma->source.top,
pBitmapData, pBitmapInfo, DIB_RGB_COLORS, SRCCOPY); pBitmapData, pBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
return TRUE; return (wma->ash_video.dwScale / (double)wma->ash_video.dwRate) * 1000000;
} }
...@@ -96,7 +96,7 @@ BOOL MCIAVI_GetInfo(WINE_MCIAVI* wma) DECLSPEC_HIDDEN; ...@@ -96,7 +96,7 @@ BOOL MCIAVI_GetInfo(WINE_MCIAVI* wma) DECLSPEC_HIDDEN;
DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma, unsigned* nHdr, LPWAVEHDR* pWaveHdr) DECLSPEC_HIDDEN; DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma, unsigned* nHdr, LPWAVEHDR* pWaveHdr) DECLSPEC_HIDDEN;
BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wma) DECLSPEC_HIDDEN; BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wma) DECLSPEC_HIDDEN;
void MCIAVI_PlayAudioBlocks(WINE_MCIAVI* wma, unsigned nHdr, LPWAVEHDR waveHdr) 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 */ /* mciavi.c */
WINE_MCIAVI* MCIAVI_mciGetOpenDev(UINT wDevID) DECLSPEC_HIDDEN; WINE_MCIAVI* MCIAVI_mciGetOpenDev(UINT wDevID) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment