1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * Digital video MCI Wine Driver
6 * Copyright 1999, 2000 Eric POUECH
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "private_mciavi.h"
25 #include "wine/debug.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(mciavi
);
29 /**************************************************************************
30 * MCIAVI_ConvertFrameToTimeFormat [internal]
32 DWORD
MCIAVI_ConvertFrameToTimeFormat(WINE_MCIAVI
* wma
, DWORD val
, LPDWORD lpRet
)
36 switch (wma
->dwMciTimeFormat
) {
37 case MCI_FORMAT_MILLISECONDS
:
38 ret
= (val
* wma
->mah
.dwMicroSecPerFrame
) / 1000;
40 case MCI_FORMAT_FRAMES
:
44 WARN("Bad time format %lu!\n", wma
->dwMciTimeFormat
);
46 TRACE("val=%lu=0x%08lx [tf=%lu] => ret=%lu\n", val
, val
, wma
->dwMciTimeFormat
, ret
);
51 /**************************************************************************
52 * MCIAVI_ConvertTimeFormatToFrame [internal]
54 DWORD
MCIAVI_ConvertTimeFormatToFrame(WINE_MCIAVI
* wma
, DWORD val
)
58 switch (wma
->dwMciTimeFormat
) {
59 case MCI_FORMAT_MILLISECONDS
:
60 ret
= (val
* 1000) / wma
->mah
.dwMicroSecPerFrame
;
62 case MCI_FORMAT_FRAMES
:
66 WARN("Bad time format %lu!\n", wma
->dwMciTimeFormat
);
68 TRACE("val=%lu=0x%08lx [tf=%lu] => ret=%lu\n", val
, val
, wma
->dwMciTimeFormat
, ret
);
72 /***************************************************************************
73 * MCIAVI_mciGetDevCaps [internal]
75 DWORD
MCIAVI_mciGetDevCaps(UINT wDevID
, DWORD dwFlags
, LPMCI_GETDEVCAPS_PARMS lpParms
)
77 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
80 TRACE("(%04x, %08lX, %p)\n", wDevID
, dwFlags
, lpParms
);
82 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
83 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
85 if (dwFlags
& MCI_GETDEVCAPS_ITEM
) {
86 switch (lpParms
->dwItem
) {
87 case MCI_GETDEVCAPS_DEVICE_TYPE
:
88 TRACE("MCI_GETDEVCAPS_DEVICE_TYPE !\n");
89 lpParms
->dwReturn
= MAKEMCIRESOURCE(MCI_DEVTYPE_DIGITAL_VIDEO
, MCI_DEVTYPE_DIGITAL_VIDEO
);
90 ret
= MCI_RESOURCE_RETURNED
;
92 case MCI_GETDEVCAPS_HAS_AUDIO
:
93 TRACE("MCI_GETDEVCAPS_HAS_AUDIO !\n");
94 lpParms
->dwReturn
= MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
95 ret
= MCI_RESOURCE_RETURNED
;
97 case MCI_GETDEVCAPS_HAS_VIDEO
:
98 TRACE("MCI_GETDEVCAPS_HAS_VIDEO !\n");
99 lpParms
->dwReturn
= MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
100 ret
= MCI_RESOURCE_RETURNED
;
102 case MCI_GETDEVCAPS_USES_FILES
:
103 TRACE("MCI_GETDEVCAPS_USES_FILES !\n");
104 lpParms
->dwReturn
= MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
105 ret
= MCI_RESOURCE_RETURNED
;
107 case MCI_GETDEVCAPS_COMPOUND_DEVICE
:
108 TRACE("MCI_GETDEVCAPS_COMPOUND_DEVICE !\n");
109 lpParms
->dwReturn
= MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
110 ret
= MCI_RESOURCE_RETURNED
;
112 case MCI_GETDEVCAPS_CAN_EJECT
:
113 TRACE("MCI_GETDEVCAPS_CAN_EJECT !\n");
114 lpParms
->dwReturn
= MAKEMCIRESOURCE(FALSE
, MCI_FALSE
);
115 ret
= MCI_RESOURCE_RETURNED
;
117 case MCI_GETDEVCAPS_CAN_PLAY
:
118 TRACE("MCI_GETDEVCAPS_CAN_PLAY !\n");
119 lpParms
->dwReturn
= MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
120 ret
= MCI_RESOURCE_RETURNED
;
122 case MCI_GETDEVCAPS_CAN_RECORD
:
123 TRACE("MCI_GETDEVCAPS_CAN_RECORD !\n");
124 lpParms
->dwReturn
= MAKEMCIRESOURCE(FALSE
, MCI_FALSE
);
125 ret
= MCI_RESOURCE_RETURNED
;
127 case MCI_GETDEVCAPS_CAN_SAVE
:
128 TRACE("MCI_GETDEVCAPS_CAN_SAVE !\n");
129 lpParms
->dwReturn
= MAKEMCIRESOURCE(FALSE
, MCI_FALSE
);
130 ret
= MCI_RESOURCE_RETURNED
;
133 FIXME("Unknown capability (%08lx) !\n", lpParms
->dwItem
);
134 return MCIERR_UNRECOGNIZED_COMMAND
;
137 WARN("No GetDevCaps-Item !\n");
138 return MCIERR_UNRECOGNIZED_COMMAND
;
143 /***************************************************************************
144 * MCIAVI_mciInfo [internal]
146 DWORD
MCIAVI_mciInfo(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_INFO_PARMSA lpParms
)
149 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
152 if (lpParms
== NULL
|| lpParms
->lpstrReturn
== NULL
)
153 return MCIERR_NULL_PARAMETER_BLOCK
;
154 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
156 TRACE("buf=%p, len=%lu\n", lpParms
->lpstrReturn
, lpParms
->dwRetSize
);
159 case MCI_INFO_PRODUCT
:
160 str
= "Wine's AVI player";
163 str
= wma
->openParms
.lpstrElementName
;
166 WARN("Don't know this info command (%lu)\n", dwFlags
);
167 return MCIERR_UNRECOGNIZED_COMMAND
;
170 if (strlen(str
) + 1 > lpParms
->dwRetSize
) {
171 ret
= MCIERR_PARAM_OVERFLOW
;
173 lstrcpynA(lpParms
->lpstrReturn
, str
, lpParms
->dwRetSize
);
176 lpParms
->lpstrReturn
[0] = 0;
181 /***************************************************************************
182 * MCIAVI_mciSet [internal]
184 DWORD
MCIAVI_mciSet(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_SET_PARMS lpParms
)
186 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
188 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
189 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
191 if (dwFlags
& MCI_SET_TIME_FORMAT
) {
192 switch (lpParms
->dwTimeFormat
) {
193 case MCI_FORMAT_MILLISECONDS
:
194 TRACE("MCI_FORMAT_MILLISECONDS !\n");
195 wma
->dwMciTimeFormat
= MCI_FORMAT_MILLISECONDS
;
197 case MCI_FORMAT_FRAMES
:
198 TRACE("MCI_FORMAT_FRAMES !\n");
199 wma
->dwMciTimeFormat
= MCI_FORMAT_FRAMES
;
202 WARN("Bad time format %lu!\n", lpParms
->dwTimeFormat
);
203 return MCIERR_BAD_TIME_FORMAT
;
207 if (dwFlags
& MCI_SET_DOOR_OPEN
) {
208 TRACE("No support for door open !\n");
209 return MCIERR_UNSUPPORTED_FUNCTION
;
211 if (dwFlags
& MCI_SET_DOOR_CLOSED
) {
212 TRACE("No support for door close !\n");
213 return MCIERR_UNSUPPORTED_FUNCTION
;
215 if (dwFlags
& MCI_SET_ON
) {
218 strcpy(buffer
, "MCI_SET_ON:");
220 if (dwFlags
& MCI_SET_VIDEO
) {
221 strncat(buffer
, " video", sizeof(buffer
));
224 if (dwFlags
& MCI_SET_AUDIO
) {
225 strncat(buffer
, " audio", sizeof(buffer
));
226 switch (lpParms
->dwAudio
) {
227 case MCI_SET_AUDIO_ALL
:
228 strncat(buffer
, " all", sizeof(buffer
));
231 case MCI_SET_AUDIO_LEFT
:
232 strncat(buffer
, " left", sizeof(buffer
));
235 case MCI_SET_AUDIO_RIGHT
:
236 strncat(buffer
, " right", sizeof(buffer
));
240 WARN("Unknown audio chanel %lu\n", lpParms
->dwAudio
);
244 if (dwFlags
& MCI_DGV_SET_SEEK_EXACTLY
) {
245 strncat(buffer
, " seek_exactly", sizeof(buffer
));
247 FIXME("%s\n", buffer
);
250 if (dwFlags
& MCI_SET_OFF
) {
253 strcpy(buffer
, "MCI_SET_OFF:");
254 if (dwFlags
& MCI_SET_VIDEO
) {
255 strncat(buffer
, " video", sizeof(buffer
));
258 if (dwFlags
& MCI_SET_AUDIO
) {
259 strncat(buffer
, " audio", sizeof(buffer
));
260 switch (lpParms
->dwAudio
) {
261 case MCI_SET_AUDIO_ALL
:
262 strncat(buffer
, " all", sizeof(buffer
));
265 case MCI_SET_AUDIO_LEFT
:
266 strncat(buffer
, " left", sizeof(buffer
));
269 case MCI_SET_AUDIO_RIGHT
:
270 strncat(buffer
, " right", sizeof(buffer
));
274 WARN("Unknown audio chanel %lu\n", lpParms
->dwAudio
);
278 if (dwFlags
& MCI_DGV_SET_SEEK_EXACTLY
) {
279 strncat(buffer
, " seek_exactly", sizeof(buffer
));
281 FIXME("%s\n", buffer
);
283 if (dwFlags
& MCI_DGV_SET_FILEFORMAT
) {
285 if (dwFlags
& MCI_DGV_SET_STILL
)
288 switch (lpParms
->dwFileFormat
) {
289 case MCI_DGV_FF_AVI
: FIXME("Setting file format (%s) to 'AVI'\n", str
); break;
290 case MCI_DGV_FF_AVSS
: FIXME("Setting file format (%s) to 'AVSS'\n", str
); break;
291 case MCI_DGV_FF_DIB
: FIXME("Setting file format (%s) to 'DIB'\n", str
); break;
292 case MCI_DGV_FF_JFIF
: FIXME("Setting file format (%s) to 'JFIF'\n", str
); break;
293 case MCI_DGV_FF_JPEG
: FIXME("Setting file format (%s) to 'JPEG'\n", str
); break;
294 case MCI_DGV_FF_MPEG
: FIXME("Setting file format (%s) to 'MPEG'\n", str
); break;
295 case MCI_DGV_FF_RDIB
: FIXME("Setting file format (%s) to 'RLE DIB'\n", str
); break;
296 case MCI_DGV_FF_RJPEG
: FIXME("Setting file format (%s) to 'RJPEG'\n", str
); break;
297 default: FIXME("Setting unknown file format (%s): %ld\n", str
, lpParms
->dwFileFormat
);
301 if (dwFlags
& MCI_DGV_SET_SPEED
) {
302 FIXME("Setting speed to %ld\n", lpParms
->dwSpeed
);
308 /***************************************************************************
309 * MCIAVI_mciStatus [internal]
311 DWORD
MCIAVI_mciStatus(UINT wDevID
, DWORD dwFlags
, LPMCI_DGV_STATUS_PARMSA lpParms
)
313 WINE_MCIAVI
* wma
= MCIAVI_mciGetOpenDev(wDevID
);
316 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
317 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
319 if (dwFlags
& MCI_STATUS_ITEM
) {
320 switch (lpParms
->dwItem
) {
321 case MCI_STATUS_CURRENT_TRACK
:
322 lpParms
->dwReturn
= 1;
323 TRACE("MCI_STATUS_CURRENT_TRACK => %lu\n", lpParms
->dwReturn
);
325 case MCI_STATUS_LENGTH
:
327 lpParms
->dwReturn
= 0;
328 return MCIERR_UNSUPPORTED_FUNCTION
;
330 /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
331 lpParms
->dwReturn
= MCIAVI_ConvertFrameToTimeFormat(wma
, wma
->mah
.dwTotalFrames
, &ret
);
332 TRACE("MCI_STATUS_LENGTH => %lu\n", lpParms
->dwReturn
);
334 case MCI_STATUS_MODE
:
335 lpParms
->dwReturn
= MAKEMCIRESOURCE(wma
->dwStatus
, wma
->dwStatus
);
336 ret
= MCI_RESOURCE_RETURNED
;
337 TRACE("MCI_STATUS_MODE => %u\n", LOWORD(lpParms
->dwReturn
));
339 case MCI_STATUS_MEDIA_PRESENT
:
340 TRACE("MCI_STATUS_MEDIA_PRESENT => TRUE\n");
341 lpParms
->dwReturn
= MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
342 ret
= MCI_RESOURCE_RETURNED
;
344 case MCI_STATUS_NUMBER_OF_TRACKS
:
345 lpParms
->dwReturn
= 1;
346 TRACE("MCI_STATUS_NUMBER_OF_TRACKS => %lu\n", lpParms
->dwReturn
);
348 case MCI_STATUS_POSITION
:
350 lpParms
->dwReturn
= 0;
351 return MCIERR_UNSUPPORTED_FUNCTION
;
353 /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
354 lpParms
->dwReturn
= MCIAVI_ConvertFrameToTimeFormat(wma
,
355 (dwFlags
& MCI_STATUS_START
) ? 0 : wma
->dwCurrVideoFrame
,
357 TRACE("MCI_STATUS_POSITION %s => %lu\n",
358 (dwFlags
& MCI_STATUS_START
) ? "start" : "current", lpParms
->dwReturn
);
360 case MCI_STATUS_READY
:
361 lpParms
->dwReturn
= (wma
->dwStatus
== MCI_MODE_NOT_READY
) ?
362 MAKEMCIRESOURCE(FALSE
, MCI_FALSE
) : MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
363 ret
= MCI_RESOURCE_RETURNED
;
364 TRACE("MCI_STATUS_READY = %u\n", LOWORD(lpParms
->dwReturn
));
366 case MCI_STATUS_TIME_FORMAT
:
367 lpParms
->dwReturn
= MAKEMCIRESOURCE(wma
->dwMciTimeFormat
, wma
->dwMciTimeFormat
);
368 TRACE("MCI_STATUS_TIME_FORMAT => %u\n", LOWORD(lpParms
->dwReturn
));
369 ret
= MCI_RESOURCE_RETURNED
;
372 case MCI_AVI_STATUS_AUDIO_BREAKS
:
373 case MCI_AVI_STATUS_FRAMES_SKIPPED
:
374 case MCI_AVI_STATUS_LAST_PLAY_SPEED
:
375 case MCI_DGV_STATUS_AUDIO
:
376 case MCI_DGV_STATUS_AUDIO_INPUT
:
377 case MCI_DGV_STATUS_AUDIO_RECORD
:
378 case MCI_DGV_STATUS_AUDIO_SOURCE
:
379 case MCI_DGV_SETAUDIO_AVERAGE
:
380 case MCI_DGV_SETAUDIO_LEFT
:
381 case MCI_DGV_SETAUDIO_RIGHT
:
382 case MCI_DGV_SETAUDIO_STEREO
:
383 case MCI_DGV_STATUS_AUDIO_STREAM
:
384 case MCI_DGV_STATUS_AVGBYTESPERSEC
:
385 case MCI_DGV_STATUS_BASS
:
386 case MCI_DGV_STATUS_BITSPERPEL
:
387 case MCI_DGV_STATUS_BITSPERSAMPLE
:
388 case MCI_DGV_STATUS_BLOCKALIGN
:
389 case MCI_DGV_STATUS_BRIGHTNESS
:
390 case MCI_DGV_STATUS_COLOR
:
391 case MCI_DGV_STATUS_CONTRAST
:
392 case MCI_DGV_STATUS_FILEFORMAT
:
393 case MCI_DGV_STATUS_FILE_MODE
:
394 case MCI_DGV_STATUS_FILE_COMPLETION
:
395 case MCI_DGV_STATUS_FORWARD
:
396 case MCI_DGV_STATUS_FRAME_RATE
:
397 case MCI_DGV_STATUS_GAMMA
:
399 case MCI_DGV_STATUS_HPAL
:
400 lpParms
->dwReturn
= 0;
401 TRACE("MCI_DGV_STATUS_HPAL => %lx\n", lpParms
->dwReturn
);
403 case MCI_DGV_STATUS_HWND
:
404 lpParms
->dwReturn
= (DWORD
)wma
->hWnd
;
405 TRACE("MCI_DGV_STATUS_HWND => %p\n", wma
->hWnd
);
408 case MCI_DGV_STATUS_KEY_COLOR
:
409 case MCI_DGV_STATUS_KEY_INDEX
:
410 case MCI_DGV_STATUS_MONITOR
:
411 case MCI_DGV_MONITOR_FILE
:
412 case MCI_DGV_MONITOR_INPUT
:
413 case MCI_DGV_STATUS_MONITOR_METHOD
:
414 case MCI_DGV_STATUS_PAUSE_MODE
:
415 case MCI_DGV_STATUS_SAMPLESPERSECOND
:
416 case MCI_DGV_STATUS_SEEK_EXACTLY
:
417 case MCI_DGV_STATUS_SHARPNESS
:
418 case MCI_DGV_STATUS_SIZE
:
419 case MCI_DGV_STATUS_SMPTE
:
420 case MCI_DGV_STATUS_SPEED
:
421 case MCI_DGV_STATUS_STILL_FILEFORMAT
:
422 case MCI_DGV_STATUS_TINT
:
423 case MCI_DGV_STATUS_TREBLE
:
424 case MCI_DGV_STATUS_UNSAVED
:
425 case MCI_DGV_STATUS_VIDEO
:
426 case MCI_DGV_STATUS_VIDEO_RECORD
:
427 case MCI_DGV_STATUS_VIDEO_SOURCE
:
428 case MCI_DGV_STATUS_VIDEO_SRC_NUM
:
429 case MCI_DGV_STATUS_VIDEO_STREAM
:
430 case MCI_DGV_STATUS_VOLUME
:
431 case MCI_DGV_STATUS_WINDOW_VISIBLE
:
432 case MCI_DGV_STATUS_WINDOW_MINIMIZED
:
433 case MCI_DGV_STATUS_WINDOW_MAXIMIZED
:
434 case MCI_STATUS_MEDIA_PRESENT
:
437 FIXME("Unknowm command %08lX !\n", lpParms
->dwItem
);
438 TRACE("(%04x, %08lX, %p)\n", wDevID
, dwFlags
, lpParms
);
439 return MCIERR_UNRECOGNIZED_COMMAND
;
442 WARN("No Status-Item!\n");
443 return MCIERR_UNRECOGNIZED_COMMAND
;
445 if (dwFlags
& MCI_NOTIFY
) {
446 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
447 mciDriverNotify(HWND_32(LOWORD(lpParms
->dwCallback
)),
448 wma
->openParms
.wDeviceID
, MCI_NOTIFY_SUCCESSFUL
);