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

Alexandre Julliard julliard at winehq.org
Thu Aug 16 15:26:11 CDT 2012


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

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




More information about the wine-cvs mailing list