Various cosmetic changes.
[wine] / dlls / quartz / sample.c
1 /*
2  * Implements IMediaSample2 for CMemMediaSample.
3  *
4  * hidenori@a2.ctktv.ne.jp
5  */
6
7 #include "config.h"
8
9 #include "windef.h"
10 #include "winbase.h"
11 #include "wingdi.h"
12 #include "winuser.h"
13 #include "winerror.h"
14 #include "strmif.h"
15 #include "vfwmsgs.h"
16
17 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(quartz);
19
20 #include "quartz_private.h"
21 #include "sample.h"
22 #include "mtype.h"
23
24
25 /***************************************************************************
26  *
27  *      Helper functions
28  *
29  */
30
31 HRESULT QUARTZ_IMediaSample_GetProperties(
32         IMediaSample* pSample,
33         AM_SAMPLE2_PROPERTIES* pProp )
34 {
35 #if 0 /* not yet */
36         HRESULT hr;
37         AM_SAMPLE2_PROPERTIES   prop;
38         IMediaSample2*  pSample2 = NULL;
39
40         ZeroMemory( &prop, sizeof(AM_SAMPLE2_PROPERTIES) );
41
42         hr = IMediaSample_QueryInterface( pSample, &IID_IMediaSample2, (void**)&pSample2 );
43         if ( hr == S_OK )
44         {
45                 hr = IMediaSample2_GetProperties(pSample2,sizeof(AM_SAMPLE2_PROPERTIES),&prop);
46                 IMediaSample2_Release(pSample2);
47                 if ( hr == S_OK )
48                 {
49                         memcpy( pProp, &prop, sizeof(AM_SAMPLE2_PROPERTIES) );
50                         pProp->pMediaType =
51                                 QUARTZ_MediaType_Duplicate( &prop.pMediaType );
52
53                         return NOERROR;
54                 }
55         }
56 #endif
57
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);
75
76         return NOERROR;
77 }
78
79 HRESULT QUARTZ_IMediaSample_SetProperties(
80         IMediaSample* pSample,
81         const AM_SAMPLE2_PROPERTIES* pProp )
82 {
83         HRESULT hr;
84         AM_SAMPLE2_PROPERTIES   prop;
85 #if 0 /* not yet */
86         IMediaSample2*  pSample2 = NULL;
87 #endif
88
89         memcpy( &prop, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
90         prop.cbData = sizeof(AM_SAMPLE2_PROPERTIES);
91         prop.pbBuffer = NULL;
92         prop.cbBuffer = 0;
93
94 #if 0 /* not yet */
95         hr = IMediaSample_QueryInterface( pSample, &IID_IMediaSample2, (void**)&pSample2 );
96         if ( hr == S_OK )
97         {
98                 hr = IMediaSample2_SetProperties(pSample2,sizeof(AM_SAMPLE2_PROPERTIES),&prop);
99                 IMediaSample2_Release(pSample2);
100                 if ( hr == S_OK )
101                         return NOERROR;
102         }
103 #endif
104
105         hr = S_OK;
106
107         if ( SUCCEEDED(hr) )
108                 hr = IMediaSample_SetSyncPoint(pSample,
109                         (prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT) ? TRUE : FALSE);
110         if ( SUCCEEDED(hr) )
111                 hr = IMediaSample_SetPreroll(pSample,
112                         (prop.dwSampleFlags & AM_SAMPLE_PREROLL) ? TRUE : FALSE);
113         if ( SUCCEEDED(hr) )
114                 hr = IMediaSample_SetDiscontinuity(pSample,
115                         (prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) ? TRUE : FALSE);
116         if ( SUCCEEDED(hr) )
117         {
118                 TRACE("length = %ld/%ld\n",prop.lActual,pProp->cbBuffer);
119                 hr = IMediaSample_SetActualDataLength(pSample,prop.lActual);
120         }
121         if ( SUCCEEDED(hr) )
122         {
123                 if ( ( prop.dwSampleFlags & AM_SAMPLE_TIMEVALID) &&
124                      ( prop.dwSampleFlags & AM_SAMPLE_STOPVALID) )
125                         hr = IMediaSample_SetTime(pSample,&prop.tStart,&prop.tStop);
126                 else
127                         hr = IMediaSample_SetTime(pSample,NULL,NULL);
128         }
129         if ( SUCCEEDED(hr) )
130                 hr = IMediaSample_SetMediaType(pSample,
131                         (prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) ?
132                                 prop.pMediaType : NULL);
133
134         return hr;
135 }
136
137 HRESULT QUARTZ_IMediaSample_Copy(
138         IMediaSample* pDstSample,
139         IMediaSample* pSrcSample,
140         BOOL bCopyData )
141 {
142         HRESULT hr;
143         AM_SAMPLE2_PROPERTIES   prop;
144         BYTE* pDataSrc = NULL;
145         BYTE* pDataDst = NULL;
146
147         hr = QUARTZ_IMediaSample_GetProperties( pSrcSample, &prop );
148         if ( FAILED(hr) )
149                 return hr;
150         if ( !bCopyData )
151                 prop.lActual = 0;
152         hr = QUARTZ_IMediaSample_SetProperties( pDstSample, &prop );
153         if ( prop.pMediaType != NULL )
154                 QUARTZ_MediaType_Destroy( prop.pMediaType );
155
156         if ( SUCCEEDED(hr) && bCopyData )
157         {
158                 hr = IMediaSample_GetPointer(pSrcSample,&pDataSrc);
159                 if ( SUCCEEDED(hr) )
160                         hr = IMediaSample_GetPointer(pDstSample,&pDataDst);
161                 if ( SUCCEEDED(hr) )
162                 {
163                         if ( pDataSrc != NULL && pDataDst != NULL )
164                                 memcpy( pDataDst, pDataSrc, prop.lActual );
165                         else
166                                 hr = E_FAIL;
167                 }
168         }
169
170         return hr;
171 }
172
173 /***************************************************************************
174  *
175  *      CMemMediaSample::IMediaSample2
176  *
177  */
178
179 static HRESULT WINAPI
180 IMediaSample2_fnQueryInterface(IMediaSample2* iface,REFIID riid,void** ppobj)
181 {
182         ICOM_THIS(CMemMediaSample,iface);
183
184         TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
185
186         if ( ppobj == NULL )
187                 return E_POINTER;
188
189         if ( IsEqualGUID( riid, &IID_IUnknown ) ||
190              IsEqualGUID( riid, &IID_IMediaSample ) ||
191              IsEqualGUID( riid, &IID_IMediaSample2 ) )
192         {
193                 *ppobj = iface;
194                 IMediaSample2_AddRef(iface);
195                 return NOERROR;
196         }
197
198         return E_NOINTERFACE;
199 }
200
201 static ULONG WINAPI
202 IMediaSample2_fnAddRef(IMediaSample2* iface)
203 {
204         ICOM_THIS(CMemMediaSample,iface);
205
206         TRACE("(%p)->()\n",This);
207
208         return InterlockedExchangeAdd(&(This->ref),1) + 1;
209 }
210
211 static ULONG WINAPI
212 IMediaSample2_fnRelease(IMediaSample2* iface)
213 {
214         ICOM_THIS(CMemMediaSample,iface);
215         LONG    ref;
216
217         TRACE("(%p)->()\n",This);
218
219         if ( This->ref == 0 )
220         {
221                 ERR("(%p) - released sample!\n",This);
222                 return 0;
223         }
224
225         ref = InterlockedExchangeAdd(&(This->ref),-1) - 1;
226         if ( ref > 0 )
227                 return (ULONG)ref;
228
229         /* this class would be reused.. */
230         if ( This->prop.pMediaType != NULL )
231         {
232                 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
233                 This->prop.pMediaType = NULL;
234         }
235         This->prop.dwTypeSpecificFlags = 0;
236         This->prop.dwSampleFlags = 0;
237         This->prop.lActual = This->prop.cbBuffer;
238
239         IMemAllocator_ReleaseBuffer(This->pOwner,(IMediaSample*)iface);
240
241         return 0;
242 }
243
244
245
246 static HRESULT WINAPI
247 IMediaSample2_fnGetPointer(IMediaSample2* iface,BYTE** ppData)
248 {
249         ICOM_THIS(CMemMediaSample,iface);
250
251         TRACE("(%p)->()\n",This);
252
253         if ( This->ref == 0 )
254         {
255                 ERR("(%p) - released sample!\n",This);
256                 return E_UNEXPECTED;
257         }
258
259         if ( ppData == NULL )
260                 return E_POINTER;
261
262         *ppData = This->prop.pbBuffer;
263         return NOERROR;
264 }
265
266 static long WINAPI
267 IMediaSample2_fnGetSize(IMediaSample2* iface)
268 {
269         ICOM_THIS(CMemMediaSample,iface);
270
271         TRACE("(%p)->()\n",This);
272
273         return This->prop.cbBuffer;
274 }
275
276 static HRESULT WINAPI
277 IMediaSample2_fnGetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
278 {
279         ICOM_THIS(CMemMediaSample,iface);
280
281         TRACE("(%p)->(%p,%p)\n",This,prtStart,prtEnd);
282
283         if ( This->ref == 0 )
284         {
285                 ERR("(%p) - released sample!\n",This);
286                 return E_UNEXPECTED;
287         }
288
289         if ( prtStart == NULL || prtEnd == NULL )
290                 return E_POINTER;
291
292         if ( ( This->prop.dwSampleFlags & AM_SAMPLE_TIMEVALID ) &&
293                  ( This->prop.dwSampleFlags & AM_SAMPLE_STOPVALID ) )
294         {
295                 *prtStart = This->prop.tStart;
296                 *prtEnd = This->prop.tStop;
297                 return NOERROR;
298         }
299
300         return VFW_E_MEDIA_TIME_NOT_SET;
301 }
302
303 static HRESULT WINAPI
304 IMediaSample2_fnSetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
305 {
306         ICOM_THIS(CMemMediaSample,iface);
307
308         TRACE("(%p)->(%p,%p) stub!\n",This,prtStart,prtEnd);
309
310         This->prop.dwSampleFlags &= ~(AM_SAMPLE_TIMEVALID|AM_SAMPLE_STOPVALID);
311         if ( prtStart != NULL )
312         {
313                 This->prop.dwSampleFlags |= AM_SAMPLE_TIMEVALID;
314                 This->prop.tStart = *prtStart;
315         }
316         if ( prtEnd != NULL )
317         {
318                 This->prop.dwSampleFlags |= AM_SAMPLE_STOPVALID;
319                 This->prop.tStop = *prtEnd;
320         }
321
322         return NOERROR;
323 }
324
325 static HRESULT WINAPI
326 IMediaSample2_fnIsSyncPoint(IMediaSample2* iface)
327 {
328         ICOM_THIS(CMemMediaSample,iface);
329
330         TRACE("(%p)->()\n",This);
331
332         return ( This->prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT ) ?
333                                                 S_OK : S_FALSE;
334 }
335
336 static HRESULT WINAPI
337 IMediaSample2_fnSetSyncPoint(IMediaSample2* iface,BOOL bSync)
338 {
339         ICOM_THIS(CMemMediaSample,iface);
340
341         TRACE("(%p)->(%d)\n",This,bSync);
342
343         if ( bSync )
344                 This->prop.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
345         else
346                 This->prop.dwSampleFlags &= ~AM_SAMPLE_SPLICEPOINT;
347
348         return NOERROR;
349 }
350
351 static HRESULT WINAPI
352 IMediaSample2_fnIsPreroll(IMediaSample2* iface)
353 {
354         ICOM_THIS(CMemMediaSample,iface);
355
356         TRACE("(%p)->()\n",This);
357
358         return ( This->prop.dwSampleFlags & AM_SAMPLE_PREROLL ) ?
359                                                 S_OK : S_FALSE;
360 }
361
362 static HRESULT WINAPI
363 IMediaSample2_fnSetPreroll(IMediaSample2* iface,BOOL bPreroll)
364 {
365         ICOM_THIS(CMemMediaSample,iface);
366
367         TRACE("(%p)->(%d)\n",This,bPreroll);
368
369         if ( bPreroll )
370                 This->prop.dwSampleFlags |= AM_SAMPLE_PREROLL;
371         else
372                 This->prop.dwSampleFlags &= ~AM_SAMPLE_PREROLL;
373
374         return NOERROR;
375 }
376
377 static long WINAPI
378 IMediaSample2_fnGetActualDataLength(IMediaSample2* iface)
379 {
380         ICOM_THIS(CMemMediaSample,iface);
381
382         TRACE("(%p)->()\n",This);
383
384         return This->prop.lActual;
385 }
386
387 static HRESULT WINAPI
388 IMediaSample2_fnSetActualDataLength(IMediaSample2* iface,long lLength)
389 {
390         ICOM_THIS(CMemMediaSample,iface);
391
392         TRACE("(%p)->(%ld)\n",This,lLength);
393
394         if ( This->prop.cbBuffer < lLength )
395                 return E_INVALIDARG;
396
397         This->prop.lActual = lLength;
398         return NOERROR;
399 }
400
401 static HRESULT WINAPI
402 IMediaSample2_fnGetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE** ppmt)
403 {
404         ICOM_THIS(CMemMediaSample,iface);
405
406         TRACE("(%p)->(%p)\n",This,ppmt);
407
408         if ( ppmt == NULL )
409                 return E_POINTER;
410         *ppmt = NULL;
411         if ( !(This->prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) )
412                 return S_FALSE;
413
414         *ppmt = QUARTZ_MediaType_Duplicate( This->prop.pMediaType );
415         if ( *ppmt == NULL )
416                 return E_OUTOFMEMORY;
417
418         return NOERROR;
419 }
420
421 static HRESULT WINAPI
422 IMediaSample2_fnSetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE* pmt)
423 {
424         ICOM_THIS(CMemMediaSample,iface);
425         AM_MEDIA_TYPE* pmtDup;
426
427         TRACE("(%p)->(%p)\n",This,pmt);
428
429         if ( pmt == NULL )
430         {
431                 /* FIXME? */
432                 if ( This->prop.pMediaType != NULL )
433                 {
434                         QUARTZ_MediaType_Destroy( This->prop.pMediaType );
435                         This->prop.pMediaType = NULL;
436                 }
437                 This->prop.dwSampleFlags &= ~AM_SAMPLE_TYPECHANGED;
438                 return NOERROR;
439         }
440
441         pmtDup = QUARTZ_MediaType_Duplicate( pmt );
442         if ( pmtDup == NULL )
443                 return E_OUTOFMEMORY;
444
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;
449
450         return NOERROR;
451 }
452
453 static HRESULT WINAPI
454 IMediaSample2_fnIsDiscontinuity(IMediaSample2* iface)
455 {
456         ICOM_THIS(CMemMediaSample,iface);
457
458         TRACE("(%p)->()\n",This);
459
460         return ( This->prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY ) ?
461                                                 S_OK : S_FALSE;
462 }
463
464 static HRESULT WINAPI
465 IMediaSample2_fnSetDiscontinuity(IMediaSample2* iface,BOOL bDiscontinuity)
466 {
467         ICOM_THIS(CMemMediaSample,iface);
468
469         TRACE("(%p)->(%d)\n",This,bDiscontinuity);
470
471         if ( bDiscontinuity )
472                 This->prop.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
473         else
474                 This->prop.dwSampleFlags &= ~AM_SAMPLE_DATADISCONTINUITY;
475
476         return NOERROR;
477 }
478
479 static HRESULT WINAPI
480 IMediaSample2_fnGetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
481 {
482         ICOM_THIS(CMemMediaSample,iface);
483
484         TRACE("(%p)->(%p,%p)\n",This,pTimeStart,pTimeEnd);
485
486         if ( pTimeStart == NULL || pTimeEnd == NULL )
487                 return E_POINTER;
488
489         if ( !This->fMediaTimeIsValid )
490                 return VFW_E_MEDIA_TIME_NOT_SET;
491
492         *pTimeStart = This->llMediaTimeStart;
493         *pTimeEnd = This->llMediaTimeEnd;
494
495         return NOERROR;
496
497         return E_NOTIMPL;
498 }
499
500 static HRESULT WINAPI
501 IMediaSample2_fnSetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
502 {
503         ICOM_THIS(CMemMediaSample,iface);
504
505         TRACE("(%p)->()\n",This);
506         if ( pTimeStart == NULL || pTimeEnd == NULL )
507         {
508                 This->fMediaTimeIsValid = FALSE;
509         }
510         else
511         {
512                 This->fMediaTimeIsValid = TRUE;
513                 This->llMediaTimeStart = *pTimeStart;
514                 This->llMediaTimeEnd = *pTimeEnd;
515         }
516
517         return NOERROR;
518 }
519
520
521 static HRESULT WINAPI
522 IMediaSample2_fnGetProperties(IMediaSample2* iface,DWORD cbProp,BYTE* pbProp)
523 {
524         ICOM_THIS(CMemMediaSample,iface);
525
526         TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
527
528         if ( cbProp < 0 || cbProp > sizeof(AM_SAMPLE2_PROPERTIES) )
529                 return E_FAIL;
530         memcpy( pbProp, &This->prop, cbProp );
531
532         return NOERROR;
533 }
534
535 static HRESULT WINAPI
536 IMediaSample2_fnSetProperties(IMediaSample2* iface,DWORD cbProp,const BYTE* pbProp)
537 {
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;
543
544         TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
545
546         if ( pbProp == NULL )
547                 return E_POINTER;
548         pProp = (const AM_SAMPLE2_PROPERTIES*)pbProp;
549         if ( cbProp != sizeof(AM_SAMPLE2_PROPERTIES) )
550                 goto err;
551
552         CopyMemory( &propNew, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
553         if ( propNew.cbData != sizeof(AM_SAMPLE2_PROPERTIES) )
554                 goto err;
555
556         if ( This->prop.cbBuffer < propNew.lActual )
557                 goto err;
558
559         if ( propNew.dwSampleFlags & AM_SAMPLE_TYPECHANGED )
560         {
561                 pmtDup = QUARTZ_MediaType_Duplicate( propNew.pMediaType );
562                 if ( pmtDup == NULL )
563                 {
564                         hr = E_OUTOFMEMORY;
565                         goto err;
566                 }
567         }
568
569         if ( propNew.pbBuffer != NULL && propNew.pbBuffer != This->prop.pbBuffer )
570                 goto err;
571         if ( propNew.cbBuffer != 0 && propNew.cbBuffer != This->prop.cbBuffer )
572                 goto err;
573
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;
578         pmtDup = NULL;
579
580         hr= NOERROR;
581 err:
582         if ( pmtDup != NULL )
583                 QUARTZ_MediaType_Destroy( pmtDup );
584
585         return hr;
586 }
587
588
589 static ICOM_VTABLE(IMediaSample2) imediasample2 =
590 {
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,
616 };
617
618
619 /***************************************************************************
620  *
621  *      new/delete for CMemMediaSample
622  *
623  */
624
625 HRESULT QUARTZ_CreateMemMediaSample(
626         BYTE* pbData, DWORD dwDataLength,
627         IMemAllocator* pOwner,
628         CMemMediaSample** ppSample )
629 {
630         CMemMediaSample*        pms;
631
632         TRACE("(%p,%08lx,%p,%p)\n",pbData,dwDataLength,pOwner,ppSample);
633         pms = (CMemMediaSample*)QUARTZ_AllocObj( sizeof(CMemMediaSample) );
634         if ( pms == NULL )
635                 return E_OUTOFMEMORY;
636
637         ICOM_VTBL(pms) = &imediasample2;
638         pms->ref = 0;
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;
650
651         *ppSample = pms;
652
653         return S_OK;
654 }
655
656 void QUARTZ_DestroyMemMediaSample(
657         CMemMediaSample* pSample )
658 {
659         TRACE("(%p)\n",pSample);
660
661         QUARTZ_FreeObj( pSample );
662 }
663