atl100: Added AtlWaitWithMessageLoop implementation.
[wine] / dlls / amstream / mediastream.c
1 /*
2  * Implementation of IMediaStream Interfaces
3  *
4  * Copyright 2005, 2008, 2012 Christian Costa
5  *
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.
10  *
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.
15  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "wine/debug.h"
22
23 #define COBJMACROS
24
25 #include "winbase.h"
26 #include "wingdi.h"
27
28 #include "amstream_private.h"
29 #include "amstream.h"
30
31 #include "ddstream.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(amstream);
34
35 static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectDrawStreamSample **ddraw_stream_sample);
36 static HRESULT audiostreamsample_create(IAudioMediaStream *parent, IAudioData *audio_data, IAudioStreamSample **audio_stream_sample);
37
38 typedef struct {
39     IAMMediaStream IAMMediaStream_iface;
40     IDirectDrawMediaStream IDirectDrawMediaStream_iface;
41     LONG ref;
42     IMultiMediaStream* parent;
43     MSPID purpose_id;
44     STREAM_TYPE stream_type;
45 } DirectDrawMediaStreamImpl;
46
47 static inline DirectDrawMediaStreamImpl *impl_from_DirectDrawMediaStream_IAMMediaStream(IAMMediaStream *iface)
48 {
49     return CONTAINING_RECORD(iface, DirectDrawMediaStreamImpl, IAMMediaStream_iface);
50 }
51
52 /*** IUnknown methods ***/
53 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_QueryInterface(IAMMediaStream *iface,
54                                                         REFIID riid, void **ret_iface)
55 {
56     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
57
58     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface);
59
60     if (IsEqualGUID(riid, &IID_IUnknown) ||
61         IsEqualGUID(riid, &IID_IMediaStream) ||
62         IsEqualGUID(riid, &IID_IAMMediaStream))
63     {
64         IAMMediaStream_AddRef(iface);
65         *ret_iface = iface;
66         return S_OK;
67     }
68     else if (IsEqualGUID(riid, &IID_IDirectDrawMediaStream))
69     {
70         IAMMediaStream_AddRef(iface);
71         *ret_iface = &This->IDirectDrawMediaStream_iface;
72         return S_OK;
73     }
74
75     ERR("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ret_iface);
76     return E_NOINTERFACE;
77 }
78
79 static ULONG WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_AddRef(IAMMediaStream *iface)
80 {
81     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
82     ULONG ref = InterlockedIncrement(&This->ref);
83
84     TRACE("(%p/%p)->(): new ref = %u\n", iface, This, ref);
85
86     return ref;
87 }
88
89 static ULONG WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_Release(IAMMediaStream *iface)
90 {
91     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
92     ULONG ref = InterlockedDecrement(&This->ref);
93
94     TRACE("(%p/%p)->(): new ref = %u\n", iface, This, ref);
95
96     if (!ref)
97         HeapFree(GetProcessHeap(), 0, This);
98
99     return ref;
100 }
101
102 /*** IMediaStream methods ***/
103 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_GetMultiMediaStream(IAMMediaStream *iface,
104         IMultiMediaStream** multi_media_stream)
105 {
106     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
107
108     FIXME("(%p/%p)->(%p) stub!\n", This, iface, multi_media_stream);
109
110     return S_FALSE;
111 }
112
113 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_GetInformation(IAMMediaStream *iface,
114         MSPID *purpose_id, STREAM_TYPE *type)
115 {
116     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
117
118     TRACE("(%p/%p)->(%p,%p)\n", This, iface, purpose_id, type);
119
120     if (purpose_id)
121         *purpose_id = This->purpose_id;
122     if (type)
123         *type = This->stream_type;
124
125     return S_OK;
126 }
127
128 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_SetSameFormat(IAMMediaStream *iface,
129         IMediaStream *pStreamThatHasDesiredFormat, DWORD flags)
130 {
131     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
132
133     FIXME("(%p/%p)->(%p,%x) stub!\n", This, iface, pStreamThatHasDesiredFormat, flags);
134
135     return S_FALSE;
136 }
137
138 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_AllocateSample(IAMMediaStream *iface,
139         DWORD flags, IStreamSample **sample)
140 {
141     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
142
143     FIXME("(%p/%p)->(%x,%p) stub!\n", This, iface, flags, sample);
144
145     return S_FALSE;
146 }
147
148 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_CreateSharedSample(IAMMediaStream *iface,
149         IStreamSample *existing_sample, DWORD flags, IStreamSample **sample)
150 {
151     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
152
153     FIXME("(%p/%p)->(%p,%x,%p) stub!\n", This, iface, existing_sample, flags, sample);
154
155     return S_FALSE;
156 }
157
158 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_SendEndOfStream(IAMMediaStream *iface, DWORD flags)
159 {
160     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
161
162     FIXME("(%p/%p)->(%x) stub!\n", This, iface, flags);
163
164     return S_FALSE;
165 }
166
167 /*** IAMMediaStream methods ***/
168 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_Initialize(IAMMediaStream *iface, IUnknown *source_object, DWORD flags,
169                                                     REFMSPID purpose_id, const STREAM_TYPE stream_type)
170 {
171     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
172
173     FIXME("(%p/%p)->(%p,%x,%p,%u) stub!\n", This, iface, source_object, flags, purpose_id, stream_type);
174
175     return S_FALSE;
176 }
177
178 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_SetState(IAMMediaStream *iface, FILTER_STATE state)
179 {
180     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
181
182     FIXME("(%p/%p)->(%u) stub!\n", This, iface, state);
183
184     return S_FALSE;
185 }
186
187 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_JoinAMMultiMediaStream(IAMMediaStream *iface, IAMMultiMediaStream *am_multi_media_stream)
188 {
189     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
190
191     FIXME("(%p/%p)->(%p) stub!\n", This, iface, am_multi_media_stream);
192
193     return S_FALSE;
194 }
195
196 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_JoinFilter(IAMMediaStream *iface, IMediaStreamFilter *media_stream_filter)
197 {
198     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
199
200     FIXME("(%p/%p)->(%p) stub!\n", This, iface, media_stream_filter);
201
202     return S_FALSE;
203 }
204
205 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_JoinFilterGraph(IAMMediaStream *iface, IFilterGraph *filtergraph)
206 {
207     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
208
209     FIXME("(%p/%p)->(%p) stub!\n", This, iface, filtergraph);
210
211     return S_FALSE;
212 }
213
214 static const struct IAMMediaStreamVtbl DirectDrawMediaStreamImpl_IAMMediaStream_Vtbl =
215 {
216     /*** IUnknown methods ***/
217     DirectDrawMediaStreamImpl_IAMMediaStream_QueryInterface,
218     DirectDrawMediaStreamImpl_IAMMediaStream_AddRef,
219     DirectDrawMediaStreamImpl_IAMMediaStream_Release,
220     /*** IMediaStream methods ***/
221     DirectDrawMediaStreamImpl_IAMMediaStream_GetMultiMediaStream,
222     DirectDrawMediaStreamImpl_IAMMediaStream_GetInformation,
223     DirectDrawMediaStreamImpl_IAMMediaStream_SetSameFormat,
224     DirectDrawMediaStreamImpl_IAMMediaStream_AllocateSample,
225     DirectDrawMediaStreamImpl_IAMMediaStream_CreateSharedSample,
226     DirectDrawMediaStreamImpl_IAMMediaStream_SendEndOfStream,
227     /*** IAMMediaStream methods ***/
228     DirectDrawMediaStreamImpl_IAMMediaStream_Initialize,
229     DirectDrawMediaStreamImpl_IAMMediaStream_SetState,
230     DirectDrawMediaStreamImpl_IAMMediaStream_JoinAMMultiMediaStream,
231     DirectDrawMediaStreamImpl_IAMMediaStream_JoinFilter,
232     DirectDrawMediaStreamImpl_IAMMediaStream_JoinFilterGraph
233 };
234
235 static inline DirectDrawMediaStreamImpl *impl_from_IDirectDrawMediaStream(IDirectDrawMediaStream *iface)
236 {
237     return CONTAINING_RECORD(iface, DirectDrawMediaStreamImpl, IDirectDrawMediaStream_iface);
238 }
239
240 /*** IUnknown methods ***/
241 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_QueryInterface(IDirectDrawMediaStream *iface,
242         REFIID riid, void **ret_iface)
243 {
244     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
245
246     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface);
247
248     if (IsEqualGUID(riid, &IID_IUnknown) ||
249         IsEqualGUID(riid, &IID_IMediaStream) ||
250         IsEqualGUID(riid, &IID_IDirectDrawMediaStream))
251     {
252         IDirectDrawMediaStream_AddRef(iface);
253         *ret_iface = iface;
254         return S_OK;
255     }
256     else if (IsEqualGUID(riid, &IID_IAMMediaStream))
257     {
258         IDirectDrawMediaStream_AddRef(iface);
259         *ret_iface = &This->IAMMediaStream_iface;
260         return S_OK;
261     }
262
263     ERR("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ret_iface);
264     return E_NOINTERFACE;
265 }
266
267 static ULONG WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AddRef(IDirectDrawMediaStream *iface)
268 {
269     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
270
271     TRACE("(%p/%p)\n", iface, This);
272
273     return InterlockedIncrement(&This->ref);
274 }
275
276 static ULONG WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_Release(IDirectDrawMediaStream *iface)
277 {
278     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
279     ULONG ref = InterlockedDecrement(&This->ref);
280
281     TRACE("(%p/%p)\n", iface, This);
282
283     if (!ref)
284         HeapFree(GetProcessHeap(), 0, This);
285
286     return ref;
287 }
288
289 /*** IMediaStream methods ***/
290 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetMultiMediaStream(IDirectDrawMediaStream *iface,
291         IMultiMediaStream** ppMultiMediaStream)
292 {
293     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
294
295     FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppMultiMediaStream);
296
297     return S_FALSE;
298 }
299
300 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetInformation(IDirectDrawMediaStream *iface,
301         MSPID *purpose_id, STREAM_TYPE *type)
302 {
303     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
304
305     TRACE("(%p/%p)->(%p,%p)\n", This, iface, purpose_id, type);
306
307     if (purpose_id)
308         *purpose_id = This->purpose_id;
309     if (type)
310         *type = This->stream_type;
311
312     return S_OK;
313 }
314
315 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetSameFormat(IDirectDrawMediaStream *iface,
316         IMediaStream *pStreamThatHasDesiredFormat, DWORD dwFlags)
317 {
318     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
319
320     FIXME("(%p/%p)->(%p,%x) stub!\n", This, iface, pStreamThatHasDesiredFormat, dwFlags);
321
322     return S_FALSE;
323 }
324
325 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AllocateSample(IDirectDrawMediaStream *iface,
326         DWORD dwFlags, IStreamSample **ppSample)
327 {
328     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
329
330     FIXME("(%p/%p)->(%x,%p) stub!\n", This, iface, dwFlags, ppSample);
331
332     return S_FALSE;
333 }
334
335 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSharedSample(IDirectDrawMediaStream *iface,
336         IStreamSample *pExistingSample, DWORD dwFlags, IStreamSample **ppSample)
337 {
338     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
339
340     FIXME("(%p/%p)->(%p,%x,%p) stub!\n", This, iface, pExistingSample, dwFlags, ppSample);
341
342     return S_FALSE;
343 }
344
345 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SendEndOfStream(IDirectDrawMediaStream *iface,
346         DWORD dwFlags)
347 {
348     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
349
350     FIXME("(%p/%p)->(%x) stub!\n", This, iface, dwFlags);
351
352     return S_FALSE;
353 }
354
355 /*** IDirectDrawMediaStream methods ***/
356 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetFormat(IDirectDrawMediaStream *iface,
357         DDSURFACEDESC *current_format, IDirectDrawPalette **palette,
358         DDSURFACEDESC *desired_format, DWORD *flags)
359 {
360     FIXME("(%p)->(%p,%p,%p,%p) stub!\n", iface, current_format, palette, desired_format,
361             flags);
362
363     return MS_E_NOSTREAM;
364
365 }
366
367 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream *iface,
368         const DDSURFACEDESC *pDDSurfaceDesc, IDirectDrawPalette *pDirectDrawPalette)
369 {
370     FIXME("(%p)->(%p,%p) stub!\n", iface, pDDSurfaceDesc, pDirectDrawPalette);
371
372     return E_NOTIMPL;
373 }
374
375 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetDirectDraw(IDirectDrawMediaStream *iface,
376         IDirectDraw **ppDirectDraw)
377 {
378     FIXME("(%p)->(%p) stub!\n", iface, ppDirectDraw);
379
380     return E_NOTIMPL;
381 }
382
383 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetDirectDraw(IDirectDrawMediaStream *iface,
384         IDirectDraw *pDirectDraw)
385 {
386     FIXME("(%p)->(%p) stub!\n", iface, pDirectDraw);
387
388     return E_NOTIMPL;
389 }
390
391 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSample(IDirectDrawMediaStream *iface,
392         IDirectDrawSurface *pSurface, const RECT *pRect, DWORD dwFlags,
393         IDirectDrawStreamSample **ppSample)
394 {
395     TRACE("(%p)->(%p,%p,%x,%p)\n", iface, pSurface, pRect, dwFlags, ppSample);
396
397     return ddrawstreamsample_create(iface, ppSample);
398 }
399
400 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetTimePerFrame(IDirectDrawMediaStream *iface,
401         STREAM_TIME *pFrameTime)
402 {
403     FIXME("(%p)->(%p) stub!\n", iface, pFrameTime);
404
405     return E_NOTIMPL;
406 }
407
408 static const struct IDirectDrawMediaStreamVtbl DirectDrawMediaStreamImpl_IDirectDrawMediaStream_Vtbl =
409 {
410     /*** IUnknown methods ***/
411     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_QueryInterface,
412     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AddRef,
413     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_Release,
414     /*** IMediaStream methods ***/
415     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetMultiMediaStream,
416     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetInformation,
417     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetSameFormat,
418     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AllocateSample,
419     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSharedSample,
420     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SendEndOfStream,
421     /*** IDirectDrawMediaStream methods ***/
422     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetFormat,
423     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetFormat,
424     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetDirectDraw,
425     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetDirectDraw,
426     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSample,
427     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetTimePerFrame
428 };
429
430 HRESULT ddrawmediastream_create(IMultiMediaStream *parent, const MSPID *purpose_id,
431         STREAM_TYPE stream_type, IMediaStream **media_stream)
432 {
433     DirectDrawMediaStreamImpl *object;
434
435     TRACE("(%p,%s,%p)\n", parent, debugstr_guid(purpose_id), media_stream);
436
437     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DirectDrawMediaStreamImpl));
438     if (!object)
439     {
440         ERR("Out of memory\n");
441         return E_OUTOFMEMORY;
442     }
443
444     object->IAMMediaStream_iface.lpVtbl = &DirectDrawMediaStreamImpl_IAMMediaStream_Vtbl;
445     object->IDirectDrawMediaStream_iface.lpVtbl = &DirectDrawMediaStreamImpl_IDirectDrawMediaStream_Vtbl;
446     object->ref = 1;
447
448     object->parent = parent;
449     object->purpose_id = *purpose_id;
450     object->stream_type = stream_type;
451
452     *media_stream = (IMediaStream*)&object->IAMMediaStream_iface;
453
454     return S_OK;
455 }
456
457 typedef struct {
458     IAMMediaStream IAMMediaStream_iface;
459     IAudioMediaStream IAudioMediaStream_iface;
460     LONG ref;
461     IMultiMediaStream* parent;
462     MSPID purpose_id;
463     STREAM_TYPE stream_type;
464 } AudioMediaStreamImpl;
465
466 static inline AudioMediaStreamImpl *impl_from_AudioMediaStream_IAMMediaStream(IAMMediaStream *iface)
467 {
468     return CONTAINING_RECORD(iface, AudioMediaStreamImpl, IAMMediaStream_iface);
469 }
470
471 /*** IUnknown methods ***/
472 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_QueryInterface(IAMMediaStream *iface,
473                                                         REFIID riid, void **ret_iface)
474 {
475     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
476
477     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface);
478
479     if (IsEqualGUID(riid, &IID_IUnknown) ||
480         IsEqualGUID(riid, &IID_IMediaStream) ||
481         IsEqualGUID(riid, &IID_IAMMediaStream))
482     {
483         IAMMediaStream_AddRef(iface);
484         *ret_iface = iface;
485         return S_OK;
486     }
487     else if (IsEqualGUID(riid, &IID_IAudioMediaStream))
488     {
489         IAMMediaStream_AddRef(iface);
490         *ret_iface = &This->IAudioMediaStream_iface;
491         return S_OK;
492     }
493
494     ERR("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ret_iface);
495     return E_NOINTERFACE;
496 }
497
498 static ULONG WINAPI AudioMediaStreamImpl_IAMMediaStream_AddRef(IAMMediaStream *iface)
499 {
500     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
501     ULONG ref = InterlockedIncrement(&This->ref);
502
503     TRACE("(%p/%p)->(): new ref = %u\n", iface, This, ref);
504
505     return ref;
506 }
507
508 static ULONG WINAPI AudioMediaStreamImpl_IAMMediaStream_Release(IAMMediaStream *iface)
509 {
510     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
511     ULONG ref = InterlockedDecrement(&This->ref);
512
513     TRACE("(%p/%p)->(): new ref = %u\n", iface, This, ref);
514
515     if (!ref)
516         HeapFree(GetProcessHeap(), 0, This);
517
518     return ref;
519 }
520
521 /*** IMediaStream methods ***/
522 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_GetMultiMediaStream(IAMMediaStream *iface,
523         IMultiMediaStream** multi_media_stream)
524 {
525     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
526
527     FIXME("(%p/%p)->(%p) stub!\n", This, iface, multi_media_stream);
528
529     return S_FALSE;
530 }
531
532 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_GetInformation(IAMMediaStream *iface,
533         MSPID *purpose_id, STREAM_TYPE *type)
534 {
535     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
536
537     TRACE("(%p/%p)->(%p,%p)\n", This, iface, purpose_id, type);
538
539     if (purpose_id)
540         *purpose_id = This->purpose_id;
541     if (type)
542         *type = This->stream_type;
543
544     return S_OK;
545 }
546
547 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_SetSameFormat(IAMMediaStream *iface,
548         IMediaStream *pStreamThatHasDesiredFormat, DWORD flags)
549 {
550     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
551
552     FIXME("(%p/%p)->(%p,%x) stub!\n", This, iface, pStreamThatHasDesiredFormat, flags);
553
554     return S_FALSE;
555 }
556
557 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_AllocateSample(IAMMediaStream *iface,
558         DWORD flags, IStreamSample **sample)
559 {
560     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
561
562     FIXME("(%p/%p)->(%x,%p) stub!\n", This, iface, flags, sample);
563
564     return S_FALSE;
565 }
566
567 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_CreateSharedSample(IAMMediaStream *iface,
568         IStreamSample *existing_sample, DWORD flags, IStreamSample **sample)
569 {
570     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
571
572     FIXME("(%p/%p)->(%p,%x,%p) stub!\n", This, iface, existing_sample, flags, sample);
573
574     return S_FALSE;
575 }
576
577 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_SendEndOfStream(IAMMediaStream *iface, DWORD flags)
578 {
579     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
580
581     FIXME("(%p/%p)->(%x) stub!\n", This, iface, flags);
582
583     return S_FALSE;
584 }
585
586 /*** IAMMediaStream methods ***/
587 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_Initialize(IAMMediaStream *iface, IUnknown *source_object, DWORD flags,
588                                                     REFMSPID purpose_id, const STREAM_TYPE stream_type)
589 {
590     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
591
592     FIXME("(%p/%p)->(%p,%x,%p,%u) stub!\n", This, iface, source_object, flags, purpose_id, stream_type);
593
594     return S_FALSE;
595 }
596
597 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_SetState(IAMMediaStream *iface, FILTER_STATE state)
598 {
599     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
600
601     FIXME("(%p/%p)->(%u) stub!\n", This, iface, state);
602
603     return S_FALSE;
604 }
605
606 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_JoinAMMultiMediaStream(IAMMediaStream *iface, IAMMultiMediaStream *am_multi_media_stream)
607 {
608     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
609
610     FIXME("(%p/%p)->(%p) stub!\n", This, iface, am_multi_media_stream);
611
612     return S_FALSE;
613 }
614
615 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_JoinFilter(IAMMediaStream *iface, IMediaStreamFilter *media_stream_filter)
616 {
617     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
618
619     FIXME("(%p/%p)->(%p) stub!\n", This, iface, media_stream_filter);
620
621     return S_FALSE;
622 }
623
624 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_JoinFilterGraph(IAMMediaStream *iface, IFilterGraph *filtergraph)
625 {
626     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
627
628     FIXME("(%p/%p)->(%p) stub!\n", This, iface, filtergraph);
629
630     return S_FALSE;
631 }
632
633 static const struct IAMMediaStreamVtbl AudioMediaStreamImpl_IAMMediaStream_Vtbl =
634 {
635     /*** IUnknown methods ***/
636     AudioMediaStreamImpl_IAMMediaStream_QueryInterface,
637     AudioMediaStreamImpl_IAMMediaStream_AddRef,
638     AudioMediaStreamImpl_IAMMediaStream_Release,
639     /*** IMediaStream methods ***/
640     AudioMediaStreamImpl_IAMMediaStream_GetMultiMediaStream,
641     AudioMediaStreamImpl_IAMMediaStream_GetInformation,
642     AudioMediaStreamImpl_IAMMediaStream_SetSameFormat,
643     AudioMediaStreamImpl_IAMMediaStream_AllocateSample,
644     AudioMediaStreamImpl_IAMMediaStream_CreateSharedSample,
645     AudioMediaStreamImpl_IAMMediaStream_SendEndOfStream,
646     /*** IAMMediaStream methods ***/
647     AudioMediaStreamImpl_IAMMediaStream_Initialize,
648     AudioMediaStreamImpl_IAMMediaStream_SetState,
649     AudioMediaStreamImpl_IAMMediaStream_JoinAMMultiMediaStream,
650     AudioMediaStreamImpl_IAMMediaStream_JoinFilter,
651     AudioMediaStreamImpl_IAMMediaStream_JoinFilterGraph
652 };
653
654 static inline AudioMediaStreamImpl *impl_from_IAudioMediaStream(IAudioMediaStream *iface)
655 {
656     return CONTAINING_RECORD(iface, AudioMediaStreamImpl, IAudioMediaStream_iface);
657 }
658
659 /*** IUnknown methods ***/
660 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_QueryInterface(IAudioMediaStream *iface,
661         REFIID riid, void **ret_iface)
662 {
663     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
664
665     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface);
666
667     if (IsEqualGUID(riid, &IID_IUnknown) ||
668         IsEqualGUID(riid, &IID_IMediaStream) ||
669         IsEqualGUID(riid, &IID_IAudioMediaStream))
670     {
671         IAudioMediaStream_AddRef(iface);
672         *ret_iface = iface;
673         return S_OK;
674     }
675     else if (IsEqualGUID(riid, &IID_IAMMediaStream))
676     {
677         IAudioMediaStream_AddRef(iface);
678         *ret_iface = &This->IAMMediaStream_iface;
679         return S_OK;
680     }
681
682
683     *ret_iface = NULL;
684
685     ERR("(%p/%p)->(%s,%p),not found\n", iface, This, debugstr_guid(riid), ret_iface);
686     return E_NOINTERFACE;
687 }
688
689 static ULONG WINAPI AudioMediaStreamImpl_IAudioMediaStream_AddRef(IAudioMediaStream *iface)
690 {
691     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
692     ULONG ref = InterlockedIncrement(&This->ref);
693
694     TRACE("(%p/%p): new ref = %u\n", iface, This, ref);
695
696     return ref;
697 }
698
699 static ULONG WINAPI AudioMediaStreamImpl_IAudioMediaStream_Release(IAudioMediaStream *iface)
700 {
701     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
702     ULONG ref = InterlockedDecrement(&This->ref);
703
704     TRACE("(%p/%p): new ref = %u\n", iface, This, ref);
705
706     if (!ref)
707         HeapFree(GetProcessHeap(), 0, This);
708
709     return ref;
710 }
711
712 /*** IMediaStream methods ***/
713 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_GetMultiMediaStream(IAudioMediaStream *iface,
714         IMultiMediaStream** multimedia_stream)
715 {
716     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
717
718     FIXME("(%p/%p)->(%p) stub!\n", iface, This, multimedia_stream);
719
720     return S_FALSE;
721 }
722
723 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_GetInformation(IAudioMediaStream *iface,
724         MSPID *purpose_id, STREAM_TYPE *type)
725 {
726     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
727
728     TRACE("(%p/%p)->(%p,%p)\n", iface, This, purpose_id, type);
729
730     if (purpose_id)
731         *purpose_id = This->purpose_id;
732     if (type)
733         *type = This->stream_type;
734
735     return S_OK;
736 }
737
738 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_SetSameFormat(IAudioMediaStream *iface,
739         IMediaStream *stream_format, DWORD flags)
740 {
741     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
742
743     FIXME("(%p/%p)->(%p,%x) stub!\n", iface, This, stream_format, flags);
744
745     return S_FALSE;
746 }
747
748 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_AllocateSample(IAudioMediaStream *iface,
749         DWORD flags, IStreamSample **sample)
750 {
751     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
752
753     FIXME("(%p/%p)->(%x,%p) stub!\n", iface, This, flags, sample);
754
755     return S_FALSE;
756 }
757
758 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_CreateSharedSample(IAudioMediaStream *iface,
759         IStreamSample *existing_sample, DWORD flags, IStreamSample **sample)
760 {
761     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
762
763     FIXME("(%p/%p)->(%p,%x,%p) stub!\n", iface, This, existing_sample, flags, sample);
764
765     return S_FALSE;
766 }
767
768 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_SendEndOfStream(IAudioMediaStream *iface,
769         DWORD flags)
770 {
771     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
772
773     FIXME("(%p/%p)->(%x) stub!\n", iface, This, flags);
774
775     return S_FALSE;
776 }
777
778 /*** IAudioMediaStream methods ***/
779 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_GetFormat(IAudioMediaStream *iface, WAVEFORMATEX *wave_format_current)
780 {
781     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
782
783     FIXME("(%p/%p)->(%p) stub!\n", iface, This, wave_format_current);
784
785     if (!wave_format_current)
786         return E_POINTER;
787
788     return MS_E_NOSTREAM;
789
790 }
791
792 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_SetFormat(IAudioMediaStream *iface, const WAVEFORMATEX *wave_format)
793 {
794     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
795
796     FIXME("(%p/%p)->(%p) stub!\n", iface, This, wave_format);
797
798     return E_NOTIMPL;
799 }
800
801 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_CreateSample(IAudioMediaStream *iface, IAudioData *audio_data,
802                                                          DWORD flags, IAudioStreamSample **sample)
803 {
804     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
805
806     TRACE("(%p/%p)->(%p,%u,%p)\n", iface, This, audio_data, flags, sample);
807
808     if (!audio_data)
809         return E_POINTER;
810
811     return audiostreamsample_create(iface, audio_data, sample);
812 }
813
814 static const struct IAudioMediaStreamVtbl AudioMediaStreamImpl_IAudioMediaStream_Vtbl =
815 {
816     /*** IUnknown methods ***/
817     AudioMediaStreamImpl_IAudioMediaStream_QueryInterface,
818     AudioMediaStreamImpl_IAudioMediaStream_AddRef,
819     AudioMediaStreamImpl_IAudioMediaStream_Release,
820     /*** IMediaStream methods ***/
821     AudioMediaStreamImpl_IAudioMediaStream_GetMultiMediaStream,
822     AudioMediaStreamImpl_IAudioMediaStream_GetInformation,
823     AudioMediaStreamImpl_IAudioMediaStream_SetSameFormat,
824     AudioMediaStreamImpl_IAudioMediaStream_AllocateSample,
825     AudioMediaStreamImpl_IAudioMediaStream_CreateSharedSample,
826     AudioMediaStreamImpl_IAudioMediaStream_SendEndOfStream,
827     /*** IAudioMediaStream methods ***/
828     AudioMediaStreamImpl_IAudioMediaStream_GetFormat,
829     AudioMediaStreamImpl_IAudioMediaStream_SetFormat,
830     AudioMediaStreamImpl_IAudioMediaStream_CreateSample
831 };
832
833 HRESULT audiomediastream_create(IMultiMediaStream *parent, const MSPID *purpose_id,
834         STREAM_TYPE stream_type, IMediaStream **media_stream)
835 {
836     AudioMediaStreamImpl *object;
837
838     TRACE("(%p,%s,%p)\n", parent, debugstr_guid(purpose_id), media_stream);
839
840     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AudioMediaStreamImpl));
841     if (!object)
842     {
843         ERR("Out of memory\n");
844         return E_OUTOFMEMORY;
845     }
846
847     object->IAMMediaStream_iface.lpVtbl = &AudioMediaStreamImpl_IAMMediaStream_Vtbl;
848     object->IAudioMediaStream_iface.lpVtbl = &AudioMediaStreamImpl_IAudioMediaStream_Vtbl;
849     object->ref = 1;
850
851     object->parent = parent;
852     object->purpose_id = *purpose_id;
853     object->stream_type = stream_type;
854
855     *media_stream = (IMediaStream*)&object->IAMMediaStream_iface;
856
857     return S_OK;
858 }
859
860 typedef struct {
861     IDirectDrawStreamSample IDirectDrawStreamSample_iface;
862     LONG ref;
863     IMediaStream *parent;
864 } IDirectDrawStreamSampleImpl;
865
866 static inline IDirectDrawStreamSampleImpl *impl_from_IDirectDrawStreamSample(IDirectDrawStreamSample *iface)
867 {
868     return CONTAINING_RECORD(iface, IDirectDrawStreamSampleImpl, IDirectDrawStreamSample_iface);
869 }
870
871 /*** IUnknown methods ***/
872 static HRESULT WINAPI IDirectDrawStreamSampleImpl_QueryInterface(IDirectDrawStreamSample *iface,
873         REFIID riid, void **ret_iface)
874 {
875     TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ret_iface);
876
877     if (IsEqualGUID(riid, &IID_IUnknown) ||
878         IsEqualGUID(riid, &IID_IStreamSample) ||
879         IsEqualGUID(riid, &IID_IDirectDrawStreamSample))
880     {
881         IDirectDrawStreamSample_AddRef(iface);
882         *ret_iface = iface;
883         return S_OK;
884     }
885
886     *ret_iface = NULL;
887
888     ERR("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ret_iface);
889     return E_NOINTERFACE;
890 }
891
892 static ULONG WINAPI IDirectDrawStreamSampleImpl_AddRef(IDirectDrawStreamSample *iface)
893 {
894     IDirectDrawStreamSampleImpl *This = impl_from_IDirectDrawStreamSample(iface);
895     ULONG ref = InterlockedIncrement(&This->ref);
896
897     TRACE("(%p)->(): new ref = %u\n", iface, ref);
898
899     return ref;
900 }
901
902 static ULONG WINAPI IDirectDrawStreamSampleImpl_Release(IDirectDrawStreamSample *iface)
903 {
904     IDirectDrawStreamSampleImpl *This = impl_from_IDirectDrawStreamSample(iface);
905     ULONG ref = InterlockedDecrement(&This->ref);
906
907     TRACE("(%p)->(): new ref = %u\n", iface, ref);
908
909     if (!ref)
910         HeapFree(GetProcessHeap(), 0, This);
911
912     return ref;
913 }
914
915 /*** IStreamSample methods ***/
916 static HRESULT WINAPI IDirectDrawStreamSampleImpl_GetMediaStream(IDirectDrawStreamSample *iface, IMediaStream **media_stream)
917 {
918     FIXME("(%p)->(%p): stub\n", iface, media_stream);
919
920     return E_NOTIMPL;
921 }
922
923 static HRESULT WINAPI IDirectDrawStreamSampleImpl_GetSampleTimes(IDirectDrawStreamSample *iface, STREAM_TIME *start_time,
924                                                                  STREAM_TIME *end_time, STREAM_TIME *current_time)
925 {
926     FIXME("(%p)->(%p,%p,%p): stub\n", iface, start_time, end_time, current_time);
927
928     return E_NOTIMPL;
929 }
930
931 static HRESULT WINAPI IDirectDrawStreamSampleImpl_SetSampleTimes(IDirectDrawStreamSample *iface, const STREAM_TIME *start_time,
932                                                                  const STREAM_TIME *end_time)
933 {
934     FIXME("(%p)->(%p,%p): stub\n", iface, start_time, end_time);
935
936     return E_NOTIMPL;
937 }
938
939 static HRESULT WINAPI IDirectDrawStreamSampleImpl_Update(IDirectDrawStreamSample *iface, DWORD flags, HANDLE event,
940                                                          PAPCFUNC func_APC, DWORD APC_data)
941 {
942     FIXME("(%p)->(%x,%p,%p,%u): stub\n", iface, flags, event, func_APC, APC_data);
943
944     return E_NOTIMPL;
945 }
946
947 static HRESULT WINAPI IDirectDrawStreamSampleImpl_CompletionStatus(IDirectDrawStreamSample *iface, DWORD flags, DWORD milliseconds)
948 {
949     FIXME("(%p)->(%x,%u): stub\n", iface, flags, milliseconds);
950
951     return E_NOTIMPL;
952 }
953
954 /*** IDirectDrawStreamSample methods ***/
955 static HRESULT WINAPI IDirectDrawStreamSampleImpl_GetSurface(IDirectDrawStreamSample *iface, IDirectDrawSurface **ddraw_surface,
956                                                              RECT *rect)
957 {
958     FIXME("(%p)->(%p,%p): stub\n", iface, ddraw_surface, rect);
959
960     return E_NOTIMPL;
961 }
962
963 static HRESULT WINAPI IDirectDrawStreamSampleImpl_SetRect(IDirectDrawStreamSample *iface, const RECT *rect)
964 {
965     FIXME("(%p)->(%p): stub\n", iface, rect);
966
967     return E_NOTIMPL;
968 }
969
970 static const struct IDirectDrawStreamSampleVtbl DirectDrawStreamSample_Vtbl =
971 {
972     /*** IUnknown methods ***/
973     IDirectDrawStreamSampleImpl_QueryInterface,
974     IDirectDrawStreamSampleImpl_AddRef,
975     IDirectDrawStreamSampleImpl_Release,
976     /*** IStreamSample methods ***/
977     IDirectDrawStreamSampleImpl_GetMediaStream,
978     IDirectDrawStreamSampleImpl_GetSampleTimes,
979     IDirectDrawStreamSampleImpl_SetSampleTimes,
980     IDirectDrawStreamSampleImpl_Update,
981     IDirectDrawStreamSampleImpl_CompletionStatus,
982     /*** IDirectDrawStreamSample methods ***/
983     IDirectDrawStreamSampleImpl_GetSurface,
984     IDirectDrawStreamSampleImpl_SetRect
985 };
986
987 static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectDrawStreamSample **ddraw_stream_sample)
988 {
989     IDirectDrawStreamSampleImpl *object;
990
991     TRACE("(%p)\n", ddraw_stream_sample);
992
993     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawStreamSampleImpl));
994     if (!object)
995     {
996         ERR("Out of memory\n");
997         return E_OUTOFMEMORY;
998     }
999
1000     object->IDirectDrawStreamSample_iface.lpVtbl = &DirectDrawStreamSample_Vtbl;
1001     object->ref = 1;
1002     object->parent = (IMediaStream*)parent;
1003
1004     *ddraw_stream_sample = (IDirectDrawStreamSample*)&object->IDirectDrawStreamSample_iface;
1005
1006     return S_OK;
1007 }
1008
1009 typedef struct {
1010     IAudioStreamSample IAudioStreamSample_iface;
1011     LONG ref;
1012     IMediaStream *parent;
1013     IAudioData *audio_data;
1014 } IAudioStreamSampleImpl;
1015
1016 static inline IAudioStreamSampleImpl *impl_from_IAudioStreamSample(IAudioStreamSample *iface)
1017 {
1018     return CONTAINING_RECORD(iface, IAudioStreamSampleImpl, IAudioStreamSample_iface);
1019 }
1020
1021 /*** IUnknown methods ***/
1022 static HRESULT WINAPI IAudioStreamSampleImpl_QueryInterface(IAudioStreamSample *iface,
1023         REFIID riid, void **ret_iface)
1024 {
1025     TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ret_iface);
1026
1027     if (IsEqualGUID(riid, &IID_IUnknown) ||
1028         IsEqualGUID(riid, &IID_IStreamSample) ||
1029         IsEqualGUID(riid, &IID_IAudioStreamSample))
1030     {
1031         IAudioStreamSample_AddRef(iface);
1032         *ret_iface = iface;
1033         return S_OK;
1034     }
1035
1036     *ret_iface = NULL;
1037
1038     ERR("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ret_iface);
1039     return E_NOINTERFACE;
1040 }
1041
1042 static ULONG WINAPI IAudioStreamSampleImpl_AddRef(IAudioStreamSample *iface)
1043 {
1044     IAudioStreamSampleImpl *This = impl_from_IAudioStreamSample(iface);
1045     ULONG ref = InterlockedIncrement(&This->ref);
1046
1047     TRACE("(%p)->(): new ref = %u\n", iface, ref);
1048
1049     return ref;
1050 }
1051
1052 static ULONG WINAPI IAudioStreamSampleImpl_Release(IAudioStreamSample *iface)
1053 {
1054     IAudioStreamSampleImpl *This = impl_from_IAudioStreamSample(iface);
1055     ULONG ref = InterlockedDecrement(&This->ref);
1056
1057     TRACE("(%p)->(): new ref = %u\n", iface, ref);
1058
1059     if (!ref)
1060         HeapFree(GetProcessHeap(), 0, This);
1061
1062     return ref;
1063 }
1064
1065 /*** IStreamSample methods ***/
1066 static HRESULT WINAPI IAudioStreamSampleImpl_GetMediaStream(IAudioStreamSample *iface, IMediaStream **media_stream)
1067 {
1068     FIXME("(%p)->(%p): stub\n", iface, media_stream);
1069
1070     return E_NOTIMPL;
1071 }
1072
1073 static HRESULT WINAPI IAudioStreamSampleImpl_GetSampleTimes(IAudioStreamSample *iface, STREAM_TIME *start_time,
1074                                                                  STREAM_TIME *end_time, STREAM_TIME *current_time)
1075 {
1076     FIXME("(%p)->(%p,%p,%p): stub\n", iface, start_time, end_time, current_time);
1077
1078     return E_NOTIMPL;
1079 }
1080
1081 static HRESULT WINAPI IAudioStreamSampleImpl_SetSampleTimes(IAudioStreamSample *iface, const STREAM_TIME *start_time,
1082                                                                  const STREAM_TIME *end_time)
1083 {
1084     FIXME("(%p)->(%p,%p): stub\n", iface, start_time, end_time);
1085
1086     return E_NOTIMPL;
1087 }
1088
1089 static HRESULT WINAPI IAudioStreamSampleImpl_Update(IAudioStreamSample *iface, DWORD flags, HANDLE event,
1090                                                          PAPCFUNC func_APC, DWORD APC_data)
1091 {
1092     FIXME("(%p)->(%x,%p,%p,%u): stub\n", iface, flags, event, func_APC, APC_data);
1093
1094     return E_NOTIMPL;
1095 }
1096
1097 static HRESULT WINAPI IAudioStreamSampleImpl_CompletionStatus(IAudioStreamSample *iface, DWORD flags, DWORD milliseconds)
1098 {
1099     FIXME("(%p)->(%x,%u): stub\n", iface, flags, milliseconds);
1100
1101     return E_NOTIMPL;
1102 }
1103
1104 /*** IAudioStreamSample methods ***/
1105 static HRESULT WINAPI IAudioStreamSampleImpl_GetAudioData(IAudioStreamSample *iface, IAudioData **audio_data)
1106 {
1107     FIXME("(%p)->(%p): stub\n", iface, audio_data);
1108
1109     return E_NOTIMPL;
1110 }
1111
1112 static const struct IAudioStreamSampleVtbl AudioStreamSample_Vtbl =
1113 {
1114     /*** IUnknown methods ***/
1115     IAudioStreamSampleImpl_QueryInterface,
1116     IAudioStreamSampleImpl_AddRef,
1117     IAudioStreamSampleImpl_Release,
1118     /*** IStreamSample methods ***/
1119     IAudioStreamSampleImpl_GetMediaStream,
1120     IAudioStreamSampleImpl_GetSampleTimes,
1121     IAudioStreamSampleImpl_SetSampleTimes,
1122     IAudioStreamSampleImpl_Update,
1123     IAudioStreamSampleImpl_CompletionStatus,
1124     /*** IAudioStreamSample methods ***/
1125     IAudioStreamSampleImpl_GetAudioData
1126 };
1127
1128 static HRESULT audiostreamsample_create(IAudioMediaStream *parent, IAudioData *audio_data, IAudioStreamSample **audio_stream_sample)
1129 {
1130     IAudioStreamSampleImpl *object;
1131
1132     TRACE("(%p)\n", audio_stream_sample);
1133
1134     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAudioStreamSampleImpl));
1135     if (!object)
1136     {
1137         ERR("Out of memory\n");
1138         return E_OUTOFMEMORY;
1139     }
1140
1141     object->IAudioStreamSample_iface.lpVtbl = &AudioStreamSample_Vtbl;
1142     object->ref = 1;
1143     object->parent = (IMediaStream*)parent;
1144     object->audio_data = audio_data;
1145
1146     *audio_stream_sample = (IAudioStreamSample*)&object->IAudioStreamSample_iface;
1147
1148     return S_OK;
1149 }