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 )
37 AM_SAMPLE2_PROPERTIES prop;
38 IMediaSample2* pSample2 = NULL;
40 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;
86 IMediaSample2* pSample2 = NULL;
89 memcpy( &prop, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
90 prop.cbData = sizeof(AM_SAMPLE2_PROPERTIES);
95 hr = IMediaSample_QueryInterface( pSample, &IID_IMediaSample2, (void**)&pSample2 );
98 hr = IMediaSample2_SetProperties(pSample2,sizeof(AM_SAMPLE2_PROPERTIES),&prop);
99 IMediaSample2_Release(pSample2);
108 hr = IMediaSample_SetSyncPoint(pSample,
109 (prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT) ? TRUE : FALSE);
111 hr = IMediaSample_SetPreroll(pSample,
112 (prop.dwSampleFlags & AM_SAMPLE_PREROLL) ? TRUE : FALSE);
114 hr = IMediaSample_SetDiscontinuity(pSample,
115 (prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) ? TRUE : FALSE);
118 TRACE("length = %ld/%ld\n",prop.lActual,pProp->cbBuffer);
119 hr = IMediaSample_SetActualDataLength(pSample,prop.lActual);
123 if ( ( prop.dwSampleFlags & AM_SAMPLE_TIMEVALID) &&
124 ( prop.dwSampleFlags & AM_SAMPLE_STOPVALID) )
125 hr = IMediaSample_SetTime(pSample,&prop.tStart,&prop.tStop);
127 hr = IMediaSample_SetTime(pSample,NULL,NULL);
130 hr = IMediaSample_SetMediaType(pSample,
131 (prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) ?
132 prop.pMediaType : NULL);
137 HRESULT QUARTZ_IMediaSample_Copy(
138 IMediaSample* pDstSample,
139 IMediaSample* pSrcSample,
143 AM_SAMPLE2_PROPERTIES prop;
144 BYTE* pDataSrc = NULL;
145 BYTE* pDataDst = NULL;
147 hr = QUARTZ_IMediaSample_GetProperties( pSrcSample, &prop );
152 hr = QUARTZ_IMediaSample_SetProperties( pDstSample, &prop );
153 if ( prop.pMediaType != NULL )
154 QUARTZ_MediaType_Destroy( prop.pMediaType );
156 if ( SUCCEEDED(hr) && bCopyData )
158 hr = IMediaSample_GetPointer(pSrcSample,&pDataSrc);
160 hr = IMediaSample_GetPointer(pDstSample,&pDataDst);
163 if ( pDataSrc != NULL && pDataDst != NULL )
164 memcpy( pDataDst, pDataSrc, prop.lActual );
173 /***************************************************************************
175 * CMemMediaSample::IMediaSample2
179 static HRESULT WINAPI
180 IMediaSample2_fnQueryInterface(IMediaSample2* iface,REFIID riid,void** ppobj)
182 ICOM_THIS(CMemMediaSample,iface);
184 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
189 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
190 IsEqualGUID( riid, &IID_IMediaSample ) ||
191 IsEqualGUID( riid, &IID_IMediaSample2 ) )
194 IMediaSample2_AddRef(iface);
198 return E_NOINTERFACE;
202 IMediaSample2_fnAddRef(IMediaSample2* iface)
204 ICOM_THIS(CMemMediaSample,iface);
206 TRACE("(%p)->()\n",This);
208 return InterlockedExchangeAdd(&(This->ref),1) + 1;
212 IMediaSample2_fnRelease(IMediaSample2* iface)
214 ICOM_THIS(CMemMediaSample,iface);
217 TRACE("(%p)->()\n",This);
219 if ( This->ref == 0 )
221 ERR("(%p) - released sample!\n",This);
225 ref = InterlockedExchangeAdd(&(This->ref),-1) - 1;
229 /* this class would be reused.. */
230 if ( This->prop.pMediaType != NULL )
232 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
233 This->prop.pMediaType = NULL;
235 This->prop.dwTypeSpecificFlags = 0;
236 This->prop.dwSampleFlags = 0;
237 This->prop.lActual = This->prop.cbBuffer;
239 IMemAllocator_ReleaseBuffer(This->pOwner,(IMediaSample*)iface);
246 static HRESULT WINAPI
247 IMediaSample2_fnGetPointer(IMediaSample2* iface,BYTE** ppData)
249 ICOM_THIS(CMemMediaSample,iface);
251 TRACE("(%p)->()\n",This);
253 if ( This->ref == 0 )
255 ERR("(%p) - released sample!\n",This);
259 if ( ppData == NULL )
262 *ppData = This->prop.pbBuffer;
267 IMediaSample2_fnGetSize(IMediaSample2* iface)
269 ICOM_THIS(CMemMediaSample,iface);
271 TRACE("(%p)->()\n",This);
273 return This->prop.cbBuffer;
276 static HRESULT WINAPI
277 IMediaSample2_fnGetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
279 ICOM_THIS(CMemMediaSample,iface);
281 TRACE("(%p)->(%p,%p)\n",This,prtStart,prtEnd);
283 if ( This->ref == 0 )
285 ERR("(%p) - released sample!\n",This);
289 if ( prtStart == NULL || prtEnd == NULL )
292 if ( ( This->prop.dwSampleFlags & AM_SAMPLE_TIMEVALID ) &&
293 ( This->prop.dwSampleFlags & AM_SAMPLE_STOPVALID ) )
295 *prtStart = This->prop.tStart;
296 *prtEnd = This->prop.tStop;
300 return VFW_E_MEDIA_TIME_NOT_SET;
303 static HRESULT WINAPI
304 IMediaSample2_fnSetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
306 ICOM_THIS(CMemMediaSample,iface);
308 TRACE("(%p)->(%p,%p) stub!\n",This,prtStart,prtEnd);
310 This->prop.dwSampleFlags &= ~(AM_SAMPLE_TIMEVALID|AM_SAMPLE_STOPVALID);
311 if ( prtStart != NULL )
313 This->prop.dwSampleFlags |= AM_SAMPLE_TIMEVALID;
314 This->prop.tStart = *prtStart;
316 if ( prtEnd != NULL )
318 This->prop.dwSampleFlags |= AM_SAMPLE_STOPVALID;
319 This->prop.tStop = *prtEnd;
325 static HRESULT WINAPI
326 IMediaSample2_fnIsSyncPoint(IMediaSample2* iface)
328 ICOM_THIS(CMemMediaSample,iface);
330 TRACE("(%p)->()\n",This);
332 return ( This->prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT ) ?
336 static HRESULT WINAPI
337 IMediaSample2_fnSetSyncPoint(IMediaSample2* iface,BOOL bSync)
339 ICOM_THIS(CMemMediaSample,iface);
341 TRACE("(%p)->(%d)\n",This,bSync);
344 This->prop.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
346 This->prop.dwSampleFlags &= ~AM_SAMPLE_SPLICEPOINT;
351 static HRESULT WINAPI
352 IMediaSample2_fnIsPreroll(IMediaSample2* iface)
354 ICOM_THIS(CMemMediaSample,iface);
356 TRACE("(%p)->()\n",This);
358 return ( This->prop.dwSampleFlags & AM_SAMPLE_PREROLL ) ?
362 static HRESULT WINAPI
363 IMediaSample2_fnSetPreroll(IMediaSample2* iface,BOOL bPreroll)
365 ICOM_THIS(CMemMediaSample,iface);
367 TRACE("(%p)->(%d)\n",This,bPreroll);
370 This->prop.dwSampleFlags |= AM_SAMPLE_PREROLL;
372 This->prop.dwSampleFlags &= ~AM_SAMPLE_PREROLL;
378 IMediaSample2_fnGetActualDataLength(IMediaSample2* iface)
380 ICOM_THIS(CMemMediaSample,iface);
382 TRACE("(%p)->()\n",This);
384 return This->prop.lActual;
387 static HRESULT WINAPI
388 IMediaSample2_fnSetActualDataLength(IMediaSample2* iface,long lLength)
390 ICOM_THIS(CMemMediaSample,iface);
392 TRACE("(%p)->(%ld)\n",This,lLength);
394 if ( This->prop.cbBuffer < lLength )
397 This->prop.lActual = lLength;
401 static HRESULT WINAPI
402 IMediaSample2_fnGetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE** ppmt)
404 ICOM_THIS(CMemMediaSample,iface);
406 TRACE("(%p)->(%p)\n",This,ppmt);
411 if ( !(This->prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) )
414 *ppmt = QUARTZ_MediaType_Duplicate( This->prop.pMediaType );
416 return E_OUTOFMEMORY;
421 static HRESULT WINAPI
422 IMediaSample2_fnSetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE* pmt)
424 ICOM_THIS(CMemMediaSample,iface);
425 AM_MEDIA_TYPE* pmtDup;
427 TRACE("(%p)->(%p)\n",This,pmt);
432 if ( This->prop.pMediaType != NULL )
434 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
435 This->prop.pMediaType = NULL;
437 This->prop.dwSampleFlags &= ~AM_SAMPLE_TYPECHANGED;
441 pmtDup = QUARTZ_MediaType_Duplicate( pmt );
442 if ( pmtDup == NULL )
443 return E_OUTOFMEMORY;
445 if ( This->prop.pMediaType != NULL )
446 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
447 This->prop.dwSampleFlags |= AM_SAMPLE_TYPECHANGED;
448 This->prop.pMediaType = pmtDup;
453 static HRESULT WINAPI
454 IMediaSample2_fnIsDiscontinuity(IMediaSample2* iface)
456 ICOM_THIS(CMemMediaSample,iface);
458 TRACE("(%p)->()\n",This);
460 return ( This->prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY ) ?
464 static HRESULT WINAPI
465 IMediaSample2_fnSetDiscontinuity(IMediaSample2* iface,BOOL bDiscontinuity)
467 ICOM_THIS(CMemMediaSample,iface);
469 TRACE("(%p)->(%d)\n",This,bDiscontinuity);
471 if ( bDiscontinuity )
472 This->prop.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
474 This->prop.dwSampleFlags &= ~AM_SAMPLE_DATADISCONTINUITY;
479 static HRESULT WINAPI
480 IMediaSample2_fnGetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
482 ICOM_THIS(CMemMediaSample,iface);
484 TRACE("(%p)->(%p,%p)\n",This,pTimeStart,pTimeEnd);
486 if ( pTimeStart == NULL || pTimeEnd == NULL )
489 if ( !This->fMediaTimeIsValid )
490 return VFW_E_MEDIA_TIME_NOT_SET;
492 *pTimeStart = This->llMediaTimeStart;
493 *pTimeEnd = This->llMediaTimeEnd;
500 static HRESULT WINAPI
501 IMediaSample2_fnSetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
503 ICOM_THIS(CMemMediaSample,iface);
505 TRACE("(%p)->()\n",This);
506 if ( pTimeStart == NULL || pTimeEnd == NULL )
508 This->fMediaTimeIsValid = FALSE;
512 This->fMediaTimeIsValid = TRUE;
513 This->llMediaTimeStart = *pTimeStart;
514 This->llMediaTimeEnd = *pTimeEnd;
521 static HRESULT WINAPI
522 IMediaSample2_fnGetProperties(IMediaSample2* iface,DWORD cbProp,BYTE* pbProp)
524 ICOM_THIS(CMemMediaSample,iface);
526 TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
528 if ( cbProp < 0 || cbProp > sizeof(AM_SAMPLE2_PROPERTIES) )
530 memcpy( pbProp, &This->prop, cbProp );
535 static HRESULT WINAPI
536 IMediaSample2_fnSetProperties(IMediaSample2* iface,DWORD cbProp,const BYTE* pbProp)
538 ICOM_THIS(CMemMediaSample,iface);
539 const AM_SAMPLE2_PROPERTIES* pProp;
540 AM_SAMPLE2_PROPERTIES propNew;
541 AM_MEDIA_TYPE* pmtDup = NULL;
542 HRESULT hr = E_INVALIDARG;
544 TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
546 if ( pbProp == NULL )
548 pProp = (const AM_SAMPLE2_PROPERTIES*)pbProp;
549 if ( cbProp != sizeof(AM_SAMPLE2_PROPERTIES) )
552 CopyMemory( &propNew, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
553 if ( propNew.cbData != sizeof(AM_SAMPLE2_PROPERTIES) )
556 if ( This->prop.cbBuffer < propNew.lActual )
559 if ( propNew.dwSampleFlags & AM_SAMPLE_TYPECHANGED )
561 pmtDup = QUARTZ_MediaType_Duplicate( propNew.pMediaType );
562 if ( pmtDup == NULL )
569 if ( propNew.pbBuffer != NULL && propNew.pbBuffer != This->prop.pbBuffer )
571 if ( propNew.cbBuffer != 0 && propNew.cbBuffer != This->prop.cbBuffer )
574 if ( This->prop.pMediaType != NULL )
575 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
576 CopyMemory( &This->prop, &propNew, sizeof(AM_SAMPLE2_PROPERTIES) );
577 This->prop.pMediaType = pmtDup;
582 if ( pmtDup != NULL )
583 QUARTZ_MediaType_Destroy( pmtDup );
589 static ICOM_VTABLE(IMediaSample2) imediasample2 =
591 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
592 /* IUnknown fields */
593 IMediaSample2_fnQueryInterface,
594 IMediaSample2_fnAddRef,
595 IMediaSample2_fnRelease,
596 /* IMediaSample fields */
597 IMediaSample2_fnGetPointer,
598 IMediaSample2_fnGetSize,
599 IMediaSample2_fnGetTime,
600 IMediaSample2_fnSetTime,
601 IMediaSample2_fnIsSyncPoint,
602 IMediaSample2_fnSetSyncPoint,
603 IMediaSample2_fnIsPreroll,
604 IMediaSample2_fnSetPreroll,
605 IMediaSample2_fnGetActualDataLength,
606 IMediaSample2_fnSetActualDataLength,
607 IMediaSample2_fnGetMediaType,
608 IMediaSample2_fnSetMediaType,
609 IMediaSample2_fnIsDiscontinuity,
610 IMediaSample2_fnSetDiscontinuity,
611 IMediaSample2_fnGetMediaTime,
612 IMediaSample2_fnSetMediaTime,
613 /* IMediaSample2 fields */
614 IMediaSample2_fnGetProperties,
615 IMediaSample2_fnSetProperties,
619 /***************************************************************************
621 * new/delete for CMemMediaSample
625 HRESULT QUARTZ_CreateMemMediaSample(
626 BYTE* pbData, DWORD dwDataLength,
627 IMemAllocator* pOwner,
628 CMemMediaSample** ppSample )
630 CMemMediaSample* pms;
632 TRACE("(%p,%08lx,%p,%p)\n",pbData,dwDataLength,pOwner,ppSample);
633 pms = (CMemMediaSample*)QUARTZ_AllocObj( sizeof(CMemMediaSample) );
635 return E_OUTOFMEMORY;
637 ICOM_VTBL(pms) = &imediasample2;
639 pms->pOwner = pOwner;
640 pms->fMediaTimeIsValid = FALSE;
641 pms->llMediaTimeStart = 0;
642 pms->llMediaTimeEnd = 0;
643 ZeroMemory( &(pms->prop), sizeof(pms->prop) );
644 pms->prop.cbData = sizeof(pms->prop);
645 pms->prop.dwTypeSpecificFlags = 0;
646 pms->prop.dwSampleFlags = 0;
647 pms->prop.pbBuffer = pbData;
648 pms->prop.cbBuffer = (LONG)dwDataLength;
649 pms->prop.lActual = (LONG)dwDataLength;
656 void QUARTZ_DestroyMemMediaSample(
657 CMemMediaSample* pSample )
659 TRACE("(%p)\n",pSample);
661 QUARTZ_FreeObj( pSample );