source: trunk/src/quartz/sample.c@ 8266

Last change on this file since 8266 was 6952, checked in by sandervl, 24 years ago

Wine 20011004 resync

File size: 10.6 KB
Line 
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 "wine/obj_base.h"
15#include "strmif.h"
16#include "vfwmsgs.h"
17
18#include "debugtools.h"
19DEFAULT_DEBUG_CHANNEL(quartz);
20
21#include "quartz_private.h"
22#include "sample.h"
23#include "mtype.h"
24
25
26/***************************************************************************
27 *
28 * CMemMediaSample::IMediaSample2
29 *
30 */
31
32static HRESULT WINAPI
33IMediaSample2_fnQueryInterface(IMediaSample2* iface,REFIID riid,void** ppobj)
34{
35 ICOM_THIS(CMemMediaSample,iface);
36
37 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
38
39 if ( ppobj == NULL )
40 return E_POINTER;
41
42 if ( IsEqualGUID( riid, &IID_IUnknown ) ||
43 IsEqualGUID( riid, &IID_IMediaSample ) ||
44 IsEqualGUID( riid, &IID_IMediaSample2 ) )
45 {
46 *ppobj = iface;
47 IMediaSample2_AddRef(iface);
48 return NOERROR;
49 }
50
51 return E_NOINTERFACE;
52}
53
54static ULONG WINAPI
55IMediaSample2_fnAddRef(IMediaSample2* iface)
56{
57 ICOM_THIS(CMemMediaSample,iface);
58
59 TRACE("(%p)->()\n",This);
60
61 return InterlockedExchangeAdd(&(This->ref),1) + 1;
62}
63
64static ULONG WINAPI
65IMediaSample2_fnRelease(IMediaSample2* iface)
66{
67 ICOM_THIS(CMemMediaSample,iface);
68 LONG ref;
69
70 TRACE("(%p)->()\n",This);
71
72 ref = InterlockedExchangeAdd(&(This->ref),-1) - 1;
73 if ( ref > 0 )
74 return (ULONG)ref;
75
76 /* this class would be reused.. */
77 if ( This->prop.pMediaType != NULL )
78 {
79 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
80 This->prop.pMediaType = NULL;
81 }
82 This->prop.dwTypeSpecificFlags = 0;
83 This->prop.dwSampleFlags = 0;
84 This->prop.lActual = This->prop.cbBuffer;
85
86 IMemAllocator_ReleaseBuffer(This->pOwner,(IMediaSample*)iface);
87
88 return 0;
89}
90
91
92
93static HRESULT WINAPI
94IMediaSample2_fnGetPointer(IMediaSample2* iface,BYTE** ppData)
95{
96 ICOM_THIS(CMemMediaSample,iface);
97
98 TRACE("(%p)->()\n",This);
99
100 if ( ppData == NULL )
101 return E_POINTER;
102
103 *ppData = This->prop.pbBuffer;
104 return NOERROR;
105}
106
107static long WINAPI
108IMediaSample2_fnGetSize(IMediaSample2* iface)
109{
110 ICOM_THIS(CMemMediaSample,iface);
111
112 TRACE("(%p)->()\n",This);
113
114 return This->prop.cbBuffer;
115}
116
117static HRESULT WINAPI
118IMediaSample2_fnGetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
119{
120 ICOM_THIS(CMemMediaSample,iface);
121
122 TRACE("(%p)->(%p,%p)\n",This,prtStart,prtEnd);
123
124 if ( prtStart == NULL || prtEnd == NULL )
125 return E_POINTER;
126
127 if ( ( This->prop.dwSampleFlags & AM_SAMPLE_TIMEVALID ) &&
128 ( This->prop.dwSampleFlags & AM_SAMPLE_STOPVALID ) )
129 {
130 *prtStart = This->prop.tStart;
131 *prtEnd = This->prop.tStop;
132 return NOERROR;
133 }
134
135 return VFW_E_MEDIA_TIME_NOT_SET;
136}
137
138static HRESULT WINAPI
139IMediaSample2_fnSetTime(IMediaSample2* iface,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd)
140{
141 ICOM_THIS(CMemMediaSample,iface);
142
143 TRACE("(%p)->(%p,%p) stub!\n",This,prtStart,prtEnd);
144
145 This->prop.dwSampleFlags &= ~(AM_SAMPLE_TIMEVALID|AM_SAMPLE_STOPVALID);
146 if ( prtStart != NULL )
147 {
148 This->prop.dwSampleFlags |= AM_SAMPLE_TIMEVALID;
149 This->prop.tStart = *prtStart;
150 }
151 if ( prtEnd != NULL )
152 {
153 This->prop.dwSampleFlags |= AM_SAMPLE_STOPVALID;
154 This->prop.tStop = *prtEnd;
155 }
156
157 return NOERROR;
158}
159
160static HRESULT WINAPI
161IMediaSample2_fnIsSyncPoint(IMediaSample2* iface)
162{
163 ICOM_THIS(CMemMediaSample,iface);
164
165 TRACE("(%p)->()\n",This);
166
167 return ( This->prop.dwSampleFlags & AM_SAMPLE_SPLICEPOINT ) ?
168 S_OK : S_FALSE;
169}
170
171static HRESULT WINAPI
172IMediaSample2_fnSetSyncPoint(IMediaSample2* iface,BOOL bSync)
173{
174 ICOM_THIS(CMemMediaSample,iface);
175
176 TRACE("(%p)->(%d)\n",This,bSync);
177
178 if ( bSync )
179 This->prop.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
180 else
181 This->prop.dwSampleFlags &= ~AM_SAMPLE_SPLICEPOINT;
182
183 return NOERROR;
184}
185
186static HRESULT WINAPI
187IMediaSample2_fnIsPreroll(IMediaSample2* iface)
188{
189 ICOM_THIS(CMemMediaSample,iface);
190
191 TRACE("(%p)->()\n",This);
192
193 return ( This->prop.dwSampleFlags & AM_SAMPLE_PREROLL ) ?
194 S_OK : S_FALSE;
195}
196
197static HRESULT WINAPI
198IMediaSample2_fnSetPreroll(IMediaSample2* iface,BOOL bPreroll)
199{
200 ICOM_THIS(CMemMediaSample,iface);
201
202 TRACE("(%p)->(%d)\n",This,bPreroll);
203
204 if ( bPreroll )
205 This->prop.dwSampleFlags |= AM_SAMPLE_PREROLL;
206 else
207 This->prop.dwSampleFlags &= ~AM_SAMPLE_PREROLL;
208
209 return NOERROR;
210}
211
212static long WINAPI
213IMediaSample2_fnGetActualDataLength(IMediaSample2* iface)
214{
215 ICOM_THIS(CMemMediaSample,iface);
216
217 TRACE("(%p)->()\n",This);
218
219 return This->prop.lActual;
220}
221
222static HRESULT WINAPI
223IMediaSample2_fnSetActualDataLength(IMediaSample2* iface,long lLength)
224{
225 ICOM_THIS(CMemMediaSample,iface);
226
227 TRACE("(%p)->(%ld)\n",This,lLength);
228
229 if ( This->prop.cbBuffer > lLength )
230 return E_INVALIDARG;
231
232 This->prop.lActual = lLength;
233 return NOERROR;
234}
235
236static HRESULT WINAPI
237IMediaSample2_fnGetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE** ppmt)
238{
239 ICOM_THIS(CMemMediaSample,iface);
240
241 TRACE("(%p)->(%p)\n",This,ppmt);
242
243 if ( ppmt == NULL )
244 return E_POINTER;
245 *ppmt = NULL;
246 if ( !(This->prop.dwSampleFlags & AM_SAMPLE_TYPECHANGED) )
247 return S_FALSE;
248
249 *ppmt = QUARTZ_MediaType_Duplicate( This->prop.pMediaType );
250 if ( *ppmt == NULL )
251 return E_OUTOFMEMORY;
252
253 return NOERROR;
254}
255
256static HRESULT WINAPI
257IMediaSample2_fnSetMediaType(IMediaSample2* iface,AM_MEDIA_TYPE* pmt)
258{
259 ICOM_THIS(CMemMediaSample,iface);
260 AM_MEDIA_TYPE* pmtDup;
261
262 TRACE("(%p)->(%p)\n",This,pmt);
263
264 if ( pmt == NULL )
265 {
266 /* FIXME? */
267 if ( This->prop.pMediaType != NULL )
268 {
269 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
270 This->prop.pMediaType = NULL;
271 }
272 This->prop.dwSampleFlags &= ~AM_SAMPLE_TYPECHANGED;
273 return NOERROR;
274 }
275
276 pmtDup = QUARTZ_MediaType_Duplicate( pmt );
277 if ( pmtDup == NULL )
278 return E_OUTOFMEMORY;
279
280 if ( This->prop.pMediaType != NULL )
281 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
282 This->prop.dwSampleFlags |= AM_SAMPLE_TYPECHANGED;
283 This->prop.pMediaType = pmtDup;
284
285 return NOERROR;
286}
287
288static HRESULT WINAPI
289IMediaSample2_fnIsDiscontinuity(IMediaSample2* iface)
290{
291 ICOM_THIS(CMemMediaSample,iface);
292
293 TRACE("(%p)->()\n",This);
294
295 return ( This->prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY ) ?
296 S_OK : S_FALSE;
297}
298
299static HRESULT WINAPI
300IMediaSample2_fnSetDiscontinuity(IMediaSample2* iface,BOOL bDiscontinuity)
301{
302 ICOM_THIS(CMemMediaSample,iface);
303
304 TRACE("(%p)->(%d)\n",This,bDiscontinuity);
305
306 if ( bDiscontinuity )
307 This->prop.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
308 else
309 This->prop.dwSampleFlags &= ~AM_SAMPLE_DATADISCONTINUITY;
310
311 return NOERROR;
312}
313
314static HRESULT WINAPI
315IMediaSample2_fnGetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
316{
317 ICOM_THIS(CMemMediaSample,iface);
318
319 TRACE("(%p)->(%p,%p)\n",This,pTimeStart,pTimeEnd);
320
321 if ( pTimeStart == NULL || pTimeEnd == NULL )
322 return E_POINTER;
323
324 if ( !This->fMediaTimeIsValid )
325 return VFW_E_MEDIA_TIME_NOT_SET;
326
327 *pTimeStart = This->llMediaTimeStart;
328 *pTimeEnd = This->llMediaTimeEnd;
329
330 return NOERROR;
331
332 return E_NOTIMPL;
333}
334
335static HRESULT WINAPI
336IMediaSample2_fnSetMediaTime(IMediaSample2* iface,LONGLONG* pTimeStart,LONGLONG* pTimeEnd)
337{
338 ICOM_THIS(CMemMediaSample,iface);
339
340 TRACE("(%p)->()\n",This);
341 if ( pTimeStart == NULL || pTimeEnd == NULL )
342 {
343 This->fMediaTimeIsValid = FALSE;
344 }
345 else
346 {
347 This->fMediaTimeIsValid = TRUE;
348 This->llMediaTimeStart = *pTimeStart;
349 This->llMediaTimeEnd = *pTimeEnd;
350 }
351
352 return NOERROR;
353}
354
355
356static HRESULT WINAPI
357IMediaSample2_fnGetProperties(IMediaSample2* iface,DWORD cbProp,BYTE* pbProp)
358{
359 ICOM_THIS(CMemMediaSample,iface);
360
361 TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
362
363 if ( cbProp < 0 || cbProp > sizeof(AM_SAMPLE2_PROPERTIES) )
364 return E_FAIL;
365 memcpy( pbProp, &This->prop, cbProp );
366
367 return NOERROR;
368}
369
370static HRESULT WINAPI
371IMediaSample2_fnSetProperties(IMediaSample2* iface,DWORD cbProp,const BYTE* pbProp)
372{
373 ICOM_THIS(CMemMediaSample,iface);
374 const AM_SAMPLE2_PROPERTIES* pProp;
375 AM_SAMPLE2_PROPERTIES propNew;
376 AM_MEDIA_TYPE* pmtDup = NULL;
377 HRESULT hr = E_INVALIDARG;
378
379 TRACE("(%p)->(%lu,%p)\n",This,cbProp,pbProp);
380
381 if ( pbProp == NULL )
382 return E_POINTER;
383 pProp = (const AM_SAMPLE2_PROPERTIES*)pbProp;
384 if ( cbProp != sizeof(AM_SAMPLE2_PROPERTIES) )
385 goto err;
386
387 CopyMemory( &propNew, pProp, sizeof(AM_SAMPLE2_PROPERTIES) );
388 if ( propNew.cbData != sizeof(AM_SAMPLE2_PROPERTIES) )
389 goto err;
390
391 if ( This->prop.cbBuffer < propNew.lActual )
392 goto err;
393
394 if ( propNew.dwSampleFlags & AM_SAMPLE_TYPECHANGED )
395 {
396 pmtDup = QUARTZ_MediaType_Duplicate( propNew.pMediaType );
397 if ( pmtDup == NULL )
398 {
399 hr = E_OUTOFMEMORY;
400 goto err;
401 }
402 }
403
404 if ( propNew.pbBuffer != NULL && propNew.pbBuffer != This->prop.pbBuffer )
405 goto err;
406 if ( propNew.cbBuffer != 0 && propNew.cbBuffer != This->prop.cbBuffer )
407 goto err;
408
409 if ( This->prop.pMediaType != NULL )
410 QUARTZ_MediaType_Destroy( This->prop.pMediaType );
411 CopyMemory( &This->prop, &propNew, sizeof(AM_SAMPLE2_PROPERTIES) );
412 This->prop.pMediaType = pmtDup;
413 pmtDup = NULL;
414
415 hr= NOERROR;
416err:
417 if ( pmtDup != NULL )
418 QUARTZ_MediaType_Destroy( pmtDup );
419
420 return hr;
421}
422
423
424static ICOM_VTABLE(IMediaSample2) imediasample2 =
425{
426 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
427 /* IUnknown fields */
428 IMediaSample2_fnQueryInterface,
429 IMediaSample2_fnAddRef,
430 IMediaSample2_fnRelease,
431 /* IMediaSample fields */
432 IMediaSample2_fnGetPointer,
433 IMediaSample2_fnGetSize,
434 IMediaSample2_fnGetTime,
435 IMediaSample2_fnSetTime,
436 IMediaSample2_fnIsSyncPoint,
437 IMediaSample2_fnSetSyncPoint,
438 IMediaSample2_fnIsPreroll,
439 IMediaSample2_fnSetPreroll,
440 IMediaSample2_fnGetActualDataLength,
441 IMediaSample2_fnSetActualDataLength,
442 IMediaSample2_fnGetMediaType,
443 IMediaSample2_fnSetMediaType,
444 IMediaSample2_fnIsDiscontinuity,
445 IMediaSample2_fnSetDiscontinuity,
446 IMediaSample2_fnGetMediaTime,
447 IMediaSample2_fnSetMediaTime,
448 /* IMediaSample2 fields */
449 IMediaSample2_fnGetProperties,
450 IMediaSample2_fnSetProperties,
451};
452
453
454/***************************************************************************
455 *
456 * new/delete for CMemMediaSample
457 *
458 */
459
460HRESULT QUARTZ_CreateMemMediaSample(
461 BYTE* pbData, DWORD dwDataLength,
462 IMemAllocator* pOwner,
463 CMemMediaSample** ppSample )
464{
465 CMemMediaSample* pms;
466
467 TRACE("(%p,%08lx,%p,%p)\n",pbData,dwDataLength,pOwner,ppSample);
468 pms = (CMemMediaSample*)QUARTZ_AllocObj( sizeof(CMemMediaSample) );
469 if ( pms == NULL )
470 return E_OUTOFMEMORY;
471
472 ICOM_VTBL(pms) = &imediasample2;
473 pms->ref = 0;
474 pms->pOwner = pOwner;
475 pms->fMediaTimeIsValid = FALSE;
476 pms->llMediaTimeStart = 0;
477 pms->llMediaTimeEnd = 0;
478 ZeroMemory( &(pms->prop), sizeof(pms->prop) );
479 pms->prop.cbData = sizeof(pms->prop);
480 pms->prop.dwTypeSpecificFlags = 0;
481 pms->prop.dwSampleFlags = 0;
482 pms->prop.pbBuffer = pbData;
483 pms->prop.cbBuffer = (LONG)dwDataLength;
484 pms->prop.lActual = (LONG)dwDataLength;
485
486 *ppSample = pms;
487
488 return S_OK;
489}
490
491void QUARTZ_DestroyMemMediaSample(
492 CMemMediaSample* pSample )
493{
494 TRACE("(%p)\n",pSample);
495
496 QUARTZ_FreeObj( pSample );
497}
498
Note: See TracBrowser for help on using the repository browser.