* audio is played... still should be stopped ASAP
*/
+#include <string.h>
#include "private_mciavi.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
-#include <mciavi.h>
-#include <wine/unicode.h>
+WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
static DWORD MCIAVI_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS);
DWORD numEvents = 1;
HANDLE events[2];
double next_frame_us;
+ BOOL wait_audio = TRUE;
EnterCriticalSection(&wma->cs);
{
while(next_frame_us <= tc && wma->dwCurrVideoFrame < wma->dwToVideoFrame){
double dur;
- ++wma->dwCurrVideoFrame;
dur = MCIAVI_PaintFrame(wma, hDC);
+ ++wma->dwCurrVideoFrame;
if(!dur)
break;
next_frame_us += dur;
}
ReleaseDC(wma->hWndPaint, hDC);
}
- if(wma->dwCurrVideoFrame >= wma->dwToVideoFrame)
- break;
+ if (wma->dwCurrVideoFrame >= wma->dwToVideoFrame)
+ {
+ if (!(dwFlags & MCI_DGV_PLAY_REPEAT))
+ break;
+ TRACE("repeat media as requested\n");
+ wma->dwCurrVideoFrame = wma->dwCurrAudioBlock = 0;
+ }
if (wma->lpWaveFormat)
MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
tc = currenttime_us();
- if(tc < next_frame_us)
+ if (tc < next_frame_us)
delta = next_frame_us - tc;
else
delta = 0;
+ /* check if the playback was cancelled */
+ if ((wma->mci_break.flags & MCI_BREAK_KEY) &&
+ (GetAsyncKeyState(wma->mci_break.parms.nVirtKey) & 0x8000))
+ {
+ if (!(wma->mci_break.flags & MCI_BREAK_HWND) ||
+ GetForegroundWindow() == wma->mci_break.parms.hwndBreak)
+ {
+ /* we queue audio blocks ahead so ignore them otherwise the audio
+ * will keep playing until the buffer is empty */
+ wait_audio = FALSE;
+
+ TRACE("playback cancelled using break key\n");
+ break;
+ }
+ }
+
LeaveCriticalSection(&wma->cs);
ret = WaitForMultipleObjects(numEvents, events, FALSE, delta / 1000);
EnterCriticalSection(&wma->cs);
if (ret == WAIT_OBJECT_0 || wma->dwStatus != MCI_MODE_PLAY) break;
}
- if (wma->lpWaveFormat) {
- while (wma->dwEventCount != nHdr - 1)
- {
- LeaveCriticalSection(&wma->cs);
- Sleep(100);
- EnterCriticalSection(&wma->cs);
- }
+ if (wma->lpWaveFormat)
+ {
+ if (wait_audio)
+ while (wma->dwEventCount != nHdr - 1)
+ {
+ LeaveCriticalSection(&wma->cs);
+ Sleep(100);
+ EnterCriticalSection(&wma->cs);
+ }
/* just to get rid of some race conditions between play, stop and pause */
LeaveCriticalSection(&wma->cs);
if (dwFlags & MCI_DGV_PLAY_REVERSE) return MCIERR_UNSUPPORTED_FUNCTION;
if (dwFlags & MCI_TEST) return 0;
- if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN|MCI_MCIAVI_PLAY_FULLBY2))
+ if (dwFlags & (MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN|MCI_MCIAVI_PLAY_FULLBY2))
FIXME("Unsupported flag %08x\n", dwFlags);
EnterCriticalSection(&wma->cs);
return 0;
}
+/******************************************************************************
+ * MCIAVI_mciBreak [internal]
+ */
+static DWORD MCIAVI_mciBreak(UINT wDevID, DWORD dwFlags, LPMCI_BREAK_PARMS lpParms)
+{
+ WINE_MCIAVI *wma;
+
+ TRACE("(%04x, %08x, %p)\n", wDevID, dwFlags, lpParms);
+
+ if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
+ if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+
+ EnterCriticalSection(&wma->cs);
+
+ wma->mci_break.flags = dwFlags;
+ wma->mci_break.parms = *lpParms;
+
+ LeaveCriticalSection(&wma->cs);
+
+ return 0;
+}
+
/******************************************************************************
* MCIAVI_mciSetAudio [internal]
*/
case MCI_WHERE: return MCIAVI_mciWhere (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2);
case MCI_STEP: return MCIAVI_mciStep (dwDevID, dwParam1, (LPMCI_DGV_STEP_PARMS) dwParam2);
case MCI_CUE: return MCIAVI_mciCue (dwDevID, dwParam1, (LPMCI_DGV_CUE_PARMS) dwParam2);
+ case MCI_BREAK: return MCIAVI_mciBreak (dwDevID, dwParam1, (LPMCI_BREAK_PARMS) dwParam2);
/* Digital Video specific */
case MCI_SETAUDIO: return MCIAVI_mciSetAudio (dwDevID, dwParam1, (LPMCI_DGV_SETAUDIO_PARMSW) dwParam2);
case MCI_SIGNAL: return MCIAVI_mciSignal (dwDevID, dwParam1, (LPMCI_DGV_SIGNAL_PARMS) dwParam2);