2 * Implements IMediaSample2 for CMemMediaSample.
4 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
34 #include "quartz_private.h"
39 /***************************************************************************
45 HRESULT QUARTZ_IMediaSample_GetProperties(
46 IMediaSample* pSample,
47 AM_SAMPLE2_PROPERTIES* pProp )
51 AM_SAMPLE2_PROPERTIES prop;
52 IMediaSample2* pSample2 = NULL;
54 ZeroMemory( &prop, sizeof(AM_SAMPLE2_PROPERTIES) );
56 hr = IMediaSample_QueryInterface( pSample, &IID_IMediaSample2, (void**)&pSample2 );
59 hr = IMediaSample2_GetProperties(pSample2,sizeof(AM_SAMPLE2_PROPERTIES),&prop);
60 IMediaSample2_Release(pSample2);
63 memcpy( pProp, &prop, sizeof(AM_SAMPLE2_PROPERTIES) );
65 QUARTZ_MediaType_Duplicate( &prop.pMediaType );
72 pProp->cbData = sizeof(AM_SAMPLE2_PROPERTIES);
73 pProp->dwTypeSpecificFlags = 0;
74 pProp->dwSampleFlags = 0;
75 if ( IMediaSample_IsSyncPoint(pSample) == S_OK )
76 pProp->dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
77 if ( IMediaSample_IsPreroll(pSample) == S_OK )
78 pProp->dwSampleFlags |= AM_SAMPLE_PREROLL;
79 if ( IMediaSample_IsDiscontinuity(pSample) == S_OK )
80 pProp->dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
81 pProp->lActual = (LONG)IMediaSample_GetActualDataLength(pSample);
82 if ( IMediaSample_GetTime(pSample,&pProp->tStart,&pProp->tStop) == S_OK )
83 pProp->dwSampleFlags |= AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID;
84 pProp->dwStreamId = 0;
85 if ( IMediaSample_GetMediaType(pSample,&(pProp->pMediaType)) == S_OK )
86 pProp->dwSampleFlags |= AM_SAMPLE_TYPECHANGED;
87 IMediaSample_GetPointer(pSample,&(pProp->pbBuffer));
88 pProp->cbBuffer = (LONG)IMediaSample_GetSize(pSample);
93 HRESULT QUARTZ_IMediaSample_SetProperties(
94 IMediaSample* pSample,
95 const AM_SAMPLE2_PROPERTIES* pProp )
98 AM_SAMPLE2_PROPERTIES prop;
100 IMediaSample2* pSample2 = NULL;
103 memcpy( &prop, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
104 prop.cbData = sizeof(AM_SAMPLE2_PROPERTIES);
105 prop.pbBuffer = NULL;
109 hr = IMediaSample_QueryInterface( pSample, &IID_IMediaSample2, (void**)&pSample2 );
112 hr = IMediaSample2_SetProperties(pSample2,sizeof(AM_SAMPLE2_PROPERTIES),&prop);
113 IMediaSample2_Release(pSample2);
122 hr = IMediaSample_SetSyncPoint(pSample,
123 (prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT) ? TRUE : FALSE);
125 hr = IMediaSample_SetPreroll(pSample,
126 (prop.dwSampleFlags & AM_SAMPLE_PREROLL) ? TRUE : FALSE);
128 hr = IMediaSample_SetDiscontinuity(pSample,
129 (prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) ? TRUE : FALSE);
132 TRACE("length = %ld/%ld\n",prop.lActual,pProp->cbBuffer);
133 hr = IMediaSample_SetActualDataLength(pSample,prop.lActual);
137 if ( ( prop.dwSampleFlags & AM_SAMPLE_TIMEVALID) &&
138 ( prop.dwSampleFlags & AM_SAMPLE_STOPVALID) )
139 hr = IMediaSample_SetTime(pSample,&prop.tStart,&prop.tStop);
141 hr = IMediaSample_SetTime(pSample,NULL,NULL);
144 hr = IMediaSample_SetMediaType(pSample,
145 (prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) ?
146 prop.pMediaType : NULL);
151 HRESULT QUARTZ_IMediaSample_Copy(
152 IMediaSample* pDstSample,
153 IMediaSample* pSrcSample,
157 AM_SAMPLE2_PROPERTIES prop;
158 BYTE* pDataSrc = NULL;
159 BYTE* pDataDst = NULL;
161 hr = QUARTZ_IMediaSample_GetProperties( pSrcSample, &prop );
166 hr = QUARTZ_IMediaSample_SetProperties( pDstSample, &prop );
167 if ( prop.pMediaType != NULL )
168 QUARTZ_MediaType_Destroy( prop.pMediaType );
170 if ( SUCCEEDED(hr) && bCopyData )
172 hr = IMediaSample_GetPointer(pSrcSample,&pDataSrc);
174 hr = IMediaSample_GetPointer(pDstSample,&pDataDst);
177 if ( pDataSrc != NULL && pDataDst != NULL )
178 memcpy( pDataDst, pDataSrc, prop.lActual );
187 /***************************************************************************
189 * CMemMediaSample::IMediaSample2
193 static HRESULT WINAPI
194 IMediaSample2_fnQueryInterface(IMediaSample2* iface,REFIID riid,void** ppobj)
196 ICOM_THIS(CMemMediaSample,iface);
198 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
203 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
204 IsEqualGUID( riid, &IID_IMediaSample ) ||
205 IsEqualGUID( riid, &IID_IMediaSample2 ) )
208 IMediaSample2_AddRef(iface);
212 return E_NOINTERFACE;
216 IMediaSample2_fnAddRef(IMediaSample2* iface)
218 ICOM_THIS(CMemMediaSample,iface);
220 TRACE("(%p)->()\n",This);
222 return InterlockedExchangeAdd(&(This->ref),1) + 1;
226 IMediaSample2_fnRelease(IMediaSample2* iface)
228 ICOM_THIS(CMemMediaSample,iface);
231 TRACE("(%p)->()\n",This);
233 if ( This->ref == 0 )
235 ERR("(%p) - released sample!\n",This);
239 ref = InterlockedExchangeAdd(&(This->ref),-1) - 1;
243 /* this class would be reused.. */
244 if ( This->prop.pMediaType != NULL )
246 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
247 This->prop.pMediaType = NULL;
249 This->prop.dwTypeSpecificFlags = 0;
250 This->prop.dwSampleFlags = 0;
251 This->prop.lActual = This->prop.cbBuffer;
253 IMemAllocator_ReleaseBuffer(This->pOwner,(IMediaSample*)iface);
260 static HRESULT WINAPI
261 IMediaSample2_fnGetPointer(IMediaSample2* iface,BYTE** ppData)
263 ICOM_THIS(CMemMediaSample,iface);
265 TRACE("(%p)->()\n",This);
267 if ( This->ref == 0 )
269 ERR("(%p) - released sample!\n",This);
273 if ( ppData == NULL )
276 *ppData = This->prop.pbBuffer;
281 IMediaSample2_fnGetSize(IMediaSample2* iface)
283 ICOM_THIS(CMemMediaSample,iface);
285 TRACE("(%p)->()\n",This);
287 return This->prop.cbBuffer;
290 static HRESULT WINAPI
291 IMediaSample2_fnGetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
293 ICOM_THIS(CMemMediaSample,iface);
295 TRACE("(%p)->(%p,%p)\n",This,prtStart,prtEnd);
297 if ( This->ref == 0 )
299 ERR("(%p) - released sample!\n",This);
303 if ( prtStart == NULL || prtEnd == NULL )
306 if ( ( This->prop.dwSampleFlags & AM_SAMPLE_TIMEVALID ) &&
307 ( This->prop.dwSampleFlags & AM_SAMPLE_STOPVALID ) )
309 *prtStart = This->prop.tStart;
310 *prtEnd = This->prop.tStop;
314 return VFW_E_MEDIA_TIME_NOT_SET;
317 static HRESULT WINAPI
318 IMediaSample2_fnSetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
320 ICOM_THIS(CMemMediaSample,iface);
322 TRACE("(%p)->(%p,%p) stub!\n",This,prtStart,prtEnd);
324 This->prop.dwSampleFlags &= ~(AM_SAMPLE_TIMEVALID|AM_SAMPLE_STOPVALID);
325 if ( prtStart != NULL )
327 This->prop.dwSampleFlags |= AM_SAMPLE_TIMEVALID;
328 This->prop.tStart = *prtStart;
330 if ( prtEnd != NULL )
332 This->prop.dwSampleFlags |= AM_SAMPLE_STOPVALID;
333 This->prop.tStop = *prtEnd;
339 static HRESULT WINAPI
340 IMediaSample2_fnIsSyncPoint(IMediaSample2* iface)
342 ICOM_THIS(CMemMediaSample,iface);
344 TRACE("(%p)->()\n",This);
346 return ( This->prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT ) ?
350 static HRESULT WINAPI
351 IMediaSample2_fnSetSyncPoint(IMediaSample2* iface,BOOL bSync)
353 ICOM_THIS(CMemMediaSample,iface);
355 TRACE("(%p)->(%d)\n",This,bSync);
358 This->prop.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
360 This->prop.dwSampleFlags &= ~AM_SAMPLE_SPLICEPOINT;
365 static HRESULT WINAPI
366 IMediaSample2_fnIsPreroll(IMediaSample2* iface)
368 ICOM_THIS(CMemMediaSample,iface);
370 TRACE("(%p)->()\n",This);
372 return ( This->prop.dwSampleFlags & AM_SAMPLE_PREROLL ) ?
376 static HRESULT WINAPI
377 IMediaSample2_fnSetPreroll(IMediaSample2* iface,BOOL bPreroll)
379 ICOM_THIS(CMemMediaSample,iface);
381 TRACE("(%p)->(%d)\n",This,bPreroll);
384 This->prop.dwSampleFlags |= AM_SAMPLE_PREROLL;
386 This->prop.dwSampleFlags &= ~AM_SAMPLE_PREROLL;
392 IMediaSample2_fnGetActualDataLength(IMediaSample2* iface)
394 ICOM_THIS(CMemMediaSample,iface);
396 TRACE("(%p)->()\n",This);
398 return This->prop.lActual;
401 static HRESULT WINAPI
402 IMediaSample2_fnSetActualDataLength(IMediaSample2* iface,long lLength)
404 ICOM_THIS(CMemMediaSample,iface);
406 TRACE("(%p)->(%ld)\n",This,lLength);
408 if ( This->prop.cbBuffer < lLength )
411 This->prop.lActual = lLength;
415 static HRESULT WINAPI
416 IMediaSample2_fnGetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE** ppmt)
418 ICOM_THIS(CMemMediaSample,iface);
420 TRACE("(%p)->(%p)\n",This,ppmt);
425 if ( !(This->prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) )
428 *ppmt = QUARTZ_MediaType_Duplicate( This->prop.pMediaType );
430 return E_OUTOFMEMORY;
435 static HRESULT WINAPI
436 IMediaSample2_fnSetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE* pmt)
438 ICOM_THIS(CMemMediaSample,iface);
439 AM_MEDIA_TYPE* pmtDup;
441 TRACE("(%p)->(%p)\n",This,pmt);
446 if ( This->prop.pMediaType != NULL )
448 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
449 This->prop.pMediaType = NULL;
451 This->prop.dwSampleFlags &= ~AM_SAMPLE_TYPECHANGED;
455 pmtDup = QUARTZ_MediaType_Duplicate( pmt );
456 if ( pmtDup == NULL )
457 return E_OUTOFMEMORY;
459 if ( This->prop.pMediaType != NULL )
460 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
461 This->prop.dwSampleFlags |= AM_SAMPLE_TYPECHANGED;
462 This->prop.pMediaType = pmtDup;
467 static HRESULT WINAPI
468 IMediaSample2_fnIsDiscontinuity(IMediaSample2* iface)
470 ICOM_THIS(CMemMediaSample,iface);
472 TRACE("(%p)->()\n",This);
474 return ( This->prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY ) ?
478 static HRESULT WINAPI
479 IMediaSample2_fnSetDiscontinuity(IMediaSample2* iface,BOOL bDiscontinuity)
481 ICOM_THIS(CMemMediaSample,iface);
483 TRACE("(%p)->(%d)\n",This,bDiscontinuity);
485 if ( bDiscontinuity )
486 This->prop.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
488 This->prop.dwSampleFlags &= ~AM_SAMPLE_DATADISCONTINUITY;
493 static HRESULT WINAPI
494 IMediaSample2_fnGetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
496 ICOM_THIS(CMemMediaSample,iface);
498 TRACE("(%p)->(%p,%p)\n",This,pTimeStart,pTimeEnd);
500 if ( pTimeStart == NULL || pTimeEnd == NULL )
503 if ( !This->fMediaTimeIsValid )
504 return VFW_E_MEDIA_TIME_NOT_SET;
506 *pTimeStart = This->llMediaTimeStart;
507 *pTimeEnd = This->llMediaTimeEnd;
514 static HRESULT WINAPI
515 IMediaSample2_fnSetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
517 ICOM_THIS(CMemMediaSample,iface);
519 TRACE("(%p)->()\n",This);
520 if ( pTimeStart == NULL || pTimeEnd == NULL )
522 This->fMediaTimeIsValid = FALSE;
526 This->fMediaTimeIsValid = TRUE;
527 This->llMediaTimeStart = *pTimeStart;
528 This->llMediaTimeEnd = *pTimeEnd;
535 static HRESULT WINAPI
536 IMediaSample2_fnGetProperties(IMediaSample2* iface,DWORD cbProp,BYTE* pbProp)
538 ICOM_THIS(CMemMediaSample,iface);
540 TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
542 if ( cbProp < 0 || cbProp > sizeof(AM_SAMPLE2_PROPERTIES) )
544 memcpy( pbProp, &This->prop, cbProp );
549 static HRESULT WINAPI
550 IMediaSample2_fnSetProperties(IMediaSample2* iface,DWORD cbProp,const BYTE* pbProp)
552 ICOM_THIS(CMemMediaSample,iface);
553 const AM_SAMPLE2_PROPERTIES* pProp;
554 AM_SAMPLE2_PROPERTIES propNew;
555 AM_MEDIA_TYPE* pmtDup = NULL;
556 HRESULT hr = E_INVALIDARG;
558 TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
560 if ( pbProp == NULL )
562 pProp = (const AM_SAMPLE2_PROPERTIES*)pbProp;
563 if ( cbProp != sizeof(AM_SAMPLE2_PROPERTIES) )
566 CopyMemory( &propNew, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
567 if ( propNew.cbData != sizeof(AM_SAMPLE2_PROPERTIES) )
570 if ( This->prop.cbBuffer < propNew.lActual )
573 if ( propNew.dwSampleFlags & AM_SAMPLE_TYPECHANGED )
575 pmtDup = QUARTZ_MediaType_Duplicate( propNew.pMediaType );
576 if ( pmtDup == NULL )
583 if ( propNew.pbBuffer != NULL && propNew.pbBuffer != This->prop.pbBuffer )
585 if ( propNew.cbBuffer != 0 && propNew.cbBuffer != This->prop.cbBuffer )
588 if ( This->prop.pMediaType != NULL )
589 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
590 CopyMemory( &This->prop, &propNew, sizeof(AM_SAMPLE2_PROPERTIES) );
591 This->prop.pMediaType = pmtDup;
596 if ( pmtDup != NULL )
597 QUARTZ_MediaType_Destroy( pmtDup );
603 static ICOM_VTABLE(IMediaSample2) imediasample2 =
605 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
606 /* IUnknown fields */
607 IMediaSample2_fnQueryInterface,
608 IMediaSample2_fnAddRef,
609 IMediaSample2_fnRelease,
610 /* IMediaSample fields */
611 IMediaSample2_fnGetPointer,
612 IMediaSample2_fnGetSize,
613 IMediaSample2_fnGetTime,
614 IMediaSample2_fnSetTime,
615 IMediaSample2_fnIsSyncPoint,
616 IMediaSample2_fnSetSyncPoint,
617 IMediaSample2_fnIsPreroll,
618 IMediaSample2_fnSetPreroll,
619 IMediaSample2_fnGetActualDataLength,
620 IMediaSample2_fnSetActualDataLength,
621 IMediaSample2_fnGetMediaType,
622 IMediaSample2_fnSetMediaType,
623 IMediaSample2_fnIsDiscontinuity,
624 IMediaSample2_fnSetDiscontinuity,
625 IMediaSample2_fnGetMediaTime,
626 IMediaSample2_fnSetMediaTime,
627 /* IMediaSample2 fields */
628 IMediaSample2_fnGetProperties,
629 IMediaSample2_fnSetProperties,
633 /***************************************************************************
635 * new/delete for CMemMediaSample
639 HRESULT QUARTZ_CreateMemMediaSample(
640 BYTE* pbData, DWORD dwDataLength,
641 IMemAllocator* pOwner,
642 CMemMediaSample** ppSample )
644 CMemMediaSample* pms;
646 TRACE("(%p,%08lx,%p,%p)\n",pbData,dwDataLength,pOwner,ppSample);
647 pms = (CMemMediaSample*)QUARTZ_AllocObj( sizeof(CMemMediaSample) );
649 return E_OUTOFMEMORY;
651 ICOM_VTBL(pms) = &imediasample2;
653 pms->pOwner = pOwner;
654 pms->fMediaTimeIsValid = FALSE;
655 pms->llMediaTimeStart = 0;
656 pms->llMediaTimeEnd = 0;
657 ZeroMemory( &(pms->prop), sizeof(pms->prop) );
658 pms->prop.cbData = sizeof(pms->prop);
659 pms->prop.dwTypeSpecificFlags = 0;
660 pms->prop.dwSampleFlags = 0;
661 pms->prop.pbBuffer = pbData;
662 pms->prop.cbBuffer = (LONG)dwDataLength;
663 pms->prop.lActual = (LONG)dwDataLength;
670 void QUARTZ_DestroyMemMediaSample(
671 CMemMediaSample* pSample )
673 TRACE("(%p)\n",pSample);
675 QUARTZ_FreeObj( pSample );