2 * Copyright 1999 Marcus Meissner
10 #include "wine/winestring.h"
15 #include "debugtools.h"
17 DECLARE_DEBUG_CHANNEL(avifile)
18 DECLARE_DEBUG_CHANNEL(msvideo)
19 DECLARE_DEBUG_CHANNEL(relay)
21 typedef struct IAVIStreamImpl {
23 ICOM_VTABLE(IAVIStream)* lpvtbl;
25 /* IAVIStream stuff */
27 DWORD inputformatsize;
31 /* Compressor stuff */
33 LPVOID lpCompressFormat;
41 AVICOMPRESSOPTIONS aco;
43 LPVOID lpPrev; /* pointer to decompressed frame later */
44 LPVOID lpPrevFormat; /* pointer to decompressed info later */
49 FIXME_(avifile)("(),stub!\n");
52 typedef struct IAVIFileImpl {
54 ICOM_VTABLE(IAVIFile)* lpvtbl;
56 /* IAVIFile stuff... */
59 struct ICOM_VTABLE(IAVIStream) iavist;
61 static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj) {
62 ICOM_THIS(IAVIFileImpl,iface);
65 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
66 TRACE_(relay)("(%p)->QueryInterface(%s,%p)\n",This,xrefiid,obj);
67 if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
68 !memcmp(&IID_IAVIFile,refiid,sizeof(IID_IAVIFile))
73 return OLE_E_ENUM_NOMORE;
76 static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface) {
77 ICOM_THIS(IAVIFileImpl,iface);
79 FIXME_(relay)("(%p)->AddRef()\n",iface);
83 static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface) {
84 ICOM_THIS(IAVIFileImpl,iface);
86 FIXME_(relay)("(%p)->Release()\n",iface);
88 HeapFree(GetProcessHeap(),0,iface);
94 static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size) {
95 FIXME_(avifile)("(%p)->Info(%p,%ld)\n",iface,afi,size);
97 /* FIXME: fill out struct? */
101 static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) {
102 FIXME_(avifile)("(%p)->GetStream(%p,0x%08lx,%ld)\n",iface,avis,fccType,lParam);
103 /* FIXME: create interface etc. */
107 static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) {
108 ICOM_THIS(IAVIStreamImpl,iface);
110 IAVIStreamImpl *istream;
112 FIXME_(avifile)("(%p,%p,%p)\n",This,avis,asi);
113 istream = (IAVIStreamImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIStreamImpl));
115 istream->lpvtbl = &iavist;
117 memcpy(fcc,(char*)&(asi->fccType),4);
118 FIXME_(avifile)("\tfccType '%s'\n",fcc);
119 memcpy(fcc,(char*)&(asi->fccHandler),4);
120 FIXME_(avifile)("\tfccHandler '%s'\n",fcc);
121 FIXME_(avifile)("\tdwFlags 0x%08lx\n",asi->dwFlags);
122 FIXME_(avifile)("\tdwCaps 0x%08lx\n",asi->dwCaps);
123 FIXME_(avifile)("\tname '%s'\n",debugstr_w(asi->szName));
125 istream->curframe = 0;
126 *avis = (PAVISTREAM)istream;
130 static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size) {
131 FIXME_(avifile)("(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,ckid,lpData,size);
132 /* FIXME: write data to file */
136 static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size) {
137 FIXME_(avifile)("(%p)->ReadData(0x%08lx,%p,%p)\n",iface,ckid,lpData,size);
138 /* FIXME: read at most size bytes from file */
142 static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface) {
143 FIXME_(avifile)("(%p)->EndRecord()\n",iface);
144 /* FIXME: end record? */
148 static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam) {
149 FIXME_(avifile)("(%p)->DeleteStream(0x%08lx,%ld)\n",iface,fccType,lParam);
150 /* FIXME: delete stream? */
154 struct ICOM_VTABLE(IAVIFile) iavift = {
155 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
156 IAVIFile_fnQueryInterface,
160 IAVIFile_fnGetStream,
161 IAVIFile_fnCreateStream,
162 IAVIFile_fnWriteData,
164 IAVIFile_fnEndRecord,
165 IAVIFile_fnDeleteStream
168 HRESULT WINAPI AVIFileOpenA(
169 PAVIFILE * ppfile,LPCSTR szFile,UINT uMode,LPCLSID lpHandler
175 if (HIWORD(lpHandler))
176 WINE_StringFromCLSID(lpHandler,buf);
178 sprintf(buf,"<clsid-0x%04lx>",(DWORD)lpHandler);
180 FIXME_(avifile)("(%p,%s,0x%08lx,%s),stub!\n",ppfile,szFile,(DWORD)uMode,buf);
181 iavi = (IAVIFileImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIFileImpl));
183 iavi->lpvtbl = &iavift;
184 *ppfile = (LPVOID)iavi;
188 static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj) {
189 ICOM_THIS(IAVIStreamImpl,iface);
192 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
193 TRACE_(relay)("(%p)->QueryInterface(%s,%p)\n",This,xrefiid,obj);
194 if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
195 !memcmp(&IID_IAVIStream,refiid,sizeof(IID_IAVIStream))
200 /* can return IGetFrame interface too */
201 return OLE_E_ENUM_NOMORE;
204 static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface) {
205 ICOM_THIS(IAVIStreamImpl,iface);
207 FIXME_(relay)("(%p)->AddRef()\n",iface);
208 return ++(This->ref);
211 static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) {
212 ICOM_THIS(IAVIStreamImpl,iface);
214 FIXME_(relay)("(%p)->Release()\n",iface);
215 if (!--(This->ref)) {
216 HeapFree(GetProcessHeap(),0,This);
222 HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2) {
223 FIXME_(avifile)("(%p)->Create(0x%08lx,0x%08lx)\n",iface,lParam1,lParam2);
227 HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size) {
228 FIXME_(avifile)("(%p)->Info(%p,%ld)\n",iface,psi,size);
232 LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags) {
233 FIXME_(avifile)("(%p)->FindSample(%ld,0x%08lx)\n",iface,pos,flags);
237 HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize) {
238 FIXME_(avifile)("(%p)->ReadFormat(%ld,%p,%p)\n",iface,pos,format,formatsize);
242 /*****************************************************************************
243 * [IAVIStream::SetFormat]
245 HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize) {
246 IAVIStreamImpl *as = (IAVIStreamImpl*)iface;
248 FIXME_(avifile)("(%p)->SetFormat(%ld,%p,%ld)\n",iface,pos,format,formatsize);
249 if (as->lpInputFormat) HeapFree(GetProcessHeap(),0,as->lpInputFormat);
250 as->inputformatsize = formatsize;
251 as->lpInputFormat = HeapAlloc(GetProcessHeap(),0,formatsize);
252 memcpy(as->lpInputFormat,format,formatsize);
253 if (as->iscompressing) {
255 /* Set up the Compressor part */
256 xsize = ICCompressGetFormatSize(as->hic,as->lpInputFormat);
257 as->lpCompressFormat = HeapAlloc(GetProcessHeap(),0,xsize);
258 ICCompressGetFormat(as->hic,as->lpInputFormat,as->lpCompressFormat);
259 ICCompressBegin(as->hic,as->lpInputFormat,as->lpCompressFormat);
260 as->compbufsize = ICCompressGetSize(as->hic,as->lpInputFormat,as->lpCompressFormat);
261 as->compbuffer = HeapAlloc(GetProcessHeap(),0,as->compbufsize);
263 /* Set up the Decompressor part (for prev frames?) */
264 xsize=ICDecompressGetFormatSize(as->hic,as->lpCompressFormat);
265 as->decompformat = HeapAlloc(GetProcessHeap(),0,xsize);
266 ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat);
267 as->decompbufsize=((LPBITMAPINFOHEADER)as->decompbuffer)->biSizeImage;
268 as->decompbuffer = HeapReAlloc(GetProcessHeap(),0,as->decompbuffer,as->decompbufsize);
269 memset(as->decompbuffer,0xff,as->decompbufsize);
270 assert(HeapValidate(GetProcessHeap(),0,NULL));
272 ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat);
273 ICDecompressBegin(as->hic,as->lpCompressFormat,as->decompformat);
274 as->lpPrev = as->lpPrevFormat = NULL;
279 HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
280 FIXME_(avifile)("(%p)->Read(%ld,%ld,%p,%ld,%p,%p)\n",iface,start,samples,buffer,buffersize,bytesread,samplesread);
284 HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
285 IAVIStreamImpl *as = (IAVIStreamImpl*)iface;
288 FIXME_(avifile)("(%p)->Write(%ld,%ld,%p,%ld,0x%08lx,%p,%p)\n",iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);
292 as->lpCompressFormat,
294 as->lpInputFormat,buffer,
296 as->curframe,0xffffff/*framesize*/,as->aco.dwQuality,
297 as->lpPrevFormat,as->lpPrev
301 flags, /* FIXME: check */
302 as->lpCompressFormat,
307 /* We now have a prev format for the next compress ... */
308 as->lpPrevFormat = as->decompformat;
309 as->lpPrev = as->decompbuffer;
313 HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples) {
314 FIXME_(avifile)("(%p)->Delete(%ld,%ld)\n",iface,start,samples);
318 HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread) {
319 FIXME_(avifile)("(%p)->ReadData(0x%08lx,%p,%p)\n",iface,fcc,lp,lpread);
323 HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size) {
324 FIXME_(avifile)("(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,fcc,lp,size);
328 HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen) {
329 FIXME_(avifile)("(%p)->SetInfo(%p,%ld)\n",iface,info,infolen);
333 struct ICOM_VTABLE(IAVIStream) iavist = {
334 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
335 IAVIStream_fnQueryInterface,
337 IAVIStream_fnRelease,
340 IAVIStream_fnFindSample,
341 IAVIStream_fnReadFormat,
342 IAVIStream_fnSetFormat,
346 IAVIStream_fnReadData,
347 IAVIStream_fnWriteData,
351 HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE iface,PAVISTREAM *ppavi,AVISTREAMINFOA * psi) {
354 /* Only the szName at the end is different */
355 memcpy(&psiw,psi,sizeof(*psi)-sizeof(psi->szName));
356 lstrcpynAtoW(psiw.szName,psi->szName,sizeof(psi->szName));
357 return iface->lpvtbl->fnCreateStream(iface,ppavi,&psiw);
360 HRESULT WINAPI AVIFileCreateStreamW(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) {
361 return iface->lpvtbl->fnCreateStream(iface,avis,asi);
365 HRESULT WINAPI AVIFileGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) {
366 return iface->lpvtbl->fnGetStream(iface,avis,fccType,lParam);
369 HRESULT WINAPI AVIFileInfoA(PAVIFILE iface,LPAVIFILEINFOA afi,LONG size) {
373 if (size < sizeof(AVIFILEINFOA))
374 return AVIERR_BADSIZE;
375 hres = iface->lpvtbl->fnInfo(iface,&afiw,sizeof(afiw));
376 memcpy(afi,&afiw,sizeof(*afi)-sizeof(afi->szFileType));
377 lstrcpynWtoA(afi->szFileType,afiw.szFileType,sizeof(afi->szFileType));
381 HRESULT WINAPI AVIStreamInfoW(PAVISTREAM iface,AVISTREAMINFOW *asi,LONG
383 return iface->lpvtbl->fnInfo(iface,asi,size);
386 HRESULT WINAPI AVIStreamInfoA(PAVISTREAM iface,AVISTREAMINFOA *asi,LONG
391 if (size<sizeof(AVISTREAMINFOA))
392 return AVIERR_BADSIZE;
393 hres = iface->lpvtbl->fnInfo(iface,&asiw,sizeof(asiw));
394 memcpy(asi,&asiw,sizeof(asiw)-sizeof(asiw.szName));
395 lstrcpynWtoA(asi->szName,asiw.szName,sizeof(asi->szName));
399 HRESULT WINAPI AVIFileInfoW(PAVIFILE iface,LPAVIFILEINFOW afi,LONG size) {
400 return iface->lpvtbl->fnInfo(iface,afi,size);
403 HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,PAVISTREAM ppsSource,AVICOMPRESSOPTIONS *aco,CLSID *pclsidHandler) {
406 FIXME_(avifile)("(%p,%p,%p,%p)\n",ppsCompressed,ppsSource,aco,pclsidHandler);
408 memcpy(fcc,&(aco->fccType),4);
409 FIXME_(avifile)("\tfccType: '%s'\n",fcc);
410 memcpy(fcc,&(aco->fccHandler),4);
411 FIXME_(avifile)("\tfccHandler: '%s'\n",fcc);
412 FIXME_(avifile)("\tdwFlags: 0x%08lx\n",aco->dwFlags);
414 /* we just create a duplicate for now */
415 ((IUnknown*)ppsSource)->lpvtbl->fnAddRef((IUnknown*)ppsSource);
416 *ppsCompressed = ppsSource;
417 as = (IAVIStreamImpl*)ppsSource;
419 /* this is where the fun begins. Open a compressor and prepare it. */
420 as->hic = ICOpen(aco->fccType,aco->fccHandler,ICMODE_COMPRESS);
422 /* May happen. for instance if the codec is not able to compress */
424 return AVIERR_UNSUPPORTED;
426 ICGetInfo(as->hic,&(as->icinfo),sizeof(ICINFO));
427 FIXME_(avifile)("Opened compressor: '%s' '%s'\n",debugstr_w(as->icinfo.szName),debugstr_w(as->icinfo.szDescription));
428 as->iscompressing = TRUE;
429 memcpy(&(as->aco),aco,sizeof(*aco));
430 if (as->icinfo.dwFlags & VIDCF_COMPRESSFRAMES) {
431 ICCOMPRESSFRAMES icf;
433 /* now what to fill in there ... Hmm */
434 memset(&icf,0,sizeof(icf));
435 icf.lDataRate = aco->dwBytesPerSecond;
436 icf.lQuality = aco->dwQuality;
437 icf.lKeyRate = aco->dwKeyFrameEvery;
439 icf.GetData = (LONG (*)(LPARAM,LONG,LPVOID,LONG)) 0xdead4242;
440 icf.PutData = (LONG (*)(LPARAM,LONG,LPVOID,LONG)) 0xdead4243;
441 ICSendMessage(as->hic,ICM_COMPRESS_FRAMES_INFO,(LPARAM)&icf,sizeof(icf));
446 HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG formatsize) {
447 return iface->lpvtbl->fnSetFormat(iface,pos,format,formatsize);
450 HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG *formatsize) {
451 return iface->lpvtbl->fnReadFormat(iface,pos,format,formatsize);
454 HRESULT WINAPI AVIStreamWrite(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
455 return iface->lpvtbl->fnWrite(iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);
458 HRESULT WINAPI AVIStreamRead(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
459 return iface->lpvtbl->fnRead(iface,start,samples,buffer,buffersize,bytesread,samplesread);
462 HRESULT WINAPI AVIStreamWriteData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG size) {
463 return iface->lpvtbl->fnWriteData(iface,fcc,lp,size);
466 HRESULT WINAPI AVIStreamReadData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG *lpread) {
467 return iface->lpvtbl->fnReadData(iface,fcc,lp,lpread);
470 LONG WINAPI AVIStreamStart(PAVISTREAM iface) {
473 iface->lpvtbl->fnInfo(iface,&si,sizeof(si));
477 LONG WINAPI AVIStreamLength(PAVISTREAM iface) {
481 ret = iface->lpvtbl->fnInfo(iface,&si,sizeof(si));
487 ULONG WINAPI AVIStreamRelease(PAVISTREAM iface) {
488 return ((LPUNKNOWN)iface)->lpvtbl->fnRelease((LPUNKNOWN)iface);
491 PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM iface,LPBITMAPINFOHEADER bmi) {
492 FIXME_(msvideo)("(%p)->(%p),stub!\n",iface,bmi);
496 LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg,LONG pos) {
497 return pg->lpvtbl->fnGetFrame(pg,pos);
500 HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg) {
501 if (pg) ((LPUNKNOWN)pg)->lpvtbl->fnRelease((LPUNKNOWN)pg);
505 ULONG WINAPI AVIFileRelease(PAVIFILE iface) {
506 return ((LPUNKNOWN)iface)->lpvtbl->fnRelease((LPUNKNOWN)iface);
509 void WINAPI AVIFileExit(void) {
510 FIXME_(avifile)("(), stub.\n");