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 #ifndef __REACTOS__
22 #define NONAMELESSUNION
23 #endif
24 #define COBJMACROS
25 
26 #include <stdarg.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "dshow.h"
31 
32 #include "wine/strmbase.h"
33 
34 #include "amstream_private.h"
35 
36 #include "ddstream.h"
37 #include "wine/debug.h"
38 
39 WINE_DEFAULT_DEBUG_CHANNEL(amstream);
40 
41 #include <initguid.h>
42 DEFINE_GUID(IID_IDirectDraw7, 0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b);
43 
44 static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectDrawSurface *surface,
45     const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample);
46 static HRESULT audiostreamsample_create(IAudioMediaStream *parent, IAudioData *audio_data, IAudioStreamSample **audio_stream_sample);
47 
48 struct DirectDrawMediaStreamImpl;
49 
50 typedef struct {
51     BaseInputPin pin;
52     struct DirectDrawMediaStreamImpl *parent;
53 } DirectDrawMediaStreamInputPin;
54 
55 typedef struct DirectDrawMediaStreamImpl {
56     IAMMediaStream IAMMediaStream_iface;
57     IDirectDrawMediaStream IDirectDrawMediaStream_iface;
58     LONG ref;
59     IMultiMediaStream* parent;
60     MSPID purpose_id;
61     STREAM_TYPE stream_type;
62     IDirectDraw7 *ddraw;
63     DirectDrawMediaStreamInputPin *input_pin;
64     CRITICAL_SECTION critical_section;
65 } DirectDrawMediaStreamImpl;
66 
impl_from_DirectDrawMediaStream_IAMMediaStream(IAMMediaStream * iface)67 static inline DirectDrawMediaStreamImpl *impl_from_DirectDrawMediaStream_IAMMediaStream(IAMMediaStream *iface)
68 {
69     return CONTAINING_RECORD(iface, DirectDrawMediaStreamImpl, IAMMediaStream_iface);
70 }
71 
72 /*** IUnknown methods ***/
DirectDrawMediaStreamImpl_IAMMediaStream_QueryInterface(IAMMediaStream * iface,REFIID riid,void ** ret_iface)73 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_QueryInterface(IAMMediaStream *iface,
74                                                         REFIID riid, void **ret_iface)
75 {
76     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
77 
78     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface);
79 
80     if (IsEqualGUID(riid, &IID_IUnknown) ||
81         IsEqualGUID(riid, &IID_IMediaStream) ||
82         IsEqualGUID(riid, &IID_IAMMediaStream))
83     {
84         IAMMediaStream_AddRef(iface);
85         *ret_iface = iface;
86         return S_OK;
87     }
88     else if (IsEqualGUID(riid, &IID_IDirectDrawMediaStream))
89     {
90         IAMMediaStream_AddRef(iface);
91         *ret_iface = &This->IDirectDrawMediaStream_iface;
92         return S_OK;
93     }
94     else if (IsEqualGUID(riid, &IID_IPin))
95     {
96         IAMMediaStream_AddRef(iface);
97         *ret_iface = &This->input_pin->pin.pin.IPin_iface;
98         return S_OK;
99     }
100     else if (IsEqualGUID(riid, &IID_IMemInputPin))
101     {
102         IAMMediaStream_AddRef(iface);
103         *ret_iface = &This->input_pin->pin.IMemInputPin_iface;
104         return S_OK;
105     }
106 
107     ERR("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ret_iface);
108     return E_NOINTERFACE;
109 }
110 
DirectDrawMediaStreamImpl_IAMMediaStream_AddRef(IAMMediaStream * iface)111 static ULONG WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_AddRef(IAMMediaStream *iface)
112 {
113     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
114     ULONG ref = InterlockedIncrement(&This->ref);
115 
116     TRACE("(%p/%p)->(): new ref = %u\n", iface, This, ref);
117 
118     return ref;
119 }
120 
DirectDrawMediaStreamImpl_IAMMediaStream_Release(IAMMediaStream * iface)121 static ULONG WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_Release(IAMMediaStream *iface)
122 {
123     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
124     ULONG ref = InterlockedDecrement(&This->ref);
125 
126     TRACE("(%p/%p)->(): new ref = %u\n", iface, This, ref);
127 
128     if (!ref)
129     {
130         BaseInputPin_Destroy((BaseInputPin *)This->input_pin);
131         DeleteCriticalSection(&This->critical_section);
132         if (This->ddraw)
133             IDirectDraw7_Release(This->ddraw);
134         HeapFree(GetProcessHeap(), 0, This);
135     }
136 
137     return ref;
138 }
139 
140 /*** IMediaStream methods ***/
DirectDrawMediaStreamImpl_IAMMediaStream_GetMultiMediaStream(IAMMediaStream * iface,IMultiMediaStream ** multi_media_stream)141 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_GetMultiMediaStream(IAMMediaStream *iface,
142         IMultiMediaStream** multi_media_stream)
143 {
144     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
145 
146     TRACE("(%p/%p)->(%p)\n", This, iface, multi_media_stream);
147 
148     if (!multi_media_stream)
149         return E_POINTER;
150 
151     IMultiMediaStream_AddRef(This->parent);
152     *multi_media_stream = This->parent;
153 
154     return S_OK;
155 }
156 
DirectDrawMediaStreamImpl_IAMMediaStream_GetInformation(IAMMediaStream * iface,MSPID * purpose_id,STREAM_TYPE * type)157 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_GetInformation(IAMMediaStream *iface,
158         MSPID *purpose_id, STREAM_TYPE *type)
159 {
160     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
161 
162     TRACE("(%p/%p)->(%p,%p)\n", This, iface, purpose_id, type);
163 
164     if (purpose_id)
165         *purpose_id = This->purpose_id;
166     if (type)
167         *type = This->stream_type;
168 
169     return S_OK;
170 }
171 
DirectDrawMediaStreamImpl_IAMMediaStream_SetSameFormat(IAMMediaStream * iface,IMediaStream * pStreamThatHasDesiredFormat,DWORD flags)172 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_SetSameFormat(IAMMediaStream *iface,
173         IMediaStream *pStreamThatHasDesiredFormat, DWORD flags)
174 {
175     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
176 
177     FIXME("(%p/%p)->(%p,%x) stub!\n", This, iface, pStreamThatHasDesiredFormat, flags);
178 
179     return S_FALSE;
180 }
181 
DirectDrawMediaStreamImpl_IAMMediaStream_AllocateSample(IAMMediaStream * iface,DWORD flags,IStreamSample ** sample)182 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_AllocateSample(IAMMediaStream *iface,
183         DWORD flags, IStreamSample **sample)
184 {
185     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
186 
187     FIXME("(%p/%p)->(%x,%p) stub!\n", This, iface, flags, sample);
188 
189     return S_FALSE;
190 }
191 
DirectDrawMediaStreamImpl_IAMMediaStream_CreateSharedSample(IAMMediaStream * iface,IStreamSample * existing_sample,DWORD flags,IStreamSample ** sample)192 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_CreateSharedSample(IAMMediaStream *iface,
193         IStreamSample *existing_sample, DWORD flags, IStreamSample **sample)
194 {
195     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
196 
197     FIXME("(%p/%p)->(%p,%x,%p) stub!\n", This, iface, existing_sample, flags, sample);
198 
199     return S_FALSE;
200 }
201 
DirectDrawMediaStreamImpl_IAMMediaStream_SendEndOfStream(IAMMediaStream * iface,DWORD flags)202 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_SendEndOfStream(IAMMediaStream *iface, DWORD flags)
203 {
204     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
205 
206     FIXME("(%p/%p)->(%x) stub!\n", This, iface, flags);
207 
208     return S_FALSE;
209 }
210 
211 /*** IAMMediaStream methods ***/
DirectDrawMediaStreamImpl_IAMMediaStream_Initialize(IAMMediaStream * iface,IUnknown * source_object,DWORD flags,REFMSPID purpose_id,const STREAM_TYPE stream_type)212 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_Initialize(IAMMediaStream *iface, IUnknown *source_object, DWORD flags,
213                                                     REFMSPID purpose_id, const STREAM_TYPE stream_type)
214 {
215     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
216 
217     FIXME("(%p/%p)->(%p,%x,%p,%u) stub!\n", This, iface, source_object, flags, purpose_id, stream_type);
218 
219     return S_FALSE;
220 }
221 
DirectDrawMediaStreamImpl_IAMMediaStream_SetState(IAMMediaStream * iface,FILTER_STATE state)222 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_SetState(IAMMediaStream *iface, FILTER_STATE state)
223 {
224     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
225 
226     FIXME("(%p/%p)->(%u) stub!\n", This, iface, state);
227 
228     return S_FALSE;
229 }
230 
DirectDrawMediaStreamImpl_IAMMediaStream_JoinAMMultiMediaStream(IAMMediaStream * iface,IAMMultiMediaStream * am_multi_media_stream)231 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_JoinAMMultiMediaStream(IAMMediaStream *iface, IAMMultiMediaStream *am_multi_media_stream)
232 {
233     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
234 
235     FIXME("(%p/%p)->(%p) stub!\n", This, iface, am_multi_media_stream);
236 
237     return S_FALSE;
238 }
239 
DirectDrawMediaStreamImpl_IAMMediaStream_JoinFilter(IAMMediaStream * iface,IMediaStreamFilter * media_stream_filter)240 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_JoinFilter(IAMMediaStream *iface, IMediaStreamFilter *media_stream_filter)
241 {
242     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
243 
244     TRACE("(%p/%p)->(%p)\n", This, iface, media_stream_filter);
245 
246     This->input_pin->pin.pin.pinInfo.pFilter = (IBaseFilter *)media_stream_filter;
247 
248     return S_OK;
249 }
250 
DirectDrawMediaStreamImpl_IAMMediaStream_JoinFilterGraph(IAMMediaStream * iface,IFilterGraph * filtergraph)251 static HRESULT WINAPI DirectDrawMediaStreamImpl_IAMMediaStream_JoinFilterGraph(IAMMediaStream *iface, IFilterGraph *filtergraph)
252 {
253     DirectDrawMediaStreamImpl *This = impl_from_DirectDrawMediaStream_IAMMediaStream(iface);
254 
255     FIXME("(%p/%p)->(%p) stub!\n", This, iface, filtergraph);
256 
257     return S_FALSE;
258 }
259 
260 static const struct IAMMediaStreamVtbl DirectDrawMediaStreamImpl_IAMMediaStream_Vtbl =
261 {
262     /*** IUnknown methods ***/
263     DirectDrawMediaStreamImpl_IAMMediaStream_QueryInterface,
264     DirectDrawMediaStreamImpl_IAMMediaStream_AddRef,
265     DirectDrawMediaStreamImpl_IAMMediaStream_Release,
266     /*** IMediaStream methods ***/
267     DirectDrawMediaStreamImpl_IAMMediaStream_GetMultiMediaStream,
268     DirectDrawMediaStreamImpl_IAMMediaStream_GetInformation,
269     DirectDrawMediaStreamImpl_IAMMediaStream_SetSameFormat,
270     DirectDrawMediaStreamImpl_IAMMediaStream_AllocateSample,
271     DirectDrawMediaStreamImpl_IAMMediaStream_CreateSharedSample,
272     DirectDrawMediaStreamImpl_IAMMediaStream_SendEndOfStream,
273     /*** IAMMediaStream methods ***/
274     DirectDrawMediaStreamImpl_IAMMediaStream_Initialize,
275     DirectDrawMediaStreamImpl_IAMMediaStream_SetState,
276     DirectDrawMediaStreamImpl_IAMMediaStream_JoinAMMultiMediaStream,
277     DirectDrawMediaStreamImpl_IAMMediaStream_JoinFilter,
278     DirectDrawMediaStreamImpl_IAMMediaStream_JoinFilterGraph
279 };
280 
impl_from_IDirectDrawMediaStream(IDirectDrawMediaStream * iface)281 static inline DirectDrawMediaStreamImpl *impl_from_IDirectDrawMediaStream(IDirectDrawMediaStream *iface)
282 {
283     return CONTAINING_RECORD(iface, DirectDrawMediaStreamImpl, IDirectDrawMediaStream_iface);
284 }
285 
286 /*** IUnknown methods ***/
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_QueryInterface(IDirectDrawMediaStream * iface,REFIID riid,void ** ret_iface)287 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_QueryInterface(IDirectDrawMediaStream *iface,
288         REFIID riid, void **ret_iface)
289 {
290     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
291     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface);
292     return IAMMediaStream_QueryInterface(&This->IAMMediaStream_iface, riid, ret_iface);
293 }
294 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AddRef(IDirectDrawMediaStream * iface)295 static ULONG WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AddRef(IDirectDrawMediaStream *iface)
296 {
297     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
298     TRACE("(%p/%p)\n", iface, This);
299     return IAMMediaStream_AddRef(&This->IAMMediaStream_iface);
300 }
301 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_Release(IDirectDrawMediaStream * iface)302 static ULONG WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_Release(IDirectDrawMediaStream *iface)
303 {
304     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
305     TRACE("(%p/%p)\n", iface, This);
306     return IAMMediaStream_Release(&This->IAMMediaStream_iface);
307 }
308 
309 /*** IMediaStream methods ***/
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetMultiMediaStream(IDirectDrawMediaStream * iface,IMultiMediaStream ** multi_media_stream)310 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetMultiMediaStream(IDirectDrawMediaStream *iface,
311         IMultiMediaStream **multi_media_stream)
312 {
313     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
314 
315     TRACE("(%p/%p)->(%p)\n", This, iface, multi_media_stream);
316 
317     if (!multi_media_stream)
318         return E_POINTER;
319 
320     IMultiMediaStream_AddRef(This->parent);
321     *multi_media_stream = This->parent;
322 
323     return S_OK;
324 }
325 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetInformation(IDirectDrawMediaStream * iface,MSPID * purpose_id,STREAM_TYPE * type)326 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetInformation(IDirectDrawMediaStream *iface,
327         MSPID *purpose_id, STREAM_TYPE *type)
328 {
329     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
330 
331     TRACE("(%p/%p)->(%p,%p)\n", This, iface, purpose_id, type);
332 
333     if (purpose_id)
334         *purpose_id = This->purpose_id;
335     if (type)
336         *type = This->stream_type;
337 
338     return S_OK;
339 }
340 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetSameFormat(IDirectDrawMediaStream * iface,IMediaStream * pStreamThatHasDesiredFormat,DWORD dwFlags)341 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetSameFormat(IDirectDrawMediaStream *iface,
342         IMediaStream *pStreamThatHasDesiredFormat, DWORD dwFlags)
343 {
344     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
345 
346     FIXME("(%p/%p)->(%p,%x) stub!\n", This, iface, pStreamThatHasDesiredFormat, dwFlags);
347 
348     return S_FALSE;
349 }
350 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AllocateSample(IDirectDrawMediaStream * iface,DWORD dwFlags,IStreamSample ** ppSample)351 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AllocateSample(IDirectDrawMediaStream *iface,
352         DWORD dwFlags, IStreamSample **ppSample)
353 {
354     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
355 
356     FIXME("(%p/%p)->(%x,%p) stub!\n", This, iface, dwFlags, ppSample);
357 
358     return S_FALSE;
359 }
360 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSharedSample(IDirectDrawMediaStream * iface,IStreamSample * pExistingSample,DWORD dwFlags,IStreamSample ** ppSample)361 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSharedSample(IDirectDrawMediaStream *iface,
362         IStreamSample *pExistingSample, DWORD dwFlags, IStreamSample **ppSample)
363 {
364     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
365 
366     FIXME("(%p/%p)->(%p,%x,%p) stub!\n", This, iface, pExistingSample, dwFlags, ppSample);
367 
368     return S_FALSE;
369 }
370 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SendEndOfStream(IDirectDrawMediaStream * iface,DWORD dwFlags)371 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SendEndOfStream(IDirectDrawMediaStream *iface,
372         DWORD dwFlags)
373 {
374     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
375 
376     FIXME("(%p/%p)->(%x) stub!\n", This, iface, dwFlags);
377 
378     return S_FALSE;
379 }
380 
381 /*** IDirectDrawMediaStream methods ***/
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetFormat(IDirectDrawMediaStream * iface,DDSURFACEDESC * current_format,IDirectDrawPalette ** palette,DDSURFACEDESC * desired_format,DWORD * flags)382 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetFormat(IDirectDrawMediaStream *iface,
383         DDSURFACEDESC *current_format, IDirectDrawPalette **palette,
384         DDSURFACEDESC *desired_format, DWORD *flags)
385 {
386     FIXME("(%p)->(%p,%p,%p,%p) stub!\n", iface, current_format, palette, desired_format,
387             flags);
388 
389     return MS_E_NOSTREAM;
390 
391 }
392 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream * iface,const DDSURFACEDESC * pDDSurfaceDesc,IDirectDrawPalette * pDirectDrawPalette)393 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetFormat(IDirectDrawMediaStream *iface,
394         const DDSURFACEDESC *pDDSurfaceDesc, IDirectDrawPalette *pDirectDrawPalette)
395 {
396     FIXME("(%p)->(%p,%p) stub!\n", iface, pDDSurfaceDesc, pDirectDrawPalette);
397 
398     return E_NOTIMPL;
399 }
400 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetDirectDraw(IDirectDrawMediaStream * iface,IDirectDraw ** ddraw)401 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetDirectDraw(IDirectDrawMediaStream *iface,
402         IDirectDraw **ddraw)
403 {
404     DirectDrawMediaStreamImpl *This = impl_from_IDirectDrawMediaStream(iface);
405 
406     TRACE("(%p)->(%p)\n", iface, ddraw);
407 
408     *ddraw = NULL;
409     if (!This->ddraw)
410     {
411         HRESULT hr = DirectDrawCreateEx(NULL, (void**)&This->ddraw, &IID_IDirectDraw7, NULL);
412         if (FAILED(hr))
413             return hr;
414         IDirectDraw7_SetCooperativeLevel(This->ddraw, NULL, DDSCL_NORMAL);
415     }
416 
417     return IDirectDraw7_QueryInterface(This->ddraw, &IID_IDirectDraw, (void**)ddraw);
418 }
419 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetDirectDraw(IDirectDrawMediaStream * iface,IDirectDraw * pDirectDraw)420 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetDirectDraw(IDirectDrawMediaStream *iface,
421         IDirectDraw *pDirectDraw)
422 {
423     FIXME("(%p)->(%p) stub!\n", iface, pDirectDraw);
424 
425     return E_NOTIMPL;
426 }
427 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSample(IDirectDrawMediaStream * iface,IDirectDrawSurface * surface,const RECT * rect,DWORD dwFlags,IDirectDrawStreamSample ** ppSample)428 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSample(IDirectDrawMediaStream *iface,
429         IDirectDrawSurface *surface, const RECT *rect, DWORD dwFlags,
430         IDirectDrawStreamSample **ppSample)
431 {
432     TRACE("(%p)->(%p,%s,%x,%p)\n", iface, surface, wine_dbgstr_rect(rect), dwFlags, ppSample);
433 
434     return ddrawstreamsample_create(iface, surface, rect, ppSample);
435 }
436 
DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetTimePerFrame(IDirectDrawMediaStream * iface,STREAM_TIME * pFrameTime)437 static HRESULT WINAPI DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetTimePerFrame(IDirectDrawMediaStream *iface,
438         STREAM_TIME *pFrameTime)
439 {
440     FIXME("(%p)->(%p) stub!\n", iface, pFrameTime);
441 
442     return E_NOTIMPL;
443 }
444 
445 static const struct IDirectDrawMediaStreamVtbl DirectDrawMediaStreamImpl_IDirectDrawMediaStream_Vtbl =
446 {
447     /*** IUnknown methods ***/
448     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_QueryInterface,
449     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AddRef,
450     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_Release,
451     /*** IMediaStream methods ***/
452     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetMultiMediaStream,
453     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetInformation,
454     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetSameFormat,
455     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_AllocateSample,
456     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSharedSample,
457     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SendEndOfStream,
458     /*** IDirectDrawMediaStream methods ***/
459     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetFormat,
460     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetFormat,
461     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetDirectDraw,
462     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_SetDirectDraw,
463     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_CreateSample,
464     DirectDrawMediaStreamImpl_IDirectDrawMediaStream_GetTimePerFrame
465 };
466 
impl_from_DirectDrawMediaStreamInputPin_IPin(IPin * iface)467 static inline DirectDrawMediaStreamInputPin *impl_from_DirectDrawMediaStreamInputPin_IPin(IPin *iface)
468 {
469     return CONTAINING_RECORD(iface, DirectDrawMediaStreamInputPin, pin.pin.IPin_iface);
470 }
471 
472 /*** IUnknown methods ***/
DirectDrawMediaStreamInputPin_IPin_QueryInterface(IPin * iface,REFIID riid,void ** ret_iface)473 static HRESULT WINAPI DirectDrawMediaStreamInputPin_IPin_QueryInterface(IPin *iface, REFIID riid, void **ret_iface)
474 {
475     DirectDrawMediaStreamInputPin *This = impl_from_DirectDrawMediaStreamInputPin_IPin(iface);
476 
477     return IAMMediaStream_QueryInterface(&This->parent->IAMMediaStream_iface, riid, ret_iface);
478 }
479 
DirectDrawMediaStreamInputPin_IPin_AddRef(IPin * iface)480 static ULONG WINAPI DirectDrawMediaStreamInputPin_IPin_AddRef(IPin *iface)
481 {
482     DirectDrawMediaStreamInputPin *This = impl_from_DirectDrawMediaStreamInputPin_IPin(iface);
483 
484     return IAMMediaStream_AddRef(&This->parent->IAMMediaStream_iface);
485 }
486 
DirectDrawMediaStreamInputPin_IPin_Release(IPin * iface)487 static ULONG WINAPI DirectDrawMediaStreamInputPin_IPin_Release(IPin *iface)
488 {
489     DirectDrawMediaStreamInputPin *This = impl_from_DirectDrawMediaStreamInputPin_IPin(iface);
490 
491     return IAMMediaStream_Release(&This->parent->IAMMediaStream_iface);
492 }
493 
494 static const IPinVtbl DirectDrawMediaStreamInputPin_IPin_Vtbl =
495 {
496     DirectDrawMediaStreamInputPin_IPin_QueryInterface,
497     DirectDrawMediaStreamInputPin_IPin_AddRef,
498     DirectDrawMediaStreamInputPin_IPin_Release,
499     BaseInputPinImpl_Connect,
500     BaseInputPinImpl_ReceiveConnection,
501     BasePinImpl_Disconnect,
502     BasePinImpl_ConnectedTo,
503     BasePinImpl_ConnectionMediaType,
504     BasePinImpl_QueryPinInfo,
505     BasePinImpl_QueryDirection,
506     BasePinImpl_QueryId,
507     BasePinImpl_QueryAccept,
508     BasePinImpl_EnumMediaTypes,
509     BasePinImpl_QueryInternalConnections,
510     BaseInputPinImpl_EndOfStream,
511     BaseInputPinImpl_BeginFlush,
512     BaseInputPinImpl_EndFlush,
513     BaseInputPinImpl_NewSegment,
514 };
515 
DirectDrawMediaStreamInputPin_CheckMediaType(BasePin * base,const AM_MEDIA_TYPE * media_type)516 static HRESULT WINAPI DirectDrawMediaStreamInputPin_CheckMediaType(BasePin *base, const AM_MEDIA_TYPE *media_type)
517 {
518     DirectDrawMediaStreamInputPin *This = impl_from_DirectDrawMediaStreamInputPin_IPin(&base->IPin_iface);
519 
520     TRACE("(%p)->(%p)\n", This, media_type);
521 
522     if (IsEqualGUID(&media_type->majortype, &MEDIATYPE_Video))
523     {
524         if (IsEqualGUID(&media_type->subtype, &MEDIASUBTYPE_RGB1) ||
525             IsEqualGUID(&media_type->subtype, &MEDIASUBTYPE_RGB4) ||
526             IsEqualGUID(&media_type->subtype, &MEDIASUBTYPE_RGB8)  ||
527             IsEqualGUID(&media_type->subtype, &MEDIASUBTYPE_RGB565) ||
528             IsEqualGUID(&media_type->subtype, &MEDIASUBTYPE_RGB555) ||
529             IsEqualGUID(&media_type->subtype, &MEDIASUBTYPE_RGB24) ||
530             IsEqualGUID(&media_type->subtype, &MEDIASUBTYPE_RGB32))
531         {
532             TRACE("Video sub-type %s matches\n", debugstr_guid(&media_type->subtype));
533             return S_OK;
534         }
535     }
536 
537     return S_FALSE;
538 }
539 
DirectDrawMediaStreamInputPin_GetMediaTypeVersion(BasePin * base)540 static LONG WINAPI DirectDrawMediaStreamInputPin_GetMediaTypeVersion(BasePin *base)
541 {
542     return 0;
543 }
544 
DirectDrawMediaStreamInputPin_GetMediaType(BasePin * base,int index,AM_MEDIA_TYPE * media_type)545 static HRESULT WINAPI DirectDrawMediaStreamInputPin_GetMediaType(BasePin *base, int index, AM_MEDIA_TYPE *media_type)
546 {
547     DirectDrawMediaStreamInputPin *This = impl_from_DirectDrawMediaStreamInputPin_IPin(&base->IPin_iface);
548 
549     TRACE("(%p)->(%d,%p)\n", This, index, media_type);
550 
551     /* FIXME: Reset structure as we only fill majortype and minortype for now */
552     ZeroMemory(media_type, sizeof(*media_type));
553 
554     media_type->majortype = MEDIATYPE_Video;
555 
556     switch (index)
557     {
558         case 0:
559             media_type->subtype = MEDIASUBTYPE_RGB1;
560             break;
561         case 1:
562             media_type->subtype = MEDIASUBTYPE_RGB4;
563             break;
564         case 2:
565             media_type->subtype = MEDIASUBTYPE_RGB8;
566             break;
567         case 3:
568             media_type->subtype = MEDIASUBTYPE_RGB565;
569             break;
570         case 4:
571             media_type->subtype = MEDIASUBTYPE_RGB555;
572             break;
573         case 5:
574             media_type->subtype = MEDIASUBTYPE_RGB24;
575             break;
576         case 6:
577             media_type->subtype = MEDIASUBTYPE_RGB32;
578             break;
579         default:
580             return S_FALSE;
581     }
582 
583     return S_OK;
584 }
585 
DirectDrawMediaStreamInputPin_Receive(BaseInputPin * base,IMediaSample * sample)586 static HRESULT WINAPI DirectDrawMediaStreamInputPin_Receive(BaseInputPin *base, IMediaSample *sample)
587 {
588     DirectDrawMediaStreamInputPin *This = impl_from_DirectDrawMediaStreamInputPin_IPin(&base->pin.IPin_iface);
589 
590     FIXME("(%p)->(%p) stub!\n", This, sample);
591 
592     return E_NOTIMPL;
593 }
594 
595 static const BaseInputPinFuncTable DirectDrawMediaStreamInputPin_FuncTable =
596 {
597     {
598         DirectDrawMediaStreamInputPin_CheckMediaType,
599         NULL,
600         DirectDrawMediaStreamInputPin_GetMediaTypeVersion,
601         DirectDrawMediaStreamInputPin_GetMediaType,
602     },
603     DirectDrawMediaStreamInputPin_Receive,
604 };
605 
ddrawmediastream_create(IMultiMediaStream * parent,const MSPID * purpose_id,STREAM_TYPE stream_type,IAMMediaStream ** media_stream)606 HRESULT ddrawmediastream_create(IMultiMediaStream *parent, const MSPID *purpose_id,
607         STREAM_TYPE stream_type, IAMMediaStream **media_stream)
608 {
609     DirectDrawMediaStreamImpl *object;
610     PIN_INFO pin_info;
611     HRESULT hr;
612 
613     TRACE("(%p,%s,%p)\n", parent, debugstr_guid(purpose_id), media_stream);
614 
615     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DirectDrawMediaStreamImpl));
616     if (!object)
617         return E_OUTOFMEMORY;
618 
619     object->IAMMediaStream_iface.lpVtbl = &DirectDrawMediaStreamImpl_IAMMediaStream_Vtbl;
620     object->IDirectDrawMediaStream_iface.lpVtbl = &DirectDrawMediaStreamImpl_IDirectDrawMediaStream_Vtbl;
621     object->ref = 1;
622 
623     InitializeCriticalSection(&object->critical_section);
624 
625     pin_info.pFilter = NULL;
626     pin_info.dir = PINDIR_INPUT;
627     pin_info.achName[0] = 'I';
628     StringFromGUID2(purpose_id, pin_info.achName + 1, MAX_PIN_NAME - 1);
629     hr = BaseInputPin_Construct(&DirectDrawMediaStreamInputPin_IPin_Vtbl,
630         sizeof(DirectDrawMediaStreamInputPin), &pin_info, &DirectDrawMediaStreamInputPin_FuncTable,
631         &object->critical_section, NULL, (IPin **)&object->input_pin);
632     if (FAILED(hr))
633         goto out_object;
634 
635     object->input_pin->parent = object;
636 
637     object->parent = parent;
638     object->purpose_id = *purpose_id;
639     object->stream_type = stream_type;
640 
641     *media_stream = &object->IAMMediaStream_iface;
642 
643     return S_OK;
644 
645 out_object:
646     HeapFree(GetProcessHeap(), 0, object);
647 
648     return hr;
649 }
650 
651 struct AudioMediaStreamImpl;
652 
653 typedef struct {
654     BaseInputPin pin;
655     struct AudioMediaStreamImpl *parent;
656 } AudioMediaStreamInputPin;
657 
658 typedef struct AudioMediaStreamImpl {
659     IAMMediaStream IAMMediaStream_iface;
660     IAudioMediaStream IAudioMediaStream_iface;
661     LONG ref;
662     IMultiMediaStream* parent;
663     MSPID purpose_id;
664     STREAM_TYPE stream_type;
665     AudioMediaStreamInputPin *input_pin;
666     CRITICAL_SECTION critical_section;
667 } AudioMediaStreamImpl;
668 
impl_from_AudioMediaStream_IAMMediaStream(IAMMediaStream * iface)669 static inline AudioMediaStreamImpl *impl_from_AudioMediaStream_IAMMediaStream(IAMMediaStream *iface)
670 {
671     return CONTAINING_RECORD(iface, AudioMediaStreamImpl, IAMMediaStream_iface);
672 }
673 
674 /*** IUnknown methods ***/
AudioMediaStreamImpl_IAMMediaStream_QueryInterface(IAMMediaStream * iface,REFIID riid,void ** ret_iface)675 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_QueryInterface(IAMMediaStream *iface,
676                                                         REFIID riid, void **ret_iface)
677 {
678     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
679 
680     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface);
681 
682     if (IsEqualGUID(riid, &IID_IUnknown) ||
683         IsEqualGUID(riid, &IID_IMediaStream) ||
684         IsEqualGUID(riid, &IID_IAMMediaStream))
685     {
686         IAMMediaStream_AddRef(iface);
687         *ret_iface = iface;
688         return S_OK;
689     }
690     else if (IsEqualGUID(riid, &IID_IAudioMediaStream))
691     {
692         IAMMediaStream_AddRef(iface);
693         *ret_iface = &This->IAudioMediaStream_iface;
694         return S_OK;
695     }
696     else if (IsEqualGUID(riid, &IID_IPin))
697     {
698         IAMMediaStream_AddRef(iface);
699         *ret_iface = &This->input_pin->pin.pin.IPin_iface;
700         return S_OK;
701     }
702     else if (IsEqualGUID(riid, &IID_IMemInputPin))
703     {
704         IAMMediaStream_AddRef(iface);
705         *ret_iface = &This->input_pin->pin.IMemInputPin_iface;
706         return S_OK;
707     }
708 
709     ERR("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ret_iface);
710     return E_NOINTERFACE;
711 }
712 
AudioMediaStreamImpl_IAMMediaStream_AddRef(IAMMediaStream * iface)713 static ULONG WINAPI AudioMediaStreamImpl_IAMMediaStream_AddRef(IAMMediaStream *iface)
714 {
715     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
716     ULONG ref = InterlockedIncrement(&This->ref);
717 
718     TRACE("(%p/%p)->(): new ref = %u\n", iface, This, ref);
719 
720     return ref;
721 }
722 
AudioMediaStreamImpl_IAMMediaStream_Release(IAMMediaStream * iface)723 static ULONG WINAPI AudioMediaStreamImpl_IAMMediaStream_Release(IAMMediaStream *iface)
724 {
725     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
726     ULONG ref = InterlockedDecrement(&This->ref);
727 
728     TRACE("(%p/%p)->(): new ref = %u\n", iface, This, ref);
729 
730     if (!ref)
731     {
732         BaseInputPin_Destroy((BaseInputPin *)This->input_pin);
733         DeleteCriticalSection(&This->critical_section);
734         HeapFree(GetProcessHeap(), 0, This);
735     }
736 
737     return ref;
738 }
739 
740 /*** IMediaStream methods ***/
AudioMediaStreamImpl_IAMMediaStream_GetMultiMediaStream(IAMMediaStream * iface,IMultiMediaStream ** multi_media_stream)741 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_GetMultiMediaStream(IAMMediaStream *iface,
742         IMultiMediaStream** multi_media_stream)
743 {
744     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
745 
746     TRACE("(%p/%p)->(%p)\n", This, iface, multi_media_stream);
747 
748     if (!multi_media_stream)
749         return E_POINTER;
750 
751     IMultiMediaStream_AddRef(This->parent);
752     *multi_media_stream = This->parent;
753 
754     return S_OK;
755 }
756 
AudioMediaStreamImpl_IAMMediaStream_GetInformation(IAMMediaStream * iface,MSPID * purpose_id,STREAM_TYPE * type)757 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_GetInformation(IAMMediaStream *iface,
758         MSPID *purpose_id, STREAM_TYPE *type)
759 {
760     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
761 
762     TRACE("(%p/%p)->(%p,%p)\n", This, iface, purpose_id, type);
763 
764     if (purpose_id)
765         *purpose_id = This->purpose_id;
766     if (type)
767         *type = This->stream_type;
768 
769     return S_OK;
770 }
771 
AudioMediaStreamImpl_IAMMediaStream_SetSameFormat(IAMMediaStream * iface,IMediaStream * pStreamThatHasDesiredFormat,DWORD flags)772 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_SetSameFormat(IAMMediaStream *iface,
773         IMediaStream *pStreamThatHasDesiredFormat, DWORD flags)
774 {
775     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
776 
777     FIXME("(%p/%p)->(%p,%x) stub!\n", This, iface, pStreamThatHasDesiredFormat, flags);
778 
779     return S_FALSE;
780 }
781 
AudioMediaStreamImpl_IAMMediaStream_AllocateSample(IAMMediaStream * iface,DWORD flags,IStreamSample ** sample)782 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_AllocateSample(IAMMediaStream *iface,
783         DWORD flags, IStreamSample **sample)
784 {
785     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
786 
787     FIXME("(%p/%p)->(%x,%p) stub!\n", This, iface, flags, sample);
788 
789     return S_FALSE;
790 }
791 
AudioMediaStreamImpl_IAMMediaStream_CreateSharedSample(IAMMediaStream * iface,IStreamSample * existing_sample,DWORD flags,IStreamSample ** sample)792 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_CreateSharedSample(IAMMediaStream *iface,
793         IStreamSample *existing_sample, DWORD flags, IStreamSample **sample)
794 {
795     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
796 
797     FIXME("(%p/%p)->(%p,%x,%p) stub!\n", This, iface, existing_sample, flags, sample);
798 
799     return S_FALSE;
800 }
801 
AudioMediaStreamImpl_IAMMediaStream_SendEndOfStream(IAMMediaStream * iface,DWORD flags)802 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_SendEndOfStream(IAMMediaStream *iface, DWORD flags)
803 {
804     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
805 
806     FIXME("(%p/%p)->(%x) stub!\n", This, iface, flags);
807 
808     return S_FALSE;
809 }
810 
811 /*** IAMMediaStream methods ***/
AudioMediaStreamImpl_IAMMediaStream_Initialize(IAMMediaStream * iface,IUnknown * source_object,DWORD flags,REFMSPID purpose_id,const STREAM_TYPE stream_type)812 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_Initialize(IAMMediaStream *iface, IUnknown *source_object, DWORD flags,
813                                                     REFMSPID purpose_id, const STREAM_TYPE stream_type)
814 {
815     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
816 
817     FIXME("(%p/%p)->(%p,%x,%p,%u) stub!\n", This, iface, source_object, flags, purpose_id, stream_type);
818 
819     return S_FALSE;
820 }
821 
AudioMediaStreamImpl_IAMMediaStream_SetState(IAMMediaStream * iface,FILTER_STATE state)822 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_SetState(IAMMediaStream *iface, FILTER_STATE state)
823 {
824     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
825 
826     FIXME("(%p/%p)->(%u) stub!\n", This, iface, state);
827 
828     return S_FALSE;
829 }
830 
AudioMediaStreamImpl_IAMMediaStream_JoinAMMultiMediaStream(IAMMediaStream * iface,IAMMultiMediaStream * am_multi_media_stream)831 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_JoinAMMultiMediaStream(IAMMediaStream *iface, IAMMultiMediaStream *am_multi_media_stream)
832 {
833     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
834 
835     FIXME("(%p/%p)->(%p) stub!\n", This, iface, am_multi_media_stream);
836 
837     return S_FALSE;
838 }
839 
AudioMediaStreamImpl_IAMMediaStream_JoinFilter(IAMMediaStream * iface,IMediaStreamFilter * media_stream_filter)840 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_JoinFilter(IAMMediaStream *iface, IMediaStreamFilter *media_stream_filter)
841 {
842     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
843 
844     TRACE("(%p/%p)->(%p)\n", This, iface, media_stream_filter);
845 
846     This->input_pin->pin.pin.pinInfo.pFilter = (IBaseFilter *)media_stream_filter;
847 
848     return S_OK;
849 }
850 
AudioMediaStreamImpl_IAMMediaStream_JoinFilterGraph(IAMMediaStream * iface,IFilterGraph * filtergraph)851 static HRESULT WINAPI AudioMediaStreamImpl_IAMMediaStream_JoinFilterGraph(IAMMediaStream *iface, IFilterGraph *filtergraph)
852 {
853     AudioMediaStreamImpl *This = impl_from_AudioMediaStream_IAMMediaStream(iface);
854 
855     FIXME("(%p/%p)->(%p) stub!\n", This, iface, filtergraph);
856 
857     return S_FALSE;
858 }
859 
860 static const struct IAMMediaStreamVtbl AudioMediaStreamImpl_IAMMediaStream_Vtbl =
861 {
862     /*** IUnknown methods ***/
863     AudioMediaStreamImpl_IAMMediaStream_QueryInterface,
864     AudioMediaStreamImpl_IAMMediaStream_AddRef,
865     AudioMediaStreamImpl_IAMMediaStream_Release,
866     /*** IMediaStream methods ***/
867     AudioMediaStreamImpl_IAMMediaStream_GetMultiMediaStream,
868     AudioMediaStreamImpl_IAMMediaStream_GetInformation,
869     AudioMediaStreamImpl_IAMMediaStream_SetSameFormat,
870     AudioMediaStreamImpl_IAMMediaStream_AllocateSample,
871     AudioMediaStreamImpl_IAMMediaStream_CreateSharedSample,
872     AudioMediaStreamImpl_IAMMediaStream_SendEndOfStream,
873     /*** IAMMediaStream methods ***/
874     AudioMediaStreamImpl_IAMMediaStream_Initialize,
875     AudioMediaStreamImpl_IAMMediaStream_SetState,
876     AudioMediaStreamImpl_IAMMediaStream_JoinAMMultiMediaStream,
877     AudioMediaStreamImpl_IAMMediaStream_JoinFilter,
878     AudioMediaStreamImpl_IAMMediaStream_JoinFilterGraph
879 };
880 
impl_from_IAudioMediaStream(IAudioMediaStream * iface)881 static inline AudioMediaStreamImpl *impl_from_IAudioMediaStream(IAudioMediaStream *iface)
882 {
883     return CONTAINING_RECORD(iface, AudioMediaStreamImpl, IAudioMediaStream_iface);
884 }
885 
886 /*** IUnknown methods ***/
AudioMediaStreamImpl_IAudioMediaStream_QueryInterface(IAudioMediaStream * iface,REFIID riid,void ** ret_iface)887 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_QueryInterface(IAudioMediaStream *iface,
888         REFIID riid, void **ret_iface)
889 {
890     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
891     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ret_iface);
892     return IAMMediaStream_QueryInterface(&This->IAMMediaStream_iface, riid, ret_iface);
893 }
894 
AudioMediaStreamImpl_IAudioMediaStream_AddRef(IAudioMediaStream * iface)895 static ULONG WINAPI AudioMediaStreamImpl_IAudioMediaStream_AddRef(IAudioMediaStream *iface)
896 {
897     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
898     TRACE("(%p/%p)\n", iface, This);
899     return IAMMediaStream_AddRef(&This->IAMMediaStream_iface);
900 }
901 
AudioMediaStreamImpl_IAudioMediaStream_Release(IAudioMediaStream * iface)902 static ULONG WINAPI AudioMediaStreamImpl_IAudioMediaStream_Release(IAudioMediaStream *iface)
903 {
904     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
905     TRACE("(%p/%p)\n", iface, This);
906     return IAMMediaStream_Release(&This->IAMMediaStream_iface);
907 }
908 
909 /*** IMediaStream methods ***/
AudioMediaStreamImpl_IAudioMediaStream_GetMultiMediaStream(IAudioMediaStream * iface,IMultiMediaStream ** multi_media_stream)910 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_GetMultiMediaStream(IAudioMediaStream *iface,
911         IMultiMediaStream **multi_media_stream)
912 {
913     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
914 
915     TRACE("(%p/%p)->(%p)\n", iface, This, multi_media_stream);
916 
917     if (!multi_media_stream)
918         return E_POINTER;
919 
920     IMultiMediaStream_AddRef(This->parent);
921     *multi_media_stream = This->parent;
922 
923     return S_OK;
924 }
925 
AudioMediaStreamImpl_IAudioMediaStream_GetInformation(IAudioMediaStream * iface,MSPID * purpose_id,STREAM_TYPE * type)926 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_GetInformation(IAudioMediaStream *iface,
927         MSPID *purpose_id, STREAM_TYPE *type)
928 {
929     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
930 
931     TRACE("(%p/%p)->(%p,%p)\n", iface, This, purpose_id, type);
932 
933     if (purpose_id)
934         *purpose_id = This->purpose_id;
935     if (type)
936         *type = This->stream_type;
937 
938     return S_OK;
939 }
940 
AudioMediaStreamImpl_IAudioMediaStream_SetSameFormat(IAudioMediaStream * iface,IMediaStream * stream_format,DWORD flags)941 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_SetSameFormat(IAudioMediaStream *iface,
942         IMediaStream *stream_format, DWORD flags)
943 {
944     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
945 
946     FIXME("(%p/%p)->(%p,%x) stub!\n", iface, This, stream_format, flags);
947 
948     return S_FALSE;
949 }
950 
AudioMediaStreamImpl_IAudioMediaStream_AllocateSample(IAudioMediaStream * iface,DWORD flags,IStreamSample ** sample)951 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_AllocateSample(IAudioMediaStream *iface,
952         DWORD flags, IStreamSample **sample)
953 {
954     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
955 
956     FIXME("(%p/%p)->(%x,%p) stub!\n", iface, This, flags, sample);
957 
958     return S_FALSE;
959 }
960 
AudioMediaStreamImpl_IAudioMediaStream_CreateSharedSample(IAudioMediaStream * iface,IStreamSample * existing_sample,DWORD flags,IStreamSample ** sample)961 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_CreateSharedSample(IAudioMediaStream *iface,
962         IStreamSample *existing_sample, DWORD flags, IStreamSample **sample)
963 {
964     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
965 
966     FIXME("(%p/%p)->(%p,%x,%p) stub!\n", iface, This, existing_sample, flags, sample);
967 
968     return S_FALSE;
969 }
970 
AudioMediaStreamImpl_IAudioMediaStream_SendEndOfStream(IAudioMediaStream * iface,DWORD flags)971 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_SendEndOfStream(IAudioMediaStream *iface,
972         DWORD flags)
973 {
974     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
975 
976     FIXME("(%p/%p)->(%x) stub!\n", iface, This, flags);
977 
978     return S_FALSE;
979 }
980 
981 /*** IAudioMediaStream methods ***/
AudioMediaStreamImpl_IAudioMediaStream_GetFormat(IAudioMediaStream * iface,WAVEFORMATEX * wave_format_current)982 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_GetFormat(IAudioMediaStream *iface, WAVEFORMATEX *wave_format_current)
983 {
984     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
985 
986     FIXME("(%p/%p)->(%p) stub!\n", iface, This, wave_format_current);
987 
988     if (!wave_format_current)
989         return E_POINTER;
990 
991     return MS_E_NOSTREAM;
992 
993 }
994 
AudioMediaStreamImpl_IAudioMediaStream_SetFormat(IAudioMediaStream * iface,const WAVEFORMATEX * wave_format)995 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_SetFormat(IAudioMediaStream *iface, const WAVEFORMATEX *wave_format)
996 {
997     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
998 
999     FIXME("(%p/%p)->(%p) stub!\n", iface, This, wave_format);
1000 
1001     return E_NOTIMPL;
1002 }
1003 
AudioMediaStreamImpl_IAudioMediaStream_CreateSample(IAudioMediaStream * iface,IAudioData * audio_data,DWORD flags,IAudioStreamSample ** sample)1004 static HRESULT WINAPI AudioMediaStreamImpl_IAudioMediaStream_CreateSample(IAudioMediaStream *iface, IAudioData *audio_data,
1005                                                          DWORD flags, IAudioStreamSample **sample)
1006 {
1007     AudioMediaStreamImpl *This = impl_from_IAudioMediaStream(iface);
1008 
1009     TRACE("(%p/%p)->(%p,%u,%p)\n", iface, This, audio_data, flags, sample);
1010 
1011     if (!audio_data)
1012         return E_POINTER;
1013 
1014     return audiostreamsample_create(iface, audio_data, sample);
1015 }
1016 
1017 static const struct IAudioMediaStreamVtbl AudioMediaStreamImpl_IAudioMediaStream_Vtbl =
1018 {
1019     /*** IUnknown methods ***/
1020     AudioMediaStreamImpl_IAudioMediaStream_QueryInterface,
1021     AudioMediaStreamImpl_IAudioMediaStream_AddRef,
1022     AudioMediaStreamImpl_IAudioMediaStream_Release,
1023     /*** IMediaStream methods ***/
1024     AudioMediaStreamImpl_IAudioMediaStream_GetMultiMediaStream,
1025     AudioMediaStreamImpl_IAudioMediaStream_GetInformation,
1026     AudioMediaStreamImpl_IAudioMediaStream_SetSameFormat,
1027     AudioMediaStreamImpl_IAudioMediaStream_AllocateSample,
1028     AudioMediaStreamImpl_IAudioMediaStream_CreateSharedSample,
1029     AudioMediaStreamImpl_IAudioMediaStream_SendEndOfStream,
1030     /*** IAudioMediaStream methods ***/
1031     AudioMediaStreamImpl_IAudioMediaStream_GetFormat,
1032     AudioMediaStreamImpl_IAudioMediaStream_SetFormat,
1033     AudioMediaStreamImpl_IAudioMediaStream_CreateSample
1034 };
1035 
impl_from_AudioMediaStreamInputPin_IPin(IPin * iface)1036 static inline AudioMediaStreamInputPin *impl_from_AudioMediaStreamInputPin_IPin(IPin *iface)
1037 {
1038     return CONTAINING_RECORD(iface, AudioMediaStreamInputPin, pin.pin.IPin_iface);
1039 }
1040 
1041 /*** IUnknown methods ***/
AudioMediaStreamInputPin_IPin_QueryInterface(IPin * iface,REFIID riid,void ** ret_iface)1042 static HRESULT WINAPI AudioMediaStreamInputPin_IPin_QueryInterface(IPin *iface, REFIID riid, void **ret_iface)
1043 {
1044     AudioMediaStreamInputPin *This = impl_from_AudioMediaStreamInputPin_IPin(iface);
1045 
1046     return IAMMediaStream_QueryInterface(&This->parent->IAMMediaStream_iface, riid, ret_iface);
1047 }
1048 
AudioMediaStreamInputPin_IPin_AddRef(IPin * iface)1049 static ULONG WINAPI AudioMediaStreamInputPin_IPin_AddRef(IPin *iface)
1050 {
1051     AudioMediaStreamInputPin *This = impl_from_AudioMediaStreamInputPin_IPin(iface);
1052 
1053     return IAMMediaStream_AddRef(&This->parent->IAMMediaStream_iface);
1054 }
1055 
AudioMediaStreamInputPin_IPin_Release(IPin * iface)1056 static ULONG WINAPI AudioMediaStreamInputPin_IPin_Release(IPin *iface)
1057 {
1058     AudioMediaStreamInputPin *This = impl_from_AudioMediaStreamInputPin_IPin(iface);
1059 
1060     return IAMMediaStream_Release(&This->parent->IAMMediaStream_iface);
1061 }
1062 
1063 static const IPinVtbl AudioMediaStreamInputPin_IPin_Vtbl =
1064 {
1065     AudioMediaStreamInputPin_IPin_QueryInterface,
1066     AudioMediaStreamInputPin_IPin_AddRef,
1067     AudioMediaStreamInputPin_IPin_Release,
1068     BaseInputPinImpl_Connect,
1069     BaseInputPinImpl_ReceiveConnection,
1070     BasePinImpl_Disconnect,
1071     BasePinImpl_ConnectedTo,
1072     BasePinImpl_ConnectionMediaType,
1073     BasePinImpl_QueryPinInfo,
1074     BasePinImpl_QueryDirection,
1075     BasePinImpl_QueryId,
1076     BasePinImpl_QueryAccept,
1077     BasePinImpl_EnumMediaTypes,
1078     BasePinImpl_QueryInternalConnections,
1079     BaseInputPinImpl_EndOfStream,
1080     BaseInputPinImpl_BeginFlush,
1081     BaseInputPinImpl_EndFlush,
1082     BaseInputPinImpl_NewSegment,
1083 };
1084 
AudioMediaStreamInputPin_CheckMediaType(BasePin * base,const AM_MEDIA_TYPE * media_type)1085 static HRESULT WINAPI AudioMediaStreamInputPin_CheckMediaType(BasePin *base, const AM_MEDIA_TYPE *media_type)
1086 {
1087     AudioMediaStreamInputPin *This = impl_from_AudioMediaStreamInputPin_IPin(&base->IPin_iface);
1088 
1089     TRACE("(%p)->(%p)\n", This, media_type);
1090 
1091     if (IsEqualGUID(&media_type->majortype, &MEDIATYPE_Audio))
1092     {
1093         if (IsEqualGUID(&media_type->subtype, &MEDIASUBTYPE_PCM))
1094         {
1095             TRACE("Audio sub-type %s matches\n", debugstr_guid(&media_type->subtype));
1096             return S_OK;
1097         }
1098     }
1099 
1100     return S_OK;
1101 }
1102 
AudioMediaStreamInputPin_GetMediaTypeVersion(BasePin * base)1103 static LONG WINAPI AudioMediaStreamInputPin_GetMediaTypeVersion(BasePin *base)
1104 {
1105     return 0;
1106 }
1107 
AudioMediaStreamInputPin_GetMediaType(BasePin * base,int index,AM_MEDIA_TYPE * media_type)1108 static HRESULT WINAPI AudioMediaStreamInputPin_GetMediaType(BasePin *base, int index, AM_MEDIA_TYPE *media_type)
1109 {
1110     AudioMediaStreamInputPin *This = impl_from_AudioMediaStreamInputPin_IPin(&base->IPin_iface);
1111 
1112     TRACE("(%p)->(%d,%p)\n", This, index, media_type);
1113 
1114     /* FIXME: Reset structure as we only fill majortype and minortype for now */
1115     ZeroMemory(media_type, sizeof(*media_type));
1116 
1117     if (index)
1118         return S_FALSE;
1119 
1120     media_type->majortype = MEDIATYPE_Audio;
1121     media_type->subtype = MEDIASUBTYPE_PCM;
1122 
1123     return S_OK;
1124 }
1125 
AudioMediaStreamInputPin_Receive(BaseInputPin * base,IMediaSample * sample)1126 static HRESULT WINAPI AudioMediaStreamInputPin_Receive(BaseInputPin *base, IMediaSample *sample)
1127 {
1128     AudioMediaStreamInputPin *This = impl_from_AudioMediaStreamInputPin_IPin(&base->pin.IPin_iface);
1129 
1130     FIXME("(%p)->(%p) stub!\n", This, sample);
1131 
1132     return E_NOTIMPL;
1133 }
1134 
1135 static const BaseInputPinFuncTable AudioMediaStreamInputPin_FuncTable =
1136 {
1137     {
1138         AudioMediaStreamInputPin_CheckMediaType,
1139         NULL,
1140         AudioMediaStreamInputPin_GetMediaTypeVersion,
1141         AudioMediaStreamInputPin_GetMediaType,
1142     },
1143     AudioMediaStreamInputPin_Receive,
1144 };
1145 
audiomediastream_create(IMultiMediaStream * parent,const MSPID * purpose_id,STREAM_TYPE stream_type,IAMMediaStream ** media_stream)1146 HRESULT audiomediastream_create(IMultiMediaStream *parent, const MSPID *purpose_id,
1147         STREAM_TYPE stream_type, IAMMediaStream **media_stream)
1148 {
1149     AudioMediaStreamImpl *object;
1150     PIN_INFO pin_info;
1151     HRESULT hr;
1152 
1153     TRACE("(%p,%s,%p)\n", parent, debugstr_guid(purpose_id), media_stream);
1154 
1155     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(AudioMediaStreamImpl));
1156     if (!object)
1157         return E_OUTOFMEMORY;
1158 
1159     object->IAMMediaStream_iface.lpVtbl = &AudioMediaStreamImpl_IAMMediaStream_Vtbl;
1160     object->IAudioMediaStream_iface.lpVtbl = &AudioMediaStreamImpl_IAudioMediaStream_Vtbl;
1161     object->ref = 1;
1162 
1163     InitializeCriticalSection(&object->critical_section);
1164 
1165     pin_info.pFilter = NULL;
1166     pin_info.dir = PINDIR_INPUT;
1167     pin_info.achName[0] = 'I';
1168     StringFromGUID2(purpose_id, pin_info.achName + 1, MAX_PIN_NAME - 1);
1169     hr = BaseInputPin_Construct(&AudioMediaStreamInputPin_IPin_Vtbl,
1170         sizeof(AudioMediaStreamInputPin), &pin_info, &AudioMediaStreamInputPin_FuncTable,
1171         &object->critical_section, NULL, (IPin **)&object->input_pin);
1172     if (FAILED(hr))
1173         goto out_object;
1174 
1175     object->input_pin->parent = object;
1176 
1177     object->parent = parent;
1178     object->purpose_id = *purpose_id;
1179     object->stream_type = stream_type;
1180 
1181     *media_stream = &object->IAMMediaStream_iface;
1182 
1183     return S_OK;
1184 
1185 out_object:
1186     HeapFree(GetProcessHeap(), 0, object);
1187 
1188     return hr;
1189 }
1190 
1191 typedef struct {
1192     IDirectDrawStreamSample IDirectDrawStreamSample_iface;
1193     LONG ref;
1194     IMediaStream *parent;
1195     IDirectDrawSurface *surface;
1196     RECT rect;
1197 } IDirectDrawStreamSampleImpl;
1198 
impl_from_IDirectDrawStreamSample(IDirectDrawStreamSample * iface)1199 static inline IDirectDrawStreamSampleImpl *impl_from_IDirectDrawStreamSample(IDirectDrawStreamSample *iface)
1200 {
1201     return CONTAINING_RECORD(iface, IDirectDrawStreamSampleImpl, IDirectDrawStreamSample_iface);
1202 }
1203 
1204 /*** IUnknown methods ***/
IDirectDrawStreamSampleImpl_QueryInterface(IDirectDrawStreamSample * iface,REFIID riid,void ** ret_iface)1205 static HRESULT WINAPI IDirectDrawStreamSampleImpl_QueryInterface(IDirectDrawStreamSample *iface,
1206         REFIID riid, void **ret_iface)
1207 {
1208     TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ret_iface);
1209 
1210     if (IsEqualGUID(riid, &IID_IUnknown) ||
1211         IsEqualGUID(riid, &IID_IStreamSample) ||
1212         IsEqualGUID(riid, &IID_IDirectDrawStreamSample))
1213     {
1214         IDirectDrawStreamSample_AddRef(iface);
1215         *ret_iface = iface;
1216         return S_OK;
1217     }
1218 
1219     *ret_iface = NULL;
1220 
1221     ERR("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ret_iface);
1222     return E_NOINTERFACE;
1223 }
1224 
IDirectDrawStreamSampleImpl_AddRef(IDirectDrawStreamSample * iface)1225 static ULONG WINAPI IDirectDrawStreamSampleImpl_AddRef(IDirectDrawStreamSample *iface)
1226 {
1227     IDirectDrawStreamSampleImpl *This = impl_from_IDirectDrawStreamSample(iface);
1228     ULONG ref = InterlockedIncrement(&This->ref);
1229 
1230     TRACE("(%p)->(): new ref = %u\n", iface, ref);
1231 
1232     return ref;
1233 }
1234 
IDirectDrawStreamSampleImpl_Release(IDirectDrawStreamSample * iface)1235 static ULONG WINAPI IDirectDrawStreamSampleImpl_Release(IDirectDrawStreamSample *iface)
1236 {
1237     IDirectDrawStreamSampleImpl *This = impl_from_IDirectDrawStreamSample(iface);
1238     ULONG ref = InterlockedDecrement(&This->ref);
1239 
1240     TRACE("(%p)->(): new ref = %u\n", iface, ref);
1241 
1242     if (!ref)
1243     {
1244         if (This->surface)
1245             IDirectDrawSurface_Release(This->surface);
1246         IMediaStream_Release(This->parent);
1247         HeapFree(GetProcessHeap(), 0, This);
1248     }
1249 
1250     return ref;
1251 }
1252 
1253 /*** IStreamSample methods ***/
IDirectDrawStreamSampleImpl_GetMediaStream(IDirectDrawStreamSample * iface,IMediaStream ** media_stream)1254 static HRESULT WINAPI IDirectDrawStreamSampleImpl_GetMediaStream(IDirectDrawStreamSample *iface, IMediaStream **media_stream)
1255 {
1256     FIXME("(%p)->(%p): stub\n", iface, media_stream);
1257 
1258     return E_NOTIMPL;
1259 }
1260 
IDirectDrawStreamSampleImpl_GetSampleTimes(IDirectDrawStreamSample * iface,STREAM_TIME * start_time,STREAM_TIME * end_time,STREAM_TIME * current_time)1261 static HRESULT WINAPI IDirectDrawStreamSampleImpl_GetSampleTimes(IDirectDrawStreamSample *iface, STREAM_TIME *start_time,
1262                                                                  STREAM_TIME *end_time, STREAM_TIME *current_time)
1263 {
1264     FIXME("(%p)->(%p,%p,%p): stub\n", iface, start_time, end_time, current_time);
1265 
1266     return E_NOTIMPL;
1267 }
1268 
IDirectDrawStreamSampleImpl_SetSampleTimes(IDirectDrawStreamSample * iface,const STREAM_TIME * start_time,const STREAM_TIME * end_time)1269 static HRESULT WINAPI IDirectDrawStreamSampleImpl_SetSampleTimes(IDirectDrawStreamSample *iface, const STREAM_TIME *start_time,
1270                                                                  const STREAM_TIME *end_time)
1271 {
1272     FIXME("(%p)->(%p,%p): stub\n", iface, start_time, end_time);
1273 
1274     return E_NOTIMPL;
1275 }
1276 
IDirectDrawStreamSampleImpl_Update(IDirectDrawStreamSample * iface,DWORD flags,HANDLE event,PAPCFUNC func_APC,DWORD APC_data)1277 static HRESULT WINAPI IDirectDrawStreamSampleImpl_Update(IDirectDrawStreamSample *iface, DWORD flags, HANDLE event,
1278                                                          PAPCFUNC func_APC, DWORD APC_data)
1279 {
1280     FIXME("(%p)->(%x,%p,%p,%u): stub\n", iface, flags, event, func_APC, APC_data);
1281 
1282     return S_OK;
1283 }
1284 
IDirectDrawStreamSampleImpl_CompletionStatus(IDirectDrawStreamSample * iface,DWORD flags,DWORD milliseconds)1285 static HRESULT WINAPI IDirectDrawStreamSampleImpl_CompletionStatus(IDirectDrawStreamSample *iface, DWORD flags, DWORD milliseconds)
1286 {
1287     FIXME("(%p)->(%x,%u): stub\n", iface, flags, milliseconds);
1288 
1289     return E_NOTIMPL;
1290 }
1291 
1292 /*** IDirectDrawStreamSample methods ***/
IDirectDrawStreamSampleImpl_GetSurface(IDirectDrawStreamSample * iface,IDirectDrawSurface ** ddraw_surface,RECT * rect)1293 static HRESULT WINAPI IDirectDrawStreamSampleImpl_GetSurface(IDirectDrawStreamSample *iface, IDirectDrawSurface **ddraw_surface,
1294                                                              RECT *rect)
1295 {
1296     IDirectDrawStreamSampleImpl *This = impl_from_IDirectDrawStreamSample(iface);
1297 
1298     TRACE("(%p)->(%p,%p)\n", iface, ddraw_surface, rect);
1299 
1300     if (ddraw_surface)
1301     {
1302         *ddraw_surface = This->surface;
1303         if (*ddraw_surface)
1304             IDirectDrawSurface_AddRef(*ddraw_surface);
1305     }
1306 
1307     if (rect)
1308         *rect = This->rect;
1309 
1310     return S_OK;
1311 }
1312 
IDirectDrawStreamSampleImpl_SetRect(IDirectDrawStreamSample * iface,const RECT * rect)1313 static HRESULT WINAPI IDirectDrawStreamSampleImpl_SetRect(IDirectDrawStreamSample *iface, const RECT *rect)
1314 {
1315     FIXME("(%p)->(%p): stub\n", iface, rect);
1316 
1317     return E_NOTIMPL;
1318 }
1319 
1320 static const struct IDirectDrawStreamSampleVtbl DirectDrawStreamSample_Vtbl =
1321 {
1322     /*** IUnknown methods ***/
1323     IDirectDrawStreamSampleImpl_QueryInterface,
1324     IDirectDrawStreamSampleImpl_AddRef,
1325     IDirectDrawStreamSampleImpl_Release,
1326     /*** IStreamSample methods ***/
1327     IDirectDrawStreamSampleImpl_GetMediaStream,
1328     IDirectDrawStreamSampleImpl_GetSampleTimes,
1329     IDirectDrawStreamSampleImpl_SetSampleTimes,
1330     IDirectDrawStreamSampleImpl_Update,
1331     IDirectDrawStreamSampleImpl_CompletionStatus,
1332     /*** IDirectDrawStreamSample methods ***/
1333     IDirectDrawStreamSampleImpl_GetSurface,
1334     IDirectDrawStreamSampleImpl_SetRect
1335 };
1336 
ddrawstreamsample_create(IDirectDrawMediaStream * parent,IDirectDrawSurface * surface,const RECT * rect,IDirectDrawStreamSample ** ddraw_stream_sample)1337 static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectDrawSurface *surface,
1338     const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample)
1339 {
1340     IDirectDrawStreamSampleImpl *object;
1341     HRESULT hr;
1342 
1343     TRACE("(%p)\n", ddraw_stream_sample);
1344 
1345     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1346     if (!object)
1347         return E_OUTOFMEMORY;
1348 
1349     object->IDirectDrawStreamSample_iface.lpVtbl = &DirectDrawStreamSample_Vtbl;
1350     object->ref = 1;
1351     object->parent = (IMediaStream*)parent;
1352     IMediaStream_AddRef(object->parent);
1353 
1354     if (surface)
1355     {
1356         object->surface = surface;
1357         IDirectDrawSurface_AddRef(surface);
1358     }
1359     else
1360     {
1361         DDSURFACEDESC desc;
1362         IDirectDraw *ddraw;
1363 
1364         hr = IDirectDrawMediaStream_GetDirectDraw(parent, &ddraw);
1365         if (FAILED(hr))
1366         {
1367             IDirectDrawStreamSample_Release(&object->IDirectDrawStreamSample_iface);
1368             return hr;
1369         }
1370 
1371         desc.dwSize = sizeof(desc);
1372         desc.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
1373         desc.dwHeight = 100;
1374         desc.dwWidth = 100;
1375         desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
1376         desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
1377         desc.ddpfPixelFormat.dwRGBBitCount = 32;
1378         desc.ddpfPixelFormat.dwRBitMask = 0xff0000;
1379         desc.ddpfPixelFormat.dwGBitMask = 0x00ff00;
1380         desc.ddpfPixelFormat.dwBBitMask = 0x0000ff;
1381         desc.ddpfPixelFormat.dwRGBAlphaBitMask = 0;
1382         desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN;
1383         desc.lpSurface = NULL;
1384 
1385         hr = IDirectDraw_CreateSurface(ddraw, &desc, &object->surface, NULL);
1386         IDirectDraw_Release(ddraw);
1387         if (FAILED(hr))
1388         {
1389             ERR("failed to create surface, 0x%08x\n", hr);
1390             IDirectDrawStreamSample_Release(&object->IDirectDrawStreamSample_iface);
1391             return hr;
1392         }
1393     }
1394 
1395     if (rect)
1396         object->rect = *rect;
1397     else if (object->surface)
1398     {
1399         DDSURFACEDESC desc = { sizeof(desc) };
1400         hr = IDirectDrawSurface_GetSurfaceDesc(object->surface, &desc);
1401         if (hr == S_OK)
1402             SetRect(&object->rect, 0, 0, desc.dwWidth, desc.dwHeight);
1403     }
1404 
1405     *ddraw_stream_sample = &object->IDirectDrawStreamSample_iface;
1406 
1407     return S_OK;
1408 }
1409 
1410 typedef struct {
1411     IAudioStreamSample IAudioStreamSample_iface;
1412     LONG ref;
1413     IMediaStream *parent;
1414     IAudioData *audio_data;
1415 } IAudioStreamSampleImpl;
1416 
impl_from_IAudioStreamSample(IAudioStreamSample * iface)1417 static inline IAudioStreamSampleImpl *impl_from_IAudioStreamSample(IAudioStreamSample *iface)
1418 {
1419     return CONTAINING_RECORD(iface, IAudioStreamSampleImpl, IAudioStreamSample_iface);
1420 }
1421 
1422 /*** IUnknown methods ***/
IAudioStreamSampleImpl_QueryInterface(IAudioStreamSample * iface,REFIID riid,void ** ret_iface)1423 static HRESULT WINAPI IAudioStreamSampleImpl_QueryInterface(IAudioStreamSample *iface,
1424         REFIID riid, void **ret_iface)
1425 {
1426     TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ret_iface);
1427 
1428     if (IsEqualGUID(riid, &IID_IUnknown) ||
1429         IsEqualGUID(riid, &IID_IStreamSample) ||
1430         IsEqualGUID(riid, &IID_IAudioStreamSample))
1431     {
1432         IAudioStreamSample_AddRef(iface);
1433         *ret_iface = iface;
1434         return S_OK;
1435     }
1436 
1437     *ret_iface = NULL;
1438 
1439     ERR("(%p)->(%s,%p),not found\n", iface, debugstr_guid(riid), ret_iface);
1440     return E_NOINTERFACE;
1441 }
1442 
IAudioStreamSampleImpl_AddRef(IAudioStreamSample * iface)1443 static ULONG WINAPI IAudioStreamSampleImpl_AddRef(IAudioStreamSample *iface)
1444 {
1445     IAudioStreamSampleImpl *This = impl_from_IAudioStreamSample(iface);
1446     ULONG ref = InterlockedIncrement(&This->ref);
1447 
1448     TRACE("(%p)->(): new ref = %u\n", iface, ref);
1449 
1450     return ref;
1451 }
1452 
IAudioStreamSampleImpl_Release(IAudioStreamSample * iface)1453 static ULONG WINAPI IAudioStreamSampleImpl_Release(IAudioStreamSample *iface)
1454 {
1455     IAudioStreamSampleImpl *This = impl_from_IAudioStreamSample(iface);
1456     ULONG ref = InterlockedDecrement(&This->ref);
1457 
1458     TRACE("(%p)->(): new ref = %u\n", iface, ref);
1459 
1460     if (!ref)
1461         HeapFree(GetProcessHeap(), 0, This);
1462 
1463     return ref;
1464 }
1465 
1466 /*** IStreamSample methods ***/
IAudioStreamSampleImpl_GetMediaStream(IAudioStreamSample * iface,IMediaStream ** media_stream)1467 static HRESULT WINAPI IAudioStreamSampleImpl_GetMediaStream(IAudioStreamSample *iface, IMediaStream **media_stream)
1468 {
1469     FIXME("(%p)->(%p): stub\n", iface, media_stream);
1470 
1471     return E_NOTIMPL;
1472 }
1473 
IAudioStreamSampleImpl_GetSampleTimes(IAudioStreamSample * iface,STREAM_TIME * start_time,STREAM_TIME * end_time,STREAM_TIME * current_time)1474 static HRESULT WINAPI IAudioStreamSampleImpl_GetSampleTimes(IAudioStreamSample *iface, STREAM_TIME *start_time,
1475                                                                  STREAM_TIME *end_time, STREAM_TIME *current_time)
1476 {
1477     FIXME("(%p)->(%p,%p,%p): stub\n", iface, start_time, end_time, current_time);
1478 
1479     return E_NOTIMPL;
1480 }
1481 
IAudioStreamSampleImpl_SetSampleTimes(IAudioStreamSample * iface,const STREAM_TIME * start_time,const STREAM_TIME * end_time)1482 static HRESULT WINAPI IAudioStreamSampleImpl_SetSampleTimes(IAudioStreamSample *iface, const STREAM_TIME *start_time,
1483                                                                  const STREAM_TIME *end_time)
1484 {
1485     FIXME("(%p)->(%p,%p): stub\n", iface, start_time, end_time);
1486 
1487     return E_NOTIMPL;
1488 }
1489 
IAudioStreamSampleImpl_Update(IAudioStreamSample * iface,DWORD flags,HANDLE event,PAPCFUNC func_APC,DWORD APC_data)1490 static HRESULT WINAPI IAudioStreamSampleImpl_Update(IAudioStreamSample *iface, DWORD flags, HANDLE event,
1491                                                          PAPCFUNC func_APC, DWORD APC_data)
1492 {
1493     FIXME("(%p)->(%x,%p,%p,%u): stub\n", iface, flags, event, func_APC, APC_data);
1494 
1495     return E_NOTIMPL;
1496 }
1497 
IAudioStreamSampleImpl_CompletionStatus(IAudioStreamSample * iface,DWORD flags,DWORD milliseconds)1498 static HRESULT WINAPI IAudioStreamSampleImpl_CompletionStatus(IAudioStreamSample *iface, DWORD flags, DWORD milliseconds)
1499 {
1500     FIXME("(%p)->(%x,%u): stub\n", iface, flags, milliseconds);
1501 
1502     return E_NOTIMPL;
1503 }
1504 
1505 /*** IAudioStreamSample methods ***/
IAudioStreamSampleImpl_GetAudioData(IAudioStreamSample * iface,IAudioData ** audio_data)1506 static HRESULT WINAPI IAudioStreamSampleImpl_GetAudioData(IAudioStreamSample *iface, IAudioData **audio_data)
1507 {
1508     FIXME("(%p)->(%p): stub\n", iface, audio_data);
1509 
1510     return E_NOTIMPL;
1511 }
1512 
1513 static const struct IAudioStreamSampleVtbl AudioStreamSample_Vtbl =
1514 {
1515     /*** IUnknown methods ***/
1516     IAudioStreamSampleImpl_QueryInterface,
1517     IAudioStreamSampleImpl_AddRef,
1518     IAudioStreamSampleImpl_Release,
1519     /*** IStreamSample methods ***/
1520     IAudioStreamSampleImpl_GetMediaStream,
1521     IAudioStreamSampleImpl_GetSampleTimes,
1522     IAudioStreamSampleImpl_SetSampleTimes,
1523     IAudioStreamSampleImpl_Update,
1524     IAudioStreamSampleImpl_CompletionStatus,
1525     /*** IAudioStreamSample methods ***/
1526     IAudioStreamSampleImpl_GetAudioData
1527 };
1528 
audiostreamsample_create(IAudioMediaStream * parent,IAudioData * audio_data,IAudioStreamSample ** audio_stream_sample)1529 static HRESULT audiostreamsample_create(IAudioMediaStream *parent, IAudioData *audio_data, IAudioStreamSample **audio_stream_sample)
1530 {
1531     IAudioStreamSampleImpl *object;
1532 
1533     TRACE("(%p)\n", audio_stream_sample);
1534 
1535     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IAudioStreamSampleImpl));
1536     if (!object)
1537         return E_OUTOFMEMORY;
1538 
1539     object->IAudioStreamSample_iface.lpVtbl = &AudioStreamSample_Vtbl;
1540     object->ref = 1;
1541     object->parent = (IMediaStream*)parent;
1542     object->audio_data = audio_data;
1543 
1544     *audio_stream_sample = (IAudioStreamSample*)&object->IAudioStreamSample_iface;
1545 
1546     return S_OK;
1547 }
1548