[PATCH 2/3] mciavi32: Implement MCI_BREAK (try 3)
Andrew Eikum
aeikum at codeweavers.com
Mon Mar 6 08:21:17 CST 2017
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
On Mon, Mar 06, 2017 at 01:24:27AM -0300, Bruno Jesus wrote:
> From: Bruno Jesus <bjesus at codeweavers.com>
>
> try 3:
> Protect wma struct changes with critical section as requested by Andrew Eikum
>
> try 2:
> Test correct HWND to break
>
> Tested with Half-Life and Worms 2. Since it requires watching a video and pressing a key and realizing that the video was skipped I believe it is hard to write a test.
>
> Signed-off-by: Bruno Jesus <bjesus at codeweavers.com>
> ---
> dlls/mciavi32/mciavi.c | 58 +++++++++++++++++++++++++++++++++++++-----
> dlls/mciavi32/private_mciavi.h | 5 ++++
> 2 files changed, 56 insertions(+), 7 deletions(-)
>
> diff --git a/dlls/mciavi32/mciavi.c b/dlls/mciavi32/mciavi.c
> index fc50a5e..0b340e8 100644
> --- a/dlls/mciavi32/mciavi.c
> +++ b/dlls/mciavi32/mciavi.c
> @@ -353,6 +353,7 @@ static DWORD MCIAVI_player(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PARMS lpP
> DWORD numEvents = 1;
> HANDLE events[2];
> double next_frame_us;
> + BOOL wait_audio = TRUE;
>
> EnterCriticalSection(&wma->cs);
>
> @@ -419,19 +420,37 @@ static DWORD MCIAVI_player(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PARMS lpP
> 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);
> @@ -871,6 +890,30 @@ static DWORD MCIAVI_mciCue(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUE_PARMS lpPar
> }
>
> /******************************************************************************
> + * 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]
> */
> static DWORD MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSW lpParms)
> @@ -988,6 +1031,7 @@ LRESULT CALLBACK MCIAVI_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
> 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);
> diff --git a/dlls/mciavi32/private_mciavi.h b/dlls/mciavi32/private_mciavi.h
> index 4dfcc09..1b53ab8 100644
> --- a/dlls/mciavi32/private_mciavi.h
> +++ b/dlls/mciavi32/private_mciavi.h
> @@ -76,6 +76,11 @@ typedef struct {
> DWORD dwToVideoFrame; /* play to */
> DWORD dwCurrAudioBlock; /* current audio block being played */
> RECT source, dest;
> + struct
> + {
> + DWORD flags;
> + MCI_BREAK_PARMS parms;
> + } mci_break;
> /* data for the background mechanism */
> CRITICAL_SECTION cs;
> HANDLE hStopEvent;
> --
> 2.9.3
>
>
>
More information about the wine-patches
mailing list