1c2c66affSColin Finck /*
2c2c66affSColin Finck * Digital video MCI Wine Driver
3c2c66affSColin Finck *
4c2c66affSColin Finck * Copyright 1999, 2000 Eric POUECH
5c2c66affSColin Finck * Copyright 2003 Dmitry Timoshkov
6c2c66affSColin Finck *
7c2c66affSColin Finck * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck * License as published by the Free Software Foundation; either
10c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck *
12c2c66affSColin Finck * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15c2c66affSColin Finck * Lesser General Public License for more details.
16c2c66affSColin Finck *
17c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck */
21c2c66affSColin Finck
22c2c66affSColin Finck /* TODO list :
23c2c66affSColin Finck * - handling of palettes
24c2c66affSColin Finck * - recording (which input devices ?), a cam recorder ?
25c2c66affSColin Finck * - lots of messages still need to be handled (cf FIXME)
26c2c66affSColin Finck * - synchronization between audio and video (especially for interleaved
27c2c66affSColin Finck * files)
28c2c66affSColin Finck * - robustness when reading file can be enhanced
29c2c66affSColin Finck * - reimplement the AVI handling part with avifile DLL because
30c2c66affSColin Finck * "open @1122334 type avivideo alias a" expects an AVIFile/Stream
31c2c66affSColin Finck * and MCI_DGV_SET|STATUS_SPEED maps to Rate/Scale
32c2c66affSColin Finck * - some files appear to have more than one audio stream (we only play the
33c2c66affSColin Finck * first one)
34c2c66affSColin Finck * - some files contain an index of audio/video frame. Better use it,
35c2c66affSColin Finck * instead of rebuilding it (AVIFile does that already)
36c2c66affSColin Finck * - stopping while playing a file with sound blocks until all buffered
37c2c66affSColin Finck * audio is played... still should be stopped ASAP
38c2c66affSColin Finck */
39c2c66affSColin Finck
40ba65d708SAmine Khaldi #include <string.h>
41c2c66affSColin Finck #include "private_mciavi.h"
42ba65d708SAmine Khaldi #include "wine/debug.h"
43c2c66affSColin Finck
44ba65d708SAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
45c2c66affSColin Finck
46c2c66affSColin Finck static DWORD MCIAVI_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS);
47c2c66affSColin Finck
48c2c66affSColin Finck /*======================================================================*
49c2c66affSColin Finck * MCI AVI implementation *
50c2c66affSColin Finck *======================================================================*/
51c2c66affSColin Finck
52c2c66affSColin Finck HINSTANCE MCIAVI_hInstance = 0;
53c2c66affSColin Finck
54c2c66affSColin Finck /***********************************************************************
55c2c66affSColin Finck * DllMain (MCIAVI.0)
56c2c66affSColin Finck */
DllMain(HINSTANCE hInstDLL,DWORD fdwReason,LPVOID fImpLoad)57c2c66affSColin Finck BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
58c2c66affSColin Finck {
59c2c66affSColin Finck switch (fdwReason) {
60c2c66affSColin Finck case DLL_PROCESS_ATTACH:
61c2c66affSColin Finck DisableThreadLibraryCalls(hInstDLL);
62c2c66affSColin Finck MCIAVI_hInstance = hInstDLL;
63c2c66affSColin Finck break;
64c2c66affSColin Finck }
65c2c66affSColin Finck return TRUE;
66c2c66affSColin Finck }
67c2c66affSColin Finck
68c2c66affSColin Finck /**************************************************************************
69c2c66affSColin Finck * MCIAVI_drvOpen [internal]
70c2c66affSColin Finck */
MCIAVI_drvOpen(LPCWSTR str,LPMCI_OPEN_DRIVER_PARMSW modp)71c2c66affSColin Finck static DWORD MCIAVI_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
72c2c66affSColin Finck {
73c2c66affSColin Finck WINE_MCIAVI* wma;
74c2c66affSColin Finck static const WCHAR mciAviWStr[] = {'M','C','I','A','V','I',0};
75c2c66affSColin Finck
76c2c66affSColin Finck TRACE("%s, %p\n", debugstr_w(str), modp);
77c2c66affSColin Finck
78c2c66affSColin Finck /* session instance */
79c2c66affSColin Finck if (!modp) return 0xFFFFFFFF;
80c2c66affSColin Finck
81c2c66affSColin Finck if (!MCIAVI_RegisterClass()) return 0;
82c2c66affSColin Finck
83c2c66affSColin Finck wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIAVI));
84c2c66affSColin Finck if (!wma)
85c2c66affSColin Finck return 0;
86c2c66affSColin Finck
87c2c66affSColin Finck InitializeCriticalSection(&wma->cs);
88c2c66affSColin Finck wma->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": WINE_MCIAVI.cs");
89c2c66affSColin Finck wma->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
90c2c66affSColin Finck wma->wDevID = modp->wDeviceID;
91c2c66affSColin Finck wma->wCommandTable = mciLoadCommandResource(MCIAVI_hInstance, mciAviWStr, 0);
92c2c66affSColin Finck wma->dwStatus = MCI_MODE_NOT_READY;
93c2c66affSColin Finck modp->wCustomCommandTable = wma->wCommandTable;
94c2c66affSColin Finck modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO;
95c2c66affSColin Finck mciSetDriverData(wma->wDevID, (DWORD_PTR)wma);
96c2c66affSColin Finck
97c2c66affSColin Finck return modp->wDeviceID;
98c2c66affSColin Finck }
99c2c66affSColin Finck
100c2c66affSColin Finck /**************************************************************************
101c2c66affSColin Finck * MCIAVI_drvClose [internal]
102c2c66affSColin Finck */
MCIAVI_drvClose(DWORD dwDevID)103c2c66affSColin Finck static DWORD MCIAVI_drvClose(DWORD dwDevID)
104c2c66affSColin Finck {
105c2c66affSColin Finck WINE_MCIAVI *wma;
106c2c66affSColin Finck
107c2c66affSColin Finck TRACE("%04x\n", dwDevID);
108c2c66affSColin Finck
109c2c66affSColin Finck /* finish all outstanding things */
110c2c66affSColin Finck MCIAVI_mciClose(dwDevID, MCI_WAIT, NULL);
111c2c66affSColin Finck
112c2c66affSColin Finck wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
113c2c66affSColin Finck
114c2c66affSColin Finck if (wma) {
115c2c66affSColin Finck MCIAVI_UnregisterClass();
116c2c66affSColin Finck
117c2c66affSColin Finck EnterCriticalSection(&wma->cs);
118c2c66affSColin Finck
119c2c66affSColin Finck mciSetDriverData(dwDevID, 0);
120c2c66affSColin Finck mciFreeCommandResource(wma->wCommandTable);
121c2c66affSColin Finck
122c2c66affSColin Finck CloseHandle(wma->hStopEvent);
123c2c66affSColin Finck
124c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
125c2c66affSColin Finck wma->cs.DebugInfo->Spare[0] = 0;
126c2c66affSColin Finck DeleteCriticalSection(&wma->cs);
127c2c66affSColin Finck
128c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, wma);
129c2c66affSColin Finck return 1;
130c2c66affSColin Finck }
131c2c66affSColin Finck return (dwDevID == 0xFFFFFFFF) ? 1 : 0;
132c2c66affSColin Finck }
133c2c66affSColin Finck
134c2c66affSColin Finck /**************************************************************************
135c2c66affSColin Finck * MCIAVI_drvConfigure [internal]
136c2c66affSColin Finck */
MCIAVI_drvConfigure(DWORD dwDevID)137c2c66affSColin Finck static DWORD MCIAVI_drvConfigure(DWORD dwDevID)
138c2c66affSColin Finck {
139c2c66affSColin Finck WINE_MCIAVI *wma;
140c2c66affSColin Finck
141c2c66affSColin Finck TRACE("%04x\n", dwDevID);
142c2c66affSColin Finck
143c2c66affSColin Finck MCIAVI_mciStop(dwDevID, MCI_WAIT, NULL);
144c2c66affSColin Finck
145c2c66affSColin Finck wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
146c2c66affSColin Finck
147c2c66affSColin Finck if (wma) {
148c2c66affSColin Finck MessageBoxA(0, "Sample AVI Wine Driver !", "MM-Wine Driver", MB_OK);
149c2c66affSColin Finck return 1;
150c2c66affSColin Finck }
151c2c66affSColin Finck return 0;
152c2c66affSColin Finck }
153c2c66affSColin Finck
154c2c66affSColin Finck /**************************************************************************
155c2c66affSColin Finck * MCIAVI_mciGetOpenDev [internal]
156c2c66affSColin Finck */
MCIAVI_mciGetOpenDev(UINT wDevID)157c2c66affSColin Finck WINE_MCIAVI* MCIAVI_mciGetOpenDev(UINT wDevID)
158c2c66affSColin Finck {
159c2c66affSColin Finck WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(wDevID);
160c2c66affSColin Finck
161c2c66affSColin Finck if (wma == NULL || wma->nUseCount == 0) {
162c2c66affSColin Finck WARN("Invalid wDevID=%u\n", wDevID);
163c2c66affSColin Finck return 0;
164c2c66affSColin Finck }
165c2c66affSColin Finck return wma;
166c2c66affSColin Finck }
167c2c66affSColin Finck
MCIAVI_CleanUp(WINE_MCIAVI * wma)168c2c66affSColin Finck static void MCIAVI_CleanUp(WINE_MCIAVI* wma)
169c2c66affSColin Finck {
170c2c66affSColin Finck /* to prevent handling in WindowProc */
171c2c66affSColin Finck wma->dwStatus = MCI_MODE_NOT_READY;
172c2c66affSColin Finck if (wma->hFile) {
173c2c66affSColin Finck mmioClose(wma->hFile, 0);
174c2c66affSColin Finck wma->hFile = 0;
175c2c66affSColin Finck
176c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, wma->lpFileName);
177c2c66affSColin Finck wma->lpFileName = NULL;
178c2c66affSColin Finck
179c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, wma->lpVideoIndex);
180c2c66affSColin Finck wma->lpVideoIndex = NULL;
181c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, wma->lpAudioIndex);
182c2c66affSColin Finck wma->lpAudioIndex = NULL;
183c2c66affSColin Finck if (wma->hic) ICClose(wma->hic);
184c2c66affSColin Finck wma->hic = 0;
185c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, wma->inbih);
186c2c66affSColin Finck wma->inbih = NULL;
187c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, wma->outbih);
188c2c66affSColin Finck wma->outbih = NULL;
189c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, wma->indata);
190c2c66affSColin Finck wma->indata = NULL;
191c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, wma->outdata);
192c2c66affSColin Finck wma->outdata = NULL;
193c2c66affSColin Finck if (wma->hbmFrame) DeleteObject(wma->hbmFrame);
194c2c66affSColin Finck wma->hbmFrame = 0;
195c2c66affSColin Finck if (wma->hWnd) DestroyWindow(wma->hWnd);
196c2c66affSColin Finck wma->hWnd = 0;
197c2c66affSColin Finck
198c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, wma->lpWaveFormat);
199c2c66affSColin Finck wma->lpWaveFormat = 0;
200c2c66affSColin Finck
201c2c66affSColin Finck memset(&wma->mah, 0, sizeof(wma->mah));
202c2c66affSColin Finck memset(&wma->ash_video, 0, sizeof(wma->ash_video));
203c2c66affSColin Finck memset(&wma->ash_audio, 0, sizeof(wma->ash_audio));
204c2c66affSColin Finck wma->dwCurrVideoFrame = wma->dwCurrAudioBlock = 0;
205c2c66affSColin Finck wma->dwCachedFrame = -1;
206c2c66affSColin Finck }
207c2c66affSColin Finck }
208c2c66affSColin Finck
209c2c66affSColin Finck /***************************************************************************
210c2c66affSColin Finck * MCIAVI_mciOpen [internal]
211c2c66affSColin Finck */
MCIAVI_mciOpen(UINT wDevID,DWORD dwFlags,LPMCI_DGV_OPEN_PARMSW lpOpenParms)212c2c66affSColin Finck static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags,
213c2c66affSColin Finck LPMCI_DGV_OPEN_PARMSW lpOpenParms)
214c2c66affSColin Finck {
215c2c66affSColin Finck WINE_MCIAVI *wma;
216c2c66affSColin Finck LRESULT dwRet = 0;
217c2c66affSColin Finck
218c2c66affSColin Finck TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpOpenParms);
219c2c66affSColin Finck
220c2c66affSColin Finck if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
221c2c66affSColin Finck
222c2c66affSColin Finck wma = (WINE_MCIAVI *)mciGetDriverData(wDevID);
223c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
224c2c66affSColin Finck
225c2c66affSColin Finck EnterCriticalSection(&wma->cs);
226c2c66affSColin Finck
227c2c66affSColin Finck if (wma->nUseCount > 0) {
228c2c66affSColin Finck /* The driver is already open on this channel */
229c2c66affSColin Finck /* If the driver was opened shareable before and this open specifies */
230c2c66affSColin Finck /* shareable then increment the use count */
231c2c66affSColin Finck if (wma->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
232c2c66affSColin Finck ++wma->nUseCount;
233c2c66affSColin Finck else
234c2c66affSColin Finck {
235c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
236c2c66affSColin Finck return MCIERR_MUST_USE_SHAREABLE;
237c2c66affSColin Finck }
238c2c66affSColin Finck } else {
239c2c66affSColin Finck wma->nUseCount = 1;
240c2c66affSColin Finck wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE;
241c2c66affSColin Finck }
242c2c66affSColin Finck
243c2c66affSColin Finck wma->dwStatus = MCI_MODE_NOT_READY;
244c2c66affSColin Finck
245c2c66affSColin Finck if (dwFlags & MCI_OPEN_ELEMENT) {
246c2c66affSColin Finck if (dwFlags & MCI_OPEN_ELEMENT_ID) {
247c2c66affSColin Finck /* could it be that (DWORD)lpOpenParms->lpstrElementName
248c2c66affSColin Finck * contains the hFile value ?
249c2c66affSColin Finck */
250c2c66affSColin Finck dwRet = MCIERR_UNRECOGNIZED_COMMAND;
251c2c66affSColin Finck } else if (lpOpenParms->lpstrElementName && lpOpenParms->lpstrElementName[0]) {
252c2c66affSColin Finck /* FIXME : what should be done id wma->hFile is already != 0, or the driver is playin' */
253c2c66affSColin Finck TRACE("MCI_OPEN_ELEMENT %s!\n", debugstr_w(lpOpenParms->lpstrElementName));
254c2c66affSColin Finck
255*9ac5b9a0SAmine Khaldi wma->lpFileName = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(lpOpenParms->lpstrElementName) + 1) * sizeof(WCHAR));
256*9ac5b9a0SAmine Khaldi lstrcpyW(wma->lpFileName, lpOpenParms->lpstrElementName);
257c2c66affSColin Finck
258c2c66affSColin Finck if (lpOpenParms->lpstrElementName[0] == '@') {
259c2c66affSColin Finck /* The file name @11223344 encodes an AVIFile handle in decimal notation
260c2c66affSColin Finck * in Win3.1 and w2k/NT, but this feature is absent in win95 (KB140750).
261*9ac5b9a0SAmine Khaldi * wma->hFile = LongToHandle(wcstol(lpOpenParms->lpstrElementName+1, NULL, 10)); */
262c2c66affSColin Finck FIXME("Using AVIFile/Stream %s NIY\n", debugstr_w(lpOpenParms->lpstrElementName));
263c2c66affSColin Finck }
264c2c66affSColin Finck wma->hFile = mmioOpenW(lpOpenParms->lpstrElementName, NULL,
265c2c66affSColin Finck MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READ);
266c2c66affSColin Finck
267c2c66affSColin Finck if (wma->hFile == 0) {
268c2c66affSColin Finck WARN("can't find file=%s!\n", debugstr_w(lpOpenParms->lpstrElementName));
269c2c66affSColin Finck dwRet = MCIERR_FILE_NOT_FOUND;
270c2c66affSColin Finck } else {
271c2c66affSColin Finck if (!MCIAVI_GetInfo(wma))
272c2c66affSColin Finck dwRet = MCIERR_INVALID_FILE;
273c2c66affSColin Finck else if (!MCIAVI_OpenVideo(wma))
274c2c66affSColin Finck dwRet = MCIERR_CANNOT_LOAD_DRIVER;
275c2c66affSColin Finck else if (!MCIAVI_CreateWindow(wma, dwFlags, lpOpenParms))
276c2c66affSColin Finck dwRet = MCIERR_CREATEWINDOW;
277c2c66affSColin Finck }
278c2c66affSColin Finck } else {
279c2c66affSColin Finck FIXME("Don't record yet\n");
280c2c66affSColin Finck dwRet = MCIERR_UNSUPPORTED_FUNCTION;
281c2c66affSColin Finck }
282c2c66affSColin Finck }
283c2c66affSColin Finck
284c2c66affSColin Finck if (dwRet == 0) {
285c2c66affSColin Finck TRACE("lpOpenParms->wDeviceID = %04x\n", lpOpenParms->wDeviceID);
286c2c66affSColin Finck
287c2c66affSColin Finck wma->dwStatus = MCI_MODE_STOP;
288c2c66affSColin Finck wma->dwMciTimeFormat = MCI_FORMAT_FRAMES;
289c2c66affSColin Finck } else {
290c2c66affSColin Finck MCIAVI_CleanUp(wma);
291c2c66affSColin Finck }
292c2c66affSColin Finck
293c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
294c2c66affSColin Finck
295c2c66affSColin Finck if (!dwRet && (dwFlags & MCI_NOTIFY)) {
296c2c66affSColin Finck mciDriverNotify(HWND_32(LOWORD(lpOpenParms->dwCallback)),
297c2c66affSColin Finck wDevID, MCI_NOTIFY_SUCCESSFUL);
298c2c66affSColin Finck }
299c2c66affSColin Finck return dwRet;
300c2c66affSColin Finck }
301c2c66affSColin Finck
302c2c66affSColin Finck /***************************************************************************
303c2c66affSColin Finck * MCIAVI_mciClose [internal]
304c2c66affSColin Finck */
MCIAVI_mciClose(UINT wDevID,DWORD dwFlags,LPMCI_GENERIC_PARMS lpParms)305c2c66affSColin Finck DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
306c2c66affSColin Finck {
307c2c66affSColin Finck WINE_MCIAVI *wma;
308c2c66affSColin Finck DWORD dwRet = 0;
309c2c66affSColin Finck
310c2c66affSColin Finck TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
311c2c66affSColin Finck
312c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
313c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
314c2c66affSColin Finck
315c2c66affSColin Finck MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
316c2c66affSColin Finck
317c2c66affSColin Finck EnterCriticalSection(&wma->cs);
318c2c66affSColin Finck
319c2c66affSColin Finck if (wma->nUseCount == 1) {
320c2c66affSColin Finck MCIAVI_CleanUp(wma);
321c2c66affSColin Finck
322c2c66affSColin Finck if ((dwFlags & MCI_NOTIFY) && lpParms) {
323c2c66affSColin Finck mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
324c2c66affSColin Finck wDevID,
325c2c66affSColin Finck MCI_NOTIFY_SUCCESSFUL);
326c2c66affSColin Finck }
327c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
328c2c66affSColin Finck return dwRet;
329c2c66affSColin Finck }
330c2c66affSColin Finck wma->nUseCount--;
331c2c66affSColin Finck
332c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
333c2c66affSColin Finck return dwRet;
334c2c66affSColin Finck }
335c2c66affSColin Finck
currenttime_us(void)336c2c66affSColin Finck static double currenttime_us(void)
337c2c66affSColin Finck {
338c2c66affSColin Finck LARGE_INTEGER lc, lf;
339c2c66affSColin Finck QueryPerformanceCounter(&lc);
340c2c66affSColin Finck QueryPerformanceFrequency(&lf);
341c2c66affSColin Finck return (lc.QuadPart * 1000000) / lf.QuadPart;
342c2c66affSColin Finck }
343c2c66affSColin Finck
344c2c66affSColin Finck /***************************************************************************
345c2c66affSColin Finck * MCIAVI_player [internal]
346c2c66affSColin Finck */
MCIAVI_player(WINE_MCIAVI * wma,DWORD dwFlags,LPMCI_PLAY_PARMS lpParms)347c2c66affSColin Finck static DWORD MCIAVI_player(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
348c2c66affSColin Finck {
349c2c66affSColin Finck DWORD dwRet;
350c2c66affSColin Finck LPWAVEHDR waveHdr = NULL;
351c2c66affSColin Finck unsigned i, nHdr = 0;
352c2c66affSColin Finck DWORD numEvents = 1;
353c2c66affSColin Finck HANDLE events[2];
354c2c66affSColin Finck double next_frame_us;
355c2c66affSColin Finck BOOL wait_audio = TRUE;
356c2c66affSColin Finck
357c2c66affSColin Finck EnterCriticalSection(&wma->cs);
358c2c66affSColin Finck
359c2c66affSColin Finck if (wma->dwToVideoFrame <= wma->dwCurrVideoFrame)
360c2c66affSColin Finck {
361c2c66affSColin Finck dwRet = 0;
362c2c66affSColin Finck goto mci_play_done;
363c2c66affSColin Finck }
364c2c66affSColin Finck
365c2c66affSColin Finck events[0] = wma->hStopEvent;
366c2c66affSColin Finck if (wma->lpWaveFormat) {
367c2c66affSColin Finck if (MCIAVI_OpenAudio(wma, &nHdr, &waveHdr) != 0)
368c2c66affSColin Finck {
369c2c66affSColin Finck /* can't play audio */
370c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, wma->lpWaveFormat);
371c2c66affSColin Finck wma->lpWaveFormat = NULL;
372c2c66affSColin Finck }
373c2c66affSColin Finck else
374c2c66affSColin Finck {
375c2c66affSColin Finck /* fill the queue with as many wave headers as possible */
376c2c66affSColin Finck MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
377c2c66affSColin Finck events[1] = wma->hEvent;
378c2c66affSColin Finck numEvents = 2;
379c2c66affSColin Finck }
380c2c66affSColin Finck }
381c2c66affSColin Finck
382c2c66affSColin Finck next_frame_us = currenttime_us();
383c2c66affSColin Finck while (wma->dwStatus == MCI_MODE_PLAY)
384c2c66affSColin Finck {
385c2c66affSColin Finck HDC hDC;
386c2c66affSColin Finck double tc, delta;
387c2c66affSColin Finck DWORD ret;
388c2c66affSColin Finck
389c2c66affSColin Finck tc = currenttime_us();
390c2c66affSColin Finck
391c2c66affSColin Finck hDC = wma->hWndPaint ? GetDC(wma->hWndPaint) : 0;
392c2c66affSColin Finck if (hDC)
393c2c66affSColin Finck {
394c2c66affSColin Finck while(next_frame_us <= tc && wma->dwCurrVideoFrame < wma->dwToVideoFrame){
395c2c66affSColin Finck double dur;
396c2c66affSColin Finck dur = MCIAVI_PaintFrame(wma, hDC);
397c2c66affSColin Finck ++wma->dwCurrVideoFrame;
398c2c66affSColin Finck if(!dur)
399c2c66affSColin Finck break;
400c2c66affSColin Finck next_frame_us += dur;
401c2c66affSColin Finck TRACE("next_frame: %f\n", next_frame_us);
402c2c66affSColin Finck }
403c2c66affSColin Finck ReleaseDC(wma->hWndPaint, hDC);
404c2c66affSColin Finck }
405c2c66affSColin Finck if (wma->dwCurrVideoFrame >= wma->dwToVideoFrame)
406c2c66affSColin Finck {
407c2c66affSColin Finck if (!(dwFlags & MCI_DGV_PLAY_REPEAT))
408c2c66affSColin Finck break;
409c2c66affSColin Finck TRACE("repeat media as requested\n");
410c2c66affSColin Finck wma->dwCurrVideoFrame = wma->dwCurrAudioBlock = 0;
411c2c66affSColin Finck }
412c2c66affSColin Finck
413c2c66affSColin Finck if (wma->lpWaveFormat)
414c2c66affSColin Finck MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
415c2c66affSColin Finck
416c2c66affSColin Finck tc = currenttime_us();
417c2c66affSColin Finck if (tc < next_frame_us)
418c2c66affSColin Finck delta = next_frame_us - tc;
419c2c66affSColin Finck else
420c2c66affSColin Finck delta = 0;
421c2c66affSColin Finck
422c2c66affSColin Finck /* check if the playback was cancelled */
423c2c66affSColin Finck if ((wma->mci_break.flags & MCI_BREAK_KEY) &&
424c2c66affSColin Finck (GetAsyncKeyState(wma->mci_break.parms.nVirtKey) & 0x8000))
425c2c66affSColin Finck {
426c2c66affSColin Finck if (!(wma->mci_break.flags & MCI_BREAK_HWND) ||
427c2c66affSColin Finck GetForegroundWindow() == wma->mci_break.parms.hwndBreak)
428c2c66affSColin Finck {
429c2c66affSColin Finck /* we queue audio blocks ahead so ignore them otherwise the audio
430c2c66affSColin Finck * will keep playing until the buffer is empty */
431c2c66affSColin Finck wait_audio = FALSE;
432c2c66affSColin Finck
433c2c66affSColin Finck TRACE("playback cancelled using break key\n");
434c2c66affSColin Finck break;
435c2c66affSColin Finck }
436c2c66affSColin Finck }
437c2c66affSColin Finck
438c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
439c2c66affSColin Finck ret = WaitForMultipleObjects(numEvents, events, FALSE, delta / 1000);
440c2c66affSColin Finck EnterCriticalSection(&wma->cs);
441c2c66affSColin Finck if (ret == WAIT_OBJECT_0 || wma->dwStatus != MCI_MODE_PLAY) break;
442c2c66affSColin Finck }
443c2c66affSColin Finck
444c2c66affSColin Finck if (wma->lpWaveFormat)
445c2c66affSColin Finck {
446c2c66affSColin Finck if (wait_audio)
447c2c66affSColin Finck while (wma->dwEventCount != nHdr - 1)
448c2c66affSColin Finck {
449c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
450c2c66affSColin Finck Sleep(100);
451c2c66affSColin Finck EnterCriticalSection(&wma->cs);
452c2c66affSColin Finck }
453c2c66affSColin Finck
454c2c66affSColin Finck /* just to get rid of some race conditions between play, stop and pause */
455c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
456c2c66affSColin Finck waveOutReset(wma->hWave);
457c2c66affSColin Finck EnterCriticalSection(&wma->cs);
458c2c66affSColin Finck
459c2c66affSColin Finck for (i = 0; i < nHdr; i++)
460c2c66affSColin Finck waveOutUnprepareHeader(wma->hWave, &waveHdr[i], sizeof(WAVEHDR));
461c2c66affSColin Finck }
462c2c66affSColin Finck
463c2c66affSColin Finck dwRet = 0;
464c2c66affSColin Finck
465c2c66affSColin Finck if (wma->lpWaveFormat) {
466c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, waveHdr);
467c2c66affSColin Finck
468c2c66affSColin Finck if (wma->hWave) {
469c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
470c2c66affSColin Finck waveOutClose(wma->hWave);
471c2c66affSColin Finck EnterCriticalSection(&wma->cs);
472c2c66affSColin Finck wma->hWave = 0;
473c2c66affSColin Finck }
474c2c66affSColin Finck CloseHandle(wma->hEvent);
475c2c66affSColin Finck }
476c2c66affSColin Finck
477c2c66affSColin Finck mci_play_done:
478c2c66affSColin Finck wma->dwStatus = MCI_MODE_STOP;
479c2c66affSColin Finck
480c2c66affSColin Finck if (dwFlags & MCI_NOTIFY) {
481c2c66affSColin Finck TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
482c2c66affSColin Finck mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
483c2c66affSColin Finck wma->wDevID, MCI_NOTIFY_SUCCESSFUL);
484c2c66affSColin Finck }
485c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
486c2c66affSColin Finck return dwRet;
487c2c66affSColin Finck }
488c2c66affSColin Finck
489c2c66affSColin Finck struct MCIAVI_play_data
490c2c66affSColin Finck {
491c2c66affSColin Finck WINE_MCIAVI *wma;
492c2c66affSColin Finck DWORD flags;
493c2c66affSColin Finck MCI_PLAY_PARMS params; /* FIXME: notify via wma->hCallback like the other MCI drivers */
494c2c66affSColin Finck };
495c2c66affSColin Finck
496c2c66affSColin Finck /*
497c2c66affSColin Finck * MCIAVI_mciPlay_thread
498c2c66affSColin Finck *
499c2c66affSColin Finck * FIXME: probably should use a common worker thread created at the driver
500c2c66affSColin Finck * load time and queue all async commands to it.
501c2c66affSColin Finck */
MCIAVI_mciPlay_thread(LPVOID arg)502c2c66affSColin Finck static DWORD WINAPI MCIAVI_mciPlay_thread(LPVOID arg)
503c2c66affSColin Finck {
504c2c66affSColin Finck struct MCIAVI_play_data *data = (struct MCIAVI_play_data *)arg;
505c2c66affSColin Finck DWORD ret;
506c2c66affSColin Finck
507c2c66affSColin Finck TRACE("In thread before async play command (id %u, flags %08x)\n", data->wma->wDevID, data->flags);
508c2c66affSColin Finck ret = MCIAVI_player(data->wma, data->flags, &data->params);
509c2c66affSColin Finck TRACE("In thread after async play command (id %u, flags %08x)\n", data->wma->wDevID, data->flags);
510c2c66affSColin Finck
511c2c66affSColin Finck HeapFree(GetProcessHeap(), 0, data);
512c2c66affSColin Finck return ret;
513c2c66affSColin Finck }
514c2c66affSColin Finck
515c2c66affSColin Finck /*
516c2c66affSColin Finck * MCIAVI_mciPlay_async
517c2c66affSColin Finck */
MCIAVI_mciPlay_async(WINE_MCIAVI * wma,DWORD dwFlags,LPMCI_PLAY_PARMS lpParams)518c2c66affSColin Finck static DWORD MCIAVI_mciPlay_async(WINE_MCIAVI *wma, DWORD dwFlags, LPMCI_PLAY_PARMS lpParams)
519c2c66affSColin Finck {
520c2c66affSColin Finck HANDLE handle;
521c2c66affSColin Finck struct MCIAVI_play_data *data = HeapAlloc(GetProcessHeap(), 0, sizeof(struct MCIAVI_play_data));
522c2c66affSColin Finck
523c2c66affSColin Finck if (!data) return MCIERR_OUT_OF_MEMORY;
524c2c66affSColin Finck
525c2c66affSColin Finck data->wma = wma;
526c2c66affSColin Finck data->flags = dwFlags;
527c2c66affSColin Finck if (dwFlags & MCI_NOTIFY)
528c2c66affSColin Finck data->params.dwCallback = lpParams->dwCallback;
529c2c66affSColin Finck
530c2c66affSColin Finck if (!(handle = CreateThread(NULL, 0, MCIAVI_mciPlay_thread, data, 0, NULL)))
531c2c66affSColin Finck {
532c2c66affSColin Finck WARN("Couldn't create thread for async play, playing synchronously\n");
533c2c66affSColin Finck return MCIAVI_mciPlay_thread(data);
534c2c66affSColin Finck }
535c2c66affSColin Finck SetThreadPriority(handle, THREAD_PRIORITY_TIME_CRITICAL);
536c2c66affSColin Finck CloseHandle(handle);
537c2c66affSColin Finck return 0;
538c2c66affSColin Finck }
539c2c66affSColin Finck
540c2c66affSColin Finck /***************************************************************************
541c2c66affSColin Finck * MCIAVI_mciPlay [internal]
542c2c66affSColin Finck */
MCIAVI_mciPlay(UINT wDevID,DWORD dwFlags,LPMCI_PLAY_PARMS lpParms)543c2c66affSColin Finck static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
544c2c66affSColin Finck {
545c2c66affSColin Finck WINE_MCIAVI *wma;
546c2c66affSColin Finck DWORD dwRet;
547c2c66affSColin Finck DWORD dwFromFrame, dwToFrame;
548c2c66affSColin Finck
549c2c66affSColin Finck TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
550c2c66affSColin Finck
551c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
552c2c66affSColin Finck
553c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
554c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
555c2c66affSColin Finck if (dwFlags & MCI_DGV_PLAY_REVERSE) return MCIERR_UNSUPPORTED_FUNCTION;
556c2c66affSColin Finck if (dwFlags & MCI_TEST) return 0;
557c2c66affSColin Finck
558*9ac5b9a0SAmine Khaldi if (dwFlags & (MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLBY2))
559c2c66affSColin Finck FIXME("Unsupported flag %08x\n", dwFlags);
560c2c66affSColin Finck
561c2c66affSColin Finck EnterCriticalSection(&wma->cs);
562c2c66affSColin Finck
563c2c66affSColin Finck if (!wma->hFile)
564c2c66affSColin Finck {
565c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
566c2c66affSColin Finck return MCIERR_FILE_NOT_FOUND;
567c2c66affSColin Finck }
568c2c66affSColin Finck if (!wma->hWndPaint)
569c2c66affSColin Finck {
570c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
571c2c66affSColin Finck return MCIERR_NO_WINDOW;
572c2c66affSColin Finck }
573c2c66affSColin Finck
574c2c66affSColin Finck dwFromFrame = wma->dwCurrVideoFrame;
575c2c66affSColin Finck dwToFrame = wma->dwPlayableVideoFrames - 1;
576c2c66affSColin Finck
577c2c66affSColin Finck if (dwFlags & MCI_FROM) {
578c2c66affSColin Finck dwFromFrame = MCIAVI_ConvertTimeFormatToFrame(wma, lpParms->dwFrom);
579c2c66affSColin Finck }
580c2c66affSColin Finck if (dwFlags & MCI_TO) {
581c2c66affSColin Finck dwToFrame = MCIAVI_ConvertTimeFormatToFrame(wma, lpParms->dwTo);
582c2c66affSColin Finck }
583c2c66affSColin Finck if (dwToFrame >= wma->dwPlayableVideoFrames)
584c2c66affSColin Finck dwToFrame = wma->dwPlayableVideoFrames - 1;
585c2c66affSColin Finck
586c2c66affSColin Finck TRACE("Playing from frame=%u to frame=%u\n", dwFromFrame, dwToFrame);
587c2c66affSColin Finck
588c2c66affSColin Finck wma->dwCurrVideoFrame = dwFromFrame;
589c2c66affSColin Finck wma->dwToVideoFrame = dwToFrame;
590c2c66affSColin Finck
591c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
592c2c66affSColin Finck
593*9ac5b9a0SAmine Khaldi if (dwFlags & MCI_MCIAVI_PLAY_FULLSCREEN)
594*9ac5b9a0SAmine Khaldi {
595*9ac5b9a0SAmine Khaldi HMONITOR mon = MonitorFromWindow(wma->hWndPaint, MONITOR_DEFAULTTONEAREST);
596*9ac5b9a0SAmine Khaldi MONITORINFO mi;
597*9ac5b9a0SAmine Khaldi mi.cbSize = sizeof(mi);
598*9ac5b9a0SAmine Khaldi GetMonitorInfoA(mon, &mi);
599*9ac5b9a0SAmine Khaldi wma->hWndPaint = CreateWindowA("STATIC", NULL, WS_POPUP | WS_VISIBLE, mi.rcMonitor.left,
600*9ac5b9a0SAmine Khaldi mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top,
601*9ac5b9a0SAmine Khaldi NULL, NULL, NULL, 0);
602*9ac5b9a0SAmine Khaldi }
603*9ac5b9a0SAmine Khaldi /* if not fullscreen ensure the window is visible */
604*9ac5b9a0SAmine Khaldi else if (!(GetWindowLongW(wma->hWndPaint, GWL_STYLE) & WS_VISIBLE))
605c2c66affSColin Finck ShowWindow(wma->hWndPaint, SW_SHOWNA);
606c2c66affSColin Finck
607c2c66affSColin Finck EnterCriticalSection(&wma->cs);
608c2c66affSColin Finck
609c2c66affSColin Finck /* if already playing exit */
610c2c66affSColin Finck if (wma->dwStatus == MCI_MODE_PLAY)
611c2c66affSColin Finck {
612c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
613c2c66affSColin Finck return 0;
614c2c66affSColin Finck }
615c2c66affSColin Finck
616c2c66affSColin Finck wma->dwStatus = MCI_MODE_PLAY;
617c2c66affSColin Finck
618c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
619c2c66affSColin Finck
620c2c66affSColin Finck if (dwFlags & MCI_WAIT)
621c2c66affSColin Finck return MCIAVI_player(wma, dwFlags, lpParms);
622c2c66affSColin Finck
623c2c66affSColin Finck dwRet = MCIAVI_mciPlay_async(wma, dwFlags, lpParms);
624c2c66affSColin Finck
625c2c66affSColin Finck if (dwRet) {
626c2c66affSColin Finck EnterCriticalSection(&wma->cs);
627c2c66affSColin Finck wma->dwStatus = MCI_MODE_STOP;
628c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
629c2c66affSColin Finck }
630c2c66affSColin Finck return dwRet;
631c2c66affSColin Finck }
632c2c66affSColin Finck
633c2c66affSColin Finck /***************************************************************************
634c2c66affSColin Finck * MCIAVI_mciStop [internal]
635c2c66affSColin Finck */
MCIAVI_mciStop(UINT wDevID,DWORD dwFlags,LPMCI_GENERIC_PARMS lpParms)636c2c66affSColin Finck static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
637c2c66affSColin Finck {
638c2c66affSColin Finck WINE_MCIAVI *wma;
639c2c66affSColin Finck DWORD dwRet = 0;
640c2c66affSColin Finck
641c2c66affSColin Finck TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
642c2c66affSColin Finck
643c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
644c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
645c2c66affSColin Finck if (dwFlags & MCI_TEST) return 0;
646c2c66affSColin Finck
647c2c66affSColin Finck EnterCriticalSection(&wma->cs);
648c2c66affSColin Finck
649c2c66affSColin Finck TRACE("current status %04x\n", wma->dwStatus);
650c2c66affSColin Finck
651c2c66affSColin Finck switch (wma->dwStatus) {
652c2c66affSColin Finck case MCI_MODE_PLAY:
653c2c66affSColin Finck case MCI_MODE_RECORD:
654c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
655c2c66affSColin Finck SetEvent(wma->hStopEvent);
656c2c66affSColin Finck EnterCriticalSection(&wma->cs);
657c2c66affSColin Finck /* fall through */
658c2c66affSColin Finck case MCI_MODE_PAUSE:
659c2c66affSColin Finck /* Since our wave notification callback takes the lock,
660c2c66affSColin Finck * we must release it before resetting the device */
661c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
662c2c66affSColin Finck dwRet = waveOutReset(wma->hWave);
663c2c66affSColin Finck EnterCriticalSection(&wma->cs);
664c2c66affSColin Finck /* fall through */
665c2c66affSColin Finck default:
666c2c66affSColin Finck do /* one more chance for an async thread to finish */
667c2c66affSColin Finck {
668c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
669c2c66affSColin Finck Sleep(10);
670c2c66affSColin Finck EnterCriticalSection(&wma->cs);
671c2c66affSColin Finck } while (wma->dwStatus != MCI_MODE_STOP);
672c2c66affSColin Finck
673c2c66affSColin Finck break;
674c2c66affSColin Finck
675c2c66affSColin Finck case MCI_MODE_NOT_READY:
676c2c66affSColin Finck break;
677c2c66affSColin Finck }
678c2c66affSColin Finck
679c2c66affSColin Finck if ((dwFlags & MCI_NOTIFY) && lpParms) {
680c2c66affSColin Finck mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
681c2c66affSColin Finck wDevID, MCI_NOTIFY_SUCCESSFUL);
682c2c66affSColin Finck }
683c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
684c2c66affSColin Finck return dwRet;
685c2c66affSColin Finck }
686c2c66affSColin Finck
687c2c66affSColin Finck /***************************************************************************
688c2c66affSColin Finck * MCIAVI_mciPause [internal]
689c2c66affSColin Finck */
MCIAVI_mciPause(UINT wDevID,DWORD dwFlags,LPMCI_GENERIC_PARMS lpParms)690c2c66affSColin Finck static DWORD MCIAVI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
691c2c66affSColin Finck {
692c2c66affSColin Finck WINE_MCIAVI *wma;
693c2c66affSColin Finck
694c2c66affSColin Finck TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
695c2c66affSColin Finck
696c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
697c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
698c2c66affSColin Finck if (dwFlags & MCI_TEST) return 0;
699c2c66affSColin Finck
700c2c66affSColin Finck EnterCriticalSection(&wma->cs);
701c2c66affSColin Finck
702c2c66affSColin Finck if (wma->dwStatus == MCI_MODE_PLAY)
703c2c66affSColin Finck wma->dwStatus = MCI_MODE_PAUSE;
704c2c66affSColin Finck
705c2c66affSColin Finck if (wma->lpWaveFormat) {
706c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
707c2c66affSColin Finck return waveOutPause(wma->hWave);
708c2c66affSColin Finck }
709c2c66affSColin Finck
710c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
711c2c66affSColin Finck return 0;
712c2c66affSColin Finck }
713c2c66affSColin Finck
714c2c66affSColin Finck /***************************************************************************
715c2c66affSColin Finck * MCIAVI_mciResume [internal]
716c2c66affSColin Finck */
MCIAVI_mciResume(UINT wDevID,DWORD dwFlags,LPMCI_GENERIC_PARMS lpParms)717c2c66affSColin Finck static DWORD MCIAVI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
718c2c66affSColin Finck {
719c2c66affSColin Finck WINE_MCIAVI *wma;
720c2c66affSColin Finck
721c2c66affSColin Finck TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
722c2c66affSColin Finck
723c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
724c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
725c2c66affSColin Finck if (dwFlags & MCI_TEST) return 0;
726c2c66affSColin Finck
727c2c66affSColin Finck EnterCriticalSection(&wma->cs);
728c2c66affSColin Finck
729c2c66affSColin Finck if (wma->dwStatus == MCI_MODE_PAUSE)
730c2c66affSColin Finck wma->dwStatus = MCI_MODE_PLAY;
731c2c66affSColin Finck
732c2c66affSColin Finck if (wma->lpWaveFormat) {
733c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
734c2c66affSColin Finck return waveOutRestart(wma->hWave);
735c2c66affSColin Finck }
736c2c66affSColin Finck
737c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
738c2c66affSColin Finck return 0;
739c2c66affSColin Finck }
740c2c66affSColin Finck
741c2c66affSColin Finck /***************************************************************************
742c2c66affSColin Finck * MCIAVI_mciSeek [internal]
743c2c66affSColin Finck */
MCIAVI_mciSeek(UINT wDevID,DWORD dwFlags,LPMCI_SEEK_PARMS lpParms)744c2c66affSColin Finck static DWORD MCIAVI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
745c2c66affSColin Finck {
746c2c66affSColin Finck WINE_MCIAVI *wma;
747c2c66affSColin Finck DWORD position;
748c2c66affSColin Finck
749c2c66affSColin Finck TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
750c2c66affSColin Finck
751c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
752c2c66affSColin Finck
753c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
754c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
755c2c66affSColin Finck
756c2c66affSColin Finck position = dwFlags & (MCI_SEEK_TO_START|MCI_SEEK_TO_END|MCI_TO);
757c2c66affSColin Finck if (!position) return MCIERR_MISSING_PARAMETER;
758c2c66affSColin Finck if (position&(position-1)) return MCIERR_FLAGS_NOT_COMPATIBLE;
759c2c66affSColin Finck
760c2c66affSColin Finck if (dwFlags & MCI_TO) {
761c2c66affSColin Finck position = MCIAVI_ConvertTimeFormatToFrame(wma, lpParms->dwTo);
762c2c66affSColin Finck if (position >= wma->dwPlayableVideoFrames)
763c2c66affSColin Finck return MCIERR_OUTOFRANGE;
764c2c66affSColin Finck } else if (dwFlags & MCI_SEEK_TO_START) {
765c2c66affSColin Finck position = 0;
766c2c66affSColin Finck } else {
767c2c66affSColin Finck position = wma->dwPlayableVideoFrames - 1;
768c2c66affSColin Finck }
769c2c66affSColin Finck if (dwFlags & MCI_TEST) return 0;
770c2c66affSColin Finck
771c2c66affSColin Finck MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
772c2c66affSColin Finck
773c2c66affSColin Finck EnterCriticalSection(&wma->cs);
774c2c66affSColin Finck
775c2c66affSColin Finck wma->dwCurrVideoFrame = position;
776c2c66affSColin Finck TRACE("Seeking to frame=%u\n", wma->dwCurrVideoFrame);
777c2c66affSColin Finck
778c2c66affSColin Finck if (dwFlags & MCI_NOTIFY) {
779c2c66affSColin Finck mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
780c2c66affSColin Finck wDevID, MCI_NOTIFY_SUCCESSFUL);
781c2c66affSColin Finck }
782c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
783c2c66affSColin Finck return 0;
784c2c66affSColin Finck }
785c2c66affSColin Finck
786c2c66affSColin Finck /*****************************************************************************
787c2c66affSColin Finck * MCIAVI_mciLoad [internal]
788c2c66affSColin Finck */
MCIAVI_mciLoad(UINT wDevID,DWORD dwFlags,LPMCI_DGV_LOAD_PARMSW lpParms)789c2c66affSColin Finck static DWORD MCIAVI_mciLoad(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LOAD_PARMSW lpParms)
790c2c66affSColin Finck {
791c2c66affSColin Finck WINE_MCIAVI *wma;
792c2c66affSColin Finck
793c2c66affSColin Finck FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms);
794c2c66affSColin Finck
795c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
796c2c66affSColin Finck
797c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
798c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
799c2c66affSColin Finck
800c2c66affSColin Finck return MCIERR_UNSUPPORTED_FUNCTION; /* like w2k */
801c2c66affSColin Finck }
802c2c66affSColin Finck
803c2c66affSColin Finck /******************************************************************************
804c2c66affSColin Finck * MCIAVI_mciRealize [internal]
805c2c66affSColin Finck */
MCIAVI_mciRealize(UINT wDevID,DWORD dwFlags,LPMCI_GENERIC_PARMS lpParms)806c2c66affSColin Finck static DWORD MCIAVI_mciRealize(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
807c2c66affSColin Finck {
808c2c66affSColin Finck WINE_MCIAVI *wma;
809c2c66affSColin Finck
810c2c66affSColin Finck FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms);
811c2c66affSColin Finck
812c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
813c2c66affSColin Finck
814c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
815c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
816c2c66affSColin Finck if (dwFlags & MCI_TEST) return 0;
817c2c66affSColin Finck
818c2c66affSColin Finck return 0;
819c2c66affSColin Finck }
820c2c66affSColin Finck
821c2c66affSColin Finck /******************************************************************************
822c2c66affSColin Finck * MCIAVI_mciUpdate [internal]
823c2c66affSColin Finck */
MCIAVI_mciUpdate(UINT wDevID,DWORD dwFlags,LPMCI_DGV_UPDATE_PARMS lpParms)824c2c66affSColin Finck static DWORD MCIAVI_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS lpParms)
825c2c66affSColin Finck {
826c2c66affSColin Finck WINE_MCIAVI *wma;
827c2c66affSColin Finck
828c2c66affSColin Finck TRACE("%04x, %08x, %p\n", wDevID, dwFlags, lpParms);
829c2c66affSColin Finck
830c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
831c2c66affSColin Finck
832c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
833c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
834c2c66affSColin Finck /* Ignore MCI_TEST flag. */
835c2c66affSColin Finck
836c2c66affSColin Finck EnterCriticalSection(&wma->cs);
837c2c66affSColin Finck
838c2c66affSColin Finck if (dwFlags & MCI_DGV_UPDATE_HDC)
839c2c66affSColin Finck MCIAVI_PaintFrame(wma, lpParms->hDC);
840c2c66affSColin Finck
841c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
842c2c66affSColin Finck
843c2c66affSColin Finck return 0;
844c2c66affSColin Finck }
845c2c66affSColin Finck
846c2c66affSColin Finck /******************************************************************************
847c2c66affSColin Finck * MCIAVI_mciStep [internal]
848c2c66affSColin Finck */
MCIAVI_mciStep(UINT wDevID,DWORD dwFlags,LPMCI_DGV_STEP_PARMS lpParms)849c2c66affSColin Finck static DWORD MCIAVI_mciStep(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STEP_PARMS lpParms)
850c2c66affSColin Finck {
851c2c66affSColin Finck WINE_MCIAVI *wma;
852c2c66affSColin Finck DWORD position;
853c2c66affSColin Finck int delta = 1;
854c2c66affSColin Finck
855c2c66affSColin Finck TRACE("(%04x, %08x, %p)\n", wDevID, dwFlags, lpParms);
856c2c66affSColin Finck
857c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
858c2c66affSColin Finck
859c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
860c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
861c2c66affSColin Finck
862c2c66affSColin Finck if (dwFlags & MCI_DGV_STEP_FRAMES) delta = lpParms->dwFrames;
863c2c66affSColin Finck if (dwFlags & MCI_DGV_STEP_REVERSE) delta = -delta;
864c2c66affSColin Finck position = wma->dwCurrVideoFrame + delta;
865c2c66affSColin Finck if (position >= wma->dwPlayableVideoFrames) return MCIERR_OUTOFRANGE;
866c2c66affSColin Finck if (dwFlags & MCI_TEST) return 0;
867c2c66affSColin Finck
868c2c66affSColin Finck MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
869c2c66affSColin Finck
870c2c66affSColin Finck EnterCriticalSection(&wma->cs);
871c2c66affSColin Finck
872c2c66affSColin Finck wma->dwCurrVideoFrame = position;
873c2c66affSColin Finck TRACE("Stepping to frame=%u\n", wma->dwCurrVideoFrame);
874c2c66affSColin Finck
875c2c66affSColin Finck if (dwFlags & MCI_NOTIFY) {
876c2c66affSColin Finck mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
877c2c66affSColin Finck wDevID, MCI_NOTIFY_SUCCESSFUL);
878c2c66affSColin Finck }
879c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
880c2c66affSColin Finck return 0;
881c2c66affSColin Finck }
882c2c66affSColin Finck
883c2c66affSColin Finck /******************************************************************************
884c2c66affSColin Finck * MCIAVI_mciCue [internal]
885c2c66affSColin Finck */
MCIAVI_mciCue(UINT wDevID,DWORD dwFlags,LPMCI_DGV_CUE_PARMS lpParms)886c2c66affSColin Finck static DWORD MCIAVI_mciCue(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUE_PARMS lpParms)
887c2c66affSColin Finck {
888c2c66affSColin Finck WINE_MCIAVI *wma;
889c2c66affSColin Finck
890c2c66affSColin Finck FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms);
891c2c66affSColin Finck
892c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
893c2c66affSColin Finck
894c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
895c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
896c2c66affSColin Finck if (dwFlags & MCI_DGV_CUE_INPUT) return MCIERR_UNSUPPORTED_FUNCTION;
897c2c66affSColin Finck if (dwFlags & MCI_TEST) return 0;
898c2c66affSColin Finck
899c2c66affSColin Finck return 0;
900c2c66affSColin Finck }
901c2c66affSColin Finck
902c2c66affSColin Finck /******************************************************************************
903c2c66affSColin Finck * MCIAVI_mciBreak [internal]
904c2c66affSColin Finck */
MCIAVI_mciBreak(UINT wDevID,DWORD dwFlags,LPMCI_BREAK_PARMS lpParms)905c2c66affSColin Finck static DWORD MCIAVI_mciBreak(UINT wDevID, DWORD dwFlags, LPMCI_BREAK_PARMS lpParms)
906c2c66affSColin Finck {
907c2c66affSColin Finck WINE_MCIAVI *wma;
908c2c66affSColin Finck
909c2c66affSColin Finck TRACE("(%04x, %08x, %p)\n", wDevID, dwFlags, lpParms);
910c2c66affSColin Finck
911c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
912c2c66affSColin Finck
913c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
914c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
915c2c66affSColin Finck
916c2c66affSColin Finck EnterCriticalSection(&wma->cs);
917c2c66affSColin Finck
918c2c66affSColin Finck wma->mci_break.flags = dwFlags;
919c2c66affSColin Finck wma->mci_break.parms = *lpParms;
920c2c66affSColin Finck
921c2c66affSColin Finck LeaveCriticalSection(&wma->cs);
922c2c66affSColin Finck
923c2c66affSColin Finck return 0;
924c2c66affSColin Finck }
925c2c66affSColin Finck
926c2c66affSColin Finck /******************************************************************************
927c2c66affSColin Finck * MCIAVI_mciSetAudio [internal]
928c2c66affSColin Finck */
MCIAVI_mciSetAudio(UINT wDevID,DWORD dwFlags,LPMCI_DGV_SETAUDIO_PARMSW lpParms)929c2c66affSColin Finck static DWORD MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSW lpParms)
930c2c66affSColin Finck {
931c2c66affSColin Finck WINE_MCIAVI *wma;
932c2c66affSColin Finck
933c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
934c2c66affSColin Finck
935c2c66affSColin Finck FIXME("(%04x, %08x, %p) Item %04x: stub\n", wDevID, dwFlags, lpParms, dwFlags & MCI_DGV_SETAUDIO_ITEM ? lpParms->dwItem : 0);
936c2c66affSColin Finck
937c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
938c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
939c2c66affSColin Finck
940c2c66affSColin Finck return 0;
941c2c66affSColin Finck }
942c2c66affSColin Finck
943c2c66affSColin Finck /******************************************************************************
944c2c66affSColin Finck * MCIAVI_mciSignal [internal]
945c2c66affSColin Finck */
MCIAVI_mciSignal(UINT wDevID,DWORD dwFlags,LPMCI_DGV_SIGNAL_PARMS lpParms)946c2c66affSColin Finck static DWORD MCIAVI_mciSignal(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SIGNAL_PARMS lpParms)
947c2c66affSColin Finck {
948c2c66affSColin Finck WINE_MCIAVI *wma;
949c2c66affSColin Finck
950c2c66affSColin Finck FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms);
951c2c66affSColin Finck
952c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
953c2c66affSColin Finck
954c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
955c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
956c2c66affSColin Finck
957c2c66affSColin Finck return 0;
958c2c66affSColin Finck }
959c2c66affSColin Finck
960c2c66affSColin Finck /******************************************************************************
961c2c66affSColin Finck * MCIAVI_mciSetVideo [internal]
962c2c66affSColin Finck */
MCIAVI_mciSetVideo(UINT wDevID,DWORD dwFlags,LPMCI_DGV_SETVIDEO_PARMSW lpParms)963c2c66affSColin Finck static DWORD MCIAVI_mciSetVideo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETVIDEO_PARMSW lpParms)
964c2c66affSColin Finck {
965c2c66affSColin Finck WINE_MCIAVI *wma;
966c2c66affSColin Finck
967c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
968c2c66affSColin Finck
969c2c66affSColin Finck FIXME("(%04x, %08x, %p) Item %04x: stub\n", wDevID, dwFlags, lpParms, dwFlags & MCI_DGV_SETVIDEO_ITEM ? lpParms->dwItem : 0);
970c2c66affSColin Finck
971c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
972c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
973c2c66affSColin Finck
974c2c66affSColin Finck return 0;
975c2c66affSColin Finck }
976c2c66affSColin Finck
977c2c66affSColin Finck /******************************************************************************
978c2c66affSColin Finck * MCIAVI_mciConfigure [internal]
979c2c66affSColin Finck */
MCIAVI_mciConfigure(UINT wDevID,DWORD dwFlags,LPMCI_GENERIC_PARMS lpParms)980c2c66affSColin Finck static DWORD MCIAVI_mciConfigure(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
981c2c66affSColin Finck {
982c2c66affSColin Finck WINE_MCIAVI *wma;
983c2c66affSColin Finck
984c2c66affSColin Finck FIXME("(%04x, %08x, %p) : stub\n", wDevID, dwFlags, lpParms);
985c2c66affSColin Finck
986c2c66affSColin Finck if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
987c2c66affSColin Finck
988c2c66affSColin Finck wma = MCIAVI_mciGetOpenDev(wDevID);
989c2c66affSColin Finck if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
990c2c66affSColin Finck if (dwFlags & MCI_TEST) return 0;
991c2c66affSColin Finck
992c2c66affSColin Finck return 0;
993c2c66affSColin Finck }
994c2c66affSColin Finck
995c2c66affSColin Finck /*======================================================================*
996c2c66affSColin Finck * MCI AVI entry points *
997c2c66affSColin Finck *======================================================================*/
998c2c66affSColin Finck
999c2c66affSColin Finck /**************************************************************************
1000c2c66affSColin Finck * DriverProc (MCIAVI.@)
1001c2c66affSColin Finck */
MCIAVI_DriverProc(DWORD_PTR dwDevID,HDRVR hDriv,UINT wMsg,LPARAM dwParam1,LPARAM dwParam2)1002c2c66affSColin Finck LRESULT CALLBACK MCIAVI_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
1003c2c66affSColin Finck LPARAM dwParam1, LPARAM dwParam2)
1004c2c66affSColin Finck {
1005c2c66affSColin Finck TRACE("(%08lX, %p, %08X, %08lX, %08lX)\n",
1006c2c66affSColin Finck dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1007c2c66affSColin Finck
1008c2c66affSColin Finck switch (wMsg) {
1009c2c66affSColin Finck case DRV_LOAD: return 1;
1010c2c66affSColin Finck case DRV_FREE: return 1;
1011c2c66affSColin Finck case DRV_OPEN: return MCIAVI_drvOpen((LPCWSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSW)dwParam2);
1012c2c66affSColin Finck case DRV_CLOSE: return MCIAVI_drvClose(dwDevID);
1013c2c66affSColin Finck case DRV_ENABLE: return 1;
1014c2c66affSColin Finck case DRV_DISABLE: return 1;
1015c2c66affSColin Finck case DRV_QUERYCONFIGURE: return 1;
1016c2c66affSColin Finck case DRV_CONFIGURE: return MCIAVI_drvConfigure(dwDevID);
1017c2c66affSColin Finck case DRV_INSTALL: return DRVCNF_RESTART;
1018c2c66affSColin Finck case DRV_REMOVE: return DRVCNF_RESTART;
1019c2c66affSColin Finck }
1020c2c66affSColin Finck
1021c2c66affSColin Finck /* session instance */
1022c2c66affSColin Finck if (dwDevID == 0xFFFFFFFF) return 1;
1023c2c66affSColin Finck
1024c2c66affSColin Finck switch (wMsg) {
1025c2c66affSColin Finck case MCI_OPEN_DRIVER: return MCIAVI_mciOpen (dwDevID, dwParam1, (LPMCI_DGV_OPEN_PARMSW) dwParam2);
1026c2c66affSColin Finck case MCI_CLOSE_DRIVER: return MCIAVI_mciClose (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1027c2c66affSColin Finck case MCI_PLAY: return MCIAVI_mciPlay (dwDevID, dwParam1, (LPMCI_PLAY_PARMS) dwParam2);
1028c2c66affSColin Finck case MCI_STOP: return MCIAVI_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1029c2c66affSColin Finck case MCI_SET: return MCIAVI_mciSet (dwDevID, dwParam1, (LPMCI_DGV_SET_PARMS) dwParam2);
1030c2c66affSColin Finck case MCI_PAUSE: return MCIAVI_mciPause (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1031c2c66affSColin Finck case MCI_RESUME: return MCIAVI_mciResume (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1032c2c66affSColin Finck case MCI_STATUS: return MCIAVI_mciStatus (dwDevID, dwParam1, (LPMCI_DGV_STATUS_PARMSW) dwParam2);
1033c2c66affSColin Finck case MCI_GETDEVCAPS: return MCIAVI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS) dwParam2);
1034c2c66affSColin Finck case MCI_INFO: return MCIAVI_mciInfo (dwDevID, dwParam1, (LPMCI_DGV_INFO_PARMSW) dwParam2);
1035c2c66affSColin Finck case MCI_SEEK: return MCIAVI_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2);
1036c2c66affSColin Finck case MCI_PUT: return MCIAVI_mciPut (dwDevID, dwParam1, (LPMCI_DGV_PUT_PARMS) dwParam2);
1037c2c66affSColin Finck case MCI_WINDOW: return MCIAVI_mciWindow (dwDevID, dwParam1, (LPMCI_DGV_WINDOW_PARMSW) dwParam2);
1038c2c66affSColin Finck case MCI_LOAD: return MCIAVI_mciLoad (dwDevID, dwParam1, (LPMCI_DGV_LOAD_PARMSW) dwParam2);
1039c2c66affSColin Finck case MCI_REALIZE: return MCIAVI_mciRealize (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1040c2c66affSColin Finck case MCI_UPDATE: return MCIAVI_mciUpdate (dwDevID, dwParam1, (LPMCI_DGV_UPDATE_PARMS) dwParam2);
1041c2c66affSColin Finck case MCI_WHERE: return MCIAVI_mciWhere (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2);
1042c2c66affSColin Finck case MCI_STEP: return MCIAVI_mciStep (dwDevID, dwParam1, (LPMCI_DGV_STEP_PARMS) dwParam2);
1043c2c66affSColin Finck case MCI_CUE: return MCIAVI_mciCue (dwDevID, dwParam1, (LPMCI_DGV_CUE_PARMS) dwParam2);
1044c2c66affSColin Finck case MCI_BREAK: return MCIAVI_mciBreak (dwDevID, dwParam1, (LPMCI_BREAK_PARMS) dwParam2);
1045c2c66affSColin Finck /* Digital Video specific */
1046c2c66affSColin Finck case MCI_SETAUDIO: return MCIAVI_mciSetAudio (dwDevID, dwParam1, (LPMCI_DGV_SETAUDIO_PARMSW) dwParam2);
1047c2c66affSColin Finck case MCI_SIGNAL: return MCIAVI_mciSignal (dwDevID, dwParam1, (LPMCI_DGV_SIGNAL_PARMS) dwParam2);
1048c2c66affSColin Finck case MCI_SETVIDEO: return MCIAVI_mciSetVideo (dwDevID, dwParam1, (LPMCI_DGV_SETVIDEO_PARMSW) dwParam2);
1049c2c66affSColin Finck case MCI_CONFIGURE: return MCIAVI_mciConfigure (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1050c2c66affSColin Finck
1051c2c66affSColin Finck /* no editing, recording, saving, locking without inputs */
1052c2c66affSColin Finck case MCI_CAPTURE:
1053c2c66affSColin Finck case MCI_COPY:
1054c2c66affSColin Finck case MCI_CUT:
1055c2c66affSColin Finck case MCI_DELETE:
1056c2c66affSColin Finck case MCI_FREEZE:
1057c2c66affSColin Finck case MCI_LIST:
1058c2c66affSColin Finck case MCI_MONITOR:
1059c2c66affSColin Finck case MCI_PASTE:
1060c2c66affSColin Finck case MCI_QUALITY:
1061c2c66affSColin Finck case MCI_RECORD:
1062c2c66affSColin Finck case MCI_RESERVE:
1063c2c66affSColin Finck case MCI_RESTORE:
1064c2c66affSColin Finck case MCI_SAVE:
1065c2c66affSColin Finck case MCI_UNDO:
1066c2c66affSColin Finck case MCI_UNFREEZE:
1067c2c66affSColin Finck TRACE("Unsupported function [0x%x] flags=%08x\n", wMsg, (DWORD)dwParam1);
1068c2c66affSColin Finck return MCIERR_UNSUPPORTED_FUNCTION;
1069c2c66affSColin Finck case MCI_SPIN:
1070c2c66affSColin Finck case MCI_ESCAPE:
1071c2c66affSColin Finck WARN("Unsupported command [0x%x] %08x\n", wMsg, (DWORD)dwParam1);
1072c2c66affSColin Finck break;
1073c2c66affSColin Finck case MCI_OPEN:
1074c2c66affSColin Finck case MCI_CLOSE:
1075c2c66affSColin Finck FIXME("Shouldn't receive a MCI_OPEN or CLOSE message\n");
1076c2c66affSColin Finck break;
1077c2c66affSColin Finck default:
1078c2c66affSColin Finck TRACE("Sending msg [%u] to default driver proc\n", wMsg);
1079c2c66affSColin Finck return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1080c2c66affSColin Finck }
1081c2c66affSColin Finck return MCIERR_UNRECOGNIZED_COMMAND;
1082c2c66affSColin Finck }
1083