Much improved mciavi driver. Fixed synchronization, RIFF file with

many streams parsing, added support for some MCI_PUT and MCI_WHERE
cases.
This commit is contained in:
Dmitry Timoshkov 2004-01-01 00:48:01 +00:00 committed by Alexandre Julliard
parent cd61ce8529
commit f41e047020
6 changed files with 487 additions and 211 deletions

View File

@ -1027,13 +1027,11 @@ DWORD WINAPI mciSendStringA(LPCSTR lpstrCommand, LPSTR lpstrRet,
*/
if (lpstrRet && uRetLen) *lpstrRet = '\0';
#define STR_OF(_x) (IsBadReadPtr((char*)_x,1)?"?":(char*)(_x))
TRACE("[%d, %s, %08lx, %08lx/%s %08lx/%s %08lx/%s %08lx/%s %08lx/%s %08lx/%s]\n",
wmd->wDeviceID, MCI_MessageToString(MCI_GetMessage(lpCmd)), dwFlags,
data[0], STR_OF(data[0]), data[1], STR_OF(data[1]),
data[2], STR_OF(data[2]), data[3], STR_OF(data[3]),
data[4], STR_OF(data[4]), data[5], STR_OF(data[5]));
#undef STR_OF
data[0], debugstr_a((char *)data[0]), data[1], debugstr_a((char *)data[1]),
data[2], debugstr_a((char *)data[2]), data[3], debugstr_a((char *)data[3]),
data[4], debugstr_a((char *)data[4]), data[5], debugstr_a((char *)data[5]));
if (strcmp(verb, "open") == 0) {
if ((dwRet = MCI_FinishOpen(wmd, (LPMCI_OPEN_PARMSA)data, dwFlags)))

View File

@ -82,6 +82,8 @@ DWORD MCIAVI_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS l
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
if (dwFlags & MCI_GETDEVCAPS_ITEM) {
switch (lpParms->dwItem) {
case MCI_GETDEVCAPS_DEVICE_TYPE:
@ -131,12 +133,15 @@ DWORD MCIAVI_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS l
break;
default:
FIXME("Unknown capability (%08lx) !\n", lpParms->dwItem);
return MCIERR_UNRECOGNIZED_COMMAND;
ret = MCIERR_UNRECOGNIZED_COMMAND;
break;
}
} else {
WARN("No GetDevCaps-Item !\n");
return MCIERR_UNRECOGNIZED_COMMAND;
ret = MCIERR_UNRECOGNIZED_COMMAND;
}
LeaveCriticalSection(&wma->cs);
return ret;
}
@ -155,15 +160,18 @@ DWORD MCIAVI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_INFO_PARMSA lpParms)
TRACE("buf=%p, len=%lu\n", lpParms->lpstrReturn, lpParms->dwRetSize);
EnterCriticalSection(&wma->cs);
switch (dwFlags) {
case MCI_INFO_PRODUCT:
str = "Wine's AVI player";
break;
case MCI_INFO_FILE:
str = wma->openParms.lpstrElementName;
str = wma->lpFileName;
break;
default:
WARN("Don't know this info command (%lu)\n", dwFlags);
LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (str) {
@ -175,6 +183,8 @@ DWORD MCIAVI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_INFO_PARMSA lpParms)
} else {
lpParms->lpstrReturn[0] = 0;
}
LeaveCriticalSection(&wma->cs);
return ret;
}
@ -188,6 +198,8 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpParms)
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
if (dwFlags & MCI_SET_TIME_FORMAT) {
switch (lpParms->dwTimeFormat) {
case MCI_FORMAT_MILLISECONDS:
@ -200,18 +212,22 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpParms)
break;
default:
WARN("Bad time format %lu!\n", lpParms->dwTimeFormat);
LeaveCriticalSection(&wma->cs);
return MCIERR_BAD_TIME_FORMAT;
}
}
if (dwFlags & MCI_SET_DOOR_OPEN) {
TRACE("No support for door open !\n");
LeaveCriticalSection(&wma->cs);
return MCIERR_UNSUPPORTED_FUNCTION;
}
if (dwFlags & MCI_SET_DOOR_CLOSED) {
TRACE("No support for door close !\n");
LeaveCriticalSection(&wma->cs);
return MCIERR_UNSUPPORTED_FUNCTION;
}
if (dwFlags & MCI_SET_ON) {
char buffer[256];
@ -302,6 +318,7 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpParms)
FIXME("Setting speed to %ld\n", lpParms->dwSpeed);
}
LeaveCriticalSection(&wma->cs);
return 0;
}
@ -316,6 +333,8 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
if (dwFlags & MCI_STATUS_ITEM) {
switch (lpParms->dwItem) {
case MCI_STATUS_CURRENT_TRACK:
@ -325,6 +344,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
case MCI_STATUS_LENGTH:
if (!wma->hFile) {
lpParms->dwReturn = 0;
LeaveCriticalSection(&wma->cs);
return MCIERR_UNSUPPORTED_FUNCTION;
}
/* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
@ -334,7 +354,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
case MCI_STATUS_MODE:
lpParms->dwReturn = MAKEMCIRESOURCE(wma->dwStatus, wma->dwStatus);
ret = MCI_RESOURCE_RETURNED;
TRACE("MCI_STATUS_MODE => %u\n", LOWORD(lpParms->dwReturn));
TRACE("MCI_STATUS_MODE => 0x%04x\n", LOWORD(lpParms->dwReturn));
break;
case MCI_STATUS_MEDIA_PRESENT:
TRACE("MCI_STATUS_MEDIA_PRESENT => TRUE\n");
@ -348,6 +368,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
case MCI_STATUS_POSITION:
if (!wma->hFile) {
lpParms->dwReturn = 0;
LeaveCriticalSection(&wma->cs);
return MCIERR_UNSUPPORTED_FUNCTION;
}
/* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
@ -401,7 +422,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
TRACE("MCI_DGV_STATUS_HPAL => %lx\n", lpParms->dwReturn);
break;
case MCI_DGV_STATUS_HWND:
lpParms->dwReturn = (DWORD)wma->hWndPaint;
lpParms->dwReturn = (DWORD_PTR)wma->hWndPaint;
TRACE("MCI_DGV_STATUS_HWND => %p\n", wma->hWndPaint);
break;
#if 0
@ -436,17 +457,20 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
default:
FIXME("Unknowm command %08lX !\n", lpParms->dwItem);
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
} else {
WARN("No Status-Item!\n");
LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_NOTIFY) {
TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
wDevID, MCI_NOTIFY_SUCCESSFUL);
}
LeaveCriticalSection(&wma->cs);
return ret;
}

View File

@ -4,6 +4,7 @@
* Digital video MCI Wine Driver
*
* Copyright 1999, 2000 Eric POUECH
* Copyright 2003 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -26,14 +27,12 @@
* - lots of messages still need to be handled (cf FIXME)
* - synchronization between audio and video (especially for interleaved
* files)
* - synchronization (as in all the Wine MCI drivers (MCI_WAIT) messages)
* - robustness when reading file can be enhanced
* - better move the AVI handling part to avifile DLL and make use of it
* - some files appear to have more than one audio stream (we only play the
* first one)
* - some files contain an index of audio/video frame. Better use it,
* instead of rebuilding it
* - mciWindow (for setting the hWnd) is broken with media player
* - stopping while playing a file with sound blocks until all buffered
* audio is played... still should be stopped ASAP
*/
@ -44,6 +43,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
static DWORD MCIAVI_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS);
/* ===================================================================
* ===================================================================
* FIXME: should be using the new mmThreadXXXX functions from WINMM
@ -54,10 +55,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
* =================================================================== */
struct SCA {
UINT wDevID;
MCIDEVICEID wDevID;
UINT wMsg;
DWORD dwParam1;
DWORD dwParam2;
DWORD_PTR dwParam1;
DWORD_PTR dwParam2;
};
/**************************************************************************
@ -68,15 +69,12 @@ static DWORD CALLBACK MCI_SCAStarter(LPVOID arg)
struct SCA* sca = (struct SCA*)arg;
DWORD ret;
TRACE("In thread before async command (%08x,%u,%08lx,%08lx)\n",
TRACE("In thread before async command (%08x,%04x,%08lx,%08lx)\n",
sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2);
ret = mciSendCommandA(sca->wDevID, sca->wMsg, sca->dwParam1 | MCI_WAIT, sca->dwParam2);
TRACE("In thread after async command (%08x,%u,%08lx,%08lx)\n",
TRACE("In thread after async command (%08x,%04x,%08lx,%08lx)\n",
sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2);
HeapFree(GetProcessHeap(), 0, sca);
ExitThread(ret);
WARN("Should not happen ? what's wrong \n");
/* should not go after this point */
return ret;
}
@ -84,7 +82,7 @@ static DWORD CALLBACK MCI_SCAStarter(LPVOID arg)
* MCI_SendCommandAsync [internal]
*/
static DWORD MCI_SendCommandAsync(UINT wDevID, UINT wMsg, DWORD dwParam1,
DWORD dwParam2, UINT size)
DWORD_PTR dwParam2, UINT size)
{
struct SCA* sca = HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA) + size);
@ -96,7 +94,7 @@ static DWORD MCI_SendCommandAsync(UINT wDevID, UINT wMsg, DWORD dwParam1,
sca->dwParam1 = dwParam1;
if (size && dwParam2) {
sca->dwParam2 = (DWORD)sca + sizeof(struct SCA);
sca->dwParam2 = (DWORD_PTR)sca + sizeof(struct SCA);
/* copy structure passed by program in dwParam2 to be sure
* we can still use it whatever the program does
*/
@ -137,17 +135,22 @@ static DWORD MCIAVI_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp)
WINE_MCIAVI* wma;
static const WCHAR mciAviWStr[] = {'M','C','I','A','V','I',0};
TRACE("%s, %p\n", debugstr_a(str), modp);
/* session instance */
if (!modp) return 0xFFFFFFFF;
wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIAVI));
if (!wma)
return 0;
InitializeCriticalSection(&wma->cs);
wma->wDevID = modp->wDeviceID;
mciSetDriverData(wma->wDevID, (DWORD)wma);
wma->wCommandTable = mciLoadCommandResource(MCIAVI_hInstance, mciAviWStr, 0);
modp->wCustomCommandTable = wma->wCommandTable;
modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO;
mciSetDriverData(wma->wDevID, (DWORD)wma);
return modp->wDeviceID;
}
@ -156,11 +159,24 @@ static DWORD MCIAVI_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp)
*/
static DWORD MCIAVI_drvClose(DWORD dwDevID)
{
WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
WINE_MCIAVI *wma;
TRACE("%04lx\n", dwDevID);
/* finish all outstanding things */
MCIAVI_mciClose(dwDevID, MCI_WAIT, NULL);
wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
if (wma) {
EnterCriticalSection(&wma->cs);
mciSetDriverData(dwDevID, 0);
mciFreeCommandResource(wma->wCommandTable);
LeaveCriticalSection(&wma->cs);
DeleteCriticalSection(&wma->cs);
HeapFree(GetProcessHeap(), 0, wma);
return 1;
}
@ -172,7 +188,13 @@ static DWORD MCIAVI_drvClose(DWORD dwDevID)
*/
static DWORD MCIAVI_drvConfigure(DWORD dwDevID)
{
WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
WINE_MCIAVI *wma;
TRACE("%04lx\n", dwDevID);
MCIAVI_mciStop(dwDevID, MCI_WAIT, NULL);
wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
if (wma) {
MessageBoxA(0, "Sample AVI Wine Driver !", "MM-Wine Driver", MB_OK);
@ -202,6 +224,10 @@ static void MCIAVI_CleanUp(WINE_MCIAVI* wma)
if (wma->hFile) {
mmioClose(wma->hFile, 0);
wma->hFile = 0;
if (wma->lpFileName) HeapFree(GetProcessHeap(), 0, wma->lpFileName);
wma->lpFileName = NULL;
if (wma->lpVideoIndex) HeapFree(GetProcessHeap(), 0, wma->lpVideoIndex);
wma->lpVideoIndex = NULL;
if (wma->lpAudioIndex) HeapFree(GetProcessHeap(), 0, wma->lpAudioIndex);
@ -231,22 +257,26 @@ static void MCIAVI_CleanUp(WINE_MCIAVI* wma)
}
}
static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
/***************************************************************************
* MCIAVI_mciOpen [internal]
*/
static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags,
LPMCI_DGV_OPEN_PARMSA lpOpenParms)
{
WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(wDevID);
WINE_MCIAVI *wma;
LRESULT dwRet = 0;
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = (WINE_MCIAVI *)mciGetDriverData(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
if (wma->nUseCount > 0) {
/* The driver is already open on this channel */
/* If the driver was opened shareable before and this open specifies */
@ -254,14 +284,16 @@ static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags,
if (wma->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
++wma->nUseCount;
else
{
LeaveCriticalSection(&wma->cs);
return MCIERR_MUST_USE_SHAREABLE;
}
} else {
wma->nUseCount = 1;
wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE;
}
wma->dwStatus = MCI_MODE_NOT_READY;
InitializeCriticalSection(&wma->cs);
if (dwFlags & MCI_OPEN_ELEMENT) {
if (dwFlags & MCI_OPEN_ELEMENT_ID) {
@ -273,7 +305,11 @@ static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags,
/* FIXME : what should be done id wma->hFile is already != 0, or the driver is playin' */
TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpOpenParms->lpstrElementName);
if (lpOpenParms->lpstrElementName && (strlen(lpOpenParms->lpstrElementName) > 0)) {
if (lpOpenParms->lpstrElementName && (strlen(lpOpenParms->lpstrElementName) > 0))
{
wma->lpFileName = HeapAlloc(GetProcessHeap(), 0, strlen(lpOpenParms->lpstrElementName) + 1);
strcpy(wma->lpFileName, lpOpenParms->lpstrElementName);
wma->hFile = mmioOpenA(lpOpenParms->lpstrElementName, NULL,
MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READWRITE);
@ -295,44 +331,52 @@ static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags,
}
}
memcpy(&wma->openParms, lpOpenParms, sizeof(MCI_WAVE_OPEN_PARMSA));
if (dwRet == 0) {
TRACE("lpOpenParms->wDeviceID = %04x\n", lpOpenParms->wDeviceID);
wma->dwStatus = MCI_MODE_STOP;
wma->dwMciTimeFormat = MCI_FORMAT_FRAMES;
} else {
MCIAVI_CleanUp(wma);
}
return dwRet;
LeaveCriticalSection(&wma->cs);
return dwRet;
}
/***************************************************************************
* MCIAVI_mciClose [internal]
*/
static DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
DWORD dwRet = 0;
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
wma = (WINE_MCIAVI *)MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
if (wma->nUseCount == 1) {
if (wma->dwStatus != MCI_MODE_STOP)
dwRet = MCIAVI_mciStop(wDevID, MCI_WAIT, lpParms);
dwRet = MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
MCIAVI_CleanUp(wma);
if ((dwFlags & MCI_NOTIFY) && lpParms) {
mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
wma->openParms.wDeviceID,
wDevID,
MCI_NOTIFY_SUCCESSFUL);
}
HeapFree(GetProcessHeap(), 0, wma);
LeaveCriticalSection(&wma->cs);
return dwRet;
}
wma->nUseCount--;
LeaveCriticalSection(&wma->cs);
return dwRet;
}
@ -341,7 +385,7 @@ static DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP
*/
static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
DWORD tc;
DWORD frameTime;
DWORD delta;
@ -353,19 +397,34 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = (WINE_MCIAVI *)MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
if (!wma->hFile) return MCIERR_FILE_NOT_FOUND;
if (!wma->hWndPaint) return MCIERR_NO_WINDOW;
EnterCriticalSection(&wma->cs);
wma->dwStatus = MCI_MODE_PLAY;
if (!(dwFlags & MCI_WAIT)) {
return MCI_SendCommandAsync(wma->openParms.wDeviceID, MCI_PLAY, dwFlags,
(DWORD)lpParms, sizeof(MCI_PLAY_PARMS));
if (!wma->hFile)
{
LeaveCriticalSection(&wma->cs);
return MCIERR_FILE_NOT_FOUND;
}
if (!wma->hWndPaint)
{
LeaveCriticalSection(&wma->cs);
return MCIERR_NO_WINDOW;
}
ShowWindow(wma->hWndPaint, SW_SHOW);
wma->dwStatus = MCI_MODE_PLAY;
LeaveCriticalSection(&wma->cs);
if (!(dwFlags & MCI_WAIT)) {
return MCI_SendCommandAsync(wDevID, MCI_PLAY, dwFlags,
(DWORD_PTR)lpParms, sizeof(MCI_PLAY_PARMS));
}
ShowWindow(wma->hWndPaint, SW_SHOWNA);
EnterCriticalSection(&wma->cs);
dwFromFrame = wma->dwCurrVideoFrame;
dwToFrame = wma->dwPlayableVideoFrames - 1;
@ -381,10 +440,14 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
TRACE("Playing from frame=%lu to frame=%lu\n", dwFromFrame, dwToFrame);
if (dwToFrame <= wma->dwCurrVideoFrame)
return TRUE;
wma->dwCurrVideoFrame = dwFromFrame;
if (dwToFrame <= wma->dwCurrVideoFrame)
{
dwRet = 0;
goto mci_play_done;
}
if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_DGV_PLAY_REVERSE|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN))
FIXME("Unsupported flag %08lx\n", dwFlags);
@ -392,13 +455,19 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
frameTime = (wma->mah.dwMicroSecPerFrame + 500) / 1000;
if (wma->lpWaveFormat) {
if ((dwRet = MCIAVI_OpenAudio(wma, &nHdr, &waveHdr)) != 0)
goto cleanUp;
if (MCIAVI_OpenAudio(wma, &nHdr, &waveHdr) != 0)
{
/* can't play audio */
HeapFree(GetProcessHeap(), 0, wma->lpWaveFormat);
wma->lpWaveFormat = NULL;
}
else
/* fill the queue with as many wave headers as possible */
MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
}
while (wma->dwStatus != MCI_MODE_STOP && wma->dwStatus != MCI_MODE_NOT_READY) {
while (wma->dwStatus == MCI_MODE_PLAY)
{
tc = GetTickCount();
MCIAVI_DrawFrame(wma);
@ -406,22 +475,35 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
if (wma->lpWaveFormat) {
MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
delta = GetTickCount() - tc;
WaitForSingleObject(wma->hEvent, (delta >= frameTime) ? 0 : frameTime - delta);
LeaveCriticalSection(&wma->cs);
MsgWaitForMultipleObjects(1, &wma->hEvent, FALSE,
(delta >= frameTime) ? 0 : frameTime - delta, MWMO_INPUTAVAILABLE);
EnterCriticalSection(&wma->cs);
if (wma->dwStatus != MCI_MODE_PLAY) break;
}
delta = GetTickCount() - tc;
if (delta < frameTime)
Sleep(frameTime - delta);
if (wma->dwCurrVideoFrame++ >= dwToFrame) {
wma->dwCurrVideoFrame--;
wma->dwStatus = MCI_MODE_STOP;
{
LeaveCriticalSection(&wma->cs);
MsgWaitForMultipleObjects(0, NULL, FALSE, frameTime - delta, MWMO_INPUTAVAILABLE);
EnterCriticalSection(&wma->cs);
}
if (wma->dwCurrVideoFrame < dwToFrame)
wma->dwCurrVideoFrame++;
else
break;
}
if (wma->lpWaveFormat) {
while (*(volatile DWORD*)&wma->dwEventCount != nHdr - 1) {
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 */
@ -432,7 +514,7 @@ static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms
}
dwRet = 0;
cleanUp:
if (wma->lpWaveFormat) {
HeapFree(GetProcessHeap(), 0, waveHdr);
@ -443,14 +525,15 @@ cleanUp:
CloseHandle(wma->hEvent);
}
mci_play_done:
wma->dwStatus = MCI_MODE_STOP;
if (lpParms && (dwFlags & MCI_NOTIFY)) {
TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
wDevID, MCI_NOTIFY_SUCCESSFUL);
}
wma->dwStatus = MCI_MODE_STOP;
LeaveCriticalSection(&wma->cs);
return dwRet;
}
@ -459,14 +542,20 @@ cleanUp:
*/
static DWORD MCIAVI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECORD_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
wma->dwStatus = MCI_MODE_RECORD;
LeaveCriticalSection(&wma->cs);
return 0;
}
@ -475,14 +564,16 @@ static DWORD MCIAVI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECORD_PARMS
*/
static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
DWORD dwRet = 0;
TRACE("(%04x, %08lX, %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);
switch (wma->dwStatus) {
case MCI_MODE_PAUSE:
case MCI_MODE_PLAY:
@ -493,19 +584,26 @@ static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa
if (oldStat == MCI_MODE_PAUSE)
dwRet = waveOutReset(wma->hWave);
}
while (wma->dwStatus != MCI_MODE_STOP)
Sleep(10);
break;
/* fall through */
default:
wma->dwStatus = MCI_MODE_STOP;
do /* one more chance for an async thread to finish */
{
LeaveCriticalSection(&wma->cs);
Sleep(10);
EnterCriticalSection(&wma->cs);
} while (wma->dwStatus != MCI_MODE_STOP);
break;
case MCI_MODE_NOT_READY:
break;
}
if ((dwFlags & MCI_NOTIFY) && lpParms) {
mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
wDevID, MCI_NOTIFY_SUCCESSFUL);
}
LeaveCriticalSection(&wma->cs);
return dwRet;
}
@ -514,15 +612,21 @@ static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa
*/
static DWORD MCIAVI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
DWORD ret;
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
if (wma->dwStatus == MCI_MODE_PLAY)
wma->dwStatus = MCI_MODE_PAUSE;
return (wma->lpWaveFormat) ? waveOutPause(wma->hWave) : 0;
ret = (wma->lpWaveFormat) ? waveOutPause(wma->hWave) : 0;
LeaveCriticalSection(&wma->cs);
return ret;
}
/***************************************************************************
@ -530,17 +634,23 @@ static DWORD MCIAVI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpP
*/
static DWORD MCIAVI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
DWORD ret;
FIXME("(%04x, %08lX, %p) : stub\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);
if (wma->dwStatus == MCI_MODE_PAUSE)
wma->dwStatus = MCI_MODE_PLAY;
return (wma->lpWaveFormat) ? waveOutRestart(wma->hWave) : 0;
ret = (wma->lpWaveFormat) ? waveOutRestart(wma->hWave) : 0;
LeaveCriticalSection(&wma->cs);
return ret;
}
/***************************************************************************
@ -548,17 +658,19 @@ static DWORD MCIAVI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lp
*/
static DWORD MCIAVI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
MCIAVI_mciStop(wDevID, MCI_WAIT, 0);
if (dwFlags & MCI_SEEK_TO_START) {
wma->dwCurrVideoFrame = 0;
} else if (dwFlags & MCI_SEEK_TO_END) {
@ -575,11 +687,9 @@ static DWORD MCIAVI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms
if (dwFlags & MCI_NOTIFY) {
mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
wDevID, MCI_NOTIFY_SUCCESSFUL);
}
LeaveCriticalSection(&wma->cs);
return 0;
}
@ -588,11 +698,15 @@ static DWORD MCIAVI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms
*/
static DWORD MCIAVI_mciLoad(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LOAD_PARMSA lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -603,11 +717,15 @@ static DWORD MCIAVI_mciLoad(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LOAD_PARMSA lp
*/
static DWORD MCIAVI_mciSave(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SAVE_PARMSA lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -618,11 +736,15 @@ static DWORD MCIAVI_mciSave(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SAVE_PARMSA lp
*/
static DWORD MCIAVI_mciFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -633,11 +755,15 @@ static DWORD MCIAVI_mciFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS l
*/
static DWORD MCIAVI_mciRealize(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -648,11 +774,15 @@ static DWORD MCIAVI_mciRealize(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS l
*/
static DWORD MCIAVI_mciUnFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -663,11 +793,15 @@ static DWORD MCIAVI_mciUnFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS
*/
static DWORD MCIAVI_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -678,11 +812,15 @@ static DWORD MCIAVI_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS
*/
static DWORD MCIAVI_mciStep(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STEP_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -693,11 +831,15 @@ static DWORD MCIAVI_mciStep(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STEP_PARMS lpP
*/
static DWORD MCIAVI_mciCopy(UINT wDevID, DWORD dwFlags, LPMCI_DGV_COPY_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -708,11 +850,15 @@ static DWORD MCIAVI_mciCopy(UINT wDevID, DWORD dwFlags, LPMCI_DGV_COPY_PARMS lpP
*/
static DWORD MCIAVI_mciCut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUT_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -723,11 +869,15 @@ static DWORD MCIAVI_mciCut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUT_PARMS lpPar
*/
static DWORD MCIAVI_mciDelete(UINT wDevID, DWORD dwFlags, LPMCI_DGV_DELETE_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -738,11 +888,15 @@ static DWORD MCIAVI_mciDelete(UINT wDevID, DWORD dwFlags, LPMCI_DGV_DELETE_PARMS
*/
static DWORD MCIAVI_mciPaste(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PASTE_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -753,11 +907,15 @@ static DWORD MCIAVI_mciPaste(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PASTE_PARMS l
*/
static DWORD MCIAVI_mciCue(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUE_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -768,11 +926,15 @@ static DWORD MCIAVI_mciCue(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUE_PARMS lpPar
*/
static DWORD MCIAVI_mciCapture(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CAPTURE_PARMSA lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -783,11 +945,15 @@ static DWORD MCIAVI_mciCapture(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CAPTURE_PAR
*/
static DWORD MCIAVI_mciMonitor(UINT wDevID, DWORD dwFlags, LPMCI_DGV_MONITOR_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -798,11 +964,15 @@ static DWORD MCIAVI_mciMonitor(UINT wDevID, DWORD dwFlags, LPMCI_DGV_MONITOR_PAR
*/
static DWORD MCIAVI_mciReserve(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESERVE_PARMSA lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -813,11 +983,15 @@ static DWORD MCIAVI_mciReserve(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESERVE_PAR
*/
static DWORD MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSA lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -828,11 +1002,15 @@ static DWORD MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_P
*/
static DWORD MCIAVI_mciSignal(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SIGNAL_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -843,11 +1021,15 @@ static DWORD MCIAVI_mciSignal(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SIGNAL_PARMS
*/
static DWORD MCIAVI_mciSetVideo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETVIDEO_PARMSA lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -858,11 +1040,15 @@ static DWORD MCIAVI_mciSetVideo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETVIDEO_P
*/
static DWORD MCIAVI_mciQuality(UINT wDevID, DWORD dwFlags, LPMCI_DGV_QUALITY_PARMSA lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -873,11 +1059,15 @@ static DWORD MCIAVI_mciQuality(UINT wDevID, DWORD dwFlags, LPMCI_DGV_QUALITY_PAR
*/
static DWORD MCIAVI_mciList(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LIST_PARMSA lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -888,11 +1078,15 @@ static DWORD MCIAVI_mciList(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LIST_PARMSA lp
*/
static DWORD MCIAVI_mciUndo(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -903,11 +1097,15 @@ static DWORD MCIAVI_mciUndo(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPa
*/
static DWORD MCIAVI_mciConfigure(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -918,11 +1116,15 @@ static DWORD MCIAVI_mciConfigure(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS
*/
static DWORD MCIAVI_mciRestore(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESTORE_PARMSA lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@ -954,7 +1156,8 @@ LONG CALLBACK MCIAVI_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
case DRV_REMOVE: return DRVCNF_RESTART;
}
if (dwDevID == 0xFFFFFFFF) return MCIERR_UNSUPPORTED_FUNCTION;
/* session instance */
if (dwDevID == 0xFFFFFFFF) return 1;
switch (wMsg) {
case MCI_OPEN_DRIVER: return MCIAVI_mciOpen (dwDevID, dwParam1, (LPMCI_DGV_OPEN_PARMSA) dwParam2);

View File

@ -4,6 +4,7 @@
* Digital video MCI Wine Driver
*
* Copyright 1999, 2000 Eric POUECH
* Copyright 2003 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -25,16 +26,10 @@
WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI* wma, const MMCKINFO* mmckList)
static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI* wma, const MMCKINFO* mmckList, MMCKINFO *mmckStream)
{
MMCKINFO mmckInfo;
mmckInfo.ckid = ckidSTREAMHEADER;
if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
WARN("Can't find 'strh' chunk\n");
return FALSE;
}
mmioRead(wma->hFile, (LPSTR)&wma->ash_audio, sizeof(wma->ash_audio));
TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_audio.fccType)),
@ -59,11 +54,12 @@ static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI* wma, const MMCKINFO* mmckList)
TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_audio.rcFrame.top, wma->ash_audio.rcFrame.left,
wma->ash_audio.rcFrame.bottom, wma->ash_audio.rcFrame.right);
mmioAscend(wma->hFile, &mmckInfo, 0);
/* rewind to the start of the stream */
mmioAscend(wma->hFile, mmckStream, 0);
mmckInfo.ckid = ckidSTREAMFORMAT;
if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
WARN("Can't find 'strh' chunk\n");
WARN("Can't find 'strf' chunk\n");
return FALSE;
}
if (mmckInfo.cksize < sizeof(WAVEFORMAT)) {
@ -87,21 +83,13 @@ static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI* wma, const MMCKINFO* mmckList)
if (mmckInfo.cksize >= sizeof(WAVEFORMATEX))
TRACE("waveFormat.cbSize=%d\n", wma->lpWaveFormat->cbSize);
mmioAscend(wma->hFile, &mmckInfo, 0);
return TRUE;
}
static BOOL MCIAVI_GetInfoVideo(WINE_MCIAVI* wma, const MMCKINFO* mmckList)
static BOOL MCIAVI_GetInfoVideo(WINE_MCIAVI* wma, const MMCKINFO* mmckList, MMCKINFO* mmckStream)
{
MMCKINFO mmckInfo;
mmckInfo.ckid = ckidSTREAMHEADER;
if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
WARN("Can't find 'strh' chunk\n");
return FALSE;
}
mmioRead(wma->hFile, (LPSTR)&wma->ash_video, sizeof(wma->ash_video));
TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_video.fccType)),
@ -126,11 +114,12 @@ static BOOL MCIAVI_GetInfoVideo(WINE_MCIAVI* wma, const MMCKINFO* mmckList)
TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_video.rcFrame.top, wma->ash_video.rcFrame.left,
wma->ash_video.rcFrame.bottom, wma->ash_video.rcFrame.right);
mmioAscend(wma->hFile, &mmckInfo, 0);
/* rewind to the start of the stream */
mmioAscend(wma->hFile, mmckStream, 0);
mmckInfo.ckid = ckidSTREAMFORMAT;
if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
WARN("Can't find 'strh' chunk\n");
WARN("Can't find 'strf' chunk\n");
return FALSE;
}
@ -154,7 +143,12 @@ static BOOL MCIAVI_GetInfoVideo(WINE_MCIAVI* wma, const MMCKINFO* mmckList)
TRACE("bih.biClrUsed=%ld\n", wma->inbih->biClrUsed);
TRACE("bih.biClrImportant=%ld\n", wma->inbih->biClrImportant);
mmioAscend(wma->hFile, &mmckInfo, 0);
wma->source.left = 0;
wma->source.top = 0;
wma->source.right = wma->inbih->biWidth;
wma->source.bottom = wma->inbih->biHeight;
wma->dest = wma->source;
return TRUE;
}
@ -178,6 +172,9 @@ static BOOL MCIAVI_AddFrame(WINE_MCIAVI* wma, LPMMCKINFO mmck,
case cktypePALchange:
TRACE("Adding video frame[%ld]: %ld bytes\n",
alb->numVideoFrames, mmck->cksize);
if (!mmck->cksize)
TRACE("got a zero sized frame\n");
if (alb->numVideoFrames < wma->dwPlayableVideoFrames) {
wma->lpVideoIndex[alb->numVideoFrames].dwOffset = mmck->dwDataOffset;
wma->lpVideoIndex[alb->numVideoFrames].dwSize = mmck->cksize;
@ -263,25 +260,43 @@ BOOL MCIAVI_GetInfo(WINE_MCIAVI* wma)
mmioAscend(wma->hFile, &mmckInfo, 0);
mmckList.fccType = listtypeSTREAMHEADER;
if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) != 0) {
WARN("Can't find 'strl' list\n");
return FALSE;
}
if (!MCIAVI_GetInfoVideo(wma, &mmckList)) {
return FALSE;
}
mmioAscend(wma->hFile, &mmckList, 0);
TRACE("Start of streams\n");
do
{
MMCKINFO mmckStream;
mmckList.fccType = listtypeSTREAMHEADER;
if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) == 0) {
if (!MCIAVI_GetInfoAudio(wma, &mmckList)) {
if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) != 0)
break;
mmckStream.ckid = ckidSTREAMHEADER;
if (mmioDescend(wma->hFile, &mmckStream, &mmckList, MMIO_FINDCHUNK) != 0)
{
WARN("Can't find 'strh' chunk\n");
continue;
}
TRACE("Stream fccType %4.4s\n", (LPSTR)&mmckStream.fccType);
if (mmckStream.fccType == streamtypeVIDEO)
{
TRACE("found video stream\n");
if (!MCIAVI_GetInfoVideo(wma, &mmckList, &mmckStream))
return FALSE;
}
mmioAscend(wma->hFile, &mmckList, 0);
else if (mmckStream.fccType == streamtypeAUDIO)
{
TRACE("found audio stream\n");
if (!MCIAVI_GetInfoAudio(wma, &mmckList, &mmckStream))
return FALSE;
}
else
TRACE("Unsupported stream type %4.4s\n", (LPSTR)&mmckStream.fccType);
mmioAscend(wma->hFile, &mmckList, 0);
} while(1);
TRACE("End of streams\n");
mmioAscend(wma->hFile, &mmckHead, 0);
@ -351,6 +366,8 @@ BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wma)
DWORD outSize;
FOURCC fcc = wma->ash_video.fccHandler;
TRACE("fcc %4.4s\n", (LPSTR)&fcc);
/* check uncompressed AVI */
if ((fcc == mmioFOURCC('D','I','B',' ')) ||
(fcc == mmioFOURCC('R','L','E',' '))) {
@ -411,10 +428,14 @@ BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wma)
return TRUE;
}
static void CALLBACK MCIAVI_waveCallback(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance,
DWORD dwParam1, DWORD dwParam2)
static void CALLBACK MCIAVI_waveCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
WINE_MCIAVI* wma = (WINE_MCIAVI*)dwInstance;
WINE_MCIAVI *wma = (WINE_MCIAVI *)MCIAVI_mciGetOpenDev(dwInstance);
if (!wma) return;
EnterCriticalSection(&wma->cs);
switch (uMsg) {
case WOM_OPEN:
@ -428,6 +449,8 @@ static void CALLBACK MCIAVI_waveCallback(HWAVEOUT hwo, UINT uMsg, DWORD dwInstan
default:
ERR("Unknown uMsg=%d\n", uMsg);
}
LeaveCriticalSection(&wma->cs);
}
DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma, unsigned* nHdr, LPWAVEHDR* pWaveHdr)
@ -437,7 +460,7 @@ DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma, unsigned* nHdr, LPWAVEHDR* pWaveHdr)
unsigned i;
dwRet = waveOutOpen((HWAVEOUT *)&wma->hWave, WAVE_MAPPER, wma->lpWaveFormat,
(DWORD)MCIAVI_waveCallback, (DWORD)wma, CALLBACK_FUNCTION);
(DWORD_PTR)MCIAVI_waveCallback, wma->wDevID, CALLBACK_FUNCTION);
if (dwRet != 0) {
TRACE("Can't open low level audio device %ld\n", dwRet);
dwRet = MCIERR_DEVICE_OPEN;
@ -543,7 +566,11 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC)
hdcMem = CreateCompatibleDC(hDC);
hbmOld = SelectObject(hdcMem, wma->hbmFrame);
BitBlt(hDC, 0, 0, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY);
StretchBlt(hDC,
wma->dest.left, wma->dest.top, wma->dest.right, wma->dest.bottom,
hdcMem,
wma->source.left, wma->source.top, wma->source.right, wma->source.bottom,
SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
@ -559,8 +586,6 @@ LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wma)
if (!wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset)
return FALSE;
EnterCriticalSection(&wma->cs);
mmioSeek(wma->hFile, wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset, SEEK_SET);
mmioRead(wma->hFile, wma->indata, wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize);
@ -570,7 +595,6 @@ LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wma)
if (wma->hic &&
ICDecompress(wma->hic, 0, wma->inbih, wma->indata,
wma->outbih, wma->outdata) != ICERR_OK) {
LeaveCriticalSection(&wma->cs);
WARN("Decompression error\n");
return FALSE;
}

View File

@ -41,12 +41,12 @@ struct MMIOPos {
};
typedef struct {
UINT wDevID;
MCIDEVICEID wDevID;
int nUseCount; /* Incremented for each shared open */
BOOL fShareable; /* TRUE if first open was shareable */
WORD wCommandTable; /* custom MCI command table */
volatile DWORD dwStatus; /* One of MCI_MODE_XXX */
MCI_OPEN_PARMSA openParms;
DWORD dwStatus; /* One of MCI_MODE_XXX */
LPSTR lpFileName;
DWORD dwMciTimeFormat; /* current time format */
DWORD dwSet; /* what's turned on: video & audio l&r */
/* information on the loaded AVI file */
@ -75,6 +75,7 @@ typedef struct {
HWND hWnd, hWndPaint;
DWORD dwCurrVideoFrame; /* video frame to display and current position */
DWORD dwCurrAudioBlock; /* current audio block being played */
RECT source, dest;
/* data for the background mechanism */
CRITICAL_SECTION cs;
} WINE_MCIAVI;
@ -99,6 +100,7 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* wma, HDC hDC);
/* mciavi.c */
WINE_MCIAVI* MCIAVI_mciGetOpenDev(UINT wDevID);
DWORD MCIAVI_mciClose(UINT, DWORD, LPMCI_GENERIC_PARMS);
/* window.c */
BOOL MCIAVI_CreateWindow(WINE_MCIAVI* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpOpenParms);

View File

@ -4,6 +4,7 @@
* Digital video MCI Wine Driver
*
* Copyright 1999, 2000 Eric POUECH
* Copyright 2003 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -30,15 +31,13 @@ static LRESULT WINAPI MCIAVI_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
{
TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hWnd, uMsg, wParam, lParam);
if (!(WINE_MCIAVI*)GetWindowLongA(hWnd, 0) && uMsg != WM_CREATE)
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
switch (uMsg) {
case WM_CREATE:
SetWindowLongA(hWnd, 0, (LPARAM)((CREATESTRUCTA*)lParam)->lpCreateParams);
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
case WM_DESTROY:
MCIAVI_mciClose(GetWindowLongA(hWnd, 0), MCI_WAIT, NULL);
SetWindowLongA(hWnd, 0, 0);
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
@ -48,32 +47,38 @@ static LRESULT WINAPI MCIAVI_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
GetClientRect(hWnd, &rect);
FillRect((HDC)wParam, &rect, GetStockObject(BLACK_BRUSH));
}
break;
return 1;
case WM_PAINT:
{
WINE_MCIAVI* wma = (WINE_MCIAVI*)GetWindowLongA(hWnd, 0);
WINE_MCIAVI *wma = (WINE_MCIAVI *)mciGetDriverData(GetWindowLongA(hWnd, 0));
if (!wma)
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
EnterCriticalSection(&wma->cs);
/* the animation isn't playing, don't paint */
if (wma->dwStatus == MCI_MODE_NOT_READY)
{
LeaveCriticalSection(&wma->cs);
/* default paint handling */
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
}
if (wParam) {
EnterCriticalSection(&wma->cs);
if (wParam)
MCIAVI_PaintFrame(wma, (HDC)wParam);
LeaveCriticalSection(&wma->cs);
} else {
else
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
EnterCriticalSection(&wma->cs);
MCIAVI_PaintFrame(wma, hDC);
LeaveCriticalSection(&wma->cs);
EndPaint(hWnd, &ps);
}
LeaveCriticalSection(&wma->cs);
}
break;
return 1;
default:
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
@ -93,15 +98,16 @@ BOOL MCIAVI_CreateWindow(WINE_MCIAVI* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARM
if (wma->hWnd) return TRUE;
ZeroMemory(&wndClass, sizeof(WNDCLASSA));
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
wndClass.style = CS_DBLCLKS;
wndClass.lpfnWndProc = (WNDPROC)MCIAVI_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = sizeof(WINE_MCIAVI*);
wndClass.cbWndExtra = sizeof(MCIDEVICEID);
wndClass.hInstance = MCIAVI_hInstance;
wndClass.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndClass.lpszClassName = "MCIAVI";
RegisterClassA(&wndClass);
if (!RegisterClassA(&wndClass)) return FALSE;
if (dwFlags & MCI_DGV_OPEN_PARENT) hParent = lpOpenParms->hWndParent;
if (dwFlags & MCI_DGV_OPEN_WS) dwStyle = lpOpenParms->dwStyle;
@ -116,7 +122,8 @@ BOOL MCIAVI_CreateWindow(WINE_MCIAVI* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARM
wma->hWnd = CreateWindowA("MCIAVI", "Wine MCI-AVI player",
dwStyle, rc.left, rc.top,
rc.right, rc.bottom,
hParent, 0, MCIAVI_hInstance, wma);
hParent, 0, MCIAVI_hInstance,
(LPVOID)wma->wDevID);
wma->hWndPaint = wma->hWnd;
return (BOOL)wma->hWnd;
}
@ -128,40 +135,49 @@ DWORD MCIAVI_mciPut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PUT_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
RECT rc;
char buffer[256];
FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
if (dwFlags & MCI_DGV_RECT) {
rc = lpParms->rc;
} else {
SetRectEmpty(&rc);
GetClientRect(wma->hWndPaint, &rc);
}
*buffer = 0;
if (dwFlags & MCI_DGV_PUT_CLIENT) {
strncat(buffer, "PUT_CLIENT", sizeof(buffer));
FIXME("PUT_CLIENT %s\n", wine_dbgstr_rect(&rc));
LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_PUT_DESTINATION) {
strncat(buffer, "PUT_DESTINATION", sizeof(buffer));
TRACE("PUT_DESTINATION %s\n", wine_dbgstr_rect(&rc));
wma->dest = rc;
}
if (dwFlags & MCI_DGV_PUT_FRAME) {
strncat(buffer, "PUT_FRAME", sizeof(buffer));
FIXME("PUT_FRAME %s\n", wine_dbgstr_rect(&rc));
LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_PUT_SOURCE) {
strncat(buffer, "PUT_SOURCE", sizeof(buffer));
TRACE("PUT_SOURCE %s\n", wine_dbgstr_rect(&rc));
wma->source = rc;
}
if (dwFlags & MCI_DGV_PUT_VIDEO) {
strncat(buffer, "PUT_VIDEO", sizeof(buffer));
FIXME("PUT_VIDEO %s\n", wine_dbgstr_rect(&rc));
LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_PUT_WINDOW) {
strncat(buffer, "PUT_WINDOW", sizeof(buffer));
FIXME("PUT_WINDOW %s\n", wine_dbgstr_rect(&rc));
LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
TRACE("%s (%ld,%ld,%ld,%ld)\n", buffer, rc.left, rc.top, rc.right, rc.bottom);
LeaveCriticalSection(&wma->cs);
return 0;
}
@ -171,40 +187,43 @@ DWORD MCIAVI_mciPut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PUT_PARMS lpParms)
DWORD MCIAVI_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
LPCSTR x = "";
TRACE("(%04x, %08lx, %p)\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
if (dwFlags & MCI_DGV_WHERE_MAX) FIXME("Max NIY\n");
if (dwFlags & MCI_DGV_WHERE_MAX)
{
FIXME("WHERE_MAX\n");
return MCIERR_UNRECOGNIZED_COMMAND;
}
EnterCriticalSection(&wma->cs);
if (dwFlags & MCI_DGV_WHERE_DESTINATION) {
x = "Dest";
GetClientRect(wma->hWnd, &lpParms->rc);
TRACE("WHERE_DESTINATION %s\n", wine_dbgstr_rect(&wma->dest));
lpParms->rc = wma->dest;
}
if (dwFlags & MCI_DGV_WHERE_FRAME) {
FIXME(x = "Frame\n");
FIXME("MCI_DGV_WHERE_FRAME\n");
LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_WHERE_SOURCE) {
x = "Source";
lpParms->rc.left = lpParms->rc.top = 0;
lpParms->rc.right = wma->mah.dwWidth;
lpParms->rc.bottom = wma->mah.dwHeight;
TRACE("WHERE_SOURCE %s\n", wine_dbgstr_rect(&wma->source));
lpParms->rc = wma->source;
}
if (dwFlags & MCI_DGV_WHERE_VIDEO) {
FIXME(x = "Video\n");
FIXME("WHERE_VIDEO\n");
LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_WHERE_WINDOW) {
x = "Window";
GetClientRect(wma->hWndPaint, &lpParms->rc);
TRACE("WHERE_WINDOW %s\n", wine_dbgstr_rect(&lpParms->rc));
}
TRACE("%s -> (%ld,%ld,%ld,%ld)\n",
x, lpParms->rc.left, lpParms->rc.top, lpParms->rc.right, lpParms->rc.bottom);
LeaveCriticalSection(&wma->cs);
return 0;
}
@ -220,12 +239,17 @@ DWORD MCIAVI_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMSA lpPar
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
if (dwFlags & MCI_DGV_WINDOW_HWND) {
if (IsWindow(lpParms->hWnd))
{
TRACE("Setting hWnd to %p\n", lpParms->hWnd);
if (wma->hWnd) ShowWindow(wma->hWnd, SW_HIDE);
wma->hWndPaint = (lpParms->hWnd == MCI_DGV_WINDOW_DEFAULT) ? wma->hWnd : lpParms->hWnd;
InvalidateRect(wma->hWndPaint, NULL, FALSE);
}
}
if (dwFlags & MCI_DGV_WINDOW_STATE) {
TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow);
ShowWindow(wma->hWndPaint, lpParms->nCmdShow);
@ -235,5 +259,6 @@ DWORD MCIAVI_mciWindow(UINT wDevID, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMSA lpPar
SetWindowTextA(wma->hWndPaint, lpParms->lpstrText);
}
LeaveCriticalSection(&wma->cs);
return 0;
}