dmusic: COM cleanup of IDirectMusic8.
[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     IDirectDrawMediaStream IDirectDrawMediaStream_iface;
40     LONG ref;
41     IMultiMediaStream* Parent;
42     MSPID PurposeId;
43     STREAM_TYPE StreamType;
44 } IDirectDrawMediaStreamImpl;
45
46 static inline IDirectDrawMediaStreamImpl *impl_from_IDirectDrawMediaStream(IDirectDrawMediaStream *iface)
47 {
48     return CONTAINING_RECORD(iface, IDirectDrawMediaStreamImpl, IDirectDrawMediaStream_iface);
49 }
50
51 /*** IUnknown methods ***/
52 static HRESULT WINAPI IDirectDrawMediaStreamImpl_QueryInterface(IDirectDrawMediaStream *iface,
53         REFIID riid, void **ppv)
54 {
55     IDirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
56
57     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppv);
58
59     if (IsEqualGUID(riid, &IID_IUnknown) ||
60         IsEqualGUID(riid, &IID_IMediaStream) ||
61         IsEqualGUID(riid, &IID_IDirectDrawMediaStream))
62     {
63         IUnknown_AddRef(iface);
64         *ppv = This;
65         return S_OK;
66     }
67
68     ERR("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppv);
69     return E_NOINTERFACE;
70 }
71
72 static ULONG WINAPI IDirectDrawMediaStreamImpl_AddRef(IDirectDrawMediaStream *iface)
73 {
74     IDirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
75
76     TRACE("(%p/%p)\n", iface, This);
77
78     return InterlockedIncrement(&This->ref);
79 }
80
81 static ULONG WINAPI IDirectDrawMediaStreamImpl_Release(IDirectDrawMediaStream *iface)
82 {
83     IDirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
84     ULONG ref = InterlockedDecrement(&This->ref);
85
86     TRACE("(%p/%p)\n", iface, This);
87
88     if (!ref)
89         HeapFree(GetProcessHeap(), 0, This);
90
91     return ref;
92 }
93
94 /*** IMediaStream methods ***/
95 static HRESULT WINAPI IDirectDrawMediaStreamImpl_GetMultiMediaStream(IDirectDrawMediaStream *iface,
96         IMultiMediaStream** ppMultiMediaStream)
97 {
98     IDirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
99
100     FIXME("(%p/%p)->(%p) stub!\n", This, iface, ppMultiMediaStream);
101
102     return S_FALSE;
103 }
104
105 static HRESULT WINAPI IDirectDrawMediaStreamImpl_GetInformation(IDirectDrawMediaStream *iface,
106         MSPID *pPurposeId, STREAM_TYPE *pType)
107 {
108     IDirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
109
110     TRACE("(%p/%p)->(%p,%p)\n", This, iface, pPurposeId, pType);
111
112     if (pPurposeId)
113         *pPurposeId = This->PurposeId;
114     if (pType)
115         *pType = This->StreamType;
116
117     return S_OK;
118 }
119
120 static HRESULT WINAPI IDirectDrawMediaStreamImpl_SetSameFormat(IDirectDrawMediaStream *iface,
121         IMediaStream *pStreamThatHasDesiredFormat, DWORD dwFlags)
122 {
123     IDirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
124
125     FIXME("(%p/%p)->(%p,%x) stub!\n", This, iface, pStreamThatHasDesiredFormat, dwFlags);
126
127     return S_FALSE;
128 }
129
130 static HRESULT WINAPI IDirectDrawMediaStreamImpl_AllocateSample(IDirectDrawMediaStream *iface,
131         DWORD dwFlags, IStreamSample **ppSample)
132 {
133     IDirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
134
135     FIXME("(%p/%p)->(%x,%p) stub!\n", This, iface, dwFlags, ppSample);
136
137     return S_FALSE;
138 }
139
140 static HRESULT WINAPI IDirectDrawMediaStreamImpl_CreateSharedSample(IDirectDrawMediaStream *iface,
141         IStreamSample *pExistingSample, DWORD dwFlags, IStreamSample **ppSample)
142 {
143     IDirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
144
145     FIXME("(%p/%p)->(%p,%x,%p) stub!\n", This, iface, pExistingSample, dwFlags, ppSample);
146
147     return S_FALSE;
148 }
149
150 static HRESULT WINAPI IDirectDrawMediaStreamImpl_SendEndOfStream(IDirectDrawMediaStream *iface,
151         DWORD dwFlags)
152 {
153     IDirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
154
155     FIXME("(%p/%p)->(%x) stub!\n", This, iface, dwFlags);
156
157     return S_FALSE;
158 }
159
160 /*** IDirectDrawMediaStream methods ***/
161 static HRESULT WINAPI IDirectDrawMediaStreamImpl_GetFormat(IDirectDrawMediaStream *iface,
162         DDSURFACEDESC *pDDSDCurrent, IDirectDrawPalette **ppDirectDrawPalette,
163         DDSURFACEDESC *pDDSDDesired, DWORD *pdwFlags)
164 {
165     FIXME("(%p)->(%p,%p,%p,%p) stub!\n", iface, pDDSDCurrent, ppDirectDrawPalette, pDDSDDesired,
166             pdwFlags);
167
168     return E_NOTIMPL;
169
170 }
171
172 static HRESULT WINAPI IDirectDrawMediaStreamImpl_SetFormat(IDirectDrawMediaStream *iface,
173         const DDSURFACEDESC *pDDSurfaceDesc, IDirectDrawPalette *pDirectDrawPalette)
174 {
175     FIXME("(%p)->(%p,%p) stub!\n", iface, pDDSurfaceDesc, pDirectDrawPalette);
176
177     return E_NOTIMPL;
178 }
179
180 static HRESULT WINAPI IDirectDrawMediaStreamImpl_GetDirectDraw(IDirectDrawMediaStream *iface,
181         IDirectDraw **ppDirectDraw)
182 {
183     FIXME("(%p)->(%p) stub!\n", iface, ppDirectDraw);
184
185     return E_NOTIMPL;
186 }
187
188 static HRESULT WINAPI IDirectDrawMediaStreamImpl_SetDirectDraw(IDirectDrawMediaStream *iface,
189         IDirectDraw *pDirectDraw)
190 {
191     FIXME("(%p)->(%p) stub!\n", iface, pDirectDraw);
192
193     return E_NOTIMPL;
194 }
195
196 static HRESULT WINAPI IDirectDrawMediaStreamImpl_CreateSample(IDirectDrawMediaStream *iface,
197         IDirectDrawSurface *pSurface, const RECT *pRect, DWORD dwFlags,
198         IDirectDrawStreamSample **ppSample)
199 {
200     TRACE("(%p)->(%p,%p,%x,%p)\n", iface, pSurface, pRect, dwFlags, ppSample);
201
202     return ddrawstreamsample_create(iface, ppSample);
203 }
204
205 static HRESULT WINAPI IDirectDrawMediaStreamImpl_GetTimePerFrame(IDirectDrawMediaStream *iface,
206         STREAM_TIME *pFrameTime)
207 {
208     FIXME("(%p)->(%p) stub!\n", iface, pFrameTime);
209
210     return E_NOTIMPL;
211 }
212
213 static const struct IDirectDrawMediaStreamVtbl DirectDrawMediaStream_Vtbl =
214 {
215     /*** IUnknown methods ***/
216     IDirectDrawMediaStreamImpl_QueryInterface,
217     IDirectDrawMediaStreamImpl_AddRef,
218     IDirectDrawMediaStreamImpl_Release,
219     /*** IMediaStream methods ***/
220     IDirectDrawMediaStreamImpl_GetMultiMediaStream,
221     IDirectDrawMediaStreamImpl_GetInformation,
222     IDirectDrawMediaStreamImpl_SetSameFormat,
223     IDirectDrawMediaStreamImpl_AllocateSample,
224     IDirectDrawMediaStreamImpl_CreateSharedSample,
225     IDirectDrawMediaStreamImpl_SendEndOfStream,
226     /*** IDirectDrawMediaStream methods ***/
227     IDirectDrawMediaStreamImpl_GetFormat,
228     IDirectDrawMediaStreamImpl_SetFormat,
229     IDirectDrawMediaStreamImpl_GetDirectDraw,
230     IDirectDrawMediaStreamImpl_SetDirectDraw,
231     IDirectDrawMediaStreamImpl_CreateSample,
232     IDirectDrawMediaStreamImpl_GetTimePerFrame
233 };
234
235 HRESULT ddrawmediastream_create(IMultiMediaStream *Parent, const MSPID *pPurposeId,
236         STREAM_TYPE StreamType, IMediaStream **ppMediaStream)
237 {
238     IDirectDrawMediaStreamImpl *object;
239
240     TRACE("(%p,%s,%p)\n", Parent, debugstr_guid(pPurposeId), ppMediaStream);
241
242     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawMediaStreamImpl));
243     if (!object)
244     {
245         ERR("Out of memory\n");
246         return E_OUTOFMEMORY;
247     }
248
249     object->IDirectDrawMediaStream_iface.lpVtbl = &DirectDrawMediaStream_Vtbl;
250     object->ref = 1;
251
252     object->Parent = Parent;
253     object->PurposeId = *pPurposeId;
254     object->StreamType = StreamType;
255
256     *ppMediaStream = (IMediaStream*)&object->IDirectDrawMediaStream_iface;
257
258     return S_OK;
259 }
260
261 typedef struct {
262     IAudioMediaStream IAudioMediaStream_iface;
263     LONG ref;
264     IMultiMediaStream* parent;
265     MSPID purpose_id;
266     STREAM_TYPE stream_type;
267 } IAudioMediaStreamImpl;
268
269 static inline IAudioMediaStreamImpl *impl_from_IAudioMediaStream(IAudioMediaStream *iface)
270 {
271     return CONTAINING_RECORD(iface, IAudioMediaStreamImpl, IAudioMediaStream_iface);
272 }
273
274 /*** IUnknown methods ***/
275 static HRESULT WINAPI IAudioMediaStreamImpl_QueryInterface(IAudioMediaStream *iface,
276         REFIID riid, void **ret_iface)
277 {
278     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
279
280     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface);
281
282     if (IsEqualGUID(riid, &IID_IUnknown) ||
283         IsEqualGUID(riid, &IID_IMediaStream) ||
284         IsEqualGUID(riid, &IID_IAudioMediaStream))
285     {
286         IAudioMediaStream_AddRef(iface);
287         *ret_iface = iface;
288         return S_OK;
289     }
290
291     *ret_iface = NULL;
292
293     ERR("(%p/%p)->(%s,%p),not found\n", iface, This, debugstr_guid(riid), ret_iface);
294     return E_NOINTERFACE;
295 }
296
297 static ULONG WINAPI IAudioMediaStreamImpl_AddRef(IAudioMediaStream *iface)
298 {
299     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
300     ULONG ref = InterlockedIncrement(&This->ref);
301
302     TRACE("(%p/%p): new ref = %u\n", iface, This, ref);
303
304     return ref;
305 }
306
307 static ULONG WINAPI IAudioMediaStreamImpl_Release(IAudioMediaStream *iface)
308 {
309     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
310     ULONG ref = InterlockedDecrement(&This->ref);
311
312     TRACE("(%p/%p): new ref = %u\n", iface, This, ref);
313
314     if (!ref)
315         HeapFree(GetProcessHeap(), 0, This);
316
317     return ref;
318 }
319
320 /*** IMediaStream methods ***/
321 static HRESULT WINAPI IAudioMediaStreamImpl_GetMultiMediaStream(IAudioMediaStream *iface,
322         IMultiMediaStream** multimedia_stream)
323 {
324     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
325
326     FIXME("(%p/%p)->(%p) stub!\n", iface, This, multimedia_stream);
327
328     return S_FALSE;
329 }
330
331 static HRESULT WINAPI IAudioMediaStreamImpl_GetInformation(IAudioMediaStream *iface,
332         MSPID *purpose_id, STREAM_TYPE *type)
333 {
334     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
335
336     TRACE("(%p/%p)->(%p,%p)\n", iface, This, purpose_id, type);
337
338     if (purpose_id)
339         *purpose_id = This->purpose_id;
340     if (type)
341         *type = This->stream_type;
342
343     return S_OK;
344 }
345
346 static HRESULT WINAPI IAudioMediaStreamImpl_SetSameFormat(IAudioMediaStream *iface,
347         IMediaStream *stream_format, DWORD flags)
348 {
349     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
350
351     FIXME("(%p/%p)->(%p,%x) stub!\n", iface, This, stream_format, flags);
352
353     return S_FALSE;
354 }
355
356 static HRESULT WINAPI IAudioMediaStreamImpl_AllocateSample(IAudioMediaStream *iface,
357         DWORD flags, IStreamSample **sample)
358 {
359     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
360
361     FIXME("(%p/%p)->(%x,%p) stub!\n", iface, This, flags, sample);
362
363     return S_FALSE;
364 }
365
366 static HRESULT WINAPI IAudioMediaStreamImpl_CreateSharedSample(IAudioMediaStream *iface,
367         IStreamSample *existing_sample, DWORD flags, IStreamSample **sample)
368 {
369     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
370
371     FIXME("(%p/%p)->(%p,%x,%p) stub!\n", iface, This, existing_sample, flags, sample);
372
373     return S_FALSE;
374 }
375
376 static HRESULT WINAPI IAudioMediaStreamImpl_SendEndOfStream(IAudioMediaStream *iface,
377         DWORD flags)
378 {
379     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
380
381     FIXME("(%p/%p)->(%x) stub!\n", iface, This, flags);
382
383     return S_FALSE;
384 }
385
386 /*** IAudioMediaStream methods ***/
387 static HRESULT WINAPI IAudioMediaStreamImpl_GetFormat(IAudioMediaStream *iface, WAVEFORMATEX *wave_format_current)
388 {
389     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
390
391     FIXME("(%p/%p)->(%p) stub!\n", iface, This, wave_format_current);
392
393     return E_NOTIMPL;
394
395 }
396
397 static HRESULT WINAPI IAudioMediaStreamImpl_SetFormat(IAudioMediaStream *iface, const WAVEFORMATEX *wave_format)
398 {
399     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
400
401     FIXME("(%p/%p)->(%p) stub!\n", iface, This, wave_format);
402
403     return E_NOTIMPL;
404 }
405
406 static HRESULT WINAPI IAudioMediaStreamImpl_CreateSample(IAudioMediaStream *iface, IAudioData *audio_data,
407                                                          DWORD flags, IAudioStreamSample **sample)
408 {
409     IAudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
410
411     TRACE("(%p/%p)->(%p,%u,%p)\n", iface, This, audio_data, flags, sample);
412
413     if (!audio_data)
414         return E_POINTER;
415
416     return audiostreamsample_create(iface, audio_data, sample);
417 }
418
419 static const struct IAudioMediaStreamVtbl AudioMediaStream_Vtbl =
420 {
421     /*** IUnknown methods ***/
422     IAudioMediaStreamImpl_QueryInterface,
423     IAudioMediaStreamImpl_AddRef,
424     IAudioMediaStreamImpl_Release,
425     /*** IMediaStream methods ***/
426     IAudioMediaStreamImpl_GetMultiMediaStream,
427     IAudioMediaStreamImpl_GetInformation,
428     IAudioMediaStreamImpl_SetSameFormat,
429     IAudioMediaStreamImpl_AllocateSample,
430     IAudioMediaStreamImpl_CreateSharedSample,
431     IAudioMediaStreamImpl_SendEndOfStream,
432     /*** IAudioMediaStream methods ***/
433     IAudioMediaStreamImpl_GetFormat,
434     IAudioMediaStreamImpl_SetFormat,
435     IAudioMediaStreamImpl_CreateSample
436 };
437
438 HRESULT audiomediastream_create(IMultiMediaStream *parent, const MSPID *purpose_id,
439         STREAM_TYPE stream_type, IMediaStream **media_stream)
440 {
441     IAudioMediaStreamImpl *object;
442
443     TRACE("(%p,%s,%p)\n", parent, debugstr_guid(purpose_id), media_stream);
444
445     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAudioMediaStreamImpl));
446     if (!object)
447     {
448         ERR("Out of memory\n");
449         return E_OUTOFMEMORY;
450     }
451
452     object->IAudioMediaStream_iface.lpVtbl = &AudioMediaStream_Vtbl;
453     object->ref = 1;
454
455     object->parent = parent;
456     object->purpose_id = *purpose_id;
457     object->stream_type = stream_type;
458
459     *media_stream = (IMediaStream*)&object->IAudioMediaStream_iface;
460
461     return S_OK;
462 }
463
464 typedef struct {
465     IDirectDrawStreamSample IDirectDrawStreamSample_iface;
466     LONG ref;
467     IMediaStream *parent;
468 } IDirectDrawStreamSampleImpl;
469
470 static inline IDirectDrawStreamSampleImpl *impl_from_IDirectDrawStreamSample(IDirectDrawStreamSample *iface)
471 {
472     return CONTAINING_RECORD(iface, IDirectDrawStreamSampleImpl, IDirectDrawStreamSample_iface);
473 }
474
475 /*** IUnknown methods ***/
476 static HRESULT WINAPI IDirectDrawStreamSampleImpl_QueryInterface(IDirectDrawStreamSample *iface,
477         REFIID riid, void **ret_iface)
478 {
479     TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ret_iface);
480
481     if (IsEqualGUID(riid, &IID_IUnknown) ||
482         IsEqualGUID(riid, &IID_IStreamSample) ||
483         IsEqualGUID(riid, &IID_IDirectDrawStreamSample))
484     {
485         IDirectDrawStreamSample_AddRef(iface);
486         *ret_iface = iface;
487         return S_OK;
488     }
489
490     *ret_iface = NULL;
491
492     ERR("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ret_iface);
493     return E_NOINTERFACE;
494 }
495
496 static ULONG WINAPI IDirectDrawStreamSampleImpl_AddRef(IDirectDrawStreamSample *iface)
497 {
498     IDirectDrawStreamSampleImpl *This = impl_from_IDirectDrawStreamSample(iface);
499     ULONG ref = InterlockedIncrement(&This->ref);
500
501     TRACE("(%p)->(): new ref = %u\n", iface, ref);
502
503     return ref;
504 }
505
506 static ULONG WINAPI IDirectDrawStreamSampleImpl_Release(IDirectDrawStreamSample *iface)
507 {
508     IDirectDrawStreamSampleImpl *This = impl_from_IDirectDrawStreamSample(iface);
509     ULONG ref = InterlockedDecrement(&This->ref);
510
511     TRACE("(%p)->(): new ref = %u\n", iface, ref);
512
513     if (!ref)
514         HeapFree(GetProcessHeap(), 0, This);
515
516     return ref;
517 }
518
519 /*** IStreamSample methods ***/
520 static HRESULT WINAPI IDirectDrawStreamSampleImpl_GetMediaStream(IDirectDrawStreamSample *iface, IMediaStream **media_stream)
521 {
522     FIXME("(%p)->(%p): stub\n", iface, media_stream);
523
524     return E_NOTIMPL;
525 }
526
527 static HRESULT WINAPI IDirectDrawStreamSampleImpl_GetSampleTimes(IDirectDrawStreamSample *iface, STREAM_TIME *start_time,
528                                                                  STREAM_TIME *end_time, STREAM_TIME *current_time)
529 {
530     FIXME("(%p)->(%p,%p,%p): stub\n", iface, start_time, end_time, current_time);
531
532     return E_NOTIMPL;
533 }
534
535 static HRESULT WINAPI IDirectDrawStreamSampleImpl_SetSampleTimes(IDirectDrawStreamSample *iface, const STREAM_TIME *start_time,
536                                                                  const STREAM_TIME *end_time)
537 {
538     FIXME("(%p)->(%p,%p): stub\n", iface, start_time, end_time);
539
540     return E_NOTIMPL;
541 }
542
543 static HRESULT WINAPI IDirectDrawStreamSampleImpl_Update(IDirectDrawStreamSample *iface, DWORD flags, HANDLE event,
544                                                          PAPCFUNC func_APC, DWORD APC_data)
545 {
546     FIXME("(%p)->(%x,%p,%p,%u): stub\n", iface, flags, event, func_APC, APC_data);
547
548     return E_NOTIMPL;
549 }
550
551 static HRESULT WINAPI IDirectDrawStreamSampleImpl_CompletionStatus(IDirectDrawStreamSample *iface, DWORD flags, DWORD milliseconds)
552 {
553     FIXME("(%p)->(%x,%u): stub\n", iface, flags, milliseconds);
554
555     return E_NOTIMPL;
556 }
557
558 /*** IDirectDrawStreamSample methods ***/
559 static HRESULT WINAPI IDirectDrawStreamSampleImpl_GetSurface(IDirectDrawStreamSample *iface, IDirectDrawSurface **ddraw_surface,
560                                                              RECT *rect)
561 {
562     FIXME("(%p)->(%p,%p): stub\n", iface, ddraw_surface, rect);
563
564     return E_NOTIMPL;
565 }
566
567 static HRESULT WINAPI IDirectDrawStreamSampleImpl_SetRect(IDirectDrawStreamSample *iface, const RECT *rect)
568 {
569     FIXME("(%p)->(%p): stub\n", iface, rect);
570
571     return E_NOTIMPL;
572 }
573
574 static const struct IDirectDrawStreamSampleVtbl DirectDrawStreamSample_Vtbl =
575 {
576     /*** IUnknown methods ***/
577     IDirectDrawStreamSampleImpl_QueryInterface,
578     IDirectDrawStreamSampleImpl_AddRef,
579     IDirectDrawStreamSampleImpl_Release,
580     /*** IStreamSample methods ***/
581     IDirectDrawStreamSampleImpl_GetMediaStream,
582     IDirectDrawStreamSampleImpl_GetSampleTimes,
583     IDirectDrawStreamSampleImpl_SetSampleTimes,
584     IDirectDrawStreamSampleImpl_Update,
585     IDirectDrawStreamSampleImpl_CompletionStatus,
586     /*** IDirectDrawStreamSample methods ***/
587     IDirectDrawStreamSampleImpl_GetSurface,
588     IDirectDrawStreamSampleImpl_SetRect
589 };
590
591 static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectDrawStreamSample **ddraw_stream_sample)
592 {
593     IDirectDrawStreamSampleImpl *object;
594
595     TRACE("(%p)\n", ddraw_stream_sample);
596
597     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawStreamSampleImpl));
598     if (!object)
599     {
600         ERR("Out of memory\n");
601         return E_OUTOFMEMORY;
602     }
603
604     object->IDirectDrawStreamSample_iface.lpVtbl = &DirectDrawStreamSample_Vtbl;
605     object->ref = 1;
606     object->parent = (IMediaStream*)parent;
607
608     *ddraw_stream_sample = (IDirectDrawStreamSample*)&object->IDirectDrawStreamSample_iface;
609
610     return S_OK;
611 }
612
613 typedef struct {
614     IAudioStreamSample IAudioStreamSample_iface;
615     LONG ref;
616     IMediaStream *parent;
617     IAudioData *audio_data;
618 } IAudioStreamSampleImpl;
619
620 static inline IAudioStreamSampleImpl *impl_from_IAudioStreamSample(IAudioStreamSample *iface)
621 {
622     return CONTAINING_RECORD(iface, IAudioStreamSampleImpl, IAudioStreamSample_iface);
623 }
624
625 /*** IUnknown methods ***/
626 static HRESULT WINAPI IAudioStreamSampleImpl_QueryInterface(IAudioStreamSample *iface,
627         REFIID riid, void **ret_iface)
628 {
629     TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ret_iface);
630
631     if (IsEqualGUID(riid, &IID_IUnknown) ||
632         IsEqualGUID(riid, &IID_IStreamSample) ||
633         IsEqualGUID(riid, &IID_IAudioStreamSample))
634     {
635         IAudioStreamSample_AddRef(iface);
636         *ret_iface = iface;
637         return S_OK;
638     }
639
640     *ret_iface = NULL;
641
642     ERR("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ret_iface);
643     return E_NOINTERFACE;
644 }
645
646 static ULONG WINAPI IAudioStreamSampleImpl_AddRef(IAudioStreamSample *iface)
647 {
648     IAudioStreamSampleImpl *This = impl_from_IAudioStreamSample(iface);
649     ULONG ref = InterlockedIncrement(&This->ref);
650
651     TRACE("(%p)->(): new ref = %u\n", iface, ref);
652
653     return ref;
654 }
655
656 static ULONG WINAPI IAudioStreamSampleImpl_Release(IAudioStreamSample *iface)
657 {
658     IAudioStreamSampleImpl *This = impl_from_IAudioStreamSample(iface);
659     ULONG ref = InterlockedDecrement(&This->ref);
660
661     TRACE("(%p)->(): new ref = %u\n", iface, ref);
662
663     if (!ref)
664         HeapFree(GetProcessHeap(), 0, This);
665
666     return ref;
667 }
668
669 /*** IStreamSample methods ***/
670 static HRESULT WINAPI IAudioStreamSampleImpl_GetMediaStream(IAudioStreamSample *iface, IMediaStream **media_stream)
671 {
672     FIXME("(%p)->(%p): stub\n", iface, media_stream);
673
674     return E_NOTIMPL;
675 }
676
677 static HRESULT WINAPI IAudioStreamSampleImpl_GetSampleTimes(IAudioStreamSample *iface, STREAM_TIME *start_time,
678                                                                  STREAM_TIME *end_time, STREAM_TIME *current_time)
679 {
680     FIXME("(%p)->(%p,%p,%p): stub\n", iface, start_time, end_time, current_time);
681
682     return E_NOTIMPL;
683 }
684
685 static HRESULT WINAPI IAudioStreamSampleImpl_SetSampleTimes(IAudioStreamSample *iface, const STREAM_TIME *start_time,
686                                                                  const STREAM_TIME *end_time)
687 {
688     FIXME("(%p)->(%p,%p): stub\n", iface, start_time, end_time);
689
690     return E_NOTIMPL;
691 }
692
693 static HRESULT WINAPI IAudioStreamSampleImpl_Update(IAudioStreamSample *iface, DWORD flags, HANDLE event,
694                                                          PAPCFUNC func_APC, DWORD APC_data)
695 {
696     FIXME("(%p)->(%x,%p,%p,%u): stub\n", iface, flags, event, func_APC, APC_data);
697
698     return E_NOTIMPL;
699 }
700
701 static HRESULT WINAPI IAudioStreamSampleImpl_CompletionStatus(IAudioStreamSample *iface, DWORD flags, DWORD milliseconds)
702 {
703     FIXME("(%p)->(%x,%u): stub\n", iface, flags, milliseconds);
704
705     return E_NOTIMPL;
706 }
707
708 /*** IAudioStreamSample methods ***/
709 static HRESULT WINAPI IAudioStreamSampleImpl_GetAudioData(IAudioStreamSample *iface, IAudioData **audio_data)
710 {
711     FIXME("(%p)->(%p): stub\n", iface, audio_data);
712
713     return E_NOTIMPL;
714 }
715
716 static const struct IAudioStreamSampleVtbl AudioStreamSample_Vtbl =
717 {
718     /*** IUnknown methods ***/
719     IAudioStreamSampleImpl_QueryInterface,
720     IAudioStreamSampleImpl_AddRef,
721     IAudioStreamSampleImpl_Release,
722     /*** IStreamSample methods ***/
723     IAudioStreamSampleImpl_GetMediaStream,
724     IAudioStreamSampleImpl_GetSampleTimes,
725     IAudioStreamSampleImpl_SetSampleTimes,
726     IAudioStreamSampleImpl_Update,
727     IAudioStreamSampleImpl_CompletionStatus,
728     /*** IAudioStreamSample methods ***/
729     IAudioStreamSampleImpl_GetAudioData
730 };
731
732 static HRESULT audiostreamsample_create(IAudioMediaStream *parent, IAudioData *audio_data, IAudioStreamSample **audio_stream_sample)
733 {
734     IAudioStreamSampleImpl *object;
735
736     TRACE("(%p)\n", audio_stream_sample);
737
738     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAudioStreamSampleImpl));
739     if (!object)
740     {
741         ERR("Out of memory\n");
742         return E_OUTOFMEMORY;
743     }
744
745     object->IAudioStreamSample_iface.lpVtbl = &AudioStreamSample_Vtbl;
746     object->ref = 1;
747     object->parent = (IMediaStream*)parent;
748     object->audio_data = audio_data;
749
750     *audio_stream_sample = (IAudioStreamSample*)&object->IAudioStreamSample_iface;
751
752     return S_OK;
753 }