1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * Digital video MCI Wine Driver
6 * Copyright 1999, 2000 Eric POUECH
10 * - handling of palettes
11 * - recording (which input devices ?), a cam recorder ?
12 * - lots of messages still need to be handled (cf FIXME)
13 * - synchronization between audio and video (especially for interleaved
15 * - synchronization (as in all the Wine MCI drivers (MCI_WAIT) messages)
16 * - robustness when reading file can be enhanced
17 * - better move the AVI handling part to avifile DLL and make use of it
18 * - some files appear to have more than one audio stream (we only play the
20 * - some files contain an index of audio/video frame. Better use it,
21 * instead of rebuilding it
22 * - mciWindow (for setting the hWnd) is broken with media player
23 * - stopping while playing a file with sound blocks until all buffered
24 * audio is played... still should be stopped ASAP
28 #include "private_mciavi.h"
29 #include "debugtools.h"
31 DEFAULT_DEBUG_CHANNEL(mciavi
);
33 /* ===================================================================
34 * ===================================================================
35 * FIXME: should be using the new mmThreadXXXX functions from WINMM
37 * it would require to add a wine internal flag to mmThreadCreate
38 * in order to pass a 32 bit function instead of a 16 bit one
39 * ===================================================================
40 * =================================================================== */
49 /**************************************************************************
50 * MCI_SCAStarter [internal]
52 static DWORD CALLBACK
MCI_SCAStarter(LPVOID arg
)
54 struct SCA
* sca
= (struct SCA
*)arg
;
57 TRACE("In thread before async command (%08x,%u,%08lx,%08lx)\n",
58 sca
->wDevID
, sca
->wMsg
, sca
->dwParam1
, sca
->dwParam2
);
59 ret
= mciSendCommandA(sca
->wDevID
, sca
->wMsg
, sca
->dwParam1
| MCI_WAIT
, sca
->dwParam2
);
60 TRACE("In thread after async command (%08x,%u,%08lx,%08lx)\n",
61 sca
->wDevID
, sca
->wMsg
, sca
->dwParam1
, sca
->dwParam2
);
62 HeapFree(GetProcessHeap(), 0, sca
);
64 WARN("Should not happen ? what's wrong \n");
65 /* should not go after this point */
69 /**************************************************************************
70 * MCI_SendCommandAsync [internal]
72 static DWORD
MCI_SendCommandAsync(UINT wDevID
, UINT wMsg
, DWORD dwParam1
,
73 DWORD dwParam2
, UINT size
)
75 struct SCA
* sca
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA
) + size
);
78 return MCIERR_OUT_OF_MEMORY
;
82 sca
->dwParam1
= dwParam1
;
84 if (size
&& dwParam2
) {
85 sca
->dwParam2
= (DWORD
)sca
+ sizeof(struct SCA
);
86 /* copy structure passed by program in dwParam2 to be sure
87 * we can still use it whatever the program does
89 memcpy((LPVOID
)sca
->dwParam2
, (LPVOID
)dwParam2
, size
);
91 sca
->dwParam2
= dwParam2
;
94 if (CreateThread(NULL
, 0, MCI_SCAStarter
, sca
, 0, NULL
) == 0) {
95 WARN("Couldn't allocate thread for async command handling, sending synchronously\n");
96 return MCI_SCAStarter(&sca
);
101 /*======================================================================*
102 * MCI AVI implemantation *
103 *======================================================================*/
105 HINSTANCE MCIAVI_hInstance
= 0;
107 BOOL WINAPI
MCIAVI_LibMain(HINSTANCE hInstDLL
, DWORD fdwReason
, LPVOID fImpLoad
)
110 case DLL_PROCESS_ATTACH
:
111 MCIAVI_hInstance
= hInstDLL
;
117 /**************************************************************************
118 * MCIAVI_drvOpen [internal]
120 static DWORD
MCIAVI_drvOpen(LPSTR str
, LPMCI_OPEN_DRIVER_PARMSA modp
)
122 WINE_MCIAVI
* wma
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(WINE_MCIAVI
));
123 static WCHAR mciAviWStr
[] = {'M','C','I','A','V','I',0};
128 wma
->wDevID
= modp
->wDeviceID
;
129 mciSetDriverData(wma
->wDevID
, (DWORD
)wma
);
130 wma
->wCommandTable
= mciLoadCommandResource(MCIAVI_hInstance
, mciAviWStr
, 0);
131 modp
->wCustomCommandTable
= wma
->wCommandTable
;
132 modp
->wType
= MCI_DEVTYPE_DIGITAL_VIDEO
;
133 return modp
->wDeviceID
;
136 /**************************************************************************
137 * MCIAVI_drvClose [internal]
139 static DWORD
MCIAVI_drvClose(DWORD dwDevID
)
141 WINE_MCIAVI
* wma
= (WINE_MCIAVI
*)mciGetDriverData(dwDevID
);
144 mciSetDriverData(dwDevID
, 0);
145 mciFreeCommandResource(wma
->wCommandTable
);
146 HeapFree(GetProcessHeap(), 0, wma
);
152 /**************************************************************************
153 * MCIAVI_drvConfigure [internal]
155 static DWORD
MCIAVI_drvConfigure(DWORD dwDevID
)
157 WINE_MCIAVI
* wma
= (WINE_MCIAVI
*)mciGetDriverData(dwDevID
);
160 MessageBoxA(0, "Sample AVI Wine Driver !", "MM-Wine Driver", MB_OK
);
166 /**************************************************************************
167 * MCIAVI_mciGetOpenDev [internal]
169 WINE_MCIAVI
* MCIAVI_mciGetOpenDev(UINT wDevID
)
171 WINE_MCIAVI
* wma
= (WINE_MCIAVI
*)mciGetDriverData(wDevID
);
173 if (wma
== NULL
|| wma
->nUseCount
== 0) {
174 WARN("Invalid wDevID=%u\n", wDevID
);
180 static void MCIAVI_CleanUp(WINE_MCIAVI
* wma
)
182 /* to prevent handling in WindowProc */
183 wma
->dwStatus
= MCI_MODE_NOT_READY
;
185 mmioClose(wma
->hFile
, 0);
187 if (wma
->lpVideoIndex
) HeapFree(GetProcessHeap(), 0, wma
->lpVideoIndex
);
188 wma
->lpVideoIndex
= NULL
;
189 if (wma
->lpAudioIndex
) HeapFree(GetProcessHeap(), 0, wma
->lpAudioIndex
);
190 wma
->lpAudioIndex
= NULL
;
191 if (wma
->hic
) ICClose(wma
->hic
);
193 if (wma
->inbih
) HeapFree(GetProcessHeap(), 0, wma
->inbih
);
195 if (wma
->outbih
) HeapFree(GetProcessHeap(), 0, wma
->outbih
);
197 if (wma
->indata
) HeapFree(GetProcessHeap(), 0, wma
->indata
);
199 if (wma
->outdata
) HeapFree(GetProcessHeap(), 0, wma
->outdata
);
201 if (wma
->hbmFrame
) DeleteObject(wma
->hbmFrame
);
203 if (wma
->hWnd
) DestroyWindow(wma
->hWnd
);
206 if (wma
->lpWaveFormat
) HeapFree(GetProcessHeap(), 0, wma
->lpWaveFormat
);
207 wma
->lpWaveFormat
= 0;
209 memset(&wma
->mah
, 0, sizeof(wma
->mah
));
210 memset(&wma
->ash_video
, 0, sizeof(wma
->ash_video
));
211 memset(&wma
->ash_audio
, 0, sizeof(wma
->ash_audio
));
212 wma
->dwCurrVideoFrame
= wma
->dwCurrAudioBlock
= 0;
216 static DWORD
MCIAVI_mciStop(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
);
218 /***************************************************************************
219 * MCIAVI_mciOpen [internal]
221 static DWORD
MCIAVI_mciOpen(UINT wDevID
, DWORD dwFlags
,
222 LPMCI_DGV_OPEN_PARMSA lpOpenParms
)
224 WINE_MCIAVI
* wma
= (WINE_MCIAVI
*)mciGetDriverData(wDevID
);
227 TRACE("(%04x, %08lX, %p)\n", wDevID
, dwFlags
, lpOpenParms
);
229 if (lpOpenParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
230 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
232 if (wma
->nUseCount
> 0) {
233 /* The driver is already open on this channel */
234 /* If the driver was opened shareable before and this open specifies */
235 /* shareable then increment the use count */
236 if (wma
->fShareable
&& (dwFlags
& MCI_OPEN_SHAREABLE
))
239 return MCIERR_MUST_USE_SHAREABLE
;
242 wma
->fShareable
= dwFlags
& MCI_OPEN_SHAREABLE
;
245 wma
->dwStatus
= MCI_MODE_NOT_READY
;
246 InitializeCriticalSection(&wma
->cs
);
248 if (dwFlags
& MCI_OPEN_ELEMENT
) {
249 if (dwFlags
& MCI_OPEN_ELEMENT_ID
) {
250 /* could it be that (DWORD)lpOpenParms->lpstrElementName
251 * contains the hFile value ?
253 dwRet
= MCIERR_UNRECOGNIZED_COMMAND
;
254 } else if (strlen(lpOpenParms
->lpstrElementName
) > 0) {
255 /* FIXME : what should be done id wma->hFile is already != 0, or the driver is playin' */
256 TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpOpenParms
->lpstrElementName
);
258 if (lpOpenParms
->lpstrElementName
&& (strlen(lpOpenParms
->lpstrElementName
) > 0)) {
259 wma
->hFile
= mmioOpenA(lpOpenParms
->lpstrElementName
, NULL
,
260 MMIO_ALLOCBUF
| MMIO_DENYWRITE
| MMIO_READWRITE
);
262 if (wma
->hFile
== 0) {
263 WARN("can't find file='%s' !\n", lpOpenParms
->lpstrElementName
);
264 dwRet
= MCIERR_FILE_NOT_FOUND
;
266 if (!MCIAVI_GetInfo(wma
))
267 dwRet
= MCIERR_INVALID_FILE
;
268 else if (!MCIAVI_OpenVideo(wma
))
269 dwRet
= MCIERR_CANNOT_LOAD_DRIVER
;
270 else if (!MCIAVI_CreateWindow(wma
, dwFlags
, lpOpenParms
))
271 dwRet
= MCIERR_CREATEWINDOW
;
275 FIXME("Don't record yet\n");
276 dwRet
= MCIERR_UNSUPPORTED_FUNCTION
;
280 memcpy(&wma
->openParms
, lpOpenParms
, sizeof(MCI_WAVE_OPEN_PARMSA
));
283 wma
->dwStatus
= MCI_MODE_STOP
;
284 wma
->dwMciTimeFormat
= MCI_FORMAT_FRAMES
;
292 /***************************************************************************
293 * MCIAVI_mciClose [internal]
295 static DWORD
MCIAVI_mciClose(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
297 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
300 TRACE("(%04x, %08lX, %p)\n", wDevID
, dwFlags
, lpParms
);
302 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
304 if (wma
->nUseCount
== 1) {
305 if (wma
->dwStatus
!= MCI_MODE_STOP
)
306 dwRet
= MCIAVI_mciStop(wDevID
, MCI_WAIT
, lpParms
);
309 if ((dwFlags
& MCI_NOTIFY
) && lpParms
) {
310 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
311 wma
->openParms
.wDeviceID
,
312 MCI_NOTIFY_SUCCESSFUL
);
314 HeapFree(GetProcessHeap(), 0, wma
);
321 /***************************************************************************
322 * MCIAVI_mciPlay [internal]
324 static DWORD
MCIAVI_mciPlay(UINT wDevID
, DWORD dwFlags
, LPMCI_PLAY_PARMS lpParms
)
326 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
331 LPWAVEHDR waveHdr
= NULL
;
332 unsigned i
, nHdr
= 0;
333 DWORD dwFromFrame
, dwToFrame
;
335 TRACE("(%04x, %08lX, %p)\n", wDevID
, dwFlags
, lpParms
);
337 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
338 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
340 if (!wma
->hFile
) return MCIERR_FILE_NOT_FOUND
;
341 if (!wma
->hWnd
) return MCIERR_NO_WINDOW
;
343 wma
->dwStatus
= MCI_MODE_PLAY
;
345 if (!(dwFlags
& MCI_WAIT
)) {
346 return MCI_SendCommandAsync(wma
->openParms
.wDeviceID
, MCI_PLAY
, dwFlags
,
347 (DWORD
)lpParms
, sizeof(MCI_PLAY_PARMS
));
350 ShowWindow(wma
->hWnd
, SW_SHOW
);
352 dwFromFrame
= wma
->dwCurrVideoFrame
;
353 dwToFrame
= wma
->dwPlayableVideoFrames
- 1;
355 if (lpParms
&& (dwFlags
& MCI_FROM
)) {
356 dwFromFrame
= MCIAVI_ConvertTimeFormatToFrame(wma
, lpParms
->dwFrom
);
358 if (lpParms
&& (dwFlags
& MCI_TO
)) {
359 dwToFrame
= MCIAVI_ConvertTimeFormatToFrame(wma
, lpParms
->dwTo
);
361 if (dwToFrame
>= wma
->dwPlayableVideoFrames
)
362 dwToFrame
= wma
->dwPlayableVideoFrames
- 1;
364 TRACE("Playing from frame=%lu to frame=%lu\n", dwFromFrame
, dwToFrame
);
366 if (dwToFrame
<= wma
->dwCurrVideoFrame
)
368 wma
->dwCurrVideoFrame
= dwFromFrame
;
370 if (dwFlags
& (MCI_DGV_PLAY_REPEAT
|MCI_DGV_PLAY_REVERSE
|MCI_MCIAVI_PLAY_WINDOW
|MCI_MCIAVI_PLAY_FULLSCREEN
))
371 FIXME("Unsupported flag %08lx\n", dwFlags
);
373 /* time is in microseconds, we should convert it to milliseconds */
374 frameTime
= (wma
->mah
.dwMicroSecPerFrame
+ 500) / 1000;
376 if (wma
->lpWaveFormat
) {
377 if ((dwRet
= MCIAVI_OpenAudio(wma
, &nHdr
, &waveHdr
)) != 0)
379 /* fill the queue with as many wave headers as possible */
380 MCIAVI_PlayAudioBlocks(wma
, nHdr
, waveHdr
);
383 while (wma
->dwStatus
!= MCI_MODE_STOP
&& wma
->dwStatus
!= MCI_MODE_NOT_READY
) {
386 MCIAVI_DrawFrame(wma
);
388 if (wma
->lpWaveFormat
) {
389 MCIAVI_PlayAudioBlocks(wma
, nHdr
, waveHdr
);
390 delta
= GetTickCount() - tc
;
391 WaitForSingleObject(wma
->hEvent
, (delta
>= frameTime
) ? 0 : frameTime
- delta
);
394 delta
= GetTickCount() - tc
;
395 if (delta
< frameTime
)
396 Sleep(frameTime
- delta
);
398 if (wma
->dwCurrVideoFrame
++ >= dwToFrame
) {
399 wma
->dwCurrVideoFrame
--;
400 wma
->dwStatus
= MCI_MODE_STOP
;
404 if (wma
->lpWaveFormat
) {
405 while (*(volatile DWORD
*)&wma
->dwEventCount
!= nHdr
- 1) {
409 /* just to get rid of some race conditions between play, stop and pause */
410 waveOutReset(wma
->hWave
);
412 for (i
= 0; i
< nHdr
; i
++)
413 waveOutUnprepareHeader(wma
->hWave
, &waveHdr
[i
], sizeof(WAVEHDR
));
418 if (wma
->lpWaveFormat
) {
419 HeapFree(GetProcessHeap(), 0, waveHdr
);
422 waveOutClose(wma
->hWave
);
425 CloseHandle(wma
->hEvent
);
428 if (lpParms
&& (dwFlags
& MCI_NOTIFY
)) {
429 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
430 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
431 wma
->openParms
.wDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
434 wma
->dwStatus
= MCI_MODE_STOP
;
439 /***************************************************************************
440 * MCIAVI_mciRecord [internal]
442 static DWORD
MCIAVI_mciRecord(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_RECORD_PARMS lpParms
)
444 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
446 FIXME("(%04x, %08lX, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
448 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
449 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
451 wma
->dwStatus
= MCI_MODE_RECORD
;
455 /***************************************************************************
456 * MCIAVI_mciStop [internal]
458 static DWORD
MCIAVI_mciStop(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
460 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
463 TRACE("(%04x, %08lX, %p)\n", wDevID
, dwFlags
, lpParms
);
465 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
466 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
468 switch (wma
->dwStatus
) {
471 case MCI_MODE_RECORD
:
473 int oldStat
= wma
->dwStatus
;
474 wma
->dwStatus
= MCI_MODE_NOT_READY
;
475 if (oldStat
== MCI_MODE_PAUSE
)
476 dwRet
= waveOutReset(wma
->hWave
);
478 while (wma
->dwStatus
!= MCI_MODE_STOP
)
482 wma
->dwStatus
= MCI_MODE_STOP
;
486 if ((dwFlags
& MCI_NOTIFY
) && lpParms
) {
487 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
488 wma
->openParms
.wDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
494 /***************************************************************************
495 * MCIAVI_mciPause [internal]
497 static DWORD
MCIAVI_mciPause(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
499 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
501 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
502 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
504 if (wma
->dwStatus
== MCI_MODE_PLAY
)
505 wma
->dwStatus
= MCI_MODE_PAUSE
;
507 return (wma
->lpWaveFormat
) ? waveOutPause(wma
->hWave
) : 0;
510 /***************************************************************************
511 * MCIAVI_mciResume [internal]
513 static DWORD
MCIAVI_mciResume(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
515 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
517 FIXME("(%04x, %08lX, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
519 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
520 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
522 if (wma
->dwStatus
== MCI_MODE_PAUSE
)
523 wma
->dwStatus
= MCI_MODE_PLAY
;
525 return (wma
->lpWaveFormat
) ? waveOutRestart(wma
->hWave
) : 0;
528 /***************************************************************************
529 * MCIAVI_mciSeek [internal]
531 static DWORD
MCIAVI_mciSeek(UINT wDevID
, DWORD dwFlags
, LPMCI_SEEK_PARMS lpParms
)
533 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
535 TRACE("(%04x, %08lX, %p)\n", wDevID
, dwFlags
, lpParms
);
537 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
538 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
540 EnterCriticalSection(&wma
->cs
);
542 MCIAVI_mciStop(wDevID
, MCI_WAIT
, 0);
544 if (dwFlags
& MCI_SEEK_TO_START
) {
545 wma
->dwCurrVideoFrame
= 0;
546 } else if (dwFlags
& MCI_SEEK_TO_END
) {
547 wma
->dwCurrVideoFrame
= wma
->dwPlayableVideoFrames
- 1;
548 } else if (dwFlags
& MCI_TO
) {
549 wma
->dwCurrVideoFrame
= MCIAVI_ConvertTimeFormatToFrame(wma
, lpParms
->dwTo
);
551 WARN("dwFlag doesn't tell where to seek to...\n");
552 return MCIERR_MISSING_PARAMETER
;
555 TRACE("Seeking to frame=%lu bytes\n", wma
->dwCurrVideoFrame
);
557 if (dwFlags
& MCI_NOTIFY
) {
558 mciDriverNotify((HWND
)LOWORD(lpParms
->dwCallback
),
559 wma
->openParms
.wDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
562 LeaveCriticalSection(&wma
->cs
);
567 /*****************************************************************************
568 * MCIAVI_mciLoad [internal]
570 static DWORD
MCIAVI_mciLoad(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_LOAD_PARMSA lpParms
)
572 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
574 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
576 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
577 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
582 /******************************************************************************
583 * MCIAVI_mciSave [internal]
585 static DWORD
MCIAVI_mciSave(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_SAVE_PARMSA lpParms
)
587 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
589 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
591 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
592 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
597 /******************************************************************************
598 * MCIAVI_mciFreeze [internal]
600 static DWORD
MCIAVI_mciFreeze(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_RECT_PARMS lpParms
)
602 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
604 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
606 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
607 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
612 /******************************************************************************
613 * MCIAVI_mciRealize [internal]
615 static DWORD
MCIAVI_mciRealize(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
617 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
619 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
621 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
622 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
627 /******************************************************************************
628 * MCIAVI_mciUnFreeze [internal]
630 static DWORD
MCIAVI_mciUnFreeze(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_RECT_PARMS lpParms
)
632 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
634 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
636 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
637 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
642 /******************************************************************************
643 * MCIAVI_mciUpdate [internal]
645 static DWORD
MCIAVI_mciUpdate(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_UPDATE_PARMS lpParms
)
647 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
649 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
651 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
652 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
657 /******************************************************************************
658 * MCIAVI_mciStep [internal]
660 static DWORD
MCIAVI_mciStep(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_STEP_PARMS lpParms
)
662 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
664 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
666 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
667 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
672 /******************************************************************************
673 * MCIAVI_mciCopy [internal]
675 static DWORD
MCIAVI_mciCopy(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_COPY_PARMS lpParms
)
677 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
679 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
681 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
682 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
687 /******************************************************************************
688 * MCIAVI_mciCut [internal]
690 static DWORD
MCIAVI_mciCut(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_CUT_PARMS lpParms
)
692 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
694 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
696 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
697 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
702 /******************************************************************************
703 * MCIAVI_mciDelete [internal]
705 static DWORD
MCIAVI_mciDelete(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_DELETE_PARMS lpParms
)
707 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
709 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
711 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
712 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
717 /******************************************************************************
718 * MCIAVI_mciPaste [internal]
720 static DWORD
MCIAVI_mciPaste(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_PASTE_PARMS lpParms
)
722 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
724 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
726 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
727 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
732 /******************************************************************************
733 * MCIAVI_mciCue [internal]
735 static DWORD
MCIAVI_mciCue(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_CUE_PARMS lpParms
)
737 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
739 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
741 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
742 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
747 /******************************************************************************
748 * MCIAVI_mciCapture [internal]
750 static DWORD
MCIAVI_mciCapture(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_CAPTURE_PARMSA lpParms
)
752 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
754 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
756 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
757 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
762 /******************************************************************************
763 * MCIAVI_mciMonitor [internal]
765 static DWORD
MCIAVI_mciMonitor(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_MONITOR_PARMS lpParms
)
767 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
769 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
771 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
772 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
777 /******************************************************************************
778 * MCIAVI_mciReserve [internal]
780 static DWORD
MCIAVI_mciReserve(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_RESERVE_PARMSA lpParms
)
782 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
784 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
786 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
787 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
792 /******************************************************************************
793 * MCIAVI_mciSetAudio [internal]
795 static DWORD
MCIAVI_mciSetAudio(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_SETAUDIO_PARMSA lpParms
)
797 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
799 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
801 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
802 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
807 /******************************************************************************
808 * MCIAVI_mciSignal [internal]
810 static DWORD
MCIAVI_mciSignal(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_SIGNAL_PARMS lpParms
)
812 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
814 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
816 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
817 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
822 /******************************************************************************
823 * MCIAVI_mciSetVideo [internal]
825 static DWORD
MCIAVI_mciSetVideo(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_SETVIDEO_PARMSA lpParms
)
827 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
829 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
831 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
832 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
837 /******************************************************************************
838 * MCIAVI_mciQuality [internal]
840 static DWORD
MCIAVI_mciQuality(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_QUALITY_PARMSA lpParms
)
842 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
844 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
846 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
847 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
852 /******************************************************************************
853 * MCIAVI_mciList [internal]
855 static DWORD
MCIAVI_mciList(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_LIST_PARMSA lpParms
)
857 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
859 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
861 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
862 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
867 /******************************************************************************
868 * MCIAVI_mciUndo [internal]
870 static DWORD
MCIAVI_mciUndo(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
872 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
874 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
876 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
877 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
882 /******************************************************************************
883 * MCIAVI_mciConfigure [internal]
885 static DWORD
MCIAVI_mciConfigure(UINT wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
887 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
889 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
891 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
892 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
897 /******************************************************************************
898 * MCIAVI_mciRestore [internal]
900 static DWORD
MCIAVI_mciRestore(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_RESTORE_PARMSA lpParms
)
902 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
904 FIXME("(%04x, %08lx, %p) : stub\n", wDevID
, dwFlags
, lpParms
);
906 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
907 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
912 /*======================================================================*
913 * MCI AVI entry points *
914 *======================================================================*/
916 /**************************************************************************
917 * DriverProc (MCIAVI.@)
919 LONG CALLBACK
MCIAVI_DriverProc(DWORD dwDevID
, HDRVR hDriv
, DWORD wMsg
,
920 DWORD dwParam1
, DWORD dwParam2
)
922 TRACE("(%08lX, %04X, %08lX, %08lX, %08lX)\n",
923 dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
926 case DRV_LOAD
: return 1;
927 case DRV_FREE
: return 1;
928 case DRV_OPEN
: return MCIAVI_drvOpen((LPSTR
)dwParam1
, (LPMCI_OPEN_DRIVER_PARMSA
)dwParam2
);
929 case DRV_CLOSE
: return MCIAVI_drvClose(dwDevID
);
930 case DRV_ENABLE
: return 1;
931 case DRV_DISABLE
: return 1;
932 case DRV_QUERYCONFIGURE
: return 1;
933 case DRV_CONFIGURE
: return MCIAVI_drvConfigure(dwDevID
);
934 case DRV_INSTALL
: return DRVCNF_RESTART
;
935 case DRV_REMOVE
: return DRVCNF_RESTART
;
937 case MCI_OPEN_DRIVER
: return MCIAVI_mciOpen (dwDevID
, dwParam1
, (LPMCI_DGV_OPEN_PARMSA
) dwParam2
);
938 case MCI_CLOSE_DRIVER
: return MCIAVI_mciClose (dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
) dwParam2
);
939 case MCI_PLAY
: return MCIAVI_mciPlay (dwDevID
, dwParam1
, (LPMCI_PLAY_PARMS
) dwParam2
);
940 case MCI_RECORD
: return MCIAVI_mciRecord (dwDevID
, dwParam1
, (LPMCI_DGV_RECORD_PARMS
) dwParam2
);
941 case MCI_STOP
: return MCIAVI_mciStop (dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
) dwParam2
);
942 case MCI_SET
: return MCIAVI_mciSet (dwDevID
, dwParam1
, (LPMCI_DGV_SET_PARMS
) dwParam2
);
943 case MCI_PAUSE
: return MCIAVI_mciPause (dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
) dwParam2
);
944 case MCI_RESUME
: return MCIAVI_mciResume (dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
) dwParam2
);
945 case MCI_STATUS
: return MCIAVI_mciStatus (dwDevID
, dwParam1
, (LPMCI_DGV_STATUS_PARMSA
) dwParam2
);
946 case MCI_GETDEVCAPS
: return MCIAVI_mciGetDevCaps(dwDevID
, dwParam1
, (LPMCI_GETDEVCAPS_PARMS
) dwParam2
);
947 case MCI_INFO
: return MCIAVI_mciInfo (dwDevID
, dwParam1
, (LPMCI_DGV_INFO_PARMSA
) dwParam2
);
948 case MCI_SEEK
: return MCIAVI_mciSeek (dwDevID
, dwParam1
, (LPMCI_SEEK_PARMS
) dwParam2
);
949 case MCI_PUT
: return MCIAVI_mciPut (dwDevID
, dwParam1
, (LPMCI_DGV_PUT_PARMS
) dwParam2
);
950 case MCI_WINDOW
: return MCIAVI_mciWindow (dwDevID
, dwParam1
, (LPMCI_DGV_WINDOW_PARMSA
) dwParam2
);
951 case MCI_LOAD
: return MCIAVI_mciLoad (dwDevID
, dwParam1
, (LPMCI_DGV_LOAD_PARMSA
) dwParam2
);
952 case MCI_SAVE
: return MCIAVI_mciSave (dwDevID
, dwParam1
, (LPMCI_DGV_SAVE_PARMSA
) dwParam2
);
953 case MCI_FREEZE
: return MCIAVI_mciFreeze (dwDevID
, dwParam1
, (LPMCI_DGV_RECT_PARMS
) dwParam2
);
954 case MCI_REALIZE
: return MCIAVI_mciRealize (dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
) dwParam2
);
955 case MCI_UNFREEZE
: return MCIAVI_mciUnFreeze (dwDevID
, dwParam1
, (LPMCI_DGV_RECT_PARMS
) dwParam2
);
956 case MCI_UPDATE
: return MCIAVI_mciUpdate (dwDevID
, dwParam1
, (LPMCI_DGV_UPDATE_PARMS
) dwParam2
);
957 case MCI_WHERE
: return MCIAVI_mciWhere (dwDevID
, dwParam1
, (LPMCI_DGV_RECT_PARMS
) dwParam2
);
958 case MCI_STEP
: return MCIAVI_mciStep (dwDevID
, dwParam1
, (LPMCI_DGV_STEP_PARMS
) dwParam2
);
959 case MCI_COPY
: return MCIAVI_mciCopy (dwDevID
, dwParam1
, (LPMCI_DGV_COPY_PARMS
) dwParam2
);
960 case MCI_CUT
: return MCIAVI_mciCut (dwDevID
, dwParam1
, (LPMCI_DGV_CUT_PARMS
) dwParam2
);
961 case MCI_DELETE
: return MCIAVI_mciDelete (dwDevID
, dwParam1
, (LPMCI_DGV_DELETE_PARMS
) dwParam2
);
962 case MCI_PASTE
: return MCIAVI_mciPaste (dwDevID
, dwParam1
, (LPMCI_DGV_PASTE_PARMS
) dwParam2
);
963 case MCI_CUE
: return MCIAVI_mciCue (dwDevID
, dwParam1
, (LPMCI_DGV_CUE_PARMS
) dwParam2
);
964 /* Digital Video specific */
965 case MCI_CAPTURE
: return MCIAVI_mciCapture (dwDevID
, dwParam1
, (LPMCI_DGV_CAPTURE_PARMSA
) dwParam2
);
966 case MCI_MONITOR
: return MCIAVI_mciMonitor (dwDevID
, dwParam1
, (LPMCI_DGV_MONITOR_PARMS
) dwParam2
);
967 case MCI_RESERVE
: return MCIAVI_mciReserve (dwDevID
, dwParam1
, (LPMCI_DGV_RESERVE_PARMSA
) dwParam2
);
968 case MCI_SETAUDIO
: return MCIAVI_mciSetAudio (dwDevID
, dwParam1
, (LPMCI_DGV_SETAUDIO_PARMSA
) dwParam2
);
969 case MCI_SIGNAL
: return MCIAVI_mciSignal (dwDevID
, dwParam1
, (LPMCI_DGV_SIGNAL_PARMS
) dwParam2
);
970 case MCI_SETVIDEO
: return MCIAVI_mciSetVideo (dwDevID
, dwParam1
, (LPMCI_DGV_SETVIDEO_PARMSA
) dwParam2
);
971 case MCI_QUALITY
: return MCIAVI_mciQuality (dwDevID
, dwParam1
, (LPMCI_DGV_QUALITY_PARMSA
) dwParam2
);
972 case MCI_LIST
: return MCIAVI_mciList (dwDevID
, dwParam1
, (LPMCI_DGV_LIST_PARMSA
) dwParam2
);
973 case MCI_UNDO
: return MCIAVI_mciUndo (dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
) dwParam2
);
974 case MCI_CONFIGURE
: return MCIAVI_mciConfigure (dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
) dwParam2
);
975 case MCI_RESTORE
: return MCIAVI_mciRestore (dwDevID
, dwParam1
, (LPMCI_DGV_RESTORE_PARMSA
) dwParam2
);
979 WARN("Unsupported command [%lu]\n", wMsg
);
983 FIXME("Shouldn't receive a MCI_OPEN or CLOSE message\n");
986 TRACE("Sending msg [%lu] to default driver proc\n", wMsg
);
987 return DefDriverProc(dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
989 return MCIERR_UNRECOGNIZED_COMMAND
;