Authors: Chris Morgan <cmorgan@wpi.edu>, James Abbatiello <abbejy@wpi.edu>
[wine/multimedia.git] / multimedia / msvideo.c
blobd3c372bae490d4eb582abe82601123592e154524
1 /*
2 * Copyright 1998 Marcus Meissner
3 */
4 #include <stdio.h>
5 #include <string.h>
7 #include "winbase.h"
8 #include "winuser.h"
9 #include "wingdi.h"
10 #include "vfw.h"
11 #include "wine/winestring.h"
12 #include "driver.h"
13 #include "debug.h"
15 DEFAULT_DEBUG_CHANNEL(msvideo)
17 /****************************************************************************
18 * VideoForWindowsVersion [MSVFW.2][MSVIDEO.2]
19 * Returns the version in major.minor form.
20 * In Windows95 this returns 0x040003b6 (4.950)
22 DWORD WINAPI
23 VideoForWindowsVersion(void) {
24 return 0x040003B6; /* 4.950 */
27 /* system.ini: [drivers] */
29 /**************************************************************************
30 * ICInfo [MSVFW.33]
31 * Get information about an installable compressor. Return TRUE if there
32 * is one.
34 BOOL WINAPI
35 ICInfo(
36 DWORD fccType, /* [in] type of compressor ('vidc') */
37 DWORD fccHandler, /* [in] <n>th compressor */
38 ICINFO *lpicinfo /* [out] information about compressor */
39 ) {
40 char type[5],buf[2000];
42 memcpy(type,&fccType,4);type[4]=0;
43 TRACE(msvideo,"(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
44 /* does OpenDriver/CloseDriver */
45 lpicinfo->dwSize = sizeof(ICINFO);
46 lpicinfo->fccType = fccType;
47 lpicinfo->dwFlags = 0;
48 if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
49 char *s = buf;
50 while (*s) {
51 if (!lstrncmpiA(type,s,4)) {
52 if(!fccHandler--) {
53 lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
54 return TRUE;
57 s=s+lstrlenA(s)+1; /* either next char or \0 */
60 return FALSE;
63 /**************************************************************************
64 * ICOpen [MSVFW.37]
65 * Opens an installable compressor. Return special handle.
67 HIC WINAPI
68 ICOpen(DWORD fccType,DWORD fccHandler,UINT wMode) {
69 char type[5],handler[5],codecname[20];
70 ICOPEN icopen;
71 HDRVR hdrv;
72 WINE_HIC *whic;
74 memcpy(type,&fccType,4);type[4]=0;
75 memcpy(handler,&fccHandler,4);handler[4]=0;
76 TRACE(msvideo,"(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);
77 sprintf(codecname,"%s.%s",type,handler);
79 /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
80 * same layout as ICOPEN
82 icopen.fccType = fccType;
83 icopen.fccHandler = fccHandler;
84 icopen.dwSize = sizeof(ICOPEN);
85 icopen.dwFlags = wMode;
86 /* FIXME: do we need to fill out the rest too? */
87 hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
88 if (!hdrv) {
89 if (!strcasecmp(type,"vids")) {
90 sprintf(codecname,"vidc.%s",handler);
91 fccType = mmioFOURCC('v','i','d','c');
93 hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
94 if (!hdrv)
95 return 0;
97 whic = HeapAlloc(GetProcessHeap(),0,sizeof(WINE_HIC));
98 whic->hdrv = hdrv;
99 whic->driverproc= NULL;
100 whic->private = ICSendMessage((HIC)whic,DRV_OPEN,0,(LPARAM)&icopen);
101 return (HIC)whic;
103 HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode,
104 FARPROC lpfnHandler) {
105 char type[5],handler[5];
106 HIC hic;
107 WINE_HIC *whic;
109 memcpy(type,&fccType,4);type[4]=0;
110 memcpy(handler,&fccHandler,4);handler[4]=0;
111 FIXME(msvideo,"(%s,%s,%d,%p), stub!\n",type,handler,wMode,lpfnHandler);
112 hic = ICOpen(fccType,fccHandler,wMode);
113 if (!hic)
114 return hic;
115 whic = (WINE_HIC*)hic;
116 whic->driverproc = lpfnHandler;
117 return hic;
121 LRESULT WINAPI
122 ICGetInfo(HIC hic,ICINFO *picinfo,DWORD cb) {
123 LRESULT ret;
125 TRACE(msvideo,"(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
126 ret = ICSendMessage(hic,ICM_GETINFO,(DWORD)picinfo,cb);
127 TRACE(msvideo," -> 0x%08lx\n",ret);
128 return ret;
131 HIC VFWAPI
132 ICLocate(
133 DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
134 LPBITMAPINFOHEADER lpbiOut, WORD wMode
136 char type[5],handler[5];
137 HIC hic;
138 DWORD querymsg;
140 switch (wMode) {
141 case ICMODE_FASTCOMPRESS:
142 case ICMODE_COMPRESS:
143 querymsg = ICM_COMPRESS_QUERY;
144 break;
145 case ICMODE_DECOMPRESS:
146 case ICMODE_FASTDECOMPRESS:
147 querymsg = ICM_DECOMPRESS_QUERY;
148 break;
149 case ICMODE_DRAW:
150 querymsg = ICM_DRAW_QUERY;
151 break;
152 default:
153 FIXME(msvideo,"Unknown mode (%d)\n",wMode);
154 return 0;
157 /* Easy case: handler/type match, we just fire a query and return */
158 hic = ICOpen(fccType,fccHandler,wMode);
159 if (hic) {
160 if (!ICSendMessage(hic,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
161 return hic;
162 ICClose(hic);
164 type[4]='\0';memcpy(type,&fccType,4);
165 handler[4]='\0';memcpy(handler,&fccHandler,4);
166 if (fccType==streamtypeVIDEO) {
167 hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
168 if (hic)
169 return hic;
171 FIXME(msvideo,"(%s,%s,%p,%p,0x%04x),unhandled!\n",type,handler,lpbiIn,lpbiOut,wMode);
172 return 0;
175 HIC VFWAPI ICGetDisplayFormat(
176 HIC hic,LPBITMAPINFOHEADER lpbiIn,LPBITMAPINFOHEADER lpbiOut,
177 INT depth,INT dx,INT dy
179 HIC tmphic = hic;
180 LRESULT lres;
182 FIXME(msvideo,"(0x%08lx,%p,%p,%d,%d,%d),stub!\n",(DWORD)hic,lpbiIn,lpbiOut,depth,dx,dy);
183 if (!tmphic) {
184 tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS);
185 if (!tmphic)
186 return tmphic;
188 if ((dy == lpbiIn->biHeight) || (dx == lpbiIn->biWidth))
189 dy = dx = 0; /* no resize needed */
190 /* Can we decompress it ? */
191 lres = ICDecompressQuery(tmphic,lpbiIn,NULL);
192 if (lres)
193 goto errout; /* no, sorry */
194 ICDecompressGetFormat(hic,lpbiIn,lpbiOut);
195 *lpbiOut=*lpbiIn;
196 lpbiOut->biCompression = 0;
197 lpbiOut->biSize = sizeof(*lpbiOut);
198 if (!depth) {
199 HDC hdc;
201 hdc = GetDC(0);
202 depth = GetDeviceCaps(hdc,12)*GetDeviceCaps(hdc,14);
203 ReleaseDC(0,hdc);
204 if (depth==15) depth = 16;
205 if (depth<8) depth = 8;
206 /* more constraints and tests */
208 if (lpbiIn->biBitCount == 8)
209 depth = 8;
211 return hic;
212 errout:
213 if (hic!=tmphic)
214 ICClose(tmphic);
215 return 0;
218 DWORD VFWAPIV
219 ICCompress(
220 HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiOutput,LPVOID lpData,
221 LPBITMAPINFOHEADER lpbiInput,LPVOID lpBits,LPDWORD lpckid,
222 LPDWORD lpdwFlags,LONG lFrameNum,DWORD dwFrameSize,DWORD dwQuality,
223 LPBITMAPINFOHEADER lpbiPrev,LPVOID lpPrev
225 ICCOMPRESS iccmp;
227 iccmp.dwFlags = dwFlags;
229 iccmp.lpbiOutput = lpbiOutput;
230 iccmp.lpOutput = lpData;
231 iccmp.lpbiInput = lpbiInput;
232 iccmp.lpInput = lpBits;
234 iccmp.lpckid = lpckid;
235 iccmp.lpdwFlags = lpdwFlags;
236 iccmp.lFrameNum = lFrameNum;
237 iccmp.dwFrameSize = dwFrameSize;
238 iccmp.dwQuality = dwQuality;
239 iccmp.lpbiPrev = lpbiPrev;
240 iccmp.lpPrev = lpPrev;
241 return ICSendMessage(hic,ICM_COMPRESS,(LPARAM)&iccmp,sizeof(iccmp));
244 DWORD VFWAPIV
245 ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,LPVOID lpData,LPBITMAPINFOHEADER lpbi,LPVOID lpBits) {
246 ICDECOMPRESS icd;
248 icd.dwFlags = dwFlags;
249 icd.lpbiInput = lpbiFormat;
250 icd.lpInput = lpData;
252 icd.lpbiOutput = lpbi;
253 icd.lpOutput = lpBits;
254 icd.ckid = 0;
255 return ICSendMessage(hic,ICM_DECOMPRESS,(LPARAM)&icd,sizeof(icd));
258 LRESULT VFWAPI
259 ICSendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2) {
260 LRESULT ret;
261 WINE_HIC *whic = (WINE_HIC*)hic;
263 #define XX(x) case x: TRACE(msvideo,"(0x%08lx,"#x",0x%08lx,0x%08lx)\n",(DWORD)hic,lParam1,lParam2);break;
265 switch (msg) {
266 XX(ICM_ABOUT)
267 XX(ICM_GETINFO)
268 XX(ICM_COMPRESS_FRAMES_INFO)
269 XX(ICM_COMPRESS_GET_FORMAT)
270 XX(ICM_COMPRESS_GET_SIZE)
271 XX(ICM_COMPRESS_QUERY)
272 XX(ICM_COMPRESS_BEGIN)
273 XX(ICM_COMPRESS)
274 XX(ICM_COMPRESS_END)
275 XX(ICM_DECOMPRESS_GET_FORMAT)
276 XX(ICM_DECOMPRESS_QUERY)
277 XX(ICM_DECOMPRESS_BEGIN)
278 XX(ICM_DECOMPRESS)
279 XX(ICM_DECOMPRESS_END)
280 XX(ICM_DECOMPRESS_SET_PALETTE)
281 XX(ICM_DECOMPRESS_GET_PALETTE)
282 XX(ICM_DRAW_QUERY)
283 XX(ICM_DRAW_BEGIN)
284 XX(ICM_DRAW_GET_PALETTE)
285 XX(ICM_DRAW_START)
286 XX(ICM_DRAW_STOP)
287 XX(ICM_DRAW_END)
288 XX(ICM_DRAW_GETTIME)
289 XX(ICM_DRAW)
290 XX(ICM_DRAW_WINDOW)
291 XX(ICM_DRAW_SETTIME)
292 XX(ICM_DRAW_REALIZE)
293 XX(ICM_DRAW_FLUSH)
294 XX(ICM_DRAW_RENDERBUFFER)
295 XX(ICM_DRAW_START_PLAY)
296 XX(ICM_DRAW_STOP_PLAY)
297 XX(ICM_DRAW_SUGGESTFORMAT)
298 XX(ICM_DRAW_CHANGEPALETTE)
299 XX(ICM_GETBUFFERSWANTED)
300 XX(ICM_GETDEFAULTKEYFRAMERATE)
301 XX(ICM_DECOMPRESSEX_BEGIN)
302 XX(ICM_DECOMPRESSEX_QUERY)
303 XX(ICM_DECOMPRESSEX)
304 XX(ICM_DECOMPRESSEX_END)
305 XX(ICM_SET_STATUS_PROC)
306 default:
307 FIXME(msvideo,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx)\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2);
309 #if 0
310 if (whic->driverproc) {
311 FIXME(msvideo,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx), calling %p\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2,whic->driverproc);
312 ret = whic->driverproc(whic->hdrv,1,msg,lParam1,lParam2);
313 } else
314 #endif
315 ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
316 TRACE(msvideo," -> 0x%08lx\n",ret);
317 return ret;
320 DWORD VFWAPIV ICDrawBegin(
321 HIC hic,
322 DWORD dwFlags,/* flags */
323 HPALETTE hpal, /* palette to draw with */
324 HWND hwnd, /* window to draw to */
325 HDC hdc, /* HDC to draw to */
326 INT xDst, /* destination rectangle */
327 INT yDst,
328 INT dxDst,
329 INT dyDst,
330 LPBITMAPINFOHEADER lpbi, /* format of frame to draw */
331 INT xSrc, /* source rectangle */
332 INT ySrc,
333 INT dxSrc,
334 INT dySrc,
335 DWORD dwRate, /* frames/second = (dwRate/dwScale) */
336 DWORD dwScale) {
337 ICDRAWBEGIN icdb;
339 icdb.dwFlags = dwFlags;
340 icdb.hpal = hpal;
341 icdb.hwnd = hwnd;
342 icdb.hdc = hdc;
343 icdb.xDst = xDst;
344 icdb.yDst = yDst;
345 icdb.dxDst = dxDst;
346 icdb.dyDst = dyDst;
347 icdb.lpbi = lpbi;
348 icdb.xSrc = xSrc;
349 icdb.ySrc = ySrc;
350 icdb.dxSrc = dxSrc;
351 icdb.dySrc = dySrc;
352 icdb.dwRate = dwRate;
353 icdb.dwScale = dwScale;
354 return ICSendMessage(hic,ICM_DRAW_BEGIN,(LPARAM)&icdb,sizeof(icdb));
357 DWORD VFWAPIV ICDraw(
358 HIC hic,DWORD dwFlags,LPVOID lpFormat,LPVOID lpData,DWORD cbData,
359 LONG lTime
361 ICDRAW icd;
363 icd.dwFlags = dwFlags;
364 icd.lpFormat = lpFormat;
365 icd.lpData = lpData;
366 icd.cbData = cbData;
367 icd.lTime = lTime;
368 return ICSendMessage(hic,ICM_DRAW,(LPARAM)&icd,sizeof(icd));
371 LRESULT WINAPI ICClose(HIC hic) {
372 WINE_HIC *whic = (WINE_HIC*)hic;
373 TRACE(msvideo,"(%d).\n",hic);
374 /* FIXME: correct? */
375 CloseDriver(whic->hdrv,0,0);
376 HeapFree(GetProcessHeap(),0,whic);
377 return 0;
380 HANDLE /* HDRAWDIB */ WINAPI
381 DrawDibOpen( void ) {
382 FIXME(msvideo,"stub!\n");
383 return 0xdead;
386 BOOL VFWAPI DrawDibBegin(HANDLE /*HDRAWDIB*/ hdd,
387 HDC hdc,
388 INT dxDst,
389 INT dyDst,
390 LPBITMAPINFOHEADER lpbi,
391 INT dxSrc,
392 INT dySrc,
393 UINT wFlags) {
394 FIXME(msvideo,"(%d,0x%lx,%d,%d,%p,%d,%d,0x%08lx), stub!\n",
395 hdd,(DWORD)hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
397 return TRUE;
401 BOOL VFWAPI
402 DrawDibSetPalette(HANDLE /*HDRAWDIB*/ hdd, HPALETTE hpal) {
403 FIXME(msvideo,"(%d,%d),stub!\n",hdd,hpal);
404 return TRUE;
407 UINT VFWAPI DrawDibRealize(HANDLE /*HDRAWDIB*/ hdd, HDC hdc, BOOL fBackground) {
408 FIXME(msvideo,"(0x%08lx,0x%08lx,%d),stub!\n",(DWORD)hdd,(DWORD)hdc,fBackground);
409 return 0;
413 HWND VFWAPIV MCIWndCreate (HWND hwndParent, HINSTANCE hInstance,
414 DWORD dwStyle,LPVOID szFile)
415 { FIXME(msvideo,"%x %x %lx %p\n",hwndParent, hInstance, dwStyle, szFile);
416 return 0;
418 HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
419 DWORD dwStyle,LPCSTR szFile)
420 { FIXME(msvideo,"%x %x %lx %s\n",hwndParent, hInstance, dwStyle, szFile);
421 return 0;
423 HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
424 DWORD dwStyle,LPCWSTR szFile)
425 { FIXME(msvideo,"%x %x %lx %s\n",hwndParent, hInstance, dwStyle, debugstr_w(szFile));
426 return 0;