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);
115 hr = IMediaSample_SetActualDataLength(pSample,prop.lActual);
118 if ( ( prop.dwSampleFlags & AM_SAMPLE_TIMEVALID) &&
119 ( prop.dwSampleFlags & AM_SAMPLE_STOPVALID) )
120 hr = IMediaSample_SetTime(pSample,&prop.tStart,&prop.tStop);
122 hr = IMediaSample_SetTime(pSample,NULL,NULL);
125 hr = IMediaSample_SetMediaType(pSample,
126 (prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) ?
127 prop.pMediaType : NULL);
132 HRESULT QUARTZ_IMediaSample_Copy(
133 IMediaSample* pDstSample,
134 IMediaSample* pSrcSample,
138 AM_SAMPLE2_PROPERTIES prop;
139 BYTE* pDataSrc = NULL;
140 BYTE* pDataDst = NULL;
142 hr = QUARTZ_IMediaSample_GetProperties( pSrcSample, &prop );
145 hr = QUARTZ_IMediaSample_SetProperties( pDstSample, &prop );
146 if ( prop.pMediaType != NULL )
147 QUARTZ_MediaType_Destroy( prop.pMediaType );
149 if ( SUCCEEDED(hr) && bCopyData )
151 hr = IMediaSample_GetPointer(pSrcSample,&pDataSrc);
153 hr = IMediaSample_GetPointer(pDstSample,&pDataDst);
156 if ( pDataSrc != NULL && pDataDst != NULL )
157 memcpy( pDataDst, pDataSrc, prop.lActual );
166 /***************************************************************************
168 * CMemMediaSample::IMediaSample2
172 static HRESULT WINAPI
173 IMediaSample2_fnQueryInterface(IMediaSample2* iface,REFIID riid,void** ppobj)
175 ICOM_THIS(CMemMediaSample,iface);
177 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
182 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
183 IsEqualGUID( riid, &IID_IMediaSample ) ||
184 IsEqualGUID( riid, &IID_IMediaSample2 ) )
187 IMediaSample2_AddRef(iface);
191 return E_NOINTERFACE;
195 IMediaSample2_fnAddRef(IMediaSample2* iface)
197 ICOM_THIS(CMemMediaSample,iface);
199 TRACE("(%p)->()\n",This);
201 return InterlockedExchangeAdd(&(This->ref),1) + 1;
205 IMediaSample2_fnRelease(IMediaSample2* iface)
207 ICOM_THIS(CMemMediaSample,iface);
210 TRACE("(%p)->()\n",This);
212 if ( This->ref == 0 )
214 ERR("(%p) - released sample!\n",This);
218 ref = InterlockedExchangeAdd(&(This->ref),-1) - 1;
222 /* this class would be reused.. */
223 if ( This->prop.pMediaType != NULL )
225 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
226 This->prop.pMediaType = NULL;
228 This->prop.dwTypeSpecificFlags = 0;
229 This->prop.dwSampleFlags = 0;
230 This->prop.lActual = This->prop.cbBuffer;
232 IMemAllocator_ReleaseBuffer(This->pOwner,(IMediaSample*)iface);
239 static HRESULT WINAPI
240 IMediaSample2_fnGetPointer(IMediaSample2* iface,BYTE** ppData)
242 ICOM_THIS(CMemMediaSample,iface);
244 TRACE("(%p)->()\n",This);
246 if ( This->ref == 0 )
248 ERR("(%p) - released sample!\n",This);
252 if ( ppData == NULL )
255 *ppData = This->prop.pbBuffer;
260 IMediaSample2_fnGetSize(IMediaSample2* iface)
262 ICOM_THIS(CMemMediaSample,iface);
264 TRACE("(%p)->()\n",This);
266 return This->prop.cbBuffer;
269 static HRESULT WINAPI
270 IMediaSample2_fnGetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
272 ICOM_THIS(CMemMediaSample,iface);
274 TRACE("(%p)->(%p,%p)\n",This,prtStart,prtEnd);
276 if ( This->ref == 0 )
278 ERR("(%p) - released sample!\n",This);
282 if ( prtStart == NULL || prtEnd == NULL )
285 if ( ( This->prop.dwSampleFlags & AM_SAMPLE_TIMEVALID ) &&
286 ( This->prop.dwSampleFlags & AM_SAMPLE_STOPVALID ) )
288 *prtStart = This->prop.tStart;
289 *prtEnd = This->prop.tStop;
293 return VFW_E_MEDIA_TIME_NOT_SET;
296 static HRESULT WINAPI
297 IMediaSample2_fnSetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
299 ICOM_THIS(CMemMediaSample,iface);
301 TRACE("(%p)->(%p,%p) stub!\n",This,prtStart,prtEnd);
303 This->prop.dwSampleFlags &= ~(AM_SAMPLE_TIMEVALID|AM_SAMPLE_STOPVALID);
304 if ( prtStart != NULL )
306 This->prop.dwSampleFlags |= AM_SAMPLE_TIMEVALID;
307 This->prop.tStart = *prtStart;
309 if ( prtEnd != NULL )
311 This->prop.dwSampleFlags |= AM_SAMPLE_STOPVALID;
312 This->prop.tStop = *prtEnd;
318 static HRESULT WINAPI
319 IMediaSample2_fnIsSyncPoint(IMediaSample2* iface)
321 ICOM_THIS(CMemMediaSample,iface);
323 TRACE("(%p)->()\n",This);
325 return ( This->prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT ) ?
329 static HRESULT WINAPI
330 IMediaSample2_fnSetSyncPoint(IMediaSample2* iface,BOOL bSync)
332 ICOM_THIS(CMemMediaSample,iface);
334 TRACE("(%p)->(%d)\n",This,bSync);
337 This->prop.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
339 This->prop.dwSampleFlags &= ~AM_SAMPLE_SPLICEPOINT;
344 static HRESULT WINAPI
345 IMediaSample2_fnIsPreroll(IMediaSample2* iface)
347 ICOM_THIS(CMemMediaSample,iface);
349 TRACE("(%p)->()\n",This);
351 return ( This->prop.dwSampleFlags & AM_SAMPLE_PREROLL ) ?
355 static HRESULT WINAPI
356 IMediaSample2_fnSetPreroll(IMediaSample2* iface,BOOL bPreroll)
358 ICOM_THIS(CMemMediaSample,iface);
360 TRACE("(%p)->(%d)\n",This,bPreroll);
363 This->prop.dwSampleFlags |= AM_SAMPLE_PREROLL;
365 This->prop.dwSampleFlags &= ~AM_SAMPLE_PREROLL;
371 IMediaSample2_fnGetActualDataLength(IMediaSample2* iface)
373 ICOM_THIS(CMemMediaSample,iface);
375 TRACE("(%p)->()\n",This);
377 return This->prop.lActual;
380 static HRESULT WINAPI
381 IMediaSample2_fnSetActualDataLength(IMediaSample2* iface,long lLength)
383 ICOM_THIS(CMemMediaSample,iface);
385 TRACE("(%p)->(%ld)\n",This,lLength);
387 if ( This->prop.cbBuffer < lLength )
390 This->prop.lActual = lLength;
394 static HRESULT WINAPI
395 IMediaSample2_fnGetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE** ppmt)
397 ICOM_THIS(CMemMediaSample,iface);
399 TRACE("(%p)->(%p)\n",This,ppmt);
404 if ( !(This->prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) )
407 *ppmt = QUARTZ_MediaType_Duplicate( This->prop.pMediaType );
409 return E_OUTOFMEMORY;
414 static HRESULT WINAPI
415 IMediaSample2_fnSetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE* pmt)
417 ICOM_THIS(CMemMediaSample,iface);
418 AM_MEDIA_TYPE* pmtDup;
420 TRACE("(%p)->(%p)\n",This,pmt);
425 if ( This->prop.pMediaType != NULL )
427 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
428 This->prop.pMediaType = NULL;
430 This->prop.dwSampleFlags &= ~AM_SAMPLE_TYPECHANGED;
434 pmtDup = QUARTZ_MediaType_Duplicate( pmt );
435 if ( pmtDup == NULL )
436 return E_OUTOFMEMORY;
438 if ( This->prop.pMediaType != NULL )
439 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
440 This->prop.dwSampleFlags |= AM_SAMPLE_TYPECHANGED;
441 This->prop.pMediaType = pmtDup;
446 static HRESULT WINAPI
447 IMediaSample2_fnIsDiscontinuity(IMediaSample2* iface)
449 ICOM_THIS(CMemMediaSample,iface);
451 TRACE("(%p)->()\n",This);
453 return ( This->prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY ) ?
457 static HRESULT WINAPI
458 IMediaSample2_fnSetDiscontinuity(IMediaSample2* iface,BOOL bDiscontinuity)
460 ICOM_THIS(CMemMediaSample,iface);
462 TRACE("(%p)->(%d)\n",This,bDiscontinuity);
464 if ( bDiscontinuity )
465 This->prop.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
467 This->prop.dwSampleFlags &= ~AM_SAMPLE_DATADISCONTINUITY;
472 static HRESULT WINAPI
473 IMediaSample2_fnGetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
475 ICOM_THIS(CMemMediaSample,iface);
477 TRACE("(%p)->(%p,%p)\n",This,pTimeStart,pTimeEnd);
479 if ( pTimeStart == NULL || pTimeEnd == NULL )
482 if ( !This->fMediaTimeIsValid )
483 return VFW_E_MEDIA_TIME_NOT_SET;
485 *pTimeStart = This->llMediaTimeStart;
486 *pTimeEnd = This->llMediaTimeEnd;
493 static HRESULT WINAPI
494 IMediaSample2_fnSetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
496 ICOM_THIS(CMemMediaSample,iface);
498 TRACE("(%p)->()\n",This);
499 if ( pTimeStart == NULL || pTimeEnd == NULL )
501 This->fMediaTimeIsValid = FALSE;
505 This->fMediaTimeIsValid = TRUE;
506 This->llMediaTimeStart = *pTimeStart;
507 This->llMediaTimeEnd = *pTimeEnd;
514 static HRESULT WINAPI
515 IMediaSample2_fnGetProperties(IMediaSample2* iface,DWORD cbProp,BYTE* pbProp)
517 ICOM_THIS(CMemMediaSample,iface);
519 TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
521 if ( cbProp < 0 || cbProp > sizeof(AM_SAMPLE2_PROPERTIES) )
523 memcpy( pbProp, &This->prop, cbProp );
528 static HRESULT WINAPI
529 IMediaSample2_fnSetProperties(IMediaSample2* iface,DWORD cbProp,const BYTE* pbProp)
531 ICOM_THIS(CMemMediaSample,iface);
532 const AM_SAMPLE2_PROPERTIES* pProp;
533 AM_SAMPLE2_PROPERTIES propNew;
534 AM_MEDIA_TYPE* pmtDup = NULL;
535 HRESULT hr = E_INVALIDARG;
537 TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
539 if ( pbProp == NULL )
541 pProp = (const AM_SAMPLE2_PROPERTIES*)pbProp;
542 if ( cbProp != sizeof(AM_SAMPLE2_PROPERTIES) )
545 CopyMemory( &propNew, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
546 if ( propNew.cbData != sizeof(AM_SAMPLE2_PROPERTIES) )
549 if ( This->prop.cbBuffer < propNew.lActual )
552 if ( propNew.dwSampleFlags & AM_SAMPLE_TYPECHANGED )
554 pmtDup = QUARTZ_MediaType_Duplicate( propNew.pMediaType );
555 if ( pmtDup == NULL )
562 if ( propNew.pbBuffer != NULL && propNew.pbBuffer != This->prop.pbBuffer )
564 if ( propNew.cbBuffer != 0 && propNew.cbBuffer != This->prop.cbBuffer )
567 if ( This->prop.pMediaType != NULL )
568 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
569 CopyMemory( &This->prop, &propNew, sizeof(AM_SAMPLE2_PROPERTIES) );
570 This->prop.pMediaType = pmtDup;
575 if ( pmtDup != NULL )
576 QUARTZ_MediaType_Destroy( pmtDup );
582 static ICOM_VTABLE(IMediaSample2) imediasample2 =
584 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
585 /* IUnknown fields */
586 IMediaSample2_fnQueryInterface,
587 IMediaSample2_fnAddRef,
588 IMediaSample2_fnRelease,
589 /* IMediaSample fields */
590 IMediaSample2_fnGetPointer,
591 IMediaSample2_fnGetSize,
592 IMediaSample2_fnGetTime,
593 IMediaSample2_fnSetTime,
594 IMediaSample2_fnIsSyncPoint,
595 IMediaSample2_fnSetSyncPoint,
596 IMediaSample2_fnIsPreroll,
597 IMediaSample2_fnSetPreroll,
598 IMediaSample2_fnGetActualDataLength,
599 IMediaSample2_fnSetActualDataLength,
600 IMediaSample2_fnGetMediaType,
601 IMediaSample2_fnSetMediaType,
602 IMediaSample2_fnIsDiscontinuity,
603 IMediaSample2_fnSetDiscontinuity,
604 IMediaSample2_fnGetMediaTime,
605 IMediaSample2_fnSetMediaTime,
606 /* IMediaSample2 fields */
607 IMediaSample2_fnGetProperties,
608 IMediaSample2_fnSetProperties,
612 /***************************************************************************
614 * new/delete for CMemMediaSample
618 HRESULT QUARTZ_CreateMemMediaSample(
619 BYTE* pbData, DWORD dwDataLength,
620 IMemAllocator* pOwner,
621 CMemMediaSample** ppSample )
623 CMemMediaSample* pms;
625 TRACE("(%p,%08lx,%p,%p)\n",pbData,dwDataLength,pOwner,ppSample);
626 pms = (CMemMediaSample*)QUARTZ_AllocObj( sizeof(CMemMediaSample) );
628 return E_OUTOFMEMORY;
630 ICOM_VTBL(pms) = &imediasample2;
632 pms->pOwner = pOwner;
633 pms->fMediaTimeIsValid = FALSE;
634 pms->llMediaTimeStart = 0;
635 pms->llMediaTimeEnd = 0;
636 ZeroMemory( &(pms->prop), sizeof(pms->prop) );
637 pms->prop.cbData = sizeof(pms->prop);
638 pms->prop.dwTypeSpecificFlags = 0;
639 pms->prop.dwSampleFlags = 0;
640 pms->prop.pbBuffer = pbData;
641 pms->prop.cbBuffer = (LONG)dwDataLength;
642 pms->prop.lActual = (LONG)dwDataLength;
649 void QUARTZ_DestroyMemMediaSample(
650 CMemMediaSample* pSample )
652 TRACE("(%p)\n",pSample);
654 QUARTZ_FreeObj( pSample );