2 * Copyright 2001 Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
14 #include "debugtools.h"
15 #include "avifile_private.h"
17 DEFAULT_DEBUG_CHANNEL(avifile);
19 static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj);
20 static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface);
21 static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface);
22 static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2);
23 static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size);
24 static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags);
25 static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize);
26 static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize);
27 static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread);
28 static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten);
29 static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples);
30 static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread);
31 static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size);
32 static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen);
35 struct ICOM_VTABLE(IAVIStream) iavist = {
36 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
37 IAVIStream_fnQueryInterface,
42 IAVIStream_fnFindSample,
43 IAVIStream_fnReadFormat,
44 IAVIStream_fnSetFormat,
48 IAVIStream_fnReadData,
49 IAVIStream_fnWriteData,
55 typedef struct IAVIStreamImpl
57 ICOM_VFIELD(IAVIStream);
60 /* IAVIStream stuff */
62 WINE_AVISTREAM_DATA* pData;
65 static HRESULT IAVIStream_Construct( IAVIStreamImpl* This );
66 static void IAVIStream_Destruct( IAVIStreamImpl* This );
68 HRESULT AVIFILE_CreateIAVIStream(void** ppobj)
74 This = (IAVIStreamImpl*)HeapAlloc(AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
75 sizeof(IAVIStreamImpl));
77 ICOM_VTBL(This) = &iavist;
78 hr = IAVIStream_Construct( This );
81 IAVIStream_Destruct( This );
85 *ppobj = (LPVOID)This;
91 /****************************************************************************
95 static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj) {
96 ICOM_THIS(IAVIStreamImpl,iface);
98 TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
99 if ( IsEqualGUID(&IID_IUnknown,refiid) ||
100 IsEqualGUID(&IID_IAVIStream,refiid) )
102 IAVIStream_AddRef(iface);
106 /* can return IGetFrame interface too */
108 return OLE_E_ENUM_NOMORE;
111 static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface) {
112 ICOM_THIS(IAVIStreamImpl,iface);
114 TRACE("(%p)->AddRef()\n",iface);
115 return ++(This->ref);
118 static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) {
119 ICOM_THIS(IAVIStreamImpl,iface);
121 TRACE("(%p)->Release()\n",iface);
122 if ((--(This->ref)) > 0 )
124 IAVIStream_Destruct(This);
126 HeapFree(AVIFILE_data.hHeap,0,iface);
130 /****************************************************************************
131 * IAVIStream interface
134 static HRESULT IAVIStream_Construct( IAVIStreamImpl* This )
139 AVIFILE_data.dwClassObjRef ++;
144 static void IAVIStream_Destruct( IAVIStreamImpl* This )
146 AVIFILE_data.dwClassObjRef --;
149 static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2)
151 ICOM_THIS(IAVIStreamImpl,iface);
153 FIXME("(%p)->Create(%ld,%ld)\n",iface,lParam1,lParam2);
155 This->paf = (IAVIFile*)lParam1;
156 This->pData = (WINE_AVISTREAM_DATA*)lParam2;
161 static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size)
163 ICOM_THIS(IAVIStreamImpl,iface);
166 FIXME("(%p)->Info(%p,%ld)\n",iface,psi,size);
167 if ( This->pData == NULL )
170 memset( &siw, 0, sizeof(AVISTREAMINFOW) );
171 siw.fccType = This->pData->pstrhdr->fccType;
172 siw.fccHandler = This->pData->pstrhdr->fccHandler;
173 siw.dwFlags = This->pData->pstrhdr->dwFlags;
174 siw.dwCaps = 0; /* FIXME */
175 siw.wPriority = This->pData->pstrhdr->wPriority;
176 siw.wLanguage = This->pData->pstrhdr->wLanguage;
177 siw.dwScale = This->pData->pstrhdr->dwScale;
178 siw.dwRate = This->pData->pstrhdr->dwRate;
179 siw.dwStart = This->pData->pstrhdr->dwStart;
180 siw.dwLength = This->pData->pstrhdr->dwLength;
181 siw.dwInitialFrames = This->pData->pstrhdr->dwInitialFrames;
182 siw.dwSuggestedBufferSize = This->pData->pstrhdr->dwSuggestedBufferSize;
183 siw.dwQuality = This->pData->pstrhdr->dwQuality;
184 siw.dwSampleSize = This->pData->pstrhdr->dwSampleSize;
185 siw.rcFrame.left = This->pData->pstrhdr->rcFrame.left;
186 siw.rcFrame.top = This->pData->pstrhdr->rcFrame.top;
187 siw.rcFrame.right = This->pData->pstrhdr->rcFrame.right;
188 siw.rcFrame.bottom = This->pData->pstrhdr->rcFrame.bottom;
189 siw.dwEditCount = 0; /* FIXME */
190 siw.dwFormatChangeCount = 0; /* FIXME */
193 if ( size > sizeof(AVISTREAMINFOW) )
194 size = sizeof(AVISTREAMINFOW);
195 memcpy( psi, &siw, size );
200 static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags)
202 ICOM_THIS(IAVIStreamImpl,iface);
204 AVIINDEXENTRY* pIndexEntry;
205 DWORD dwCountOfIndexEntry;
206 LONG lCur, lAdd, lEnd;
208 FIXME("(%p)->FindSample(%ld,0x%08lx)\n",This,pos,flags);
210 hr = AVIFILE_IAVIFile_GetIndexTable(
211 This->paf, This->pData->dwStreamIndex,
212 &pIndexEntry, &dwCountOfIndexEntry );
216 if ( flags & (~(FIND_DIR|FIND_TYPE|FIND_RET)) )
218 FIXME( "unknown flag %08lx\n", flags );
222 switch ( flags & FIND_DIR )
227 lEnd = dwCountOfIndexEntry;
228 if ( lCur > dwCountOfIndexEntry )
233 if ( lCur > dwCountOfIndexEntry )
234 lCur = dwCountOfIndexEntry;
238 case FIND_FROM_START:
241 lEnd = dwCountOfIndexEntry;
244 FIXME( "unknown direction flag %08lx\n", (flags & FIND_DIR) );
248 switch ( flags & FIND_TYPE )
253 if ( pIndexEntry[lCur].dwFlags & AVIIF_KEYFRAME )
263 if ( !(pIndexEntry[lCur].dwFlags & AVIIF_NOTIME) )
271 FIXME( "FIND_FORMAT is not implemented.\n" );
274 FIXME( "unknown type flag %08lx\n", (flags & FIND_TYPE) );
278 switch ( flags & FIND_RET )
283 FIXME( "FIND_LENGTH is not implemented.\n" );
286 return pIndexEntry[lCur].dwChunkOffset;
288 return pIndexEntry[lCur].dwChunkLength;
290 FIXME( "FIND_INDEX is not implemented.\n" );
293 FIXME( "unknown return type flag %08lx\n", (flags & FIND_RET) );
300 static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize) {
301 ICOM_THIS(IAVIStreamImpl,iface);
303 TRACE("(%p)->ReadFormat(%ld,%p,%p)\n",This,pos,format,formatsize);
304 if ( This->pData == NULL )
307 /* FIXME - check pos. */
308 if ( format == NULL )
310 *formatsize = This->pData->dwFmtLen;
313 if ( (*formatsize) < This->pData->dwFmtLen )
314 return AVIERR_BUFFERTOOSMALL;
316 memcpy( format, This->pData->pbFmt, This->pData->dwFmtLen );
317 *formatsize = This->pData->dwFmtLen;
322 static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize) {
323 ICOM_THIS(IAVIStreamImpl,iface);
325 FIXME("(%p)->SetFormat(%ld,%p,%ld)\n",This,pos,format,formatsize);
329 static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
330 ICOM_THIS(IAVIStreamImpl,iface);
332 AVIINDEXENTRY* pIndexEntry;
333 DWORD dwCountOfIndexEntry;
336 FIXME("(%p)->Read(%ld,%ld,%p,%ld,%p,%p)\n",This,start,samples,buffer,buffersize,bytesread,samplesread);
341 hr = AVIFILE_IAVIFile_GetIndexTable(
342 This->paf, This->pData->dwStreamIndex,
343 &pIndexEntry, &dwCountOfIndexEntry );
348 if ( start >= dwCountOfIndexEntry || samples <= 0 )
350 FIXME("start %ld,samples %ld,total %ld\n",start,samples,dwCountOfIndexEntry);
354 /* FIXME - is this data valid??? */
355 dwFrameLength = pIndexEntry[start].dwChunkLength + sizeof(DWORD)*2;
357 if ( buffer == NULL )
359 *bytesread = dwFrameLength;
363 if ( buffersize < dwFrameLength )
365 FIXME( "buffer is too small!\n" );
366 return AVIERR_BUFFERTOOSMALL;
369 hr = AVIFILE_IAVIFile_ReadMovieData(
371 pIndexEntry[start].dwChunkOffset,
372 dwFrameLength, buffer );
375 FIXME( "ReadMovieData failed!\n");
378 *bytesread = dwFrameLength;
384 static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
385 ICOM_THIS(IAVIStreamImpl,iface);
388 FIXME("(%p)->Write(%ld,%ld,%p,%ld,0x%08lx,%p,%p)\n",This,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);
392 static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples) {
393 ICOM_THIS(IAVIStreamImpl,iface);
395 FIXME("(%p)->Delete(%ld,%ld)\n",This,start,samples);
398 static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread) {
399 ICOM_THIS(IAVIStreamImpl,iface);
401 FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",This,fcc,lp,lpread);
405 static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size) {
406 ICOM_THIS(IAVIStreamImpl,iface);
408 FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",This,fcc,lp,size);
412 static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen) {
413 ICOM_THIS(IAVIStreamImpl,iface);
415 FIXME("(%p)->SetInfo(%p,%ld)\n",This,info,infolen);