2 * Implements IMediaSample2 for CMemMediaSample.
4 * hidenori@a2.ctktv.ne.jp
17 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(quartz);
20 #include "quartz_private.h"
25 /***************************************************************************
31 HRESULT QUARTZ_IMediaSample_GetProperties(
32 IMediaSample* pSample,
33 AM_SAMPLE2_PROPERTIES* pProp )
36 AM_SAMPLE2_PROPERTIES prop;
37 IMediaSample2* pSample2 = NULL;
39 ZeroMemory( &prop, sizeof(AM_SAMPLE2_PROPERTIES) );
42 hr = IMediaSample_QueryInterface( pSample, &IID_IMediaSample2, (void**)&pSample2 );
45 hr = IMediaSample2_GetProperties(pSample2,sizeof(AM_SAMPLE2_PROPERTIES),&prop);
46 IMediaSample2_Release(pSample2);
49 memcpy( pProp, &prop, sizeof(AM_SAMPLE2_PROPERTIES) );
51 QUARTZ_MediaType_Duplicate( &prop.pMediaType );
58 pProp->cbData = sizeof(AM_SAMPLE2_PROPERTIES);
59 pProp->dwTypeSpecificFlags = 0;
60 pProp->dwSampleFlags = 0;
61 if ( IMediaSample_IsSyncPoint(pSample) == S_OK )
62 pProp->dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
63 if ( IMediaSample_IsPreroll(pSample) == S_OK )
64 pProp->dwSampleFlags |= AM_SAMPLE_PREROLL;
65 if ( IMediaSample_IsDiscontinuity(pSample) == S_OK )
66 pProp->dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
67 pProp->lActual = (LONG)IMediaSample_GetActualDataLength(pSample);
68 if ( IMediaSample_GetTime(pSample,&pProp->tStart,&pProp->tStop) == S_OK )
69 pProp->dwSampleFlags |= AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID;
70 pProp->dwStreamId = 0;
71 if ( IMediaSample_GetMediaType(pSample,&(pProp->pMediaType)) == S_OK )
72 pProp->dwSampleFlags |= AM_SAMPLE_TYPECHANGED;
73 IMediaSample_GetPointer(pSample,&(pProp->pbBuffer));
74 pProp->cbBuffer = (LONG)IMediaSample_GetSize(pSample);
79 HRESULT QUARTZ_IMediaSample_SetProperties(
80 IMediaSample* pSample,
81 const AM_SAMPLE2_PROPERTIES* pProp )
84 AM_SAMPLE2_PROPERTIES prop;
85 IMediaSample2* pSample2 = NULL;
87 memcpy( &prop, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
88 prop.cbData = sizeof(AM_SAMPLE2_PROPERTIES);
93 hr = IMediaSample_QueryInterface( pSample, &IID_IMediaSample2, (void**)&pSample2 );
96 hr = IMediaSample2_SetProperties(pSample2,sizeof(AM_SAMPLE2_PROPERTIES),&prop);
97 IMediaSample2_Release(pSample2);
106 hr = IMediaSample_SetSyncPoint(pSample,
107 (prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT) ? TRUE : FALSE);
109 hr = IMediaSample_SetPreroll(pSample,
110 (prop.dwSampleFlags & AM_SAMPLE_PREROLL) ? TRUE : FALSE);
112 hr = IMediaSample_SetDiscontinuity(pSample,
113 (prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) ? TRUE : FALSE);
116 TRACE("length = %ld/%ld\n",prop.lActual,pProp->cbBuffer);
117 hr = IMediaSample_SetActualDataLength(pSample,prop.lActual);
121 if ( ( prop.dwSampleFlags & AM_SAMPLE_TIMEVALID) &&
122 ( prop.dwSampleFlags & AM_SAMPLE_STOPVALID) )
123 hr = IMediaSample_SetTime(pSample,&prop.tStart,&prop.tStop);
125 hr = IMediaSample_SetTime(pSample,NULL,NULL);
128 hr = IMediaSample_SetMediaType(pSample,
129 (prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) ?
130 prop.pMediaType : NULL);
135 HRESULT QUARTZ_IMediaSample_Copy(
136 IMediaSample* pDstSample,
137 IMediaSample* pSrcSample,
141 AM_SAMPLE2_PROPERTIES prop;
142 BYTE* pDataSrc = NULL;
143 BYTE* pDataDst = NULL;
145 hr = QUARTZ_IMediaSample_GetProperties( pSrcSample, &prop );
150 hr = QUARTZ_IMediaSample_SetProperties( pDstSample, &prop );
151 if ( prop.pMediaType != NULL )
152 QUARTZ_MediaType_Destroy( prop.pMediaType );
154 if ( SUCCEEDED(hr) && bCopyData )
156 hr = IMediaSample_GetPointer(pSrcSample,&pDataSrc);
158 hr = IMediaSample_GetPointer(pDstSample,&pDataDst);
161 if ( pDataSrc != NULL && pDataDst != NULL )
162 memcpy( pDataDst, pDataSrc, prop.lActual );
171 /***************************************************************************
173 * CMemMediaSample::IMediaSample2
177 static HRESULT WINAPI
178 IMediaSample2_fnQueryInterface(IMediaSample2* iface,REFIID riid,void** ppobj)
180 ICOM_THIS(CMemMediaSample,iface);
182 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
187 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
188 IsEqualGUID( riid, &IID_IMediaSample ) ||
189 IsEqualGUID( riid, &IID_IMediaSample2 ) )
192 IMediaSample2_AddRef(iface);
196 return E_NOINTERFACE;
200 IMediaSample2_fnAddRef(IMediaSample2* iface)
202 ICOM_THIS(CMemMediaSample,iface);
204 TRACE("(%p)->()\n",This);
206 return InterlockedExchangeAdd(&(This->ref),1) + 1;
210 IMediaSample2_fnRelease(IMediaSample2* iface)
212 ICOM_THIS(CMemMediaSample,iface);
215 TRACE("(%p)->()\n",This);
217 if ( This->ref == 0 )
219 ERR("(%p) - released sample!\n",This);
223 ref = InterlockedExchangeAdd(&(This->ref),-1) - 1;
227 /* this class would be reused.. */
228 if ( This->prop.pMediaType != NULL )
230 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
231 This->prop.pMediaType = NULL;
233 This->prop.dwTypeSpecificFlags = 0;
234 This->prop.dwSampleFlags = 0;
235 This->prop.lActual = This->prop.cbBuffer;
237 IMemAllocator_ReleaseBuffer(This->pOwner,(IMediaSample*)iface);
244 static HRESULT WINAPI
245 IMediaSample2_fnGetPointer(IMediaSample2* iface,BYTE** ppData)
247 ICOM_THIS(CMemMediaSample,iface);
249 TRACE("(%p)->()\n",This);
251 if ( This->ref == 0 )
253 ERR("(%p) - released sample!\n",This);
257 if ( ppData == NULL )
260 *ppData = This->prop.pbBuffer;
265 IMediaSample2_fnGetSize(IMediaSample2* iface)
267 ICOM_THIS(CMemMediaSample,iface);
269 TRACE("(%p)->()\n",This);
271 return This->prop.cbBuffer;
274 static HRESULT WINAPI
275 IMediaSample2_fnGetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
277 ICOM_THIS(CMemMediaSample,iface);
279 TRACE("(%p)->(%p,%p)\n",This,prtStart,prtEnd);
281 if ( This->ref == 0 )
283 ERR("(%p) - released sample!\n",This);
287 if ( prtStart == NULL || prtEnd == NULL )
290 if ( ( This->prop.dwSampleFlags & AM_SAMPLE_TIMEVALID ) &&
291 ( This->prop.dwSampleFlags & AM_SAMPLE_STOPVALID ) )
293 *prtStart = This->prop.tStart;
294 *prtEnd = This->prop.tStop;
298 return VFW_E_MEDIA_TIME_NOT_SET;
301 static HRESULT WINAPI
302 IMediaSample2_fnSetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
304 ICOM_THIS(CMemMediaSample,iface);
306 TRACE("(%p)->(%p,%p) stub!\n",This,prtStart,prtEnd);
308 This->prop.dwSampleFlags &= ~(AM_SAMPLE_TIMEVALID|AM_SAMPLE_STOPVALID);
309 if ( prtStart != NULL )
311 This->prop.dwSampleFlags |= AM_SAMPLE_TIMEVALID;
312 This->prop.tStart = *prtStart;
314 if ( prtEnd != NULL )
316 This->prop.dwSampleFlags |= AM_SAMPLE_STOPVALID;
317 This->prop.tStop = *prtEnd;
323 static HRESULT WINAPI
324 IMediaSample2_fnIsSyncPoint(IMediaSample2* iface)
326 ICOM_THIS(CMemMediaSample,iface);
328 TRACE("(%p)->()\n",This);
330 return ( This->prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT ) ?
334 static HRESULT WINAPI
335 IMediaSample2_fnSetSyncPoint(IMediaSample2* iface,BOOL bSync)
337 ICOM_THIS(CMemMediaSample,iface);
339 TRACE("(%p)->(%d)\n",This,bSync);
342 This->prop.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
344 This->prop.dwSampleFlags &= ~AM_SAMPLE_SPLICEPOINT;
349 static HRESULT WINAPI
350 IMediaSample2_fnIsPreroll(IMediaSample2* iface)
352 ICOM_THIS(CMemMediaSample,iface);
354 TRACE("(%p)->()\n",This);
356 return ( This->prop.dwSampleFlags & AM_SAMPLE_PREROLL ) ?
360 static HRESULT WINAPI
361 IMediaSample2_fnSetPreroll(IMediaSample2* iface,BOOL bPreroll)
363 ICOM_THIS(CMemMediaSample,iface);
365 TRACE("(%p)->(%d)\n",This,bPreroll);
368 This->prop.dwSampleFlags |= AM_SAMPLE_PREROLL;
370 This->prop.dwSampleFlags &= ~AM_SAMPLE_PREROLL;
376 IMediaSample2_fnGetActualDataLength(IMediaSample2* iface)
378 ICOM_THIS(CMemMediaSample,iface);
380 TRACE("(%p)->()\n",This);
382 return This->prop.lActual;
385 static HRESULT WINAPI
386 IMediaSample2_fnSetActualDataLength(IMediaSample2* iface,long lLength)
388 ICOM_THIS(CMemMediaSample,iface);
390 TRACE("(%p)->(%ld)\n",This,lLength);
392 if ( This->prop.cbBuffer < lLength )
395 This->prop.lActual = lLength;
399 static HRESULT WINAPI
400 IMediaSample2_fnGetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE** ppmt)
402 ICOM_THIS(CMemMediaSample,iface);
404 TRACE("(%p)->(%p)\n",This,ppmt);
409 if ( !(This->prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) )
412 *ppmt = QUARTZ_MediaType_Duplicate( This->prop.pMediaType );
414 return E_OUTOFMEMORY;
419 static HRESULT WINAPI
420 IMediaSample2_fnSetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE* pmt)
422 ICOM_THIS(CMemMediaSample,iface);
423 AM_MEDIA_TYPE* pmtDup;
425 TRACE("(%p)->(%p)\n",This,pmt);
430 if ( This->prop.pMediaType != NULL )
432 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
433 This->prop.pMediaType = NULL;
435 This->prop.dwSampleFlags &= ~AM_SAMPLE_TYPECHANGED;
439 pmtDup = QUARTZ_MediaType_Duplicate( pmt );
440 if ( pmtDup == NULL )
441 return E_OUTOFMEMORY;
443 if ( This->prop.pMediaType != NULL )
444 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
445 This->prop.dwSampleFlags |= AM_SAMPLE_TYPECHANGED;
446 This->prop.pMediaType = pmtDup;
451 static HRESULT WINAPI
452 IMediaSample2_fnIsDiscontinuity(IMediaSample2* iface)
454 ICOM_THIS(CMemMediaSample,iface);
456 TRACE("(%p)->()\n",This);
458 return ( This->prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY ) ?
462 static HRESULT WINAPI
463 IMediaSample2_fnSetDiscontinuity(IMediaSample2* iface,BOOL bDiscontinuity)
465 ICOM_THIS(CMemMediaSample,iface);
467 TRACE("(%p)->(%d)\n",This,bDiscontinuity);
469 if ( bDiscontinuity )
470 This->prop.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
472 This->prop.dwSampleFlags &= ~AM_SAMPLE_DATADISCONTINUITY;
477 static HRESULT WINAPI
478 IMediaSample2_fnGetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
480 ICOM_THIS(CMemMediaSample,iface);
482 TRACE("(%p)->(%p,%p)\n",This,pTimeStart,pTimeEnd);
484 if ( pTimeStart == NULL || pTimeEnd == NULL )
487 if ( !This->fMediaTimeIsValid )
488 return VFW_E_MEDIA_TIME_NOT_SET;
490 *pTimeStart = This->llMediaTimeStart;
491 *pTimeEnd = This->llMediaTimeEnd;
498 static HRESULT WINAPI
499 IMediaSample2_fnSetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
501 ICOM_THIS(CMemMediaSample,iface);
503 TRACE("(%p)->()\n",This);
504 if ( pTimeStart == NULL || pTimeEnd == NULL )
506 This->fMediaTimeIsValid = FALSE;
510 This->fMediaTimeIsValid = TRUE;
511 This->llMediaTimeStart = *pTimeStart;
512 This->llMediaTimeEnd = *pTimeEnd;
519 static HRESULT WINAPI
520 IMediaSample2_fnGetProperties(IMediaSample2* iface,DWORD cbProp,BYTE* pbProp)
522 ICOM_THIS(CMemMediaSample,iface);
524 TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
526 if ( cbProp < 0 || cbProp > sizeof(AM_SAMPLE2_PROPERTIES) )
528 memcpy( pbProp, &This->prop, cbProp );
533 static HRESULT WINAPI
534 IMediaSample2_fnSetProperties(IMediaSample2* iface,DWORD cbProp,const BYTE* pbProp)
536 ICOM_THIS(CMemMediaSample,iface);
537 const AM_SAMPLE2_PROPERTIES* pProp;
538 AM_SAMPLE2_PROPERTIES propNew;
539 AM_MEDIA_TYPE* pmtDup = NULL;
540 HRESULT hr = E_INVALIDARG;
542 TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
544 if ( pbProp == NULL )
546 pProp = (const AM_SAMPLE2_PROPERTIES*)pbProp;
547 if ( cbProp != sizeof(AM_SAMPLE2_PROPERTIES) )
550 CopyMemory( &propNew, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
551 if ( propNew.cbData != sizeof(AM_SAMPLE2_PROPERTIES) )
554 if ( This->prop.cbBuffer < propNew.lActual )
557 if ( propNew.dwSampleFlags & AM_SAMPLE_TYPECHANGED )
559 pmtDup = QUARTZ_MediaType_Duplicate( propNew.pMediaType );
560 if ( pmtDup == NULL )
567 if ( propNew.pbBuffer != NULL && propNew.pbBuffer != This->prop.pbBuffer )
569 if ( propNew.cbBuffer != 0 && propNew.cbBuffer != This->prop.cbBuffer )
572 if ( This->prop.pMediaType != NULL )
573 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
574 CopyMemory( &This->prop, &propNew, sizeof(AM_SAMPLE2_PROPERTIES) );
575 This->prop.pMediaType = pmtDup;
580 if ( pmtDup != NULL )
581 QUARTZ_MediaType_Destroy( pmtDup );
587 static ICOM_VTABLE(IMediaSample2) imediasample2 =
589 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
590 /* IUnknown fields */
591 IMediaSample2_fnQueryInterface,
592 IMediaSample2_fnAddRef,
593 IMediaSample2_fnRelease,
594 /* IMediaSample fields */
595 IMediaSample2_fnGetPointer,
596 IMediaSample2_fnGetSize,
597 IMediaSample2_fnGetTime,
598 IMediaSample2_fnSetTime,
599 IMediaSample2_fnIsSyncPoint,
600 IMediaSample2_fnSetSyncPoint,
601 IMediaSample2_fnIsPreroll,
602 IMediaSample2_fnSetPreroll,
603 IMediaSample2_fnGetActualDataLength,
604 IMediaSample2_fnSetActualDataLength,
605 IMediaSample2_fnGetMediaType,
606 IMediaSample2_fnSetMediaType,
607 IMediaSample2_fnIsDiscontinuity,
608 IMediaSample2_fnSetDiscontinuity,
609 IMediaSample2_fnGetMediaTime,
610 IMediaSample2_fnSetMediaTime,
611 /* IMediaSample2 fields */
612 IMediaSample2_fnGetProperties,
613 IMediaSample2_fnSetProperties,
617 /***************************************************************************
619 * new/delete for CMemMediaSample
623 HRESULT QUARTZ_CreateMemMediaSample(
624 BYTE* pbData, DWORD dwDataLength,
625 IMemAllocator* pOwner,
626 CMemMediaSample** ppSample )
628 CMemMediaSample* pms;
630 TRACE("(%p,%08lx,%p,%p)\n",pbData,dwDataLength,pOwner,ppSample);
631 pms = (CMemMediaSample*)QUARTZ_AllocObj( sizeof(CMemMediaSample) );
633 return E_OUTOFMEMORY;
635 ICOM_VTBL(pms) = &imediasample2;
637 pms->pOwner = pOwner;
638 pms->fMediaTimeIsValid = FALSE;
639 pms->llMediaTimeStart = 0;
640 pms->llMediaTimeEnd = 0;
641 ZeroMemory( &(pms->prop), sizeof(pms->prop) );
642 pms->prop.cbData = sizeof(pms->prop);
643 pms->prop.dwTypeSpecificFlags = 0;
644 pms->prop.dwSampleFlags = 0;
645 pms->prop.pbBuffer = pbData;
646 pms->prop.cbBuffer = (LONG)dwDataLength;
647 pms->prop.lActual = (LONG)dwDataLength;
654 void QUARTZ_DestroyMemMediaSample(
655 CMemMediaSample* pSample )
657 TRACE("(%p)\n",pSample);
659 QUARTZ_FreeObj( pSample );