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