2 * Implements IEnumMediaTypes and helper functions. (internal)
4 * hidenori@a2.ctktv.ne.jp
19 #include "debugtools.h"
20 DEFAULT_DEBUG_CHANNEL(quartz);
22 #include "quartz_private.h"
27 /****************************************************************************/
31 HRESULT QUARTZ_MediaType_Copy(
32 AM_MEDIA_TYPE* pmtDst,
33 const AM_MEDIA_TYPE* pmtSrc )
35 memcpy( &pmtDst->majortype, &pmtSrc->majortype, sizeof(GUID) );
36 memcpy( &pmtDst->subtype, &pmtSrc->subtype, sizeof(GUID) );
37 pmtDst->bFixedSizeSamples = pmtSrc->bFixedSizeSamples;
38 pmtDst->bTemporalCompression = pmtSrc->bTemporalCompression;
39 pmtDst->lSampleSize = pmtSrc->lSampleSize;
40 memcpy( &pmtDst->formattype, &pmtSrc->formattype, sizeof(GUID) );
42 pmtDst->cbFormat = pmtSrc->cbFormat;
43 pmtDst->pbFormat = NULL;
45 if ( pmtSrc->pbFormat != NULL && pmtSrc->cbFormat != 0 )
47 pmtDst->pbFormat = (BYTE*)CoTaskMemAlloc( pmtSrc->cbFormat );
48 if ( pmtDst->pbFormat == NULL )
50 CoTaskMemFree( pmtDst );
53 memcpy( pmtDst->pbFormat, pmtSrc->pbFormat, pmtSrc->cbFormat );
56 if ( pmtSrc->pUnk != NULL )
58 pmtDst->pUnk = pmtSrc->pUnk;
59 IUnknown_AddRef( pmtSrc->pUnk );
65 void QUARTZ_MediaType_Free(
68 if ( pmt->pUnk != NULL )
70 IUnknown_Release( pmt->pUnk );
73 if ( pmt->pbFormat != NULL )
75 CoTaskMemFree( pmt->pbFormat );
81 AM_MEDIA_TYPE* QUARTZ_MediaType_Duplicate(
82 const AM_MEDIA_TYPE* pmtSrc )
84 AM_MEDIA_TYPE* pmtDup;
86 pmtDup = (AM_MEDIA_TYPE*)CoTaskMemAlloc( sizeof(AM_MEDIA_TYPE) );
89 if ( QUARTZ_MediaType_Copy( pmtDup, pmtSrc ) != S_OK )
91 CoTaskMemFree( pmtDup );
98 void QUARTZ_MediaType_Destroy(
101 QUARTZ_MediaType_Free( pmt );
102 CoTaskMemFree( pmt );
105 void QUARTZ_MediaSubType_FromFourCC(
106 GUID* psubtype, DWORD dwFourCC )
108 memcpy( psubtype, &MEDIASUBTYPE_PCM, sizeof(GUID) );
109 psubtype->Data1 = dwFourCC;
112 BOOL QUARTZ_MediaSubType_IsFourCC(
113 const GUID* psubtype )
117 QUARTZ_MediaSubType_FromFourCC(
118 &guidTemp, psubtype->Data1 );
119 return IsEqualGUID( psubtype, &guidTemp );
122 HRESULT QUARTZ_MediaSubType_FromBitmap(
123 GUID* psubtype, const BITMAPINFOHEADER* pbi )
128 if ( (pbi->biCompression & 0xffff) != 0 )
131 if ( pbi->biWidth <= 0 || pbi->biHeight == 0 )
135 switch ( pbi->biCompression )
138 if ( pbi->biPlanes != 1 )
140 switch ( pbi->biBitCount )
143 memcpy( psubtype, &MEDIASUBTYPE_RGB1, sizeof(GUID) );
147 memcpy( psubtype, &MEDIASUBTYPE_RGB4, sizeof(GUID) );
151 memcpy( psubtype, &MEDIASUBTYPE_RGB8, sizeof(GUID) );
155 memcpy( psubtype, &MEDIASUBTYPE_RGB555, sizeof(GUID) );
159 memcpy( psubtype, &MEDIASUBTYPE_RGB24, sizeof(GUID) );
163 memcpy( psubtype, &MEDIASUBTYPE_RGB32, sizeof(GUID) );
169 if ( pbi->biPlanes == 1 && pbi->biHeight > 0 &&
170 pbi->biBitCount == 8 )
172 QUARTZ_MediaSubType_FromFourCC( psubtype, mmioFOURCC('M','R','L','E') );
177 if ( pbi->biPlanes == 1 && pbi->biHeight > 0 &&
178 pbi->biBitCount == 4 )
180 QUARTZ_MediaSubType_FromFourCC( psubtype, mmioFOURCC('M','R','L','E') );
185 if ( pbi->biPlanes != 1 )
187 pdwBitf = (DWORD*)( (BYTE*)pbi + sizeof(BITMAPINFOHEADER) );
188 switch ( pbi->biBitCount )
191 if ( pdwBitf[0] == 0x7c00 &&
192 pdwBitf[1] == 0x03e0 &&
193 pdwBitf[2] == 0x001f )
195 memcpy( psubtype, &MEDIASUBTYPE_RGB555, sizeof(GUID) );
198 if ( pdwBitf[0] == 0xf800 &&
199 pdwBitf[1] == 0x07e0 &&
200 pdwBitf[2] == 0x001f )
202 memcpy( psubtype, &MEDIASUBTYPE_RGB565, sizeof(GUID) );
207 if ( pdwBitf[0] == 0x00ff0000 &&
208 pdwBitf[1] == 0x0000ff00 &&
209 pdwBitf[2] == 0x000000ff )
211 memcpy( psubtype, &MEDIASUBTYPE_RGB32, sizeof(GUID) );
224 /****************************************************************************/
226 typedef struct IEnumMediaTypesImpl
228 ICOM_VFIELD(IEnumMediaTypes);
229 } IEnumMediaTypesImpl;
234 IEnumMediaTypesImpl enummtype;
235 struct QUARTZ_IFEntry IFEntries[1];
237 AM_MEDIA_TYPE* pTypes;
242 #define CEnumMediaTypes_THIS(iface,member) CEnumMediaTypes* This = ((CEnumMediaTypes*)(((char*)iface)-offsetof(CEnumMediaTypes,member)))
246 static HRESULT WINAPI
247 IEnumMediaTypes_fnQueryInterface(IEnumMediaTypes* iface,REFIID riid,void** ppobj)
249 CEnumMediaTypes_THIS(iface,enummtype);
251 TRACE("(%p)->()\n",This);
253 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
257 IEnumMediaTypes_fnAddRef(IEnumMediaTypes* iface)
259 CEnumMediaTypes_THIS(iface,enummtype);
261 TRACE("(%p)->()\n",This);
263 return IUnknown_AddRef(This->unk.punkControl);
267 IEnumMediaTypes_fnRelease(IEnumMediaTypes* iface)
269 CEnumMediaTypes_THIS(iface,enummtype);
271 TRACE("(%p)->()\n",This);
273 return IUnknown_Release(This->unk.punkControl);
276 static HRESULT WINAPI
277 IEnumMediaTypes_fnNext(IEnumMediaTypes* iface,ULONG cReq,AM_MEDIA_TYPE** ppmtype,ULONG* pcFetched)
279 CEnumMediaTypes_THIS(iface,enummtype);
283 TRACE("(%p)->(%lu,%p,%p)\n",This,cReq,ppmtype,pcFetched);
285 if ( pcFetched == NULL && cReq > 1 )
287 if ( ppmtype == NULL )
290 EnterCriticalSection( &This->cs );
296 if ( This->cCur >= This->cTypes )
301 ppmtype[ cFetched ] =
302 QUARTZ_MediaType_Duplicate( &This->pTypes[ This->cCur ] );
303 if ( ppmtype[ cFetched ] == NULL )
306 while ( cFetched > 0 )
309 QUARTZ_MediaType_Destroy( ppmtype[ cFetched ] );
320 LeaveCriticalSection( &This->cs );
322 if ( pcFetched != NULL )
323 *pcFetched = cFetched;
328 static HRESULT WINAPI
329 IEnumMediaTypes_fnSkip(IEnumMediaTypes* iface,ULONG cSkip)
331 CEnumMediaTypes_THIS(iface,enummtype);
334 TRACE("(%p)->()\n",This);
336 EnterCriticalSection( &This->cs );
341 if ( This->cCur >= This->cTypes )
350 LeaveCriticalSection( &This->cs );
355 static HRESULT WINAPI
356 IEnumMediaTypes_fnReset(IEnumMediaTypes* iface)
358 CEnumMediaTypes_THIS(iface,enummtype);
360 TRACE("(%p)->()\n",This);
362 EnterCriticalSection( &This->cs );
366 LeaveCriticalSection( &This->cs );
371 static HRESULT WINAPI
372 IEnumMediaTypes_fnClone(IEnumMediaTypes* iface,IEnumMediaTypes** ppobj)
374 CEnumMediaTypes_THIS(iface,enummtype);
377 TRACE("(%p)->()\n",This);
382 EnterCriticalSection( &This->cs );
384 hr = QUARTZ_CreateEnumMediaTypes(
386 This->pTypes, This->cTypes );
388 IEnumMediaTypes_Skip( *ppobj, This->cCur );
390 LeaveCriticalSection( &This->cs );
396 static ICOM_VTABLE(IEnumMediaTypes) ienummtype =
398 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
399 /* IUnknown fields */
400 IEnumMediaTypes_fnQueryInterface,
401 IEnumMediaTypes_fnAddRef,
402 IEnumMediaTypes_fnRelease,
403 /* IEnumMediaTypes fields */
404 IEnumMediaTypes_fnNext,
405 IEnumMediaTypes_fnSkip,
406 IEnumMediaTypes_fnReset,
407 IEnumMediaTypes_fnClone,
411 /* can I use offsetof safely? - FIXME? */
412 static QUARTZ_IFEntry IFEntries[] =
414 { &IID_IEnumMediaTypes, offsetof(CEnumMediaTypes,enummtype)-offsetof(CEnumMediaTypes,unk) },
418 void QUARTZ_DestroyEnumMediaTypes(IUnknown* punk)
420 CEnumMediaTypes_THIS(punk,unk);
423 if ( This->pTypes != NULL )
425 for ( i = 0; i < This->cTypes; i++ )
426 QUARTZ_MediaType_Free( &This->pTypes[i] );
427 QUARTZ_FreeMem( This->pTypes );
430 DeleteCriticalSection( &This->cs );
433 HRESULT QUARTZ_CreateEnumMediaTypes(
434 IEnumMediaTypes** ppobj,
435 const AM_MEDIA_TYPE* pTypes, ULONG cTypes )
437 CEnumMediaTypes* penum;
438 AM_MEDIA_TYPE* pTypesDup = NULL;
442 TRACE("(%p,%p,%lu)\n",ppobj,pTypes,cTypes);
446 pTypesDup = (AM_MEDIA_TYPE*)QUARTZ_AllocMem(
447 sizeof( AM_MEDIA_TYPE ) * cTypes );
448 if ( pTypesDup == NULL )
449 return E_OUTOFMEMORY;
454 hr = QUARTZ_MediaType_Copy( &pTypesDup[i], &pTypes[i] );
460 QUARTZ_MediaType_Free( &pTypesDup[i] );
462 QUARTZ_FreeMem( pTypesDup );
470 penum = (CEnumMediaTypes*)QUARTZ_AllocObj( sizeof(CEnumMediaTypes) );
473 return E_OUTOFMEMORY;
475 penum->pTypes = pTypesDup;
476 penum->cTypes = cTypes;
479 QUARTZ_IUnkInit( &penum->unk, NULL );
480 ICOM_VTBL(&penum->enummtype) = &ienummtype;
482 penum->unk.pEntries = IFEntries;
483 penum->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
484 penum->unk.pOnFinalRelease = QUARTZ_DestroyEnumMediaTypes;
486 InitializeCriticalSection( &penum->cs );
488 *ppobj = (IEnumMediaTypes*)(&penum->enummtype);