amstream: Implement AMAudioStream::NewSegment.
[wine/zf.git] / dlls / amstream / tests / amstream.c
blobeb9b852ba48774b99d7e778bbe2dbc0627b6a1bb
1 /*
2 * Unit tests for MultiMedia Stream functions
4 * Copyright (C) 2009, 2012 Christian Costa
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.
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.
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
21 #define COBJMACROS
23 #include "wine/test.h"
24 #include "dshow.h"
25 #include "amstream.h"
26 #include "mmreg.h"
27 #include "ks.h"
28 #include "initguid.h"
29 #include "ksmedia.h"
30 #include "wine/strmbase.h"
32 static const WAVEFORMATEX audio_format =
34 .wFormatTag = WAVE_FORMAT_PCM,
35 .nChannels = 1,
36 .nSamplesPerSec = 11025,
37 .wBitsPerSample = 16,
38 .nBlockAlign = 2,
39 .nAvgBytesPerSec = 2 * 11025,
42 static const AM_MEDIA_TYPE audio_mt =
44 /* MEDIATYPE_Audio, MEDIASUBTYPE_PCM, FORMAT_WaveFormatEx */
45 .majortype = {0x73647561, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
46 .subtype = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
47 .formattype = {0x05589f81, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
48 .cbFormat = sizeof(WAVEFORMATEX),
49 .pbFormat = (BYTE *)&audio_format,
52 static const WCHAR primary_video_sink_id[] = L"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}";
53 static const WCHAR primary_audio_sink_id[] = L"I{A35FF56B-9FDA-11D0-8FDF-00C04FD9189D}";
55 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
56 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
58 ULONG rc;
59 IUnknown_AddRef(obj);
60 rc = IUnknown_Release(obj);
61 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
64 static IDirectDraw7* pdd7;
65 static IDirectDrawSurface7* pdds7;
67 static IAMMultiMediaStream *create_ammultimediastream(void)
69 IAMMultiMediaStream *stream = NULL;
70 HRESULT hr = CoCreateInstance(&CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER,
71 &IID_IAMMultiMediaStream, (void **)&stream);
72 ok(hr == S_OK, "Got hr %#x.\n", hr);
73 return stream;
76 static int create_directdraw(void)
78 HRESULT hr;
79 IDirectDraw* pdd = NULL;
80 DDSURFACEDESC2 ddsd;
82 hr = DirectDrawCreate(NULL, &pdd, NULL);
83 ok(hr==DD_OK, "DirectDrawCreate returned: %x\n", hr);
84 if (hr != DD_OK)
85 goto error;
87 hr = IDirectDraw_QueryInterface(pdd, &IID_IDirectDraw7, (LPVOID*)&pdd7);
88 ok(hr==DD_OK, "QueryInterface returned: %x\n", hr);
89 if (hr != DD_OK) goto error;
91 hr = IDirectDraw7_SetCooperativeLevel(pdd7, GetDesktopWindow(), DDSCL_NORMAL);
92 ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr);
94 ZeroMemory(&ddsd, sizeof(ddsd));
95 ddsd.dwSize = sizeof(ddsd);
96 ddsd.dwFlags = DDSD_CAPS;
97 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
98 hr = IDirectDraw7_CreateSurface(pdd7, &ddsd, &pdds7, NULL);
99 ok(hr==DD_OK, "CreateSurface returned: %x\n", hr);
101 return TRUE;
103 error:
104 if (pdds7)
105 IDirectDrawSurface7_Release(pdds7);
106 if (pdd7)
107 IDirectDraw7_Release(pdd7);
108 if (pdd)
109 IDirectDraw_Release(pdd);
111 return FALSE;
114 static void release_directdraw(void)
116 IDirectDrawSurface7_Release(pdds7);
117 IDirectDraw7_Release(pdd7);
120 static ULONG get_refcount(void *iface)
122 IUnknown *unknown = iface;
123 IUnknown_AddRef(unknown);
124 return IUnknown_Release(unknown);
127 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
128 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
130 IUnknown *iface = iface_ptr;
131 HRESULT hr, expected_hr;
132 IUnknown *unk;
134 expected_hr = supported ? S_OK : E_NOINTERFACE;
136 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
137 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
138 if (SUCCEEDED(hr))
139 IUnknown_Release(unk);
142 static void test_interfaces(void)
144 IAMMultiMediaStream *mmstream = create_ammultimediastream();
145 IMediaStreamFilter *filter;
146 IMediaStream *stream;
147 HRESULT hr;
148 ULONG ref;
150 check_interface(mmstream, &IID_IAMMultiMediaStream, TRUE);
151 check_interface(mmstream, &IID_IMultiMediaStream, TRUE);
152 check_interface(mmstream, &IID_IUnknown, TRUE);
154 check_interface(mmstream, &IID_IAMMediaStream, FALSE);
155 check_interface(mmstream, &IID_IAMMediaTypeStream, FALSE);
156 check_interface(mmstream, &IID_IAudioMediaStream, FALSE);
157 check_interface(mmstream, &IID_IBaseFilter, FALSE);
158 check_interface(mmstream, &IID_IDirectDrawMediaStream, FALSE);
159 check_interface(mmstream, &IID_IMediaFilter, FALSE);
160 check_interface(mmstream, &IID_IMediaStream, FALSE);
161 check_interface(mmstream, &IID_IMediaStreamFilter, FALSE);
162 check_interface(mmstream, &IID_IPin, FALSE);
164 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
165 ok(hr == S_OK, "Got hr %#x.\n", hr);
167 check_interface(filter, &IID_IBaseFilter, TRUE);
168 check_interface(filter, &IID_IMediaFilter, TRUE);
169 check_interface(filter, &IID_IMediaStreamFilter, TRUE);
170 check_interface(filter, &IID_IPersist, TRUE);
171 check_interface(filter, &IID_IUnknown, TRUE);
173 check_interface(filter, &IID_IAMMediaStream, FALSE);
174 check_interface(filter, &IID_IAMMediaTypeStream, FALSE);
175 check_interface(filter, &IID_IAMMultiMediaStream, FALSE);
176 check_interface(filter, &IID_IAudioMediaStream, FALSE);
177 check_interface(filter, &IID_IDirectDrawMediaStream, FALSE);
178 check_interface(filter, &IID_IMediaStream, FALSE);
179 check_interface(filter, &IID_IMultiMediaStream, FALSE);
180 check_interface(filter, &IID_IPin, FALSE);
182 IMediaStreamFilter_Release(filter);
184 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
185 ok(hr == S_OK, "Got hr %#x.\n", hr);
187 check_interface(stream, &IID_IAMMediaStream, TRUE);
188 check_interface(stream, &IID_IAudioMediaStream, TRUE);
189 check_interface(stream, &IID_IMediaStream, TRUE);
190 check_interface(stream, &IID_IMemInputPin, TRUE);
191 check_interface(stream, &IID_IPin, TRUE);
192 check_interface(stream, &IID_IUnknown, TRUE);
194 check_interface(stream, &IID_IAMMediaTypeStream, FALSE);
195 check_interface(stream, &IID_IAMMultiMediaStream, FALSE);
196 check_interface(stream, &IID_IBaseFilter, FALSE);
197 check_interface(stream, &IID_IDirectDrawMediaStream, FALSE);
198 check_interface(stream, &IID_IMediaFilter, FALSE);
199 check_interface(stream, &IID_IMediaStreamFilter, FALSE);
200 check_interface(stream, &IID_IMultiMediaStream, FALSE);
201 check_interface(stream, &IID_IPersist, FALSE);
203 IMediaStream_Release(stream);
205 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
206 ok(hr == S_OK, "Got hr %#x.\n", hr);
208 check_interface(stream, &IID_IAMMediaStream, TRUE);
209 check_interface(stream, &IID_IDirectDrawMediaStream, TRUE);
210 check_interface(stream, &IID_IMediaStream, TRUE);
211 check_interface(stream, &IID_IMemInputPin, TRUE);
212 check_interface(stream, &IID_IPin, TRUE);
213 check_interface(stream, &IID_IUnknown, TRUE);
215 check_interface(stream, &IID_IAMMediaTypeStream, FALSE);
216 check_interface(stream, &IID_IAMMultiMediaStream, FALSE);
217 check_interface(stream, &IID_IAudioMediaStream, FALSE);
218 check_interface(stream, &IID_IBaseFilter, FALSE);
219 check_interface(stream, &IID_IDirectDraw, FALSE);
220 check_interface(stream, &IID_IMediaFilter, FALSE);
221 check_interface(stream, &IID_IMediaStreamFilter, FALSE);
222 check_interface(stream, &IID_IMultiMediaStream, FALSE);
223 check_interface(stream, &IID_IPersist, FALSE);
225 IMediaStream_Release(stream);
227 ref = IAMMultiMediaStream_Release(mmstream);
228 ok(!ref, "Got outstanding refcount %u.\n", ref);
231 static void test_openfile(void)
233 IAMMultiMediaStream *pams;
234 HRESULT hr;
235 IGraphBuilder* pgraph;
237 if (!(pams = create_ammultimediastream()))
238 return;
240 hr = IAMMultiMediaStream_GetFilterGraph(pams, &pgraph);
241 ok(hr==S_OK, "IAMMultiMediaStream_GetFilterGraph returned: %x\n", hr);
242 ok(pgraph==NULL, "Filtergraph should not be created yet\n");
244 if (pgraph)
245 IGraphBuilder_Release(pgraph);
247 check_interface(pams, &IID_IMediaSeeking, FALSE);
249 hr = IAMMultiMediaStream_OpenFile(pams, L"test.avi", 0);
250 ok(hr==S_OK, "IAMMultiMediaStream_OpenFile returned: %x\n", hr);
252 check_interface(pams, &IID_IMediaSeeking, TRUE);
254 hr = IAMMultiMediaStream_GetFilterGraph(pams, &pgraph);
255 ok(hr==S_OK, "IAMMultiMediaStream_GetFilterGraph returned: %x\n", hr);
256 ok(pgraph!=NULL, "Filtergraph should be created\n");
258 if (pgraph)
259 IGraphBuilder_Release(pgraph);
261 IAMMultiMediaStream_Release(pams);
264 static void test_renderfile(void)
266 IAMMultiMediaStream *pams;
267 HRESULT hr;
268 IMediaStream *pvidstream = NULL;
269 IDirectDrawMediaStream *pddstream = NULL;
270 IDirectDrawStreamSample *pddsample = NULL;
271 IDirectDrawSurface *surface;
272 RECT rect;
274 if (!(pams = create_ammultimediastream()))
275 return;
276 if (!create_directdraw())
278 IAMMultiMediaStream_Release(pams);
279 return;
282 hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL);
283 ok(hr==S_OK, "IAMMultiMediaStream_Initialize returned: %x\n", hr);
285 hr = IAMMultiMediaStream_AddMediaStream(pams, (IUnknown*)pdd7, &MSPID_PrimaryVideo, 0, NULL);
286 ok(hr==S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
288 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
289 ok(hr==S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
291 hr = IAMMultiMediaStream_OpenFile(pams, L"test.avi", 0);
292 ok(hr==S_OK, "IAMMultiMediaStream_OpenFile returned: %x\n", hr);
294 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &pvidstream);
295 ok(hr==S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
296 if (FAILED(hr)) goto error;
298 hr = IMediaStream_QueryInterface(pvidstream, &IID_IDirectDrawMediaStream, (LPVOID*)&pddstream);
299 ok(hr==S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
300 if (FAILED(hr)) goto error;
302 hr = IDirectDrawMediaStream_CreateSample(pddstream, NULL, NULL, 0, &pddsample);
303 ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr);
305 surface = NULL;
306 hr = IDirectDrawStreamSample_GetSurface(pddsample, &surface, &rect);
307 ok(hr == S_OK, "got 0x%08x\n", hr);
308 ok(surface == NULL, "got %p\n", surface);
309 IDirectDrawStreamSample_Release(pddsample);
311 hr = IDirectDrawSurface7_QueryInterface(pdds7, &IID_IDirectDrawSurface, (void**)&surface);
312 ok(hr == S_OK, "got 0x%08x\n", hr);
314 EXPECT_REF(surface, 1);
315 hr = IDirectDrawMediaStream_CreateSample(pddstream, surface, NULL, 0, &pddsample);
316 ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr);
317 EXPECT_REF(surface, 2);
318 IDirectDrawStreamSample_Release(pddsample);
319 IDirectDrawSurface_Release(surface);
321 error:
322 if (pddstream)
323 IDirectDrawMediaStream_Release(pddstream);
324 if (pvidstream)
325 IMediaStream_Release(pvidstream);
327 release_directdraw();
328 IAMMultiMediaStream_Release(pams);
331 static const GUID test_mspid = {0x88888888};
333 struct teststream
335 IAMMediaStream IAMMediaStream_iface;
336 IPin IPin_iface;
337 LONG refcount;
338 GUID mspid;
339 IAMMultiMediaStream *mmstream;
340 IMediaStreamFilter *filter;
341 IFilterGraph *graph;
342 FILTER_STATE state;
343 HRESULT set_state_result;
346 static struct teststream *impl_from_IAMMediaStream(IAMMediaStream *iface)
348 return CONTAINING_RECORD(iface, struct teststream, IAMMediaStream_iface);
351 static struct teststream *impl_from_IPin(IPin *iface)
353 return CONTAINING_RECORD(iface, struct teststream, IPin_iface);
356 static HRESULT WINAPI pin_QueryInterface(IPin *iface, REFIID iid, void **out)
358 struct teststream *stream = impl_from_IPin(iface);
359 return IAMMediaStream_QueryInterface(&stream->IAMMediaStream_iface, iid, out);
362 static ULONG WINAPI pin_AddRef(IPin *iface)
364 struct teststream *stream = impl_from_IPin(iface);
365 return IAMMediaStream_AddRef(&stream->IAMMediaStream_iface);
368 static ULONG WINAPI pin_Release(IPin *iface)
370 struct teststream *stream = impl_from_IPin(iface);
371 return IAMMediaStream_Release(&stream->IAMMediaStream_iface);
374 static HRESULT WINAPI pin_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
376 ok(0, "Unexpected call.\n");
377 return E_NOTIMPL;
380 static HRESULT WINAPI pin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
382 ok(0, "Unexpected call.\n");
383 return E_NOTIMPL;
386 static HRESULT WINAPI pin_Disconnect(IPin *iface)
388 if (winetest_debug > 1) trace("Disconnect\n");
389 return E_NOTIMPL;
392 static HRESULT WINAPI pin_ConnectedTo(IPin *iface, IPin **peer)
394 if (winetest_debug > 1) trace("ConnectedTo\n");
395 return E_NOTIMPL;
398 static HRESULT WINAPI pin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *mt)
400 ok(0, "Unexpected call.\n");
401 return E_NOTIMPL;
404 static HRESULT WINAPI pin_QueryPinInfo(IPin *iface, PIN_INFO *info)
406 ok(0, "Unexpected call.\n");
407 return E_NOTIMPL;
410 static HRESULT WINAPI pin_QueryDirection(IPin *iface, PIN_DIRECTION *dir)
412 if (winetest_debug > 1) trace("QueryDirection\n");
413 *dir = PINDIR_INPUT;
414 return S_OK;
417 static HRESULT WINAPI pin_QueryId(IPin *iface, WCHAR **id)
419 ok(0, "Unexpected call.\n");
420 return E_NOTIMPL;
423 static HRESULT WINAPI pin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *mt)
425 ok(0, "Unexpected call.\n");
426 return E_NOTIMPL;
429 static HRESULT WINAPI pin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **out)
431 ok(0, "Unexpected call.\n");
432 return E_NOTIMPL;
435 static HRESULT WINAPI pin_QueryInternalConnections(IPin *iface, IPin **pins, ULONG *count)
437 ok(0, "Unexpected call.\n");
438 return E_NOTIMPL;
441 static HRESULT WINAPI pin_EndOfStream(IPin *iface)
443 ok(0, "Unexpected call.\n");
444 return E_NOTIMPL;
447 static HRESULT WINAPI pin_BeginFlush(IPin *iface)
449 ok(0, "Unexpected call.\n");
450 return E_NOTIMPL;
453 static HRESULT WINAPI pin_EndFlush(IPin *iface)
455 ok(0, "Unexpected call.\n");
456 return E_NOTIMPL;
459 static HRESULT WINAPI pin_NewSegment(IPin *iface, REFERENCE_TIME start, REFERENCE_TIME stop, double rate)
461 ok(0, "Unexpected call.\n");
462 return E_NOTIMPL;
465 static const IPinVtbl pin_vtbl =
467 pin_QueryInterface,
468 pin_AddRef,
469 pin_Release,
470 pin_Connect,
471 pin_ReceiveConnection,
472 pin_Disconnect,
473 pin_ConnectedTo,
474 pin_ConnectionMediaType,
475 pin_QueryPinInfo,
476 pin_QueryDirection,
477 pin_QueryId,
478 pin_QueryAccept,
479 pin_EnumMediaTypes,
480 pin_QueryInternalConnections,
481 pin_EndOfStream,
482 pin_BeginFlush,
483 pin_EndFlush,
484 pin_NewSegment
487 static HRESULT WINAPI stream_QueryInterface(IAMMediaStream *iface, REFIID iid, void **out)
489 struct teststream *stream = impl_from_IAMMediaStream(iface);
491 if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
493 if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IMediaStream) || IsEqualGUID(iid, &IID_IAMMediaStream))
495 IAMMediaStream_AddRef(iface);
496 *out = iface;
497 return S_OK;
499 else if (IsEqualGUID(iid, &IID_IPin))
501 IAMMediaStream_AddRef(iface);
502 *out = &stream->IPin_iface;
503 return S_OK;
506 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(iid));
507 return E_NOINTERFACE;
510 static ULONG WINAPI stream_AddRef(IAMMediaStream *iface)
512 struct teststream *stream = impl_from_IAMMediaStream(iface);
513 return InterlockedIncrement(&stream->refcount);
516 static ULONG WINAPI stream_Release(IAMMediaStream *iface)
518 struct teststream *stream = impl_from_IAMMediaStream(iface);
519 return InterlockedDecrement(&stream->refcount);
522 static HRESULT WINAPI stream_GetMultiMediaStream(IAMMediaStream *iface, IMultiMediaStream **mmstream)
524 ok(0, "Unexpected call.\n");
525 return E_NOTIMPL;
528 static HRESULT WINAPI stream_GetInformation(IAMMediaStream *iface, MSPID *id, STREAM_TYPE *type)
530 struct teststream *stream = impl_from_IAMMediaStream(iface);
531 if (winetest_debug > 1) trace("GetInformation(%p, %p)\n", id, type);
532 if (id)
533 *id = stream->mspid;
534 if (type)
535 *type = STREAMTYPE_READ;
536 return S_OK;
539 static HRESULT WINAPI stream_SetSameFormat(IAMMediaStream *iface, IMediaStream *ref, DWORD flags)
541 ok(0, "Unexpected call.\n");
542 return E_NOTIMPL;
545 static HRESULT WINAPI stream_AllocateSample(IAMMediaStream *iface, DWORD flags, IStreamSample **sample)
547 ok(0, "Unexpected call.\n");
548 return E_NOTIMPL;
551 static HRESULT WINAPI stream_CreateSharedSample(IAMMediaStream *iface,
552 IStreamSample *existing, DWORD flags, IStreamSample **out)
554 ok(0, "Unexpected call.\n");
555 return E_NOTIMPL;
558 static HRESULT WINAPI stream_SendEndOfStream(IAMMediaStream *iface, DWORD flags)
560 ok(0, "Unexpected call.\n");
561 return E_NOTIMPL;
564 static HRESULT WINAPI stream_Initialize(IAMMediaStream *iface, IUnknown *source,
565 DWORD flags, REFMSPID id, const STREAM_TYPE type)
567 ok(0, "Unexpected call.\n");
568 return E_NOTIMPL;
571 static HRESULT WINAPI stream_SetState(IAMMediaStream *iface, FILTER_STATE state)
573 struct teststream *stream = impl_from_IAMMediaStream(iface);
574 if (winetest_debug > 1) trace("SetState(%#x)\n", state);
575 if (SUCCEEDED(stream->set_state_result))
576 stream->state = state;
577 return stream->set_state_result;
580 static HRESULT WINAPI stream_JoinAMMultiMediaStream(IAMMediaStream *iface, IAMMultiMediaStream *mmstream)
582 struct teststream *stream = impl_from_IAMMediaStream(iface);
583 if (winetest_debug > 1) trace("JoinAMMultiMediaStream(%p)\n", mmstream);
584 stream->mmstream = mmstream;
585 return S_OK;
588 static HRESULT WINAPI stream_JoinFilter(IAMMediaStream *iface, IMediaStreamFilter *filter)
590 struct teststream *stream = impl_from_IAMMediaStream(iface);
591 if (winetest_debug > 1) trace("JoinFilter(%p)\n", filter);
592 stream->filter = filter;
593 return S_OK;
596 static HRESULT WINAPI stream_JoinFilterGraph(IAMMediaStream *iface, IFilterGraph *graph)
598 struct teststream *stream = impl_from_IAMMediaStream(iface);
599 if (winetest_debug > 1) trace("JoinFilterGraph(%p)\n", graph);
600 stream->graph = graph;
601 return S_OK;
604 static const IAMMediaStreamVtbl stream_vtbl =
606 stream_QueryInterface,
607 stream_AddRef,
608 stream_Release,
609 stream_GetMultiMediaStream,
610 stream_GetInformation,
611 stream_SetSameFormat,
612 stream_AllocateSample,
613 stream_CreateSharedSample,
614 stream_SendEndOfStream,
615 stream_Initialize,
616 stream_SetState,
617 stream_JoinAMMultiMediaStream,
618 stream_JoinFilter,
619 stream_JoinFilterGraph,
622 static void teststream_init(struct teststream *stream)
624 memset(stream, 0, sizeof(*stream));
625 stream->IAMMediaStream_iface.lpVtbl = &stream_vtbl;
626 stream->IPin_iface.lpVtbl = &pin_vtbl;
627 stream->refcount = 1;
628 stream->mspid = test_mspid;
629 stream->set_state_result = S_OK;
632 #define check_enum_stream(a,b,c,d) check_enum_stream_(__LINE__,a,b,c,d)
633 static void check_enum_stream_(int line, IAMMultiMediaStream *mmstream,
634 IMediaStreamFilter *filter, LONG index, IMediaStream *expect)
636 IMediaStream *stream = NULL, *stream2 = NULL;
637 HRESULT hr;
639 hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, index, &stream);
640 ok_(__FILE__, line)(hr == (expect ? S_OK : S_FALSE),
641 "IAMMultiMediaStream::EnumMediaStreams() returned %#x.\n", hr);
642 hr = IMediaStreamFilter_EnumMediaStreams(filter, index, &stream2);
643 ok_(__FILE__, line)(hr == (expect ? S_OK : S_FALSE),
644 "IMediaStreamFilter::EnumMediaStreams() returned %#x.\n", hr);
645 if (hr == S_OK)
647 ok_(__FILE__, line)(stream == expect, "Expected stream %p, got %p.\n", expect, stream);
648 ok_(__FILE__, line)(stream2 == expect, "Expected stream %p, got %p.\n", expect, stream2);
649 IMediaStream_Release(stream);
650 IMediaStream_Release(stream2);
654 #define check_get_stream(a,b,c,d) check_get_stream_(__LINE__,a,b,c,d)
655 static void check_get_stream_(int line, IAMMultiMediaStream *mmstream,
656 IMediaStreamFilter *filter, const GUID *mspid, IMediaStream *expect)
658 IMediaStream *stream = NULL, *stream2 = NULL;
659 HRESULT hr;
661 hr = IAMMultiMediaStream_GetMediaStream(mmstream, mspid, &stream);
662 ok_(__FILE__, line)(hr == (expect ? S_OK : MS_E_NOSTREAM),
663 "IAMMultiMediaStream::GetMediaStream() returned %#x.\n", hr);
664 hr = IMediaStreamFilter_GetMediaStream(filter, mspid, &stream2);
665 ok_(__FILE__, line)(hr == (expect ? S_OK : MS_E_NOSTREAM),
666 "IMediaStreamFilter::GetMediaStream() returned %#x.\n", hr);
667 if (hr == S_OK)
669 ok_(__FILE__, line)(stream == expect, "Expected stream %p, got %p.\n", expect, stream);
670 ok_(__FILE__, line)(stream2 == expect, "Expected stream %p, got %p.\n", expect, stream2);
673 if (stream) IMediaStream_Release(stream);
674 if (stream2) IMediaStream_Release(stream2);
677 static void test_add_stream(void)
679 IAMMultiMediaStream *mmstream = create_ammultimediastream();
680 IMediaStream *video_stream, *audio_stream, *stream;
681 IDirectDrawMediaStream *ddraw_stream;
682 IMediaStreamFilter *stream_filter;
683 struct teststream teststream;
684 IDirectDraw *ddraw, *ddraw2;
685 IEnumFilters *enum_filters;
686 IBaseFilter *filters[3];
687 IGraphBuilder *graph;
688 ULONG ref, count;
689 CLSID clsid;
690 HRESULT hr;
692 teststream_init(&teststream);
694 hr = IAMMultiMediaStream_GetFilter(mmstream, &stream_filter);
695 ok(hr == S_OK, "Got hr %#x.\n", hr);
697 hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, 0, NULL);
698 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
699 hr = IMediaStreamFilter_EnumMediaStreams(stream_filter, 0, NULL);
700 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
702 hr = IAMMultiMediaStream_GetMediaStream(mmstream, &MSPID_PrimaryAudio, NULL);
703 todo_wine ok(hr == E_POINTER, "Got hr %#x.\n", hr);
704 hr = IMediaStreamFilter_GetMediaStream(stream_filter, &MSPID_PrimaryAudio, NULL);
705 todo_wine ok(hr == E_POINTER, "Got hr %#x.\n", hr);
707 check_enum_stream(mmstream, stream_filter, 0, NULL);
709 check_get_stream(mmstream, stream_filter, NULL, NULL);
710 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, NULL);
711 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, NULL);
712 check_get_stream(mmstream, stream_filter, &test_mspid, NULL);
714 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &test_mspid, 0, &stream);
715 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
717 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &video_stream);
718 ok(hr == S_OK, "Got hr %#x.\n", hr);
720 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
721 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
723 hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, 0, NULL);
724 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
725 hr = IMediaStreamFilter_EnumMediaStreams(stream_filter, 0, NULL);
726 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
727 hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, 1, NULL);
728 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
729 hr = IMediaStreamFilter_EnumMediaStreams(stream_filter, 1, NULL);
730 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
732 check_enum_stream(mmstream, stream_filter, 0, video_stream);
733 check_enum_stream(mmstream, stream_filter, 1, NULL);
735 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, video_stream);
736 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, NULL);
737 check_get_stream(mmstream, stream_filter, &test_mspid, NULL);
739 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &audio_stream);
740 ok(hr == S_OK, "Got hr %#x.\n", hr);
742 check_enum_stream(mmstream, stream_filter, 0, video_stream);
743 check_enum_stream(mmstream, stream_filter, 1, audio_stream);
744 check_enum_stream(mmstream, stream_filter, 2, NULL);
746 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, video_stream);
747 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, audio_stream);
748 check_get_stream(mmstream, stream_filter, &test_mspid, NULL);
750 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &IID_IUnknown, 0, &stream);
751 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
753 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &test_mspid, 0, &stream);
754 ok(hr == S_OK, "Got hr %#x.\n", hr);
755 ok(stream == (IMediaStream *)&teststream, "Streams didn't match.\n");
756 if (hr == S_OK) IMediaStream_Release(stream);
757 ok(teststream.mmstream == mmstream, "IAMMultiMediaStream objects didn't match.\n");
758 ok(teststream.filter == stream_filter, "IMediaStreamFilter objects didn't match.\n");
759 todo_wine ok(!!teststream.graph, "Expected a non-NULL graph.\n");
761 check_enum_stream(mmstream, stream_filter, 0, video_stream);
762 check_enum_stream(mmstream, stream_filter, 1, audio_stream);
763 check_enum_stream(mmstream, stream_filter, 2, (IMediaStream *)&teststream);
764 check_enum_stream(mmstream, stream_filter, 3, NULL);
766 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, video_stream);
767 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, audio_stream);
768 check_get_stream(mmstream, stream_filter, &test_mspid, (IMediaStream *)&teststream);
770 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
771 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
773 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
774 ok(hr == S_OK, "Got hr %#x.\n", hr);
775 ok(!!graph, "Expected a non-NULL graph.\n");
777 hr = IGraphBuilder_EnumFilters(graph, &enum_filters);
778 ok(hr == S_OK, "Got hr %#x.\n", hr);
779 hr = IEnumFilters_Next(enum_filters, 3, filters, &count);
780 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
781 ok(count == 1, "Got count %u.\n", count);
782 ok(filters[0] == (IBaseFilter *)stream_filter,
783 "Expected filter %p, got %p.\n", stream_filter, filters[0]);
784 IBaseFilter_Release(filters[0]);
785 IEnumFilters_Release(enum_filters);
786 IGraphBuilder_Release(graph);
788 IMediaStreamFilter_Release(stream_filter);
789 ref = IAMMultiMediaStream_Release(mmstream);
790 ok(!ref, "Got outstanding refcount %d.\n", ref);
791 ref = IMediaStream_Release(video_stream);
792 ok(!ref, "Got outstanding refcount %d.\n", ref);
793 ref = IMediaStream_Release(audio_stream);
794 ok(!ref, "Got outstanding refcount %d.\n", ref);
795 ok(teststream.refcount == 1, "Got outstanding refcount %d.\n", teststream.refcount);
797 /* The return parameter is optional. */
799 mmstream = create_ammultimediastream();
801 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, NULL);
802 ok(hr == S_OK, "Got hr %#x.\n", hr);
804 hr = IAMMultiMediaStream_GetMediaStream(mmstream, &MSPID_PrimaryVideo, &stream);
805 ok(hr == S_OK, "Got hr %#x.\n", hr);
806 IMediaStream_Release(stream);
808 ref = IAMMultiMediaStream_Release(mmstream);
809 ok(!ref, "Got outstanding refcount %d.\n", ref);
811 /* Test supplying a DirectDraw object with the primary video stream. */
813 hr = DirectDrawCreate(NULL, &ddraw, NULL);
814 ok(hr == DD_OK, "Got hr %#x.\n", hr);
815 mmstream = create_ammultimediastream();
817 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)ddraw, &MSPID_PrimaryVideo, 0, &video_stream);
818 ok(hr == S_OK, "Got hr %#x.\n", hr);
820 hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
821 ok(hr == S_OK, "Got hr %#x.\n", hr);
822 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw2);
823 ok(hr == S_OK, "Got hr %#x.\n", hr);
824 ok(ddraw2 == ddraw, "Expected IDirectDraw %p, got %p.\n", ddraw, ddraw2);
825 IDirectDraw_Release(ddraw2);
826 IDirectDrawMediaStream_Release(ddraw_stream);
828 ref = IAMMultiMediaStream_Release(mmstream);
829 ok(!ref, "Got outstanding refcount %d.\n", ref);
830 ref = IMediaStream_Release(video_stream);
831 ok(!ref, "Got outstanding refcount %d.\n", ref);
832 ref = IDirectDraw_Release(ddraw);
833 ok(!ref, "Got outstanding refcount %d.\n", ref);
835 mmstream = create_ammultimediastream();
837 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &video_stream);
838 ok(hr == S_OK, "Got hr %#x.\n", hr);
840 hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
841 ok(hr == S_OK, "Got hr %#x.\n", hr);
842 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw);
843 ok(hr == S_OK, "Got hr %#x.\n", hr);
844 ok(!!ddraw, "Expected a non-NULL IDirectDraw.\n");
845 IDirectDraw_Release(ddraw);
846 IDirectDrawMediaStream_Release(ddraw_stream);
848 ref = IAMMultiMediaStream_Release(mmstream);
849 ok(!ref, "Got outstanding refcount %d.\n", ref);
850 ref = IMediaStream_Release(video_stream);
851 ok(!ref, "Got outstanding refcount %d.\n", ref);
853 /* Test the AMMSF_ADDDEFAULTRENDERER flag. No stream is added; however, a
854 * new filter will be added to the graph. */
856 mmstream = create_ammultimediastream();
857 hr = IAMMultiMediaStream_GetFilter(mmstream, &stream_filter);
858 ok(hr == S_OK, "Got hr %#x.\n", hr);
860 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo,
861 AMMSF_ADDDEFAULTRENDERER, &video_stream);
862 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
864 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo,
865 AMMSF_ADDDEFAULTRENDERER, NULL);
866 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
868 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio,
869 AMMSF_ADDDEFAULTRENDERER, &audio_stream);
870 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
872 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio,
873 AMMSF_ADDDEFAULTRENDERER, NULL);
874 ok(hr == S_OK || hr == VFW_E_NO_AUDIO_HARDWARE, "Got hr %#x.\n", hr);
876 check_enum_stream(mmstream, stream_filter, 0, NULL);
878 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, NULL);
879 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, NULL);
881 if (hr == S_OK)
883 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
884 ok(hr == S_OK, "Got hr %#x.\n", hr);
885 ok(!!graph, "Got graph %p.\n", graph);
886 hr = IAMMultiMediaStream_GetFilter(mmstream, &stream_filter);
887 ok(hr == S_OK, "Got hr %#x.\n", hr);
888 hr = IGraphBuilder_EnumFilters(graph, &enum_filters);
889 ok(hr == S_OK, "Got hr %#x.\n", hr);
890 hr = IEnumFilters_Next(enum_filters, 3, filters, &count);
891 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
892 ok(count == 2, "Got count %u.\n", count);
893 ok(filters[1] == (IBaseFilter *)stream_filter,
894 "Expected filter %p, got %p.\n", stream_filter, filters[1]);
895 hr = IBaseFilter_GetClassID(filters[0], &clsid);
896 ok(hr == S_OK, "Got hr %#x.\n", hr);
897 ok(IsEqualGUID(&clsid, &CLSID_DSoundRender), "Got unexpected filter %s.\n", wine_dbgstr_guid(&clsid));
898 IBaseFilter_Release(filters[0]);
899 IMediaStreamFilter_Release(stream_filter);
900 IEnumFilters_Release(enum_filters);
901 IGraphBuilder_Release(graph);
904 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &test_mspid,
905 AMMSF_ADDDEFAULTRENDERER, NULL);
906 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
907 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &test_mspid,
908 AMMSF_ADDDEFAULTRENDERER, &audio_stream);
909 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
911 IMediaStreamFilter_Release(stream_filter);
912 ref = IAMMultiMediaStream_Release(mmstream);
913 ok(!ref, "Got outstanding refcount %d.\n", ref);
916 static void test_media_streams(void)
918 IAMMultiMediaStream *pams;
919 HRESULT hr;
920 IMediaStream *video_stream = NULL;
921 IMediaStream *audio_stream = NULL;
922 IMediaStreamFilter* media_stream_filter = NULL;
924 if (!(pams = create_ammultimediastream()))
925 return;
926 if (!create_directdraw())
928 IAMMultiMediaStream_Release(pams);
929 return;
932 hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL);
933 ok(hr == S_OK, "IAMMultiMediaStream_Initialize returned: %x\n", hr);
935 /* Retrieve media stream filter */
936 hr = IAMMultiMediaStream_GetFilter(pams, NULL);
937 ok(hr == E_POINTER, "IAMMultiMediaStream_GetFilter returned: %x\n", hr);
938 hr = IAMMultiMediaStream_GetFilter(pams, &media_stream_filter);
939 ok(hr == S_OK, "IAMMultiMediaStream_GetFilter returned: %x\n", hr);
941 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryVideo, 0, NULL);
942 ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
943 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
944 ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
946 /* Check interfaces and samples for video */
947 if (video_stream)
949 IAMMediaStream* am_media_stream;
950 IMultiMediaStream *multi_media_stream;
951 IPin *pin = NULL;
952 IAudioMediaStream* audio_media_stream;
953 IDirectDrawMediaStream *ddraw_stream = NULL;
954 IDirectDrawStreamSample *ddraw_sample = NULL;
956 hr = IMediaStream_QueryInterface(video_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
957 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
958 ok((void*)am_media_stream == (void*)video_stream, "Not same interface, got %p expected %p\n", am_media_stream, video_stream);
960 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, NULL);
961 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
963 multi_media_stream = (void *)0xdeadbeef;
964 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, &multi_media_stream);
965 ok(hr == S_OK, "IAMMediaStream_GetMultiMediaStream returned: %x\n", hr);
966 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
967 IMultiMediaStream_Release(multi_media_stream);
969 IAMMediaStream_Release(am_media_stream);
971 hr = IMediaStream_QueryInterface(video_stream, &IID_IPin, (void **)&pin);
972 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
974 IPin_Release(pin);
976 hr = IMediaStream_QueryInterface(video_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
977 ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %x\n", hr);
979 hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
980 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
982 if (SUCCEEDED(hr))
984 DDSURFACEDESC current_format, desired_format;
985 IDirectDrawPalette *palette;
986 DWORD flags;
988 hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, &palette, &desired_format, &flags);
989 ok(hr == MS_E_NOSTREAM, "IDirectDrawoMediaStream_GetFormat returned: %x\n", hr);
991 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample);
992 ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr);
994 hr = IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream, NULL);
995 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
997 multi_media_stream = (void *)0xdeadbeef;
998 hr = IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream, &multi_media_stream);
999 ok(hr == S_OK, "IDirectDrawMediaStream_GetMultiMediaStream returned: %x\n", hr);
1000 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1001 IMultiMediaStream_Release(multi_media_stream);
1004 if (ddraw_sample)
1005 IDirectDrawStreamSample_Release(ddraw_sample);
1006 if (ddraw_stream)
1007 IDirectDrawMediaStream_Release(ddraw_stream);
1010 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, 0, NULL);
1011 ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
1012 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
1013 ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
1015 /* Check interfaces and samples for audio */
1016 if (audio_stream)
1018 IAMMediaStream* am_media_stream;
1019 IMultiMediaStream *multi_media_stream;
1020 IPin *pin = NULL;
1021 IDirectDrawMediaStream* ddraw_stream = NULL;
1022 IAudioMediaStream* audio_media_stream = NULL;
1023 IAudioStreamSample *audio_sample = NULL;
1025 hr = IMediaStream_QueryInterface(audio_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
1026 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
1027 ok((void*)am_media_stream == (void*)audio_stream, "Not same interface, got %p expected %p\n", am_media_stream, audio_stream);
1029 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, NULL);
1030 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
1032 multi_media_stream = (void *)0xdeadbeef;
1033 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, &multi_media_stream);
1034 ok(hr == S_OK, "IAMMediaStream_GetMultiMediaStream returned: %x\n", hr);
1035 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1036 IMultiMediaStream_Release(multi_media_stream);
1038 IAMMediaStream_Release(am_media_stream);
1040 hr = IMediaStream_QueryInterface(audio_stream, &IID_IPin, (void **)&pin);
1041 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
1043 IPin_Release(pin);
1045 hr = IMediaStream_QueryInterface(audio_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
1046 ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %x\n", hr);
1048 hr = IMediaStream_QueryInterface(audio_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
1049 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
1051 if (SUCCEEDED(hr))
1053 IAudioData* audio_data = NULL;
1055 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
1056 ok(hr == S_OK, "CoCreateInstance returned: %x\n", hr);
1058 hr = IAudioMediaStream_CreateSample(audio_media_stream, NULL, 0, &audio_sample);
1059 ok(hr == E_POINTER, "IAudioMediaStream_CreateSample returned: %x\n", hr);
1060 hr = IAudioMediaStream_CreateSample(audio_media_stream, audio_data, 0, &audio_sample);
1061 ok(hr == S_OK, "IAudioMediaStream_CreateSample returned: %x\n", hr);
1063 hr = IAudioMediaStream_GetMultiMediaStream(audio_media_stream, NULL);
1064 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
1066 multi_media_stream = (void *)0xdeadbeef;
1067 hr = IAudioMediaStream_GetMultiMediaStream(audio_media_stream, &multi_media_stream);
1068 ok(hr == S_OK, "IAudioMediaStream_GetMultiMediaStream returned: %x\n", hr);
1069 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1070 IMultiMediaStream_Release(multi_media_stream);
1072 if (audio_data)
1073 IAudioData_Release(audio_data);
1074 if (audio_sample)
1075 IAudioStreamSample_Release(audio_sample);
1076 if (audio_media_stream)
1077 IAudioMediaStream_Release(audio_media_stream);
1081 if (media_stream_filter)
1083 IEnumPins *enum_pins;
1085 hr = IMediaStreamFilter_EnumPins(media_stream_filter, &enum_pins);
1086 ok(hr == S_OK, "IBaseFilter_EnumPins returned: %x\n", hr);
1087 if (hr == S_OK)
1089 IPin* pins[3] = { NULL, NULL, NULL };
1090 ULONG nb_pins;
1091 ULONG expected_nb_pins = audio_stream ? 2 : 1;
1092 int i;
1094 hr = IEnumPins_Next(enum_pins, 3, pins, &nb_pins);
1095 ok(SUCCEEDED(hr), "IEnumPins_Next returned: %x\n", hr);
1096 ok(nb_pins == expected_nb_pins, "Number of pins is %u instead of %u\n", nb_pins, expected_nb_pins);
1097 for (i = 0; i < min(nb_pins, expected_nb_pins); i++)
1099 IPin* pin;
1101 hr = IPin_ConnectedTo(pins[i], &pin);
1102 ok(hr == VFW_E_NOT_CONNECTED, "IPin_ConnectedTo returned: %x\n", hr);
1103 IPin_Release(pins[i]);
1105 IEnumPins_Release(enum_pins);
1109 /* Test open file with no filename */
1110 hr = IAMMultiMediaStream_OpenFile(pams, NULL, 0);
1111 ok(hr == E_POINTER, "IAMMultiMediaStream_OpenFile returned %x instead of %x\n", hr, E_POINTER);
1113 if (video_stream)
1114 IMediaStream_Release(video_stream);
1115 if (audio_stream)
1116 IMediaStream_Release(audio_stream);
1117 if (media_stream_filter)
1118 IMediaStreamFilter_Release(media_stream_filter);
1120 release_directdraw();
1121 IAMMultiMediaStream_Release(pams);
1124 static void test_enum_pins(void)
1126 IAMMultiMediaStream *mmstream = create_ammultimediastream();
1127 IMediaStreamFilter *filter;
1128 IEnumPins *enum1, *enum2;
1129 IMediaStream *stream;
1130 IPin *pins[3], *pin;
1131 ULONG ref, count;
1132 HRESULT hr;
1134 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
1135 ok(hr == S_OK, "Got hr %#x.\n", hr);
1137 ref = get_refcount(filter);
1138 todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref);
1140 hr = IMediaStreamFilter_EnumPins(filter, NULL);
1141 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1143 hr = IMediaStreamFilter_EnumPins(filter, &enum1);
1144 ok(hr == S_OK, "Got hr %#x.\n", hr);
1145 ref = get_refcount(filter);
1146 todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref);
1147 ref = get_refcount(enum1);
1148 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
1150 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
1151 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1153 hr = IEnumPins_Next(enum1, 1, pins, NULL);
1154 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1156 hr = IEnumPins_Reset(enum1);
1157 ok(hr == S_OK, "Got hr %#x.\n", hr);
1159 hr = IEnumPins_Skip(enum1, 0);
1160 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1162 hr = IEnumPins_Skip(enum1, 1);
1163 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1165 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1166 ok(hr == S_OK, "Got hr %#x.\n", hr);
1167 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1168 ok(hr == S_OK, "Got hr %#x.\n", hr);
1170 /* Reset() isn't enough; we have to call EnumPins() again to see the updated
1171 * pin count. */
1172 hr = IEnumPins_Reset(enum1);
1173 ok(hr == S_OK, "Got hr %#x.\n", hr);
1175 hr = IEnumPins_Next(enum1, 1, pins, NULL);
1176 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1178 IEnumPins_Release(enum1);
1180 hr = IMediaStreamFilter_EnumPins(filter, &enum1);
1181 ok(hr == S_OK, "Got hr %#x.\n", hr);
1183 ref = get_refcount(filter);
1184 todo_wine ok(ref == 4, "Got unexpected refcount %d.\n", ref);
1185 ref = get_refcount(enum1);
1186 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
1187 ref = get_refcount(pin);
1188 ok(ref == 4, "Got unexpected refcount %d.\n", ref);
1190 hr = IEnumPins_Next(enum1, 1, pins, NULL);
1191 ok(hr == S_OK, "Got hr %#x.\n", hr);
1192 ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
1193 ref = get_refcount(filter);
1194 todo_wine ok(ref == 4, "Got unexpected refcount %d.\n", ref);
1195 ref = get_refcount(enum1);
1196 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
1197 ref = get_refcount(pin);
1198 ok(ref == 5, "Got unexpected refcount %d.\n", ref);
1199 IPin_Release(pins[0]);
1201 hr = IEnumPins_Next(enum1, 1, pins, NULL);
1202 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1204 hr = IEnumPins_Reset(enum1);
1205 ok(hr == S_OK, "Got hr %#x.\n", hr);
1207 hr = IEnumPins_Next(enum1, 1, pins, &count);
1208 ok(hr == S_OK, "Got hr %#x.\n", hr);
1209 ok(count == 1, "Got count %u.\n", count);
1210 ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
1211 IPin_Release(pins[0]);
1213 hr = IEnumPins_Reset(enum1);
1214 ok(hr == S_OK, "Got hr %#x.\n", hr);
1216 hr = IEnumPins_Next(enum1, 2, pins, NULL);
1217 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1219 hr = IEnumPins_Next(enum1, 2, pins, &count);
1220 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1221 ok(count == 1, "Got count %u.\n", count);
1222 ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
1223 IPin_Release(pins[0]);
1225 hr = IEnumPins_Reset(enum1);
1226 ok(hr == S_OK, "Got hr %#x.\n", hr);
1228 hr = IEnumPins_Clone(enum1, &enum2);
1229 ok(hr == S_OK, "Got hr %#x.\n", hr);
1231 hr = IEnumPins_Skip(enum1, 0);
1232 ok(hr == S_OK, "Got hr %#x.\n", hr);
1234 hr = IEnumPins_Skip(enum1, 1);
1235 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1237 hr = IEnumPins_Next(enum1, 1, pins, NULL);
1238 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1240 hr = IEnumPins_Next(enum2, 1, pins, NULL);
1241 ok(hr == S_OK, "Got hr %#x.\n", hr);
1242 ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
1243 IPin_Release(pins[0]);
1245 IEnumPins_Release(enum2);
1246 IEnumPins_Release(enum1);
1248 IMediaStreamFilter_Release(filter);
1249 ref = IAMMultiMediaStream_Release(mmstream);
1250 ok(!ref, "Got outstanding refcount %d.\n", ref);
1251 IMediaStream_Release(stream);
1252 ref = IPin_Release(pin);
1253 ok(!ref, "Got outstanding refcount %d.\n", ref);
1256 static void test_find_pin(void)
1258 IAMMultiMediaStream *mmstream = create_ammultimediastream();
1259 IMediaStreamFilter *filter;
1260 IMediaStream *stream;
1261 IPin *pin, *pin2;
1262 HRESULT hr;
1263 ULONG ref;
1265 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
1266 ok(hr == S_OK, "Got hr %#x.\n", hr);
1268 hr = IMediaStreamFilter_FindPin(filter, primary_video_sink_id, &pin2);
1269 ok(hr == VFW_E_NOT_FOUND, "Got hr %#x.\n", hr);
1271 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1272 ok(hr == S_OK, "Got hr %#x.\n", hr);
1273 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1274 ok(hr == S_OK, "Got hr %#x.\n", hr);
1276 hr = IMediaStreamFilter_FindPin(filter, primary_video_sink_id, &pin2);
1277 ok(hr == S_OK, "Got hr %#x.\n", hr);
1278 ok(pin2 == pin, "Expected pin %p, got %p.\n", pin, pin2);
1280 IPin_Release(pin2);
1281 IPin_Release(pin);
1282 IMediaStreamFilter_Release(filter);
1283 ref = IAMMultiMediaStream_Release(mmstream);
1284 ok(!ref, "Got outstanding refcount %d.\n", ref);
1287 static void test_pin_info(void)
1289 IAMMultiMediaStream *mmstream = create_ammultimediastream();
1290 IMediaStreamFilter *filter;
1291 IMediaStream *stream;
1292 PIN_DIRECTION dir;
1293 ULONG ref, count;
1294 PIN_INFO info;
1295 HRESULT hr;
1296 WCHAR *id;
1297 IPin *pin;
1299 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
1300 ok(hr == S_OK, "Got hr %#x.\n", hr);
1302 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1303 ok(hr == S_OK, "Got hr %#x.\n", hr);
1304 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1305 ok(hr == S_OK, "Got hr %#x.\n", hr);
1307 hr = IPin_QueryPinInfo(pin, &info);
1308 ok(hr == S_OK, "Got hr %#x.\n", hr);
1309 ok(info.pFilter == (IBaseFilter *)filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
1310 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
1311 ok(!wcscmp(info.achName, primary_video_sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
1312 IBaseFilter_Release(info.pFilter);
1314 hr = IPin_QueryDirection(pin, &dir);
1315 ok(hr == S_OK, "Got hr %#x.\n", hr);
1316 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
1318 hr = IPin_QueryId(pin, &id);
1319 ok(hr == S_OK, "Got hr %#x.\n", hr);
1320 ok(!wcscmp(id, primary_video_sink_id), "Got id %s.\n", wine_dbgstr_w(id));
1321 CoTaskMemFree(id);
1323 hr = IPin_QueryInternalConnections(pin, NULL, &count);
1324 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
1326 IPin_Release(pin);
1327 IMediaStream_Release(stream);
1329 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
1330 ok(hr == S_OK, "Got hr %#x.\n", hr);
1331 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1332 ok(hr == S_OK, "Got hr %#x.\n", hr);
1334 hr = IPin_QueryPinInfo(pin, &info);
1335 ok(hr == S_OK, "Got hr %#x.\n", hr);
1336 ok(info.pFilter == (IBaseFilter *)filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
1337 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
1338 ok(!wcscmp(info.achName, primary_audio_sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
1339 IBaseFilter_Release(info.pFilter);
1341 hr = IPin_QueryDirection(pin, &dir);
1342 ok(hr == S_OK, "Got hr %#x.\n", hr);
1343 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
1345 hr = IPin_QueryId(pin, &id);
1346 ok(hr == S_OK, "Got hr %#x.\n", hr);
1347 ok(!wcscmp(id, primary_audio_sink_id), "Got id %s.\n", wine_dbgstr_w(id));
1348 CoTaskMemFree(id);
1350 hr = IPin_QueryInternalConnections(pin, NULL, &count);
1351 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
1353 IPin_Release(pin);
1354 IMediaStream_Release(stream);
1356 IMediaStreamFilter_Release(filter);
1357 ref = IAMMultiMediaStream_Release(mmstream);
1358 ok(!ref, "Got outstanding refcount %d.\n", ref);
1361 static IUnknown *graph_inner_unk;
1362 static IFilterGraph2 *graph_inner;
1363 static LONG graph_refcount = 1;
1364 static unsigned int got_add_filter;
1365 static IBaseFilter *graph_filter;
1366 static WCHAR graph_filter_name[128];
1368 static HRESULT WINAPI graph_QueryInterface(IFilterGraph2 *iface, REFIID iid, void **out)
1370 if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
1371 if (IsEqualGUID(iid, &IID_IFilterGraph2)
1372 || IsEqualGUID(iid, &IID_IGraphBuilder)
1373 || IsEqualGUID(iid, &IID_IFilterGraph)
1374 || IsEqualGUID(iid, &IID_IUnknown))
1376 *out = iface;
1377 IFilterGraph2_AddRef(iface);
1378 return S_OK;
1380 else if (IsEqualGUID(iid, &IID_IMediaSeeking)
1381 || IsEqualGUID(iid, &IID_IMediaControl)
1382 || IsEqualGUID(iid, &IID_IMediaEventEx))
1384 return IUnknown_QueryInterface(graph_inner_unk, iid, out);
1386 return E_NOINTERFACE;
1389 static ULONG WINAPI graph_AddRef(IFilterGraph2 *iface)
1391 return InterlockedIncrement(&graph_refcount);
1394 static ULONG WINAPI graph_Release(IFilterGraph2 *iface)
1396 return InterlockedDecrement(&graph_refcount);
1399 static HRESULT WINAPI graph_AddFilter(IFilterGraph2 *iface, IBaseFilter *filter, const WCHAR *name)
1401 if (winetest_debug > 1) trace("AddFilter(%p, %s)\n", filter, wine_dbgstr_w(name));
1402 ++got_add_filter;
1403 graph_filter = filter;
1404 if (name)
1405 wcscpy(graph_filter_name, name);
1406 else
1407 graph_filter_name[0] = 0;
1408 return IFilterGraph2_AddFilter(graph_inner, filter, name);
1411 static HRESULT WINAPI graph_RemoveFilter(IFilterGraph2 *iface, IBaseFilter *filter)
1413 ok(0, "Unexpected call.\n");
1414 return E_NOTIMPL;
1417 static HRESULT WINAPI graph_EnumFilters(IFilterGraph2 *iface, IEnumFilters **enumfilters)
1419 if (winetest_debug > 1) trace("EnumFilters()\n");
1420 return IFilterGraph2_EnumFilters(graph_inner, enumfilters);
1423 static HRESULT WINAPI graph_FindFilterByName(IFilterGraph2 *iface, const WCHAR *name, IBaseFilter **filter)
1425 ok(0, "Unexpected call.\n");
1426 return E_NOTIMPL;
1429 static HRESULT WINAPI graph_ConnectDirect(IFilterGraph2 *iface, IPin *source, IPin *sink, const AM_MEDIA_TYPE *mt)
1431 ok(0, "Unexpected call.\n");
1432 return E_NOTIMPL;
1435 static HRESULT WINAPI graph_Reconnect(IFilterGraph2 *iface, IPin *pin)
1437 ok(0, "Unexpected call.\n");
1438 return E_NOTIMPL;
1441 static HRESULT WINAPI graph_Disconnect(IFilterGraph2 *iface, IPin *pin)
1443 ok(0, "Unexpected call.\n");
1444 return E_NOTIMPL;
1447 static HRESULT WINAPI graph_SetDefaultSyncSource(IFilterGraph2 *iface)
1449 ok(0, "Unexpected call.\n");
1450 return E_NOTIMPL;
1453 static HRESULT WINAPI graph_Connect(IFilterGraph2 *iface, IPin *source, IPin *sink)
1455 ok(0, "Unexpected call.\n");
1456 return E_NOTIMPL;
1459 static HRESULT WINAPI graph_Render(IFilterGraph2 *iface, IPin *source)
1461 ok(0, "Unexpected call.\n");
1462 return E_NOTIMPL;
1465 static HRESULT WINAPI graph_RenderFile(IFilterGraph2 *iface, const WCHAR *filename, const WCHAR *playlist)
1467 ok(0, "Unexpected call.\n");
1468 return E_NOTIMPL;
1471 static HRESULT WINAPI graph_AddSourceFilter(IFilterGraph2 *iface,
1472 const WCHAR *filename, const WCHAR *filter_name, IBaseFilter **filter)
1474 ok(0, "Unexpected call.\n");
1475 return E_NOTIMPL;
1478 static HRESULT WINAPI graph_SetLogFile(IFilterGraph2 *iface, DWORD_PTR file)
1480 ok(0, "Unexpected call.\n");
1481 return E_NOTIMPL;
1484 static HRESULT WINAPI graph_Abort(IFilterGraph2 *iface)
1486 ok(0, "Unexpected call.\n");
1487 return E_NOTIMPL;
1490 static HRESULT WINAPI graph_ShouldOperationContinue(IFilterGraph2 *iface)
1492 ok(0, "Unexpected call.\n");
1493 return E_NOTIMPL;
1496 static HRESULT WINAPI graph_AddSourceFilterForMoniker(IFilterGraph2 *iface,
1497 IMoniker *moniker, IBindCtx *bind_ctx, const WCHAR *filter_name, IBaseFilter **filter)
1499 ok(0, "Unexpected call.\n");
1500 return E_NOTIMPL;
1503 static HRESULT WINAPI graph_ReconnectEx(IFilterGraph2 *iface, IPin *pin, const AM_MEDIA_TYPE *mt)
1505 ok(0, "Unexpected call.\n");
1506 return E_NOTIMPL;
1509 static HRESULT WINAPI graph_RenderEx(IFilterGraph2 *iface, IPin *pin, DWORD flags, DWORD *context)
1511 ok(0, "Unexpected call.\n");
1512 return E_NOTIMPL;
1515 static const IFilterGraph2Vtbl graph_vtbl =
1517 graph_QueryInterface,
1518 graph_AddRef,
1519 graph_Release,
1520 graph_AddFilter,
1521 graph_RemoveFilter,
1522 graph_EnumFilters,
1523 graph_FindFilterByName,
1524 graph_ConnectDirect,
1525 graph_Reconnect,
1526 graph_Disconnect,
1527 graph_SetDefaultSyncSource,
1528 graph_Connect,
1529 graph_Render,
1530 graph_RenderFile,
1531 graph_AddSourceFilter,
1532 graph_SetLogFile,
1533 graph_Abort,
1534 graph_ShouldOperationContinue,
1535 graph_AddSourceFilterForMoniker,
1536 graph_ReconnectEx,
1537 graph_RenderEx,
1540 static void test_initialize(void)
1542 IAMMultiMediaStream *mmstream = create_ammultimediastream();
1543 IFilterGraph2 graph = {&graph_vtbl};
1544 IMediaStreamFilter *filter;
1545 IGraphBuilder *ret_graph;
1546 IMediaStream *stream;
1547 STREAM_TYPE type;
1548 HRESULT hr;
1549 ULONG ref;
1551 ret_graph = (IGraphBuilder *)0xdeadbeef;
1552 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
1553 ok(hr == S_OK, "Got hr %#x.\n", hr);
1554 ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
1556 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
1557 ok(hr == S_OK, "Got hr %#x.\n", hr);
1558 ok(!!filter, "Expected a non-NULL filter.");
1559 IMediaStreamFilter_Release(filter);
1561 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
1562 ok(hr == S_OK, "Got hr %#x.\n", hr);
1564 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
1565 ok(hr == S_OK, "Got hr %#x.\n", hr);
1566 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
1567 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1568 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
1569 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1571 ret_graph = (IGraphBuilder *)0xdeadbeef;
1572 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
1573 ok(hr == S_OK, "Got hr %#x.\n", hr);
1574 ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
1576 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1577 ok(hr == S_OK, "Got hr %#x.\n", hr);
1578 type = 0xdeadbeef;
1579 hr = IMediaStream_GetInformation(stream, NULL, &type);
1580 ok(hr == S_OK, "Got hr %#x.\n", hr);
1581 ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
1582 IMediaStream_Release(stream);
1584 ret_graph = NULL;
1585 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
1586 ok(hr == S_OK, "Got hr %#x.\n", hr);
1587 ok(!!ret_graph, "Got unexpected graph %p.\n", ret_graph);
1588 IGraphBuilder_Release(ret_graph);
1590 ref = IAMMultiMediaStream_Release(mmstream);
1591 ok(!ref, "Got outstanding refcount %d.\n", ref);
1593 mmstream = create_ammultimediastream();
1595 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
1596 ok(hr == S_OK, "Got hr %#x.\n", hr);
1598 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
1599 ok(hr == S_OK, "Got hr %#x.\n", hr);
1600 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
1601 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1602 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
1603 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1605 ret_graph = (IGraphBuilder *)0xdeadbeef;
1606 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
1607 ok(hr == S_OK, "Got hr %#x.\n", hr);
1608 ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
1610 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1611 ok(hr == S_OK, "Got hr %#x.\n", hr);
1612 type = 0xdeadbeef;
1613 hr = IMediaStream_GetInformation(stream, NULL, &type);
1614 ok(hr == S_OK, "Got hr %#x.\n", hr);
1615 ok(type == STREAMTYPE_WRITE, "Got type %u.\n", type);
1616 IMediaStream_Release(stream);
1618 ref = IAMMultiMediaStream_Release(mmstream);
1619 ok(!ref, "Got outstanding refcount %d.\n", ref);
1621 mmstream = create_ammultimediastream();
1623 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
1624 ok(hr == S_OK, "Got hr %#x.\n", hr);
1626 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
1627 ok(hr == S_OK, "Got hr %#x.\n", hr);
1628 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
1629 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1630 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
1631 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1633 ret_graph = (IGraphBuilder *)0xdeadbeef;
1634 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
1635 ok(hr == S_OK, "Got hr %#x.\n", hr);
1636 ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
1638 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1639 ok(hr == S_OK, "Got hr %#x.\n", hr);
1640 type = 0xdeadbeef;
1641 hr = IMediaStream_GetInformation(stream, NULL, &type);
1642 ok(hr == S_OK, "Got hr %#x.\n", hr);
1643 ok(type == STREAMTYPE_TRANSFORM, "Got type %u.\n", type);
1644 IMediaStream_Release(stream);
1646 ref = IAMMultiMediaStream_Release(mmstream);
1647 ok(!ref, "Got outstanding refcount %d.\n", ref);
1649 mmstream = create_ammultimediastream();
1651 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1652 ok(hr == S_OK, "Got hr %#x.\n", hr);
1654 type = 0xdeadbeef;
1655 hr = IMediaStream_GetInformation(stream, NULL, &type);
1656 ok(hr == S_OK, "Got hr %#x.\n", hr);
1657 ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
1659 ret_graph = NULL;
1660 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
1661 ok(hr == S_OK, "Got hr %#x.\n", hr);
1662 ok(!!ret_graph, "Got unexpected graph %p.\n", ret_graph);
1663 IGraphBuilder_Release(ret_graph);
1665 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
1666 ok(hr == S_OK, "Got hr %#x.\n", hr);
1668 type = 0xdeadbeef;
1669 hr = IMediaStream_GetInformation(stream, NULL, &type);
1670 ok(hr == S_OK, "Got hr %#x.\n", hr);
1671 ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
1673 IMediaStream_Release(stream);
1674 ref = IAMMultiMediaStream_Release(mmstream);
1675 ok(!ref, "Got outstanding refcount %d.\n", ref);
1677 /* Test with a custom filter graph. */
1679 mmstream = create_ammultimediastream();
1681 CoCreateInstance(&CLSID_FilterGraph, (IUnknown *)&graph, CLSCTX_INPROC_SERVER,
1682 &IID_IUnknown, (void **)&graph_inner_unk);
1683 IUnknown_QueryInterface(graph_inner_unk, &IID_IFilterGraph2, (void **)&graph_inner);
1685 ret_graph = (IGraphBuilder *)0xdeadbeef;
1686 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
1687 ok(hr == S_OK, "Got hr %#x.\n", hr);
1688 ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
1690 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
1691 ok(hr == S_OK, "Got hr %#x.\n", hr);
1692 ok(!!filter, "Expected a non-NULL filter.");
1694 got_add_filter = 0;
1695 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, (IGraphBuilder *)&graph);
1696 ok(hr == S_OK, "Got hr %#x.\n", hr);
1697 ok(got_add_filter == 1, "Got %d calls to IGraphBuilder::AddFilter().\n", got_add_filter);
1698 ok(graph_filter == (IBaseFilter *)filter, "Got filter %p.\n", filter);
1699 ok(!wcscmp(graph_filter_name, L"MediaStreamFilter"), "Got unexpected name %s.\n", wine_dbgstr_w(graph_filter_name));
1701 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
1702 ok(hr == S_OK, "Got hr %#x.\n", hr);
1703 ok(ret_graph == (IGraphBuilder *)&graph, "Got unexpected graph %p.\n", ret_graph);
1704 IGraphBuilder_Release(ret_graph);
1706 got_add_filter = 0;
1707 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
1708 ok(hr == S_OK, "Got hr %#x.\n", hr);
1709 ok(!got_add_filter, "Got %d calls to IGraphBuilder::AddFilter().\n", got_add_filter);
1711 got_add_filter = 0;
1712 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, NULL);
1713 ok(hr == S_OK, "Got hr %#x.\n", hr);
1714 ok(!got_add_filter, "Got %d calls to IGraphBuilder::AddFilter().\n", got_add_filter);
1716 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, (IGraphBuilder *)&graph);
1717 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1718 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
1719 ok(hr == S_OK, "Got hr %#x.\n", hr);
1720 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
1721 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1722 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
1723 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1725 IMediaStreamFilter_Release(filter);
1726 ref = IAMMultiMediaStream_Release(mmstream);
1727 ok(!ref, "Got outstanding refcount %d.\n", ref);
1728 IFilterGraph2_Release(graph_inner);
1729 ok(graph_refcount == 1, "Got outstanding refcount %d.\n", graph_refcount);
1730 IUnknown_Release(graph_inner_unk);
1733 static void test_enum_media_types(void)
1735 IAMMultiMediaStream *mmstream = create_ammultimediastream();
1736 IEnumMediaTypes *enum1, *enum2;
1737 AM_MEDIA_TYPE *mts[2];
1738 IMediaStream *stream;
1739 ULONG ref, count;
1740 HRESULT hr;
1741 IPin *pin;
1743 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1744 ok(hr == S_OK, "Got hr %#x.\n", hr);
1745 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1746 ok(hr == S_OK, "Got hr %#x.\n", hr);
1748 hr = IPin_EnumMediaTypes(pin, &enum1);
1749 ok(hr == S_OK, "Got hr %#x.\n", hr);
1751 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
1752 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1754 hr = IEnumMediaTypes_Next(enum1, 0, mts, &count);
1755 ok(hr == S_OK, "Got hr %#x.\n", hr);
1756 ok(!count, "Got count %u.\n", count);
1758 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
1759 ok(hr == S_OK, "Got hr %#x.\n", hr);
1760 ok(count == 1, "Got count %u.\n", count);
1761 CoTaskMemFree(mts[0]);
1763 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
1764 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1765 ok(!count, "Got count %u.\n", count);
1767 hr = IEnumMediaTypes_Reset(enum1);
1768 ok(hr == S_OK, "Got hr %#x.\n", hr);
1770 hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
1771 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1772 ok(count == 1, "Got count %u.\n", count);
1773 CoTaskMemFree(mts[0]);
1775 hr = IEnumMediaTypes_Reset(enum1);
1776 ok(hr == S_OK, "Got hr %#x.\n", hr);
1778 hr = IEnumMediaTypes_Clone(enum1, &enum2);
1779 ok(hr == S_OK, "Got hr %#x.\n", hr);
1781 hr = IEnumMediaTypes_Skip(enum1, 2);
1782 ok(hr == S_OK, "Got hr %#x.\n", hr);
1784 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
1785 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1786 ok(!count, "Got count %u.\n", count);
1788 hr = IEnumMediaTypes_Next(enum2, 1, mts, &count);
1789 ok(hr == S_OK, "Got hr %#x.\n", hr);
1790 ok(count == 1, "Got count %u.\n", count);
1791 CoTaskMemFree(mts[0]);
1793 IEnumMediaTypes_Release(enum2);
1794 IEnumMediaTypes_Release(enum1);
1795 IPin_Release(pin);
1796 IMediaStream_Release(stream);
1798 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
1799 ok(hr == S_OK, "Got hr %#x.\n", hr);
1800 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1801 ok(hr == S_OK, "Got hr %#x.\n", hr);
1803 hr = IPin_EnumMediaTypes(pin, &enum1);
1804 ok(hr == S_OK, "Got hr %#x.\n", hr);
1806 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
1807 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1809 hr = IEnumMediaTypes_Next(enum1, 0, mts, &count);
1810 ok(hr == S_OK, "Got hr %#x.\n", hr);
1811 ok(!count, "Got count %u.\n", count);
1813 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
1814 ok(hr == S_OK, "Got hr %#x.\n", hr);
1815 ok(count == 1, "Got count %u.\n", count);
1816 CoTaskMemFree(mts[0]->pbFormat);
1817 CoTaskMemFree(mts[0]);
1819 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
1820 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1821 ok(!count, "Got count %u.\n", count);
1823 hr = IEnumMediaTypes_Reset(enum1);
1824 ok(hr == S_OK, "Got hr %#x.\n", hr);
1826 hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
1827 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1828 ok(count == 1, "Got count %u.\n", count);
1829 CoTaskMemFree(mts[0]->pbFormat);
1830 CoTaskMemFree(mts[0]);
1832 hr = IEnumMediaTypes_Reset(enum1);
1833 ok(hr == S_OK, "Got hr %#x.\n", hr);
1835 hr = IEnumMediaTypes_Clone(enum1, &enum2);
1836 ok(hr == S_OK, "Got hr %#x.\n", hr);
1838 hr = IEnumMediaTypes_Skip(enum1, 2);
1839 ok(hr == S_OK, "Got hr %#x.\n", hr);
1841 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
1842 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1843 ok(!count, "Got count %u.\n", count);
1845 hr = IEnumMediaTypes_Next(enum2, 1, mts, &count);
1846 ok(hr == S_OK, "Got hr %#x.\n", hr);
1847 ok(count == 1, "Got count %u.\n", count);
1848 CoTaskMemFree(mts[0]->pbFormat);
1849 CoTaskMemFree(mts[0]);
1851 IEnumMediaTypes_Release(enum2);
1852 IEnumMediaTypes_Release(enum1);
1853 IPin_Release(pin);
1854 IMediaStream_Release(stream);
1856 ref = IAMMultiMediaStream_Release(mmstream);
1857 ok(!ref, "Got outstanding refcount %d.\n", ref);
1860 static void test_media_types(void)
1862 static const VIDEOINFOHEADER req_vih = {};
1863 static const WAVEFORMATEX expect_wfx =
1865 .wFormatTag = WAVE_FORMAT_PCM,
1866 .nChannels = 1,
1867 .nSamplesPerSec = 11025,
1868 .nAvgBytesPerSec = 11025 * 2,
1869 .nBlockAlign = 2,
1870 .wBitsPerSample = 16,
1871 .cbSize = 0,
1873 IAMMultiMediaStream *mmstream = create_ammultimediastream();
1874 IEnumMediaTypes *enummt;
1875 IMediaStream *stream;
1876 AM_MEDIA_TYPE *pmt;
1877 ULONG ref, count;
1878 unsigned int i;
1879 HRESULT hr;
1880 IPin *pin;
1882 static const GUID *rejected_subtypes[] =
1884 &MEDIASUBTYPE_RGB1,
1885 &MEDIASUBTYPE_RGB4,
1886 &MEDIASUBTYPE_RGB565,
1887 &MEDIASUBTYPE_RGB555,
1888 &MEDIASUBTYPE_RGB24,
1889 &MEDIASUBTYPE_RGB32,
1890 &MEDIASUBTYPE_ARGB32,
1891 &MEDIASUBTYPE_ARGB1555,
1892 &MEDIASUBTYPE_ARGB4444,
1893 &GUID_NULL,
1896 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1897 ok(hr == S_OK, "Got hr %#x.\n", hr);
1898 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1899 ok(hr == S_OK, "Got hr %#x.\n", hr);
1901 hr = IPin_EnumMediaTypes(pin, &enummt);
1902 ok(hr == S_OK, "Got hr %#x.\n", hr);
1904 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
1905 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1907 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
1908 ok(hr == S_OK, "Got hr %#x.\n", hr);
1909 ok(count == 1, "Got count %u.\n", count);
1910 ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Video), "Got major type %s\n",
1911 wine_dbgstr_guid(&pmt->majortype));
1912 ok(IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB8), "Got subtype %s\n",
1913 wine_dbgstr_guid(&pmt->subtype));
1914 ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
1915 ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
1916 ok(pmt->lSampleSize == 10000, "Got sample size %u.\n", pmt->lSampleSize);
1917 ok(IsEqualGUID(&pmt->formattype, &GUID_NULL), "Got format type %s.\n",
1918 wine_dbgstr_guid(&pmt->formattype));
1919 ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
1921 hr = IPin_QueryAccept(pin, pmt);
1922 todo_wine ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
1924 pmt->formattype = FORMAT_VideoInfo;
1925 pmt->cbFormat = sizeof(VIDEOINFOHEADER);
1926 pmt->pbFormat = (BYTE *)&req_vih;
1927 hr = IPin_QueryAccept(pin, pmt);
1928 ok(hr == S_OK, "Got hr %#x.\n", hr);
1930 pmt->bFixedSizeSamples = FALSE;
1931 pmt->bTemporalCompression = TRUE;
1932 pmt->lSampleSize = 123;
1933 hr = IPin_QueryAccept(pin, pmt);
1934 ok(hr == S_OK, "Got hr %#x.\n", hr);
1936 pmt->majortype = MEDIATYPE_NULL;
1937 hr = IPin_QueryAccept(pin, pmt);
1938 todo_wine ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
1939 pmt->majortype = MEDIATYPE_Audio;
1940 hr = IPin_QueryAccept(pin, pmt);
1941 todo_wine ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
1942 pmt->majortype = MEDIATYPE_Stream;
1943 hr = IPin_QueryAccept(pin, pmt);
1944 todo_wine ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
1945 pmt->majortype = MEDIATYPE_Video;
1947 for (i = 0; i < ARRAY_SIZE(rejected_subtypes); ++i)
1949 pmt->subtype = *rejected_subtypes[i];
1950 hr = IPin_QueryAccept(pin, pmt);
1951 todo_wine ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x for subtype %s.\n",
1952 hr, wine_dbgstr_guid(rejected_subtypes[i]));
1955 CoTaskMemFree(pmt);
1957 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
1958 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1960 IEnumMediaTypes_Release(enummt);
1961 IPin_Release(pin);
1962 IMediaStream_Release(stream);
1964 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
1965 ok(hr == S_OK, "Got hr %#x.\n", hr);
1966 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1967 ok(hr == S_OK, "Got hr %#x.\n", hr);
1969 hr = IPin_EnumMediaTypes(pin, &enummt);
1970 ok(hr == S_OK, "Got hr %#x.\n", hr);
1972 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
1973 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1975 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
1976 ok(hr == S_OK, "Got hr %#x.\n", hr);
1977 ok(count == 1, "Got count %u.\n", count);
1978 ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s\n",
1979 wine_dbgstr_guid(&pmt->majortype));
1980 todo_wine ok(IsEqualGUID(&pmt->subtype, &GUID_NULL), "Got subtype %s\n",
1981 wine_dbgstr_guid(&pmt->subtype));
1982 todo_wine ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
1983 ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
1984 todo_wine ok(pmt->lSampleSize == 2, "Got sample size %u.\n", pmt->lSampleSize);
1985 todo_wine ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n",
1986 wine_dbgstr_guid(&pmt->formattype));
1987 ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
1988 todo_wine ok(pmt->cbFormat == sizeof(WAVEFORMATEX), "Got format size %u.\n", pmt->cbFormat);
1989 ok(!memcmp(pmt->pbFormat, &expect_wfx, pmt->cbFormat), "Format blocks didn't match.\n");
1991 hr = IPin_QueryAccept(pin, pmt);
1992 todo_wine ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
1994 CoTaskMemFree(pmt);
1996 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
1997 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1999 IEnumMediaTypes_Release(enummt);
2000 IPin_Release(pin);
2001 IMediaStream_Release(stream);
2003 ref = IAMMultiMediaStream_Release(mmstream);
2004 ok(!ref, "Got outstanding refcount %d.\n", ref);
2007 static void test_IDirectDrawStreamSample(void)
2009 IDirectDrawMediaStream *ddraw_stream = NULL;
2010 IDirectDrawStreamSample *sample = NULL;
2011 IDirectDrawSurface *surface, *surface2;
2012 IMediaStream *stream2, *stream = NULL;
2013 DDSURFACEDESC desc = { sizeof(desc) };
2014 IAMMultiMediaStream *mmstream;
2015 IDirectDrawSurface7 *surface7;
2016 IDirectDraw *ddraw, *ddraw2;
2017 IDirectDraw7 *ddraw7;
2018 HRESULT hr;
2019 RECT rect;
2021 if (!(mmstream = create_ammultimediastream()))
2022 return;
2023 if (!create_directdraw())
2025 IAMMultiMediaStream_Release(mmstream);
2026 return;
2029 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2030 ok(hr == S_OK, "got 0x%08x\n", hr);
2032 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown*)pdd7, &MSPID_PrimaryVideo, 0, NULL);
2033 ok(hr == S_OK, "got 0x%08x\n", hr);
2035 hr = IAMMultiMediaStream_GetMediaStream(mmstream, &MSPID_PrimaryVideo, &stream);
2036 ok(hr == S_OK, "got 0x%08x\n", hr);
2037 if (FAILED(hr)) goto error;
2039 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
2040 ok(hr == S_OK, "got 0x%08x\n", hr);
2041 if (FAILED(hr)) goto error;
2043 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw);
2044 ok(hr == S_OK, "got 0x%08x\n", hr);
2046 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw2);
2047 ok(hr == S_OK, "got 0x%08x\n", hr);
2048 ok(ddraw == ddraw2, "got %p, %p\n", ddraw, ddraw2);
2050 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw7, (void **)&ddraw7);
2051 ok(hr == S_OK, "got 0x%08x\n", hr);
2052 ok(ddraw7 == pdd7, "Got IDirectDraw instance %p, expected %p.\n", ddraw7, pdd7);
2053 IDirectDraw7_Release(ddraw7);
2055 IDirectDraw_Release(ddraw2);
2056 IDirectDraw_Release(ddraw);
2058 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
2059 ok(hr == S_OK, "got 0x%08x\n", hr);
2061 surface = NULL;
2062 hr = IDirectDrawStreamSample_GetSurface(sample, &surface, &rect);
2063 ok(hr == S_OK, "got 0x%08x\n", hr);
2064 ok(surface != NULL, "got %p\n", surface);
2066 /* Crashes on native. */
2067 if (0)
2069 hr = IDirectDrawStreamSample_GetMediaStream(sample, NULL);
2070 ok(hr == E_POINTER, "got 0x%08x\n", hr);
2073 hr = IDirectDrawStreamSample_GetMediaStream(sample, &stream2);
2074 todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
2075 todo_wine ok(stream2 == stream, "Expected stream %p, got %p.\n", stream, stream2);
2076 if (hr == S_OK) IMediaStream_Release(stream2);
2078 hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void **)&surface7);
2079 ok(hr == S_OK, "got 0x%08x\n", hr);
2080 IDirectDrawSurface7_Release(surface7);
2082 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
2083 ok(hr == S_OK, "got 0x%08x\n", hr);
2084 ok(desc.dwWidth == 100, "width %d\n", desc.dwWidth);
2085 ok(desc.dwHeight == 100, "height %d\n", desc.dwHeight);
2086 ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "format flags %08x\n", desc.ddpfPixelFormat.dwFlags);
2087 ok(desc.ddpfPixelFormat.dwRGBBitCount, "dwRGBBitCount %d\n", desc.ddpfPixelFormat.dwRGBBitCount);
2088 IDirectDrawSurface_Release(surface);
2089 IDirectDrawStreamSample_Release(sample);
2091 hr = IDirectDrawSurface7_QueryInterface(pdds7, &IID_IDirectDrawSurface, (void **)&surface);
2092 ok(hr == S_OK, "got 0x%08x\n", hr);
2094 EXPECT_REF(surface, 1);
2095 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, NULL, 0, &sample);
2096 ok(hr == S_OK, "got 0x%08x\n", hr);
2097 EXPECT_REF(surface, 2);
2099 surface2 = NULL;
2100 SetRectEmpty(&rect);
2101 hr = IDirectDrawStreamSample_GetSurface(sample, &surface2, &rect);
2102 ok(hr == S_OK, "got 0x%08x\n", hr);
2103 ok(surface == surface2, "got %p\n", surface2);
2104 ok(rect.right > 0 && rect.bottom > 0, "got %d, %d\n", rect.right, rect.bottom);
2105 EXPECT_REF(surface, 3);
2106 IDirectDrawSurface_Release(surface2);
2108 hr = IDirectDrawStreamSample_GetSurface(sample, NULL, NULL);
2109 ok(hr == S_OK, "got 0x%08x\n", hr);
2111 IDirectDrawStreamSample_Release(sample);
2112 IDirectDrawSurface_Release(surface);
2114 error:
2115 if (ddraw_stream)
2116 IDirectDrawMediaStream_Release(ddraw_stream);
2117 if (stream)
2118 IMediaStream_Release(stream);
2120 release_directdraw();
2121 IAMMultiMediaStream_Release(mmstream);
2124 static IUnknown *create_audio_data(void)
2126 IUnknown *audio_data = NULL;
2127 HRESULT result = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER,
2128 &IID_IUnknown, (void **)&audio_data);
2129 ok(S_OK == result, "got 0x%08x\n", result);
2130 return audio_data;
2133 static void test_audiodata_query_interface(void)
2135 IUnknown *unknown = create_audio_data();
2136 IMemoryData *memory_data = NULL;
2137 IAudioData *audio_data = NULL;
2139 HRESULT result;
2141 result = IUnknown_QueryInterface(unknown, &IID_IMemoryData, (void **)&memory_data);
2142 ok(E_NOINTERFACE == result, "got 0x%08x\n", result);
2144 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
2145 ok(S_OK == result, "got 0x%08x\n", result);
2146 if (S_OK == result)
2148 result = IAudioData_QueryInterface(audio_data, &IID_IMemoryData, (void **)&memory_data);
2149 ok(E_NOINTERFACE == result, "got 0x%08x\n", result);
2151 IAudioData_Release(audio_data);
2154 IUnknown_Release(unknown);
2157 static void test_audiodata_get_info(void)
2159 IUnknown *unknown = create_audio_data();
2160 IAudioData *audio_data = NULL;
2162 HRESULT result;
2164 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
2165 if (FAILED(result))
2167 /* test_audiodata_query_interface handles this case */
2168 skip("No IAudioData\n");
2169 goto out_unknown;
2172 result = IAudioData_GetInfo(audio_data, NULL, NULL, NULL);
2173 ok(MS_E_NOTINIT == result, "got 0x%08x\n", result);
2175 IAudioData_Release(audio_data);
2177 out_unknown:
2178 IUnknown_Release(unknown);
2181 static void test_audiodata_set_buffer(void)
2183 IUnknown *unknown = create_audio_data();
2184 IAudioData *audio_data = NULL;
2185 BYTE buffer[100] = {0};
2186 DWORD length = 0;
2187 BYTE *data = NULL;
2189 HRESULT result;
2191 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
2192 if (FAILED(result))
2194 /* test_audiodata_query_interface handles this case */
2195 skip("No IAudioData\n");
2196 goto out_unknown;
2199 result = IAudioData_SetBuffer(audio_data, 100, NULL, 0);
2200 ok(S_OK == result, "got 0x%08x\n", result);
2202 data = (BYTE *)0xdeadbeef;
2203 length = 0xdeadbeef;
2204 result = IAudioData_GetInfo(audio_data, &length, &data, NULL);
2205 ok(S_OK == result, "got 0x%08x\n", result);
2206 ok(100 == length, "got %u\n", length);
2207 ok(NULL != data, "got %p\n", data);
2209 result = IAudioData_SetBuffer(audio_data, 0, buffer, 0);
2210 ok(E_INVALIDARG == result, "got 0x%08x\n", result);
2212 result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
2213 ok(S_OK == result, "got 0x%08x\n", result);
2215 data = (BYTE *)0xdeadbeef;
2216 length = 0xdeadbeef;
2217 result = IAudioData_GetInfo(audio_data, &length, &data, NULL);
2218 ok(S_OK == result, "got 0x%08x\n", result);
2219 ok(sizeof(buffer) == length, "got %u\n", length);
2220 ok(buffer == data, "got %p\n", data);
2222 IAudioData_Release(audio_data);
2224 out_unknown:
2225 IUnknown_Release(unknown);
2228 static void test_audiodata_set_actual(void)
2230 IUnknown *unknown = create_audio_data();
2231 IAudioData *audio_data = NULL;
2232 BYTE buffer[100] = {0};
2233 DWORD actual_data = 0;
2235 HRESULT result;
2237 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
2238 if (FAILED(result))
2240 /* test_audiodata_query_interface handles this case */
2241 skip("No IAudioData\n");
2242 goto out_unknown;
2245 result = IAudioData_SetActual(audio_data, 0);
2246 ok(S_OK == result, "got 0x%08x\n", result);
2248 result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
2249 ok(S_OK == result, "got 0x%08x\n", result);
2251 result = IAudioData_SetActual(audio_data, sizeof(buffer) + 1);
2252 ok(E_INVALIDARG == result, "got 0x%08x\n", result);
2254 result = IAudioData_SetActual(audio_data, sizeof(buffer));
2255 ok(S_OK == result, "got 0x%08x\n", result);
2257 actual_data = 0xdeadbeef;
2258 result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data);
2259 ok(S_OK == result, "got 0x%08x\n", result);
2260 ok(sizeof(buffer) == actual_data, "got %u\n", actual_data);
2262 result = IAudioData_SetActual(audio_data, 0);
2263 ok(S_OK == result, "got 0x%08x\n", result);
2265 actual_data = 0xdeadbeef;
2266 result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data);
2267 ok(S_OK == result, "got 0x%08x\n", result);
2268 ok(0 == actual_data, "got %u\n", actual_data);
2270 IAudioData_Release(audio_data);
2272 out_unknown:
2273 IUnknown_Release(unknown);
2276 static void test_audiodata_get_format(void)
2278 IUnknown *unknown = create_audio_data();
2279 IAudioData *audio_data = NULL;
2280 WAVEFORMATEX wave_format = {0};
2282 HRESULT result;
2284 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
2285 if (FAILED(result))
2287 /* test_audiodata_query_interface handles this case */
2288 skip("No IAudioData\n");
2289 goto out_unknown;
2292 result = IAudioData_GetFormat(audio_data, NULL);
2293 ok(E_POINTER == result, "got 0x%08x\n", result);
2295 wave_format.wFormatTag = 0xdead;
2296 wave_format.nChannels = 0xdead;
2297 wave_format.nSamplesPerSec = 0xdeadbeef;
2298 wave_format.nAvgBytesPerSec = 0xdeadbeef;
2299 wave_format.nBlockAlign = 0xdead;
2300 wave_format.wBitsPerSample = 0xdead;
2301 wave_format.cbSize = 0xdead;
2302 result = IAudioData_GetFormat(audio_data, &wave_format);
2303 ok(S_OK == result, "got 0x%08x\n", result);
2304 ok(WAVE_FORMAT_PCM == wave_format.wFormatTag, "got %u\n", wave_format.wFormatTag);
2305 ok(1 == wave_format.nChannels, "got %u\n", wave_format.nChannels);
2306 ok(11025 == wave_format.nSamplesPerSec, "got %u\n", wave_format.nSamplesPerSec);
2307 ok(22050 == wave_format.nAvgBytesPerSec, "got %u\n", wave_format.nAvgBytesPerSec);
2308 ok(2 == wave_format.nBlockAlign, "got %u\n", wave_format.nBlockAlign);
2309 ok(16 == wave_format.wBitsPerSample, "got %u\n", wave_format.wBitsPerSample);
2310 ok(0 == wave_format.cbSize, "got %u\n", wave_format.cbSize);
2312 IAudioData_Release(audio_data);
2314 out_unknown:
2315 IUnknown_Release(unknown);
2318 static void test_audiodata_set_format(void)
2320 IUnknown *unknown = create_audio_data();
2321 IAudioData *audio_data = NULL;
2322 WAVEFORMATPCMEX wave_format = {{0}};
2324 HRESULT result;
2326 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
2327 if (FAILED(result))
2329 /* test_audiodata_query_interface handles this case */
2330 skip("No IAudioData\n");
2331 goto out_unknown;
2334 result = IAudioData_SetFormat(audio_data, NULL);
2335 ok(E_POINTER == result, "got 0x%08x\n", result);
2337 wave_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
2338 wave_format.Format.nChannels = 2;
2339 wave_format.Format.nSamplesPerSec = 44100;
2340 wave_format.Format.nAvgBytesPerSec = 176400;
2341 wave_format.Format.nBlockAlign = 4;
2342 wave_format.Format.wBitsPerSample = 16;
2343 wave_format.Format.cbSize = 22;
2344 wave_format.Samples.wValidBitsPerSample = 16;
2345 wave_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
2346 wave_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
2347 result = IAudioData_SetFormat(audio_data, &wave_format.Format);
2348 ok(E_INVALIDARG == result, "got 0x%08x\n", result);
2350 wave_format.Format.wFormatTag = WAVE_FORMAT_PCM;
2351 wave_format.Format.nChannels = 2;
2352 wave_format.Format.nSamplesPerSec = 44100;
2353 wave_format.Format.nAvgBytesPerSec = 176400;
2354 wave_format.Format.nBlockAlign = 4;
2355 wave_format.Format.wBitsPerSample = 16;
2356 wave_format.Format.cbSize = 0;
2357 result = IAudioData_SetFormat(audio_data, &wave_format.Format);
2358 ok(S_OK == result, "got 0x%08x\n", result);
2360 wave_format.Format.wFormatTag = 0xdead;
2361 wave_format.Format.nChannels = 0xdead;
2362 wave_format.Format.nSamplesPerSec = 0xdeadbeef;
2363 wave_format.Format.nAvgBytesPerSec = 0xdeadbeef;
2364 wave_format.Format.nBlockAlign = 0xdead;
2365 wave_format.Format.wBitsPerSample = 0xdead;
2366 wave_format.Format.cbSize = 0xdead;
2367 result = IAudioData_GetFormat(audio_data, &wave_format.Format);
2368 ok(S_OK == result, "got 0x%08x\n", result);
2369 ok(WAVE_FORMAT_PCM == wave_format.Format.wFormatTag, "got %u\n", wave_format.Format.wFormatTag);
2370 ok(2 == wave_format.Format.nChannels, "got %u\n", wave_format.Format.nChannels);
2371 ok(44100 == wave_format.Format.nSamplesPerSec, "got %u\n", wave_format.Format.nSamplesPerSec);
2372 ok(176400 == wave_format.Format.nAvgBytesPerSec, "got %u\n", wave_format.Format.nAvgBytesPerSec);
2373 ok(4 == wave_format.Format.nBlockAlign, "got %u\n", wave_format.Format.nBlockAlign);
2374 ok(16 == wave_format.Format.wBitsPerSample, "got %u\n", wave_format.Format.wBitsPerSample);
2375 ok(0 == wave_format.Format.cbSize, "got %u\n", wave_format.Format.cbSize);
2377 IAudioData_Release(audio_data);
2379 out_unknown:
2380 IUnknown_Release(unknown);
2383 struct testfilter
2385 struct strmbase_filter filter;
2386 struct strmbase_source source;
2387 IMediaSeeking IMediaSeeking_iface;
2388 LONGLONG current_position;
2389 LONGLONG stop_position;
2390 HRESULT get_duration_hr;
2391 HRESULT set_positions_hr;
2394 static inline struct testfilter *impl_from_BaseFilter(struct strmbase_filter *iface)
2396 return CONTAINING_RECORD(iface, struct testfilter, filter);
2399 static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
2401 struct testfilter *filter = impl_from_BaseFilter(iface);
2402 if (!index)
2403 return &filter->source.pin;
2404 return NULL;
2407 static void testfilter_destroy(struct strmbase_filter *iface)
2409 struct testfilter *filter = impl_from_BaseFilter(iface);
2410 strmbase_source_cleanup(&filter->source);
2411 strmbase_filter_cleanup(&filter->filter);
2414 static HRESULT testfilter_init_stream(struct strmbase_filter *iface)
2416 struct testfilter *filter = impl_from_BaseFilter(iface);
2418 BaseOutputPinImpl_Active(&filter->source);
2419 return S_OK;
2422 static HRESULT testfilter_cleanup_stream(struct strmbase_filter *iface)
2424 struct testfilter *filter = impl_from_BaseFilter(iface);
2426 BaseOutputPinImpl_Inactive(&filter->source);
2427 return S_OK;
2430 static const struct strmbase_filter_ops testfilter_ops =
2432 .filter_get_pin = testfilter_get_pin,
2433 .filter_destroy = testfilter_destroy,
2434 .filter_init_stream = testfilter_init_stream,
2435 .filter_cleanup_stream = testfilter_cleanup_stream,
2438 static inline struct testfilter *impl_from_base_pin(struct strmbase_pin *iface)
2440 return CONTAINING_RECORD(iface, struct testfilter, source.pin);
2443 static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
2445 struct testfilter *filter = impl_from_base_pin(iface);
2447 if (IsEqualGUID(iid, &IID_IMediaSeeking) && filter->IMediaSeeking_iface.lpVtbl)
2448 *out = &filter->IMediaSeeking_iface;
2449 else
2450 return E_NOINTERFACE;
2452 IUnknown_AddRef((IUnknown *)*out);
2454 return S_OK;
2457 static HRESULT WINAPI testsource_DecideBufferSize(struct strmbase_source *iface,
2458 IMemAllocator *alloc, ALLOCATOR_PROPERTIES *requested)
2460 ALLOCATOR_PROPERTIES actual;
2462 if (!requested->cbAlign)
2463 requested->cbAlign = 1;
2465 if (requested->cbBuffer < 4096)
2466 requested->cbBuffer = 4096;
2468 if (!requested->cBuffers)
2469 requested->cBuffers = 2;
2471 return IMemAllocator_SetProperties(alloc, requested, &actual);
2474 static const struct strmbase_source_ops testsource_ops =
2476 .base.pin_query_interface = testsource_query_interface,
2477 .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
2478 .pfnDecideBufferSize = testsource_DecideBufferSize,
2479 .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
2482 static void testfilter_init(struct testfilter *filter)
2484 static const GUID clsid = {0xabacab};
2485 memset(filter, 0, sizeof(*filter));
2486 strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
2487 strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops);
2488 filter->stop_position = 0x8000000000000000ULL;
2491 static inline struct testfilter *impl_from_IMediaSeeking(IMediaSeeking *iface)
2493 return CONTAINING_RECORD(iface, struct testfilter, IMediaSeeking_iface);
2496 static HRESULT WINAPI testsource_seeking_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
2498 struct testfilter *filter = impl_from_IMediaSeeking(iface);
2499 return IBaseFilter_QueryInterface(&filter->filter.IBaseFilter_iface, iid, out);
2502 static ULONG WINAPI testsource_seeking_AddRef(IMediaSeeking *iface)
2504 struct testfilter *filter = impl_from_IMediaSeeking(iface);
2505 return IBaseFilter_AddRef(&filter->filter.IBaseFilter_iface);
2508 static ULONG WINAPI testsource_seeking_Release(IMediaSeeking *iface)
2510 struct testfilter *filter = impl_from_IMediaSeeking(iface);
2511 return IBaseFilter_Release(&filter->filter.IBaseFilter_iface);
2514 static HRESULT WINAPI testsource_seeking_GetCapabilities(IMediaSeeking *iface, DWORD *capabilities)
2516 ok(0, "Unexpected call.\n");
2517 return E_NOTIMPL;
2520 static HRESULT WINAPI testsource_seeking_CheckCapabilities(IMediaSeeking *iface, DWORD *capabilities)
2522 ok(0, "Unexpected call.\n");
2523 return E_NOTIMPL;
2526 static HRESULT WINAPI testsource_seeking_IsFormatSupported(IMediaSeeking *iface, const GUID *format)
2528 ok(0, "Unexpected call.\n");
2529 return E_NOTIMPL;
2532 static HRESULT WINAPI testsource_seeking_QueryPreferredFormat(IMediaSeeking *iface, GUID *format)
2534 ok(0, "Unexpected call.\n");
2535 return E_NOTIMPL;
2538 static HRESULT WINAPI testsource_seeking_GetTimeFormat(IMediaSeeking *iface, GUID *format)
2540 ok(0, "Unexpected call.\n");
2541 return E_NOTIMPL;
2544 static HRESULT WINAPI testsource_seeking_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format)
2546 ok(0, "Unexpected call.\n");
2547 return E_NOTIMPL;
2550 static HRESULT WINAPI testsource_seeking_SetTimeFormat(IMediaSeeking *iface, const GUID *format)
2552 ok(0, "Unexpected call.\n");
2553 return E_NOTIMPL;
2556 static HRESULT WINAPI testsource_seeking_GetDuration(IMediaSeeking *iface, LONGLONG *duration)
2558 struct testfilter *filter = impl_from_IMediaSeeking(iface);
2560 if (SUCCEEDED(filter->get_duration_hr))
2561 *duration = 0x8000000000000000ULL;
2563 return filter->get_duration_hr;
2566 static HRESULT WINAPI testsource_seeking_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop)
2568 ok(0, "Unexpected call.\n");
2569 return E_NOTIMPL;
2572 static HRESULT WINAPI testsource_seeking_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current)
2574 ok(0, "Unexpected call.\n");
2575 return E_NOTIMPL;
2578 static HRESULT WINAPI testsource_seeking_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target,
2579 const GUID *target_format, LONGLONG source, const GUID *source_format)
2581 ok(0, "Unexpected call.\n");
2582 return E_NOTIMPL;
2585 static HRESULT WINAPI testsource_seeking_SetPositions(IMediaSeeking *iface, LONGLONG *current_ptr, DWORD current_flags,
2586 LONGLONG *stop_ptr, DWORD stop_flags)
2588 struct testfilter *filter = impl_from_IMediaSeeking(iface);
2590 if (SUCCEEDED(filter->set_positions_hr))
2592 if (current_ptr)
2593 filter->current_position = *current_ptr;
2595 if (stop_ptr)
2596 filter->stop_position = *stop_ptr;
2599 return filter->set_positions_hr;
2602 static HRESULT WINAPI testsource_seeking_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop)
2604 ok(0, "Unexpected call.\n");
2605 return E_NOTIMPL;
2608 static HRESULT WINAPI testsource_seeking_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest)
2610 ok(0, "Unexpected call.\n");
2611 return E_NOTIMPL;
2614 static HRESULT WINAPI testsource_seeking_SetRate(IMediaSeeking *iface, double rate)
2616 ok(0, "Unexpected call.\n");
2617 return E_NOTIMPL;
2620 static HRESULT WINAPI testsource_seeking_GetRate(IMediaSeeking *iface, double *rate)
2622 ok(0, "Unexpected call.\n");
2623 return E_NOTIMPL;
2626 static HRESULT WINAPI testsource_seeking_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll)
2628 ok(0, "Unexpected call.\n");
2629 return E_NOTIMPL;
2632 static const IMediaSeekingVtbl testsource_seeking_vtbl =
2634 testsource_seeking_QueryInterface,
2635 testsource_seeking_AddRef,
2636 testsource_seeking_Release,
2637 testsource_seeking_GetCapabilities,
2638 testsource_seeking_CheckCapabilities,
2639 testsource_seeking_IsFormatSupported,
2640 testsource_seeking_QueryPreferredFormat,
2641 testsource_seeking_GetTimeFormat,
2642 testsource_seeking_IsUsingTimeFormat,
2643 testsource_seeking_SetTimeFormat,
2644 testsource_seeking_GetDuration,
2645 testsource_seeking_GetStopPosition,
2646 testsource_seeking_GetCurrentPosition,
2647 testsource_seeking_ConvertTimeFormat,
2648 testsource_seeking_SetPositions,
2649 testsource_seeking_GetPositions,
2650 testsource_seeking_GetAvailable,
2651 testsource_seeking_SetRate,
2652 testsource_seeking_GetRate,
2653 testsource_seeking_GetPreroll,
2656 struct testclock
2658 IReferenceClock IReferenceClock_iface;
2659 LONG refcount;
2660 LONGLONG time;
2661 HRESULT get_time_hr;
2664 static inline struct testclock *impl_from_IReferenceClock(IReferenceClock *iface)
2666 return CONTAINING_RECORD(iface, struct testclock, IReferenceClock_iface);
2669 static HRESULT WINAPI testclock_QueryInterface(IReferenceClock *iface, REFIID iid, void **out)
2671 if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
2672 if (IsEqualGUID(iid, &IID_IReferenceClock)
2673 || IsEqualGUID(iid, &IID_IUnknown))
2675 *out = iface;
2676 IReferenceClock_AddRef(iface);
2677 return S_OK;
2679 return E_NOINTERFACE;
2682 static ULONG WINAPI testclock_AddRef(IReferenceClock *iface)
2684 struct testclock *clock = impl_from_IReferenceClock(iface);
2685 return InterlockedIncrement(&clock->refcount);
2688 static ULONG WINAPI testclock_Release(IReferenceClock *iface)
2690 struct testclock *clock = impl_from_IReferenceClock(iface);
2691 return InterlockedDecrement(&clock->refcount);
2694 static HRESULT WINAPI testclock_GetTime(IReferenceClock *iface, REFERENCE_TIME *time)
2696 struct testclock *clock = impl_from_IReferenceClock(iface);
2697 if (SUCCEEDED(clock->get_time_hr))
2698 *time = clock->time;
2699 return clock->get_time_hr;
2702 static HRESULT WINAPI testclock_AdviseTime(IReferenceClock *iface, REFERENCE_TIME base, REFERENCE_TIME offset, HEVENT event, DWORD_PTR *cookie)
2704 ok(0, "Unexpected call.\n");
2705 return E_NOTIMPL;
2708 static HRESULT WINAPI testclock_AdvisePeriodic(IReferenceClock *iface, REFERENCE_TIME start, REFERENCE_TIME period, HSEMAPHORE semaphore, DWORD_PTR *cookie)
2710 ok(0, "Unexpected call.\n");
2711 return E_NOTIMPL;
2714 static HRESULT WINAPI testclock_Unadvise(IReferenceClock *iface, DWORD_PTR cookie)
2716 ok(0, "Unexpected call.\n");
2717 return E_NOTIMPL;
2720 static IReferenceClockVtbl testclock_vtbl =
2722 testclock_QueryInterface,
2723 testclock_AddRef,
2724 testclock_Release,
2725 testclock_GetTime,
2726 testclock_AdviseTime,
2727 testclock_AdvisePeriodic,
2728 testclock_Unadvise,
2731 static void testclock_init(struct testclock *clock)
2733 memset(clock, 0, sizeof(*clock));
2734 clock->IReferenceClock_iface.lpVtbl = &testclock_vtbl;
2737 static void test_audiostream_get_format(void)
2739 static const WAVEFORMATEX pin_format =
2741 .wFormatTag = WAVE_FORMAT_PCM,
2742 .nChannels = 2,
2743 .nSamplesPerSec = 44100,
2744 .wBitsPerSample = 16,
2745 .nBlockAlign = 4,
2746 .nAvgBytesPerSec = 4 * 44100,
2748 AM_MEDIA_TYPE mt =
2750 .majortype = MEDIATYPE_Audio,
2751 .subtype = MEDIASUBTYPE_PCM,
2752 .formattype = FORMAT_WaveFormatEx,
2753 .cbFormat = sizeof(WAVEFORMATEX),
2754 .pbFormat = (BYTE *)&pin_format,
2756 IAMMultiMediaStream *mmstream = create_ammultimediastream();
2757 IAudioMediaStream *audio_stream;
2758 struct testfilter source;
2759 IGraphBuilder *graph;
2760 IMediaStream *stream;
2761 WAVEFORMATEX format;
2762 HRESULT hr;
2763 ULONG ref;
2764 IPin *pin;
2766 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
2767 ok(hr == S_OK, "Got hr %#x.\n", hr);
2768 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
2769 ok(hr == S_OK, "Got hr %#x.\n", hr);
2770 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2771 ok(hr == S_OK, "Got hr %#x.\n", hr);
2773 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
2774 ok(hr == S_OK, "Got hr %#x.\n", hr);
2775 ok(!!graph, "Expected non-NULL graph.\n");
2777 testfilter_init(&source);
2779 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
2780 ok(hr == S_OK, "Got hr %#x.\n", hr);
2782 hr = IAudioMediaStream_GetFormat(audio_stream, NULL);
2783 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
2785 hr = IAudioMediaStream_GetFormat(audio_stream, &format);
2786 ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
2788 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
2789 ok(hr == S_OK, "Got hr %#x.\n", hr);
2791 memset(&format, 0xcc, sizeof(format));
2792 hr = IAudioMediaStream_GetFormat(audio_stream, &format);
2793 ok(hr == S_OK, "Got hr %#x.\n", hr);
2794 ok(format.wFormatTag == WAVE_FORMAT_PCM, "Got tag %#x.\n", format.wFormatTag);
2795 ok(format.nChannels == 2, "Got %u channels.\n", format.nChannels);
2796 ok(format.nSamplesPerSec == 44100, "Got sample rate %u.\n", format.nSamplesPerSec);
2797 ok(format.nAvgBytesPerSec == 176400, "Got %u bytes/sec.\n", format.nAvgBytesPerSec);
2798 ok(format.nBlockAlign == 4, "Got alignment %u.\n", format.nBlockAlign);
2799 ok(format.wBitsPerSample == 16, "Got %u bits/sample.\n", format.wBitsPerSample);
2800 ok(!format.cbSize, "Got extra size %u.\n", format.cbSize);
2802 hr = IGraphBuilder_Disconnect(graph, pin);
2803 ok(hr == S_OK, "Got hr %#x.\n", hr);
2804 hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
2805 ok(hr == S_OK, "Got hr %#x.\n", hr);
2807 hr = IAudioMediaStream_GetFormat(audio_stream, &format);
2808 ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
2810 ref = IAMMultiMediaStream_Release(mmstream);
2811 ok(!ref, "Got outstanding refcount %d.\n", ref);
2812 ref = IGraphBuilder_Release(graph);
2813 ok(!ref, "Got outstanding refcount %d.\n", ref);
2814 IPin_Release(pin);
2815 IAudioMediaStream_Release(audio_stream);
2816 ref = IMediaStream_Release(stream);
2817 ok(!ref, "Got outstanding refcount %d.\n", ref);
2818 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
2819 ok(!ref, "Got outstanding refcount %d.\n", ref);
2822 static HRESULT set_audiostream_format(const WAVEFORMATEX *format)
2824 IAMMultiMediaStream *mmstream = create_ammultimediastream();
2825 IAudioMediaStream *audio_stream;
2826 IMediaStream *stream;
2827 HRESULT hr;
2828 ULONG ref;
2830 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
2831 ok(hr == S_OK, "Got hr %#x.\n", hr);
2832 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
2833 ok(hr == S_OK, "Got hr %#x.\n", hr);
2835 hr = IAudioMediaStream_SetFormat(audio_stream, format);
2837 ref = IAMMultiMediaStream_Release(mmstream);
2838 ok(!ref, "Got outstanding refcount %d.\n", ref);
2839 IAudioMediaStream_Release(audio_stream);
2840 ref = IMediaStream_Release(stream);
2841 ok(!ref, "Got outstanding refcount %d.\n", ref);
2843 return hr;
2846 static void test_audiostream_set_format(void)
2848 static const WAVEFORMATEX valid_format =
2850 .wFormatTag = WAVE_FORMAT_PCM,
2851 .nChannels = 2,
2852 .nSamplesPerSec = 44100,
2853 .wBitsPerSample = 16,
2854 .nBlockAlign = 4,
2855 .nAvgBytesPerSec = 4 * 44100,
2858 const AM_MEDIA_TYPE mt =
2860 .majortype = MEDIATYPE_Audio,
2861 .subtype = MEDIASUBTYPE_PCM,
2862 .formattype = FORMAT_WaveFormatEx,
2863 .cbFormat = sizeof(WAVEFORMATEX),
2864 .pbFormat = (BYTE *)&valid_format,
2867 WAVEFORMATEXTENSIBLE extensible_format;
2868 IAudioMediaStream *audio_stream;
2869 IAMMultiMediaStream *mmstream;
2870 struct testfilter source;
2871 IGraphBuilder *graph;
2872 IMediaStream *stream;
2873 WAVEFORMATEX format;
2874 HRESULT hr;
2875 ULONG ref;
2876 IPin *pin;
2878 hr = set_audiostream_format(&valid_format);
2879 ok(hr == S_OK, "Got hr %#x.\n", hr);
2880 hr = set_audiostream_format(NULL);
2881 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
2883 extensible_format.Format = valid_format;
2884 extensible_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
2885 extensible_format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
2886 extensible_format.Samples.wValidBitsPerSample = valid_format.wBitsPerSample;
2887 extensible_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
2888 extensible_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
2889 hr = set_audiostream_format(&extensible_format.Format);
2890 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2892 format = valid_format;
2893 format.nBlockAlign = 1;
2894 hr = set_audiostream_format(&format);
2895 ok(hr == S_OK, "Got hr %#x.\n", hr);
2897 format = valid_format;
2898 format.nAvgBytesPerSec = 1234;
2899 hr = set_audiostream_format(&format);
2900 ok(hr == S_OK, "Got hr %#x.\n", hr);
2902 mmstream = create_ammultimediastream();
2904 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
2905 ok(hr == S_OK, "Got hr %#x.\n", hr);
2906 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
2907 ok(hr == S_OK, "Got hr %#x.\n", hr);
2909 hr = IAudioMediaStream_SetFormat(audio_stream, &valid_format);
2910 ok(hr == S_OK, "Got hr %#x.\n", hr);
2912 hr = IAudioMediaStream_GetFormat(audio_stream, &format);
2913 ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
2915 format = valid_format;
2916 format.nChannels = 1;
2917 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
2918 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2920 format = valid_format;
2921 format.nSamplesPerSec = 11025;
2922 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
2923 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2925 format = valid_format;
2926 format.nAvgBytesPerSec = 1234;
2927 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
2928 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2930 format = valid_format;
2931 format.nBlockAlign = 1;
2932 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
2933 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2935 format = valid_format;
2936 format.wBitsPerSample = 8;
2937 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
2938 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2940 format = valid_format;
2941 format.cbSize = 1;
2942 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
2943 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2945 hr = IAudioMediaStream_SetFormat(audio_stream, &valid_format);
2946 ok(hr == S_OK, "Got hr %#x.\n", hr);
2948 ref = IAMMultiMediaStream_Release(mmstream);
2949 ok(!ref, "Got outstanding refcount %d.\n", ref);
2950 IAudioMediaStream_Release(audio_stream);
2951 ref = IMediaStream_Release(stream);
2952 ok(!ref, "Got outstanding refcount %d.\n", ref);
2954 mmstream = create_ammultimediastream();
2956 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
2957 ok(hr == S_OK, "Got hr %#x.\n", hr);
2958 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
2959 ok(hr == S_OK, "Got hr %#x.\n", hr);
2960 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2961 ok(hr == S_OK, "Got hr %#x.\n", hr);
2963 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
2964 ok(hr == S_OK, "Got hr %#x.\n", hr);
2965 ok(!!graph, "Expected non-NULL graph.\n");
2967 testfilter_init(&source);
2969 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
2970 ok(hr == S_OK, "Got hr %#x.\n", hr);
2972 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
2973 ok(hr == S_OK, "Got hr %#x.\n", hr);
2975 format = valid_format;
2976 format.nChannels = 1;
2977 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
2978 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2980 hr = IGraphBuilder_Disconnect(graph, pin);
2981 ok(hr == S_OK, "Got hr %#x.\n", hr);
2982 hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
2983 ok(hr == S_OK, "Got hr %#x.\n", hr);
2985 format = valid_format;
2986 format.nChannels = 1;
2987 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
2988 ok(hr == S_OK, "Got hr %#x.\n", hr);
2990 ref = IAMMultiMediaStream_Release(mmstream);
2991 ok(!ref, "Got outstanding refcount %d.\n", ref);
2992 ref = IGraphBuilder_Release(graph);
2993 ok(!ref, "Got outstanding refcount %d.\n", ref);
2994 IPin_Release(pin);
2995 IAudioMediaStream_Release(audio_stream);
2996 ref = IMediaStream_Release(stream);
2997 ok(!ref, "Got outstanding refcount %d.\n", ref);
2998 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
2999 ok(!ref, "Got outstanding refcount %d.\n", ref);
3002 static void test_audiostream_receive_connection(void)
3004 WAVEFORMATEXTENSIBLE extensible_format;
3005 IAudioMediaStream *audio_stream;
3006 IAMMultiMediaStream *mmstream;
3007 struct testfilter source;
3008 IGraphBuilder *graph;
3009 IMediaStream *stream;
3010 WAVEFORMATEX format;
3011 AM_MEDIA_TYPE mt;
3012 HRESULT hr;
3013 ULONG ref;
3014 IPin *pin;
3016 mmstream = create_ammultimediastream();
3017 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3018 ok(hr == S_OK, "Got hr %#x.\n", hr);
3019 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3020 ok(hr == S_OK, "Got hr %#x.\n", hr);
3021 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3022 ok(hr == S_OK, "Got hr %#x.\n", hr);
3023 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3024 ok(hr == S_OK, "Got hr %#x.\n", hr);
3025 ok(graph != NULL, "Expected non-null graph\n");
3026 testfilter_init(&source);
3027 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3028 ok(hr == S_OK, "Got hr %#x.\n", hr);
3030 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3031 ok(hr == S_OK, "Got hr %#x.\n", hr);
3032 IGraphBuilder_Disconnect(graph, pin);
3033 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3035 mt = audio_mt;
3036 mt.majortype = GUID_NULL;
3037 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3038 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3040 mt = audio_mt;
3041 mt.subtype = MEDIASUBTYPE_RGB24;
3042 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3043 ok(hr == S_OK, "Got hr %#x.\n", hr);
3044 IGraphBuilder_Disconnect(graph, pin);
3045 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3047 mt = audio_mt;
3048 mt.formattype = GUID_NULL;
3049 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3050 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3052 mt = audio_mt;
3053 mt.cbFormat = sizeof(WAVEFORMATEX) - 1;
3054 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3055 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3057 extensible_format.Format = audio_format;
3058 extensible_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
3059 extensible_format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
3060 extensible_format.Samples.wValidBitsPerSample = audio_format.wBitsPerSample;
3061 extensible_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
3062 extensible_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
3063 mt = audio_mt;
3064 mt.cbFormat = sizeof(extensible_format);
3065 mt.pbFormat = (BYTE *)&extensible_format;
3066 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3067 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3069 hr = IAudioMediaStream_SetFormat(audio_stream, &audio_format);
3070 ok(hr == S_OK, "Got hr %#x.\n", hr);
3072 format = audio_format;
3073 format.nChannels = 2;
3074 mt = audio_mt;
3075 mt.pbFormat = (BYTE *)&format;
3076 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3077 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3079 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3080 ok(hr == S_OK, "Got hr %#x.\n", hr);
3081 IGraphBuilder_Disconnect(graph, pin);
3082 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3084 ref = IAMMultiMediaStream_Release(mmstream);
3085 ok(!ref, "Got outstanding refcount %d.\n", ref);
3086 ref = IGraphBuilder_Release(graph);
3087 ok(!ref, "Got outstanding refcount %d.\n", ref);
3088 IPin_Release(pin);
3089 IAudioMediaStream_Release(audio_stream);
3090 ref = IMediaStream_Release(stream);
3091 ok(!ref, "Got outstanding refcount %d.\n", ref);
3092 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
3093 ok(!ref, "Got outstanding refcount %d.\n", ref);
3096 static void test_audiostream_set_state(void)
3098 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3099 IAMMediaStream *am_stream;
3100 IMediaStream *stream;
3101 HRESULT hr;
3102 ULONG ref;
3104 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
3105 ok(hr == S_OK, "Got hr %#x.\n", hr);
3106 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3107 ok(hr == S_OK, "Got hr %#x.\n", hr);
3108 hr = IMediaStream_QueryInterface(stream, &IID_IAMMediaStream, (void **)&am_stream);
3109 ok(hr == S_OK, "Got hr %#x.\n", hr);
3111 hr = IAMMediaStream_SetState(am_stream, 4);
3112 ok(hr == S_OK, "Got hr %#x.\n", hr);
3114 hr = IAMMediaStream_SetState(am_stream, State_Running);
3115 ok(hr == S_OK, "Got hr %#x.\n", hr);
3117 hr = IAMMediaStream_SetState(am_stream, State_Paused);
3118 ok(hr == S_OK, "Got hr %#x.\n", hr);
3120 hr = IAMMediaStream_SetState(am_stream, State_Stopped);
3121 ok(hr == S_OK, "Got hr %#x.\n", hr);
3123 ref = IAMMultiMediaStream_Release(mmstream);
3124 ok(!ref, "Got outstanding refcount %d.\n", ref);
3125 IAMMediaStream_Release(am_stream);
3126 ref = IMediaStream_Release(stream);
3127 ok(!ref, "Got outstanding refcount %d.\n", ref);
3130 void test_audiostream_end_of_stream(void)
3132 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3133 struct testfilter source;
3134 IGraphBuilder *graph;
3135 IMediaStream *stream;
3136 HRESULT hr;
3137 ULONG ref;
3138 IPin *pin;
3140 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
3141 ok(hr == S_OK, "Got hr %#x.\n", hr);
3142 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3143 ok(hr == S_OK, "Got hr %#x.\n", hr);
3144 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3145 ok(hr == S_OK, "Got hr %#x.\n", hr);
3146 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3147 ok(hr == S_OK, "Got hr %#x.\n", hr);
3148 ok(!!graph, "Expected non-NULL graph.\n");
3149 testfilter_init(&source);
3150 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3151 ok(hr == S_OK, "Got hr %#x.\n", hr);
3153 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3154 ok(hr == S_OK, "Got hr %#x.\n", hr);
3156 hr = IPin_EndOfStream(pin);
3157 ok(hr == S_OK, "Got hr %#x.\n", hr);
3159 hr = IPin_EndOfStream(pin);
3160 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
3162 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3163 ok(hr == S_OK, "Got hr %#x.\n", hr);
3165 hr = IPin_EndOfStream(pin);
3166 ok(hr == S_OK, "Got hr %#x.\n", hr);
3168 hr = IPin_EndOfStream(pin);
3169 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
3171 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3172 ok(hr == S_OK, "Got hr %#x.\n", hr);
3174 hr = IPin_EndOfStream(pin);
3175 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
3177 IGraphBuilder_Disconnect(graph, pin);
3178 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3180 ref = IAMMultiMediaStream_Release(mmstream);
3181 ok(!ref, "Got outstanding refcount %d.\n", ref);
3182 ref = IGraphBuilder_Release(graph);
3183 ok(!ref, "Got outstanding refcount %d.\n", ref);
3184 IPin_Release(pin);
3185 ref = IMediaStream_Release(stream);
3186 ok(!ref, "Got outstanding refcount %d.\n", ref);
3189 static void test_audiostream_receive(void)
3191 ALLOCATOR_PROPERTIES properties =
3193 .cBuffers = 3,
3194 .cbBuffer = 16,
3195 .cbAlign = 1,
3198 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3199 ALLOCATOR_PROPERTIES actual;
3200 struct testfilter source;
3201 IMemAllocator *allocator;
3202 IGraphBuilder *graph;
3203 IMediaStream *stream;
3204 IMediaSample *sample1;
3205 IMediaSample *sample2;
3206 IMediaSample *sample3;
3207 HRESULT hr;
3208 ULONG ref;
3209 IPin *pin;
3211 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
3212 ok(hr == S_OK, "Got hr %#x.\n", hr);
3213 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3214 ok(hr == S_OK, "Got hr %#x.\n", hr);
3215 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3216 ok(hr == S_OK, "Got hr %#x.\n", hr);
3217 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3218 ok(hr == S_OK, "Got hr %#x.\n", hr);
3219 ok(graph != NULL, "Expected non-NULL graph.\n");
3220 testfilter_init(&source);
3221 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3222 ok(hr == S_OK, "Got hr %#x.\n", hr);
3223 hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (void **)&allocator);
3224 ok(hr == S_OK, "Got hr %#x.\n", hr);
3225 hr = IMemAllocator_SetProperties(allocator, &properties, &actual);
3226 ok(hr == S_OK, "Got hr %#x.\n", hr);
3227 hr = IMemAllocator_Commit(allocator);
3228 ok(hr == S_OK, "Got hr %#x.\n", hr);
3230 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3231 ok(hr == S_OK, "Got hr %#x.\n", hr);
3233 hr = IMemAllocator_GetBuffer(allocator, &sample1, NULL, NULL, 0);
3234 ok(hr == S_OK, "Got hr %#x.\n", hr);
3235 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample1);
3236 ok(hr == VFW_E_WRONG_STATE, "Got hr %#x.\n", hr);
3237 ref = IMediaSample_Release(sample1);
3238 ok(!ref, "Got outstanding refcount %d.\n", ref);
3240 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3241 ok(hr == S_OK, "Got hr %#x.\n", hr);
3243 hr = IMemAllocator_GetBuffer(allocator, &sample1, NULL, NULL, 0);
3244 ok(hr == S_OK, "Got hr %#x.\n", hr);
3245 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample1);
3246 ok(hr == S_OK, "Got hr %#x.\n", hr);
3247 ref = get_refcount(sample1);
3248 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
3250 hr = IMemAllocator_GetBuffer(allocator, &sample2, NULL, NULL, 0);
3251 ok(hr == S_OK, "Got hr %#x.\n", hr);
3252 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample2);
3253 ok(hr == S_OK, "Got hr %#x.\n", hr);
3254 ref = get_refcount(sample2);
3255 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
3257 hr = IPin_EndOfStream(pin);
3258 ok(hr == S_OK, "Got hr %#x.\n", hr);
3260 hr = IMemAllocator_GetBuffer(allocator, &sample3, NULL, NULL, 0);
3261 ok(hr == S_OK, "Got hr %#x.\n", hr);
3262 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample3);
3263 ok(hr == S_OK, "Got hr %#x.\n", hr);
3264 ref = get_refcount(sample3);
3265 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
3267 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3268 ok(hr == S_OK, "Got hr %#x.\n", hr);
3270 ref = IMediaSample_Release(sample1);
3271 ok(!ref, "Got outstanding refcount %d.\n", ref);
3272 ref = IMediaSample_Release(sample2);
3273 ok(!ref, "Got outstanding refcount %d.\n", ref);
3274 ref = IMediaSample_Release(sample3);
3275 ok(!ref, "Got outstanding refcount %d.\n", ref);
3277 hr = IMemAllocator_GetBuffer(allocator, &sample1, NULL, NULL, 0);
3278 ok(hr == S_OK, "Got hr %#x.\n", hr);
3279 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample1);
3280 ok(hr == VFW_E_WRONG_STATE, "Got hr %#x.\n", hr);
3281 ref = IMediaSample_Release(sample1);
3282 ok(!ref, "Got outstanding refcount %d.\n", ref);
3284 IGraphBuilder_Disconnect(graph, pin);
3285 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3287 hr = IMemAllocator_Decommit(allocator);
3288 ok(hr == S_OK, "Got hr %#x.\n", hr);
3290 ref = IAMMultiMediaStream_Release(mmstream);
3291 ok(!ref, "Got outstanding refcount %d.\n", ref);
3292 ref = IGraphBuilder_Release(graph);
3293 ok(!ref, "Got outstanding refcount %d.\n", ref);
3294 IPin_Release(pin);
3295 ref = IMediaStream_Release(stream);
3296 ok(!ref, "Got outstanding refcount %d.\n", ref);
3297 ref = IMemAllocator_Release(allocator);
3298 ok(!ref, "Got outstanding refcount %d.\n", ref);
3301 static void test_audiostream_initialize(void)
3303 IAMMediaStream *stream;
3304 STREAM_TYPE type;
3305 MSPID mspid;
3306 HRESULT hr;
3307 ULONG ref;
3309 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
3310 ok(hr == S_OK, "Got hr %#x.\n", hr);
3312 /* Crashes on native. */
3313 if (0)
3315 hr = IAMMediaStream_Initialize(stream, NULL, 0, NULL, STREAMTYPE_WRITE);
3316 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
3319 hr = IAMMediaStream_Initialize(stream, NULL, 0, &test_mspid, STREAMTYPE_WRITE);
3320 ok(hr == S_OK, "Got hr %#x.\n", hr);
3322 hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
3323 ok(hr == S_OK, "Got hr %#x.\n", hr);
3324 ok(IsEqualGUID(&mspid, &test_mspid), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
3325 ok(type == STREAMTYPE_WRITE, "Got type %u.\n", type);
3327 hr = IAMMediaStream_Initialize(stream, NULL, 0, &MSPID_PrimaryAudio, STREAMTYPE_READ);
3328 ok(hr == S_OK, "Got hr %#x.\n", hr);
3330 hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
3331 ok(hr == S_OK, "Got hr %#x.\n", hr);
3332 ok(IsEqualGUID(&mspid, &MSPID_PrimaryAudio), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
3333 ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
3335 ref = IAMMediaStream_Release(stream);
3336 ok(!ref, "Got outstanding refcount %d.\n", ref);
3339 static void test_audiostream_begin_flush_end_flush(void)
3341 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3342 IAudioStreamSample *stream_sample;
3343 IAudioMediaStream *audio_stream;
3344 IMediaSample *media_sample;
3345 struct testfilter source;
3346 IAudioData *audio_data;
3347 IGraphBuilder *graph;
3348 IMediaStream *stream;
3349 HRESULT hr;
3350 ULONG ref;
3351 IPin *pin;
3353 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
3354 ok(hr == S_OK, "Got hr %#x.\n", hr);
3355 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3356 ok(hr == S_OK, "Got hr %#x.\n", hr);
3357 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3358 ok(hr == S_OK, "Got hr %#x.\n", hr);
3359 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3360 ok(hr == S_OK, "Got hr %#x.\n", hr);
3361 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3362 ok(hr == S_OK, "Got hr %#x.\n", hr);
3363 ok(graph != NULL, "Expected non-NULL graph.\n");
3364 testfilter_init(&source);
3365 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3366 ok(hr == S_OK, "Got hr %#x.\n", hr);
3367 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
3368 ok(hr == S_OK, "Got hr %#x.\n", hr);
3369 hr = IAudioData_SetBuffer(audio_data, 16, NULL, 0);
3370 ok(hr == S_OK, "Got hr %#x.\n", hr);
3371 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
3372 ok(hr == S_OK, "Got hr %#x.\n", hr);
3374 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3375 ok(hr == S_OK, "Got hr %#x.\n", hr);
3377 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3378 ok(hr == S_OK, "Got hr %#x.\n", hr);
3380 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source.source, &media_sample, NULL, NULL, 0);
3381 ok(hr == S_OK, "Got hr %#x.\n", hr);
3382 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
3383 ok(hr == S_OK, "Got hr %#x.\n", hr);
3384 ref = get_refcount(media_sample);
3385 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
3387 hr = IPin_EndOfStream(pin);
3388 ok(hr == S_OK, "Got hr %#x.\n", hr);
3390 hr = IPin_BeginFlush(pin);
3391 ok(hr == S_OK, "Got hr %#x.\n", hr);
3393 ref = IMediaSample_Release(media_sample);
3394 ok(!ref, "Got outstanding refcount %d.\n", ref);
3396 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source.source, &media_sample, NULL, NULL, 0);
3397 ok(hr == S_OK, "Got hr %#x.\n", hr);
3398 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
3399 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
3401 ref = IMediaSample_Release(media_sample);
3402 ok(!ref, "Got outstanding refcount %d.\n", ref);
3404 hr = IAudioStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
3405 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
3407 hr = IPin_EndOfStream(pin);
3408 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
3410 hr = IPin_EndFlush(pin);
3411 ok(hr == S_OK, "Got hr %#x.\n", hr);
3413 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source.source, &media_sample, NULL, NULL, 0);
3414 ok(hr == S_OK, "Got hr %#x.\n", hr);
3415 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
3416 ok(hr == S_OK, "Got hr %#x.\n", hr);
3417 ref = IMediaSample_Release(media_sample);
3418 ok(ref == 1, "Got outstanding refcount %d.\n", ref);
3420 hr = IPin_EndOfStream(pin);
3421 ok(hr == S_OK, "Got hr %#x.\n", hr);
3423 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3424 ok(hr == S_OK, "Got hr %#x.\n", hr);
3426 IGraphBuilder_Disconnect(graph, pin);
3427 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3429 ref = IAudioStreamSample_Release(stream_sample);
3430 ok(!ref, "Got outstanding refcount %d.\n", ref);
3431 ref = IAudioData_Release(audio_data);
3432 ok(!ref, "Got outstanding refcount %d.\n", ref);
3433 ref = IAMMultiMediaStream_Release(mmstream);
3434 ok(!ref, "Got outstanding refcount %d.\n", ref);
3435 ref = IGraphBuilder_Release(graph);
3436 ok(!ref, "Got outstanding refcount %d.\n", ref);
3437 IPin_Release(pin);
3438 IAudioMediaStream_Release(audio_stream);
3439 ref = IMediaStream_Release(stream);
3440 ok(!ref, "Got outstanding refcount %d.\n", ref);
3443 static IMediaSample *audiostream_allocate_sample(struct testfilter *source, const BYTE *input_data, DWORD input_length)
3445 IMediaSample *sample;
3446 BYTE *sample_data;
3447 HRESULT hr;
3449 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source->source, &sample, NULL, NULL, 0);
3450 ok(hr == S_OK, "Got hr %#x.\n", hr);
3452 hr = IMediaSample_GetPointer(sample, &sample_data);
3453 ok(hr == S_OK, "Got hr %#x.\n", hr);
3455 hr = IMediaSample_SetActualDataLength(sample, input_length);
3456 ok(hr == S_OK, "Got hr %#x.\n", hr);
3458 memcpy(sample_data, input_data, input_length);
3460 return sample;
3463 static void test_audiostream_new_segment(void)
3465 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3466 static const BYTE test_data[8] = { 0 };
3467 IAudioStreamSample *stream_sample;
3468 IAudioMediaStream *audio_stream;
3469 IMemInputPin *mem_input_pin;
3470 IMediaSample *media_sample;
3471 struct testfilter source;
3472 IAudioData *audio_data;
3473 STREAM_TIME start_time;
3474 STREAM_TIME end_time;
3475 IGraphBuilder *graph;
3476 IMediaStream *stream;
3477 HRESULT hr;
3478 ULONG ref;
3479 IPin *pin;
3481 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
3482 ok(hr == S_OK, "Got hr %#x.\n", hr);
3483 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3484 ok(hr == S_OK, "Got hr %#x.\n", hr);
3485 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3486 ok(hr == S_OK, "Got hr %#x.\n", hr);
3487 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3488 ok(hr == S_OK, "Got hr %#x.\n", hr);
3489 hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
3490 ok(hr == S_OK, "Got hr %#x.\n", hr);
3491 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3492 ok(hr == S_OK, "Got hr %#x.\n", hr);
3493 ok(graph != NULL, "Expected non-NULL graph.\n");
3494 testfilter_init(&source);
3495 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3496 ok(hr == S_OK, "Got hr %#x.\n", hr);
3497 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
3498 ok(hr == S_OK, "Got hr %#x.\n", hr);
3499 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
3500 ok(hr == S_OK, "Got hr %#x.\n", hr);
3501 hr = IAudioData_SetBuffer(audio_data, 5, NULL, 0);
3502 ok(hr == S_OK, "Got hr %#x.\n", hr);
3504 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3505 ok(hr == S_OK, "Got hr %#x.\n", hr);
3506 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3507 ok(hr == S_OK, "Got hr %#x.\n", hr);
3509 hr = IPin_NewSegment(pin, 11111111, 22222222, 1.0);
3510 ok(hr == S_OK, "Got hr %#x.\n", hr);
3512 media_sample = audiostream_allocate_sample(&source, test_data, 5);
3513 start_time = 12345678;
3514 end_time = 23456789;
3515 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
3516 ok(hr == S_OK, "Got hr %#x.\n", hr);
3517 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
3518 ok(hr == S_OK, "Got hr %#x.\n", hr);
3519 IMediaSample_Release(media_sample);
3521 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3522 ok(hr == S_OK, "Got hr %#x.\n", hr);
3524 start_time = 0xdeadbeefdeadbeef;
3525 end_time = 0xdeadbeefdeadbeef;
3526 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
3527 ok(hr == S_OK, "Got hr %#x.\n", hr);
3528 ok(start_time == 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
3529 ok(end_time == 23459057, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
3531 hr = IPin_NewSegment(pin, 11111111, 22222222, 2.0);
3532 ok(hr == S_OK, "Got hr %#x.\n", hr);
3534 media_sample = audiostream_allocate_sample(&source, test_data, 5);
3535 start_time = 12345678;
3536 end_time = 23456789;
3537 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
3538 ok(hr == S_OK, "Got hr %#x.\n", hr);
3539 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
3540 ok(hr == S_OK, "Got hr %#x.\n", hr);
3541 IMediaSample_Release(media_sample);
3543 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3544 ok(hr == S_OK, "Got hr %#x.\n", hr);
3546 start_time = 0xdeadbeefdeadbeef;
3547 end_time = 0xdeadbeefdeadbeef;
3548 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
3549 ok(hr == S_OK, "Got hr %#x.\n", hr);
3550 ok(start_time == 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
3551 ok(end_time == 23459057, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
3553 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3554 ok(hr == S_OK, "Got hr %#x.\n", hr);
3555 IGraphBuilder_Disconnect(graph, pin);
3556 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3558 ref = IAudioStreamSample_Release(stream_sample);
3559 ok(!ref, "Got outstanding refcount %d.\n", ref);
3560 ref = IAudioData_Release(audio_data);
3561 ok(!ref, "Got outstanding refcount %d.\n", ref);
3562 ref = IAMMultiMediaStream_Release(mmstream);
3563 ok(!ref, "Got outstanding refcount %d.\n", ref);
3564 ref = IGraphBuilder_Release(graph);
3565 ok(!ref, "Got outstanding refcount %d.\n", ref);
3566 IPin_Release(pin);
3567 IMemInputPin_Release(mem_input_pin);
3568 IAudioMediaStream_Release(audio_stream);
3569 ref = IMediaStream_Release(stream);
3570 ok(!ref, "Got outstanding refcount %d.\n", ref);
3573 static void CALLBACK apc_func(ULONG_PTR param)
3577 static IPin *audiostream_pin;
3578 static IMemInputPin *audiostream_mem_input_pin;
3579 static IMediaSample *audiostream_media_sample;
3581 static DWORD CALLBACK audiostream_end_of_stream(void *param)
3583 HRESULT hr;
3585 Sleep(100);
3586 hr = IPin_EndOfStream(audiostream_pin);
3587 ok(hr == S_OK, "Got hr %#x.\n", hr);
3589 return 0;
3592 static DWORD CALLBACK audiostream_receive(void *param)
3594 HRESULT hr;
3596 Sleep(100);
3597 hr = IMemInputPin_Receive(audiostream_mem_input_pin, audiostream_media_sample);
3598 ok(hr == S_OK, "Got hr %#x.\n", hr);
3600 return 0;
3603 static void test_audiostreamsample_update(void)
3605 static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
3606 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3607 IAudioStreamSample *stream_sample;
3608 IAudioMediaStream *audio_stream;
3609 IMediaControl *media_control;
3610 IMemInputPin *mem_input_pin;
3611 IMediaSample *media_sample1;
3612 IMediaSample *media_sample2;
3613 struct testfilter source;
3614 IAudioData *audio_data;
3615 IGraphBuilder *graph;
3616 IMediaStream *stream;
3617 DWORD actual_length;
3618 BYTE buffer[6];
3619 HANDLE thread;
3620 HANDLE event;
3621 HRESULT hr;
3622 ULONG ref;
3623 IPin *pin;
3625 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
3626 ok(hr == S_OK, "Got hr %#x.\n", hr);
3627 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3628 ok(hr == S_OK, "Got hr %#x.\n", hr);
3629 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3630 ok(hr == S_OK, "Got hr %#x.\n", hr);
3631 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3632 ok(hr == S_OK, "Got hr %#x.\n", hr);
3633 hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
3634 ok(hr == S_OK, "Got hr %#x.\n", hr);
3635 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3636 ok(hr == S_OK, "Got hr %#x.\n", hr);
3637 ok(graph != NULL, "Expected non-NULL graph.\n");
3638 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
3639 ok(hr == S_OK, "Got hr %#x.\n", hr);
3640 testfilter_init(&source);
3641 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3642 ok(hr == S_OK, "Got hr %#x.\n", hr);
3643 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
3644 ok(hr == S_OK, "Got hr %#x.\n", hr);
3645 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
3646 ok(hr == S_OK, "Got hr %#x.\n", hr);
3647 event = CreateEventW(NULL, FALSE, FALSE, NULL);
3648 ok(event != NULL, "Expected non-NULL event.");
3650 hr = IAudioStreamSample_Update(stream_sample, 0, event, apc_func, 0);
3651 ok(hr == MS_E_NOTINIT, "Got hr %#x.\n", hr);
3653 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3654 ok(hr == MS_E_NOTINIT, "Got hr %#x.\n", hr);
3656 hr = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
3657 ok(hr == S_OK, "Got hr %#x.\n", hr);
3659 hr = IAudioStreamSample_Update(stream_sample, 0, event, apc_func, 0);
3660 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3662 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3663 ok(hr == MS_E_NOTRUNNING, "Got hr %#x.\n", hr);
3665 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3666 ok(hr == S_OK, "Got hr %#x.\n", hr);
3668 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3669 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
3671 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3672 ok(hr == S_OK, "Got hr %#x.\n", hr);
3673 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3674 ok(hr == S_OK, "Got hr %#x.\n", hr);
3675 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3676 ok(hr == S_OK, "Got hr %#x.\n", hr);
3678 media_sample1 = audiostream_allocate_sample(&source, test_data, 8);
3679 hr = IMemInputPin_Receive(mem_input_pin, media_sample1);
3680 ok(hr == S_OK, "Got hr %#x.\n", hr);
3681 ref = get_refcount(media_sample1);
3682 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
3684 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3685 ok(hr == S_OK, "Got hr %#x.\n", hr);
3687 hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
3688 ok(hr == S_OK, "Got hr %#x.\n", hr);
3689 ok(actual_length == 6, "Got actual length %u.\n", actual_length);
3691 ok(memcmp(buffer, test_data, 6) == 0, "Sample data didn't match.\n");
3693 ref = get_refcount(media_sample1);
3694 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
3696 media_sample2 = audiostream_allocate_sample(&source, test_data, 8);
3697 hr = IMemInputPin_Receive(mem_input_pin, media_sample2);
3698 ok(hr == S_OK, "Got hr %#x.\n", hr);
3699 ref = get_refcount(media_sample2);
3700 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
3702 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3703 ok(hr == S_OK, "Got hr %#x.\n", hr);
3705 hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
3706 ok(hr == S_OK, "Got hr %#x.\n", hr);
3707 ok(actual_length == 6, "Got actual length %u.\n", actual_length);
3709 ok(memcmp(buffer, &test_data[6], 2) == 0, "Sample data didn't match.\n");
3710 ok(memcmp(&buffer[2], test_data, 4) == 0, "Sample data didn't match.\n");
3712 ref = IMediaSample_Release(media_sample1);
3713 ok(!ref, "Got outstanding refcount %d.\n", ref);
3715 hr = IPin_EndOfStream(pin);
3716 ok(hr == S_OK, "Got hr %#x.\n", hr);
3718 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3719 ok(hr == S_OK, "Got hr %#x.\n", hr);
3721 hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
3722 ok(hr == S_OK, "Got hr %#x.\n", hr);
3723 ok(actual_length == 4, "Got actual length %u.\n", actual_length);
3725 ok(memcmp(buffer, &test_data[4], 4) == 0, "Sample data didn't match.\n");
3727 ref = IMediaSample_Release(media_sample2);
3728 ok(!ref, "Got outstanding refcount %d.\n", ref);
3730 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3731 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
3733 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3734 ok(hr == S_OK, "Got hr %#x.\n", hr);
3735 hr = IMediaControl_Pause(media_control);
3736 ok(hr == S_OK, "Got hr %#x.\n", hr);
3738 media_sample1 = audiostream_allocate_sample(&source, test_data, 6);
3739 hr = IMemInputPin_Receive(mem_input_pin, media_sample1);
3740 ok(hr == S_OK, "Got hr %#x.\n", hr);
3741 ref = IMediaSample_Release(media_sample1);
3742 ok(ref == 1, "Got outstanding refcount %d.\n", ref);
3744 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3745 ok(hr == MS_E_NOTRUNNING, "Got hr %#x.\n", hr);
3747 hr = IMediaControl_Stop(media_control);
3748 ok(hr == S_OK, "Got hr %#x.\n", hr);
3749 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3750 ok(hr == S_OK, "Got hr %#x.\n", hr);
3752 media_sample1 = audiostream_allocate_sample(&source, test_data, 6);
3754 audiostream_mem_input_pin = mem_input_pin;
3755 audiostream_media_sample = media_sample1;
3756 thread = CreateThread(NULL, 0, audiostream_receive, NULL, 0, NULL);
3758 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3759 ok(hr == S_OK, "Got hr %#x.\n", hr);
3761 hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
3762 ok(hr == S_OK, "Got hr %#x.\n", hr);
3763 ok(actual_length == 6, "Got actual length %u.\n", actual_length);
3765 ok(memcmp(buffer, test_data, 6) == 0, "Sample data didn't match.\n");
3767 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
3768 CloseHandle(thread);
3770 ref = IMediaSample_Release(media_sample1);
3771 ok(!ref, "Got outstanding refcount %d.\n", ref);
3773 audiostream_pin = pin;
3774 thread = CreateThread(NULL, 0, audiostream_end_of_stream, NULL, 0, NULL);
3776 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3777 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
3779 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
3780 CloseHandle(thread);
3782 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3783 ok(hr == S_OK, "Got hr %#x.\n", hr);
3784 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3785 ok(hr == S_OK, "Got hr %#x.\n", hr);
3787 hr = IAudioStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
3788 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
3790 IAudioStreamSample_AddRef(stream_sample);
3791 ref = IAudioStreamSample_Release(stream_sample);
3792 ok(ref == 1, "Got outstanding refcount %d.\n", ref);
3794 hr = IAudioStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
3795 ok(hr == MS_E_BUSY, "Got hr %#x.\n", hr);
3797 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3798 ok(hr == S_OK, "Got hr %#x.\n", hr);
3799 IGraphBuilder_Disconnect(graph, pin);
3800 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3801 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3802 ok(hr == S_OK, "Got hr %#x.\n", hr);
3804 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
3805 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
3807 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3809 CloseHandle(event);
3810 ref = IAudioStreamSample_Release(stream_sample);
3811 ok(!ref, "Got outstanding refcount %d.\n", ref);
3812 ref = IAudioData_Release(audio_data);
3813 ok(!ref, "Got outstanding refcount %d.\n", ref);
3814 ref = IAMMultiMediaStream_Release(mmstream);
3815 ok(!ref, "Got outstanding refcount %d.\n", ref);
3816 IMediaControl_Release(media_control);
3817 ref = IGraphBuilder_Release(graph);
3818 ok(!ref, "Got outstanding refcount %d.\n", ref);
3819 IPin_Release(pin);
3820 IMemInputPin_Release(mem_input_pin);
3821 IAudioMediaStream_Release(audio_stream);
3822 ref = IMediaStream_Release(stream);
3823 ok(!ref, "Got outstanding refcount %d.\n", ref);
3826 void test_audiostreamsample_completion_status(void)
3828 static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
3829 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3830 IAudioStreamSample *stream_sample1;
3831 IAudioStreamSample *stream_sample2;
3832 IAudioMediaStream *audio_stream;
3833 IMediaSample *media_sample;
3834 struct testfilter source;
3835 IAudioData *audio_data1;
3836 IAudioData *audio_data2;
3837 IGraphBuilder *graph;
3838 IMediaStream *stream;
3839 HANDLE event;
3840 HRESULT hr;
3841 ULONG ref;
3842 IPin *pin;
3844 event = CreateEventW(NULL, FALSE, FALSE, NULL);
3845 ok(event != NULL, "Expected non-NULL event.");
3847 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
3848 ok(hr == S_OK, "Got hr %#x.\n", hr);
3849 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3850 ok(hr == S_OK, "Got hr %#x.\n", hr);
3851 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3852 ok(hr == S_OK, "Got hr %#x.\n", hr);
3853 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3854 ok(hr == S_OK, "Got hr %#x.\n", hr);
3855 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3856 ok(hr == S_OK, "Got hr %#x.\n", hr);
3857 ok(graph != NULL, "Expected non-NULL graph.\n");
3858 testfilter_init(&source);
3859 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3860 ok(hr == S_OK, "Got hr %#x.\n", hr);
3861 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data1);
3862 ok(hr == S_OK, "Got hr %#x.\n", hr);
3863 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data2);
3864 ok(hr == S_OK, "Got hr %#x.\n", hr);
3865 hr = IAudioData_SetBuffer(audio_data1, 6, NULL, 0);
3866 ok(hr == S_OK, "Got hr %#x.\n", hr);
3867 hr = IAudioData_SetBuffer(audio_data2, 6, NULL, 0);
3868 ok(hr == S_OK, "Got hr %#x.\n", hr);
3869 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data1, 0, &stream_sample1);
3870 ok(hr == S_OK, "Got hr %#x.\n", hr);
3871 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data2, 0, &stream_sample2);
3872 ok(hr == S_OK, "Got hr %#x.\n", hr);
3874 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3875 ok(hr == S_OK, "Got hr %#x.\n", hr);
3876 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3877 ok(hr == S_OK, "Got hr %#x.\n", hr);
3879 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
3880 ok(hr == S_OK, "Got hr %#x.\n", hr);
3882 hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
3883 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
3885 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
3886 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
3888 media_sample = audiostream_allocate_sample(&source, test_data, 6);
3889 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
3890 ok(hr == S_OK, "Got hr %#x.\n", hr);
3891 ref = IMediaSample_Release(media_sample);
3892 ok(!ref, "Got outstanding refcount %d.\n", ref);
3894 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
3895 ok(hr == S_OK, "Got hr %#x.\n", hr);
3897 hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
3898 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
3900 hr = IAudioStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
3901 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
3903 media_sample = audiostream_allocate_sample(&source, test_data, 12);
3904 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
3905 ok(hr == S_OK, "Got hr %#x.\n", hr);
3906 ref = IMediaSample_Release(media_sample);
3907 ok(!ref, "Got outstanding refcount %d.\n", ref);
3909 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
3910 ok(hr == S_OK, "Got hr %#x.\n", hr);
3912 hr = IAudioStreamSample_CompletionStatus(stream_sample2, 0, 0);
3913 ok(hr == S_OK, "Got hr %#x.\n", hr);
3915 hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
3916 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
3918 hr = IPin_EndOfStream(pin);
3919 ok(hr == S_OK, "Got hr %#x.\n", hr);
3921 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
3922 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
3924 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3925 ok(hr == S_OK, "Got hr %#x.\n", hr);
3926 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3927 ok(hr == S_OK, "Got hr %#x.\n", hr);
3929 hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
3930 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
3932 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3933 ok(hr == S_OK, "Got hr %#x.\n", hr);
3935 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
3936 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
3938 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3939 ok(hr == S_OK, "Got hr %#x.\n", hr);
3941 media_sample = audiostream_allocate_sample(&source, test_data, 6);
3942 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
3943 ok(hr == S_OK, "Got hr %#x.\n", hr);
3944 ref = IMediaSample_Release(media_sample);
3945 ok(!ref, "Got outstanding refcount %d.\n", ref);
3947 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
3948 ok(hr == S_OK, "Got hr %#x.\n", hr);
3950 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3951 ok(hr == S_OK, "Got hr %#x.\n", hr);
3953 IGraphBuilder_Disconnect(graph, pin);
3954 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3956 ref = IAudioStreamSample_Release(stream_sample1);
3957 ok(!ref, "Got outstanding refcount %d.\n", ref);
3958 ref = IAudioStreamSample_Release(stream_sample2);
3959 ok(!ref, "Got outstanding refcount %d.\n", ref);
3960 ref = IAudioData_Release(audio_data1);
3961 ok(!ref, "Got outstanding refcount %d.\n", ref);
3962 ref = IAudioData_Release(audio_data2);
3963 ok(!ref, "Got outstanding refcount %d.\n", ref);
3964 ref = IAMMultiMediaStream_Release(mmstream);
3965 ok(!ref, "Got outstanding refcount %d.\n", ref);
3966 ref = IGraphBuilder_Release(graph);
3967 ok(!ref, "Got outstanding refcount %d.\n", ref);
3968 IPin_Release(pin);
3969 IAudioMediaStream_Release(audio_stream);
3970 ref = IMediaStream_Release(stream);
3971 ok(!ref, "Got outstanding refcount %d.\n", ref);
3973 CloseHandle(event);
3976 static void test_audiostreamsample_get_sample_times(void)
3978 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3979 static const BYTE test_data[8] = { 0 };
3980 IAudioStreamSample *stream_sample;
3981 IMediaFilter *graph_media_filter;
3982 IAudioMediaStream *audio_stream;
3983 STREAM_TIME filter_start_time;
3984 IMemInputPin *mem_input_pin;
3985 IMediaStreamFilter *filter;
3986 IMediaSample *media_sample;
3987 struct testfilter source;
3988 STREAM_TIME current_time;
3989 struct testclock clock;
3990 IAudioData *audio_data;
3991 STREAM_TIME start_time;
3992 STREAM_TIME end_time;
3993 IGraphBuilder *graph;
3994 IMediaStream *stream;
3995 HRESULT hr;
3996 ULONG ref;
3997 IPin *pin;
3999 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4000 ok(hr == S_OK, "Got hr %#x.\n", hr);
4001 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
4002 ok(hr == S_OK, "Got hr %#x.\n", hr);
4003 ok(!!filter, "Expected non-null filter.\n");
4004 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
4005 ok(hr == S_OK, "Got hr %#x.\n", hr);
4006 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
4007 ok(hr == S_OK, "Got hr %#x.\n", hr);
4008 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4009 ok(hr == S_OK, "Got hr %#x.\n", hr);
4010 hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
4011 ok(hr == S_OK, "Got hr %#x.\n", hr);
4012 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4013 ok(hr == S_OK, "Got hr %#x.\n", hr);
4014 ok(graph != NULL, "Expected non-NULL graph.\n");
4015 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&graph_media_filter);
4016 ok(hr == S_OK, "Got hr %#x.\n", hr);
4017 testfilter_init(&source);
4018 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
4019 ok(hr == S_OK, "Got hr %#x.\n", hr);
4020 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
4021 ok(hr == S_OK, "Got hr %#x.\n", hr);
4022 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
4023 ok(hr == S_OK, "Got hr %#x.\n", hr);
4024 hr = IAudioData_SetBuffer(audio_data, 5, NULL, 0);
4025 ok(hr == S_OK, "Got hr %#x.\n", hr);
4026 testclock_init(&clock);
4028 clock.time = 12345678;
4030 current_time = 0xdeadbeefdeadbeef;
4031 hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
4032 ok(hr == S_OK, "Got hr %#x.\n", hr);
4033 ok(current_time == 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time));
4035 IMediaFilter_SetSyncSource(graph_media_filter, &clock.IReferenceClock_iface);
4036 ok(hr == S_OK, "Got hr %#x.\n", hr);
4038 current_time = 0xdeadbeefdeadbeef;
4039 hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
4040 ok(hr == S_OK, "Got hr %#x.\n", hr);
4041 ok(current_time == 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time));
4043 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
4044 ok(hr == S_OK, "Got hr %#x.\n", hr);
4045 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4046 ok(hr == S_OK, "Got hr %#x.\n", hr);
4048 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &filter_start_time);
4049 ok(hr == S_OK, "Got hr %#x.\n", hr);
4051 clock.get_time_hr = E_FAIL;
4053 current_time = 0xdeadbeefdeadbeef;
4054 hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
4055 ok(hr == S_OK, "Got hr %#x.\n", hr);
4056 ok(current_time == 0xdeadbeefddf15da1 + filter_start_time, "Expected current time %s, got %s.\n",
4057 wine_dbgstr_longlong(0xdeadbeefddf15da1 + filter_start_time), wine_dbgstr_longlong(current_time));
4059 clock.get_time_hr = S_OK;
4061 current_time = 0xdeadbeefdeadbeef;
4062 hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
4063 ok(hr == S_OK, "Got hr %#x.\n", hr);
4064 ok(current_time == filter_start_time, "Expected current time %s, got %s.\n",
4065 wine_dbgstr_longlong(filter_start_time), wine_dbgstr_longlong(current_time));
4067 clock.time = 23456789;
4069 current_time = 0xdeadbeefdeadbeef;
4070 hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
4071 ok(hr == S_OK, "Got hr %#x.\n", hr);
4072 ok(current_time == filter_start_time + 11111111, "Expected current time %s, got %s.\n",
4073 wine_dbgstr_longlong(filter_start_time + 11111111), wine_dbgstr_longlong(current_time));
4075 start_time = 0xdeadbeefdeadbeef;
4076 end_time = 0xdeadbeefdeadbeef;
4077 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4078 ok(hr == S_OK, "Got hr %#x.\n", hr);
4079 ok(start_time == 0, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4080 ok(end_time == 0, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4082 media_sample = audiostream_allocate_sample(&source, test_data, 8);
4083 start_time = 12345678;
4084 end_time = 23456789;
4085 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
4086 ok(hr == S_OK, "Got hr %#x.\n", hr);
4087 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
4088 ok(hr == S_OK, "Got hr %#x.\n", hr);
4089 IMediaSample_Release(media_sample);
4091 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4092 ok(hr == S_OK, "Got hr %#x.\n", hr);
4094 start_time = 0xdeadbeefdeadbeef;
4095 end_time = 0xdeadbeefdeadbeef;
4096 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4097 ok(hr == S_OK, "Got hr %#x.\n", hr);
4098 ok(start_time == 12345678, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4099 ok(end_time == 12347946, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4101 media_sample = audiostream_allocate_sample(&source, test_data, 6);
4102 start_time = 12345678;
4103 end_time = 23456789;
4104 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
4105 ok(hr == S_OK, "Got hr %#x.\n", hr);
4106 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
4107 ok(hr == S_OK, "Got hr %#x.\n", hr);
4108 IMediaSample_Release(media_sample);
4110 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4111 ok(hr == S_OK, "Got hr %#x.\n", hr);
4113 start_time = 0xdeadbeefdeadbeef;
4114 end_time = 0xdeadbeefdeadbeef;
4115 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4116 ok(hr == S_OK, "Got hr %#x.\n", hr);
4117 ok(start_time == 12347946, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4118 ok(end_time == 12346585, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4120 hr = IPin_EndOfStream(pin);
4121 ok(hr == S_OK, "Got hr %#x.\n", hr);
4123 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4124 ok(hr == S_OK, "Got hr %#x.\n", hr);
4126 start_time = 0xdeadbeefdeadbeef;
4127 end_time = 0xdeadbeefdeadbeef;
4128 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4129 ok(hr == S_OK, "Got hr %#x.\n", hr);
4130 ok(start_time == 12346585, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4131 ok(end_time == 12348399, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4133 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4134 ok(hr == S_OK, "Got hr %#x.\n", hr);
4135 IGraphBuilder_Disconnect(graph, pin);
4136 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
4138 ref = IAudioStreamSample_Release(stream_sample);
4139 ok(!ref, "Got outstanding refcount %d.\n", ref);
4140 ref = IAudioData_Release(audio_data);
4141 ok(!ref, "Got outstanding refcount %d.\n", ref);
4142 ref = IAMMultiMediaStream_Release(mmstream);
4143 ok(!ref, "Got outstanding refcount %d.\n", ref);
4144 IMediaFilter_Release(graph_media_filter);
4145 ref = IGraphBuilder_Release(graph);
4146 ok(!ref, "Got outstanding refcount %d.\n", ref);
4147 ref = IMediaStreamFilter_Release(filter);
4148 ok(!ref, "Got outstanding refcount %d.\n", ref);
4149 IPin_Release(pin);
4150 IMemInputPin_Release(mem_input_pin);
4151 IAudioMediaStream_Release(audio_stream);
4152 ref = IMediaStream_Release(stream);
4153 ok(!ref, "Got outstanding refcount %d.\n", ref);
4156 static void test_ddrawstream_initialize(void)
4158 IDirectDrawMediaStream *ddraw_stream;
4159 IAMMediaStream *stream;
4160 IDirectDraw *ddraw2;
4161 IDirectDraw *ddraw;
4162 STREAM_TYPE type;
4163 MSPID mspid;
4164 HRESULT hr;
4165 ULONG ref;
4167 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4168 ok(hr == S_OK, "Got hr %#x.\n", hr);
4170 hr = CoCreateInstance(&CLSID_AMDirectDrawStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
4171 ok(hr == S_OK, "Got hr %#x.\n", hr);
4173 hr = IAMMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
4174 ok(hr == S_OK, "Got hr %#x.\n", hr);
4176 /* Crashes on native. */
4177 if (0)
4179 hr = IAMMediaStream_Initialize(stream, NULL, 0, NULL, STREAMTYPE_WRITE);
4180 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
4183 hr = IAMMediaStream_Initialize(stream, NULL, 0, &test_mspid, STREAMTYPE_WRITE);
4184 ok(hr == S_OK, "Got hr %#x.\n", hr);
4186 hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
4187 ok(hr == S_OK, "Got hr %#x.\n", hr);
4188 ok(IsEqualGUID(&mspid, &test_mspid), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
4189 ok(type == STREAMTYPE_WRITE, "Got type %u.\n", type);
4191 hr = IAMMediaStream_Initialize(stream, (IUnknown *)ddraw, 0, &MSPID_PrimaryAudio, STREAMTYPE_READ);
4192 ok(hr == S_OK, "Got hr %#x.\n", hr);
4194 hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
4195 ok(hr == S_OK, "Got hr %#x.\n", hr);
4196 ok(IsEqualGUID(&mspid, &MSPID_PrimaryAudio), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
4197 ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
4199 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw2);
4200 ok(hr == S_OK, "Got hr %#x.\n", hr);
4201 ok(ddraw2 == ddraw, "Expected ddraw %p, got %p.\n", ddraw, ddraw2);
4203 IDirectDrawMediaStream_Release(ddraw_stream);
4204 ref = IAMMediaStream_Release(stream);
4205 ok(!ref, "Got outstanding refcount %d.\n", ref);
4206 IDirectDraw_Release(ddraw2);
4207 ref = IDirectDraw_Release(ddraw);
4208 ok(!ref, "Got outstanding refcount %d.\n", ref);
4211 static void check_ammediastream_join_am_multi_media_stream(const CLSID *clsid)
4213 IAMMultiMediaStream *mmstream = create_ammultimediastream();
4214 IMultiMediaStream *mmstream2;
4215 IAMMediaStream *stream;
4216 HRESULT hr;
4217 ULONG mmstream_ref;
4218 ULONG ref;
4220 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
4221 ok(hr == S_OK, "Got hr %#x.\n", hr);
4223 mmstream_ref = get_refcount(mmstream);
4225 hr = IAMMediaStream_JoinAMMultiMediaStream(stream, mmstream);
4226 ok(hr == S_OK, "Got hr %#x.\n", hr);
4228 ref = get_refcount(mmstream);
4229 ok(ref == mmstream_ref, "Expected outstanding refcount %d, got %d.\n", mmstream_ref, ref);
4231 hr = IAMMediaStream_GetMultiMediaStream(stream, &mmstream2);
4232 ok(hr == S_OK, "Got hr %#x.\n", hr);
4233 ok(mmstream2 == (IMultiMediaStream *)mmstream, "Expected mmstream %p, got %p.\n", mmstream, mmstream2);
4235 IMultiMediaStream_Release(mmstream2);
4237 hr = IAMMediaStream_JoinAMMultiMediaStream(stream, NULL);
4238 ok(hr == S_OK, "Got hr %#x.\n", hr);
4240 hr = IAMMediaStream_GetMultiMediaStream(stream, &mmstream2);
4241 ok(hr == S_OK, "Got hr %#x.\n", hr);
4242 ok(mmstream2 == NULL, "Got mmstream %p.\n", mmstream2);
4244 ref = IAMMediaStream_Release(stream);
4245 ok(!ref, "Got outstanding refcount %d.\n", ref);
4246 ref = IAMMultiMediaStream_Release(mmstream);
4247 ok(!ref, "Got outstanding refcount %d.\n", ref);
4250 static void test_ammediastream_join_am_multi_media_stream(void)
4252 check_ammediastream_join_am_multi_media_stream(&CLSID_AMAudioStream);
4253 check_ammediastream_join_am_multi_media_stream(&CLSID_AMDirectDrawStream);
4256 void test_mediastreamfilter_get_state(void)
4258 IAMMultiMediaStream *mmstream = create_ammultimediastream();
4259 IMediaStreamFilter *filter;
4260 FILTER_STATE state;
4261 HRESULT hr;
4262 ULONG ref;
4264 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4265 ok(hr == S_OK, "Got hr %#x.\n", hr);
4266 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
4267 ok(hr == S_OK, "Got hr %#x.\n", hr);
4268 ok(!!filter, "Expected non-null filter.\n");
4270 /* Crashes on native. */
4271 if (0)
4273 hr = IMediaStreamFilter_GetState(filter, 0, NULL);
4274 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
4277 state = 0xcc;
4278 hr = IMediaStreamFilter_GetState(filter, 0, &state);
4279 ok(state == State_Stopped, "Got state %#x.\n", state);
4281 ref = IAMMultiMediaStream_Release(mmstream);
4282 ok(!ref, "Got outstanding refcount %d.\n", ref);
4283 ref = IMediaStreamFilter_Release(filter);
4284 ok(!ref, "Got outstanding refcount %d.\n", ref);
4287 void check_mediastreamfilter_state(FILTER_STATE expected_state, HRESULT (*set_state)(IMediaStreamFilter *),
4288 HRESULT (*reset_state)(IMediaStreamFilter *))
4290 IAMMultiMediaStream *mmstream = create_ammultimediastream();
4291 struct teststream teststream, teststream2;
4292 IMediaStreamFilter *filter;
4293 FILTER_STATE state;
4294 HRESULT hr;
4295 ULONG ref;
4297 teststream_init(&teststream);
4298 teststream_init(&teststream2);
4300 teststream2.mspid.Data2 = 1;
4302 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4303 ok(hr == S_OK, "Got hr %#x.\n", hr);
4304 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &teststream.mspid, 0, NULL);
4305 ok(hr == S_OK, "Got hr %#x.\n", hr);
4306 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream2, &teststream2.mspid, 0, NULL);
4307 ok(hr == S_OK, "Got hr %#x.\n", hr);
4308 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
4309 ok(hr == S_OK, "Got hr %#x.\n", hr);
4310 ok(filter != NULL, "Expected non-null filter\n");
4312 hr = reset_state(filter);
4313 ok(hr == S_OK, "Got hr %#x.\n", hr);
4315 teststream.state = 0xcc;
4316 teststream2.state = 0xcc;
4317 hr = set_state(filter);
4318 ok(hr == S_OK, "Got hr %#x.\n", hr);
4319 ok(teststream.state == expected_state, "Got state %#x.\n", teststream.state);
4320 ok(teststream2.state == expected_state, "Got state %#x.\n", teststream2.state);
4321 hr = IMediaStreamFilter_GetState(filter, 0, &state);
4322 ok(hr == S_OK, "Got hr %#x.\n", hr);
4323 ok(state == expected_state, "Got state %#x.\n", state);
4325 teststream.state = 0xcc;
4326 teststream2.state = 0xcc;
4327 hr = set_state(filter);
4328 ok(hr == S_OK, "Got hr %#x.\n", hr);
4329 ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state);
4330 ok(teststream2.state == 0xcc, "Got state %#x.\n", teststream2.state);
4332 hr = reset_state(filter);
4333 ok(hr == S_OK, "Got hr %#x.\n", hr);
4335 teststream.set_state_result = E_FAIL;
4336 teststream.state = 0xcc;
4337 teststream2.state = 0xcc;
4338 hr = set_state(filter);
4339 ok(hr == S_OK, "Got hr %#x.\n", hr);
4340 ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state);
4341 ok(teststream2.state == expected_state, "Got state %#x.\n", teststream2.state);
4342 hr = IMediaStreamFilter_GetState(filter, 0, &state);
4343 ok(hr == S_OK, "Got hr %#x.\n", hr);
4344 ok(state == expected_state, "Got state %#x.\n", state);
4346 hr = reset_state(filter);
4347 ok(hr == S_OK, "Got hr %#x.\n", hr);
4349 teststream.set_state_result = E_FAIL;
4350 teststream2.set_state_result = E_FAIL;
4351 teststream.state = 0xcc;
4352 teststream2.state = 0xcc;
4353 hr = set_state(filter);
4354 ok(hr == S_OK, "Got hr %#x.\n", hr);
4355 ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state);
4356 ok(teststream2.state == 0xcc, "Got state %#x.\n", teststream2.state);
4357 hr = IMediaStreamFilter_GetState(filter, 0, &state);
4358 ok(hr == S_OK, "Got hr %#x.\n", hr);
4359 ok(state == expected_state, "Got state %#x.\n", state);
4361 ref = IAMMultiMediaStream_Release(mmstream);
4362 ok(!ref, "Got outstanding refcount %d.\n", ref);
4363 ref = IMediaStreamFilter_Release(filter);
4364 ok(!ref, "Got outstanding refcount %d.\n", ref);
4365 ok(teststream.refcount == 1, "Got outstanding refcount %d.\n", teststream.refcount);
4366 ok(teststream2.refcount == 1, "Got outstanding refcount %d.\n", teststream2.refcount);
4369 static HRESULT mediastreamfilter_stop(IMediaStreamFilter *filter)
4371 return IMediaStreamFilter_Stop(filter);
4374 static HRESULT mediastreamfilter_pause(IMediaStreamFilter *filter)
4376 return IMediaStreamFilter_Pause(filter);
4379 static HRESULT mediastreamfilter_run(IMediaStreamFilter *filter)
4381 return IMediaStreamFilter_Run(filter, 0);
4384 void test_mediastreamfilter_stop_pause_run(void)
4386 check_mediastreamfilter_state(State_Stopped, mediastreamfilter_stop, mediastreamfilter_run);
4387 check_mediastreamfilter_state(State_Paused, mediastreamfilter_pause, mediastreamfilter_stop);
4388 check_mediastreamfilter_state(State_Running, mediastreamfilter_run, mediastreamfilter_stop);
4391 static void test_mediastreamfilter_support_seeking(void)
4393 IAMMultiMediaStream *mmstream = create_ammultimediastream();
4394 static const MSPID mspid1 = {0x88888888, 1};
4395 static const MSPID mspid2 = {0x88888888, 2};
4396 static const MSPID mspid3 = {0x88888888, 3};
4397 struct testfilter source1, source2, source3;
4398 IAMMediaStream *stream1, *stream2, *stream3;
4399 IMediaStreamFilter *filter;
4400 IPin *pin1, *pin2, *pin3;
4401 ULONG ref, seeking_ref;
4402 IGraphBuilder *graph;
4403 HRESULT hr;
4405 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4406 ok(hr == S_OK, "Got hr %#x.\n", hr);
4407 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream1);
4408 ok(hr == S_OK, "Got hr %#x.\n", hr);
4409 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream2);
4410 ok(hr == S_OK, "Got hr %#x.\n", hr);
4411 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream3);
4412 ok(hr == S_OK, "Got hr %#x.\n", hr);
4413 hr = IAMMediaStream_Initialize(stream1, NULL, 0, &mspid1, STREAMTYPE_READ);
4414 ok(hr == S_OK, "Got hr %#x.\n", hr);
4415 hr = IAMMediaStream_Initialize(stream2, NULL, 0, &mspid2, STREAMTYPE_READ);
4416 ok(hr == S_OK, "Got hr %#x.\n", hr);
4417 hr = IAMMediaStream_Initialize(stream3, NULL, 0, &mspid3, STREAMTYPE_READ);
4418 ok(hr == S_OK, "Got hr %#x.\n", hr);
4419 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream1, &mspid1, 0, NULL);
4420 ok(hr == S_OK, "Got hr %#x.\n", hr);
4421 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream2, &mspid2, 0, NULL);
4422 ok(hr == S_OK, "Got hr %#x.\n", hr);
4423 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream3, &mspid3, 0, NULL);
4424 ok(hr == S_OK, "Got hr %#x.\n", hr);
4425 hr = IAMMediaStream_QueryInterface(stream1, &IID_IPin, (void **)&pin1);
4426 ok(hr == S_OK, "Got hr %#x.\n", hr);
4427 hr = IAMMediaStream_QueryInterface(stream2, &IID_IPin, (void **)&pin2);
4428 ok(hr == S_OK, "Got hr %#x.\n", hr);
4429 hr = IAMMediaStream_QueryInterface(stream3, &IID_IPin, (void **)&pin3);
4430 ok(hr == S_OK, "Got hr %#x.\n", hr);
4431 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
4432 ok(hr == S_OK, "Got hr %#x.\n", hr);
4433 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4434 ok(hr == S_OK, "Got hr %#x.\n", hr);
4435 ok(graph != NULL, "Expected non-NULL graph.\n");
4436 testfilter_init(&source1);
4437 testfilter_init(&source2);
4438 testfilter_init(&source3);
4439 source2.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
4440 source3.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
4441 hr = IGraphBuilder_AddFilter(graph, &source1.filter.IBaseFilter_iface, NULL);
4442 ok(hr == S_OK, "Got hr %#x.\n", hr);
4443 hr = IGraphBuilder_AddFilter(graph, &source2.filter.IBaseFilter_iface, NULL);
4444 ok(hr == S_OK, "Got hr %#x.\n", hr);
4445 hr = IGraphBuilder_AddFilter(graph, &source3.filter.IBaseFilter_iface, NULL);
4446 ok(hr == S_OK, "Got hr %#x.\n", hr);
4448 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
4449 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
4451 hr = IGraphBuilder_ConnectDirect(graph, &source1.source.pin.IPin_iface, pin1, &audio_mt);
4452 ok(hr == S_OK, "Got hr %#x.\n", hr);
4454 source2.get_duration_hr = E_FAIL;
4456 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
4457 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
4459 hr = IGraphBuilder_ConnectDirect(graph, &source2.source.pin.IPin_iface, pin2, &audio_mt);
4460 ok(hr == S_OK, "Got hr %#x.\n", hr);
4462 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
4463 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
4465 hr = IGraphBuilder_ConnectDirect(graph, &source3.source.pin.IPin_iface, pin3, &audio_mt);
4466 ok(hr == S_OK, "Got hr %#x.\n", hr);
4468 check_interface(filter, &IID_IMediaSeeking, FALSE);
4470 seeking_ref = get_refcount(&source3.IMediaSeeking_iface);
4472 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
4473 ok(hr == S_OK, "Got hr %#x.\n", hr);
4475 check_interface(filter, &IID_IMediaSeeking, TRUE);
4477 ref = get_refcount(&source3.IMediaSeeking_iface);
4478 ok(ref == seeking_ref, "Expected outstanding refcount %d, got %d.\n", seeking_ref, ref);
4480 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
4481 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED), "Got hr %#x.\n", hr);
4483 IGraphBuilder_Disconnect(graph, pin1);
4484 IGraphBuilder_Disconnect(graph, &source1.source.pin.IPin_iface);
4486 IGraphBuilder_Disconnect(graph, pin2);
4487 IGraphBuilder_Disconnect(graph, &source2.source.pin.IPin_iface);
4489 IGraphBuilder_Disconnect(graph, pin3);
4490 IGraphBuilder_Disconnect(graph, &source3.source.pin.IPin_iface);
4492 ref = IAMMultiMediaStream_Release(mmstream);
4493 ok(!ref, "Got outstanding refcount %d.\n", ref);
4494 ref = IGraphBuilder_Release(graph);
4495 ok(!ref, "Got outstanding refcount %d.\n", ref);
4496 ref = IMediaStreamFilter_Release(filter);
4497 ok(!ref, "Got outstanding refcount %d.\n", ref);
4498 IPin_Release(pin1);
4499 ref = IAMMediaStream_Release(stream1);
4500 ok(!ref, "Got outstanding refcount %d.\n", ref);
4501 IPin_Release(pin2);
4502 ref = IAMMediaStream_Release(stream2);
4503 ok(!ref, "Got outstanding refcount %d.\n", ref);
4504 IPin_Release(pin3);
4505 ref = IAMMediaStream_Release(stream3);
4506 ok(!ref, "Got outstanding refcount %d.\n", ref);
4509 static void test_mediastreamfilter_set_positions(void)
4511 IAMMultiMediaStream *mmstream = create_ammultimediastream();
4512 static const MSPID mspid1 = {0x88888888, 1};
4513 static const MSPID mspid2 = {0x88888888, 2};
4514 static const MSPID mspid3 = {0x88888888, 3};
4515 IMediaStreamFilter *filter;
4516 struct testfilter source1;
4517 struct testfilter source2;
4518 struct testfilter source3;
4519 LONGLONG current_position;
4520 IAMMediaStream *stream1;
4521 IAMMediaStream *stream2;
4522 IAMMediaStream *stream3;
4523 LONGLONG stop_position;
4524 IMediaSeeking *seeking;
4525 IGraphBuilder *graph;
4526 IPin *pin1;
4527 IPin *pin2;
4528 IPin *pin3;
4529 HRESULT hr;
4530 ULONG ref;
4532 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4533 ok(hr == S_OK, "Got hr %#x.\n", hr);
4534 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream1);
4535 ok(hr == S_OK, "Got hr %#x.\n", hr);
4536 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream2);
4537 ok(hr == S_OK, "Got hr %#x.\n", hr);
4538 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream3);
4539 ok(hr == S_OK, "Got hr %#x.\n", hr);
4540 hr = IAMMediaStream_Initialize(stream1, NULL, 0, &mspid1, STREAMTYPE_READ);
4541 ok(hr == S_OK, "Got hr %#x.\n", hr);
4542 hr = IAMMediaStream_Initialize(stream2, NULL, 0, &mspid2, STREAMTYPE_READ);
4543 ok(hr == S_OK, "Got hr %#x.\n", hr);
4544 hr = IAMMediaStream_Initialize(stream3, NULL, 0, &mspid3, STREAMTYPE_READ);
4545 ok(hr == S_OK, "Got hr %#x.\n", hr);
4546 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream1, &mspid1, 0, NULL);
4547 ok(hr == S_OK, "Got hr %#x.\n", hr);
4548 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream2, &mspid2, 0, NULL);
4549 ok(hr == S_OK, "Got hr %#x.\n", hr);
4550 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream3, &mspid3, 0, NULL);
4551 ok(hr == S_OK, "Got hr %#x.\n", hr);
4552 hr = IAMMediaStream_QueryInterface(stream1, &IID_IPin, (void **)&pin1);
4553 ok(hr == S_OK, "Got hr %#x.\n", hr);
4554 hr = IAMMediaStream_QueryInterface(stream2, &IID_IPin, (void **)&pin2);
4555 ok(hr == S_OK, "Got hr %#x.\n", hr);
4556 hr = IAMMediaStream_QueryInterface(stream3, &IID_IPin, (void **)&pin3);
4557 ok(hr == S_OK, "Got hr %#x.\n", hr);
4558 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
4559 ok(hr == S_OK, "Got hr %#x.\n", hr);
4560 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4561 ok(hr == S_OK, "Got hr %#x.\n", hr);
4562 ok(graph != NULL, "Expected non-NULL graph.\n");
4563 testfilter_init(&source1);
4564 testfilter_init(&source2);
4565 testfilter_init(&source3);
4566 source1.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
4567 source2.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
4568 source3.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
4569 hr = IGraphBuilder_AddFilter(graph, &source1.filter.IBaseFilter_iface, NULL);
4570 ok(hr == S_OK, "Got hr %#x.\n", hr);
4571 hr = IGraphBuilder_AddFilter(graph, &source2.filter.IBaseFilter_iface, NULL);
4572 ok(hr == S_OK, "Got hr %#x.\n", hr);
4573 hr = IGraphBuilder_AddFilter(graph, &source3.filter.IBaseFilter_iface, NULL);
4574 ok(hr == S_OK, "Got hr %#x.\n", hr);
4576 hr = IGraphBuilder_ConnectDirect(graph, &source2.source.pin.IPin_iface, pin2, &audio_mt);
4577 ok(hr == S_OK, "Got hr %#x.\n", hr);
4578 hr = IGraphBuilder_ConnectDirect(graph, &source3.source.pin.IPin_iface, pin3, &audio_mt);
4579 ok(hr == S_OK, "Got hr %#x.\n", hr);
4581 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
4582 ok(hr == S_OK, "Got hr %#x.\n", hr);
4584 hr = IGraphBuilder_ConnectDirect(graph, &source1.source.pin.IPin_iface, pin1, &audio_mt);
4585 ok(hr == S_OK, "Got hr %#x.\n", hr);
4587 hr = IMediaStreamFilter_QueryInterface(filter, &IID_IMediaSeeking, (void **)&seeking);
4588 ok(hr == S_OK, "Got hr %#x.\n", hr);
4590 current_position = 12345678;
4591 stop_position = 87654321;
4592 source1.current_position = 0xdeadbeefdeadbeefULL;
4593 source1.stop_position = 0xdeadbeefdeadbeefULL;
4594 source2.current_position = 0xdeadbeefdeadbeefULL;
4595 source2.stop_position = 0xdeadbeefdeadbeefULL;
4596 source3.current_position = 0xdeadbeefdeadbeefULL;
4597 source3.stop_position = 0xdeadbeefdeadbeefULL;
4598 hr = IMediaSeeking_SetPositions(seeking, &current_position, AM_SEEKING_AbsolutePositioning,
4599 &stop_position, AM_SEEKING_AbsolutePositioning);
4600 ok(hr == S_OK, "Got hr %#x.\n", hr);
4601 ok(source1.current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
4602 wine_dbgstr_longlong(source1.current_position));
4603 ok(source1.stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
4604 wine_dbgstr_longlong(source1.stop_position));
4605 ok(source2.current_position == 12345678, "Got current position %s.\n",
4606 wine_dbgstr_longlong(source2.current_position));
4607 ok(source2.stop_position == 87654321, "Got stop position %s.\n",
4608 wine_dbgstr_longlong(source2.stop_position));
4609 ok(source3.current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
4610 wine_dbgstr_longlong(source3.current_position));
4611 ok(source3.stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
4612 wine_dbgstr_longlong(source3.stop_position));
4614 source2.set_positions_hr = E_FAIL;
4615 source1.current_position = 0xdeadbeefdeadbeefULL;
4616 source1.stop_position = 0xdeadbeefdeadbeefULL;
4617 source3.current_position = 0xdeadbeefdeadbeefULL;
4618 source3.stop_position = 0xdeadbeefdeadbeefULL;
4619 current_position = 12345678;
4620 stop_position = 87654321;
4621 hr = IMediaSeeking_SetPositions(seeking, &current_position, AM_SEEKING_AbsolutePositioning,
4622 &stop_position, AM_SEEKING_AbsolutePositioning);
4623 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
4624 ok(source1.current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
4625 wine_dbgstr_longlong(source1.current_position));
4626 ok(source1.stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
4627 wine_dbgstr_longlong(source1.stop_position));
4628 ok(source3.current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
4629 wine_dbgstr_longlong(source3.current_position));
4630 ok(source3.stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
4631 wine_dbgstr_longlong(source3.stop_position));
4633 source2.set_positions_hr = E_NOTIMPL;
4634 source1.current_position = 0xdeadbeefdeadbeefULL;
4635 source1.stop_position = 0xdeadbeefdeadbeefULL;
4636 source3.current_position = 0xdeadbeefdeadbeefULL;
4637 source3.stop_position = 0xdeadbeefdeadbeefULL;
4638 current_position = 12345678;
4639 stop_position = 87654321;
4640 hr = IMediaSeeking_SetPositions(seeking, &current_position, AM_SEEKING_AbsolutePositioning,
4641 &stop_position, AM_SEEKING_AbsolutePositioning);
4642 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
4643 ok(source1.current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
4644 wine_dbgstr_longlong(source1.current_position));
4645 ok(source1.stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
4646 wine_dbgstr_longlong(source1.stop_position));
4647 ok(source3.current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
4648 wine_dbgstr_longlong(source3.current_position));
4649 ok(source3.stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
4650 wine_dbgstr_longlong(source3.stop_position));
4652 source2.IMediaSeeking_iface.lpVtbl = NULL;
4653 source1.current_position = 0xdeadbeefdeadbeefULL;
4654 source1.stop_position = 0xdeadbeefdeadbeefULL;
4655 source3.current_position = 0xdeadbeefdeadbeefULL;
4656 source3.stop_position = 0xdeadbeefdeadbeefULL;
4657 current_position = 12345678;
4658 stop_position = 87654321;
4659 hr = IMediaSeeking_SetPositions(seeking, &current_position, AM_SEEKING_AbsolutePositioning,
4660 &stop_position, AM_SEEKING_AbsolutePositioning);
4661 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
4662 ok(source1.current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
4663 wine_dbgstr_longlong(source1.current_position));
4664 ok(source1.stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
4665 wine_dbgstr_longlong(source1.stop_position));
4666 ok(source3.current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
4667 wine_dbgstr_longlong(source3.current_position));
4668 ok(source3.stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
4669 wine_dbgstr_longlong(source3.stop_position));
4671 IGraphBuilder_Disconnect(graph, pin2);
4672 IGraphBuilder_Disconnect(graph, &source2.source.pin.IPin_iface);
4674 source2.IMediaSeeking_iface.lpVtbl = NULL;
4675 source1.current_position = 0xdeadbeefdeadbeefULL;
4676 source1.stop_position = 0xdeadbeefdeadbeefULL;
4677 source3.current_position = 0xdeadbeefdeadbeefULL;
4678 source3.stop_position = 0xdeadbeefdeadbeefULL;
4679 current_position = 12345678;
4680 stop_position = 87654321;
4681 hr = IMediaSeeking_SetPositions(seeking, &current_position, AM_SEEKING_AbsolutePositioning,
4682 &stop_position, AM_SEEKING_AbsolutePositioning);
4683 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
4684 ok(source1.current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
4685 wine_dbgstr_longlong(source1.current_position));
4686 ok(source1.stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
4687 wine_dbgstr_longlong(source1.stop_position));
4688 ok(source3.current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
4689 wine_dbgstr_longlong(source3.current_position));
4690 ok(source3.stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
4691 wine_dbgstr_longlong(source3.stop_position));
4693 IGraphBuilder_Disconnect(graph, pin2);
4694 IGraphBuilder_Disconnect(graph, &source2.source.pin.IPin_iface);
4695 IGraphBuilder_Disconnect(graph, pin3);
4696 IGraphBuilder_Disconnect(graph, &source3.source.pin.IPin_iface);
4698 ref = IAMMultiMediaStream_Release(mmstream);
4699 ok(!ref, "Got outstanding refcount %d.\n", ref);
4700 ref = IGraphBuilder_Release(graph);
4701 ok(!ref, "Got outstanding refcount %d.\n", ref);
4702 IMediaSeeking_Release(seeking);
4703 ref = IMediaStreamFilter_Release(filter);
4704 ok(!ref, "Got outstanding refcount %d.\n", ref);
4705 IPin_Release(pin1);
4706 ref = IAMMediaStream_Release(stream1);
4707 ok(!ref, "Got outstanding refcount %d.\n", ref);
4708 IPin_Release(pin2);
4709 ref = IAMMediaStream_Release(stream2);
4710 ok(!ref, "Got outstanding refcount %d.\n", ref);
4711 IPin_Release(pin3);
4712 ref = IAMMediaStream_Release(stream3);
4713 ok(!ref, "Got outstanding refcount %d.\n", ref);
4716 static void test_mediastreamfilter_get_current_stream_time(void)
4718 IMediaStreamFilter *filter;
4719 struct testclock clock;
4720 REFERENCE_TIME time;
4721 HRESULT hr;
4722 ULONG ref;
4724 hr = CoCreateInstance(&CLSID_MediaStreamFilter, NULL, CLSCTX_INPROC_SERVER,
4725 &IID_IMediaStreamFilter, (void **)&filter);
4726 ok(hr == S_OK, "Got hr %#x.\n", hr);
4727 testclock_init(&clock);
4729 /* Crashes on native. */
4730 if (0)
4732 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, NULL);
4733 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
4736 time = 0xdeadbeefdeadbeef;
4737 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &time);
4738 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
4739 ok(time == 0, "Got time %s.\n", wine_dbgstr_longlong(time));
4741 hr = IMediaStreamFilter_SetSyncSource(filter, &clock.IReferenceClock_iface);
4742 ok(hr == S_OK, "Got hr %#x.\n", hr);
4744 clock.get_time_hr = E_FAIL;
4746 time = 0xdeadbeefdeadbeef;
4747 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &time);
4748 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
4749 ok(time == 0, "Got time %s.\n", wine_dbgstr_longlong(time));
4751 hr = IMediaStreamFilter_Run(filter, 23456789);
4752 ok(hr == S_OK, "Got hr %#x.\n", hr);
4754 time = 0xdeadbeefdeadbeef;
4755 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &time);
4756 ok(hr == S_OK, "Got hr %#x.\n", hr);
4757 ok(time == 0xdeadbeefdd47d2da, "Got time %s.\n", wine_dbgstr_longlong(time));
4759 clock.time = 34567890;
4760 clock.get_time_hr = S_OK;
4762 time = 0xdeadbeefdeadbeef;
4763 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &time);
4764 ok(hr == S_OK, "Got hr %#x.\n", hr);
4765 ok(time == 11111101, "Got time %s.\n", wine_dbgstr_longlong(time));
4767 ref = IMediaStreamFilter_Release(filter);
4768 ok(!ref, "Got outstanding refcount %d.\n", ref);
4771 START_TEST(amstream)
4773 HANDLE file;
4775 CoInitializeEx(NULL, COINIT_MULTITHREADED);
4777 test_interfaces();
4778 test_add_stream();
4779 test_media_streams();
4780 test_enum_pins();
4781 test_find_pin();
4782 test_pin_info();
4783 test_initialize();
4784 test_enum_media_types();
4785 test_media_types();
4786 test_IDirectDrawStreamSample();
4788 file = CreateFileW(L"test.avi", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
4789 if (file != INVALID_HANDLE_VALUE)
4791 CloseHandle(file);
4793 test_openfile();
4794 test_renderfile();
4797 test_audiodata_query_interface();
4798 test_audiodata_get_info();
4799 test_audiodata_set_buffer();
4800 test_audiodata_set_actual();
4801 test_audiodata_get_format();
4802 test_audiodata_set_format();
4804 test_audiostream_get_format();
4805 test_audiostream_set_format();
4806 test_audiostream_receive_connection();
4807 test_audiostream_set_state();
4808 test_audiostream_end_of_stream();
4809 test_audiostream_receive();
4810 test_audiostream_initialize();
4811 test_audiostream_begin_flush_end_flush();
4812 test_audiostream_new_segment();
4814 test_audiostreamsample_update();
4815 test_audiostreamsample_completion_status();
4816 test_audiostreamsample_get_sample_times();
4818 test_ddrawstream_initialize();
4820 test_ammediastream_join_am_multi_media_stream();
4822 test_mediastreamfilter_get_state();
4823 test_mediastreamfilter_stop_pause_run();
4824 test_mediastreamfilter_support_seeking();
4825 test_mediastreamfilter_set_positions();
4826 test_mediastreamfilter_get_current_stream_time();
4828 CoUninitialize();