winegstreamer: Move the "flip" field to struct wg_parser_stream.
[wine/zf.git] / dlls / amstream / tests / amstream.c
blobf422a6a8db9610f53dc75935ab983f6bf140c39c
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
22 #define NONAMELESSUNION
24 #include "wine/test.h"
25 #include "dshow.h"
26 #include "amstream.h"
27 #include "mmreg.h"
28 #include "ks.h"
29 #include "initguid.h"
30 #include "ksmedia.h"
31 #include "dvdmedia.h"
32 #include "wmcodecdsp.h"
33 #include "wine/strmbase.h"
35 static const WAVEFORMATEX audio_format =
37 .wFormatTag = WAVE_FORMAT_PCM,
38 .nChannels = 1,
39 .nSamplesPerSec = 11025,
40 .wBitsPerSample = 16,
41 .nBlockAlign = 2,
42 .nAvgBytesPerSec = 2 * 11025,
45 static const AM_MEDIA_TYPE audio_mt =
47 /* MEDIATYPE_Audio, MEDIASUBTYPE_PCM, FORMAT_WaveFormatEx */
48 .majortype = {0x73647561, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
49 .subtype = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
50 .formattype = {0x05589f81, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
51 .cbFormat = sizeof(WAVEFORMATEX),
52 .pbFormat = (BYTE *)&audio_format,
55 static const VIDEOINFO rgb8_video_info =
57 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
58 .bmiHeader.biWidth = 333,
59 .bmiHeader.biHeight = -444,
60 .bmiHeader.biPlanes = 1,
61 .bmiHeader.biBitCount = 8,
62 .bmiHeader.biCompression = BI_RGB,
65 static const VIDEOINFO rgb555_video_info =
67 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
68 .bmiHeader.biWidth = 333,
69 .bmiHeader.biHeight = -444,
70 .bmiHeader.biPlanes = 1,
71 .bmiHeader.biBitCount = 16,
72 .bmiHeader.biCompression = BI_RGB,
75 static const VIDEOINFO rgb565_video_info =
77 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
78 .bmiHeader.biWidth = 333,
79 .bmiHeader.biHeight = -444,
80 .bmiHeader.biPlanes = 1,
81 .bmiHeader.biBitCount = 16,
82 .bmiHeader.biCompression = BI_BITFIELDS,
83 .u.dwBitMasks = {0xf800, 0x07e0, 0x001f},
86 static const VIDEOINFO rgb24_video_info =
88 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
89 .bmiHeader.biWidth = 333,
90 .bmiHeader.biHeight = -444,
91 .bmiHeader.biPlanes = 1,
92 .bmiHeader.biBitCount = 24,
93 .bmiHeader.biCompression = BI_RGB,
96 static const VIDEOINFO rgb32_video_info =
98 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
99 .bmiHeader.biWidth = 333,
100 .bmiHeader.biHeight = -444,
101 .bmiHeader.biPlanes = 1,
102 .bmiHeader.biBitCount = 32,
103 .bmiHeader.biCompression = BI_RGB,
106 static const AM_MEDIA_TYPE rgb8_mt =
108 /* MEDIATYPE_Video, MEDIASUBTYPE_RGB8, FORMAT_VideoInfo */
109 .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
110 .subtype = {0xe436eb7a, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
111 .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
112 .cbFormat = sizeof(VIDEOINFO),
113 .pbFormat = (BYTE *)&rgb8_video_info,
116 static const AM_MEDIA_TYPE rgb555_mt =
118 /* MEDIATYPE_Video, MEDIASUBTYPE_RGB555, FORMAT_VideoInfo */
119 .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
120 .subtype = {0xe436eb7c, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
121 .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
122 .cbFormat = sizeof(VIDEOINFO),
123 .pbFormat = (BYTE *)&rgb555_video_info,
126 static const AM_MEDIA_TYPE rgb565_mt =
128 /* MEDIATYPE_Video, MEDIASUBTYPE_RGB565, FORMAT_VideoInfo */
129 .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
130 .subtype = {0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
131 .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
132 .cbFormat = sizeof(VIDEOINFO),
133 .pbFormat = (BYTE *)&rgb565_video_info,
136 static const AM_MEDIA_TYPE rgb24_mt =
138 /* MEDIATYPE_Video, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo */
139 .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
140 .subtype = {0xe436eb7d, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
141 .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
142 .cbFormat = sizeof(VIDEOINFO),
143 .pbFormat = (BYTE *)&rgb24_video_info,
146 static const AM_MEDIA_TYPE rgb32_mt =
148 /* MEDIATYPE_Video, MEDIASUBTYPE_RGB32, FORMAT_VideoInfo */
149 .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
150 .subtype = {0xe436eb7e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
151 .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
152 .cbFormat = sizeof(VIDEOINFO),
153 .pbFormat = (BYTE *)&rgb32_video_info,
156 static const DDSURFACEDESC rgb8_format =
158 .dwSize = sizeof(DDSURFACEDESC),
159 .dwFlags = DDSD_PIXELFORMAT,
160 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
161 .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED8,
162 .ddpfPixelFormat.u1.dwRGBBitCount = 8,
165 static const DDSURFACEDESC rgb555_format =
167 .dwSize = sizeof(DDSURFACEDESC),
168 .dwFlags = DDSD_PIXELFORMAT,
169 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
170 .ddpfPixelFormat.dwFlags = DDPF_RGB,
171 .ddpfPixelFormat.u1.dwRGBBitCount = 16,
172 .ddpfPixelFormat.u2.dwRBitMask = 0x7c00,
173 .ddpfPixelFormat.u3.dwGBitMask = 0x03e0,
174 .ddpfPixelFormat.u4.dwBBitMask = 0x001f,
177 static const DDSURFACEDESC rgb565_format =
179 .dwSize = sizeof(DDSURFACEDESC),
180 .dwFlags = DDSD_PIXELFORMAT,
181 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
182 .ddpfPixelFormat.dwFlags = DDPF_RGB,
183 .ddpfPixelFormat.u1.dwRGBBitCount = 16,
184 .ddpfPixelFormat.u2.dwRBitMask = 0xf800,
185 .ddpfPixelFormat.u3.dwGBitMask = 0x07e0,
186 .ddpfPixelFormat.u4.dwBBitMask = 0x001f,
189 static const DDSURFACEDESC rgb24_format =
191 .dwSize = sizeof(DDSURFACEDESC),
192 .dwFlags = DDSD_PIXELFORMAT,
193 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
194 .ddpfPixelFormat.dwFlags = DDPF_RGB,
195 .ddpfPixelFormat.u1.dwRGBBitCount = 24,
196 .ddpfPixelFormat.u2.dwRBitMask = 0xff0000,
197 .ddpfPixelFormat.u3.dwGBitMask = 0x00ff00,
198 .ddpfPixelFormat.u4.dwBBitMask = 0x0000ff,
201 static const DDSURFACEDESC rgb32_format =
203 .dwSize = sizeof(DDSURFACEDESC),
204 .dwFlags = DDSD_PIXELFORMAT,
205 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
206 .ddpfPixelFormat.dwFlags = DDPF_RGB,
207 .ddpfPixelFormat.u1.dwRGBBitCount = 32,
208 .ddpfPixelFormat.u2.dwRBitMask = 0xff0000,
209 .ddpfPixelFormat.u3.dwGBitMask = 0x00ff00,
210 .ddpfPixelFormat.u4.dwBBitMask = 0x0000ff,
213 static const DDSURFACEDESC argb32_format =
215 .dwSize = sizeof(DDSURFACEDESC),
216 .dwFlags = DDSD_PIXELFORMAT,
217 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
218 .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS,
219 .ddpfPixelFormat.u1.dwRGBBitCount = 32,
220 .ddpfPixelFormat.u2.dwRBitMask = 0xff0000,
221 .ddpfPixelFormat.u3.dwGBitMask = 0x00ff00,
222 .ddpfPixelFormat.u4.dwBBitMask = 0x0000ff,
223 .ddpfPixelFormat.u5.dwRGBAlphaBitMask = 0xff000000,
226 static const DDSURFACEDESC yuy2_format =
228 .dwSize = sizeof(DDSURFACEDESC),
229 .dwFlags = DDSD_PIXELFORMAT,
230 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
231 .ddpfPixelFormat.dwFlags = DDPF_FOURCC,
232 .ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y', 'U', 'Y', '2'),
233 .ddpfPixelFormat.u1.dwYUVBitCount = 16,
236 static const DDSURFACEDESC yv12_format =
238 .dwSize = sizeof(DDSURFACEDESC),
239 .dwFlags = DDSD_PIXELFORMAT,
240 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
241 .ddpfPixelFormat.dwFlags = DDPF_FOURCC,
242 .ddpfPixelFormat.dwFourCC = MAKEFOURCC('Y', 'V', '1', '2'),
243 .ddpfPixelFormat.u1.dwYUVBitCount = 12,
246 static const WCHAR primary_video_sink_id[] = L"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}";
247 static const WCHAR primary_audio_sink_id[] = L"I{A35FF56B-9FDA-11D0-8FDF-00C04FD9189D}";
249 static const WCHAR *load_resource(const WCHAR *name)
251 HMODULE module = GetModuleHandleA(NULL);
252 HRSRC resource;
253 DWORD written;
254 HANDLE file;
255 WCHAR *path;
256 DWORD size;
257 void *ptr;
259 path = calloc(MAX_PATH + 1, sizeof(WCHAR));
260 ok(!!path, "Failed to allocate temp path string.\n");
261 GetTempPathW(MAX_PATH + 1, path);
262 wcscat(path, name);
264 file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
265 ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s, error %u.\n", wine_dbgstr_w(path), GetLastError());
267 resource = FindResourceW(module, name, (const WCHAR *)RT_RCDATA);
268 ok(!!resource, "Failed to find resource %s, error %u.\n", wine_dbgstr_w(name), GetLastError());
270 size = SizeofResource(module, resource);
271 ptr = LockResource(LoadResource(module, resource));
273 WriteFile(file, ptr, size, &written, NULL);
274 ok(written == size, "Failed to write file %s.\n", wine_dbgstr_w(path));
276 CloseHandle(file);
278 return path;
281 static void unload_resource(const WCHAR *path)
283 BOOL ret = DeleteFileW(path);
284 ok(ret, "Failed to delete file %s.\n", wine_dbgstr_w(path));
285 free((void *)path);
288 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
289 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
291 ULONG rc;
292 IUnknown_AddRef(obj);
293 rc = IUnknown_Release(obj);
294 ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
297 static IAMMultiMediaStream *create_ammultimediastream(void)
299 IAMMultiMediaStream *stream = NULL;
300 HRESULT hr = CoCreateInstance(&CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER,
301 &IID_IAMMultiMediaStream, (void **)&stream);
302 ok(hr == S_OK, "Got hr %#x.\n", hr);
303 return stream;
306 static ULONG get_refcount(void *iface)
308 IUnknown *unknown = iface;
309 IUnknown_AddRef(unknown);
310 return IUnknown_Release(unknown);
313 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
314 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
316 IUnknown *iface = iface_ptr;
317 HRESULT hr, expected_hr;
318 IUnknown *unk;
320 expected_hr = supported ? S_OK : E_NOINTERFACE;
322 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
323 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
324 if (SUCCEEDED(hr))
325 IUnknown_Release(unk);
328 static void test_interfaces(void)
330 IAMMultiMediaStream *mmstream = create_ammultimediastream();
331 IMediaStreamFilter *filter;
332 IMediaStream *stream;
333 HRESULT hr;
334 ULONG ref;
336 check_interface(mmstream, &IID_IAMMultiMediaStream, TRUE);
337 check_interface(mmstream, &IID_IMultiMediaStream, TRUE);
338 check_interface(mmstream, &IID_IUnknown, TRUE);
340 check_interface(mmstream, &IID_IAMMediaStream, FALSE);
341 check_interface(mmstream, &IID_IAMMediaTypeStream, FALSE);
342 check_interface(mmstream, &IID_IAudioMediaStream, FALSE);
343 check_interface(mmstream, &IID_IBaseFilter, FALSE);
344 check_interface(mmstream, &IID_IDirectDrawMediaStream, FALSE);
345 check_interface(mmstream, &IID_IMediaFilter, FALSE);
346 check_interface(mmstream, &IID_IMediaStream, FALSE);
347 check_interface(mmstream, &IID_IMediaStreamFilter, FALSE);
348 check_interface(mmstream, &IID_IPin, FALSE);
350 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
351 ok(hr == S_OK, "Got hr %#x.\n", hr);
353 check_interface(filter, &IID_IBaseFilter, TRUE);
354 check_interface(filter, &IID_IMediaFilter, TRUE);
355 check_interface(filter, &IID_IMediaStreamFilter, TRUE);
356 check_interface(filter, &IID_IPersist, TRUE);
357 check_interface(filter, &IID_IUnknown, TRUE);
359 check_interface(filter, &IID_IAMMediaStream, FALSE);
360 check_interface(filter, &IID_IAMMediaTypeStream, FALSE);
361 check_interface(filter, &IID_IAMMultiMediaStream, FALSE);
362 check_interface(filter, &IID_IAudioMediaStream, FALSE);
363 check_interface(filter, &IID_IDirectDrawMediaStream, FALSE);
364 check_interface(filter, &IID_IMediaStream, FALSE);
365 check_interface(filter, &IID_IMultiMediaStream, FALSE);
366 check_interface(filter, &IID_IPin, FALSE);
368 IMediaStreamFilter_Release(filter);
370 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
371 ok(hr == S_OK, "Got hr %#x.\n", hr);
373 check_interface(stream, &IID_IAMMediaStream, TRUE);
374 check_interface(stream, &IID_IAudioMediaStream, TRUE);
375 check_interface(stream, &IID_IMediaStream, TRUE);
376 check_interface(stream, &IID_IMemInputPin, TRUE);
377 check_interface(stream, &IID_IPin, TRUE);
378 check_interface(stream, &IID_IUnknown, TRUE);
380 check_interface(stream, &IID_IAMMediaTypeStream, FALSE);
381 check_interface(stream, &IID_IAMMultiMediaStream, FALSE);
382 check_interface(stream, &IID_IBaseFilter, FALSE);
383 check_interface(stream, &IID_IDirectDrawMediaStream, FALSE);
384 check_interface(stream, &IID_IMediaFilter, FALSE);
385 check_interface(stream, &IID_IMediaStreamFilter, FALSE);
386 check_interface(stream, &IID_IMultiMediaStream, FALSE);
387 check_interface(stream, &IID_IPersist, FALSE);
389 IMediaStream_Release(stream);
391 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
392 ok(hr == S_OK, "Got hr %#x.\n", hr);
394 check_interface(stream, &IID_IAMMediaStream, TRUE);
395 check_interface(stream, &IID_IDirectDrawMediaStream, TRUE);
396 check_interface(stream, &IID_IMediaStream, TRUE);
397 check_interface(stream, &IID_IMemInputPin, TRUE);
398 check_interface(stream, &IID_IPin, TRUE);
399 check_interface(stream, &IID_IUnknown, TRUE);
401 check_interface(stream, &IID_IAMMediaTypeStream, FALSE);
402 check_interface(stream, &IID_IAMMultiMediaStream, FALSE);
403 check_interface(stream, &IID_IAudioMediaStream, FALSE);
404 check_interface(stream, &IID_IBaseFilter, FALSE);
405 check_interface(stream, &IID_IDirectDraw, FALSE);
406 check_interface(stream, &IID_IMediaFilter, FALSE);
407 check_interface(stream, &IID_IMediaStreamFilter, FALSE);
408 check_interface(stream, &IID_IMultiMediaStream, FALSE);
409 check_interface(stream, &IID_IPersist, FALSE);
411 IMediaStream_Release(stream);
413 ref = IAMMultiMediaStream_Release(mmstream);
414 ok(!ref, "Got outstanding refcount %u.\n", ref);
417 static void test_openfile(const WCHAR *test_avi_path)
419 IAMMultiMediaStream *mmstream = create_ammultimediastream();
420 IMediaControl *media_control;
421 IMediaStreamFilter *filter;
422 IMediaFilter *media_filter;
423 IReferenceClock *clock;
424 IGraphBuilder *graph;
425 OAFilterState state;
426 HRESULT hr;
427 ULONG ref;
429 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
430 ok(hr == S_OK, "Got hr %#x.\n", hr);
431 ok(!graph, "Expected NULL graph.\n");
433 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
434 ok(!!filter, "Expected non-NULL filter.\n");
435 ok(hr == S_OK, "Got hr %#x.\n", hr);
437 check_interface(filter, &IID_IMediaSeeking, FALSE);
439 hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_NORENDER);
440 ok(hr == S_OK, "Got hr %#x.\n", hr);
442 check_interface(filter, &IID_IMediaSeeking, FALSE);
444 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
445 ok(hr == S_OK, "Got hr %#x.\n", hr);
446 ok(!!graph, "Expected non-NULL graph.\n");
447 IGraphBuilder_Release(graph);
448 IMediaStreamFilter_Release(filter);
450 ref = IAMMultiMediaStream_Release(mmstream);
451 ok(!ref, "Got outstanding refcount %d.\n", ref);
453 mmstream = create_ammultimediastream();
454 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
455 ok(hr == S_OK, "Got hr %#x.\n", hr);
456 ok(!graph, "Expected NULL graph.\n");
458 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
459 ok(!!filter, "Expected non-NULL filter.\n");
460 ok(hr == S_OK, "Got hr %#x.\n", hr);
462 check_interface(filter, &IID_IMediaSeeking, FALSE);
464 hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, 0);
465 ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr);
467 check_interface(filter, &IID_IMediaSeeking, FALSE);
469 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
470 ok(hr == S_OK, "Got hr %#x.\n", hr);
471 ok(!!graph, "Expected non-NULL graph.\n");
472 IGraphBuilder_Release(graph);
473 IMediaStreamFilter_Release(filter);
475 ref = IAMMultiMediaStream_Release(mmstream);
476 ok(!ref, "Got outstanding refcount %d.\n", ref);
478 mmstream = create_ammultimediastream();
479 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
480 ok(hr == S_OK, "Got hr %#x.\n", hr);
481 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
482 ok(hr == S_OK, "Got hr %#x.\n", hr);
483 ok(!!graph, "Expected non-NULL graph.\n");
484 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
485 ok(hr == S_OK, "Got hr %#x.\n", hr);
486 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
487 ok(hr == S_OK, "Got hr %#x.\n", hr);
489 check_interface(filter, &IID_IMediaSeeking, FALSE);
491 hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, 0);
492 ok(hr == S_OK, "Got hr %#x.\n", hr);
494 check_interface(filter, &IID_IMediaSeeking, TRUE);
496 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
497 ok(hr == S_OK, "Got hr %#x.\n", hr);
499 clock = NULL;
500 IMediaFilter_GetSyncSource(media_filter, &clock);
501 ok(!!clock, "Expected non-NULL clock.\n");
503 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
504 ok(hr == S_OK, "Got hr %#x.\n", hr);
506 ref = IAMMultiMediaStream_Release(mmstream);
507 ok(!ref, "Got outstanding refcount %d.\n", ref);
508 IMediaFilter_Release(media_filter);
509 ref = IGraphBuilder_Release(graph);
510 ok(!ref, "Got outstanding refcount %d.\n", ref);
511 ref = IMediaStreamFilter_Release(filter);
512 ok(!ref, "Got outstanding refcount %d.\n", ref);
513 ref = IReferenceClock_Release(clock);
514 ok(!ref, "Got outstanding refcount %d.\n", ref);
516 mmstream = create_ammultimediastream();
517 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
518 ok(hr == S_OK, "Got hr %#x.\n", hr);
519 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
520 ok(hr == S_OK, "Got hr %#x.\n", hr);
521 ok(!!graph, "Expected non-NULL graph.\n");
522 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
523 ok(hr == S_OK, "Got hr %#x.\n", hr);
525 hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_RUN);
526 ok(hr == S_OK, "Got hr %#x.\n", hr);
528 state = 0xdeadbeef;
529 hr = IMediaControl_GetState(media_control, INFINITE, &state);
530 ok(hr == S_OK, "Got hr %#x.\n", hr);
531 ok(state == State_Running, "Got state %#x.\n", state);
533 ref = IAMMultiMediaStream_Release(mmstream);
534 ok(!ref, "Got outstanding refcount %d.\n", ref);
535 IMediaControl_Release(media_control);
536 ref = IGraphBuilder_Release(graph);
537 ok(!ref, "Got outstanding refcount %d.\n", ref);
539 mmstream = create_ammultimediastream();
540 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
541 ok(hr == S_OK, "Got hr %#x.\n", hr);
542 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
543 ok(hr == S_OK, "Got hr %#x.\n", hr);
544 ok(!!graph, "Expected non-NULL graph.\n");
545 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
546 ok(hr == S_OK, "Got hr %#x.\n", hr);
548 hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_NOCLOCK);
549 ok(hr == S_OK, "Got hr %#x.\n", hr);
551 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
552 ok(hr == S_OK, "Got hr %#x.\n", hr);
554 clock = (IReferenceClock *)0xdeadbeef;
555 IMediaFilter_GetSyncSource(media_filter, &clock);
556 ok(!clock, "Got clock %p.\n", clock);
558 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
559 ok(hr == S_OK, "Got hr %#x.\n", hr);
561 ref = IAMMultiMediaStream_Release(mmstream);
562 ok(!ref, "Got outstanding refcount %d.\n", ref);
563 IMediaFilter_Release(media_filter);
564 ref = IGraphBuilder_Release(graph);
565 ok(!ref, "Got outstanding refcount %d.\n", ref);
568 static void test_mmstream_get_duration(const WCHAR *test_avi_path)
570 IAMMultiMediaStream *mmstream = create_ammultimediastream();
571 HRESULT hr, audio_hr;
572 LONGLONG duration;
573 ULONG ref;
575 duration = 0xdeadbeefdeadbeefULL;
576 hr = IAMMultiMediaStream_GetDuration(mmstream, &duration);
577 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
578 ok(duration == 0xdeadbeefdeadbeefULL, "Got duration %s.\n", wine_dbgstr_longlong(duration));
580 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, NULL);
581 ok(hr == S_OK, "Got hr %#x.\n", hr);
583 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
584 ok(hr == S_OK || hr == VFW_E_NO_AUDIO_HARDWARE, "Got hr %#x.\n", hr);
585 audio_hr = hr;
587 hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, 0);
588 ok(hr == S_OK, "Got hr %#x.\n", hr);
590 duration = 0xdeadbeefdeadbeefULL;
591 hr = IAMMultiMediaStream_GetDuration(mmstream, &duration);
592 if (audio_hr == S_OK)
594 ok(hr == S_OK, "Got hr %#x.\n", hr);
595 ok(duration == 1000000LL, "Got duration %s.\n", wine_dbgstr_longlong(duration));
597 else
599 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
600 ok(!duration, "Got duration %s.\n", wine_dbgstr_longlong(duration));
603 ref = IAMMultiMediaStream_Release(mmstream);
604 ok(!ref, "Got outstanding refcount %d.\n", ref);
606 mmstream = create_ammultimediastream();
607 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
608 ok(hr == S_OK, "Got hr %#x.\n", hr);
610 duration = 0xdeadbeefdeadbeefULL;
611 hr = IAMMultiMediaStream_GetDuration(mmstream, &duration);
612 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
613 ok(duration == 0, "Got duration %s.\n", wine_dbgstr_longlong(duration));
615 ref = IAMMultiMediaStream_Release(mmstream);
616 ok(!ref, "Got outstanding refcount %d.\n", ref);
618 mmstream = create_ammultimediastream();
620 hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, 0);
621 ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr);
623 duration = 0xdeadbeefdeadbeefULL;
624 hr = IAMMultiMediaStream_GetDuration(mmstream, &duration);
625 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
626 ok(duration == 0, "Got duration %s.\n", wine_dbgstr_longlong(duration));
628 ref = IAMMultiMediaStream_Release(mmstream);
629 ok(!ref, "Got outstanding refcount %d.\n", ref);
631 mmstream = create_ammultimediastream();
632 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
633 ok(hr == S_OK, "Got hr %#x.\n", hr);
635 hr = IAMMultiMediaStream_OpenFile(mmstream, test_avi_path, AMMSF_NORENDER);
636 ok(hr == S_OK, "Got hr %#x.\n", hr);
638 duration = 0xdeadbeefdeadbeefULL;
639 hr = IAMMultiMediaStream_GetDuration(mmstream, &duration);
640 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
641 ok(duration == 0, "Got duration %s.\n", wine_dbgstr_longlong(duration));
643 ref = IAMMultiMediaStream_Release(mmstream);
644 ok(!ref, "Got outstanding refcount %d.\n", ref);
647 static const GUID test_mspid = {0x88888888};
649 struct teststream
651 IAMMediaStream IAMMediaStream_iface;
652 IPin IPin_iface;
653 LONG refcount;
654 GUID mspid;
655 IAMMultiMediaStream *mmstream;
656 IMediaStreamFilter *filter;
657 IFilterGraph *graph;
658 FILTER_STATE state;
659 HRESULT set_state_result;
662 static struct teststream *impl_from_IAMMediaStream(IAMMediaStream *iface)
664 return CONTAINING_RECORD(iface, struct teststream, IAMMediaStream_iface);
667 static struct teststream *impl_from_IPin(IPin *iface)
669 return CONTAINING_RECORD(iface, struct teststream, IPin_iface);
672 static HRESULT WINAPI pin_QueryInterface(IPin *iface, REFIID iid, void **out)
674 struct teststream *stream = impl_from_IPin(iface);
675 return IAMMediaStream_QueryInterface(&stream->IAMMediaStream_iface, iid, out);
678 static ULONG WINAPI pin_AddRef(IPin *iface)
680 struct teststream *stream = impl_from_IPin(iface);
681 return IAMMediaStream_AddRef(&stream->IAMMediaStream_iface);
684 static ULONG WINAPI pin_Release(IPin *iface)
686 struct teststream *stream = impl_from_IPin(iface);
687 return IAMMediaStream_Release(&stream->IAMMediaStream_iface);
690 static HRESULT WINAPI pin_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
692 ok(0, "Unexpected call.\n");
693 return E_NOTIMPL;
696 static HRESULT WINAPI pin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
698 ok(0, "Unexpected call.\n");
699 return E_NOTIMPL;
702 static HRESULT WINAPI pin_Disconnect(IPin *iface)
704 if (winetest_debug > 1) trace("Disconnect\n");
705 return E_NOTIMPL;
708 static HRESULT WINAPI pin_ConnectedTo(IPin *iface, IPin **peer)
710 if (winetest_debug > 1) trace("ConnectedTo\n");
711 return E_NOTIMPL;
714 static HRESULT WINAPI pin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *mt)
716 ok(0, "Unexpected call.\n");
717 return E_NOTIMPL;
720 static HRESULT WINAPI pin_QueryPinInfo(IPin *iface, PIN_INFO *info)
722 ok(0, "Unexpected call.\n");
723 return E_NOTIMPL;
726 static HRESULT WINAPI pin_QueryDirection(IPin *iface, PIN_DIRECTION *dir)
728 if (winetest_debug > 1) trace("QueryDirection\n");
729 *dir = PINDIR_INPUT;
730 return S_OK;
733 static HRESULT WINAPI pin_QueryId(IPin *iface, WCHAR **id)
735 ok(0, "Unexpected call.\n");
736 return E_NOTIMPL;
739 static HRESULT WINAPI pin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *mt)
741 ok(0, "Unexpected call.\n");
742 return E_NOTIMPL;
745 static HRESULT WINAPI pin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **out)
747 ok(0, "Unexpected call.\n");
748 return E_NOTIMPL;
751 static HRESULT WINAPI pin_QueryInternalConnections(IPin *iface, IPin **pins, ULONG *count)
753 ok(0, "Unexpected call.\n");
754 return E_NOTIMPL;
757 static HRESULT WINAPI pin_EndOfStream(IPin *iface)
759 ok(0, "Unexpected call.\n");
760 return E_NOTIMPL;
763 static HRESULT WINAPI pin_BeginFlush(IPin *iface)
765 ok(0, "Unexpected call.\n");
766 return E_NOTIMPL;
769 static HRESULT WINAPI pin_EndFlush(IPin *iface)
771 ok(0, "Unexpected call.\n");
772 return E_NOTIMPL;
775 static HRESULT WINAPI pin_NewSegment(IPin *iface, REFERENCE_TIME start, REFERENCE_TIME stop, double rate)
777 ok(0, "Unexpected call.\n");
778 return E_NOTIMPL;
781 static const IPinVtbl pin_vtbl =
783 pin_QueryInterface,
784 pin_AddRef,
785 pin_Release,
786 pin_Connect,
787 pin_ReceiveConnection,
788 pin_Disconnect,
789 pin_ConnectedTo,
790 pin_ConnectionMediaType,
791 pin_QueryPinInfo,
792 pin_QueryDirection,
793 pin_QueryId,
794 pin_QueryAccept,
795 pin_EnumMediaTypes,
796 pin_QueryInternalConnections,
797 pin_EndOfStream,
798 pin_BeginFlush,
799 pin_EndFlush,
800 pin_NewSegment
803 static HRESULT WINAPI stream_QueryInterface(IAMMediaStream *iface, REFIID iid, void **out)
805 struct teststream *stream = impl_from_IAMMediaStream(iface);
807 if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
809 if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IMediaStream) || IsEqualGUID(iid, &IID_IAMMediaStream))
811 IAMMediaStream_AddRef(iface);
812 *out = iface;
813 return S_OK;
815 else if (IsEqualGUID(iid, &IID_IPin))
817 IAMMediaStream_AddRef(iface);
818 *out = &stream->IPin_iface;
819 return S_OK;
822 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(iid));
823 return E_NOINTERFACE;
826 static ULONG WINAPI stream_AddRef(IAMMediaStream *iface)
828 struct teststream *stream = impl_from_IAMMediaStream(iface);
829 return InterlockedIncrement(&stream->refcount);
832 static ULONG WINAPI stream_Release(IAMMediaStream *iface)
834 struct teststream *stream = impl_from_IAMMediaStream(iface);
835 return InterlockedDecrement(&stream->refcount);
838 static HRESULT WINAPI stream_GetMultiMediaStream(IAMMediaStream *iface, IMultiMediaStream **mmstream)
840 ok(0, "Unexpected call.\n");
841 return E_NOTIMPL;
844 static HRESULT WINAPI stream_GetInformation(IAMMediaStream *iface, MSPID *id, STREAM_TYPE *type)
846 struct teststream *stream = impl_from_IAMMediaStream(iface);
847 if (winetest_debug > 1) trace("GetInformation(%p, %p)\n", id, type);
848 if (id)
849 *id = stream->mspid;
850 if (type)
851 *type = STREAMTYPE_READ;
852 return S_OK;
855 static HRESULT WINAPI stream_SetSameFormat(IAMMediaStream *iface, IMediaStream *ref, DWORD flags)
857 ok(0, "Unexpected call.\n");
858 return E_NOTIMPL;
861 static HRESULT WINAPI stream_AllocateSample(IAMMediaStream *iface, DWORD flags, IStreamSample **sample)
863 ok(0, "Unexpected call.\n");
864 return E_NOTIMPL;
867 static HRESULT WINAPI stream_CreateSharedSample(IAMMediaStream *iface,
868 IStreamSample *existing, DWORD flags, IStreamSample **out)
870 ok(0, "Unexpected call.\n");
871 return E_NOTIMPL;
874 static HRESULT WINAPI stream_SendEndOfStream(IAMMediaStream *iface, DWORD flags)
876 ok(0, "Unexpected call.\n");
877 return E_NOTIMPL;
880 static HRESULT WINAPI stream_Initialize(IAMMediaStream *iface, IUnknown *source,
881 DWORD flags, REFMSPID id, const STREAM_TYPE type)
883 ok(0, "Unexpected call.\n");
884 return E_NOTIMPL;
887 static HRESULT WINAPI stream_SetState(IAMMediaStream *iface, FILTER_STATE state)
889 struct teststream *stream = impl_from_IAMMediaStream(iface);
890 if (winetest_debug > 1) trace("SetState(%#x)\n", state);
891 if (SUCCEEDED(stream->set_state_result))
892 stream->state = state;
893 return stream->set_state_result;
896 static HRESULT WINAPI stream_JoinAMMultiMediaStream(IAMMediaStream *iface, IAMMultiMediaStream *mmstream)
898 struct teststream *stream = impl_from_IAMMediaStream(iface);
899 if (winetest_debug > 1) trace("JoinAMMultiMediaStream(%p)\n", mmstream);
900 stream->mmstream = mmstream;
901 return S_OK;
904 static HRESULT WINAPI stream_JoinFilter(IAMMediaStream *iface, IMediaStreamFilter *filter)
906 struct teststream *stream = impl_from_IAMMediaStream(iface);
907 if (winetest_debug > 1) trace("JoinFilter(%p)\n", filter);
908 stream->filter = filter;
909 return S_OK;
912 static HRESULT WINAPI stream_JoinFilterGraph(IAMMediaStream *iface, IFilterGraph *graph)
914 struct teststream *stream = impl_from_IAMMediaStream(iface);
915 if (winetest_debug > 1) trace("JoinFilterGraph(%p)\n", graph);
916 stream->graph = graph;
917 return S_OK;
920 static const IAMMediaStreamVtbl stream_vtbl =
922 stream_QueryInterface,
923 stream_AddRef,
924 stream_Release,
925 stream_GetMultiMediaStream,
926 stream_GetInformation,
927 stream_SetSameFormat,
928 stream_AllocateSample,
929 stream_CreateSharedSample,
930 stream_SendEndOfStream,
931 stream_Initialize,
932 stream_SetState,
933 stream_JoinAMMultiMediaStream,
934 stream_JoinFilter,
935 stream_JoinFilterGraph,
938 static void teststream_init(struct teststream *stream)
940 memset(stream, 0, sizeof(*stream));
941 stream->IAMMediaStream_iface.lpVtbl = &stream_vtbl;
942 stream->IPin_iface.lpVtbl = &pin_vtbl;
943 stream->refcount = 1;
944 stream->mspid = test_mspid;
945 stream->set_state_result = S_OK;
948 #define check_enum_stream(a,b,c,d) check_enum_stream_(__LINE__,a,b,c,d)
949 static void check_enum_stream_(int line, IAMMultiMediaStream *mmstream,
950 IMediaStreamFilter *filter, LONG index, IMediaStream *expect)
952 IMediaStream *stream = NULL, *stream2 = NULL;
953 HRESULT hr;
955 hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, index, &stream);
956 ok_(__FILE__, line)(hr == (expect ? S_OK : S_FALSE),
957 "IAMMultiMediaStream::EnumMediaStreams() returned %#x.\n", hr);
958 hr = IMediaStreamFilter_EnumMediaStreams(filter, index, &stream2);
959 ok_(__FILE__, line)(hr == (expect ? S_OK : S_FALSE),
960 "IMediaStreamFilter::EnumMediaStreams() returned %#x.\n", hr);
961 if (hr == S_OK)
963 ok_(__FILE__, line)(stream == expect, "Expected stream %p, got %p.\n", expect, stream);
964 ok_(__FILE__, line)(stream2 == expect, "Expected stream %p, got %p.\n", expect, stream2);
965 IMediaStream_Release(stream);
966 IMediaStream_Release(stream2);
970 struct testfilter
972 struct strmbase_filter filter;
973 struct strmbase_source source;
974 IMediaSeeking IMediaSeeking_iface;
975 LONGLONG current_position;
976 LONGLONG stop_position;
977 const AM_MEDIA_TYPE *preferred_mt;
978 HANDLE wait_state_event;
979 HRESULT get_duration_hr;
980 HRESULT get_stop_position_hr;
981 HRESULT set_positions_hr;
982 HRESULT init_stream_hr;
983 HRESULT cleanup_stream_hr;
984 HRESULT wait_state_hr;
985 HRESULT is_format_supported_hr;
988 static inline struct testfilter *impl_from_BaseFilter(struct strmbase_filter *iface)
990 return CONTAINING_RECORD(iface, struct testfilter, filter);
993 static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
995 struct testfilter *filter = impl_from_BaseFilter(iface);
996 if (!index)
997 return &filter->source.pin;
998 return NULL;
1001 static void testfilter_destroy(struct strmbase_filter *iface)
1003 struct testfilter *filter = impl_from_BaseFilter(iface);
1004 CloseHandle(filter->wait_state_event);
1005 strmbase_source_cleanup(&filter->source);
1006 strmbase_filter_cleanup(&filter->filter);
1009 static HRESULT testfilter_init_stream(struct strmbase_filter *iface)
1011 struct testfilter *filter = impl_from_BaseFilter(iface);
1012 HRESULT hr;
1014 if (SUCCEEDED(filter->init_stream_hr) && filter->source.pin.peer)
1016 hr = IMemAllocator_Commit(filter->source.pAllocator);
1017 ok(hr == S_OK, "Got hr %#x.\n", hr);
1020 return filter->init_stream_hr;
1023 static HRESULT testfilter_cleanup_stream(struct strmbase_filter *iface)
1025 struct testfilter *filter = impl_from_BaseFilter(iface);
1026 HRESULT hr;
1028 if (SUCCEEDED(filter->cleanup_stream_hr) && filter->source.pin.peer)
1030 hr = IMemAllocator_Decommit(filter->source.pAllocator);
1031 ok(hr == S_OK, "Got hr %#x.\n", hr);
1034 return filter->cleanup_stream_hr;
1037 static HRESULT testfilter_wait_state(struct strmbase_filter *iface, DWORD timeout)
1039 struct testfilter *filter = impl_from_BaseFilter(iface);
1040 HRESULT hr;
1042 LeaveCriticalSection(&filter->filter.filter_cs);
1043 WaitForSingleObject(filter->wait_state_event, timeout);
1044 EnterCriticalSection(&filter->filter.filter_cs);
1046 hr = filter->wait_state_hr;
1048 return hr;
1051 static const struct strmbase_filter_ops testfilter_ops =
1053 .filter_get_pin = testfilter_get_pin,
1054 .filter_destroy = testfilter_destroy,
1055 .filter_init_stream = testfilter_init_stream,
1056 .filter_cleanup_stream = testfilter_cleanup_stream,
1057 .filter_wait_state = testfilter_wait_state,
1060 static inline struct testfilter *impl_from_base_pin(struct strmbase_pin *iface)
1062 return CONTAINING_RECORD(iface, struct testfilter, source.pin);
1065 static HRESULT testsource_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt)
1067 struct testfilter *filter = impl_from_base_pin(iface);
1069 if (index < 1 && filter->preferred_mt)
1070 return CopyMediaType(mt, filter->preferred_mt);
1072 return VFW_S_NO_MORE_ITEMS;
1075 static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
1077 struct testfilter *filter = impl_from_base_pin(iface);
1079 if (IsEqualGUID(iid, &IID_IMediaSeeking) && filter->IMediaSeeking_iface.lpVtbl)
1080 *out = &filter->IMediaSeeking_iface;
1081 else
1082 return E_NOINTERFACE;
1084 IUnknown_AddRef((IUnknown *)*out);
1086 return S_OK;
1089 static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, IMemInputPin *pin, IMemAllocator **alloc)
1091 ALLOCATOR_PROPERTIES props = {0};
1092 HRESULT hr;
1094 /* AMDirectDrawStream tries to use it's custom allocator and
1095 * when it is able to do so it's behavior changes slightly
1096 * (e.g. it uses dynamic format change instead of reconnecting in SetFormat).
1097 * We don't yet implement the custom allocator so force the standard one for now. */
1098 hr = BaseOutputPinImpl_InitAllocator(iface, alloc);
1099 ok(hr == S_OK, "Got hr %#x.\n", hr);
1101 IMemInputPin_GetAllocatorRequirements(pin, &props);
1102 hr = iface->pFuncsTable->pfnDecideBufferSize(iface, *alloc, &props);
1103 ok(hr == S_OK, "Got hr %#x.\n", hr);
1105 return IMemInputPin_NotifyAllocator(pin, *alloc, FALSE);
1108 static HRESULT WINAPI testsource_DecideBufferSize(struct strmbase_source *iface,
1109 IMemAllocator *alloc, ALLOCATOR_PROPERTIES *requested)
1111 ALLOCATOR_PROPERTIES actual;
1113 if (!requested->cbAlign)
1114 requested->cbAlign = 1;
1116 if (requested->cbBuffer < 4096)
1117 requested->cbBuffer = 4096;
1119 if (!requested->cBuffers)
1120 requested->cBuffers = 2;
1122 return IMemAllocator_SetProperties(alloc, requested, &actual);
1125 static const struct strmbase_source_ops testsource_ops =
1127 .base.pin_get_media_type = testsource_get_media_type,
1128 .base.pin_query_interface = testsource_query_interface,
1129 .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
1130 .pfnDecideBufferSize = testsource_DecideBufferSize,
1131 .pfnDecideAllocator = testsource_DecideAllocator,
1134 static void testfilter_init(struct testfilter *filter)
1136 static const GUID clsid = {0xabacab};
1137 memset(filter, 0, sizeof(*filter));
1138 strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
1139 strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops);
1140 filter->stop_position = 0x8000000000000000ULL;
1141 filter->wait_state_event = CreateEventW(NULL, TRUE, TRUE, NULL);
1144 static inline struct testfilter *impl_from_IMediaSeeking(IMediaSeeking *iface)
1146 return CONTAINING_RECORD(iface, struct testfilter, IMediaSeeking_iface);
1149 static HRESULT WINAPI testsource_seeking_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
1151 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1152 return IBaseFilter_QueryInterface(&filter->filter.IBaseFilter_iface, iid, out);
1155 static ULONG WINAPI testsource_seeking_AddRef(IMediaSeeking *iface)
1157 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1158 return IBaseFilter_AddRef(&filter->filter.IBaseFilter_iface);
1161 static ULONG WINAPI testsource_seeking_Release(IMediaSeeking *iface)
1163 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1164 return IBaseFilter_Release(&filter->filter.IBaseFilter_iface);
1167 static HRESULT WINAPI testsource_seeking_GetCapabilities(IMediaSeeking *iface, DWORD *capabilities)
1169 ok(0, "Unexpected call.\n");
1170 return E_NOTIMPL;
1173 static HRESULT WINAPI testsource_seeking_CheckCapabilities(IMediaSeeking *iface, DWORD *capabilities)
1175 ok(0, "Unexpected call.\n");
1176 return E_NOTIMPL;
1179 static HRESULT WINAPI testsource_seeking_IsFormatSupported(IMediaSeeking *iface, const GUID *format)
1181 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1183 ok(IsEqualGUID(format, &TIME_FORMAT_MEDIA_TIME),
1184 "Got format %s.\n", wine_dbgstr_guid(format));
1186 return filter->is_format_supported_hr;
1189 static HRESULT WINAPI testsource_seeking_QueryPreferredFormat(IMediaSeeking *iface, GUID *format)
1191 ok(0, "Unexpected call.\n");
1192 return E_NOTIMPL;
1195 static HRESULT WINAPI testsource_seeking_GetTimeFormat(IMediaSeeking *iface, GUID *format)
1197 ok(0, "Unexpected call.\n");
1198 return E_NOTIMPL;
1201 static HRESULT WINAPI testsource_seeking_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format)
1203 ok(0, "Unexpected call.\n");
1204 return E_NOTIMPL;
1207 static HRESULT WINAPI testsource_seeking_SetTimeFormat(IMediaSeeking *iface, const GUID *format)
1209 ok(0, "Unexpected call.\n");
1210 return E_NOTIMPL;
1213 static HRESULT WINAPI testsource_seeking_GetDuration(IMediaSeeking *iface, LONGLONG *duration)
1215 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1217 if (SUCCEEDED(filter->get_duration_hr))
1218 *duration = 0x8000000000000000ULL;
1220 return filter->get_duration_hr;
1223 static HRESULT WINAPI testsource_seeking_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop)
1225 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1227 if (SUCCEEDED(filter->get_stop_position_hr))
1228 *stop = 0x8000000000000000ULL;
1230 return filter->get_stop_position_hr;
1233 static HRESULT WINAPI testsource_seeking_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current)
1235 ok(0, "Unexpected call.\n");
1236 return E_NOTIMPL;
1239 static HRESULT WINAPI testsource_seeking_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target,
1240 const GUID *target_format, LONGLONG source, const GUID *source_format)
1242 ok(0, "Unexpected call.\n");
1243 return E_NOTIMPL;
1246 static HRESULT WINAPI testsource_seeking_SetPositions(IMediaSeeking *iface, LONGLONG *current_ptr, DWORD current_flags,
1247 LONGLONG *stop_ptr, DWORD stop_flags)
1249 struct testfilter *filter = impl_from_IMediaSeeking(iface);
1251 if (SUCCEEDED(filter->set_positions_hr))
1253 if (current_ptr)
1254 filter->current_position = *current_ptr;
1256 if (stop_ptr)
1257 filter->stop_position = *stop_ptr;
1260 return filter->set_positions_hr;
1263 static HRESULT WINAPI testsource_seeking_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop)
1265 ok(0, "Unexpected call.\n");
1266 return E_NOTIMPL;
1269 static HRESULT WINAPI testsource_seeking_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest)
1271 ok(0, "Unexpected call.\n");
1272 return E_NOTIMPL;
1275 static HRESULT WINAPI testsource_seeking_SetRate(IMediaSeeking *iface, double rate)
1277 ok(0, "Unexpected call.\n");
1278 return E_NOTIMPL;
1281 static HRESULT WINAPI testsource_seeking_GetRate(IMediaSeeking *iface, double *rate)
1283 ok(0, "Unexpected call.\n");
1284 return E_NOTIMPL;
1287 static HRESULT WINAPI testsource_seeking_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll)
1289 ok(0, "Unexpected call.\n");
1290 return E_NOTIMPL;
1293 static const IMediaSeekingVtbl testsource_seeking_vtbl =
1295 testsource_seeking_QueryInterface,
1296 testsource_seeking_AddRef,
1297 testsource_seeking_Release,
1298 testsource_seeking_GetCapabilities,
1299 testsource_seeking_CheckCapabilities,
1300 testsource_seeking_IsFormatSupported,
1301 testsource_seeking_QueryPreferredFormat,
1302 testsource_seeking_GetTimeFormat,
1303 testsource_seeking_IsUsingTimeFormat,
1304 testsource_seeking_SetTimeFormat,
1305 testsource_seeking_GetDuration,
1306 testsource_seeking_GetStopPosition,
1307 testsource_seeking_GetCurrentPosition,
1308 testsource_seeking_ConvertTimeFormat,
1309 testsource_seeking_SetPositions,
1310 testsource_seeking_GetPositions,
1311 testsource_seeking_GetAvailable,
1312 testsource_seeking_SetRate,
1313 testsource_seeking_GetRate,
1314 testsource_seeking_GetPreroll,
1317 #define check_get_stream(a,b,c,d) check_get_stream_(__LINE__,a,b,c,d)
1318 static void check_get_stream_(int line, IAMMultiMediaStream *mmstream,
1319 IMediaStreamFilter *filter, const GUID *mspid, IMediaStream *expect)
1321 IMediaStream *stream = NULL, *stream2 = NULL;
1322 HRESULT hr;
1324 hr = IAMMultiMediaStream_GetMediaStream(mmstream, mspid, &stream);
1325 ok_(__FILE__, line)(hr == (expect ? S_OK : MS_E_NOSTREAM),
1326 "IAMMultiMediaStream::GetMediaStream() returned %#x.\n", hr);
1327 hr = IMediaStreamFilter_GetMediaStream(filter, mspid, &stream2);
1328 ok_(__FILE__, line)(hr == (expect ? S_OK : MS_E_NOSTREAM),
1329 "IMediaStreamFilter::GetMediaStream() returned %#x.\n", hr);
1330 if (hr == S_OK)
1332 ok_(__FILE__, line)(stream == expect, "Expected stream %p, got %p.\n", expect, stream);
1333 ok_(__FILE__, line)(stream2 == expect, "Expected stream %p, got %p.\n", expect, stream2);
1336 if (stream) IMediaStream_Release(stream);
1337 if (stream2) IMediaStream_Release(stream2);
1340 static void test_add_stream(void)
1342 IAMMultiMediaStream *mmstream = create_ammultimediastream();
1343 IMediaStream *video_stream, *audio_stream, *stream;
1344 IDirectDrawMediaStream *ddraw_stream;
1345 IMediaStreamFilter *stream_filter;
1346 struct teststream teststream;
1347 IDirectDraw *ddraw, *ddraw2;
1348 IEnumFilters *enum_filters;
1349 IBaseFilter *filters[3];
1350 IGraphBuilder *graph;
1351 FILTER_INFO info;
1352 ULONG ref, count;
1353 CLSID clsid;
1354 HRESULT hr;
1356 teststream_init(&teststream);
1358 hr = IAMMultiMediaStream_GetFilter(mmstream, &stream_filter);
1359 ok(hr == S_OK, "Got hr %#x.\n", hr);
1361 hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, 0, NULL);
1362 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1363 hr = IMediaStreamFilter_EnumMediaStreams(stream_filter, 0, NULL);
1364 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1366 hr = IAMMultiMediaStream_GetMediaStream(mmstream, &MSPID_PrimaryAudio, NULL);
1367 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1368 hr = IMediaStreamFilter_GetMediaStream(stream_filter, &MSPID_PrimaryAudio, NULL);
1369 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1370 hr = IAMMultiMediaStream_GetMediaStream(mmstream, &MSPID_PrimaryVideo, NULL);
1371 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1372 hr = IMediaStreamFilter_GetMediaStream(stream_filter, &MSPID_PrimaryVideo, NULL);
1373 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1375 check_enum_stream(mmstream, stream_filter, 0, NULL);
1377 check_get_stream(mmstream, stream_filter, NULL, NULL);
1378 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, NULL);
1379 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, NULL);
1380 check_get_stream(mmstream, stream_filter, &test_mspid, NULL);
1382 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &test_mspid, 0, &stream);
1383 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
1385 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &video_stream);
1386 ok(hr == S_OK, "Got hr %#x.\n", hr);
1388 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1389 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
1391 hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, 0, NULL);
1392 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1393 hr = IMediaStreamFilter_EnumMediaStreams(stream_filter, 0, NULL);
1394 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1395 hr = IAMMultiMediaStream_EnumMediaStreams(mmstream, 1, NULL);
1396 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1397 hr = IMediaStreamFilter_EnumMediaStreams(stream_filter, 1, NULL);
1398 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1400 check_enum_stream(mmstream, stream_filter, 0, video_stream);
1401 check_enum_stream(mmstream, stream_filter, 1, NULL);
1403 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, video_stream);
1404 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, NULL);
1405 check_get_stream(mmstream, stream_filter, &test_mspid, NULL);
1407 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &audio_stream);
1408 ok(hr == S_OK, "Got hr %#x.\n", hr);
1410 check_enum_stream(mmstream, stream_filter, 0, video_stream);
1411 check_enum_stream(mmstream, stream_filter, 1, audio_stream);
1412 check_enum_stream(mmstream, stream_filter, 2, NULL);
1414 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, video_stream);
1415 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, audio_stream);
1416 check_get_stream(mmstream, stream_filter, &test_mspid, NULL);
1418 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &IID_IUnknown, 0, &stream);
1419 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
1421 hr = IMediaStreamFilter_QueryFilterInfo(stream_filter, &info);
1422 ok(hr == S_OK, "Got hr %#x.\n", hr);
1424 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &test_mspid, 0, &stream);
1425 ok(hr == S_OK, "Got hr %#x.\n", hr);
1426 ok(stream == (IMediaStream *)&teststream, "Streams didn't match.\n");
1427 IMediaStream_Release(stream);
1428 ok(teststream.mmstream == mmstream, "IAMMultiMediaStream objects didn't match.\n");
1429 ok(teststream.filter == stream_filter, "IMediaStreamFilter objects didn't match.\n");
1430 ok(teststream.graph == info.pGraph, "IFilterGraph objects didn't match.\n");
1432 IFilterGraph_Release(info.pGraph);
1434 check_enum_stream(mmstream, stream_filter, 0, video_stream);
1435 check_enum_stream(mmstream, stream_filter, 1, audio_stream);
1436 check_enum_stream(mmstream, stream_filter, 2, (IMediaStream *)&teststream);
1437 check_enum_stream(mmstream, stream_filter, 3, NULL);
1439 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, video_stream);
1440 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, audio_stream);
1441 check_get_stream(mmstream, stream_filter, &test_mspid, (IMediaStream *)&teststream);
1443 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1444 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
1446 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
1447 ok(hr == S_OK, "Got hr %#x.\n", hr);
1448 ok(!!graph, "Expected a non-NULL graph.\n");
1450 hr = IGraphBuilder_EnumFilters(graph, &enum_filters);
1451 ok(hr == S_OK, "Got hr %#x.\n", hr);
1452 hr = IEnumFilters_Next(enum_filters, 3, filters, &count);
1453 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1454 ok(count == 1, "Got count %u.\n", count);
1455 ok(filters[0] == (IBaseFilter *)stream_filter,
1456 "Expected filter %p, got %p.\n", stream_filter, filters[0]);
1457 IBaseFilter_Release(filters[0]);
1458 IEnumFilters_Release(enum_filters);
1459 IGraphBuilder_Release(graph);
1461 IMediaStreamFilter_Release(stream_filter);
1462 ref = IAMMultiMediaStream_Release(mmstream);
1463 ok(!ref, "Got outstanding refcount %d.\n", ref);
1464 ref = IMediaStream_Release(video_stream);
1465 ok(!ref, "Got outstanding refcount %d.\n", ref);
1466 ref = IMediaStream_Release(audio_stream);
1467 ok(!ref, "Got outstanding refcount %d.\n", ref);
1468 ok(teststream.refcount == 1, "Got outstanding refcount %d.\n", teststream.refcount);
1470 /* The return parameter is optional. */
1472 mmstream = create_ammultimediastream();
1474 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, NULL);
1475 ok(hr == S_OK, "Got hr %#x.\n", hr);
1477 hr = IAMMultiMediaStream_GetMediaStream(mmstream, &MSPID_PrimaryVideo, &stream);
1478 ok(hr == S_OK, "Got hr %#x.\n", hr);
1479 IMediaStream_Release(stream);
1481 ref = IAMMultiMediaStream_Release(mmstream);
1482 ok(!ref, "Got outstanding refcount %d.\n", ref);
1484 /* Test supplying a DirectDraw object with the primary video stream. */
1486 hr = DirectDrawCreate(NULL, &ddraw, NULL);
1487 ok(hr == DD_OK, "Got hr %#x.\n", hr);
1488 mmstream = create_ammultimediastream();
1490 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)ddraw, &MSPID_PrimaryVideo, 0, &video_stream);
1491 ok(hr == S_OK, "Got hr %#x.\n", hr);
1493 hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
1494 ok(hr == S_OK, "Got hr %#x.\n", hr);
1495 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw2);
1496 ok(hr == S_OK, "Got hr %#x.\n", hr);
1497 ok(ddraw2 == ddraw, "Expected IDirectDraw %p, got %p.\n", ddraw, ddraw2);
1498 IDirectDraw_Release(ddraw2);
1499 IDirectDrawMediaStream_Release(ddraw_stream);
1501 ref = IAMMultiMediaStream_Release(mmstream);
1502 ok(!ref, "Got outstanding refcount %d.\n", ref);
1503 ref = IMediaStream_Release(video_stream);
1504 ok(!ref, "Got outstanding refcount %d.\n", ref);
1505 ref = IDirectDraw_Release(ddraw);
1506 ok(!ref, "Got outstanding refcount %d.\n", ref);
1508 mmstream = create_ammultimediastream();
1510 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &video_stream);
1511 ok(hr == S_OK, "Got hr %#x.\n", hr);
1513 hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
1514 ok(hr == S_OK, "Got hr %#x.\n", hr);
1515 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw);
1516 ok(hr == S_OK, "Got hr %#x.\n", hr);
1517 ok(!!ddraw, "Expected a non-NULL IDirectDraw.\n");
1518 IDirectDraw_Release(ddraw);
1519 IDirectDrawMediaStream_Release(ddraw_stream);
1521 ref = IAMMultiMediaStream_Release(mmstream);
1522 ok(!ref, "Got outstanding refcount %d.\n", ref);
1523 ref = IMediaStream_Release(video_stream);
1524 ok(!ref, "Got outstanding refcount %d.\n", ref);
1526 /* Test the AMMSF_ADDDEFAULTRENDERER flag. No stream is added; however, a
1527 * new filter will be added to the graph. */
1529 mmstream = create_ammultimediastream();
1530 hr = IAMMultiMediaStream_GetFilter(mmstream, &stream_filter);
1531 ok(hr == S_OK, "Got hr %#x.\n", hr);
1533 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo,
1534 AMMSF_ADDDEFAULTRENDERER, &video_stream);
1535 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1537 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo,
1538 AMMSF_ADDDEFAULTRENDERER, NULL);
1539 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
1541 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio,
1542 AMMSF_ADDDEFAULTRENDERER, &audio_stream);
1543 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1545 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio,
1546 AMMSF_ADDDEFAULTRENDERER, NULL);
1547 ok(hr == S_OK || hr == VFW_E_NO_AUDIO_HARDWARE, "Got hr %#x.\n", hr);
1549 check_enum_stream(mmstream, stream_filter, 0, NULL);
1551 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryAudio, NULL);
1552 check_get_stream(mmstream, stream_filter, &MSPID_PrimaryVideo, NULL);
1554 if (hr == S_OK)
1556 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
1557 ok(hr == S_OK, "Got hr %#x.\n", hr);
1558 ok(!!graph, "Got graph %p.\n", graph);
1559 hr = IGraphBuilder_EnumFilters(graph, &enum_filters);
1560 ok(hr == S_OK, "Got hr %#x.\n", hr);
1561 hr = IEnumFilters_Next(enum_filters, 3, filters, &count);
1562 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1563 ok(count == 2, "Got count %u.\n", count);
1564 ok(filters[1] == (IBaseFilter *)stream_filter,
1565 "Expected filter %p, got %p.\n", stream_filter, filters[1]);
1566 hr = IBaseFilter_GetClassID(filters[0], &clsid);
1567 ok(hr == S_OK, "Got hr %#x.\n", hr);
1568 ok(IsEqualGUID(&clsid, &CLSID_DSoundRender), "Got unexpected filter %s.\n", wine_dbgstr_guid(&clsid));
1569 IBaseFilter_Release(filters[0]);
1570 IBaseFilter_Release(filters[1]);
1571 IEnumFilters_Release(enum_filters);
1572 IGraphBuilder_Release(graph);
1575 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &test_mspid,
1576 AMMSF_ADDDEFAULTRENDERER, NULL);
1577 ok(hr == MS_E_PURPOSEID, "Got hr %#x.\n", hr);
1578 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &test_mspid,
1579 AMMSF_ADDDEFAULTRENDERER, &audio_stream);
1580 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
1582 ref = IAMMultiMediaStream_Release(mmstream);
1583 ok(!ref, "Got outstanding refcount %d.\n", ref);
1584 ref = IMediaStreamFilter_Release(stream_filter);
1585 ok(!ref, "Got outstanding refcount %d.\n", ref);
1588 static void test_media_streams(void)
1590 IAMMultiMediaStream *pams;
1591 HRESULT hr;
1592 IMediaStream *video_stream = NULL;
1593 IMediaStream *audio_stream = NULL;
1594 IMediaStreamFilter* media_stream_filter = NULL;
1596 if (!(pams = create_ammultimediastream()))
1597 return;
1599 hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL);
1600 ok(hr == S_OK, "IAMMultiMediaStream_Initialize returned: %x\n", hr);
1602 /* Retrieve media stream filter */
1603 hr = IAMMultiMediaStream_GetFilter(pams, NULL);
1604 ok(hr == E_POINTER, "IAMMultiMediaStream_GetFilter returned: %x\n", hr);
1605 hr = IAMMultiMediaStream_GetFilter(pams, &media_stream_filter);
1606 ok(hr == S_OK, "IAMMultiMediaStream_GetFilter returned: %x\n", hr);
1608 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryVideo, 0, NULL);
1609 ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
1610 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &video_stream);
1611 ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
1613 /* Check interfaces and samples for video */
1614 if (video_stream)
1616 IAMMediaStream* am_media_stream;
1617 IMultiMediaStream *multi_media_stream;
1618 IPin *pin = NULL;
1619 IAudioMediaStream* audio_media_stream;
1620 IDirectDrawMediaStream *ddraw_stream = NULL;
1621 IDirectDrawStreamSample *ddraw_sample = NULL;
1623 hr = IMediaStream_QueryInterface(video_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
1624 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
1625 ok((void*)am_media_stream == (void*)video_stream, "Not same interface, got %p expected %p\n", am_media_stream, video_stream);
1627 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, NULL);
1628 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
1630 multi_media_stream = (void *)0xdeadbeef;
1631 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, &multi_media_stream);
1632 ok(hr == S_OK, "IAMMediaStream_GetMultiMediaStream returned: %x\n", hr);
1633 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1634 IMultiMediaStream_Release(multi_media_stream);
1636 IAMMediaStream_Release(am_media_stream);
1638 hr = IMediaStream_QueryInterface(video_stream, &IID_IPin, (void **)&pin);
1639 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
1641 IPin_Release(pin);
1643 hr = IMediaStream_QueryInterface(video_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
1644 ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %x\n", hr);
1646 hr = IMediaStream_QueryInterface(video_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
1647 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
1649 if (SUCCEEDED(hr))
1651 DDSURFACEDESC current_format, desired_format;
1652 IDirectDrawPalette *palette;
1653 DWORD flags;
1655 hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, &palette, &desired_format, &flags);
1656 ok(hr == MS_E_NOSTREAM, "IDirectDrawoMediaStream_GetFormat returned: %x\n", hr);
1658 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &ddraw_sample);
1659 ok(hr == S_OK, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr);
1661 hr = IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream, NULL);
1662 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
1664 multi_media_stream = (void *)0xdeadbeef;
1665 hr = IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream, &multi_media_stream);
1666 ok(hr == S_OK, "IDirectDrawMediaStream_GetMultiMediaStream returned: %x\n", hr);
1667 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1668 IMultiMediaStream_Release(multi_media_stream);
1671 if (ddraw_sample)
1672 IDirectDrawStreamSample_Release(ddraw_sample);
1673 if (ddraw_stream)
1674 IDirectDrawMediaStream_Release(ddraw_stream);
1677 hr = IAMMultiMediaStream_AddMediaStream(pams, NULL, &MSPID_PrimaryAudio, 0, NULL);
1678 ok(hr == S_OK, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr);
1679 hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryAudio, &audio_stream);
1680 ok(hr == S_OK, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr);
1682 /* Check interfaces and samples for audio */
1683 if (audio_stream)
1685 IAMMediaStream* am_media_stream;
1686 IMultiMediaStream *multi_media_stream;
1687 IPin *pin = NULL;
1688 IDirectDrawMediaStream* ddraw_stream = NULL;
1689 IAudioMediaStream* audio_media_stream = NULL;
1690 IAudioStreamSample *audio_sample = NULL;
1692 hr = IMediaStream_QueryInterface(audio_stream, &IID_IAMMediaStream, (LPVOID*)&am_media_stream);
1693 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
1694 ok((void*)am_media_stream == (void*)audio_stream, "Not same interface, got %p expected %p\n", am_media_stream, audio_stream);
1696 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, NULL);
1697 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
1699 multi_media_stream = (void *)0xdeadbeef;
1700 hr = IAMMediaStream_GetMultiMediaStream(am_media_stream, &multi_media_stream);
1701 ok(hr == S_OK, "IAMMediaStream_GetMultiMediaStream returned: %x\n", hr);
1702 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1703 IMultiMediaStream_Release(multi_media_stream);
1705 IAMMediaStream_Release(am_media_stream);
1707 hr = IMediaStream_QueryInterface(audio_stream, &IID_IPin, (void **)&pin);
1708 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
1710 IPin_Release(pin);
1712 hr = IMediaStream_QueryInterface(audio_stream, &IID_IDirectDrawMediaStream, (LPVOID*)&ddraw_stream);
1713 ok(hr == E_NOINTERFACE, "IMediaStream_QueryInterface returned: %x\n", hr);
1715 hr = IMediaStream_QueryInterface(audio_stream, &IID_IAudioMediaStream, (LPVOID*)&audio_media_stream);
1716 ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
1718 if (SUCCEEDED(hr))
1720 IAudioData* audio_data = NULL;
1722 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
1723 ok(hr == S_OK, "CoCreateInstance returned: %x\n", hr);
1725 hr = IAudioMediaStream_CreateSample(audio_media_stream, NULL, 0, &audio_sample);
1726 ok(hr == E_POINTER, "IAudioMediaStream_CreateSample returned: %x\n", hr);
1728 EXPECT_REF(audio_stream, 3);
1729 EXPECT_REF(audio_data, 1);
1730 hr = IAudioMediaStream_CreateSample(audio_media_stream, audio_data, 0, &audio_sample);
1731 ok(hr == S_OK, "IAudioMediaStream_CreateSample returned: %x\n", hr);
1732 EXPECT_REF(audio_stream, 4);
1733 EXPECT_REF(audio_data, 2);
1735 hr = IAudioMediaStream_GetMultiMediaStream(audio_media_stream, NULL);
1736 ok(hr == E_POINTER, "Expected E_POINTER, got %x\n", hr);
1738 multi_media_stream = (void *)0xdeadbeef;
1739 hr = IAudioMediaStream_GetMultiMediaStream(audio_media_stream, &multi_media_stream);
1740 ok(hr == S_OK, "IAudioMediaStream_GetMultiMediaStream returned: %x\n", hr);
1741 ok((void *)multi_media_stream == (void *)pams, "Expected %p, got %p\n", pams, multi_media_stream);
1742 IMultiMediaStream_Release(multi_media_stream);
1744 if (audio_data)
1745 IAudioData_Release(audio_data);
1746 if (audio_sample)
1747 IAudioStreamSample_Release(audio_sample);
1748 if (audio_media_stream)
1749 IAudioMediaStream_Release(audio_media_stream);
1753 if (media_stream_filter)
1755 IEnumPins *enum_pins;
1757 hr = IMediaStreamFilter_EnumPins(media_stream_filter, &enum_pins);
1758 ok(hr == S_OK, "IBaseFilter_EnumPins returned: %x\n", hr);
1759 if (hr == S_OK)
1761 IPin* pins[3] = { NULL, NULL, NULL };
1762 ULONG nb_pins;
1763 ULONG expected_nb_pins = audio_stream ? 2 : 1;
1764 int i;
1766 hr = IEnumPins_Next(enum_pins, 3, pins, &nb_pins);
1767 ok(SUCCEEDED(hr), "IEnumPins_Next returned: %x\n", hr);
1768 ok(nb_pins == expected_nb_pins, "Number of pins is %u instead of %u\n", nb_pins, expected_nb_pins);
1769 for (i = 0; i < min(nb_pins, expected_nb_pins); i++)
1771 IPin* pin;
1773 hr = IPin_ConnectedTo(pins[i], &pin);
1774 ok(hr == VFW_E_NOT_CONNECTED, "IPin_ConnectedTo returned: %x\n", hr);
1775 IPin_Release(pins[i]);
1777 IEnumPins_Release(enum_pins);
1781 /* Test open file with no filename */
1782 hr = IAMMultiMediaStream_OpenFile(pams, NULL, 0);
1783 ok(hr == E_POINTER, "IAMMultiMediaStream_OpenFile returned %x instead of %x\n", hr, E_POINTER);
1785 if (video_stream)
1786 IMediaStream_Release(video_stream);
1787 if (audio_stream)
1788 IMediaStream_Release(audio_stream);
1789 if (media_stream_filter)
1790 IMediaStreamFilter_Release(media_stream_filter);
1792 IAMMultiMediaStream_Release(pams);
1795 static void test_enum_pins(void)
1797 IAMMultiMediaStream *mmstream = create_ammultimediastream();
1798 IMediaStreamFilter *filter;
1799 IEnumPins *enum1, *enum2;
1800 IMediaStream *stream;
1801 IPin *pins[3], *pin;
1802 ULONG ref, count;
1803 HRESULT hr;
1805 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
1806 ok(hr == S_OK, "Got hr %#x.\n", hr);
1808 ref = get_refcount(filter);
1809 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
1811 hr = IMediaStreamFilter_EnumPins(filter, NULL);
1812 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1814 hr = IMediaStreamFilter_EnumPins(filter, &enum1);
1815 ok(hr == S_OK, "Got hr %#x.\n", hr);
1816 ref = get_refcount(filter);
1817 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
1818 ref = get_refcount(enum1);
1819 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
1821 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
1822 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1824 hr = IEnumPins_Next(enum1, 1, pins, NULL);
1825 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1827 hr = IEnumPins_Reset(enum1);
1828 ok(hr == S_OK, "Got hr %#x.\n", hr);
1830 hr = IEnumPins_Skip(enum1, 0);
1831 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1833 hr = IEnumPins_Skip(enum1, 1);
1834 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1836 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1837 ok(hr == S_OK, "Got hr %#x.\n", hr);
1838 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1839 ok(hr == S_OK, "Got hr %#x.\n", hr);
1841 /* Reset() isn't enough; we have to call EnumPins() again to see the updated
1842 * pin count. */
1843 hr = IEnumPins_Reset(enum1);
1844 ok(hr == S_OK, "Got hr %#x.\n", hr);
1846 hr = IEnumPins_Next(enum1, 1, pins, NULL);
1847 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1849 IEnumPins_Release(enum1);
1851 hr = IMediaStreamFilter_EnumPins(filter, &enum1);
1852 ok(hr == S_OK, "Got hr %#x.\n", hr);
1854 ref = get_refcount(filter);
1855 ok(ref == 4, "Got unexpected refcount %d.\n", ref);
1856 ref = get_refcount(enum1);
1857 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
1858 ref = get_refcount(pin);
1859 ok(ref == 4, "Got unexpected refcount %d.\n", ref);
1861 hr = IEnumPins_Next(enum1, 1, pins, NULL);
1862 ok(hr == S_OK, "Got hr %#x.\n", hr);
1863 ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
1864 ref = get_refcount(filter);
1865 ok(ref == 4, "Got unexpected refcount %d.\n", ref);
1866 ref = get_refcount(enum1);
1867 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
1868 ref = get_refcount(pin);
1869 ok(ref == 5, "Got unexpected refcount %d.\n", ref);
1870 IPin_Release(pins[0]);
1872 hr = IEnumPins_Next(enum1, 1, pins, NULL);
1873 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1875 hr = IEnumPins_Reset(enum1);
1876 ok(hr == S_OK, "Got hr %#x.\n", hr);
1878 hr = IEnumPins_Next(enum1, 1, pins, &count);
1879 ok(hr == S_OK, "Got hr %#x.\n", hr);
1880 ok(count == 1, "Got count %u.\n", count);
1881 ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
1882 IPin_Release(pins[0]);
1884 hr = IEnumPins_Reset(enum1);
1885 ok(hr == S_OK, "Got hr %#x.\n", hr);
1887 hr = IEnumPins_Next(enum1, 2, pins, NULL);
1888 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
1890 hr = IEnumPins_Next(enum1, 2, pins, &count);
1891 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1892 ok(count == 1, "Got count %u.\n", count);
1893 ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
1894 IPin_Release(pins[0]);
1896 hr = IEnumPins_Reset(enum1);
1897 ok(hr == S_OK, "Got hr %#x.\n", hr);
1899 hr = IEnumPins_Clone(enum1, &enum2);
1900 ok(hr == S_OK, "Got hr %#x.\n", hr);
1902 hr = IEnumPins_Skip(enum1, 0);
1903 ok(hr == S_OK, "Got hr %#x.\n", hr);
1905 hr = IEnumPins_Skip(enum1, 1);
1906 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1908 hr = IEnumPins_Next(enum1, 1, pins, NULL);
1909 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
1911 hr = IEnumPins_Next(enum2, 1, pins, NULL);
1912 ok(hr == S_OK, "Got hr %#x.\n", hr);
1913 ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]);
1914 IPin_Release(pins[0]);
1916 IEnumPins_Release(enum2);
1917 IEnumPins_Release(enum1);
1919 IMediaStreamFilter_Release(filter);
1920 ref = IAMMultiMediaStream_Release(mmstream);
1921 ok(!ref, "Got outstanding refcount %d.\n", ref);
1922 IMediaStream_Release(stream);
1923 ref = IPin_Release(pin);
1924 ok(!ref, "Got outstanding refcount %d.\n", ref);
1927 static void test_find_pin(void)
1929 IAMMultiMediaStream *mmstream = create_ammultimediastream();
1930 IMediaStreamFilter *filter;
1931 IMediaStream *stream;
1932 IPin *pin, *pin2;
1933 HRESULT hr;
1934 ULONG ref;
1936 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
1937 ok(hr == S_OK, "Got hr %#x.\n", hr);
1939 hr = IMediaStreamFilter_FindPin(filter, primary_video_sink_id, &pin2);
1940 ok(hr == VFW_E_NOT_FOUND, "Got hr %#x.\n", hr);
1942 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1943 ok(hr == S_OK, "Got hr %#x.\n", hr);
1944 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1945 ok(hr == S_OK, "Got hr %#x.\n", hr);
1947 hr = IMediaStreamFilter_FindPin(filter, primary_video_sink_id, &pin2);
1948 ok(hr == S_OK, "Got hr %#x.\n", hr);
1949 ok(pin2 == pin, "Expected pin %p, got %p.\n", pin, pin2);
1951 IPin_Release(pin2);
1952 IPin_Release(pin);
1953 IMediaStream_Release(stream);
1954 IMediaStreamFilter_Release(filter);
1955 ref = IAMMultiMediaStream_Release(mmstream);
1956 ok(!ref, "Got outstanding refcount %d.\n", ref);
1959 static void test_pin_info(void)
1961 IAMMultiMediaStream *mmstream = create_ammultimediastream();
1962 IMediaStreamFilter *filter;
1963 IMediaStream *stream;
1964 PIN_DIRECTION dir;
1965 ULONG ref, count;
1966 PIN_INFO info;
1967 HRESULT hr;
1968 WCHAR *id;
1969 IPin *pin;
1971 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
1972 ok(hr == S_OK, "Got hr %#x.\n", hr);
1974 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
1975 ok(hr == S_OK, "Got hr %#x.\n", hr);
1976 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
1977 ok(hr == S_OK, "Got hr %#x.\n", hr);
1979 hr = IPin_QueryPinInfo(pin, &info);
1980 ok(hr == S_OK, "Got hr %#x.\n", hr);
1981 ok(info.pFilter == (IBaseFilter *)filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
1982 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
1983 ok(!wcscmp(info.achName, primary_video_sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
1984 IBaseFilter_Release(info.pFilter);
1986 hr = IPin_QueryDirection(pin, &dir);
1987 ok(hr == S_OK, "Got hr %#x.\n", hr);
1988 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
1990 hr = IPin_QueryId(pin, &id);
1991 ok(hr == S_OK, "Got hr %#x.\n", hr);
1992 ok(!wcscmp(id, primary_video_sink_id), "Got id %s.\n", wine_dbgstr_w(id));
1993 CoTaskMemFree(id);
1995 hr = IPin_QueryInternalConnections(pin, NULL, &count);
1996 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
1998 IPin_Release(pin);
1999 IMediaStream_Release(stream);
2001 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
2002 ok(hr == S_OK, "Got hr %#x.\n", hr);
2003 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2004 ok(hr == S_OK, "Got hr %#x.\n", hr);
2006 hr = IPin_QueryPinInfo(pin, &info);
2007 ok(hr == S_OK, "Got hr %#x.\n", hr);
2008 ok(info.pFilter == (IBaseFilter *)filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
2009 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
2010 ok(!wcscmp(info.achName, primary_audio_sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
2011 IBaseFilter_Release(info.pFilter);
2013 hr = IPin_QueryDirection(pin, &dir);
2014 ok(hr == S_OK, "Got hr %#x.\n", hr);
2015 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
2017 hr = IPin_QueryId(pin, &id);
2018 ok(hr == S_OK, "Got hr %#x.\n", hr);
2019 ok(!wcscmp(id, primary_audio_sink_id), "Got id %s.\n", wine_dbgstr_w(id));
2020 CoTaskMemFree(id);
2022 hr = IPin_QueryInternalConnections(pin, NULL, &count);
2023 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
2025 IPin_Release(pin);
2026 IMediaStream_Release(stream);
2028 IMediaStreamFilter_Release(filter);
2029 ref = IAMMultiMediaStream_Release(mmstream);
2030 ok(!ref, "Got outstanding refcount %d.\n", ref);
2033 static IUnknown *graph_inner_unk;
2034 static IFilterGraph2 *graph_inner;
2035 static LONG graph_refcount = 1;
2036 static unsigned int got_add_filter;
2037 static IBaseFilter *graph_filter;
2038 static WCHAR graph_filter_name[128];
2040 static HRESULT WINAPI graph_QueryInterface(IFilterGraph2 *iface, REFIID iid, void **out)
2042 if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
2043 if (IsEqualGUID(iid, &IID_IFilterGraph2)
2044 || IsEqualGUID(iid, &IID_IGraphBuilder)
2045 || IsEqualGUID(iid, &IID_IFilterGraph)
2046 || IsEqualGUID(iid, &IID_IUnknown))
2048 *out = iface;
2049 IFilterGraph2_AddRef(iface);
2050 return S_OK;
2052 else if (IsEqualGUID(iid, &IID_IMediaSeeking)
2053 || IsEqualGUID(iid, &IID_IMediaControl)
2054 || IsEqualGUID(iid, &IID_IMediaEventEx))
2056 return IUnknown_QueryInterface(graph_inner_unk, iid, out);
2058 return E_NOINTERFACE;
2061 static ULONG WINAPI graph_AddRef(IFilterGraph2 *iface)
2063 return InterlockedIncrement(&graph_refcount);
2066 static ULONG WINAPI graph_Release(IFilterGraph2 *iface)
2068 return InterlockedDecrement(&graph_refcount);
2071 static HRESULT WINAPI graph_AddFilter(IFilterGraph2 *iface, IBaseFilter *filter, const WCHAR *name)
2073 if (winetest_debug > 1) trace("AddFilter(%p, %s)\n", filter, wine_dbgstr_w(name));
2074 ++got_add_filter;
2075 graph_filter = filter;
2076 if (name)
2077 wcscpy(graph_filter_name, name);
2078 else
2079 graph_filter_name[0] = 0;
2080 return IFilterGraph2_AddFilter(graph_inner, filter, name);
2083 static HRESULT WINAPI graph_RemoveFilter(IFilterGraph2 *iface, IBaseFilter *filter)
2085 ok(0, "Unexpected call.\n");
2086 return E_NOTIMPL;
2089 static HRESULT WINAPI graph_EnumFilters(IFilterGraph2 *iface, IEnumFilters **enumfilters)
2091 if (winetest_debug > 1) trace("EnumFilters()\n");
2092 return IFilterGraph2_EnumFilters(graph_inner, enumfilters);
2095 static HRESULT WINAPI graph_FindFilterByName(IFilterGraph2 *iface, const WCHAR *name, IBaseFilter **filter)
2097 ok(0, "Unexpected call.\n");
2098 return E_NOTIMPL;
2101 static HRESULT WINAPI graph_ConnectDirect(IFilterGraph2 *iface, IPin *source, IPin *sink, const AM_MEDIA_TYPE *mt)
2103 ok(0, "Unexpected call.\n");
2104 return E_NOTIMPL;
2107 static HRESULT WINAPI graph_Reconnect(IFilterGraph2 *iface, IPin *pin)
2109 ok(0, "Unexpected call.\n");
2110 return E_NOTIMPL;
2113 static HRESULT WINAPI graph_Disconnect(IFilterGraph2 *iface, IPin *pin)
2115 ok(0, "Unexpected call.\n");
2116 return E_NOTIMPL;
2119 static HRESULT WINAPI graph_SetDefaultSyncSource(IFilterGraph2 *iface)
2121 ok(0, "Unexpected call.\n");
2122 return E_NOTIMPL;
2125 static HRESULT WINAPI graph_Connect(IFilterGraph2 *iface, IPin *source, IPin *sink)
2127 ok(0, "Unexpected call.\n");
2128 return E_NOTIMPL;
2131 static HRESULT WINAPI graph_Render(IFilterGraph2 *iface, IPin *source)
2133 ok(0, "Unexpected call.\n");
2134 return E_NOTIMPL;
2137 static HRESULT WINAPI graph_RenderFile(IFilterGraph2 *iface, const WCHAR *filename, const WCHAR *playlist)
2139 ok(0, "Unexpected call.\n");
2140 return E_NOTIMPL;
2143 static HRESULT WINAPI graph_AddSourceFilter(IFilterGraph2 *iface,
2144 const WCHAR *filename, const WCHAR *filter_name, IBaseFilter **filter)
2146 ok(0, "Unexpected call.\n");
2147 return E_NOTIMPL;
2150 static HRESULT WINAPI graph_SetLogFile(IFilterGraph2 *iface, DWORD_PTR file)
2152 ok(0, "Unexpected call.\n");
2153 return E_NOTIMPL;
2156 static HRESULT WINAPI graph_Abort(IFilterGraph2 *iface)
2158 ok(0, "Unexpected call.\n");
2159 return E_NOTIMPL;
2162 static HRESULT WINAPI graph_ShouldOperationContinue(IFilterGraph2 *iface)
2164 ok(0, "Unexpected call.\n");
2165 return E_NOTIMPL;
2168 static HRESULT WINAPI graph_AddSourceFilterForMoniker(IFilterGraph2 *iface,
2169 IMoniker *moniker, IBindCtx *bind_ctx, const WCHAR *filter_name, IBaseFilter **filter)
2171 ok(0, "Unexpected call.\n");
2172 return E_NOTIMPL;
2175 static HRESULT WINAPI graph_ReconnectEx(IFilterGraph2 *iface, IPin *pin, const AM_MEDIA_TYPE *mt)
2177 ok(0, "Unexpected call.\n");
2178 return E_NOTIMPL;
2181 static HRESULT WINAPI graph_RenderEx(IFilterGraph2 *iface, IPin *pin, DWORD flags, DWORD *context)
2183 ok(0, "Unexpected call.\n");
2184 return E_NOTIMPL;
2187 static const IFilterGraph2Vtbl graph_vtbl =
2189 graph_QueryInterface,
2190 graph_AddRef,
2191 graph_Release,
2192 graph_AddFilter,
2193 graph_RemoveFilter,
2194 graph_EnumFilters,
2195 graph_FindFilterByName,
2196 graph_ConnectDirect,
2197 graph_Reconnect,
2198 graph_Disconnect,
2199 graph_SetDefaultSyncSource,
2200 graph_Connect,
2201 graph_Render,
2202 graph_RenderFile,
2203 graph_AddSourceFilter,
2204 graph_SetLogFile,
2205 graph_Abort,
2206 graph_ShouldOperationContinue,
2207 graph_AddSourceFilterForMoniker,
2208 graph_ReconnectEx,
2209 graph_RenderEx,
2212 static void test_initialize(void)
2214 IAMMultiMediaStream *mmstream = create_ammultimediastream();
2215 IFilterGraph2 graph = {&graph_vtbl};
2216 IMediaStreamFilter *filter;
2217 IGraphBuilder *ret_graph;
2218 IMediaStream *stream;
2219 STREAM_TYPE type;
2220 HRESULT hr;
2221 ULONG ref;
2223 ret_graph = (IGraphBuilder *)0xdeadbeef;
2224 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2225 ok(hr == S_OK, "Got hr %#x.\n", hr);
2226 ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2228 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
2229 ok(hr == S_OK, "Got hr %#x.\n", hr);
2230 ok(!!filter, "Expected a non-NULL filter.");
2231 IMediaStreamFilter_Release(filter);
2233 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2234 ok(hr == S_OK, "Got hr %#x.\n", hr);
2236 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2237 ok(hr == S_OK, "Got hr %#x.\n", hr);
2238 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
2239 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2240 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2241 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2243 ret_graph = (IGraphBuilder *)0xdeadbeef;
2244 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2245 ok(hr == S_OK, "Got hr %#x.\n", hr);
2246 ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2248 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2249 ok(hr == S_OK, "Got hr %#x.\n", hr);
2250 type = 0xdeadbeef;
2251 hr = IMediaStream_GetInformation(stream, NULL, &type);
2252 ok(hr == S_OK, "Got hr %#x.\n", hr);
2253 ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
2254 IMediaStream_Release(stream);
2256 ret_graph = NULL;
2257 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2258 ok(hr == S_OK, "Got hr %#x.\n", hr);
2259 ok(!!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2260 IGraphBuilder_Release(ret_graph);
2262 ref = IAMMultiMediaStream_Release(mmstream);
2263 ok(!ref, "Got outstanding refcount %d.\n", ref);
2265 mmstream = create_ammultimediastream();
2267 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
2268 ok(hr == S_OK, "Got hr %#x.\n", hr);
2270 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
2271 ok(hr == S_OK, "Got hr %#x.\n", hr);
2272 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2273 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2274 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2275 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2277 ret_graph = (IGraphBuilder *)0xdeadbeef;
2278 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2279 ok(hr == S_OK, "Got hr %#x.\n", hr);
2280 ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2282 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2283 ok(hr == S_OK, "Got hr %#x.\n", hr);
2284 type = 0xdeadbeef;
2285 hr = IMediaStream_GetInformation(stream, NULL, &type);
2286 ok(hr == S_OK, "Got hr %#x.\n", hr);
2287 ok(type == STREAMTYPE_WRITE, "Got type %u.\n", type);
2288 IMediaStream_Release(stream);
2290 ref = IAMMultiMediaStream_Release(mmstream);
2291 ok(!ref, "Got outstanding refcount %d.\n", ref);
2293 mmstream = create_ammultimediastream();
2295 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2296 ok(hr == S_OK, "Got hr %#x.\n", hr);
2298 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2299 ok(hr == S_OK, "Got hr %#x.\n", hr);
2300 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2301 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2302 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
2303 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2305 ret_graph = (IGraphBuilder *)0xdeadbeef;
2306 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2307 ok(hr == S_OK, "Got hr %#x.\n", hr);
2308 ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2310 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2311 ok(hr == S_OK, "Got hr %#x.\n", hr);
2312 type = 0xdeadbeef;
2313 hr = IMediaStream_GetInformation(stream, NULL, &type);
2314 ok(hr == S_OK, "Got hr %#x.\n", hr);
2315 ok(type == STREAMTYPE_TRANSFORM, "Got type %u.\n", type);
2316 IMediaStream_Release(stream);
2318 ref = IAMMultiMediaStream_Release(mmstream);
2319 ok(!ref, "Got outstanding refcount %d.\n", ref);
2321 mmstream = create_ammultimediastream();
2323 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2324 ok(hr == S_OK, "Got hr %#x.\n", hr);
2326 type = 0xdeadbeef;
2327 hr = IMediaStream_GetInformation(stream, NULL, &type);
2328 ok(hr == S_OK, "Got hr %#x.\n", hr);
2329 ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
2331 ret_graph = NULL;
2332 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2333 ok(hr == S_OK, "Got hr %#x.\n", hr);
2334 ok(!!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2335 IGraphBuilder_Release(ret_graph);
2337 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2338 ok(hr == S_OK, "Got hr %#x.\n", hr);
2340 type = 0xdeadbeef;
2341 hr = IMediaStream_GetInformation(stream, NULL, &type);
2342 ok(hr == S_OK, "Got hr %#x.\n", hr);
2343 ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
2345 IMediaStream_Release(stream);
2346 ref = IAMMultiMediaStream_Release(mmstream);
2347 ok(!ref, "Got outstanding refcount %d.\n", ref);
2349 /* Test with a custom filter graph. */
2351 mmstream = create_ammultimediastream();
2353 CoCreateInstance(&CLSID_FilterGraph, (IUnknown *)&graph, CLSCTX_INPROC_SERVER,
2354 &IID_IUnknown, (void **)&graph_inner_unk);
2355 IUnknown_QueryInterface(graph_inner_unk, &IID_IFilterGraph2, (void **)&graph_inner);
2357 ret_graph = (IGraphBuilder *)0xdeadbeef;
2358 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2359 ok(hr == S_OK, "Got hr %#x.\n", hr);
2360 ok(!ret_graph, "Got unexpected graph %p.\n", ret_graph);
2362 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
2363 ok(hr == S_OK, "Got hr %#x.\n", hr);
2364 ok(!!filter, "Expected a non-NULL filter.");
2366 got_add_filter = 0;
2367 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, (IGraphBuilder *)&graph);
2368 ok(hr == S_OK, "Got hr %#x.\n", hr);
2369 ok(got_add_filter == 1, "Got %d calls to IGraphBuilder::AddFilter().\n", got_add_filter);
2370 ok(graph_filter == (IBaseFilter *)filter, "Got filter %p.\n", filter);
2371 ok(!wcscmp(graph_filter_name, L"MediaStreamFilter"), "Got unexpected name %s.\n", wine_dbgstr_w(graph_filter_name));
2373 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &ret_graph);
2374 ok(hr == S_OK, "Got hr %#x.\n", hr);
2375 ok(ret_graph == (IGraphBuilder *)&graph, "Got unexpected graph %p.\n", ret_graph);
2376 IGraphBuilder_Release(ret_graph);
2378 got_add_filter = 0;
2379 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
2380 ok(hr == S_OK, "Got hr %#x.\n", hr);
2381 ok(!got_add_filter, "Got %d calls to IGraphBuilder::AddFilter().\n", got_add_filter);
2383 got_add_filter = 0;
2384 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, NULL);
2385 ok(hr == S_OK, "Got hr %#x.\n", hr);
2386 ok(!got_add_filter, "Got %d calls to IGraphBuilder::AddFilter().\n", got_add_filter);
2388 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, (IGraphBuilder *)&graph);
2389 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2390 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2391 ok(hr == S_OK, "Got hr %#x.\n", hr);
2392 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_WRITE, 0, NULL);
2393 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2394 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_TRANSFORM, 0, NULL);
2395 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
2397 IMediaStreamFilter_Release(filter);
2398 ref = IAMMultiMediaStream_Release(mmstream);
2399 ok(!ref, "Got outstanding refcount %d.\n", ref);
2400 IFilterGraph2_Release(graph_inner);
2401 ok(graph_refcount == 1, "Got outstanding refcount %d.\n", graph_refcount);
2402 IUnknown_Release(graph_inner_unk);
2405 static IAMMultiMediaStream *mmstream_mmstream;
2406 static STREAM_STATE mmstream_state;
2408 static DWORD CALLBACK mmstream_set_state(void *param)
2410 HRESULT hr;
2412 hr = IAMMultiMediaStream_SetState(mmstream_mmstream, mmstream_state);
2413 ok(hr == S_OK, "Got hr %#x.\n", hr);
2415 return 0;
2418 static void test_set_state(void)
2420 IAMMultiMediaStream *mmstream = create_ammultimediastream();
2421 IMediaControl *media_control;
2422 struct testfilter source;
2423 IGraphBuilder *graph;
2424 STREAM_STATE state;
2425 HANDLE thread;
2426 HRESULT hr;
2427 ULONG ref;
2429 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
2430 ok(hr == S_OK, "Got hr %#x.\n", hr);
2431 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
2432 ok(hr == S_OK, "Got hr %#x.\n", hr);
2433 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
2434 ok(hr == S_OK, "Got hr %#x.\n", hr);
2435 ok(graph != NULL, "Expected non-NULL graph.\n");
2436 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
2437 ok(hr == S_OK, "Got hr %#x.\n", hr);
2438 testfilter_init(&source);
2440 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
2441 ok(hr == S_OK, "Got hr %#x.\n", hr);
2443 source.init_stream_hr = E_FAIL;
2444 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2445 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
2446 source.init_stream_hr = S_OK;
2447 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2448 ok(hr == S_OK, "Got hr %#x.\n", hr);
2450 source.init_stream_hr = S_FALSE;
2451 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2452 ok(hr == S_OK, "Got hr %#x.\n", hr);
2453 source.init_stream_hr = S_OK;
2454 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2455 ok(hr == S_OK, "Got hr %#x.\n", hr);
2457 source.wait_state_hr = E_FAIL;
2458 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2459 ok(hr == S_OK, "Got hr %#x.\n", hr);
2460 source.wait_state_hr = S_OK;
2461 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2462 ok(hr == S_OK, "Got hr %#x.\n", hr);
2464 source.wait_state_hr = VFW_S_STATE_INTERMEDIATE;
2465 ResetEvent(source.wait_state_event);
2467 mmstream_mmstream = mmstream;
2468 mmstream_state = STREAMSTATE_RUN;
2469 thread = CreateThread(NULL, 0, mmstream_set_state, NULL, 0, NULL);
2471 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "SetState returned prematurely.\n");
2473 EnterCriticalSection(&source.filter.filter_cs);
2474 source.wait_state_hr = S_OK;
2475 SetEvent(source.wait_state_event);
2476 LeaveCriticalSection(&source.filter.filter_cs);
2478 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
2479 CloseHandle(thread);
2481 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2482 ok(hr == S_OK, "Got hr %#x.\n", hr);
2484 source.init_stream_hr = E_FAIL;
2485 source.wait_state_hr = VFW_S_STATE_INTERMEDIATE;
2486 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2487 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
2488 source.init_stream_hr = S_OK;
2489 source.wait_state_hr = S_OK;
2490 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2491 ok(hr == S_OK, "Got hr %#x.\n", hr);
2493 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2494 ok(hr == S_OK, "Got hr %#x.\n", hr);
2495 source.cleanup_stream_hr = E_FAIL;
2496 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2497 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
2498 source.cleanup_stream_hr = S_OK;
2499 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2500 ok(hr == S_OK, "Got hr %#x.\n", hr);
2502 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2503 ok(hr == S_OK, "Got hr %#x.\n", hr);
2504 source.cleanup_stream_hr = S_FALSE;
2505 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2506 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
2507 source.cleanup_stream_hr = S_OK;
2509 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2510 ok(hr == S_OK, "Got hr %#x.\n", hr);
2511 source.wait_state_hr = VFW_S_STATE_INTERMEDIATE;
2512 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2513 ok(hr == S_OK, "Got hr %#x.\n", hr);
2514 source.wait_state_hr = S_OK;
2516 /* Crashes on native. */
2517 if (0)
2519 hr = IAMMultiMediaStream_GetState(mmstream, NULL);
2520 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
2523 state = 0xdeadbeef;
2524 hr = IAMMultiMediaStream_GetState(mmstream, &state);
2525 ok(hr == S_OK, "Got hr %#x.\n", hr);
2526 ok(state == STREAMSTATE_STOP, "Got state %#x.\n", state);
2528 hr = IMediaControl_Run(media_control);
2529 ok(hr == S_OK, "Got hr %#x.\n", hr);
2531 state = 0xdeadbeef;
2532 hr = IAMMultiMediaStream_GetState(mmstream, &state);
2533 ok(hr == S_OK, "Got hr %#x.\n", hr);
2534 ok(state == STREAMSTATE_STOP, "Got state %#x.\n", state);
2536 hr = IMediaControl_Stop(media_control);
2537 ok(hr == S_OK, "Got hr %#x.\n", hr);
2539 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2540 ok(hr == S_OK, "Got hr %#x.\n", hr);
2542 state = 0xdeadbeef;
2543 hr = IAMMultiMediaStream_GetState(mmstream, &state);
2544 ok(hr == S_OK, "Got hr %#x.\n", hr);
2545 ok(state == STREAMSTATE_RUN, "Got state %#x.\n", state);
2547 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
2548 ok(hr == S_OK, "Got hr %#x.\n", hr);
2550 state = 0xdeadbeef;
2551 hr = IAMMultiMediaStream_GetState(mmstream, &state);
2552 ok(hr == S_OK, "Got hr %#x.\n", hr);
2553 ok(state == STREAMSTATE_STOP, "Got state %#x.\n", state);
2555 source.init_stream_hr = E_FAIL;
2556 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
2557 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
2559 state = 0xdeadbeef;
2560 hr = IAMMultiMediaStream_GetState(mmstream, &state);
2561 ok(hr == S_OK, "Got hr %#x.\n", hr);
2562 ok(state == STREAMSTATE_STOP, "Got state %#x.\n", state);
2564 ref = IAMMultiMediaStream_Release(mmstream);
2565 ok(!ref, "Got outstanding refcount %d.\n", ref);
2566 IMediaControl_Release(media_control);
2567 ref = IGraphBuilder_Release(graph);
2568 ok(!ref, "Got outstanding refcount %d.\n", ref);
2571 static void test_enum_media_types(void)
2573 IAMMultiMediaStream *mmstream = create_ammultimediastream();
2574 IEnumMediaTypes *enum1, *enum2;
2575 AM_MEDIA_TYPE *mts[2];
2576 IMediaStream *stream;
2577 ULONG ref, count;
2578 HRESULT hr;
2579 IPin *pin;
2581 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2582 ok(hr == S_OK, "Got hr %#x.\n", hr);
2583 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2584 ok(hr == S_OK, "Got hr %#x.\n", hr);
2586 hr = IPin_EnumMediaTypes(pin, &enum1);
2587 ok(hr == S_OK, "Got hr %#x.\n", hr);
2589 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
2590 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
2592 hr = IEnumMediaTypes_Next(enum1, 0, mts, &count);
2593 ok(hr == S_OK, "Got hr %#x.\n", hr);
2594 ok(!count, "Got count %u.\n", count);
2596 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2597 ok(hr == S_OK, "Got hr %#x.\n", hr);
2598 ok(count == 1, "Got count %u.\n", count);
2599 CoTaskMemFree(mts[0]);
2601 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2602 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
2603 ok(!count, "Got count %u.\n", count);
2605 hr = IEnumMediaTypes_Reset(enum1);
2606 ok(hr == S_OK, "Got hr %#x.\n", hr);
2608 hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
2609 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
2610 ok(count == 1, "Got count %u.\n", count);
2611 CoTaskMemFree(mts[0]);
2613 hr = IEnumMediaTypes_Reset(enum1);
2614 ok(hr == S_OK, "Got hr %#x.\n", hr);
2616 hr = IEnumMediaTypes_Clone(enum1, &enum2);
2617 ok(hr == S_OK, "Got hr %#x.\n", hr);
2619 hr = IEnumMediaTypes_Skip(enum1, 2);
2620 ok(hr == S_OK, "Got hr %#x.\n", hr);
2622 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2623 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
2624 ok(!count, "Got count %u.\n", count);
2626 hr = IEnumMediaTypes_Next(enum2, 1, mts, &count);
2627 ok(hr == S_OK, "Got hr %#x.\n", hr);
2628 ok(count == 1, "Got count %u.\n", count);
2629 CoTaskMemFree(mts[0]);
2631 IEnumMediaTypes_Release(enum2);
2632 IEnumMediaTypes_Release(enum1);
2633 IPin_Release(pin);
2634 IMediaStream_Release(stream);
2636 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
2637 ok(hr == S_OK, "Got hr %#x.\n", hr);
2638 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2639 ok(hr == S_OK, "Got hr %#x.\n", hr);
2641 hr = IPin_EnumMediaTypes(pin, &enum1);
2642 ok(hr == S_OK, "Got hr %#x.\n", hr);
2644 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
2645 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
2647 hr = IEnumMediaTypes_Next(enum1, 0, mts, &count);
2648 ok(hr == S_OK, "Got hr %#x.\n", hr);
2649 ok(!count, "Got count %u.\n", count);
2651 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2652 ok(hr == S_OK, "Got hr %#x.\n", hr);
2653 ok(count == 1, "Got count %u.\n", count);
2654 CoTaskMemFree(mts[0]->pbFormat);
2655 CoTaskMemFree(mts[0]);
2657 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2658 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
2659 ok(!count, "Got count %u.\n", count);
2661 hr = IEnumMediaTypes_Reset(enum1);
2662 ok(hr == S_OK, "Got hr %#x.\n", hr);
2664 hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
2665 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
2666 ok(count == 1, "Got count %u.\n", count);
2667 CoTaskMemFree(mts[0]->pbFormat);
2668 CoTaskMemFree(mts[0]);
2670 hr = IEnumMediaTypes_Reset(enum1);
2671 ok(hr == S_OK, "Got hr %#x.\n", hr);
2673 hr = IEnumMediaTypes_Clone(enum1, &enum2);
2674 ok(hr == S_OK, "Got hr %#x.\n", hr);
2676 hr = IEnumMediaTypes_Skip(enum1, 2);
2677 ok(hr == S_OK, "Got hr %#x.\n", hr);
2679 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
2680 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
2681 ok(!count, "Got count %u.\n", count);
2683 hr = IEnumMediaTypes_Next(enum2, 1, mts, &count);
2684 ok(hr == S_OK, "Got hr %#x.\n", hr);
2685 ok(count == 1, "Got count %u.\n", count);
2686 CoTaskMemFree(mts[0]->pbFormat);
2687 CoTaskMemFree(mts[0]);
2689 IEnumMediaTypes_Release(enum2);
2690 IEnumMediaTypes_Release(enum1);
2691 IPin_Release(pin);
2692 IMediaStream_Release(stream);
2694 ref = IAMMultiMediaStream_Release(mmstream);
2695 ok(!ref, "Got outstanding refcount %d.\n", ref);
2698 static void test_media_types(void)
2700 static const VIDEOINFOHEADER2 req_vih2;
2701 static const VIDEOINFOHEADER req_vih;
2702 static const MPEG2VIDEOINFO req_m2vi;
2703 static const MPEG1VIDEOINFO req_m1vi;
2704 static const WAVEFORMATEX req_wfx;
2705 static const WAVEFORMATEX expect_wfx =
2707 .wFormatTag = WAVE_FORMAT_PCM,
2708 .nChannels = 1,
2709 .nSamplesPerSec = 11025,
2710 .nAvgBytesPerSec = 11025 * 2,
2711 .nBlockAlign = 2,
2712 .wBitsPerSample = 16,
2713 .cbSize = 0,
2715 IAMMultiMediaStream *mmstream = create_ammultimediastream();
2716 IEnumMediaTypes *enummt;
2717 IMediaStream *stream;
2718 AM_MEDIA_TYPE *pmt;
2719 ULONG ref, count;
2720 unsigned int i;
2721 HRESULT hr;
2722 IPin *pin;
2724 static const struct
2726 const GUID *type;
2727 BYTE *format;
2728 ULONG size;
2730 tests[] =
2732 {&GUID_NULL, NULL, 0 },
2733 {&FORMAT_None, NULL, 0 },
2734 {&FORMAT_WaveFormatEx, (BYTE *)&req_wfx, sizeof(WAVEFORMATEX)},
2735 {&FORMAT_MPEG2Video, (BYTE *)&req_m2vi, sizeof(MPEG2VIDEOINFO)},
2736 {&FORMAT_MPEGVideo, (BYTE *)&req_m1vi, sizeof(MPEG2VIDEOINFO)},
2737 {&FORMAT_VideoInfo2, (BYTE *)&req_vih2, sizeof(VIDEOINFOHEADER2)},
2738 {&FORMAT_VideoInfo, (BYTE *)&req_vih, sizeof(VIDEOINFOHEADER)},
2741 static const GUID *rejected_subtypes[] =
2743 &MEDIASUBTYPE_RGB1,
2744 &MEDIASUBTYPE_RGB4,
2745 &MEDIASUBTYPE_RGB565,
2746 &MEDIASUBTYPE_RGB555,
2747 &MEDIASUBTYPE_RGB24,
2748 &MEDIASUBTYPE_RGB32,
2749 &MEDIASUBTYPE_ARGB32,
2750 &MEDIASUBTYPE_ARGB1555,
2751 &MEDIASUBTYPE_ARGB4444,
2752 &MEDIASUBTYPE_Avi,
2753 &MEDIASUBTYPE_I420,
2754 &MEDIASUBTYPE_AYUV,
2755 &MEDIASUBTYPE_YV12,
2756 &MEDIASUBTYPE_YUY2,
2757 &MEDIASUBTYPE_UYVY,
2758 &MEDIASUBTYPE_YVYU,
2759 &MEDIASUBTYPE_NV12,
2760 &GUID_NULL,
2763 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
2764 ok(hr == S_OK, "Got hr %#x.\n", hr);
2765 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2766 ok(hr == S_OK, "Got hr %#x.\n", hr);
2768 hr = IPin_EnumMediaTypes(pin, &enummt);
2769 ok(hr == S_OK, "Got hr %#x.\n", hr);
2771 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
2772 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
2774 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
2775 ok(hr == S_OK, "Got hr %#x.\n", hr);
2776 ok(count == 1, "Got count %u.\n", count);
2777 ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Video), "Got major type %s\n",
2778 wine_dbgstr_guid(&pmt->majortype));
2779 ok(IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB8), "Got subtype %s\n",
2780 wine_dbgstr_guid(&pmt->subtype));
2781 ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
2782 ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
2783 ok(pmt->lSampleSize == 10000, "Got sample size %u.\n", pmt->lSampleSize);
2784 ok(IsEqualGUID(&pmt->formattype, &GUID_NULL), "Got format type %s.\n",
2785 wine_dbgstr_guid(&pmt->formattype));
2786 ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
2788 for (i = 0; i < ARRAY_SIZE(tests); ++i)
2790 pmt->formattype = *tests[i].type;
2791 pmt->cbFormat = tests[i].size;
2792 pmt->pbFormat = tests[i].format;
2793 hr = IPin_QueryAccept(pin, pmt);
2794 ok(hr == (i == 6 ? S_OK : VFW_E_TYPE_NOT_ACCEPTED), "Got hr %#x.\n", hr);
2797 pmt->bFixedSizeSamples = FALSE;
2798 pmt->bTemporalCompression = TRUE;
2799 pmt->lSampleSize = 123;
2800 hr = IPin_QueryAccept(pin, pmt);
2801 ok(hr == S_OK, "Got hr %#x.\n", hr);
2803 pmt->majortype = MEDIATYPE_NULL;
2804 hr = IPin_QueryAccept(pin, pmt);
2805 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
2806 pmt->majortype = MEDIATYPE_Audio;
2807 hr = IPin_QueryAccept(pin, pmt);
2808 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
2809 pmt->majortype = MEDIATYPE_Stream;
2810 hr = IPin_QueryAccept(pin, pmt);
2811 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
2812 pmt->majortype = MEDIATYPE_Video;
2814 for (i = 0; i < ARRAY_SIZE(rejected_subtypes); ++i)
2816 pmt->subtype = *rejected_subtypes[i];
2817 hr = IPin_QueryAccept(pin, pmt);
2818 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x for subtype %s.\n",
2819 hr, wine_dbgstr_guid(rejected_subtypes[i]));
2822 CoTaskMemFree(pmt);
2824 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
2825 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
2827 IEnumMediaTypes_Release(enummt);
2828 IPin_Release(pin);
2829 IMediaStream_Release(stream);
2831 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
2832 ok(hr == S_OK, "Got hr %#x.\n", hr);
2833 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
2834 ok(hr == S_OK, "Got hr %#x.\n", hr);
2836 hr = IPin_EnumMediaTypes(pin, &enummt);
2837 ok(hr == S_OK, "Got hr %#x.\n", hr);
2839 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
2840 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
2842 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
2843 ok(hr == S_OK, "Got hr %#x.\n", hr);
2844 ok(count == 1, "Got count %u.\n", count);
2845 ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s\n",
2846 wine_dbgstr_guid(&pmt->majortype));
2847 ok(IsEqualGUID(&pmt->subtype, &GUID_NULL), "Got subtype %s\n",
2848 wine_dbgstr_guid(&pmt->subtype));
2849 ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
2850 ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
2851 ok(pmt->lSampleSize == 2, "Got sample size %u.\n", pmt->lSampleSize);
2852 ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n",
2853 wine_dbgstr_guid(&pmt->formattype));
2854 ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
2855 ok(pmt->cbFormat == sizeof(WAVEFORMATEX), "Got format size %u.\n", pmt->cbFormat);
2856 ok(!memcmp(pmt->pbFormat, &expect_wfx, pmt->cbFormat), "Format blocks didn't match.\n");
2858 hr = IPin_QueryAccept(pin, pmt);
2859 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
2861 CoTaskMemFree(pmt->pbFormat);
2862 CoTaskMemFree(pmt);
2864 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
2865 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
2867 IEnumMediaTypes_Release(enummt);
2868 IPin_Release(pin);
2869 IMediaStream_Release(stream);
2871 ref = IAMMultiMediaStream_Release(mmstream);
2872 ok(!ref, "Got outstanding refcount %d.\n", ref);
2875 static IUnknown *create_audio_data(void)
2877 IUnknown *audio_data = NULL;
2878 HRESULT result = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER,
2879 &IID_IUnknown, (void **)&audio_data);
2880 ok(S_OK == result, "got 0x%08x\n", result);
2881 return audio_data;
2884 static void test_audiodata_query_interface(void)
2886 IUnknown *unknown = create_audio_data();
2887 IMemoryData *memory_data = NULL;
2888 IAudioData *audio_data = NULL;
2890 HRESULT result;
2892 result = IUnknown_QueryInterface(unknown, &IID_IMemoryData, (void **)&memory_data);
2893 ok(E_NOINTERFACE == result, "got 0x%08x\n", result);
2895 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
2896 ok(S_OK == result, "got 0x%08x\n", result);
2897 if (S_OK == result)
2899 result = IAudioData_QueryInterface(audio_data, &IID_IMemoryData, (void **)&memory_data);
2900 ok(E_NOINTERFACE == result, "got 0x%08x\n", result);
2902 IAudioData_Release(audio_data);
2905 IUnknown_Release(unknown);
2908 static void test_audiodata_get_info(void)
2910 IUnknown *unknown = create_audio_data();
2911 IAudioData *audio_data = NULL;
2913 HRESULT result;
2915 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
2916 if (FAILED(result))
2918 /* test_audiodata_query_interface handles this case */
2919 skip("No IAudioData\n");
2920 goto out_unknown;
2923 result = IAudioData_GetInfo(audio_data, NULL, NULL, NULL);
2924 ok(MS_E_NOTINIT == result, "got 0x%08x\n", result);
2926 IAudioData_Release(audio_data);
2928 out_unknown:
2929 IUnknown_Release(unknown);
2932 static void test_audiodata_set_buffer(void)
2934 IUnknown *unknown = create_audio_data();
2935 IAudioData *audio_data = NULL;
2936 BYTE buffer[100] = {0};
2937 DWORD length = 0;
2938 BYTE *data = NULL;
2940 HRESULT result;
2942 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
2943 if (FAILED(result))
2945 /* test_audiodata_query_interface handles this case */
2946 skip("No IAudioData\n");
2947 goto out_unknown;
2950 result = IAudioData_SetBuffer(audio_data, 100, NULL, 0);
2951 ok(S_OK == result, "got 0x%08x\n", result);
2953 data = (BYTE *)0xdeadbeef;
2954 length = 0xdeadbeef;
2955 result = IAudioData_GetInfo(audio_data, &length, &data, NULL);
2956 ok(S_OK == result, "got 0x%08x\n", result);
2957 ok(100 == length, "got %u\n", length);
2958 ok(NULL != data, "got %p\n", data);
2960 result = IAudioData_SetBuffer(audio_data, 0, buffer, 0);
2961 ok(E_INVALIDARG == result, "got 0x%08x\n", result);
2963 result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
2964 ok(S_OK == result, "got 0x%08x\n", result);
2966 data = (BYTE *)0xdeadbeef;
2967 length = 0xdeadbeef;
2968 result = IAudioData_GetInfo(audio_data, &length, &data, NULL);
2969 ok(S_OK == result, "got 0x%08x\n", result);
2970 ok(sizeof(buffer) == length, "got %u\n", length);
2971 ok(buffer == data, "got %p\n", data);
2973 IAudioData_Release(audio_data);
2975 out_unknown:
2976 IUnknown_Release(unknown);
2979 static void test_audiodata_set_actual(void)
2981 IUnknown *unknown = create_audio_data();
2982 IAudioData *audio_data = NULL;
2983 BYTE buffer[100] = {0};
2984 DWORD actual_data = 0;
2986 HRESULT result;
2988 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
2989 if (FAILED(result))
2991 /* test_audiodata_query_interface handles this case */
2992 skip("No IAudioData\n");
2993 goto out_unknown;
2996 result = IAudioData_SetActual(audio_data, 0);
2997 ok(S_OK == result, "got 0x%08x\n", result);
2999 result = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
3000 ok(S_OK == result, "got 0x%08x\n", result);
3002 result = IAudioData_SetActual(audio_data, sizeof(buffer) + 1);
3003 ok(E_INVALIDARG == result, "got 0x%08x\n", result);
3005 result = IAudioData_SetActual(audio_data, sizeof(buffer));
3006 ok(S_OK == result, "got 0x%08x\n", result);
3008 actual_data = 0xdeadbeef;
3009 result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data);
3010 ok(S_OK == result, "got 0x%08x\n", result);
3011 ok(sizeof(buffer) == actual_data, "got %u\n", actual_data);
3013 result = IAudioData_SetActual(audio_data, 0);
3014 ok(S_OK == result, "got 0x%08x\n", result);
3016 actual_data = 0xdeadbeef;
3017 result = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_data);
3018 ok(S_OK == result, "got 0x%08x\n", result);
3019 ok(0 == actual_data, "got %u\n", actual_data);
3021 IAudioData_Release(audio_data);
3023 out_unknown:
3024 IUnknown_Release(unknown);
3027 static void test_audiodata_get_format(void)
3029 IUnknown *unknown = create_audio_data();
3030 IAudioData *audio_data = NULL;
3031 WAVEFORMATEX wave_format = {0};
3033 HRESULT result;
3035 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
3036 if (FAILED(result))
3038 /* test_audiodata_query_interface handles this case */
3039 skip("No IAudioData\n");
3040 goto out_unknown;
3043 result = IAudioData_GetFormat(audio_data, NULL);
3044 ok(E_POINTER == result, "got 0x%08x\n", result);
3046 wave_format.wFormatTag = 0xdead;
3047 wave_format.nChannels = 0xdead;
3048 wave_format.nSamplesPerSec = 0xdeadbeef;
3049 wave_format.nAvgBytesPerSec = 0xdeadbeef;
3050 wave_format.nBlockAlign = 0xdead;
3051 wave_format.wBitsPerSample = 0xdead;
3052 wave_format.cbSize = 0xdead;
3053 result = IAudioData_GetFormat(audio_data, &wave_format);
3054 ok(S_OK == result, "got 0x%08x\n", result);
3055 ok(WAVE_FORMAT_PCM == wave_format.wFormatTag, "got %u\n", wave_format.wFormatTag);
3056 ok(1 == wave_format.nChannels, "got %u\n", wave_format.nChannels);
3057 ok(11025 == wave_format.nSamplesPerSec, "got %u\n", wave_format.nSamplesPerSec);
3058 ok(22050 == wave_format.nAvgBytesPerSec, "got %u\n", wave_format.nAvgBytesPerSec);
3059 ok(2 == wave_format.nBlockAlign, "got %u\n", wave_format.nBlockAlign);
3060 ok(16 == wave_format.wBitsPerSample, "got %u\n", wave_format.wBitsPerSample);
3061 ok(0 == wave_format.cbSize, "got %u\n", wave_format.cbSize);
3063 IAudioData_Release(audio_data);
3065 out_unknown:
3066 IUnknown_Release(unknown);
3069 static void test_audiodata_set_format(void)
3071 IUnknown *unknown = create_audio_data();
3072 IAudioData *audio_data = NULL;
3073 WAVEFORMATPCMEX wave_format = {{0}};
3075 HRESULT result;
3077 result = IUnknown_QueryInterface(unknown, &IID_IAudioData, (void **)&audio_data);
3078 if (FAILED(result))
3080 /* test_audiodata_query_interface handles this case */
3081 skip("No IAudioData\n");
3082 goto out_unknown;
3085 result = IAudioData_SetFormat(audio_data, NULL);
3086 ok(E_POINTER == result, "got 0x%08x\n", result);
3088 wave_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
3089 wave_format.Format.nChannels = 2;
3090 wave_format.Format.nSamplesPerSec = 44100;
3091 wave_format.Format.nAvgBytesPerSec = 176400;
3092 wave_format.Format.nBlockAlign = 4;
3093 wave_format.Format.wBitsPerSample = 16;
3094 wave_format.Format.cbSize = 22;
3095 wave_format.Samples.wValidBitsPerSample = 16;
3096 wave_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
3097 wave_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
3098 result = IAudioData_SetFormat(audio_data, &wave_format.Format);
3099 ok(E_INVALIDARG == result, "got 0x%08x\n", result);
3101 wave_format.Format.wFormatTag = WAVE_FORMAT_PCM;
3102 wave_format.Format.nChannels = 2;
3103 wave_format.Format.nSamplesPerSec = 44100;
3104 wave_format.Format.nAvgBytesPerSec = 176400;
3105 wave_format.Format.nBlockAlign = 4;
3106 wave_format.Format.wBitsPerSample = 16;
3107 wave_format.Format.cbSize = 0;
3108 result = IAudioData_SetFormat(audio_data, &wave_format.Format);
3109 ok(S_OK == result, "got 0x%08x\n", result);
3111 wave_format.Format.wFormatTag = 0xdead;
3112 wave_format.Format.nChannels = 0xdead;
3113 wave_format.Format.nSamplesPerSec = 0xdeadbeef;
3114 wave_format.Format.nAvgBytesPerSec = 0xdeadbeef;
3115 wave_format.Format.nBlockAlign = 0xdead;
3116 wave_format.Format.wBitsPerSample = 0xdead;
3117 wave_format.Format.cbSize = 0xdead;
3118 result = IAudioData_GetFormat(audio_data, &wave_format.Format);
3119 ok(S_OK == result, "got 0x%08x\n", result);
3120 ok(WAVE_FORMAT_PCM == wave_format.Format.wFormatTag, "got %u\n", wave_format.Format.wFormatTag);
3121 ok(2 == wave_format.Format.nChannels, "got %u\n", wave_format.Format.nChannels);
3122 ok(44100 == wave_format.Format.nSamplesPerSec, "got %u\n", wave_format.Format.nSamplesPerSec);
3123 ok(176400 == wave_format.Format.nAvgBytesPerSec, "got %u\n", wave_format.Format.nAvgBytesPerSec);
3124 ok(4 == wave_format.Format.nBlockAlign, "got %u\n", wave_format.Format.nBlockAlign);
3125 ok(16 == wave_format.Format.wBitsPerSample, "got %u\n", wave_format.Format.wBitsPerSample);
3126 ok(0 == wave_format.Format.cbSize, "got %u\n", wave_format.Format.cbSize);
3128 IAudioData_Release(audio_data);
3130 out_unknown:
3131 IUnknown_Release(unknown);
3134 struct advise_time_cookie
3136 LONGLONG base;
3137 LONGLONG offset;
3138 HANDLE event;
3139 HANDLE advise_time_called_event;
3140 BOOL unadvise_called;
3143 struct testclock
3145 IReferenceClock IReferenceClock_iface;
3146 LONG refcount;
3147 LONGLONG time;
3148 struct advise_time_cookie *advise_time_cookie;
3149 HRESULT get_time_hr;
3152 static inline struct testclock *impl_from_IReferenceClock(IReferenceClock *iface)
3154 return CONTAINING_RECORD(iface, struct testclock, IReferenceClock_iface);
3157 static HRESULT WINAPI testclock_QueryInterface(IReferenceClock *iface, REFIID iid, void **out)
3159 if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
3160 if (IsEqualGUID(iid, &IID_IReferenceClock)
3161 || IsEqualGUID(iid, &IID_IUnknown))
3163 *out = iface;
3164 IReferenceClock_AddRef(iface);
3165 return S_OK;
3167 return E_NOINTERFACE;
3170 static ULONG WINAPI testclock_AddRef(IReferenceClock *iface)
3172 struct testclock *clock = impl_from_IReferenceClock(iface);
3173 return InterlockedIncrement(&clock->refcount);
3176 static ULONG WINAPI testclock_Release(IReferenceClock *iface)
3178 struct testclock *clock = impl_from_IReferenceClock(iface);
3179 return InterlockedDecrement(&clock->refcount);
3182 static HRESULT WINAPI testclock_GetTime(IReferenceClock *iface, REFERENCE_TIME *time)
3184 struct testclock *clock = impl_from_IReferenceClock(iface);
3185 if (SUCCEEDED(clock->get_time_hr))
3186 *time = clock->time;
3187 return clock->get_time_hr;
3190 static HRESULT WINAPI testclock_AdviseTime(IReferenceClock *iface, REFERENCE_TIME base, REFERENCE_TIME offset, HEVENT event, DWORD_PTR *cookie)
3192 struct testclock *clock = impl_from_IReferenceClock(iface);
3193 if (clock->advise_time_cookie)
3195 clock->advise_time_cookie->base = base;
3196 clock->advise_time_cookie->offset = offset;
3197 clock->advise_time_cookie->event = (HANDLE)event;
3198 SetEvent(clock->advise_time_cookie->advise_time_called_event);
3200 else
3202 SetEvent((HANDLE)event);
3204 *cookie = (DWORD_PTR)clock->advise_time_cookie;
3205 return S_OK;
3208 static HRESULT WINAPI testclock_AdvisePeriodic(IReferenceClock *iface, REFERENCE_TIME start, REFERENCE_TIME period, HSEMAPHORE semaphore, DWORD_PTR *cookie)
3210 ok(0, "Unexpected call.\n");
3211 return E_NOTIMPL;
3214 static HRESULT WINAPI testclock_Unadvise(IReferenceClock *iface, DWORD_PTR cookie)
3216 if (cookie)
3217 ((struct advise_time_cookie *)cookie)->unadvise_called = TRUE;
3218 return S_OK;
3221 static IReferenceClockVtbl testclock_vtbl =
3223 testclock_QueryInterface,
3224 testclock_AddRef,
3225 testclock_Release,
3226 testclock_GetTime,
3227 testclock_AdviseTime,
3228 testclock_AdvisePeriodic,
3229 testclock_Unadvise,
3232 static void testclock_init(struct testclock *clock)
3234 memset(clock, 0, sizeof(*clock));
3235 clock->IReferenceClock_iface.lpVtbl = &testclock_vtbl;
3238 static void test_audiostream_get_format(void)
3240 static const WAVEFORMATEX pin_format =
3242 .wFormatTag = WAVE_FORMAT_PCM,
3243 .nChannels = 2,
3244 .nSamplesPerSec = 44100,
3245 .wBitsPerSample = 16,
3246 .nBlockAlign = 4,
3247 .nAvgBytesPerSec = 4 * 44100,
3249 AM_MEDIA_TYPE mt =
3251 .majortype = MEDIATYPE_Audio,
3252 .subtype = MEDIASUBTYPE_PCM,
3253 .formattype = FORMAT_WaveFormatEx,
3254 .cbFormat = sizeof(WAVEFORMATEX),
3255 .pbFormat = (BYTE *)&pin_format,
3257 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3258 IAudioMediaStream *audio_stream;
3259 struct testfilter source;
3260 IGraphBuilder *graph;
3261 IMediaStream *stream;
3262 WAVEFORMATEX format;
3263 HRESULT hr;
3264 ULONG ref;
3265 IPin *pin;
3267 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3268 ok(hr == S_OK, "Got hr %#x.\n", hr);
3269 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3270 ok(hr == S_OK, "Got hr %#x.\n", hr);
3271 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3272 ok(hr == S_OK, "Got hr %#x.\n", hr);
3274 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3275 ok(hr == S_OK, "Got hr %#x.\n", hr);
3276 ok(!!graph, "Expected non-NULL graph.\n");
3278 testfilter_init(&source);
3280 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
3281 ok(hr == S_OK, "Got hr %#x.\n", hr);
3283 hr = IAudioMediaStream_GetFormat(audio_stream, NULL);
3284 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
3286 hr = IAudioMediaStream_GetFormat(audio_stream, &format);
3287 ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
3289 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3290 ok(hr == S_OK, "Got hr %#x.\n", hr);
3292 memset(&format, 0xcc, sizeof(format));
3293 hr = IAudioMediaStream_GetFormat(audio_stream, &format);
3294 ok(hr == S_OK, "Got hr %#x.\n", hr);
3295 ok(format.wFormatTag == WAVE_FORMAT_PCM, "Got tag %#x.\n", format.wFormatTag);
3296 ok(format.nChannels == 2, "Got %u channels.\n", format.nChannels);
3297 ok(format.nSamplesPerSec == 44100, "Got sample rate %u.\n", format.nSamplesPerSec);
3298 ok(format.nAvgBytesPerSec == 176400, "Got %u bytes/sec.\n", format.nAvgBytesPerSec);
3299 ok(format.nBlockAlign == 4, "Got alignment %u.\n", format.nBlockAlign);
3300 ok(format.wBitsPerSample == 16, "Got %u bits/sample.\n", format.wBitsPerSample);
3301 ok(!format.cbSize, "Got extra size %u.\n", format.cbSize);
3303 hr = IGraphBuilder_Disconnect(graph, pin);
3304 ok(hr == S_OK, "Got hr %#x.\n", hr);
3305 hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3306 ok(hr == S_OK, "Got hr %#x.\n", hr);
3308 hr = IAudioMediaStream_GetFormat(audio_stream, &format);
3309 ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
3311 ref = IAMMultiMediaStream_Release(mmstream);
3312 ok(!ref, "Got outstanding refcount %d.\n", ref);
3313 ref = IGraphBuilder_Release(graph);
3314 ok(!ref, "Got outstanding refcount %d.\n", ref);
3315 IPin_Release(pin);
3316 IAudioMediaStream_Release(audio_stream);
3317 ref = IMediaStream_Release(stream);
3318 ok(!ref, "Got outstanding refcount %d.\n", ref);
3319 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
3320 ok(!ref, "Got outstanding refcount %d.\n", ref);
3323 static HRESULT set_audiostream_format(const WAVEFORMATEX *format)
3325 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3326 IAudioMediaStream *audio_stream;
3327 IMediaStream *stream;
3328 HRESULT hr;
3329 ULONG ref;
3331 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3332 ok(hr == S_OK, "Got hr %#x.\n", hr);
3333 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3334 ok(hr == S_OK, "Got hr %#x.\n", hr);
3336 hr = IAudioMediaStream_SetFormat(audio_stream, format);
3338 ref = IAMMultiMediaStream_Release(mmstream);
3339 ok(!ref, "Got outstanding refcount %d.\n", ref);
3340 IAudioMediaStream_Release(audio_stream);
3341 ref = IMediaStream_Release(stream);
3342 ok(!ref, "Got outstanding refcount %d.\n", ref);
3344 return hr;
3347 static void test_audiostream_set_format(void)
3349 static const WAVEFORMATEX valid_format =
3351 .wFormatTag = WAVE_FORMAT_PCM,
3352 .nChannels = 2,
3353 .nSamplesPerSec = 44100,
3354 .wBitsPerSample = 16,
3355 .nBlockAlign = 4,
3356 .nAvgBytesPerSec = 4 * 44100,
3359 const AM_MEDIA_TYPE mt =
3361 .majortype = MEDIATYPE_Audio,
3362 .subtype = MEDIASUBTYPE_PCM,
3363 .formattype = FORMAT_WaveFormatEx,
3364 .cbFormat = sizeof(WAVEFORMATEX),
3365 .pbFormat = (BYTE *)&valid_format,
3368 WAVEFORMATEXTENSIBLE extensible_format;
3369 IAudioMediaStream *audio_stream;
3370 IAMMultiMediaStream *mmstream;
3371 struct testfilter source;
3372 IGraphBuilder *graph;
3373 IMediaStream *stream;
3374 WAVEFORMATEX format;
3375 HRESULT hr;
3376 ULONG ref;
3377 IPin *pin;
3379 hr = set_audiostream_format(&valid_format);
3380 ok(hr == S_OK, "Got hr %#x.\n", hr);
3381 hr = set_audiostream_format(NULL);
3382 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
3384 extensible_format.Format = valid_format;
3385 extensible_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
3386 extensible_format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
3387 extensible_format.Samples.wValidBitsPerSample = valid_format.wBitsPerSample;
3388 extensible_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
3389 extensible_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
3390 hr = set_audiostream_format(&extensible_format.Format);
3391 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3393 format = valid_format;
3394 format.nBlockAlign = 1;
3395 hr = set_audiostream_format(&format);
3396 ok(hr == S_OK, "Got hr %#x.\n", hr);
3398 format = valid_format;
3399 format.nAvgBytesPerSec = 1234;
3400 hr = set_audiostream_format(&format);
3401 ok(hr == S_OK, "Got hr %#x.\n", hr);
3403 mmstream = create_ammultimediastream();
3405 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3406 ok(hr == S_OK, "Got hr %#x.\n", hr);
3407 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3408 ok(hr == S_OK, "Got hr %#x.\n", hr);
3410 hr = IAudioMediaStream_SetFormat(audio_stream, &valid_format);
3411 ok(hr == S_OK, "Got hr %#x.\n", hr);
3413 hr = IAudioMediaStream_GetFormat(audio_stream, &format);
3414 ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
3416 format = valid_format;
3417 format.nChannels = 1;
3418 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3419 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3421 format = valid_format;
3422 format.nSamplesPerSec = 11025;
3423 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3424 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3426 format = valid_format;
3427 format.nAvgBytesPerSec = 1234;
3428 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3429 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3431 format = valid_format;
3432 format.nBlockAlign = 1;
3433 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3434 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3436 format = valid_format;
3437 format.wBitsPerSample = 8;
3438 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3439 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3441 format = valid_format;
3442 format.cbSize = 1;
3443 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3444 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3446 hr = IAudioMediaStream_SetFormat(audio_stream, &valid_format);
3447 ok(hr == S_OK, "Got hr %#x.\n", hr);
3449 ref = IAMMultiMediaStream_Release(mmstream);
3450 ok(!ref, "Got outstanding refcount %d.\n", ref);
3451 IAudioMediaStream_Release(audio_stream);
3452 ref = IMediaStream_Release(stream);
3453 ok(!ref, "Got outstanding refcount %d.\n", ref);
3455 mmstream = create_ammultimediastream();
3457 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3458 ok(hr == S_OK, "Got hr %#x.\n", hr);
3459 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3460 ok(hr == S_OK, "Got hr %#x.\n", hr);
3461 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3462 ok(hr == S_OK, "Got hr %#x.\n", hr);
3464 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3465 ok(hr == S_OK, "Got hr %#x.\n", hr);
3466 ok(!!graph, "Expected non-NULL graph.\n");
3468 testfilter_init(&source);
3470 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3471 ok(hr == S_OK, "Got hr %#x.\n", hr);
3473 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3474 ok(hr == S_OK, "Got hr %#x.\n", hr);
3476 format = valid_format;
3477 format.nChannels = 1;
3478 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3479 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3481 hr = IGraphBuilder_Disconnect(graph, pin);
3482 ok(hr == S_OK, "Got hr %#x.\n", hr);
3483 hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3484 ok(hr == S_OK, "Got hr %#x.\n", hr);
3486 format = valid_format;
3487 format.nChannels = 1;
3488 hr = IAudioMediaStream_SetFormat(audio_stream, &format);
3489 ok(hr == S_OK, "Got hr %#x.\n", hr);
3491 ref = IAMMultiMediaStream_Release(mmstream);
3492 ok(!ref, "Got outstanding refcount %d.\n", ref);
3493 ref = IGraphBuilder_Release(graph);
3494 ok(!ref, "Got outstanding refcount %d.\n", ref);
3495 IPin_Release(pin);
3496 IAudioMediaStream_Release(audio_stream);
3497 ref = IMediaStream_Release(stream);
3498 ok(!ref, "Got outstanding refcount %d.\n", ref);
3499 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
3500 ok(!ref, "Got outstanding refcount %d.\n", ref);
3503 static void test_audiostream_receive_connection(void)
3505 WAVEFORMATEXTENSIBLE extensible_format;
3506 IAudioMediaStream *audio_stream;
3507 IAMMultiMediaStream *mmstream;
3508 struct testfilter source;
3509 IGraphBuilder *graph;
3510 IMediaStream *stream;
3511 WAVEFORMATEX format;
3512 AM_MEDIA_TYPE mt;
3513 HRESULT hr;
3514 ULONG ref;
3515 IPin *pin;
3517 mmstream = create_ammultimediastream();
3518 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3519 ok(hr == S_OK, "Got hr %#x.\n", hr);
3520 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
3521 ok(hr == S_OK, "Got hr %#x.\n", hr);
3522 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3523 ok(hr == S_OK, "Got hr %#x.\n", hr);
3524 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3525 ok(hr == S_OK, "Got hr %#x.\n", hr);
3526 ok(graph != NULL, "Expected non-null graph\n");
3527 testfilter_init(&source);
3528 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3529 ok(hr == S_OK, "Got hr %#x.\n", hr);
3531 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3532 ok(hr == S_OK, "Got hr %#x.\n", hr);
3533 IGraphBuilder_Disconnect(graph, pin);
3534 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3536 mt = audio_mt;
3537 mt.majortype = GUID_NULL;
3538 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3539 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3541 mt = audio_mt;
3542 mt.subtype = MEDIASUBTYPE_RGB24;
3543 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3544 ok(hr == S_OK, "Got hr %#x.\n", hr);
3545 IGraphBuilder_Disconnect(graph, pin);
3546 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3548 mt = audio_mt;
3549 mt.formattype = GUID_NULL;
3550 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3551 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3553 mt = audio_mt;
3554 mt.cbFormat = sizeof(WAVEFORMATEX) - 1;
3555 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3556 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3558 extensible_format.Format = audio_format;
3559 extensible_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
3560 extensible_format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
3561 extensible_format.Samples.wValidBitsPerSample = audio_format.wBitsPerSample;
3562 extensible_format.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
3563 extensible_format.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
3564 mt = audio_mt;
3565 mt.cbFormat = sizeof(extensible_format);
3566 mt.pbFormat = (BYTE *)&extensible_format;
3567 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3568 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3570 hr = IAudioMediaStream_SetFormat(audio_stream, &audio_format);
3571 ok(hr == S_OK, "Got hr %#x.\n", hr);
3573 format = audio_format;
3574 format.nChannels = 2;
3575 mt = audio_mt;
3576 mt.pbFormat = (BYTE *)&format;
3577 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3578 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
3580 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3581 ok(hr == S_OK, "Got hr %#x.\n", hr);
3582 IGraphBuilder_Disconnect(graph, pin);
3583 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3585 ref = IAMMultiMediaStream_Release(mmstream);
3586 ok(!ref, "Got outstanding refcount %d.\n", ref);
3587 ref = IGraphBuilder_Release(graph);
3588 ok(!ref, "Got outstanding refcount %d.\n", ref);
3589 IPin_Release(pin);
3590 IAudioMediaStream_Release(audio_stream);
3591 ref = IMediaStream_Release(stream);
3592 ok(!ref, "Got outstanding refcount %d.\n", ref);
3593 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
3594 ok(!ref, "Got outstanding refcount %d.\n", ref);
3597 static void test_ddrawstream_receive_connection(void)
3599 static const VIDEOINFOHEADER req_vih;
3600 IDirectDrawMediaStream *ddraw_stream;
3601 IAMMultiMediaStream *mmstream;
3602 struct testfilter source;
3603 DDSURFACEDESC format;
3604 IMediaStream *stream;
3605 VIDEOINFO video_info;
3606 AM_MEDIA_TYPE mt;
3607 HRESULT hr;
3608 ULONG ref;
3609 IPin *pin;
3610 int i;
3612 static const VIDEOINFO yuy2_video_info =
3614 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
3615 .bmiHeader.biWidth = 333,
3616 .bmiHeader.biHeight = -444,
3617 .bmiHeader.biPlanes = 1,
3618 .bmiHeader.biBitCount = 16,
3619 .bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y', '2'),
3622 const AM_MEDIA_TYPE yuy2_mt =
3624 .majortype = MEDIATYPE_Video,
3625 .subtype = MEDIASUBTYPE_YUY2,
3626 .formattype = FORMAT_VideoInfo,
3627 .cbFormat = sizeof(VIDEOINFOHEADER),
3628 .pbFormat = (BYTE *)&yuy2_video_info,
3631 const AM_MEDIA_TYPE video_mt =
3633 .majortype = MEDIATYPE_Video,
3634 .subtype = MEDIASUBTYPE_RGB8,
3635 .formattype = FORMAT_VideoInfo,
3636 .cbFormat = sizeof(VIDEOINFOHEADER),
3637 .pbFormat = (BYTE *)&req_vih,
3640 static const GUID *subtypes[] =
3642 &MEDIASUBTYPE_RGB24,
3643 &MEDIASUBTYPE_RGB32,
3644 &MEDIASUBTYPE_RGB555,
3645 &MEDIASUBTYPE_RGB565,
3646 &MEDIASUBTYPE_RGB1,
3647 &MEDIASUBTYPE_RGB4,
3648 &MEDIASUBTYPE_ARGB32,
3649 &MEDIASUBTYPE_ARGB1555,
3650 &MEDIASUBTYPE_ARGB4444,
3651 &MEDIASUBTYPE_Avi,
3652 &MEDIASUBTYPE_I420,
3653 &MEDIASUBTYPE_AYUV,
3654 &MEDIASUBTYPE_YV12,
3655 &MEDIASUBTYPE_YUY2,
3656 &MEDIASUBTYPE_UYVY,
3657 &MEDIASUBTYPE_YVYU,
3658 &MEDIASUBTYPE_NV12,
3659 &GUID_NULL,
3662 mmstream = create_ammultimediastream();
3663 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
3664 ok(hr == S_OK, "Got hr %#x.\n", hr);
3665 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
3666 ok(hr == S_OK, "Got hr %#x.\n", hr);
3667 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3668 ok(hr == S_OK, "Got hr %#x.\n", hr);
3670 testfilter_init(&source);
3672 mt = video_mt;
3673 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3674 ok(hr == S_OK, "Got hr %#x.\n", hr);
3675 hr = IPin_Disconnect(pin);
3676 ok(hr == S_OK, "Got hr %#x.\n", hr);
3678 for (i = 0; i < ARRAY_SIZE(subtypes); ++i)
3680 mt = video_mt;
3681 mt.subtype = *subtypes[i];
3682 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3683 ok(hr == (i < 4 ? S_OK : VFW_E_TYPE_NOT_ACCEPTED), "Got hr %#x.\n", hr);
3684 if (hr == S_OK)
3686 hr = IPin_Disconnect(pin);
3687 ok(hr == S_OK, "Got hr %#x.\n", hr);
3691 format = rgb8_format;
3692 format.dwFlags = DDSD_WIDTH;
3693 format.dwWidth = 222;
3694 format.dwHeight = 555;
3695 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
3696 ok(hr == S_OK, "Got hr %#x.\n", hr);
3698 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
3699 ok(hr == S_OK, "Got hr %#x.\n", hr);
3700 hr = IPin_Disconnect(pin);
3701 ok(hr == S_OK, "Got hr %#x.\n", hr);
3703 format = rgb8_format;
3704 format.dwFlags = DDSD_HEIGHT;
3705 format.dwWidth = 333;
3706 format.dwHeight = 444;
3707 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
3708 ok(hr == S_OK, "Got hr %#x.\n", hr);
3710 video_info = rgb555_video_info;
3711 video_info.bmiHeader.biWidth = 333;
3712 video_info.bmiHeader.biHeight = 444;
3713 mt = rgb555_mt;
3714 mt.pbFormat = (BYTE *)&video_info;
3715 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3716 ok(hr == S_OK, "Got hr %#x.\n", hr);
3717 hr = IPin_Disconnect(pin);
3718 ok(hr == S_OK, "Got hr %#x.\n", hr);
3720 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
3721 ok(hr == S_OK, "Got hr %#x.\n", hr);
3722 hr = IPin_Disconnect(pin);
3723 ok(hr == S_OK, "Got hr %#x.\n", hr);
3725 video_info = rgb32_video_info;
3726 video_info.bmiHeader.biWidth = 332;
3727 video_info.bmiHeader.biHeight = 444;
3728 mt = rgb32_mt;
3729 mt.pbFormat = (BYTE *)&video_info;
3730 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3731 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3733 video_info = rgb32_video_info;
3734 video_info.bmiHeader.biWidth = 333;
3735 video_info.bmiHeader.biHeight = 443;
3736 mt = rgb32_mt;
3737 mt.pbFormat = (BYTE *)&video_info;
3738 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &mt);
3739 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3741 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, NULL);
3742 ok(hr == S_OK, "Got hr %#x.\n", hr);
3744 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb555_mt);
3745 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3747 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb8_mt);
3748 ok(hr == S_OK, "Got hr %#x.\n", hr);
3749 hr = IPin_Disconnect(pin);
3750 ok(hr == S_OK, "Got hr %#x.\n", hr);
3752 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
3753 ok(hr == S_OK, "Got hr %#x.\n", hr);
3755 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
3756 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3758 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb555_mt);
3759 ok(hr == S_OK, "Got hr %#x.\n", hr);
3760 hr = IPin_Disconnect(pin);
3761 ok(hr == S_OK, "Got hr %#x.\n", hr);
3763 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb565_format, NULL);
3764 ok(hr == S_OK, "Got hr %#x.\n", hr);
3766 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb24_mt);
3767 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3769 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
3770 ok(hr == S_OK, "Got hr %#x.\n", hr);
3771 hr = IPin_Disconnect(pin);
3772 ok(hr == S_OK, "Got hr %#x.\n", hr);
3774 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb24_format, NULL);
3775 ok(hr == S_OK, "Got hr %#x.\n", hr);
3777 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
3778 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3780 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb24_mt);
3781 ok(hr == S_OK, "Got hr %#x.\n", hr);
3782 hr = IPin_Disconnect(pin);
3783 ok(hr == S_OK, "Got hr %#x.\n", hr);
3785 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb32_format, NULL);
3786 ok(hr == S_OK, "Got hr %#x.\n", hr);
3788 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb8_mt);
3789 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3791 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb32_mt);
3792 ok(hr == S_OK, "Got hr %#x.\n", hr);
3793 hr = IPin_Disconnect(pin);
3794 ok(hr == S_OK, "Got hr %#x.\n", hr);
3796 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &yuy2_format, NULL);
3797 ok(hr == S_OK, "Got hr %#x.\n", hr);
3799 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &yuy2_mt);
3800 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3802 format = yuy2_format;
3803 format.ddpfPixelFormat.u2.dwRBitMask = 0xf800;
3804 format.ddpfPixelFormat.u3.dwGBitMask = 0x07e0;
3805 format.ddpfPixelFormat.u4.dwBBitMask = 0x001f;
3806 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
3807 ok(hr == S_OK, "Got hr %#x.\n", hr);
3809 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
3810 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
3812 format = rgb8_format;
3813 format.dwFlags = 0;
3814 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
3815 ok(hr == S_OK, "Got hr %#x.\n", hr);
3817 hr = IPin_ReceiveConnection(pin, &source.source.pin.IPin_iface, &rgb565_mt);
3818 ok(hr == S_OK, "Got hr %#x.\n", hr);
3819 hr = IPin_Disconnect(pin);
3820 ok(hr == S_OK, "Got hr %#x.\n", hr);
3822 ref = IAMMultiMediaStream_Release(mmstream);
3823 ok(!ref, "Got outstanding refcount %d.\n", ref);
3824 IPin_Release(pin);
3825 IDirectDrawMediaStream_Release(ddraw_stream);
3826 ref = IMediaStream_Release(stream);
3827 ok(!ref, "Got outstanding refcount %d.\n", ref);
3828 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
3829 ok(!ref, "Got outstanding refcount %d.\n", ref);
3832 static void test_audiostream_receive(void)
3834 ALLOCATOR_PROPERTIES properties =
3836 .cBuffers = 3,
3837 .cbBuffer = 16,
3838 .cbAlign = 1,
3841 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3842 ALLOCATOR_PROPERTIES actual;
3843 struct testfilter source;
3844 IMemAllocator *allocator;
3845 IGraphBuilder *graph;
3846 IMediaStream *stream;
3847 IMediaSample *sample1;
3848 IMediaSample *sample2;
3849 IMediaSample *sample3;
3850 HRESULT hr;
3851 ULONG ref;
3852 IPin *pin;
3854 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
3855 ok(hr == S_OK, "Got hr %#x.\n", hr);
3856 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3857 ok(hr == S_OK, "Got hr %#x.\n", hr);
3858 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
3859 ok(hr == S_OK, "Got hr %#x.\n", hr);
3860 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
3861 ok(hr == S_OK, "Got hr %#x.\n", hr);
3862 ok(graph != NULL, "Expected non-NULL graph.\n");
3863 testfilter_init(&source);
3864 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3865 ok(hr == S_OK, "Got hr %#x.\n", hr);
3866 hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (void **)&allocator);
3867 ok(hr == S_OK, "Got hr %#x.\n", hr);
3868 hr = IMemAllocator_SetProperties(allocator, &properties, &actual);
3869 ok(hr == S_OK, "Got hr %#x.\n", hr);
3870 hr = IMemAllocator_Commit(allocator);
3871 ok(hr == S_OK, "Got hr %#x.\n", hr);
3873 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
3874 ok(hr == S_OK, "Got hr %#x.\n", hr);
3876 hr = IMemAllocator_GetBuffer(allocator, &sample1, NULL, NULL, 0);
3877 ok(hr == S_OK, "Got hr %#x.\n", hr);
3878 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample1);
3879 ok(hr == VFW_E_WRONG_STATE, "Got hr %#x.\n", hr);
3880 ref = IMediaSample_Release(sample1);
3881 ok(!ref, "Got outstanding refcount %d.\n", ref);
3883 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
3884 ok(hr == S_OK, "Got hr %#x.\n", hr);
3886 hr = IMemAllocator_GetBuffer(allocator, &sample1, NULL, NULL, 0);
3887 ok(hr == S_OK, "Got hr %#x.\n", hr);
3888 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample1);
3889 ok(hr == S_OK, "Got hr %#x.\n", hr);
3890 ref = get_refcount(sample1);
3891 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
3893 hr = IMemAllocator_GetBuffer(allocator, &sample2, NULL, NULL, 0);
3894 ok(hr == S_OK, "Got hr %#x.\n", hr);
3895 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample2);
3896 ok(hr == S_OK, "Got hr %#x.\n", hr);
3897 ref = get_refcount(sample2);
3898 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
3900 hr = IPin_EndOfStream(pin);
3901 ok(hr == S_OK, "Got hr %#x.\n", hr);
3903 hr = IMemAllocator_GetBuffer(allocator, &sample3, NULL, NULL, 0);
3904 ok(hr == S_OK, "Got hr %#x.\n", hr);
3905 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample3);
3906 ok(hr == S_OK, "Got hr %#x.\n", hr);
3907 ref = get_refcount(sample3);
3908 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
3910 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
3911 ok(hr == S_OK, "Got hr %#x.\n", hr);
3913 ref = IMediaSample_Release(sample1);
3914 ok(!ref, "Got outstanding refcount %d.\n", ref);
3915 ref = IMediaSample_Release(sample2);
3916 ok(!ref, "Got outstanding refcount %d.\n", ref);
3917 ref = IMediaSample_Release(sample3);
3918 ok(!ref, "Got outstanding refcount %d.\n", ref);
3920 hr = IMemAllocator_GetBuffer(allocator, &sample1, NULL, NULL, 0);
3921 ok(hr == S_OK, "Got hr %#x.\n", hr);
3922 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample1);
3923 ok(hr == VFW_E_WRONG_STATE, "Got hr %#x.\n", hr);
3924 ref = IMediaSample_Release(sample1);
3925 ok(!ref, "Got outstanding refcount %d.\n", ref);
3927 IGraphBuilder_Disconnect(graph, pin);
3928 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
3930 hr = IMemAllocator_Decommit(allocator);
3931 ok(hr == S_OK, "Got hr %#x.\n", hr);
3933 ref = IAMMultiMediaStream_Release(mmstream);
3934 ok(!ref, "Got outstanding refcount %d.\n", ref);
3935 ref = IGraphBuilder_Release(graph);
3936 ok(!ref, "Got outstanding refcount %d.\n", ref);
3937 IPin_Release(pin);
3938 ref = IMediaStream_Release(stream);
3939 ok(!ref, "Got outstanding refcount %d.\n", ref);
3940 ref = IMemAllocator_Release(allocator);
3941 ok(!ref, "Got outstanding refcount %d.\n", ref);
3944 static void test_audiostream_initialize(void)
3946 IAMMediaStream *stream;
3947 STREAM_TYPE type;
3948 MSPID mspid;
3949 HRESULT hr;
3950 ULONG ref;
3952 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
3953 ok(hr == S_OK, "Got hr %#x.\n", hr);
3955 /* Crashes on native. */
3956 if (0)
3958 hr = IAMMediaStream_Initialize(stream, NULL, 0, NULL, STREAMTYPE_WRITE);
3959 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
3962 hr = IAMMediaStream_Initialize(stream, NULL, 0, &test_mspid, STREAMTYPE_WRITE);
3963 ok(hr == S_OK, "Got hr %#x.\n", hr);
3965 hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
3966 ok(hr == S_OK, "Got hr %#x.\n", hr);
3967 ok(IsEqualGUID(&mspid, &test_mspid), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
3968 ok(type == STREAMTYPE_WRITE, "Got type %u.\n", type);
3970 hr = IAMMediaStream_Initialize(stream, NULL, 0, &MSPID_PrimaryAudio, STREAMTYPE_READ);
3971 ok(hr == S_OK, "Got hr %#x.\n", hr);
3973 hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
3974 ok(hr == S_OK, "Got hr %#x.\n", hr);
3975 ok(IsEqualGUID(&mspid, &MSPID_PrimaryAudio), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
3976 ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
3978 ref = IAMMediaStream_Release(stream);
3979 ok(!ref, "Got outstanding refcount %d.\n", ref);
3982 static void test_audiostream_begin_flush_end_flush(void)
3984 IAMMultiMediaStream *mmstream = create_ammultimediastream();
3985 IAudioStreamSample *stream_sample;
3986 IAudioMediaStream *audio_stream;
3987 IMediaSample *media_sample;
3988 struct testfilter source;
3989 IAudioData *audio_data;
3990 IGraphBuilder *graph;
3991 IMediaStream *stream;
3992 HRESULT hr;
3993 ULONG ref;
3994 IPin *pin;
3996 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
3997 ok(hr == S_OK, "Got hr %#x.\n", hr);
3998 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
3999 ok(hr == S_OK, "Got hr %#x.\n", hr);
4000 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
4001 ok(hr == S_OK, "Got hr %#x.\n", hr);
4002 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4003 ok(hr == S_OK, "Got hr %#x.\n", hr);
4004 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4005 ok(hr == S_OK, "Got hr %#x.\n", hr);
4006 ok(graph != NULL, "Expected non-NULL graph.\n");
4007 testfilter_init(&source);
4008 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
4009 ok(hr == S_OK, "Got hr %#x.\n", hr);
4010 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
4011 ok(hr == S_OK, "Got hr %#x.\n", hr);
4012 hr = IAudioData_SetBuffer(audio_data, 16, NULL, 0);
4013 ok(hr == S_OK, "Got hr %#x.\n", hr);
4014 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
4015 ok(hr == S_OK, "Got hr %#x.\n", hr);
4017 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
4018 ok(hr == S_OK, "Got hr %#x.\n", hr);
4020 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4021 ok(hr == S_OK, "Got hr %#x.\n", hr);
4023 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source.source, &media_sample, NULL, NULL, 0);
4024 ok(hr == S_OK, "Got hr %#x.\n", hr);
4025 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
4026 ok(hr == S_OK, "Got hr %#x.\n", hr);
4027 ref = get_refcount(media_sample);
4028 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
4030 hr = IPin_EndOfStream(pin);
4031 ok(hr == S_OK, "Got hr %#x.\n", hr);
4033 hr = IPin_BeginFlush(pin);
4034 ok(hr == S_OK, "Got hr %#x.\n", hr);
4036 ref = IMediaSample_Release(media_sample);
4037 ok(!ref, "Got outstanding refcount %d.\n", ref);
4039 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source.source, &media_sample, NULL, NULL, 0);
4040 ok(hr == S_OK, "Got hr %#x.\n", hr);
4041 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
4042 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
4044 ref = IMediaSample_Release(media_sample);
4045 ok(!ref, "Got outstanding refcount %d.\n", ref);
4047 hr = IAudioStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
4048 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
4050 hr = IPin_EndOfStream(pin);
4051 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
4053 hr = IPin_EndFlush(pin);
4054 ok(hr == S_OK, "Got hr %#x.\n", hr);
4056 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source.source, &media_sample, NULL, NULL, 0);
4057 ok(hr == S_OK, "Got hr %#x.\n", hr);
4058 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
4059 ok(hr == S_OK, "Got hr %#x.\n", hr);
4060 ref = IMediaSample_Release(media_sample);
4061 ok(ref == 1, "Got outstanding refcount %d.\n", ref);
4063 hr = IPin_EndOfStream(pin);
4064 ok(hr == S_OK, "Got hr %#x.\n", hr);
4066 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4067 ok(hr == S_OK, "Got hr %#x.\n", hr);
4069 IGraphBuilder_Disconnect(graph, pin);
4070 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
4072 ref = IAudioStreamSample_Release(stream_sample);
4073 ok(!ref, "Got outstanding refcount %d.\n", ref);
4074 ref = IAudioData_Release(audio_data);
4075 ok(!ref, "Got outstanding refcount %d.\n", ref);
4076 ref = IAMMultiMediaStream_Release(mmstream);
4077 ok(!ref, "Got outstanding refcount %d.\n", ref);
4078 ref = IGraphBuilder_Release(graph);
4079 ok(!ref, "Got outstanding refcount %d.\n", ref);
4080 IPin_Release(pin);
4081 IAudioMediaStream_Release(audio_stream);
4082 ref = IMediaStream_Release(stream);
4083 ok(!ref, "Got outstanding refcount %d.\n", ref);
4086 static IMediaSample *ammediastream_allocate_sample(struct testfilter *source, const BYTE *input_data, DWORD input_length)
4088 IMediaSample *sample;
4089 BYTE *sample_data;
4090 HRESULT hr;
4092 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source->source, &sample, NULL, NULL, 0);
4093 ok(hr == S_OK, "Got hr %#x.\n", hr);
4095 hr = IMediaSample_GetPointer(sample, &sample_data);
4096 ok(hr == S_OK, "Got hr %#x.\n", hr);
4098 hr = IMediaSample_SetActualDataLength(sample, input_length);
4099 ok(hr == S_OK, "Got hr %#x.\n", hr);
4101 memcpy(sample_data, input_data, input_length);
4103 return sample;
4106 static void test_audiostream_new_segment(void)
4108 IAMMultiMediaStream *mmstream = create_ammultimediastream();
4109 static const BYTE test_data[8] = { 0 };
4110 IAudioStreamSample *stream_sample;
4111 IAudioMediaStream *audio_stream;
4112 IMemInputPin *mem_input_pin;
4113 IMediaSample *media_sample;
4114 struct testfilter source;
4115 IAudioData *audio_data;
4116 STREAM_TIME start_time;
4117 STREAM_TIME end_time;
4118 IGraphBuilder *graph;
4119 IMediaStream *stream;
4120 HRESULT hr;
4121 ULONG ref;
4122 IPin *pin;
4124 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4125 ok(hr == S_OK, "Got hr %#x.\n", hr);
4126 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
4127 ok(hr == S_OK, "Got hr %#x.\n", hr);
4128 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
4129 ok(hr == S_OK, "Got hr %#x.\n", hr);
4130 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4131 ok(hr == S_OK, "Got hr %#x.\n", hr);
4132 hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
4133 ok(hr == S_OK, "Got hr %#x.\n", hr);
4134 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4135 ok(hr == S_OK, "Got hr %#x.\n", hr);
4136 ok(graph != NULL, "Expected non-NULL graph.\n");
4137 testfilter_init(&source);
4138 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
4139 ok(hr == S_OK, "Got hr %#x.\n", hr);
4140 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
4141 ok(hr == S_OK, "Got hr %#x.\n", hr);
4142 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
4143 ok(hr == S_OK, "Got hr %#x.\n", hr);
4144 hr = IAudioData_SetBuffer(audio_data, 5, NULL, 0);
4145 ok(hr == S_OK, "Got hr %#x.\n", hr);
4147 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
4148 ok(hr == S_OK, "Got hr %#x.\n", hr);
4149 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4150 ok(hr == S_OK, "Got hr %#x.\n", hr);
4152 hr = IPin_NewSegment(pin, 11111111, 22222222, 1.0);
4153 ok(hr == S_OK, "Got hr %#x.\n", hr);
4155 media_sample = ammediastream_allocate_sample(&source, test_data, 5);
4156 start_time = 12345678;
4157 end_time = 23456789;
4158 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
4159 ok(hr == S_OK, "Got hr %#x.\n", hr);
4160 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
4161 ok(hr == S_OK, "Got hr %#x.\n", hr);
4162 IMediaSample_Release(media_sample);
4164 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4165 ok(hr == S_OK, "Got hr %#x.\n", hr);
4167 start_time = 0xdeadbeefdeadbeef;
4168 end_time = 0xdeadbeefdeadbeef;
4169 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4170 ok(hr == S_OK, "Got hr %#x.\n", hr);
4171 ok(start_time == 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4172 ok(end_time == 23459057, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4174 hr = IPin_NewSegment(pin, 11111111, 22222222, 2.0);
4175 ok(hr == S_OK, "Got hr %#x.\n", hr);
4177 media_sample = ammediastream_allocate_sample(&source, test_data, 5);
4178 start_time = 12345678;
4179 end_time = 23456789;
4180 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
4181 ok(hr == S_OK, "Got hr %#x.\n", hr);
4182 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
4183 ok(hr == S_OK, "Got hr %#x.\n", hr);
4184 IMediaSample_Release(media_sample);
4186 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4187 ok(hr == S_OK, "Got hr %#x.\n", hr);
4189 start_time = 0xdeadbeefdeadbeef;
4190 end_time = 0xdeadbeefdeadbeef;
4191 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4192 ok(hr == S_OK, "Got hr %#x.\n", hr);
4193 ok(start_time == 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4194 ok(end_time == 23459057, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4196 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4197 ok(hr == S_OK, "Got hr %#x.\n", hr);
4198 IGraphBuilder_Disconnect(graph, pin);
4199 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
4201 ref = IAudioStreamSample_Release(stream_sample);
4202 ok(!ref, "Got outstanding refcount %d.\n", ref);
4203 ref = IAudioData_Release(audio_data);
4204 ok(!ref, "Got outstanding refcount %d.\n", ref);
4205 ref = IAMMultiMediaStream_Release(mmstream);
4206 ok(!ref, "Got outstanding refcount %d.\n", ref);
4207 ref = IGraphBuilder_Release(graph);
4208 ok(!ref, "Got outstanding refcount %d.\n", ref);
4209 IPin_Release(pin);
4210 IMemInputPin_Release(mem_input_pin);
4211 IAudioMediaStream_Release(audio_stream);
4212 ref = IMediaStream_Release(stream);
4213 ok(!ref, "Got outstanding refcount %d.\n", ref);
4216 static void CALLBACK apc_func(ULONG_PTR param)
4220 static IPin *ammediastream_pin;
4221 static IMemInputPin *ammediastream_mem_input_pin;
4222 static IMediaSample *ammediastream_media_sample;
4223 static DWORD ammediastream_sleep_time;
4224 static HRESULT ammediastream_expected_hr;
4226 static DWORD CALLBACK ammediastream_end_of_stream(void *param)
4228 HRESULT hr;
4230 Sleep(ammediastream_sleep_time);
4231 hr = IPin_EndOfStream(ammediastream_pin);
4232 ok(hr == ammediastream_expected_hr, "Got hr %#x.\n", hr);
4234 return 0;
4237 static DWORD CALLBACK ammediastream_receive(void *param)
4239 HRESULT hr;
4241 Sleep(ammediastream_sleep_time);
4242 hr = IMemInputPin_Receive(ammediastream_mem_input_pin, ammediastream_media_sample);
4243 ok(hr == ammediastream_expected_hr, "Got hr %#x.\n", hr);
4245 return 0;
4248 struct ammediastream_receive_release_param
4250 IMemInputPin *mem_input_pin;
4251 IMediaSample *media_sample;
4254 static DWORD CALLBACK ammediastream_receive_release(void *p)
4256 struct ammediastream_receive_release_param *param = (struct ammediastream_receive_release_param *)p;
4257 HRESULT hr;
4258 ULONG ref;
4260 hr = IMemInputPin_Receive(param->mem_input_pin, param->media_sample);
4261 ok(hr == S_OK, "Got hr %#x.\n", hr);
4263 ref = IMediaSample_Release(param->media_sample);
4264 ok(!ref, "Got outstanding refcount %d.\n", ref);
4266 free(p);
4268 return 0;
4271 static HANDLE ammediastream_async_receive_time(struct testfilter *source,
4272 REFERENCE_TIME start_time, REFERENCE_TIME end_time, const BYTE *input_data, DWORD input_length)
4274 struct ammediastream_receive_release_param *param;
4275 IMediaSample *sample;
4276 HRESULT hr;
4278 sample = ammediastream_allocate_sample(source, input_data, input_length);
4279 hr = IMediaSample_SetTime(sample, &start_time, &end_time);
4280 ok(hr == S_OK, "Got hr %#x.\n", hr);
4282 param = calloc(1, sizeof(*param));
4283 param->mem_input_pin = source->source.pMemInputPin;
4284 param->media_sample = sample;
4285 return CreateThread(NULL, 0, ammediastream_receive_release, param, 0, NULL);
4288 static IStreamSample *streamsample_sample;
4289 static DWORD streamsample_flags;
4290 static DWORD streamsample_timeout;
4291 static HRESULT streamsample_expected_hr;
4293 static DWORD CALLBACK streamsample_completion_status(void *param)
4295 HRESULT hr;
4297 hr = IStreamSample_CompletionStatus(streamsample_sample, streamsample_flags, streamsample_timeout);
4298 ok(hr == streamsample_expected_hr, "Got hr %#x.\n", hr);
4300 return 0;
4303 static void test_audiostreamsample_update(void)
4305 static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
4306 IAMMultiMediaStream *mmstream = create_ammultimediastream();
4307 IAudioStreamSample *stream_sample;
4308 IAudioMediaStream *audio_stream;
4309 IMediaControl *media_control;
4310 IMemInputPin *mem_input_pin;
4311 IMediaSample *media_sample1;
4312 IMediaSample *media_sample2;
4313 struct testfilter source;
4314 IAudioData *audio_data;
4315 IGraphBuilder *graph;
4316 IMediaStream *stream;
4317 DWORD actual_length;
4318 BYTE buffer[6];
4319 HANDLE thread;
4320 HANDLE event;
4321 HRESULT hr;
4322 ULONG ref;
4323 IPin *pin;
4325 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4326 ok(hr == S_OK, "Got hr %#x.\n", hr);
4327 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
4328 ok(hr == S_OK, "Got hr %#x.\n", hr);
4329 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
4330 ok(hr == S_OK, "Got hr %#x.\n", hr);
4331 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4332 ok(hr == S_OK, "Got hr %#x.\n", hr);
4333 hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
4334 ok(hr == S_OK, "Got hr %#x.\n", hr);
4335 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4336 ok(hr == S_OK, "Got hr %#x.\n", hr);
4337 ok(graph != NULL, "Expected non-NULL graph.\n");
4338 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
4339 ok(hr == S_OK, "Got hr %#x.\n", hr);
4340 testfilter_init(&source);
4341 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
4342 ok(hr == S_OK, "Got hr %#x.\n", hr);
4343 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
4344 ok(hr == S_OK, "Got hr %#x.\n", hr);
4345 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
4346 ok(hr == S_OK, "Got hr %#x.\n", hr);
4347 event = CreateEventW(NULL, FALSE, FALSE, NULL);
4348 ok(event != NULL, "Expected non-NULL event.");
4350 hr = IAudioStreamSample_Update(stream_sample, 0, event, apc_func, 0);
4351 ok(hr == MS_E_NOTINIT, "Got hr %#x.\n", hr);
4353 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4354 ok(hr == MS_E_NOTINIT, "Got hr %#x.\n", hr);
4356 hr = IAudioData_SetBuffer(audio_data, sizeof(buffer), buffer, 0);
4357 ok(hr == S_OK, "Got hr %#x.\n", hr);
4359 hr = IAudioStreamSample_Update(stream_sample, 0, event, apc_func, 0);
4360 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
4362 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4363 ok(hr == MS_E_NOTRUNNING, "Got hr %#x.\n", hr);
4365 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4366 ok(hr == S_OK, "Got hr %#x.\n", hr);
4368 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4369 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
4371 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4372 ok(hr == S_OK, "Got hr %#x.\n", hr);
4373 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
4374 ok(hr == S_OK, "Got hr %#x.\n", hr);
4375 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4376 ok(hr == S_OK, "Got hr %#x.\n", hr);
4378 media_sample1 = ammediastream_allocate_sample(&source, test_data, 8);
4379 hr = IMemInputPin_Receive(mem_input_pin, media_sample1);
4380 ok(hr == S_OK, "Got hr %#x.\n", hr);
4381 ref = get_refcount(media_sample1);
4382 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
4384 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4385 ok(hr == S_OK, "Got hr %#x.\n", hr);
4387 hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
4388 ok(hr == S_OK, "Got hr %#x.\n", hr);
4389 ok(actual_length == 6, "Got actual length %u.\n", actual_length);
4391 ok(memcmp(buffer, test_data, 6) == 0, "Sample data didn't match.\n");
4393 ref = get_refcount(media_sample1);
4394 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
4396 media_sample2 = ammediastream_allocate_sample(&source, test_data, 8);
4397 hr = IMemInputPin_Receive(mem_input_pin, media_sample2);
4398 ok(hr == S_OK, "Got hr %#x.\n", hr);
4399 ref = get_refcount(media_sample2);
4400 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
4402 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4403 ok(hr == S_OK, "Got hr %#x.\n", hr);
4405 hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
4406 ok(hr == S_OK, "Got hr %#x.\n", hr);
4407 ok(actual_length == 6, "Got actual length %u.\n", actual_length);
4409 ok(memcmp(buffer, &test_data[6], 2) == 0, "Sample data didn't match.\n");
4410 ok(memcmp(&buffer[2], test_data, 4) == 0, "Sample data didn't match.\n");
4412 ref = IMediaSample_Release(media_sample1);
4413 ok(!ref, "Got outstanding refcount %d.\n", ref);
4415 hr = IPin_EndOfStream(pin);
4416 ok(hr == S_OK, "Got hr %#x.\n", hr);
4418 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4419 ok(hr == S_OK, "Got hr %#x.\n", hr);
4421 hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
4422 ok(hr == S_OK, "Got hr %#x.\n", hr);
4423 ok(actual_length == 4, "Got actual length %u.\n", actual_length);
4425 ok(memcmp(buffer, &test_data[4], 4) == 0, "Sample data didn't match.\n");
4427 ref = IMediaSample_Release(media_sample2);
4428 ok(!ref, "Got outstanding refcount %d.\n", ref);
4430 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4431 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
4433 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4434 ok(hr == S_OK, "Got hr %#x.\n", hr);
4435 hr = IMediaControl_Pause(media_control);
4436 ok(hr == S_OK, "Got hr %#x.\n", hr);
4438 media_sample1 = ammediastream_allocate_sample(&source, test_data, 6);
4439 hr = IMemInputPin_Receive(mem_input_pin, media_sample1);
4440 ok(hr == S_OK, "Got hr %#x.\n", hr);
4441 ref = IMediaSample_Release(media_sample1);
4442 ok(ref == 1, "Got outstanding refcount %d.\n", ref);
4444 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4445 ok(hr == MS_E_NOTRUNNING, "Got hr %#x.\n", hr);
4447 hr = IMediaControl_Stop(media_control);
4448 ok(hr == S_OK, "Got hr %#x.\n", hr);
4449 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4450 ok(hr == S_OK, "Got hr %#x.\n", hr);
4452 media_sample1 = ammediastream_allocate_sample(&source, test_data, 6);
4454 ammediastream_mem_input_pin = mem_input_pin;
4455 ammediastream_media_sample = media_sample1;
4456 ammediastream_sleep_time = 100;
4457 ammediastream_expected_hr = S_OK;
4458 thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
4460 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4461 ok(hr == S_OK, "Got hr %#x.\n", hr);
4463 hr = IAudioData_GetInfo(audio_data, NULL, NULL, &actual_length);
4464 ok(hr == S_OK, "Got hr %#x.\n", hr);
4465 ok(actual_length == 6, "Got actual length %u.\n", actual_length);
4467 ok(memcmp(buffer, test_data, 6) == 0, "Sample data didn't match.\n");
4469 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
4470 CloseHandle(thread);
4472 ref = IMediaSample_Release(media_sample1);
4473 ok(!ref, "Got outstanding refcount %d.\n", ref);
4475 ammediastream_pin = pin;
4476 ammediastream_sleep_time = 100;
4477 ammediastream_expected_hr = S_OK;
4478 thread = CreateThread(NULL, 0, ammediastream_end_of_stream, NULL, 0, NULL);
4480 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4481 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
4483 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
4484 CloseHandle(thread);
4486 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4487 ok(hr == S_OK, "Got hr %#x.\n", hr);
4488 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4489 ok(hr == S_OK, "Got hr %#x.\n", hr);
4491 hr = IAudioStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
4492 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
4494 IAudioStreamSample_AddRef(stream_sample);
4495 ref = IAudioStreamSample_Release(stream_sample);
4496 ok(ref == 1, "Got outstanding refcount %d.\n", ref);
4498 hr = IAudioStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
4499 ok(hr == MS_E_BUSY, "Got hr %#x.\n", hr);
4501 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4502 ok(hr == S_OK, "Got hr %#x.\n", hr);
4503 IGraphBuilder_Disconnect(graph, pin);
4504 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
4505 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4506 ok(hr == S_OK, "Got hr %#x.\n", hr);
4508 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4509 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
4511 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4513 CloseHandle(event);
4514 ref = IAudioStreamSample_Release(stream_sample);
4515 ok(!ref, "Got outstanding refcount %d.\n", ref);
4516 ref = IAudioData_Release(audio_data);
4517 ok(!ref, "Got outstanding refcount %d.\n", ref);
4518 ref = IAMMultiMediaStream_Release(mmstream);
4519 ok(!ref, "Got outstanding refcount %d.\n", ref);
4520 IMediaControl_Release(media_control);
4521 ref = IGraphBuilder_Release(graph);
4522 ok(!ref, "Got outstanding refcount %d.\n", ref);
4523 IPin_Release(pin);
4524 IMemInputPin_Release(mem_input_pin);
4525 IAudioMediaStream_Release(audio_stream);
4526 ref = IMediaStream_Release(stream);
4527 ok(!ref, "Got outstanding refcount %d.\n", ref);
4530 void test_audiostreamsample_completion_status(void)
4532 static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
4533 IAMMultiMediaStream *mmstream = create_ammultimediastream();
4534 IAudioStreamSample *stream_sample1;
4535 IAudioStreamSample *stream_sample2;
4536 IAudioMediaStream *audio_stream;
4537 IMediaSample *media_sample;
4538 struct testfilter source;
4539 IAudioData *audio_data1;
4540 IAudioData *audio_data2;
4541 IGraphBuilder *graph;
4542 IMediaStream *stream;
4543 HANDLE event;
4544 HRESULT hr;
4545 ULONG ref;
4546 IPin *pin;
4548 event = CreateEventW(NULL, FALSE, FALSE, NULL);
4549 ok(event != NULL, "Expected non-NULL event.");
4551 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4552 ok(hr == S_OK, "Got hr %#x.\n", hr);
4553 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
4554 ok(hr == S_OK, "Got hr %#x.\n", hr);
4555 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
4556 ok(hr == S_OK, "Got hr %#x.\n", hr);
4557 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4558 ok(hr == S_OK, "Got hr %#x.\n", hr);
4559 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4560 ok(hr == S_OK, "Got hr %#x.\n", hr);
4561 ok(graph != NULL, "Expected non-NULL graph.\n");
4562 testfilter_init(&source);
4563 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
4564 ok(hr == S_OK, "Got hr %#x.\n", hr);
4565 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data1);
4566 ok(hr == S_OK, "Got hr %#x.\n", hr);
4567 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data2);
4568 ok(hr == S_OK, "Got hr %#x.\n", hr);
4569 hr = IAudioData_SetBuffer(audio_data1, 6, NULL, 0);
4570 ok(hr == S_OK, "Got hr %#x.\n", hr);
4571 hr = IAudioData_SetBuffer(audio_data2, 6, NULL, 0);
4572 ok(hr == S_OK, "Got hr %#x.\n", hr);
4573 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data1, 0, &stream_sample1);
4574 ok(hr == S_OK, "Got hr %#x.\n", hr);
4575 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data2, 0, &stream_sample2);
4576 ok(hr == S_OK, "Got hr %#x.\n", hr);
4578 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
4579 ok(hr == S_OK, "Got hr %#x.\n", hr);
4580 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4581 ok(hr == S_OK, "Got hr %#x.\n", hr);
4583 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
4584 ok(hr == S_OK, "Got hr %#x.\n", hr);
4586 hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
4587 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
4589 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
4590 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
4592 media_sample = ammediastream_allocate_sample(&source, test_data, 6);
4593 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
4594 ok(hr == S_OK, "Got hr %#x.\n", hr);
4595 ref = IMediaSample_Release(media_sample);
4596 ok(!ref, "Got outstanding refcount %d.\n", ref);
4598 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
4599 ok(hr == S_OK, "Got hr %#x.\n", hr);
4601 hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
4602 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
4604 hr = IAudioStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
4605 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
4607 media_sample = ammediastream_allocate_sample(&source, test_data, 12);
4608 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
4609 ok(hr == S_OK, "Got hr %#x.\n", hr);
4610 ref = IMediaSample_Release(media_sample);
4611 ok(!ref, "Got outstanding refcount %d.\n", ref);
4613 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
4614 ok(hr == S_OK, "Got hr %#x.\n", hr);
4616 hr = IAudioStreamSample_CompletionStatus(stream_sample2, 0, 0);
4617 ok(hr == S_OK, "Got hr %#x.\n", hr);
4619 hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
4620 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
4622 hr = IPin_EndOfStream(pin);
4623 ok(hr == S_OK, "Got hr %#x.\n", hr);
4625 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
4626 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
4628 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4629 ok(hr == S_OK, "Got hr %#x.\n", hr);
4630 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4631 ok(hr == S_OK, "Got hr %#x.\n", hr);
4633 hr = IAudioStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
4634 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
4636 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4637 ok(hr == S_OK, "Got hr %#x.\n", hr);
4639 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
4640 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
4642 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4643 ok(hr == S_OK, "Got hr %#x.\n", hr);
4645 media_sample = ammediastream_allocate_sample(&source, test_data, 6);
4646 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
4647 ok(hr == S_OK, "Got hr %#x.\n", hr);
4648 ref = IMediaSample_Release(media_sample);
4649 ok(!ref, "Got outstanding refcount %d.\n", ref);
4651 hr = IAudioStreamSample_CompletionStatus(stream_sample1, 0, 0);
4652 ok(hr == S_OK, "Got hr %#x.\n", hr);
4654 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4655 ok(hr == S_OK, "Got hr %#x.\n", hr);
4657 IGraphBuilder_Disconnect(graph, pin);
4658 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
4660 ref = IAudioStreamSample_Release(stream_sample1);
4661 ok(!ref, "Got outstanding refcount %d.\n", ref);
4662 ref = IAudioStreamSample_Release(stream_sample2);
4663 ok(!ref, "Got outstanding refcount %d.\n", ref);
4664 ref = IAudioData_Release(audio_data1);
4665 ok(!ref, "Got outstanding refcount %d.\n", ref);
4666 ref = IAudioData_Release(audio_data2);
4667 ok(!ref, "Got outstanding refcount %d.\n", ref);
4668 ref = IAMMultiMediaStream_Release(mmstream);
4669 ok(!ref, "Got outstanding refcount %d.\n", ref);
4670 ref = IGraphBuilder_Release(graph);
4671 ok(!ref, "Got outstanding refcount %d.\n", ref);
4672 IPin_Release(pin);
4673 IAudioMediaStream_Release(audio_stream);
4674 ref = IMediaStream_Release(stream);
4675 ok(!ref, "Got outstanding refcount %d.\n", ref);
4677 CloseHandle(event);
4680 static void test_audiostreamsample_get_sample_times(void)
4682 IAMMultiMediaStream *mmstream = create_ammultimediastream();
4683 static const BYTE test_data[8] = { 0 };
4684 IAudioStreamSample *stream_sample;
4685 IMediaFilter *graph_media_filter;
4686 IAudioMediaStream *audio_stream;
4687 STREAM_TIME filter_start_time;
4688 IMemInputPin *mem_input_pin;
4689 IMediaStreamFilter *filter;
4690 IMediaSample *media_sample;
4691 struct testfilter source;
4692 STREAM_TIME current_time;
4693 struct testclock clock;
4694 IAudioData *audio_data;
4695 STREAM_TIME start_time;
4696 STREAM_TIME end_time;
4697 IGraphBuilder *graph;
4698 IMediaStream *stream;
4699 HRESULT hr;
4700 ULONG ref;
4701 IPin *pin;
4703 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
4704 ok(hr == S_OK, "Got hr %#x.\n", hr);
4705 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
4706 ok(hr == S_OK, "Got hr %#x.\n", hr);
4707 ok(!!filter, "Expected non-null filter.\n");
4708 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
4709 ok(hr == S_OK, "Got hr %#x.\n", hr);
4710 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
4711 ok(hr == S_OK, "Got hr %#x.\n", hr);
4712 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4713 ok(hr == S_OK, "Got hr %#x.\n", hr);
4714 hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
4715 ok(hr == S_OK, "Got hr %#x.\n", hr);
4716 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
4717 ok(hr == S_OK, "Got hr %#x.\n", hr);
4718 ok(graph != NULL, "Expected non-NULL graph.\n");
4719 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&graph_media_filter);
4720 ok(hr == S_OK, "Got hr %#x.\n", hr);
4721 testfilter_init(&source);
4722 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
4723 ok(hr == S_OK, "Got hr %#x.\n", hr);
4724 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
4725 ok(hr == S_OK, "Got hr %#x.\n", hr);
4726 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &stream_sample);
4727 ok(hr == S_OK, "Got hr %#x.\n", hr);
4728 hr = IAudioData_SetBuffer(audio_data, 5, NULL, 0);
4729 ok(hr == S_OK, "Got hr %#x.\n", hr);
4730 testclock_init(&clock);
4732 clock.time = 12345678;
4734 current_time = 0xdeadbeefdeadbeef;
4735 hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
4736 ok(hr == S_OK, "Got hr %#x.\n", hr);
4737 ok(current_time == 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time));
4739 IMediaFilter_SetSyncSource(graph_media_filter, &clock.IReferenceClock_iface);
4740 ok(hr == S_OK, "Got hr %#x.\n", hr);
4742 current_time = 0xdeadbeefdeadbeef;
4743 hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
4744 ok(hr == S_OK, "Got hr %#x.\n", hr);
4745 ok(current_time == 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time));
4747 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &audio_mt);
4748 ok(hr == S_OK, "Got hr %#x.\n", hr);
4749 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
4750 ok(hr == S_OK, "Got hr %#x.\n", hr);
4752 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &filter_start_time);
4753 ok(hr == S_OK, "Got hr %#x.\n", hr);
4755 clock.get_time_hr = E_FAIL;
4757 current_time = 0xdeadbeefdeadbeef;
4758 hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
4759 ok(hr == S_OK, "Got hr %#x.\n", hr);
4760 ok(current_time == 0xdeadbeefddf15da1 + filter_start_time, "Expected current time %s, got %s.\n",
4761 wine_dbgstr_longlong(0xdeadbeefddf15da1 + filter_start_time), wine_dbgstr_longlong(current_time));
4763 clock.get_time_hr = S_OK;
4765 current_time = 0xdeadbeefdeadbeef;
4766 hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
4767 ok(hr == S_OK, "Got hr %#x.\n", hr);
4768 ok(current_time == filter_start_time, "Expected current time %s, got %s.\n",
4769 wine_dbgstr_longlong(filter_start_time), wine_dbgstr_longlong(current_time));
4771 clock.time = 23456789;
4773 current_time = 0xdeadbeefdeadbeef;
4774 hr = IAudioStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
4775 ok(hr == S_OK, "Got hr %#x.\n", hr);
4776 ok(current_time == filter_start_time + 11111111, "Expected current time %s, got %s.\n",
4777 wine_dbgstr_longlong(filter_start_time + 11111111), wine_dbgstr_longlong(current_time));
4779 start_time = 0xdeadbeefdeadbeef;
4780 end_time = 0xdeadbeefdeadbeef;
4781 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4782 ok(hr == S_OK, "Got hr %#x.\n", hr);
4783 ok(start_time == 0, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4784 ok(end_time == 0, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4786 media_sample = ammediastream_allocate_sample(&source, test_data, 8);
4787 start_time = 12345678;
4788 end_time = 23456789;
4789 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
4790 ok(hr == S_OK, "Got hr %#x.\n", hr);
4791 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
4792 ok(hr == S_OK, "Got hr %#x.\n", hr);
4793 IMediaSample_Release(media_sample);
4795 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4796 ok(hr == S_OK, "Got hr %#x.\n", hr);
4798 start_time = 0xdeadbeefdeadbeef;
4799 end_time = 0xdeadbeefdeadbeef;
4800 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4801 ok(hr == S_OK, "Got hr %#x.\n", hr);
4802 ok(start_time == 12345678, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4803 ok(end_time == 12347946, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4805 media_sample = ammediastream_allocate_sample(&source, test_data, 6);
4806 start_time = 12345678;
4807 end_time = 23456789;
4808 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
4809 ok(hr == S_OK, "Got hr %#x.\n", hr);
4810 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
4811 ok(hr == S_OK, "Got hr %#x.\n", hr);
4812 IMediaSample_Release(media_sample);
4814 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4815 ok(hr == S_OK, "Got hr %#x.\n", hr);
4817 start_time = 0xdeadbeefdeadbeef;
4818 end_time = 0xdeadbeefdeadbeef;
4819 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4820 ok(hr == S_OK, "Got hr %#x.\n", hr);
4821 ok(start_time == 12347946, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4822 ok(end_time == 12346585, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4824 hr = IPin_EndOfStream(pin);
4825 ok(hr == S_OK, "Got hr %#x.\n", hr);
4827 hr = IAudioStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
4828 ok(hr == S_OK, "Got hr %#x.\n", hr);
4830 start_time = 0xdeadbeefdeadbeef;
4831 end_time = 0xdeadbeefdeadbeef;
4832 hr = IAudioStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
4833 ok(hr == S_OK, "Got hr %#x.\n", hr);
4834 ok(start_time == 12346585, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
4835 ok(end_time == 12348399, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
4837 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
4838 ok(hr == S_OK, "Got hr %#x.\n", hr);
4839 IGraphBuilder_Disconnect(graph, pin);
4840 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
4842 ref = IAudioStreamSample_Release(stream_sample);
4843 ok(!ref, "Got outstanding refcount %d.\n", ref);
4844 ref = IAudioData_Release(audio_data);
4845 ok(!ref, "Got outstanding refcount %d.\n", ref);
4846 ref = IAMMultiMediaStream_Release(mmstream);
4847 ok(!ref, "Got outstanding refcount %d.\n", ref);
4848 IMediaFilter_Release(graph_media_filter);
4849 ref = IGraphBuilder_Release(graph);
4850 ok(!ref, "Got outstanding refcount %d.\n", ref);
4851 ref = IMediaStreamFilter_Release(filter);
4852 ok(!ref, "Got outstanding refcount %d.\n", ref);
4853 IPin_Release(pin);
4854 IMemInputPin_Release(mem_input_pin);
4855 IAudioMediaStream_Release(audio_stream);
4856 ref = IMediaStream_Release(stream);
4857 ok(!ref, "Got outstanding refcount %d.\n", ref);
4860 static void test_ddrawstream_initialize(void)
4862 IDirectDrawMediaStream *ddraw_stream;
4863 IAMMediaStream *stream;
4864 IDirectDraw *ddraw2;
4865 IDirectDraw *ddraw;
4866 STREAM_TYPE type;
4867 MSPID mspid;
4868 HRESULT hr;
4869 ULONG ref;
4871 hr = DirectDrawCreate(NULL, &ddraw, NULL);
4872 ok(hr == S_OK, "Got hr %#x.\n", hr);
4874 hr = CoCreateInstance(&CLSID_AMDirectDrawStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
4875 ok(hr == S_OK, "Got hr %#x.\n", hr);
4877 hr = IAMMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
4878 ok(hr == S_OK, "Got hr %#x.\n", hr);
4880 /* Crashes on native. */
4881 if (0)
4883 hr = IAMMediaStream_Initialize(stream, NULL, 0, NULL, STREAMTYPE_WRITE);
4884 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
4887 hr = IAMMediaStream_Initialize(stream, NULL, 0, &test_mspid, STREAMTYPE_WRITE);
4888 ok(hr == S_OK, "Got hr %#x.\n", hr);
4890 hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
4891 ok(hr == S_OK, "Got hr %#x.\n", hr);
4892 ok(IsEqualGUID(&mspid, &test_mspid), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
4893 ok(type == STREAMTYPE_WRITE, "Got type %u.\n", type);
4895 hr = IAMMediaStream_Initialize(stream, (IUnknown *)ddraw, 0, &MSPID_PrimaryAudio, STREAMTYPE_READ);
4896 ok(hr == S_OK, "Got hr %#x.\n", hr);
4898 hr = IAMMediaStream_GetInformation(stream, &mspid, &type);
4899 ok(hr == S_OK, "Got hr %#x.\n", hr);
4900 ok(IsEqualGUID(&mspid, &MSPID_PrimaryAudio), "Got mspid %s.\n", wine_dbgstr_guid(&mspid));
4901 ok(type == STREAMTYPE_READ, "Got type %u.\n", type);
4903 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw2);
4904 ok(hr == S_OK, "Got hr %#x.\n", hr);
4905 ok(ddraw2 == ddraw, "Expected ddraw %p, got %p.\n", ddraw, ddraw2);
4907 IDirectDrawMediaStream_Release(ddraw_stream);
4908 ref = IAMMediaStream_Release(stream);
4909 ok(!ref, "Got outstanding refcount %d.\n", ref);
4910 IDirectDraw_Release(ddraw2);
4911 ref = IDirectDraw_Release(ddraw);
4912 ok(!ref, "Got outstanding refcount %d.\n", ref);
4915 #define check_ddrawstream_get_format(a,b,c) check_ddrawstream_get_format_(__LINE__,a,b,c)
4916 static void check_ddrawstream_get_format_(int line, IDirectDrawMediaStream *stream,
4917 const AM_MEDIA_TYPE *mt, const DDSURFACEDESC *expected_format)
4919 DDSURFACEDESC current_format;
4920 DDSURFACEDESC desired_format;
4921 struct testfilter source;
4922 FILTER_INFO filter_info;
4923 DDSURFACEDESC format;
4924 PIN_INFO pin_info;
4925 DWORD flags;
4926 HRESULT hr;
4927 IPin *pin;
4929 hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
4930 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
4931 hr = IPin_QueryPinInfo(pin, &pin_info);
4932 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
4933 hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info);
4934 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
4936 testfilter_init(&source);
4938 hr = IFilterGraph_AddFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface, L"source");
4939 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
4941 hr = IFilterGraph_ConnectDirect(filter_info.pGraph, &source.source.pin.IPin_iface, pin, mt);
4942 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
4944 hr = IDirectDrawMediaStream_GetFormat(stream, NULL, NULL, NULL, NULL);
4945 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
4947 memset(&current_format, 0xcc, sizeof(current_format));
4948 current_format.dwSize = sizeof(current_format);
4949 memset(&desired_format, 0xcc, sizeof(desired_format));
4950 desired_format.dwSize = sizeof(desired_format);
4951 flags = 0xdeadbeef;
4952 hr = IDirectDrawMediaStream_GetFormat(stream, &current_format, NULL, &desired_format, &flags);
4953 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
4954 memset(&format, 0xcc, sizeof(format));
4955 format.dwSize = sizeof(format);
4956 format.ddpfPixelFormat = expected_format->ddpfPixelFormat;
4957 format.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
4958 format.dwWidth = 333;
4959 format.dwHeight = 444;
4960 format.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
4961 ok_(__FILE__, line)(memcmp(&current_format, &format, sizeof(DDSURFACEDESC)) == 0, "Current format didn't match.\n");
4962 format.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
4963 ok_(__FILE__, line)(memcmp(&desired_format, &format, sizeof(DDSURFACEDESC)) == 0, "Desired format didn't match.\n");
4965 hr = IFilterGraph_Disconnect(filter_info.pGraph, &source.source.pin.IPin_iface);
4966 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
4967 hr = IFilterGraph_Disconnect(filter_info.pGraph, pin);
4968 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
4970 hr = IFilterGraph_RemoveFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface);
4971 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
4973 IFilterGraph_Release(filter_info.pGraph);
4974 IBaseFilter_Release(pin_info.pFilter);
4975 IPin_Release(pin);
4978 static void test_ddrawstream_get_format(void)
4980 IAMMultiMediaStream *mmstream = create_ammultimediastream();
4981 IDirectDrawMediaStream *ddraw_stream;
4982 DDSURFACEDESC current_format;
4983 DDSURFACEDESC desired_format;
4984 IDirectDrawPalette *palette;
4985 IMediaStream *stream;
4986 VIDEOINFO video_info;
4987 AM_MEDIA_TYPE mt;
4988 DWORD flags;
4989 HRESULT hr;
4990 ULONG ref;
4992 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
4993 ok(hr == S_OK, "Got hr %#x.\n", hr);
4994 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
4995 ok(hr == S_OK, "Got hr %#x.\n", hr);
4997 current_format.dwSize = sizeof(current_format);
4998 desired_format.dwSize = sizeof(desired_format);
4999 hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, &palette, &desired_format, &flags);
5000 ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
5002 video_info = rgb32_video_info;
5003 video_info.rcSource.right = 222;
5004 video_info.rcSource.bottom = 333;
5005 video_info.rcTarget.right = 444;
5006 video_info.rcTarget.bottom = 666;
5007 mt = rgb32_mt;
5008 mt.pbFormat = (BYTE *)&video_info;
5009 check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format);
5011 video_info = rgb32_video_info;
5012 video_info.bmiHeader.biHeight = 444;
5013 mt = rgb32_mt;
5014 mt.pbFormat = (BYTE *)&video_info;
5015 check_ddrawstream_get_format(ddraw_stream, &mt, &rgb32_format);
5017 check_ddrawstream_get_format(ddraw_stream, &rgb8_mt, &rgb8_format);
5018 check_ddrawstream_get_format(ddraw_stream, &rgb555_mt, &rgb555_format);
5019 check_ddrawstream_get_format(ddraw_stream, &rgb565_mt, &rgb565_format);
5020 check_ddrawstream_get_format(ddraw_stream, &rgb24_mt, &rgb24_format);
5021 check_ddrawstream_get_format(ddraw_stream, &rgb32_mt, &rgb32_format);
5023 current_format.dwSize = sizeof(current_format);
5024 desired_format.dwSize = sizeof(desired_format);
5025 hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, &palette, &desired_format, &flags);
5026 ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
5028 ref = IAMMultiMediaStream_Release(mmstream);
5029 ok(!ref, "Got outstanding refcount %d.\n", ref);
5030 IDirectDrawMediaStream_Release(ddraw_stream);
5031 ref = IMediaStream_Release(stream);
5032 ok(!ref, "Got outstanding refcount %d.\n", ref);
5035 #define check_ddrawstream_set_format(a,b,c,d) check_ddrawstream_set_format_(__LINE__,a,b,c,d)
5036 static void check_ddrawstream_set_format_(int line, IDirectDrawMediaStream *stream,
5037 const DDSURFACEDESC *format, const AM_MEDIA_TYPE *mt, HRESULT expected_hr)
5039 struct testfilter source;
5040 FILTER_INFO filter_info;
5041 PIN_INFO pin_info;
5042 HRESULT hr;
5043 IPin *pin;
5045 hr = IDirectDrawMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5046 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
5047 hr = IPin_QueryPinInfo(pin, &pin_info);
5048 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
5049 hr = IBaseFilter_QueryFilterInfo(pin_info.pFilter, &filter_info);
5050 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
5052 testfilter_init(&source);
5054 hr = IFilterGraph_AddFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface, L"source");
5055 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
5057 hr = IDirectDrawMediaStream_SetFormat(stream, format, NULL);
5058 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x.\n", hr);
5060 if (mt)
5062 DDSURFACEDESC current_format;
5063 DDSURFACEDESC desired_format;
5064 DWORD flags;
5066 hr = IFilterGraph_ConnectDirect(filter_info.pGraph, &source.source.pin.IPin_iface, pin, mt);
5067 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
5069 memset(&current_format, 0xcc, sizeof(current_format));
5070 memset(&desired_format, 0xcc, sizeof(desired_format));
5071 flags = 0xdeadbeef;
5072 current_format.dwSize = sizeof(current_format);
5073 desired_format.dwSize = sizeof(desired_format);
5074 hr = IDirectDrawMediaStream_GetFormat(stream, &current_format, NULL, &desired_format, &flags);
5075 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
5076 if (format->dwFlags & DDSD_PIXELFORMAT)
5078 ok_(__FILE__, line)(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT),
5079 "Got current format flags %#x.\n", current_format.dwFlags);
5080 ok_(__FILE__, line)(memcmp(&current_format.ddpfPixelFormat, &format->ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0,
5081 "Current pixel format didn't match.\n");
5082 ok_(__FILE__, line)(memcmp(&desired_format.ddpfPixelFormat, &format->ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0,
5083 "Desired pixel format didn't match.\n");
5085 else
5087 ok_(__FILE__, line)(current_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS),
5088 "Got flags %#x.\n", current_format.dwFlags);
5090 ok_(__FILE__, line)(desired_format.dwFlags == (DDSD_WIDTH | DDSD_HEIGHT),
5091 "Got desired format flags %#x.\n", desired_format.dwFlags);
5092 ok_(__FILE__, line)(current_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY),
5093 "Got current format caps %#x.\n", current_format.ddsCaps.dwCaps);
5094 ok_(__FILE__, line)(desired_format.ddsCaps.dwCaps == (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY),
5095 "Got desired format caps %#x.\n", desired_format.ddsCaps.dwCaps);
5096 ok_(__FILE__, line)(flags == 0, "Got flags %#x.\n", flags);
5098 hr = IFilterGraph_Disconnect(filter_info.pGraph, &source.source.pin.IPin_iface);
5099 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
5100 hr = IFilterGraph_Disconnect(filter_info.pGraph, pin);
5101 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
5104 hr = IFilterGraph_RemoveFilter(filter_info.pGraph, &source.filter.IBaseFilter_iface);
5105 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
5107 IFilterGraph_Release(filter_info.pGraph);
5108 IBaseFilter_Release(pin_info.pFilter);
5109 IPin_Release(pin);
5112 static void test_ddrawstream_set_format(void)
5114 static const DDSURFACEDESC rgb1_format =
5116 .dwSize = sizeof(DDSURFACEDESC),
5117 .dwFlags = DDSD_PIXELFORMAT,
5118 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
5119 .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED1,
5120 .ddpfPixelFormat.u1.dwRGBBitCount = 1,
5122 static const DDSURFACEDESC rgb2_format =
5124 .dwSize = sizeof(DDSURFACEDESC),
5125 .dwFlags = DDSD_PIXELFORMAT,
5126 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
5127 .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED2,
5128 .ddpfPixelFormat.u1.dwRGBBitCount = 2,
5130 static const DDSURFACEDESC rgb4_format =
5132 .dwSize = sizeof(DDSURFACEDESC),
5133 .dwFlags = DDSD_PIXELFORMAT,
5134 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
5135 .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED4,
5136 .ddpfPixelFormat.u1.dwRGBBitCount = 4,
5138 static const DDSURFACEDESC rgb4to8_format =
5140 .dwSize = sizeof(DDSURFACEDESC),
5141 .dwFlags = DDSD_PIXELFORMAT,
5142 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
5143 .ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXEDTO8,
5144 .ddpfPixelFormat.u1.dwRGBBitCount = 4,
5146 static const DDSURFACEDESC rgb332_format =
5148 .dwSize = sizeof(DDSURFACEDESC),
5149 .dwFlags = DDSD_PIXELFORMAT,
5150 .ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT),
5151 .ddpfPixelFormat.dwFlags = DDPF_RGB,
5152 .ddpfPixelFormat.u1.dwRGBBitCount = 8,
5153 .ddpfPixelFormat.u2.dwRBitMask = 0xe0,
5154 .ddpfPixelFormat.u3.dwGBitMask = 0x1c,
5155 .ddpfPixelFormat.u4.dwBBitMask = 0x03,
5158 IDirectDrawMediaStream *ddraw_stream;
5159 IAMMultiMediaStream *mmstream;
5160 DDSURFACEDESC current_format;
5161 DDSURFACEDESC desired_format;
5162 struct testfilter source;
5163 IGraphBuilder *graph;
5164 DDSURFACEDESC format;
5165 IMediaStream *stream;
5166 VIDEOINFO video_info;
5167 AM_MEDIA_TYPE mt;
5168 HRESULT hr;
5169 ULONG ref;
5170 IPin *pin;
5172 mmstream = create_ammultimediastream();
5174 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
5175 ok(hr == S_OK, "Got hr %#x.\n", hr);
5176 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
5177 ok(hr == S_OK, "Got hr %#x.\n", hr);
5179 check_ddrawstream_set_format(ddraw_stream, &rgb8_format, &rgb8_mt, S_OK);
5180 check_ddrawstream_set_format(ddraw_stream, &rgb555_format, &rgb555_mt, S_OK);
5181 check_ddrawstream_set_format(ddraw_stream, &rgb565_format, &rgb565_mt, S_OK);
5182 check_ddrawstream_set_format(ddraw_stream, &rgb24_format, &rgb24_mt, S_OK);
5183 check_ddrawstream_set_format(ddraw_stream, &rgb32_format, &rgb32_mt, S_OK);
5184 check_ddrawstream_set_format(ddraw_stream, &argb32_format, &rgb32_mt, S_OK);
5185 check_ddrawstream_set_format(ddraw_stream, &yuy2_format, NULL, S_OK);
5186 check_ddrawstream_set_format(ddraw_stream, &yv12_format, NULL, S_OK);
5188 format = rgb32_format;
5189 format.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS | DDPF_ALPHA
5190 | DDPF_COMPRESSED | DDPF_RGBTOYUV | DDPF_ZBUFFER | DDPF_ZPIXELS | DDPF_STENCILBUFFER
5191 | DDPF_ALPHAPREMULT | DDPF_LUMINANCE | DDPF_BUMPLUMINANCE | DDPF_BUMPDUDV;
5192 check_ddrawstream_set_format(ddraw_stream, &format, &rgb32_mt, S_OK);
5194 format = yuy2_format;
5195 format.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS | DDPF_ALPHA
5196 | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXEDTO8 | DDPF_PALETTEINDEXED8
5197 | DDPF_RGB | DDPF_COMPRESSED | DDPF_RGBTOYUV | DDPF_YUV | DDPF_ZBUFFER
5198 | DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_ZPIXELS
5199 | DDPF_STENCILBUFFER | DDPF_ALPHAPREMULT | DDPF_LUMINANCE
5200 | DDPF_BUMPLUMINANCE | DDPF_BUMPDUDV;
5201 check_ddrawstream_set_format(ddraw_stream, &format, NULL, S_OK);
5203 format = rgb32_format;
5204 format.dwFlags |= DDSD_CAPS;
5205 format.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
5206 check_ddrawstream_set_format(ddraw_stream, &format, &rgb32_mt, S_OK);
5208 format = rgb8_format;
5209 format.dwFlags = 0;
5210 check_ddrawstream_set_format(ddraw_stream, &format, &rgb32_mt, S_OK);
5212 check_ddrawstream_set_format(ddraw_stream, &rgb1_format, NULL, DDERR_INVALIDSURFACETYPE);
5213 check_ddrawstream_set_format(ddraw_stream, &rgb2_format, NULL, DDERR_INVALIDSURFACETYPE);
5214 check_ddrawstream_set_format(ddraw_stream, &rgb4_format, NULL, DDERR_INVALIDSURFACETYPE);
5215 check_ddrawstream_set_format(ddraw_stream, &rgb4to8_format, NULL, DDERR_INVALIDSURFACETYPE);
5216 check_ddrawstream_set_format(ddraw_stream, &rgb332_format, NULL, DDERR_INVALIDSURFACETYPE);
5218 format = rgb8_format;
5219 format.ddpfPixelFormat.dwFlags &= ~DDPF_RGB;
5220 check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5222 format = rgb8_format;
5223 format.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED1;
5224 check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5226 format = rgb32_format;
5227 format.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;
5228 check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5230 format = rgb32_format;
5231 format.ddpfPixelFormat.dwFlags |= DDPF_YUV;
5232 check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5234 format = rgb565_format;
5235 format.ddpfPixelFormat.u2.dwRBitMask = 0x001f;
5236 format.ddpfPixelFormat.u3.dwGBitMask = 0x07e0;
5237 format.ddpfPixelFormat.u4.dwBBitMask = 0xf800;
5238 check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5240 format = rgb32_format;
5241 format.ddpfPixelFormat.u2.dwRBitMask = 0x00ff00;
5242 format.ddpfPixelFormat.u3.dwGBitMask = 0x0000ff;
5243 format.ddpfPixelFormat.u4.dwBBitMask = 0xff0000;
5244 check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5246 format = yuy2_format;
5247 format.ddpfPixelFormat.u1.dwYUVBitCount = 0;
5248 check_ddrawstream_set_format(ddraw_stream, &format, NULL, E_INVALIDARG);
5250 format = rgb32_format;
5251 format.dwSize = sizeof(DDSURFACEDESC) + 1;
5252 check_ddrawstream_set_format(ddraw_stream, &format, NULL, E_INVALIDARG);
5254 format = rgb32_format;
5255 format.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT) + 1;
5256 check_ddrawstream_set_format(ddraw_stream, &format, NULL, DDERR_INVALIDSURFACETYPE);
5258 ref = IAMMultiMediaStream_Release(mmstream);
5259 ok(!ref, "Got outstanding refcount %d.\n", ref);
5260 IDirectDrawMediaStream_Release(ddraw_stream);
5261 ref = IMediaStream_Release(stream);
5262 ok(!ref, "Got outstanding refcount %d.\n", ref);
5264 mmstream = create_ammultimediastream();
5266 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
5267 ok(hr == S_OK, "Got hr %#x.\n", hr);
5268 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
5269 ok(hr == S_OK, "Got hr %#x.\n", hr);
5270 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5271 ok(hr == S_OK, "Got hr %#x.\n", hr);
5273 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
5274 ok(hr == S_OK, "Got hr %#x.\n", hr);
5275 ok(!!graph, "Expected non-NULL graph.\n");
5277 testfilter_init(&source);
5279 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
5280 ok(hr == S_OK, "Got hr %#x.\n", hr);
5282 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &rgb8_mt);
5283 ok(hr == S_OK, "Got hr %#x.\n", hr);
5285 source.preferred_mt = NULL;
5287 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
5288 ok(hr == DDERR_INVALIDSURFACETYPE, "Got hr %#x.\n", hr);
5289 ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8),
5290 "Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
5291 hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, NULL, &desired_format, NULL);
5292 ok(hr == S_OK, "Got hr %#x.\n", hr);
5293 ok(current_format.ddpfPixelFormat.u1.dwRGBBitCount == 8,
5294 "Got rgb bit count %u.\n", current_format.ddpfPixelFormat.u1.dwRGBBitCount);
5295 ok(desired_format.ddpfPixelFormat.u1.dwRGBBitCount == 8,
5296 "Got rgb bit count %u.\n", desired_format.ddpfPixelFormat.u1.dwRGBBitCount);
5298 format = rgb555_format;
5299 format.dwFlags = 0;
5300 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
5301 ok(hr == S_OK, "Got hr %#x.\n", hr);
5302 ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB8),
5303 "Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
5305 source.preferred_mt = &rgb555_mt;
5307 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb8_format, NULL);
5308 ok(hr == S_OK, "Got hr %#x.\n", hr);
5310 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &rgb555_format, NULL);
5311 ok(hr == S_OK, "Got hr %#x.\n", hr);
5312 ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB555),
5313 "Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
5314 hr = IDirectDrawMediaStream_GetFormat(ddraw_stream, &current_format, NULL, &desired_format, NULL);
5315 ok(hr == S_OK, "Got hr %#x.\n", hr);
5316 ok(current_format.ddpfPixelFormat.u1.dwRGBBitCount == 16,
5317 "Got rgb bit count %u.\n", current_format.ddpfPixelFormat.u1.dwRGBBitCount);
5318 ok(desired_format.ddpfPixelFormat.u1.dwRGBBitCount == 16,
5319 "Got rgb bit count %u.\n", desired_format.ddpfPixelFormat.u1.dwRGBBitCount);
5321 video_info = rgb555_video_info;
5322 video_info.bmiHeader.biWidth = 222;
5323 video_info.bmiHeader.biHeight = -555;
5324 mt = rgb555_mt;
5325 mt.pbFormat = (BYTE *)&video_info;
5326 source.preferred_mt = &mt;
5328 format = rgb555_format;
5329 format.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT;
5330 format.dwWidth = 222;
5331 format.dwHeight = 555;
5332 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, &format, NULL);
5333 ok(hr == S_OK, "Got hr %#x.\n", hr);
5334 ok(IsEqualGUID(&source.source.pin.mt.subtype, &MEDIASUBTYPE_RGB555),
5335 "Got subtype %s.\n", wine_dbgstr_guid(&source.source.pin.mt.subtype));
5336 ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth == 222,
5337 "Got width %d.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biWidth);
5338 ok(((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight == -555,
5339 "Got height %d.\n", ((VIDEOINFO *)source.source.pin.mt.pbFormat)->bmiHeader.biHeight);
5341 hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
5342 ok(hr == S_OK, "Got hr %#x.\n", hr);
5343 hr = IGraphBuilder_Disconnect(graph, pin);
5344 ok(hr == S_OK, "Got hr %#x.\n", hr);
5346 ref = IAMMultiMediaStream_Release(mmstream);
5347 ok(!ref, "Got outstanding refcount %d.\n", ref);
5348 ref = IGraphBuilder_Release(graph);
5349 ok(!ref, "Got outstanding refcount %d.\n", ref);
5350 IPin_Release(pin);
5351 IDirectDrawMediaStream_Release(ddraw_stream);
5352 ref = IMediaStream_Release(stream);
5353 ok(!ref, "Got outstanding refcount %d.\n", ref);
5356 static void test_ddrawstream_receive(void)
5358 ALLOCATOR_PROPERTIES properties =
5360 .cBuffers = 1,
5361 .cbBuffer = 16,
5362 .cbAlign = 1,
5365 IAMMultiMediaStream *mmstream = create_ammultimediastream();
5366 ALLOCATOR_PROPERTIES actual;
5367 IMediaStreamFilter *filter;
5368 struct testfilter source;
5369 IMemAllocator *allocator;
5370 IGraphBuilder *graph;
5371 IMediaStream *stream;
5372 IMediaSample *sample;
5373 HANDLE thread;
5374 HRESULT hr;
5375 ULONG ref;
5376 IPin *pin;
5378 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
5379 ok(hr == S_OK, "Got hr %#x.\n", hr);
5380 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
5381 ok(hr == S_OK, "Got hr %#x.\n", hr);
5382 ok(!!filter, "Expected non-null filter.\n");
5383 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
5384 ok(hr == S_OK, "Got hr %#x.\n", hr);
5385 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5386 ok(hr == S_OK, "Got hr %#x.\n", hr);
5387 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
5388 ok(hr == S_OK, "Got hr %#x.\n", hr);
5389 ok(graph != NULL, "Expected non-NULL graph.\n");
5390 testfilter_init(&source);
5391 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
5392 ok(hr == S_OK, "Got hr %#x.\n", hr);
5393 hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (void **)&allocator);
5394 ok(hr == S_OK, "Got hr %#x.\n", hr);
5395 hr = IMemAllocator_SetProperties(allocator, &properties, &actual);
5396 ok(hr == S_OK, "Got hr %#x.\n", hr);
5397 hr = IMemAllocator_Commit(allocator);
5398 ok(hr == S_OK, "Got hr %#x.\n", hr);
5400 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &rgb32_mt);
5401 ok(hr == S_OK, "Got hr %#x.\n", hr);
5403 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
5404 ok(hr == S_OK, "Got hr %#x.\n", hr);
5405 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample);
5406 ok(hr == S_OK, "Got hr %#x.\n", hr);
5407 ref = IMediaSample_Release(sample);
5408 ok(!ref, "Got outstanding refcount %d.\n", ref);
5410 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
5411 ok(hr == S_OK, "Got hr %#x.\n", hr);
5413 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
5414 ok(hr == S_OK, "Got hr %#x.\n", hr);
5416 ammediastream_mem_input_pin = source.source.pMemInputPin;
5417 ammediastream_media_sample = sample;
5418 ammediastream_sleep_time = 0;
5419 ammediastream_expected_hr = S_OK;
5420 thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
5422 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
5424 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
5425 ok(hr == S_OK, "Got hr %#x.\n", hr);
5427 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
5428 CloseHandle(thread);
5430 ref = IMediaSample_Release(sample);
5431 ok(!ref, "Got outstanding refcount %d.\n", ref);
5433 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
5434 ok(hr == S_OK, "Got hr %#x.\n", hr);
5435 hr = IMemInputPin_Receive(source.source.pMemInputPin, sample);
5436 ok(hr == S_OK, "Got hr %#x.\n", hr);
5437 ref = IMediaSample_Release(sample);
5438 ok(!ref, "Got outstanding refcount %d.\n", ref);
5440 IGraphBuilder_Disconnect(graph, pin);
5441 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
5443 hr = IMemAllocator_Decommit(allocator);
5444 ok(hr == S_OK, "Got hr %#x.\n", hr);
5446 ref = IAMMultiMediaStream_Release(mmstream);
5447 ok(!ref, "Got outstanding refcount %d.\n", ref);
5448 ref = IGraphBuilder_Release(graph);
5449 ok(!ref, "Got outstanding refcount %d.\n", ref);
5450 ref = IMediaStreamFilter_Release(filter);
5451 ok(!ref, "Got outstanding refcount %d.\n", ref);
5452 IPin_Release(pin);
5453 ref = IMediaStream_Release(stream);
5454 ok(!ref, "Got outstanding refcount %d.\n", ref);
5455 ref = IMemAllocator_Release(allocator);
5456 ok(!ref, "Got outstanding refcount %d.\n", ref);
5459 static void test_ddrawstream_begin_flush_end_flush(void)
5461 IAMMultiMediaStream *mmstream = create_ammultimediastream();
5462 IDirectDrawStreamSample *stream_sample;
5463 IDirectDrawMediaStream *ddraw_stream;
5464 IMediaSample *media_sample;
5465 IMediaFilter *media_filter;
5466 struct testfilter source;
5467 IGraphBuilder *graph;
5468 IMediaStream *stream;
5469 VIDEOINFO video_info;
5470 AM_MEDIA_TYPE mt;
5471 HANDLE thread;
5472 HRESULT hr;
5473 ULONG ref;
5474 IPin *pin;
5476 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
5477 ok(hr == S_OK, "Got hr %#x.\n", hr);
5478 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
5479 ok(hr == S_OK, "Got hr %#x.\n", hr);
5480 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
5481 ok(hr == S_OK, "Got hr %#x.\n", hr);
5482 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5483 ok(hr == S_OK, "Got hr %#x.\n", hr);
5484 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
5485 ok(hr == S_OK, "Got hr %#x.\n", hr);
5486 ok(graph != NULL, "Expected non-NULL graph.\n");
5487 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
5488 ok(hr == S_OK, "Got hr %#x.\n", hr);
5489 testfilter_init(&source);
5490 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
5491 ok(hr == S_OK, "Got hr %#x.\n", hr);
5493 hr = IMediaFilter_SetSyncSource(media_filter, NULL);
5494 ok(hr == S_OK, "Got hr %#x.\n", hr);
5496 video_info = rgb32_video_info;
5497 video_info.bmiHeader.biWidth = 3;
5498 video_info.bmiHeader.biHeight = 1;
5499 mt = rgb32_mt;
5500 mt.pbFormat = (BYTE *)&video_info;
5501 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
5502 ok(hr == S_OK, "Got hr %#x.\n", hr);
5504 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample);
5505 ok(hr == S_OK, "Got hr %#x.\n", hr);
5507 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
5508 ok(hr == S_OK, "Got hr %#x.\n", hr);
5510 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source.source, &media_sample, NULL, NULL, 0);
5511 ok(hr == S_OK, "Got hr %#x.\n", hr);
5513 ammediastream_mem_input_pin = source.source.pMemInputPin;
5514 ammediastream_media_sample = media_sample;
5515 ammediastream_sleep_time = 0;
5516 ammediastream_expected_hr = S_FALSE;
5517 thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
5519 hr = IPin_BeginFlush(pin);
5520 ok(hr == S_OK, "Got hr %#x.\n", hr);
5522 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
5523 CloseHandle(thread);
5525 ref = IMediaSample_Release(media_sample);
5526 ok(!ref, "Got outstanding refcount %d.\n", ref);
5528 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source.source, &media_sample, NULL, NULL, 0);
5529 ok(hr == S_OK, "Got hr %#x.\n", hr);
5530 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
5531 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
5533 ref = IMediaSample_Release(media_sample);
5534 ok(!ref, "Got outstanding refcount %d.\n", ref);
5536 hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
5537 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
5539 hr = IPin_EndOfStream(pin);
5540 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
5542 hr = IPin_EndFlush(pin);
5543 ok(hr == S_OK, "Got hr %#x.\n", hr);
5545 hr = BaseOutputPinImpl_GetDeliveryBuffer(&source.source, &media_sample, NULL, NULL, 0);
5546 ok(hr == S_OK, "Got hr %#x.\n", hr);
5547 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
5548 ok(hr == S_OK, "Got hr %#x.\n", hr);
5549 ref = IMediaSample_Release(media_sample);
5550 ok(!ref, "Got outstanding refcount %d.\n", ref);
5552 hr = IPin_EndOfStream(pin);
5553 ok(hr == S_OK, "Got hr %#x.\n", hr);
5555 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
5556 ok(hr == S_OK, "Got hr %#x.\n", hr);
5558 IGraphBuilder_Disconnect(graph, pin);
5559 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
5561 ref = IDirectDrawStreamSample_Release(stream_sample);
5562 ok(!ref, "Got outstanding refcount %d.\n", ref);
5563 ref = IAMMultiMediaStream_Release(mmstream);
5564 ok(!ref, "Got outstanding refcount %d.\n", ref);
5565 IMediaFilter_Release(media_filter);
5566 ref = IGraphBuilder_Release(graph);
5567 ok(!ref, "Got outstanding refcount %d.\n", ref);
5568 IPin_Release(pin);
5569 IDirectDrawMediaStream_Release(ddraw_stream);
5570 ref = IMediaStream_Release(stream);
5571 ok(!ref, "Got outstanding refcount %d.\n", ref);
5574 static void test_ddrawstream_new_segment(void)
5576 static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
5577 IAMMultiMediaStream *mmstream = create_ammultimediastream();
5578 IDirectDrawStreamSample *stream_sample;
5579 IDirectDrawMediaStream *ddraw_stream;
5580 IMemInputPin *mem_input_pin;
5581 IMediaSample *media_sample;
5582 IMediaFilter *media_filter;
5583 struct testfilter source;
5584 STREAM_TIME start_time;
5585 STREAM_TIME end_time;
5586 IGraphBuilder *graph;
5587 IMediaStream *stream;
5588 VIDEOINFO video_info;
5589 AM_MEDIA_TYPE mt;
5590 HRESULT hr;
5591 ULONG ref;
5592 IPin *pin;
5594 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
5595 ok(hr == S_OK, "Got hr %#x.\n", hr);
5596 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
5597 ok(hr == S_OK, "Got hr %#x.\n", hr);
5598 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
5599 ok(hr == S_OK, "Got hr %#x.\n", hr);
5600 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5601 ok(hr == S_OK, "Got hr %#x.\n", hr);
5602 hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
5603 ok(hr == S_OK, "Got hr %#x.\n", hr);
5604 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
5605 ok(hr == S_OK, "Got hr %#x.\n", hr);
5606 ok(graph != NULL, "Expected non-NULL graph.\n");
5607 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
5608 ok(hr == S_OK, "Got hr %#x.\n", hr);
5609 testfilter_init(&source);
5610 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
5611 ok(hr == S_OK, "Got hr %#x.\n", hr);
5613 hr = IMediaFilter_SetSyncSource(media_filter, NULL);
5614 ok(hr == S_OK, "Got hr %#x.\n", hr);
5616 video_info = rgb32_video_info;
5617 video_info.bmiHeader.biWidth = 3;
5618 video_info.bmiHeader.biHeight = 1;
5619 mt = rgb32_mt;
5620 mt.pbFormat = (BYTE *)&video_info;
5621 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
5622 ok(hr == S_OK, "Got hr %#x.\n", hr);
5624 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample);
5625 ok(hr == S_OK, "Got hr %#x.\n", hr);
5627 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
5628 ok(hr == S_OK, "Got hr %#x.\n", hr);
5630 hr = IPin_NewSegment(pin, 11111111, 22222222, 1.0);
5631 ok(hr == S_OK, "Got hr %#x.\n", hr);
5633 hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
5634 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
5636 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
5637 start_time = 12345678;
5638 end_time = 23456789;
5639 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
5640 ok(hr == S_OK, "Got hr %#x.\n", hr);
5641 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
5642 ok(hr == S_OK, "Got hr %#x.\n", hr);
5643 IMediaSample_Release(media_sample);
5645 start_time = 0xdeadbeefdeadbeef;
5646 end_time = 0xdeadbeefdeadbeef;
5647 hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
5648 ok(hr == S_OK, "Got hr %#x.\n", hr);
5649 ok(start_time == 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
5650 ok(end_time == 34567900, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
5652 hr = IPin_NewSegment(pin, 11111111, 22222222, 2.0);
5653 ok(hr == S_OK, "Got hr %#x.\n", hr);
5655 hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
5656 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
5658 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
5659 start_time = 12345678;
5660 end_time = 23456789;
5661 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
5662 ok(hr == S_OK, "Got hr %#x.\n", hr);
5663 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
5664 ok(hr == S_OK, "Got hr %#x.\n", hr);
5665 IMediaSample_Release(media_sample);
5667 start_time = 0xdeadbeefdeadbeef;
5668 end_time = 0xdeadbeefdeadbeef;
5669 hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
5670 ok(hr == S_OK, "Got hr %#x.\n", hr);
5671 ok(start_time == 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
5672 ok(end_time == 34567900, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
5674 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
5675 ok(hr == S_OK, "Got hr %#x.\n", hr);
5676 IGraphBuilder_Disconnect(graph, pin);
5677 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
5679 ref = IDirectDrawStreamSample_Release(stream_sample);
5680 ok(!ref, "Got outstanding refcount %d.\n", ref);
5681 ref = IAMMultiMediaStream_Release(mmstream);
5682 ok(!ref, "Got outstanding refcount %d.\n", ref);
5683 IMediaFilter_Release(media_filter);
5684 ref = IGraphBuilder_Release(graph);
5685 ok(!ref, "Got outstanding refcount %d.\n", ref);
5686 IPin_Release(pin);
5687 IMemInputPin_Release(mem_input_pin);
5688 IDirectDrawMediaStream_Release(ddraw_stream);
5689 ref = IMediaStream_Release(stream);
5690 ok(!ref, "Got outstanding refcount %d.\n", ref);
5693 static void test_ddrawstream_get_time_per_frame(void)
5695 IAMMultiMediaStream *mmstream = create_ammultimediastream();
5696 IDirectDrawMediaStream *ddraw_stream;
5697 struct testfilter source;
5698 STREAM_TIME frame_time;
5699 IGraphBuilder *graph;
5700 IMediaStream *stream;
5701 VIDEOINFO video_info;
5702 AM_MEDIA_TYPE mt;
5703 HRESULT hr;
5704 ULONG ref;
5705 IPin *pin;
5707 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
5708 ok(hr == S_OK, "Got hr %#x.\n", hr);
5709 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
5710 ok(hr == S_OK, "Got hr %#x.\n", hr);
5711 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
5712 ok(hr == S_OK, "Got hr %#x.\n", hr);
5713 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5714 ok(hr == S_OK, "Got hr %#x.\n", hr);
5715 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
5716 ok(hr == S_OK, "Got hr %#x.\n", hr);
5717 ok(graph != NULL, "Expected non-NULL graph.\n");
5718 testfilter_init(&source);
5719 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
5720 ok(hr == S_OK, "Got hr %#x.\n", hr);
5722 hr = IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream, NULL);
5723 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
5725 hr = IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream, &frame_time);
5726 ok(hr == MS_E_NOSTREAM, "Got hr %#x.\n", hr);
5728 video_info = rgb32_video_info;
5729 video_info.AvgTimePerFrame = 12345678;
5730 mt = rgb32_mt;
5731 mt.pbFormat = (BYTE *)&video_info;
5732 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
5733 ok(hr == S_OK, "Got hr %#x.\n", hr);
5735 frame_time = 0xdeadbeefdeadbeef;
5736 hr = IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream, &frame_time);
5737 ok(hr == S_OK, "Got hr %#x.\n", hr);
5738 ok(frame_time == 12345678, "Got frame time %s.\n", wine_dbgstr_longlong(frame_time));
5740 ref = IAMMultiMediaStream_Release(mmstream);
5741 ok(!ref, "Got outstanding refcount %d.\n", ref);
5742 ref = IGraphBuilder_Release(graph);
5743 ok(!ref, "Got outstanding refcount %d.\n", ref);
5744 IPin_Release(pin);
5745 IDirectDrawMediaStream_Release(ddraw_stream);
5746 ref = IMediaStream_Release(stream);
5747 ok(!ref, "Got outstanding refcount %d.\n", ref);
5750 static void check_ammediastream_join_am_multi_media_stream(const CLSID *clsid)
5752 IAMMultiMediaStream *mmstream = create_ammultimediastream();
5753 IMultiMediaStream *mmstream2;
5754 IAMMediaStream *stream;
5755 HRESULT hr;
5756 ULONG mmstream_ref;
5757 ULONG ref;
5759 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
5760 ok(hr == S_OK, "Got hr %#x.\n", hr);
5762 mmstream_ref = get_refcount(mmstream);
5764 hr = IAMMediaStream_JoinAMMultiMediaStream(stream, mmstream);
5765 ok(hr == S_OK, "Got hr %#x.\n", hr);
5767 ref = get_refcount(mmstream);
5768 ok(ref == mmstream_ref, "Expected outstanding refcount %d, got %d.\n", mmstream_ref, ref);
5770 hr = IAMMediaStream_GetMultiMediaStream(stream, &mmstream2);
5771 ok(hr == S_OK, "Got hr %#x.\n", hr);
5772 ok(mmstream2 == (IMultiMediaStream *)mmstream, "Expected mmstream %p, got %p.\n", mmstream, mmstream2);
5774 IMultiMediaStream_Release(mmstream2);
5776 hr = IAMMediaStream_JoinAMMultiMediaStream(stream, NULL);
5777 ok(hr == S_OK, "Got hr %#x.\n", hr);
5779 hr = IAMMediaStream_GetMultiMediaStream(stream, &mmstream2);
5780 ok(hr == S_OK, "Got hr %#x.\n", hr);
5781 ok(mmstream2 == NULL, "Got mmstream %p.\n", mmstream2);
5783 ref = IAMMediaStream_Release(stream);
5784 ok(!ref, "Got outstanding refcount %d.\n", ref);
5785 ref = IAMMultiMediaStream_Release(mmstream);
5786 ok(!ref, "Got outstanding refcount %d.\n", ref);
5789 static void test_ammediastream_join_am_multi_media_stream(void)
5791 check_ammediastream_join_am_multi_media_stream(&CLSID_AMAudioStream);
5792 check_ammediastream_join_am_multi_media_stream(&CLSID_AMDirectDrawStream);
5795 static void check_ammediastream_join_filter(const CLSID *clsid)
5797 IAMMultiMediaStream *mmstream = create_ammultimediastream();
5798 IMediaStreamFilter *filter, *filter2, *filter3;
5799 IAMMediaStream *stream;
5800 HRESULT hr;
5801 ULONG ref;
5803 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
5804 ok(hr == S_OK, "Got hr %#x.\n", hr);
5805 ok(!!filter, "Expected non-null filter.\n");
5806 EXPECT_REF(filter, 3);
5808 hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream);
5809 ok(hr == S_OK, "Got hr %#x.\n", hr);
5810 EXPECT_REF(filter, 3);
5812 hr = CoCreateInstance(&CLSID_MediaStreamFilter, NULL, CLSCTX_INPROC_SERVER,
5813 &IID_IMediaStreamFilter, (void **)&filter2);
5814 ok(hr == S_OK, "Got hr %#x.\n", hr);
5815 EXPECT_REF(filter, 3);
5816 EXPECT_REF(filter2, 1);
5818 hr = IAMMediaStream_JoinFilter(stream, filter2);
5819 ok(hr == S_OK, "Got hr %#x.\n", hr);
5820 EXPECT_REF(filter, 3);
5821 EXPECT_REF(filter2, 1);
5823 /* Crashes on native. */
5824 if (0)
5826 hr = IAMMediaStream_JoinFilter(stream, NULL);
5827 ok(hr == S_OK, "Got hr %#x.\n", hr);
5830 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter3);
5831 ok(hr == S_OK, "Got hr %#x.\n", hr);
5832 ok(filter3 == filter, "Expected filter %p, got %p.\n", filter, filter3);
5833 EXPECT_REF(filter, 4);
5835 IMediaStreamFilter_Release(filter3);
5836 EXPECT_REF(filter, 3);
5838 ref = IMediaStreamFilter_Release(filter2);
5839 ok(!ref, "Got outstanding refcount %d.\n", ref);
5840 ref = IAMMediaStream_Release(stream);
5841 ok(!ref, "Got outstanding refcount %d.\n", ref);
5842 EXPECT_REF(filter, 3);
5843 ref = IAMMultiMediaStream_Release(mmstream);
5844 ok(!ref, "Got outstanding refcount %d.\n", ref);
5845 EXPECT_REF(filter, 1);
5846 ref = IMediaStreamFilter_Release(filter);
5847 ok(!ref, "Got outstanding refcount %d.\n", ref);
5850 static void test_ammediastream_join_filter(void)
5852 check_ammediastream_join_filter(&CLSID_AMAudioStream);
5853 check_ammediastream_join_filter(&CLSID_AMDirectDrawStream);
5856 static void check_ammediastream_join_filter_graph(const MSPID *id)
5858 IAMMultiMediaStream *mmstream = create_ammultimediastream();
5859 IGraphBuilder *builder, *builder2;
5860 IMediaStreamFilter *filter;
5861 IAMMediaStream *stream;
5862 IFilterGraph *graph;
5863 FILTER_INFO info;
5864 HRESULT hr;
5865 ULONG ref;
5867 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
5868 ok(hr == S_OK, "Got hr %#x.\n", hr);
5869 ok(!!filter, "Expected non-null filter.\n");
5871 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, id, 0, (IMediaStream **)&stream);
5872 ok(hr == S_OK, "Got hr %#x.\n", hr);
5874 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &builder);
5875 ok(hr == S_OK, "Got hr %#x.\n", hr);
5876 ok(!!builder, "Expected non-null graph.\n");
5877 EXPECT_REF(builder, 4);
5879 hr = IMediaStreamFilter_QueryFilterInfo(filter, &info);
5880 ok(hr == S_OK, "Got hr %#x.\n", hr);
5881 ok(info.pGraph == (IFilterGraph *)builder, "Expected graph %p, got %p.\n", (IFilterGraph *)builder, info.pGraph);
5882 EXPECT_REF(builder, 5);
5883 IFilterGraph_Release(info.pGraph);
5884 EXPECT_REF(builder, 4);
5886 hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph, (void **)&graph);
5887 ok(hr == S_OK, "Got hr %#x.\n", hr);
5888 EXPECT_REF(builder, 4);
5889 EXPECT_REF(graph, 1);
5891 /* Crashes on native. */
5892 if (0)
5894 hr = IAMMediaStream_JoinFilterGraph(stream, NULL);
5895 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
5898 hr = IAMMediaStream_JoinFilterGraph(stream, graph);
5899 ok(hr == S_OK, "Got hr %#x.\n", hr);
5900 EXPECT_REF(builder, 4);
5901 EXPECT_REF(graph, 1);
5903 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &builder2);
5904 ok(hr == S_OK, "Got hr %#x.\n", hr);
5905 ok(builder2 == builder, "Expected graph %p, got %p.\n", builder, builder2);
5906 EXPECT_REF(builder, 5);
5907 EXPECT_REF(graph, 1);
5908 IGraphBuilder_Release(builder2);
5909 EXPECT_REF(builder, 4);
5910 EXPECT_REF(graph, 1);
5912 hr = IMediaStreamFilter_QueryFilterInfo(filter, &info);
5913 ok(hr == S_OK, "Got hr %#x.\n", hr);
5914 ok(info.pGraph == (IFilterGraph *)builder, "Expected graph %p, got %p.\n", (IFilterGraph *)builder, info.pGraph);
5915 EXPECT_REF(builder, 5);
5916 EXPECT_REF(graph, 1);
5917 IFilterGraph_Release(info.pGraph);
5918 EXPECT_REF(builder, 4);
5919 EXPECT_REF(graph, 1);
5921 ref = IFilterGraph_Release(graph);
5922 ok(!ref, "Got outstanding refcount %d.\n", ref);
5923 ref = IAMMultiMediaStream_Release(mmstream);
5924 ok(!ref, "Got outstanding refcount %d.\n", ref);
5925 ref = IGraphBuilder_Release(builder);
5926 ok(!ref, "Got outstanding refcount %d.\n", ref);
5927 ref = IMediaStreamFilter_Release(filter);
5928 ok(!ref, "Got outstanding refcount %d.\n", ref);
5929 ref = IAMMediaStream_Release(stream);
5930 ok(!ref, "Got outstanding refcount %d.\n", ref);
5933 static void test_ammediastream_join_filter_graph(void)
5935 check_ammediastream_join_filter_graph(&MSPID_PrimaryAudio);
5936 check_ammediastream_join_filter_graph(&MSPID_PrimaryVideo);
5939 static void check_ammediastream_set_state(const MSPID *id)
5941 IAMMultiMediaStream *mmstream = create_ammultimediastream();
5942 IAMMediaStream *am_stream;
5943 IMediaStream *stream;
5944 HRESULT hr;
5945 ULONG ref;
5947 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
5948 ok(hr == S_OK, "Got hr %#x.\n", hr);
5949 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, id, 0, &stream);
5950 ok(hr == S_OK, "Got hr %#x.\n", hr);
5951 hr = IMediaStream_QueryInterface(stream, &IID_IAMMediaStream, (void **)&am_stream);
5952 ok(hr == S_OK, "Got hr %#x.\n", hr);
5954 hr = IAMMediaStream_SetState(am_stream, 4);
5955 ok(hr == S_OK, "Got hr %#x.\n", hr);
5957 hr = IAMMediaStream_SetState(am_stream, State_Running);
5958 ok(hr == S_OK, "Got hr %#x.\n", hr);
5960 hr = IAMMediaStream_SetState(am_stream, State_Paused);
5961 ok(hr == S_OK, "Got hr %#x.\n", hr);
5963 hr = IAMMediaStream_SetState(am_stream, State_Stopped);
5964 ok(hr == S_OK, "Got hr %#x.\n", hr);
5966 ref = IAMMultiMediaStream_Release(mmstream);
5967 ok(!ref, "Got outstanding refcount %d.\n", ref);
5968 IAMMediaStream_Release(am_stream);
5969 ref = IMediaStream_Release(stream);
5970 ok(!ref, "Got outstanding refcount %d.\n", ref);
5973 static void test_ammediastream_set_state(void)
5975 check_ammediastream_set_state(&MSPID_PrimaryAudio);
5976 check_ammediastream_set_state(&MSPID_PrimaryVideo);
5979 static void check_ammediastream_end_of_stream(const MSPID *id, const AM_MEDIA_TYPE *mt)
5981 IAMMultiMediaStream *mmstream = create_ammultimediastream();
5982 struct testfilter source;
5983 IGraphBuilder *graph;
5984 IMediaStream *stream;
5985 HRESULT hr;
5986 ULONG ref;
5987 IPin *pin;
5989 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
5990 ok(hr == S_OK, "Got hr %#x.\n", hr);
5991 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, id, 0, &stream);
5992 ok(hr == S_OK, "Got hr %#x.\n", hr);
5993 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
5994 ok(hr == S_OK, "Got hr %#x.\n", hr);
5995 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
5996 ok(hr == S_OK, "Got hr %#x.\n", hr);
5997 ok(!!graph, "Expected non-NULL graph.\n");
5998 testfilter_init(&source);
5999 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
6000 ok(hr == S_OK, "Got hr %#x.\n", hr);
6002 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, mt);
6003 ok(hr == S_OK, "Got hr %#x.\n", hr);
6005 hr = IPin_EndOfStream(pin);
6006 ok(hr == S_OK, "Got hr %#x.\n", hr);
6008 hr = IPin_EndOfStream(pin);
6009 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
6011 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
6012 ok(hr == S_OK, "Got hr %#x.\n", hr);
6014 hr = IPin_EndOfStream(pin);
6015 ok(hr == S_OK, "Got hr %#x.\n", hr);
6017 hr = IPin_EndOfStream(pin);
6018 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
6020 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
6021 ok(hr == S_OK, "Got hr %#x.\n", hr);
6023 hr = IPin_EndOfStream(pin);
6024 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
6026 IGraphBuilder_Disconnect(graph, pin);
6027 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
6029 ref = IAMMultiMediaStream_Release(mmstream);
6030 ok(!ref, "Got outstanding refcount %d.\n", ref);
6031 ref = IGraphBuilder_Release(graph);
6032 ok(!ref, "Got outstanding refcount %d.\n", ref);
6033 IPin_Release(pin);
6034 ref = IMediaStream_Release(stream);
6035 ok(!ref, "Got outstanding refcount %d.\n", ref);
6038 static void test_ammediastream_end_of_stream(void)
6040 check_ammediastream_end_of_stream(&MSPID_PrimaryAudio, &audio_mt);
6041 check_ammediastream_end_of_stream(&MSPID_PrimaryVideo, &rgb32_mt);
6044 void test_mediastreamfilter_get_state(void)
6046 IAMMultiMediaStream *mmstream = create_ammultimediastream();
6047 IMediaStreamFilter *filter;
6048 FILTER_STATE state;
6049 HRESULT hr;
6050 ULONG ref;
6052 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6053 ok(hr == S_OK, "Got hr %#x.\n", hr);
6054 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6055 ok(hr == S_OK, "Got hr %#x.\n", hr);
6056 ok(!!filter, "Expected non-null filter.\n");
6058 /* Crashes on native. */
6059 if (0)
6061 hr = IMediaStreamFilter_GetState(filter, 0, NULL);
6062 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
6065 state = 0xcc;
6066 hr = IMediaStreamFilter_GetState(filter, 0, &state);
6067 ok(state == State_Stopped, "Got state %#x.\n", state);
6069 ref = IAMMultiMediaStream_Release(mmstream);
6070 ok(!ref, "Got outstanding refcount %d.\n", ref);
6071 ref = IMediaStreamFilter_Release(filter);
6072 ok(!ref, "Got outstanding refcount %d.\n", ref);
6075 void check_mediastreamfilter_state(FILTER_STATE expected_state, HRESULT (*set_state)(IMediaStreamFilter *),
6076 HRESULT (*reset_state)(IMediaStreamFilter *))
6078 IAMMultiMediaStream *mmstream = create_ammultimediastream();
6079 struct teststream teststream, teststream2;
6080 IMediaStreamFilter *filter;
6081 FILTER_STATE state;
6082 HRESULT hr;
6083 ULONG ref;
6085 teststream_init(&teststream);
6086 teststream_init(&teststream2);
6088 teststream2.mspid.Data2 = 1;
6090 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6091 ok(hr == S_OK, "Got hr %#x.\n", hr);
6092 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream, &teststream.mspid, 0, NULL);
6093 ok(hr == S_OK, "Got hr %#x.\n", hr);
6094 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)&teststream2, &teststream2.mspid, 0, NULL);
6095 ok(hr == S_OK, "Got hr %#x.\n", hr);
6096 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6097 ok(hr == S_OK, "Got hr %#x.\n", hr);
6098 ok(filter != NULL, "Expected non-null filter\n");
6100 hr = reset_state(filter);
6101 ok(hr == S_OK, "Got hr %#x.\n", hr);
6103 teststream.state = 0xcc;
6104 teststream2.state = 0xcc;
6105 hr = set_state(filter);
6106 ok(hr == S_OK, "Got hr %#x.\n", hr);
6107 ok(teststream.state == expected_state, "Got state %#x.\n", teststream.state);
6108 ok(teststream2.state == expected_state, "Got state %#x.\n", teststream2.state);
6109 hr = IMediaStreamFilter_GetState(filter, 0, &state);
6110 ok(hr == S_OK, "Got hr %#x.\n", hr);
6111 ok(state == expected_state, "Got state %#x.\n", state);
6113 teststream.state = 0xcc;
6114 teststream2.state = 0xcc;
6115 hr = set_state(filter);
6116 ok(hr == S_OK, "Got hr %#x.\n", hr);
6117 ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state);
6118 ok(teststream2.state == 0xcc, "Got state %#x.\n", teststream2.state);
6120 hr = reset_state(filter);
6121 ok(hr == S_OK, "Got hr %#x.\n", hr);
6123 teststream.set_state_result = E_FAIL;
6124 teststream.state = 0xcc;
6125 teststream2.state = 0xcc;
6126 hr = set_state(filter);
6127 ok(hr == S_OK, "Got hr %#x.\n", hr);
6128 ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state);
6129 ok(teststream2.state == expected_state, "Got state %#x.\n", teststream2.state);
6130 hr = IMediaStreamFilter_GetState(filter, 0, &state);
6131 ok(hr == S_OK, "Got hr %#x.\n", hr);
6132 ok(state == expected_state, "Got state %#x.\n", state);
6134 hr = reset_state(filter);
6135 ok(hr == S_OK, "Got hr %#x.\n", hr);
6137 teststream.set_state_result = E_FAIL;
6138 teststream2.set_state_result = E_FAIL;
6139 teststream.state = 0xcc;
6140 teststream2.state = 0xcc;
6141 hr = set_state(filter);
6142 ok(hr == S_OK, "Got hr %#x.\n", hr);
6143 ok(teststream.state == 0xcc, "Got state %#x.\n", teststream.state);
6144 ok(teststream2.state == 0xcc, "Got state %#x.\n", teststream2.state);
6145 hr = IMediaStreamFilter_GetState(filter, 0, &state);
6146 ok(hr == S_OK, "Got hr %#x.\n", hr);
6147 ok(state == expected_state, "Got state %#x.\n", state);
6149 ref = IAMMultiMediaStream_Release(mmstream);
6150 ok(!ref, "Got outstanding refcount %d.\n", ref);
6151 ref = IMediaStreamFilter_Release(filter);
6152 ok(!ref, "Got outstanding refcount %d.\n", ref);
6153 ok(teststream.refcount == 1, "Got outstanding refcount %d.\n", teststream.refcount);
6154 ok(teststream2.refcount == 1, "Got outstanding refcount %d.\n", teststream2.refcount);
6157 static HRESULT mediastreamfilter_stop(IMediaStreamFilter *filter)
6159 return IMediaStreamFilter_Stop(filter);
6162 static HRESULT mediastreamfilter_pause(IMediaStreamFilter *filter)
6164 return IMediaStreamFilter_Pause(filter);
6167 static HRESULT mediastreamfilter_run(IMediaStreamFilter *filter)
6169 return IMediaStreamFilter_Run(filter, 0);
6172 void test_mediastreamfilter_stop_pause_run(void)
6174 check_mediastreamfilter_state(State_Stopped, mediastreamfilter_stop, mediastreamfilter_run);
6175 check_mediastreamfilter_state(State_Paused, mediastreamfilter_pause, mediastreamfilter_stop);
6176 check_mediastreamfilter_state(State_Running, mediastreamfilter_run, mediastreamfilter_stop);
6179 static void test_mediastreamfilter_support_seeking(void)
6181 IAMMultiMediaStream *mmstream = create_ammultimediastream();
6182 static const MSPID mspid1 = {0x88888888, 1};
6183 static const MSPID mspid2 = {0x88888888, 2};
6184 static const MSPID mspid3 = {0x88888888, 3};
6185 struct testfilter source1, source2, source3;
6186 IAMMediaStream *stream1, *stream2, *stream3;
6187 IMediaStreamFilter *filter;
6188 IPin *pin1, *pin2, *pin3;
6189 ULONG ref, seeking_ref;
6190 IGraphBuilder *graph;
6191 HRESULT hr;
6193 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6194 ok(hr == S_OK, "Got hr %#x.\n", hr);
6195 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream1);
6196 ok(hr == S_OK, "Got hr %#x.\n", hr);
6197 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream2);
6198 ok(hr == S_OK, "Got hr %#x.\n", hr);
6199 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream3);
6200 ok(hr == S_OK, "Got hr %#x.\n", hr);
6201 hr = IAMMediaStream_Initialize(stream1, NULL, 0, &mspid1, STREAMTYPE_READ);
6202 ok(hr == S_OK, "Got hr %#x.\n", hr);
6203 hr = IAMMediaStream_Initialize(stream2, NULL, 0, &mspid2, STREAMTYPE_READ);
6204 ok(hr == S_OK, "Got hr %#x.\n", hr);
6205 hr = IAMMediaStream_Initialize(stream3, NULL, 0, &mspid3, STREAMTYPE_READ);
6206 ok(hr == S_OK, "Got hr %#x.\n", hr);
6207 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream1, &mspid1, 0, NULL);
6208 ok(hr == S_OK, "Got hr %#x.\n", hr);
6209 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream2, &mspid2, 0, NULL);
6210 ok(hr == S_OK, "Got hr %#x.\n", hr);
6211 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream3, &mspid3, 0, NULL);
6212 ok(hr == S_OK, "Got hr %#x.\n", hr);
6213 hr = IAMMediaStream_QueryInterface(stream1, &IID_IPin, (void **)&pin1);
6214 ok(hr == S_OK, "Got hr %#x.\n", hr);
6215 hr = IAMMediaStream_QueryInterface(stream2, &IID_IPin, (void **)&pin2);
6216 ok(hr == S_OK, "Got hr %#x.\n", hr);
6217 hr = IAMMediaStream_QueryInterface(stream3, &IID_IPin, (void **)&pin3);
6218 ok(hr == S_OK, "Got hr %#x.\n", hr);
6219 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6220 ok(hr == S_OK, "Got hr %#x.\n", hr);
6221 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
6222 ok(hr == S_OK, "Got hr %#x.\n", hr);
6223 ok(graph != NULL, "Expected non-NULL graph.\n");
6224 testfilter_init(&source1);
6225 testfilter_init(&source2);
6226 testfilter_init(&source3);
6227 source2.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
6228 source3.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
6229 hr = IGraphBuilder_AddFilter(graph, &source1.filter.IBaseFilter_iface, NULL);
6230 ok(hr == S_OK, "Got hr %#x.\n", hr);
6231 hr = IGraphBuilder_AddFilter(graph, &source2.filter.IBaseFilter_iface, NULL);
6232 ok(hr == S_OK, "Got hr %#x.\n", hr);
6233 hr = IGraphBuilder_AddFilter(graph, &source3.filter.IBaseFilter_iface, NULL);
6234 ok(hr == S_OK, "Got hr %#x.\n", hr);
6236 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6237 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
6239 hr = IGraphBuilder_ConnectDirect(graph, &source1.source.pin.IPin_iface, pin1, &audio_mt);
6240 ok(hr == S_OK, "Got hr %#x.\n", hr);
6242 source2.get_duration_hr = E_FAIL;
6244 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6245 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
6247 hr = IGraphBuilder_ConnectDirect(graph, &source2.source.pin.IPin_iface, pin2, &audio_mt);
6248 ok(hr == S_OK, "Got hr %#x.\n", hr);
6250 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6251 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
6253 hr = IGraphBuilder_ConnectDirect(graph, &source3.source.pin.IPin_iface, pin3, &audio_mt);
6254 ok(hr == S_OK, "Got hr %#x.\n", hr);
6256 check_interface(filter, &IID_IMediaSeeking, FALSE);
6258 seeking_ref = get_refcount(&source3.IMediaSeeking_iface);
6260 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6261 ok(hr == S_OK, "Got hr %#x.\n", hr);
6263 check_interface(filter, &IID_IMediaSeeking, TRUE);
6265 ref = get_refcount(&source3.IMediaSeeking_iface);
6266 ok(ref == seeking_ref, "Expected outstanding refcount %d, got %d.\n", seeking_ref, ref);
6268 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6269 ok(hr == HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED), "Got hr %#x.\n", hr);
6271 IGraphBuilder_Disconnect(graph, pin1);
6272 IGraphBuilder_Disconnect(graph, &source1.source.pin.IPin_iface);
6274 IGraphBuilder_Disconnect(graph, pin2);
6275 IGraphBuilder_Disconnect(graph, &source2.source.pin.IPin_iface);
6277 IGraphBuilder_Disconnect(graph, pin3);
6278 IGraphBuilder_Disconnect(graph, &source3.source.pin.IPin_iface);
6280 ref = IAMMultiMediaStream_Release(mmstream);
6281 ok(!ref, "Got outstanding refcount %d.\n", ref);
6282 ref = IGraphBuilder_Release(graph);
6283 ok(!ref, "Got outstanding refcount %d.\n", ref);
6284 ref = IMediaStreamFilter_Release(filter);
6285 ok(!ref, "Got outstanding refcount %d.\n", ref);
6286 IPin_Release(pin1);
6287 ref = IAMMediaStream_Release(stream1);
6288 ok(!ref, "Got outstanding refcount %d.\n", ref);
6289 IPin_Release(pin2);
6290 ref = IAMMediaStream_Release(stream2);
6291 ok(!ref, "Got outstanding refcount %d.\n", ref);
6292 IPin_Release(pin3);
6293 ref = IAMMediaStream_Release(stream3);
6294 ok(!ref, "Got outstanding refcount %d.\n", ref);
6297 static void check_mediastreamfilter_seeking(void (*check)(IMediaSeeking *seeking, struct testfilter *source1,
6298 struct testfilter *source2, struct testfilter *source3, HRESULT source2_hr, HRESULT expected_hr))
6300 IAMMultiMediaStream *mmstream = create_ammultimediastream();
6301 static const MSPID mspid1 = {0x88888888, 1};
6302 static const MSPID mspid2 = {0x88888888, 2};
6303 static const MSPID mspid3 = {0x88888888, 3};
6304 IMediaStreamFilter *filter;
6305 struct testfilter source1;
6306 struct testfilter source2;
6307 struct testfilter source3;
6308 IAMMediaStream *stream1;
6309 IAMMediaStream *stream2;
6310 IAMMediaStream *stream3;
6311 IMediaSeeking *seeking;
6312 IGraphBuilder *graph;
6313 IPin *pin1;
6314 IPin *pin2;
6315 IPin *pin3;
6316 HRESULT hr;
6317 ULONG ref;
6319 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6320 ok(hr == S_OK, "Got hr %#x.\n", hr);
6321 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream1);
6322 ok(hr == S_OK, "Got hr %#x.\n", hr);
6323 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream2);
6324 ok(hr == S_OK, "Got hr %#x.\n", hr);
6325 hr = CoCreateInstance(&CLSID_AMAudioStream, NULL, CLSCTX_INPROC_SERVER, &IID_IAMMediaStream, (void **)&stream3);
6326 ok(hr == S_OK, "Got hr %#x.\n", hr);
6327 hr = IAMMediaStream_Initialize(stream1, NULL, 0, &mspid1, STREAMTYPE_READ);
6328 ok(hr == S_OK, "Got hr %#x.\n", hr);
6329 hr = IAMMediaStream_Initialize(stream2, NULL, 0, &mspid2, STREAMTYPE_READ);
6330 ok(hr == S_OK, "Got hr %#x.\n", hr);
6331 hr = IAMMediaStream_Initialize(stream3, NULL, 0, &mspid3, STREAMTYPE_READ);
6332 ok(hr == S_OK, "Got hr %#x.\n", hr);
6333 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream1, &mspid1, 0, NULL);
6334 ok(hr == S_OK, "Got hr %#x.\n", hr);
6335 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream2, &mspid2, 0, NULL);
6336 ok(hr == S_OK, "Got hr %#x.\n", hr);
6337 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)stream3, &mspid3, 0, NULL);
6338 ok(hr == S_OK, "Got hr %#x.\n", hr);
6339 hr = IAMMediaStream_QueryInterface(stream1, &IID_IPin, (void **)&pin1);
6340 ok(hr == S_OK, "Got hr %#x.\n", hr);
6341 hr = IAMMediaStream_QueryInterface(stream2, &IID_IPin, (void **)&pin2);
6342 ok(hr == S_OK, "Got hr %#x.\n", hr);
6343 hr = IAMMediaStream_QueryInterface(stream3, &IID_IPin, (void **)&pin3);
6344 ok(hr == S_OK, "Got hr %#x.\n", hr);
6345 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6346 ok(hr == S_OK, "Got hr %#x.\n", hr);
6347 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
6348 ok(hr == S_OK, "Got hr %#x.\n", hr);
6349 ok(graph != NULL, "Expected non-NULL graph.\n");
6350 testfilter_init(&source1);
6351 testfilter_init(&source2);
6352 testfilter_init(&source3);
6353 source1.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
6354 source2.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
6355 source3.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
6356 hr = IGraphBuilder_AddFilter(graph, &source1.filter.IBaseFilter_iface, NULL);
6357 ok(hr == S_OK, "Got hr %#x.\n", hr);
6358 hr = IGraphBuilder_AddFilter(graph, &source2.filter.IBaseFilter_iface, NULL);
6359 ok(hr == S_OK, "Got hr %#x.\n", hr);
6360 hr = IGraphBuilder_AddFilter(graph, &source3.filter.IBaseFilter_iface, NULL);
6361 ok(hr == S_OK, "Got hr %#x.\n", hr);
6363 hr = IGraphBuilder_ConnectDirect(graph, &source2.source.pin.IPin_iface, pin2, &audio_mt);
6364 ok(hr == S_OK, "Got hr %#x.\n", hr);
6365 hr = IGraphBuilder_ConnectDirect(graph, &source3.source.pin.IPin_iface, pin3, &audio_mt);
6366 ok(hr == S_OK, "Got hr %#x.\n", hr);
6368 hr = IMediaStreamFilter_SupportSeeking(filter, TRUE);
6369 ok(hr == S_OK, "Got hr %#x.\n", hr);
6371 hr = IGraphBuilder_ConnectDirect(graph, &source1.source.pin.IPin_iface, pin1, &audio_mt);
6372 ok(hr == S_OK, "Got hr %#x.\n", hr);
6374 hr = IMediaStreamFilter_QueryInterface(filter, &IID_IMediaSeeking, (void **)&seeking);
6375 ok(hr == S_OK, "Got hr %#x.\n", hr);
6377 check(seeking, &source1, &source2, &source3, S_OK, S_OK);
6378 check(seeking, &source1, &source2, &source3, E_FAIL, E_FAIL);
6379 check(seeking, &source1, &source2, &source3, E_NOTIMPL, E_NOTIMPL);
6381 source2.IMediaSeeking_iface.lpVtbl = NULL;
6383 check(seeking, &source1, &source2, &source3, S_OK, E_NOTIMPL);
6385 source2.IMediaSeeking_iface.lpVtbl = &testsource_seeking_vtbl;
6387 IGraphBuilder_Disconnect(graph, pin2);
6388 IGraphBuilder_Disconnect(graph, &source2.source.pin.IPin_iface);
6390 check(seeking, &source1, &source2, &source3, S_OK, E_NOTIMPL);
6392 IGraphBuilder_Disconnect(graph, pin2);
6393 IGraphBuilder_Disconnect(graph, &source2.source.pin.IPin_iface);
6394 IGraphBuilder_Disconnect(graph, pin3);
6395 IGraphBuilder_Disconnect(graph, &source3.source.pin.IPin_iface);
6397 ref = IAMMultiMediaStream_Release(mmstream);
6398 ok(!ref, "Got outstanding refcount %d.\n", ref);
6399 ref = IGraphBuilder_Release(graph);
6400 ok(!ref, "Got outstanding refcount %d.\n", ref);
6401 IMediaSeeking_Release(seeking);
6402 ref = IMediaStreamFilter_Release(filter);
6403 ok(!ref, "Got outstanding refcount %d.\n", ref);
6404 IPin_Release(pin1);
6405 ref = IAMMediaStream_Release(stream1);
6406 ok(!ref, "Got outstanding refcount %d.\n", ref);
6407 IPin_Release(pin2);
6408 ref = IAMMediaStream_Release(stream2);
6409 ok(!ref, "Got outstanding refcount %d.\n", ref);
6410 IPin_Release(pin3);
6411 ref = IAMMediaStream_Release(stream3);
6412 ok(!ref, "Got outstanding refcount %d.\n", ref);
6415 static void check_mediastreamfilter_set_positions(IMediaSeeking *seeking, struct testfilter *source1,
6416 struct testfilter *source2, struct testfilter *source3, HRESULT source2_hr, HRESULT expected_hr)
6418 LONGLONG current_position = 12345678;
6419 LONGLONG stop_position = 87654321;
6420 HRESULT hr;
6422 source2->set_positions_hr = source2_hr;
6423 source1->current_position = 0xdeadbeefdeadbeefULL;
6424 source1->stop_position = 0xdeadbeefdeadbeefULL;
6425 source2->current_position = 0xdeadbeefdeadbeefULL;
6426 source2->stop_position = 0xdeadbeefdeadbeefULL;
6427 source3->current_position = 0xdeadbeefdeadbeefULL;
6428 source3->stop_position = 0xdeadbeefdeadbeefULL;
6429 hr = IMediaSeeking_SetPositions(seeking, &current_position, AM_SEEKING_AbsolutePositioning,
6430 &stop_position, AM_SEEKING_AbsolutePositioning);
6431 ok(hr == expected_hr, "Got hr %#x.\n", hr);
6432 ok(source1->current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
6433 wine_dbgstr_longlong(source1->current_position));
6434 ok(source1->stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
6435 wine_dbgstr_longlong(source1->stop_position));
6436 if (SUCCEEDED(expected_hr))
6438 ok(source2->current_position == 12345678, "Got current position %s.\n",
6439 wine_dbgstr_longlong(source2->current_position));
6440 ok(source2->stop_position == 87654321, "Got stop position %s.\n",
6441 wine_dbgstr_longlong(source2->stop_position));
6443 ok(source3->current_position == 0xdeadbeefdeadbeefULL, "Got current position %s.\n",
6444 wine_dbgstr_longlong(source3->current_position));
6445 ok(source3->stop_position == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n",
6446 wine_dbgstr_longlong(source3->stop_position));
6449 static void check_mediastreamfilter_get_duration(IMediaSeeking *seeking, struct testfilter *source1,
6450 struct testfilter *source2, struct testfilter *source3, HRESULT source2_hr, HRESULT expected_hr)
6452 LONGLONG duration = 0xdeadbeefdeadbeefULL;
6453 HRESULT hr;
6455 source2->get_duration_hr = source2_hr;
6456 hr = IMediaSeeking_GetDuration(seeking, &duration);
6457 ok(hr == expected_hr, "Got hr %#x.\n", hr);
6458 if (SUCCEEDED(expected_hr))
6459 ok(duration == 0x8000000000000000ULL, "Got duration %s.\n", wine_dbgstr_longlong(duration));
6460 else
6461 ok(duration == 0xdeadbeefdeadbeefULL, "Got duration %s.\n", wine_dbgstr_longlong(duration));
6464 static void check_mediastreamfilter_get_stop_position(IMediaSeeking *seeking, struct testfilter *source1,
6465 struct testfilter *source2, struct testfilter *source3, HRESULT source2_hr, HRESULT expected_hr)
6467 LONGLONG stop = 0xdeadbeefdeadbeefULL;
6468 HRESULT hr;
6470 source2->get_stop_position_hr = source2_hr;
6471 hr = IMediaSeeking_GetStopPosition(seeking, &stop);
6472 ok(hr == expected_hr, "Got hr %#x.\n", hr);
6473 if (SUCCEEDED(expected_hr))
6474 ok(stop == 0x8000000000000000ULL, "Got stop position %s.\n", wine_dbgstr_longlong(stop));
6475 else
6476 ok(stop == 0xdeadbeefdeadbeefULL, "Got stop position %s.\n", wine_dbgstr_longlong(stop));
6479 static void check_mediastreamfilter_is_format_supported(IMediaSeeking *seeking, struct testfilter *source1,
6480 struct testfilter *source2, struct testfilter *source3, HRESULT source2_hr, HRESULT expected_hr)
6482 HRESULT hr;
6484 source2->is_format_supported_hr = source2_hr;
6485 hr = IMediaSeeking_IsFormatSupported(seeking, &TIME_FORMAT_MEDIA_TIME);
6486 ok(hr == expected_hr, "Got hr %#x.\n", hr);
6489 static void test_mediastreamfilter_seeking(void)
6491 check_mediastreamfilter_seeking(check_mediastreamfilter_set_positions);
6492 check_mediastreamfilter_seeking(check_mediastreamfilter_get_duration);
6493 check_mediastreamfilter_seeking(check_mediastreamfilter_get_stop_position);
6494 check_mediastreamfilter_seeking(check_mediastreamfilter_is_format_supported);
6497 static void test_mediastreamfilter_get_current_stream_time(void)
6499 IAMMultiMediaStream *mmstream = create_ammultimediastream();
6500 STREAM_TIME filter_start_time;
6501 IMediaStreamFilter *filter;
6502 IMediaFilter *media_filter;
6503 struct testclock clock;
6504 IGraphBuilder *graph;
6505 STREAM_TIME time;
6506 HRESULT hr;
6507 ULONG ref;
6509 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6510 ok(hr == S_OK, "Got hr %#x.\n", hr);
6511 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
6512 ok(hr == S_OK, "Got hr %#x.\n", hr);
6513 ok(!!filter, "Expected non-null filter.\n");
6514 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, NULL);
6515 ok(hr == S_OK, "Got hr %#x.\n", hr);
6516 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
6517 ok(hr == S_OK, "Got hr %#x.\n", hr);
6518 ok(graph != NULL, "Expected non-NULL graph.\n");
6519 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
6520 ok(hr == S_OK, "Got hr %#x.\n", hr);
6521 testclock_init(&clock);
6523 /* Crashes on native. */
6524 if (0)
6526 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, NULL);
6527 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
6528 hr = IAMMultiMediaStream_GetTime(mmstream, NULL);
6529 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
6532 time = 0xdeadbeefdeadbeef;
6533 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &time);
6534 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
6535 ok(time == 0, "Got time %s.\n", wine_dbgstr_longlong(time));
6536 time = 0xdeadbeefdeadbeef;
6537 hr = IAMMultiMediaStream_GetTime(mmstream, &time);
6538 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
6539 ok(time == 0, "Got time %s.\n", wine_dbgstr_longlong(time));
6541 hr = IMediaFilter_SetSyncSource(media_filter, &clock.IReferenceClock_iface);
6542 ok(hr == S_OK, "Got hr %#x.\n", hr);
6544 clock.get_time_hr = E_FAIL;
6546 time = 0xdeadbeefdeadbeef;
6547 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &time);
6548 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
6549 ok(time == 0, "Got time %s.\n", wine_dbgstr_longlong(time));
6550 time = 0xdeadbeefdeadbeef;
6551 hr = IAMMultiMediaStream_GetTime(mmstream, &time);
6552 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
6553 ok(time == 0, "Got time %s.\n", wine_dbgstr_longlong(time));
6555 clock.time = 23456789;
6556 clock.get_time_hr = S_OK;
6558 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
6559 ok(hr == S_OK, "Got hr %#x.\n", hr);
6561 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &filter_start_time);
6562 ok(hr == S_OK, "Got hr %#x.\n", hr);
6564 clock.time = 34567890;
6566 time = 0xdeadbeefdeadbeef;
6567 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &time);
6568 ok(hr == S_OK, "Got hr %#x.\n", hr);
6569 ok(time == 11111101 + filter_start_time, "Got time %s.\n", wine_dbgstr_longlong(time));
6570 time = 0xdeadbeefdeadbeef;
6571 hr = IAMMultiMediaStream_GetTime(mmstream, &time);
6572 ok(hr == S_OK, "Got hr %#x.\n", hr);
6573 ok(time == 11111101 + filter_start_time, "Got time %s.\n", wine_dbgstr_longlong(time));
6575 ref = IAMMultiMediaStream_Release(mmstream);
6576 ok(!ref, "Got outstanding refcount %d.\n", ref);
6577 IMediaFilter_Release(media_filter);
6578 ref = IGraphBuilder_Release(graph);
6579 ok(!ref, "Got outstanding refcount %d.\n", ref);
6580 ref = IMediaStreamFilter_Release(filter);
6581 ok(!ref, "Got outstanding refcount %d.\n", ref);
6584 static void test_mediastreamfilter_reference_time_to_stream_time(void)
6586 IMediaStreamFilter *filter;
6587 struct testclock clock;
6588 REFERENCE_TIME time;
6589 HRESULT hr;
6590 ULONG ref;
6592 hr = CoCreateInstance(&CLSID_MediaStreamFilter, NULL, CLSCTX_INPROC_SERVER,
6593 &IID_IMediaStreamFilter, (void **)&filter);
6594 ok(hr == S_OK, "Got hr %#x.\n", hr);
6595 testclock_init(&clock);
6597 hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, NULL);
6598 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
6600 time = 0xdeadbeefdeadbeef;
6601 hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, &time);
6602 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
6603 ok(time == 0xdeadbeefdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(time));
6605 hr = IMediaStreamFilter_SetSyncSource(filter, &clock.IReferenceClock_iface);
6606 ok(hr == S_OK, "Got hr %#x.\n", hr);
6608 clock.get_time_hr = E_FAIL;
6610 /* Crashes on native. */
6611 if (0)
6613 hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, NULL);
6614 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
6617 time = 0xdeadbeefdeadbeef;
6618 hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, &time);
6619 ok(hr == S_OK, "Got hr %#x.\n", hr);
6620 ok(time == 0xdeadbeefdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(time));
6622 hr = IMediaStreamFilter_Run(filter, 23456789);
6623 ok(hr == S_OK, "Got hr %#x.\n", hr);
6625 time = 0xdeadbeefdeadbeef;
6626 hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, &time);
6627 ok(hr == S_OK, "Got hr %#x.\n", hr);
6628 ok(time == 0xdeadbeefdd47d2da, "Got time %s.\n", wine_dbgstr_longlong(time));
6630 clock.time = 34567890;
6631 clock.get_time_hr = S_OK;
6633 time = 0xdeadbeefdeadbeef;
6634 hr = IMediaStreamFilter_ReferenceTimeToStreamTime(filter, &time);
6635 ok(hr == S_OK, "Got hr %#x.\n", hr);
6636 ok(time == 0xdeadbeefdd47d2da, "Got time %s.\n", wine_dbgstr_longlong(time));
6638 ref = IMediaStreamFilter_Release(filter);
6639 ok(!ref, "Got outstanding refcount %d.\n", ref);
6642 struct mediastreamfilter_wait_until_params
6644 IMediaStreamFilter *filter;
6645 REFERENCE_TIME time;
6646 HRESULT expected_hr;
6649 static DWORD CALLBACK mediastreamfilter_wait_until(void *p)
6651 struct mediastreamfilter_wait_until_params *params = (struct mediastreamfilter_wait_until_params *)p;
6652 HRESULT hr;
6654 hr = IMediaStreamFilter_WaitUntil(params->filter, params->time);
6655 ok(hr == params->expected_hr, "Got hr %#x.\n", hr);
6657 return 0;
6660 static void test_mediastreamfilter_wait_until(void)
6662 struct mediastreamfilter_wait_until_params params1;
6663 struct mediastreamfilter_wait_until_params params2;
6664 struct advise_time_cookie cookie1 = { 0 };
6665 struct advise_time_cookie cookie2 = { 0 };
6666 IMediaStreamFilter *filter;
6667 struct testclock clock;
6668 HANDLE thread1;
6669 HANDLE thread2;
6670 HRESULT hr;
6671 ULONG ref;
6673 hr = CoCreateInstance(&CLSID_MediaStreamFilter, NULL, CLSCTX_INPROC_SERVER,
6674 &IID_IMediaStreamFilter, (void **)&filter);
6675 ok(hr == S_OK, "Got hr %#x.\n", hr);
6676 testclock_init(&clock);
6677 cookie1.advise_time_called_event = CreateEventW(NULL, FALSE, FALSE, NULL);
6678 cookie2.advise_time_called_event = CreateEventW(NULL, FALSE, FALSE, NULL);
6680 hr = IMediaStreamFilter_Run(filter, 12345678);
6681 ok(hr == S_OK, "Got hr %#x.\n", hr);
6683 hr = IMediaStreamFilter_WaitUntil(filter, 23456789);
6684 ok(hr == E_FAIL, "Got hr %#x.\n", hr);
6686 hr = IMediaStreamFilter_Stop(filter);
6687 ok(hr == S_OK, "Got hr %#x.\n", hr);
6689 hr = IMediaStreamFilter_SetSyncSource(filter, &clock.IReferenceClock_iface);
6690 ok(hr == S_OK, "Got hr %#x.\n", hr);
6692 clock.advise_time_cookie = &cookie1;
6694 params1.filter = filter;
6695 params1.time = 23456789;
6696 params1.expected_hr = S_OK;
6697 thread1 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params1, 0, NULL);
6698 ok(!WaitForSingleObject(cookie1.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
6699 ok(WaitForSingleObject(thread1, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
6701 ok(cookie1.base == 23456789, "Got base %s.\n", wine_dbgstr_longlong(cookie1.base));
6702 ok(cookie1.offset == 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie1.offset));
6703 ok(!!cookie1.event, "Expected non-NULL event.\n");
6705 SetEvent(cookie1.event);
6707 ok(!WaitForSingleObject(thread1, 2000), "Wait timed out.\n");
6708 CloseHandle(thread1);
6710 ok(!cookie1.unadvise_called, "Unexpected Unadvise call.\n");
6712 hr = IMediaStreamFilter_Run(filter, 12345678);
6713 ok(hr == S_OK, "Got hr %#x.\n", hr);
6715 clock.time = 30000000;
6717 clock.advise_time_cookie = &cookie1;
6719 params1.filter = filter;
6720 params1.time = 23456789;
6721 params1.expected_hr = S_OK;
6722 thread1 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params1, 0, NULL);
6723 ok(!WaitForSingleObject(cookie1.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
6724 ok(WaitForSingleObject(thread1, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
6726 ok(cookie1.base == 23456789, "Got base %s.\n", wine_dbgstr_longlong(cookie1.base));
6727 ok(cookie1.offset == 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie1.offset));
6728 ok(!!cookie1.event, "Expected non-NULL event.\n");
6730 clock.advise_time_cookie = &cookie2;
6732 params2.filter = filter;
6733 params2.time = 11111111;
6734 params2.expected_hr = S_OK;
6735 thread2 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params2, 0, NULL);
6736 ok(!WaitForSingleObject(cookie2.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
6737 ok(WaitForSingleObject(thread2, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
6739 ok(cookie2.base == 11111111, "Got base %s.\n", wine_dbgstr_longlong(cookie2.base));
6740 ok(cookie2.offset == 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie2.offset));
6741 ok(!!cookie2.event, "Expected non-NULL event.\n");
6743 SetEvent(cookie1.event);
6745 ok(!WaitForSingleObject(thread1, 2000), "Wait timed out.\n");
6746 CloseHandle(thread1);
6748 ok(WaitForSingleObject(thread2, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
6750 SetEvent(cookie2.event);
6752 ok(!WaitForSingleObject(thread2, 2000), "Wait timed out.\n");
6753 CloseHandle(thread2);
6755 clock.advise_time_cookie = &cookie1;
6757 params1.filter = filter;
6758 params1.time = 23456789;
6759 params1.expected_hr = S_FALSE;
6760 thread1 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params1, 0, NULL);
6761 ok(!WaitForSingleObject(cookie1.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
6762 ok(WaitForSingleObject(thread1, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
6764 clock.advise_time_cookie = &cookie2;
6766 params2.filter = filter;
6767 params2.time = 23456789;
6768 params2.expected_hr = S_FALSE;
6769 thread2 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params2, 0, NULL);
6770 ok(!WaitForSingleObject(cookie2.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
6771 ok(WaitForSingleObject(thread2, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
6773 hr = IMediaStreamFilter_Flush(filter, FALSE);
6774 ok(hr == S_OK, "Got hr %#x.\n", hr);
6776 ok(cookie1.unadvise_called, "Expected Unadvise to be called.\n");
6777 ok(cookie2.unadvise_called, "Expected Unadvise to be called.\n");
6779 ok(!WaitForSingleObject(thread1, 2000), "Wait timed out.\n");
6780 CloseHandle(thread1);
6781 ok(!WaitForSingleObject(thread2, 2000), "Wait timed out.\n");
6782 CloseHandle(thread2);
6784 clock.advise_time_cookie = &cookie1;
6786 params1.filter = filter;
6787 params1.time = 23456789;
6788 params1.expected_hr = S_FALSE;
6789 thread1 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params1, 0, NULL);
6790 ok(!WaitForSingleObject(cookie1.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
6791 ok(WaitForSingleObject(thread1, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
6793 clock.advise_time_cookie = &cookie2;
6795 params2.filter = filter;
6796 params2.time = 23456789;
6797 params2.expected_hr = S_FALSE;
6798 thread2 = CreateThread(NULL, 0, mediastreamfilter_wait_until, &params2, 0, NULL);
6799 ok(!WaitForSingleObject(cookie2.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
6800 ok(WaitForSingleObject(thread2, 100) == WAIT_TIMEOUT, "WaitUntil returned prematurely.\n");
6802 hr = IMediaStreamFilter_Stop(filter);
6803 ok(hr == S_OK, "Got hr %#x.\n", hr);
6805 ok(cookie1.unadvise_called, "Expected Unadvise to be called.\n");
6806 ok(cookie2.unadvise_called, "Expected Unadvise to be called.\n");
6808 ok(!WaitForSingleObject(thread1, 2000), "Wait timed out.\n");
6809 CloseHandle(thread1);
6810 ok(!WaitForSingleObject(thread2, 2000), "Wait timed out.\n");
6811 CloseHandle(thread2);
6813 CloseHandle(cookie1.advise_time_called_event);
6814 CloseHandle(cookie2.advise_time_called_event);
6816 ref = IMediaStreamFilter_Release(filter);
6817 ok(!ref, "Got outstanding refcount %d.\n", ref);
6820 static void test_ddrawstream_getsetdirectdraw(void)
6822 IAMMultiMediaStream *mmstream = create_ammultimediastream();
6823 IDirectDraw *ddraw, *ddraw2, *ddraw3, *ddraw4;
6824 IDirectDrawMediaStream *ddraw_stream;
6825 IDirectDrawStreamSample *sample;
6826 IDirectDraw7 *ddraw7;
6827 IMediaStream *stream;
6828 HRESULT hr;
6829 ULONG ref;
6831 hr = DirectDrawCreate(NULL, &ddraw, NULL);
6832 ok(hr == S_OK, "Got hr %#x.\n", hr);
6833 hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw7, (void **)&ddraw7);
6834 ok(hr == DD_OK, "Got hr %#x.\n", hr);
6835 hr = IDirectDraw7_SetCooperativeLevel(ddraw7, GetDesktopWindow(), DDSCL_NORMAL);
6836 ok(hr == DD_OK, "Got hr %#x.\n", hr);
6837 EXPECT_REF(ddraw, 1);
6838 EXPECT_REF(ddraw7, 1);
6840 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6841 ok(hr == S_OK, "Got hr %#x.\n", hr);
6843 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)ddraw7, &MSPID_PrimaryVideo, 0, &stream);
6844 ok(hr == S_OK, "Got hr %#x.\n", hr);
6845 EXPECT_REF(ddraw, 2);
6847 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
6848 ok(hr == S_OK, "Got hr %#x.\n", hr);
6850 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, NULL);
6851 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
6853 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw2);
6854 ok(hr == S_OK, "Got hr %#x.\n", hr);
6855 ok(ddraw2 == ddraw, "Expected ddraw %p, got %p.\n", ddraw, ddraw2);
6856 EXPECT_REF(ddraw, 3);
6858 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
6859 ok(hr == S_OK, "Got hr %#x.\n", hr);
6860 ok(ddraw3 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw3);
6861 EXPECT_REF(ddraw, 4);
6862 IDirectDraw_Release(ddraw3);
6863 EXPECT_REF(ddraw, 3);
6865 /* The current ddraw is released when SetDirectDraw() is called. */
6866 hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL);
6867 ok(hr == S_OK, "Got hr %#x.\n", hr);
6868 EXPECT_REF(ddraw, 2);
6870 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
6871 ok(hr == S_OK, "Got hr %#x.\n", hr);
6872 ok(ddraw3 == NULL, "Expected NULL, got %p.\n", ddraw3);
6874 hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw2);
6875 ok(hr == S_OK, "Got hr %#x.\n", hr);
6876 EXPECT_REF(ddraw, 3);
6878 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
6879 ok(hr == S_OK, "Got hr %#x.\n", hr);
6880 ok(ddraw3 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw3);
6881 EXPECT_REF(ddraw, 4);
6882 IDirectDraw_Release(ddraw3);
6883 EXPECT_REF(ddraw, 3);
6885 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
6886 ok(hr == S_OK, "Got hr %#x.\n", hr);
6888 /* SetDirectDraw() doesn't take an extra reference to the ddraw object
6889 * if there are samples extant. */
6890 hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw2);
6891 ok(hr == S_OK, "Got hr %#x.\n", hr);
6892 EXPECT_REF(ddraw, 3);
6894 hr = DirectDrawCreate(NULL, &ddraw3, NULL);
6895 ok(hr == S_OK, "Got hr %#x.\n", hr);
6896 hr = IDirectDraw_SetCooperativeLevel(ddraw3, GetDesktopWindow(), DDSCL_NORMAL);
6897 ok(hr == DD_OK, "Got hr %#x.\n", hr);
6898 EXPECT_REF(ddraw3, 1);
6900 hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3);
6901 ok(hr == MS_E_SAMPLEALLOC, "Got hr %#x.\n", hr);
6903 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4);
6904 ok(hr == S_OK, "Got hr %#x.\n", hr);
6905 ok(ddraw4 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw4);
6906 EXPECT_REF(ddraw, 4);
6907 IDirectDraw_Release(ddraw4);
6908 EXPECT_REF(ddraw, 3);
6910 ref = IDirectDrawStreamSample_Release(sample);
6911 ok(!ref, "Got outstanding refcount %d.\n", ref);
6913 hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3);
6914 ok(hr == S_OK, "Got hr %#x.\n", hr);
6915 EXPECT_REF(ddraw, 2);
6916 EXPECT_REF(ddraw3, 2);
6918 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4);
6919 ok(hr == S_OK, "Got hr %#x.\n", hr);
6920 ok(ddraw4 == ddraw3, "Expected ddraw %p, got %p.\n", ddraw3, ddraw4);
6921 EXPECT_REF(ddraw3, 3);
6922 IDirectDraw_Release(ddraw4);
6923 EXPECT_REF(ddraw3, 2);
6925 hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL);
6926 ok(hr == S_OK, "Got hr %#x.\n", hr);
6927 EXPECT_REF(ddraw3, 1);
6929 ref = IDirectDraw_Release(ddraw3);
6930 ok(!ref, "Got outstanding refcount %d.\n", ref);
6932 EXPECT_REF(stream, 3);
6933 IDirectDrawMediaStream_Release(ddraw_stream);
6934 EXPECT_REF(stream, 2);
6935 ref = IAMMultiMediaStream_Release(mmstream);
6936 ok(!ref, "Got outstanding refcount %d.\n", ref);
6937 EXPECT_REF(stream, 1);
6938 ref = IMediaStream_Release(stream);
6939 ok(!ref, "Got outstanding refcount %d.\n", ref);
6940 ref = IDirectDraw7_Release(ddraw7);
6941 ok(!ref, "Got outstanding refcount %d.\n", ref);
6942 IDirectDraw_Release(ddraw2);
6943 EXPECT_REF(ddraw, 1);
6944 ref = IDirectDraw_Release(ddraw);
6945 ok(!ref, "Got outstanding refcount %d.\n", ref);
6948 static void test_audiostreamsample_get_media_stream(void)
6950 IAMMultiMediaStream *mmstream = create_ammultimediastream();
6951 IAudioStreamSample *audio_sample;
6952 IAudioMediaStream *audio_stream;
6953 IMediaStream *stream, *stream2;
6954 IAudioData *audio_data;
6955 HRESULT hr;
6956 ULONG ref;
6958 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
6959 ok(hr == S_OK, "Got hr %#x.\n", hr);
6961 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
6962 ok(hr == S_OK, "Got hr %#x.\n", hr);
6964 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
6965 ok(hr == S_OK, "Got hr %#x.\n", hr);
6967 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
6968 ok(hr == S_OK, "Got hr %#x.\n", hr);
6970 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &audio_sample);
6971 ok(hr == S_OK, "Got hr %#x.\n", hr);
6973 /* Crashes on native. */
6974 if (0)
6976 hr = IAudioStreamSample_GetMediaStream(audio_sample, NULL);
6977 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
6980 EXPECT_REF(stream, 4);
6981 hr = IAudioStreamSample_GetMediaStream(audio_sample, &stream2);
6982 ok(hr == S_OK, "Got hr %#x.\n", hr);
6983 ok(stream2 == stream, "Expected stream %p, got %p.\n", stream, stream2);
6984 EXPECT_REF(stream, 5);
6986 IMediaStream_Release(stream2);
6988 IAudioMediaStream_Release(audio_stream);
6989 ref = IAudioStreamSample_Release(audio_sample);
6990 ok(!ref, "Got outstanding refcount %d.\n", ref);
6991 ref = IAudioData_Release(audio_data);
6992 ok(!ref, "Got outstanding refcount %d.\n", ref);
6993 ref = IAMMultiMediaStream_Release(mmstream);
6994 ok(!ref, "Got outstanding refcount %d.\n", ref);
6995 ref = IMediaStream_Release(stream);
6996 ok(!ref, "Got outstanding refcount %d.\n", ref);
6999 static void test_audiostreamsample_get_audio_data(void)
7001 IAMMultiMediaStream *mmstream = create_ammultimediastream();
7002 IAudioData *audio_data, *audio_data2;
7003 IAudioStreamSample *audio_sample;
7004 IAudioMediaStream *audio_stream;
7005 IMediaStream *stream;
7006 HRESULT hr;
7007 ULONG ref;
7009 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
7010 ok(hr == S_OK, "Got hr %#x.\n", hr);
7012 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryAudio, 0, &stream);
7013 ok(hr == S_OK, "Got hr %#x.\n", hr);
7015 hr = IMediaStream_QueryInterface(stream, &IID_IAudioMediaStream, (void **)&audio_stream);
7016 ok(hr == S_OK, "Got hr %#x.\n", hr);
7018 hr = CoCreateInstance(&CLSID_AMAudioData, NULL, CLSCTX_INPROC_SERVER, &IID_IAudioData, (void **)&audio_data);
7019 ok(hr == S_OK, "Got hr %#x.\n", hr);
7021 hr = IAudioMediaStream_CreateSample(audio_stream, audio_data, 0, &audio_sample);
7022 ok(hr == S_OK, "Got hr %#x.\n", hr);
7024 hr = IAudioStreamSample_GetAudioData(audio_sample, NULL);
7025 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
7027 EXPECT_REF(audio_data, 2);
7028 hr = IAudioStreamSample_GetAudioData(audio_sample, &audio_data2);
7029 ok(hr == S_OK, "Got hr %#x.\n", hr);
7030 ok(audio_data2 == audio_data, "Expected audio data %p, got %p.\n", audio_data, audio_data2);
7031 EXPECT_REF(audio_data, 3);
7033 IAudioData_Release(audio_data2);
7035 IAudioMediaStream_Release(audio_stream);
7036 ref = IAudioStreamSample_Release(audio_sample);
7037 ok(!ref, "Got outstanding refcount %d.\n", ref);
7038 ref = IAudioData_Release(audio_data);
7039 ok(!ref, "Got outstanding refcount %d.\n", ref);
7040 ref = IAMMultiMediaStream_Release(mmstream);
7041 ok(!ref, "Got outstanding refcount %d.\n", ref);
7042 ref = IMediaStream_Release(stream);
7043 ok(!ref, "Got outstanding refcount %d.\n", ref);
7046 #define get_ddrawstream_create_sample_desc(a,b,c,d) get_ddrawstream_create_sample_desc_(__LINE__,a,b,c,d)
7047 static void get_ddrawstream_create_sample_desc_(int line, const DDSURFACEDESC *format1,
7048 const DDSURFACEDESC *format2, const AM_MEDIA_TYPE *mt, DDSURFACEDESC *desc)
7050 IAMMultiMediaStream *mmstream = create_ammultimediastream();
7051 IDirectDrawMediaStream *ddraw_stream;
7052 IDirectDrawStreamSample *sample;
7053 IDirectDrawSurface *surface;
7054 struct testfilter source;
7055 IGraphBuilder *graph;
7056 IMediaStream *stream;
7057 HRESULT hr;
7058 ULONG ref;
7059 IPin *pin;
7061 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
7062 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7063 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
7064 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7065 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
7066 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7067 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
7068 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7069 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
7070 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7072 testfilter_init(&source);
7074 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
7075 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7077 if (format1)
7079 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, format1, NULL);
7080 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7082 if (format2)
7084 hr = IDirectDrawMediaStream_SetFormat(ddraw_stream, format2, NULL);
7085 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7087 if (mt)
7089 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, mt);
7090 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7092 hr = IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
7093 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7094 hr = IGraphBuilder_Disconnect(graph, pin);
7095 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7098 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
7099 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7101 hr = IDirectDrawStreamSample_GetSurface(sample, &surface, NULL);
7102 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7103 ok_(__FILE__, line)(!!surface, "Expected non-NULL sufrace.\n");
7105 desc->dwSize = sizeof(*desc);
7106 hr = IDirectDrawSurface_GetSurfaceDesc(surface, desc);
7107 ok_(__FILE__, line)(hr == S_OK, "Got hr %#x.\n", hr);
7109 ref = IDirectDrawStreamSample_Release(sample);
7110 ok_(__FILE__, line)(!ref, "Got outstanding refcount %d.\n", ref);
7111 ref = IDirectDrawSurface_Release(surface);
7112 ok_(__FILE__, line)(!ref, "Got outstanding refcount %d.\n", ref);
7113 ref = IAMMultiMediaStream_Release(mmstream);
7114 ok_(__FILE__, line)(!ref, "Got outstanding refcount %d.\n", ref);
7115 ref = IGraphBuilder_Release(graph);
7116 ok_(__FILE__, line)(!ref, "Got outstanding refcount %d.\n", ref);
7117 IPin_Release(pin);
7118 IDirectDrawMediaStream_Release(ddraw_stream);
7119 ref = IMediaStream_Release(stream);
7120 ok_(__FILE__, line)(!ref, "Got outstanding refcount %d.\n", ref);
7123 static void test_ddrawstream_create_sample(void)
7125 IAMMultiMediaStream *mmstream = create_ammultimediastream();
7126 DDSURFACEDESC desc2 = { sizeof(desc2) };
7127 IDirectDrawSurface *surface, *surface2;
7128 DDSURFACEDESC desc = { sizeof(desc) };
7129 IDirectDrawMediaStream *ddraw_stream;
7130 IDirectDrawStreamSample *sample;
7131 DDSURFACEDESC format1;
7132 DDSURFACEDESC format2;
7133 IMediaStream *stream;
7134 IDirectDraw *ddraw;
7135 HRESULT hr;
7136 RECT rect;
7137 ULONG ref;
7139 hr = DirectDrawCreate(NULL, &ddraw, NULL);
7140 ok(hr == S_OK, "Got hr %#x.\n", hr);
7142 hr = IDirectDraw_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
7143 ok(hr == S_OK, "Got hr %#x.\n", hr);
7145 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
7146 ok(hr == S_OK, "Got hr %#x.\n", hr);
7148 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)ddraw, &MSPID_PrimaryVideo, 0, &stream);
7149 ok(hr == S_OK, "Got hr %#x.\n", hr);
7151 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
7152 ok(hr == S_OK, "Got hr %#x.\n", hr);
7154 /* Crashes on native. */
7155 if (0)
7157 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, NULL);
7158 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
7161 SetRectEmpty(&rect);
7162 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, &rect, 0, &sample);
7163 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
7165 EXPECT_REF(mmstream, 1);
7166 EXPECT_REF(stream, 3);
7167 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
7168 ok(hr == S_OK, "Got hr %#x.\n", hr);
7169 EXPECT_REF(mmstream, 2);
7170 EXPECT_REF(stream, 4);
7172 hr = IDirectDrawStreamSample_GetSurface(sample, NULL, NULL);
7173 ok(hr == S_OK, "Got hr %#x.\n", hr);
7175 hr = IDirectDrawStreamSample_GetSurface(sample, NULL, &rect);
7176 ok(hr == S_OK, "Got hr %#x.\n", hr);
7178 hr = IDirectDrawStreamSample_GetSurface(sample, &surface, NULL);
7179 ok(hr == S_OK, "Got hr %#x.\n", hr);
7180 ok(surface != NULL, "Expected non-NULL surface.\n");
7181 IDirectDrawSurface_Release(surface);
7183 surface = NULL;
7184 hr = IDirectDrawStreamSample_GetSurface(sample, &surface, &rect);
7185 ok(hr == S_OK, "Got hr %#x.\n", hr);
7186 ok(surface != NULL, "Expected non-NULL surface.\n");
7188 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
7189 ok(hr == S_OK, "Got hr %#x.\n", hr);
7190 ok(desc.dwWidth == 100, "Expected width 100, got %d.\n", desc.dwWidth);
7191 ok(desc.dwHeight == 100, "Expected height 100, got %d.\n", desc.dwHeight);
7192 ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Expected format flags DDPF_RGB, got %#x.\n", desc.ddpfPixelFormat.dwFlags);
7193 ok(desc.ddpfPixelFormat.u1.dwRGBBitCount, "Expected non-zero RGB bit count.\n");
7194 IDirectDrawSurface_Release(surface);
7195 IDirectDrawStreamSample_Release(sample);
7196 EXPECT_REF(stream, 3);
7198 memset(&desc, 0, sizeof(desc));
7199 desc.dwSize = sizeof(desc);
7200 desc.dwFlags = DDSD_CAPS;
7201 desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
7202 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
7203 ok(hr == S_OK, "Got hr %#x.\n", hr);
7205 EXPECT_REF(surface, 1);
7206 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, NULL, 0, &sample);
7207 ok(hr == S_OK, "Got hr %#x.\n", hr);
7208 EXPECT_REF(surface, 2);
7210 surface2 = NULL;
7211 SetRectEmpty(&rect);
7212 hr = IDirectDrawStreamSample_GetSurface(sample, &surface2, &rect);
7213 ok(hr == S_OK, "Got hr %#x.\n", hr);
7214 ok(surface2 == surface, "Expected surface %p, got %p.\n", surface, surface2);
7215 ok(rect.right > 0 && rect.bottom > 0, "Got rect %d, %d.\n", rect.right, rect.bottom);
7216 EXPECT_REF(surface, 3);
7217 IDirectDrawSurface_Release(surface2);
7218 EXPECT_REF(surface, 2);
7219 IDirectDrawStreamSample_Release(sample);
7220 EXPECT_REF(surface, 1);
7222 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, &rect, 0, &sample);
7223 ok(hr == S_OK, "Got hr %#x.\n", hr);
7225 ref = IDirectDrawStreamSample_Release(sample);
7226 ok(!ref, "Got outstanding refcount %d.\n", ref);
7227 ref = IDirectDrawSurface_Release(surface);
7228 ok(!ref, "Got outstanding refcount %d.\n", ref);
7230 memset(&desc, 0, sizeof(desc));
7231 desc.dwSize = sizeof(desc);
7232 desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
7233 desc.dwWidth = 444;
7234 desc.dwHeight = 400;
7235 desc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
7236 desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
7237 desc.ddpfPixelFormat.u1.dwRGBBitCount = 32;
7238 desc.ddpfPixelFormat.u2.dwRBitMask = 0xff0000;
7239 desc.ddpfPixelFormat.u3.dwGBitMask = 0x00ff00;
7240 desc.ddpfPixelFormat.u4.dwBBitMask = 0x0000ff;
7241 desc.ddpfPixelFormat.u5.dwRGBAlphaBitMask = 0xff000000;
7242 desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
7243 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
7244 ok(hr == S_OK, "Got hr %#x.\n", hr);
7246 SetRect(&rect, 111, 100, 333, 300);
7248 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, &rect, 0, &sample);
7249 ok(hr == S_OK, "Got hr %#x.\n", hr);
7250 ref = IDirectDrawStreamSample_Release(sample);
7251 ok(!ref, "Got outstanding refcount %d.\n", ref);
7253 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
7254 ok(hr == S_OK, "Got hr %#x.\n", hr);
7255 surface2 = NULL;
7256 hr = IDirectDrawStreamSample_GetSurface(sample, &surface2, &rect);
7257 ok(hr == S_OK, "Got hr %#x.\n", hr);
7259 hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc);
7260 ok(hr == S_OK, "Got hr %#x.\n", hr);
7261 hr = IDirectDrawSurface_GetSurfaceDesc(surface2, &desc2);
7262 ok(hr == S_OK, "Got hr %#x.\n", hr);
7263 ok(desc2.dwWidth == 222, "Got width %u.\n", desc2.dwWidth);
7264 ok(desc2.dwHeight == 200, "Got height %u.\n", desc2.dwHeight);
7265 ok(memcmp(&desc2.ddpfPixelFormat, &desc.ddpfPixelFormat, sizeof(DDPIXELFORMAT)) == 0,
7266 "Pixel format didn't match.\n");
7268 ref = IDirectDrawStreamSample_Release(sample);
7269 ok(!ref, "Got outstanding refcount %d.\n", ref);
7270 ref = IDirectDrawSurface_Release(surface);
7271 ok(!ref, "Got outstanding refcount %d.\n", ref);
7272 ref = IDirectDrawSurface_Release(surface2);
7273 ok(!ref, "Got outstanding refcount %d.\n", ref);
7275 memset(&desc, 0, sizeof(desc));
7276 desc.dwSize = sizeof(desc);
7277 desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
7278 desc.dwWidth = 444;
7279 desc.dwHeight = 400;
7280 desc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
7281 desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_PALETTEINDEXED4;
7282 desc.ddpfPixelFormat.u1.dwRGBBitCount = 4;
7283 desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
7284 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
7285 ok(hr == S_OK, "Got hr %#x.\n", hr);
7287 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, NULL, 0, &sample);
7288 ok(hr == DDERR_INVALIDSURFACETYPE, "Got hr %#x.\n", hr);
7290 IDirectDrawMediaStream_Release(ddraw_stream);
7291 ref = IDirectDrawSurface_Release(surface);
7292 ok(!ref, "Got outstanding refcount %d.\n", ref);
7293 ref = IAMMultiMediaStream_Release(mmstream);
7294 ok(!ref, "Got outstanding refcount %d.\n", ref);
7295 ref = IMediaStream_Release(stream);
7296 ok(!ref, "Got outstanding refcount %d.\n", ref);
7297 ref = IDirectDraw_Release(ddraw);
7298 ok(!ref, "Got outstanding refcount %d.\n", ref);
7300 format1 = rgb8_format;
7301 format1.dwFlags = 0;
7302 format1.dwWidth = 333;
7303 format1.dwHeight = 444;
7304 get_ddrawstream_create_sample_desc(&format1, NULL, NULL, &desc);
7305 ok(desc.dwWidth == 100, "Got width %u.\n", desc.dwWidth);
7306 ok(desc.dwHeight == 100, "Got height %u.\n", desc.dwHeight);
7307 ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags);
7308 ok(desc.ddpfPixelFormat.u1.dwRGBBitCount == 32, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.u1.dwRGBBitCount);
7309 ok(desc.ddpfPixelFormat.u2.dwRBitMask == 0xff0000, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.u2.dwRBitMask);
7310 ok(desc.ddpfPixelFormat.u3.dwGBitMask == 0x00ff00, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.u3.dwGBitMask);
7311 ok(desc.ddpfPixelFormat.u4.dwBBitMask == 0x0000ff, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.u4.dwBBitMask);
7313 format1 = rgb8_format;
7314 format1.dwFlags |= DDSD_WIDTH;
7315 format1.dwWidth = 333;
7316 format1.dwHeight = 444;
7317 format2 = rgb8_format;
7318 format2.dwFlags = 0;
7319 get_ddrawstream_create_sample_desc(&format1, &format2, NULL, &desc);
7320 ok(desc.dwWidth == 333, "Got width %u.\n", desc.dwWidth);
7321 ok(desc.dwHeight == 444, "Got height %u.\n", desc.dwHeight);
7323 format1 = rgb8_format;
7324 format1.dwFlags |= DDSD_HEIGHT;
7325 format1.dwWidth = 333;
7326 format1.dwHeight = 444;
7327 format2 = rgb8_format;
7328 format2.dwFlags = 0;
7329 get_ddrawstream_create_sample_desc(&format1, &format2, NULL, &desc);
7330 ok(desc.dwWidth == 333, "Got width %u.\n", desc.dwWidth);
7331 ok(desc.dwHeight == 444, "Got height %u.\n", desc.dwHeight);
7333 get_ddrawstream_create_sample_desc(NULL, NULL, &rgb8_mt, &desc);
7334 ok(desc.dwWidth == 333, "Got width %u.\n", desc.dwWidth);
7335 ok(desc.dwHeight == 444, "Got height %u.\n", desc.dwHeight);
7336 ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags);
7337 ok(desc.ddpfPixelFormat.u1.dwRGBBitCount == 32, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.u1.dwRGBBitCount);
7338 ok(desc.ddpfPixelFormat.u2.dwRBitMask == 0xff0000, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.u2.dwRBitMask);
7339 ok(desc.ddpfPixelFormat.u3.dwGBitMask == 0x00ff00, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.u3.dwGBitMask);
7340 ok(desc.ddpfPixelFormat.u4.dwBBitMask == 0x0000ff, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.u4.dwBBitMask);
7342 get_ddrawstream_create_sample_desc(&rgb565_format, NULL, NULL, &desc);
7343 ok(desc.dwWidth == 100, "Got width %u.\n", desc.dwWidth);
7344 ok(desc.dwHeight == 100, "Got height %u.\n", desc.dwHeight);
7345 ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags);
7346 ok(desc.ddpfPixelFormat.u1.dwRGBBitCount == 16, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.u1.dwRGBBitCount);
7347 ok(desc.ddpfPixelFormat.u2.dwRBitMask == 0xf800, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.u2.dwRBitMask);
7348 ok(desc.ddpfPixelFormat.u3.dwGBitMask == 0x07e0, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.u3.dwGBitMask);
7349 ok(desc.ddpfPixelFormat.u4.dwBBitMask == 0x001f, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.u4.dwBBitMask);
7351 get_ddrawstream_create_sample_desc(&argb32_format, NULL, NULL, &desc);
7352 ok(desc.dwWidth == 100, "Got width %u.\n", desc.dwWidth);
7353 ok(desc.dwHeight == 100, "Got height %u.\n", desc.dwHeight);
7354 ok(desc.ddpfPixelFormat.dwFlags == (DDPF_RGB | DDPF_ALPHAPIXELS), "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags);
7355 ok(desc.ddpfPixelFormat.u1.dwRGBBitCount == 32, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.u1.dwRGBBitCount);
7356 ok(desc.ddpfPixelFormat.u2.dwRBitMask == 0xff0000, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.u2.dwRBitMask);
7357 ok(desc.ddpfPixelFormat.u3.dwGBitMask == 0x00ff00, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.u3.dwGBitMask);
7358 ok(desc.ddpfPixelFormat.u4.dwBBitMask == 0x0000ff, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.u4.dwBBitMask);
7359 ok(desc.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xff000000,
7360 "Got alpha bit mask %#x.\n", desc.ddpfPixelFormat.u4.dwBBitMask);
7362 format1 = rgb32_format;
7363 format1.dwFlags |= DDSD_CAPS;
7364 format1.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
7365 get_ddrawstream_create_sample_desc(&format1, NULL, NULL, &desc);
7366 ok(desc.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN, "Expected set DDSCAPS_OFFSCREENPLAIN.\n");
7367 ok(desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY, "Expected set DDSCAPS_SYSTEMMEMORY.\n");
7368 ok(!(desc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY), "Expected unset DDSCAPS_VIDEOMEMORY.\n");
7369 ok(desc.dwWidth == 100, "Got width %u.\n", desc.dwWidth);
7370 ok(desc.dwHeight == 100, "Got height %u.\n", desc.dwHeight);
7371 ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags);
7372 ok(desc.ddpfPixelFormat.u1.dwRGBBitCount == 32, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.u1.dwRGBBitCount);
7373 ok(desc.ddpfPixelFormat.u2.dwRBitMask == 0xff0000, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.u2.dwRBitMask);
7374 ok(desc.ddpfPixelFormat.u3.dwGBitMask == 0x00ff00, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.u3.dwGBitMask);
7375 ok(desc.ddpfPixelFormat.u4.dwBBitMask == 0x0000ff, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.u4.dwBBitMask);
7377 format1 = rgb32_format;
7378 format1.dwFlags |= DDSD_CKSRCBLT;
7379 format1.ddckCKSrcBlt.dwColorSpaceLowValue = 0xff00ff;
7380 format1.ddckCKSrcBlt.dwColorSpaceHighValue = 0xff00ff;
7381 get_ddrawstream_create_sample_desc(&format1, NULL, NULL, &desc);
7382 ok(!(desc.dwFlags & DDSD_CKSRCBLT), "Expected unset DDSD_CKSRCBLT.\n");
7383 ok(desc.dwWidth == 100, "Got width %u.\n", desc.dwWidth);
7384 ok(desc.dwHeight == 100, "Got height %u.\n", desc.dwHeight);
7385 ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#x.\n", desc.ddpfPixelFormat.dwFlags);
7386 ok(desc.ddpfPixelFormat.u1.dwRGBBitCount == 32, "Got rgb bit count %u.\n", desc.ddpfPixelFormat.u1.dwRGBBitCount);
7387 ok(desc.ddpfPixelFormat.u2.dwRBitMask == 0xff0000, "Got r bit mask %#x.\n", desc.ddpfPixelFormat.u2.dwRBitMask);
7388 ok(desc.ddpfPixelFormat.u3.dwGBitMask == 0x00ff00, "Got g bit mask %#x.\n", desc.ddpfPixelFormat.u3.dwGBitMask);
7389 ok(desc.ddpfPixelFormat.u4.dwBBitMask == 0x0000ff, "Got b bit mask %#x.\n", desc.ddpfPixelFormat.u4.dwBBitMask);
7390 ok(desc.ddckCKSrcBlt.dwColorSpaceLowValue == 0, "Got color key low value %#x.\n",
7391 desc.ddckCKSrcBlt.dwColorSpaceLowValue);
7392 ok(desc.ddckCKSrcBlt.dwColorSpaceHighValue == 0, "Got color key high value %#x.\n",
7393 desc.ddckCKSrcBlt.dwColorSpaceHighValue);
7396 static void test_ddrawstreamsample_get_media_stream(void)
7398 IAMMultiMediaStream *mmstream = create_ammultimediastream();
7399 IDirectDrawMediaStream *ddraw_stream;
7400 IDirectDrawStreamSample *sample;
7401 IMediaStream *stream, *stream2;
7402 IDirectDraw *ddraw;
7403 HRESULT hr;
7404 ULONG ref;
7406 hr = DirectDrawCreate(NULL, &ddraw, NULL);
7407 ok(hr == S_OK, "Got hr %#x.\n", hr);
7409 hr = IDirectDraw_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL);
7410 ok(hr == S_OK, "Got hr %#x.\n", hr);
7412 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
7413 ok(hr == S_OK, "Got hr %#x.\n", hr);
7415 hr = IAMMultiMediaStream_AddMediaStream(mmstream, (IUnknown *)ddraw, &MSPID_PrimaryVideo, 0, &stream);
7416 ok(hr == S_OK, "Got hr %#x.\n", hr);
7418 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
7419 ok(hr == S_OK, "Got hr %#x.\n", hr);
7421 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
7422 ok(hr == S_OK, "Got hr %#x.\n", hr);
7424 /* Crashes on native. */
7425 if (0)
7427 hr = IDirectDrawStreamSample_GetMediaStream(sample, NULL);
7428 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
7431 EXPECT_REF(stream, 4);
7432 hr = IDirectDrawStreamSample_GetMediaStream(sample, &stream2);
7433 ok(hr == S_OK, "Got hr %#x.\n", hr);
7434 ok(stream2 == stream, "Expected stream %p, got %p.\n", stream, stream2);
7435 EXPECT_REF(stream, 5);
7436 IMediaStream_Release(stream2);
7437 EXPECT_REF(stream, 4);
7439 IDirectDrawMediaStream_Release(ddraw_stream);
7440 ref = IDirectDrawStreamSample_Release(sample);
7441 ok(!ref, "Got outstanding refcount %d.\n", ref);
7442 ref = IAMMultiMediaStream_Release(mmstream);
7443 ok(!ref, "Got outstanding refcount %d.\n", ref);
7444 ref = IMediaStream_Release(stream);
7445 ok(!ref, "Got outstanding refcount %d.\n", ref);
7446 ref = IDirectDraw_Release(ddraw);
7447 ok(!ref, "Got outstanding refcount %d.\n", ref);
7450 static void test_ddrawstreamsample_update(void)
7452 static const BYTE initial_data[] =
7454 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
7456 static const BYTE test_data[] =
7458 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
7459 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
7461 IAMMultiMediaStream *mmstream = create_ammultimediastream();
7462 IDirectDrawStreamSample *stream_sample;
7463 struct advise_time_cookie cookie = {0};
7464 IDirectDrawMediaStream *ddraw_stream;
7465 IMediaControl *media_control;
7466 IDirectDrawSurface *surface;
7467 IMemInputPin *mem_input_pin;
7468 IMediaSample *media_sample;
7469 IMediaFilter *media_filter;
7470 REFERENCE_TIME start_time;
7471 REFERENCE_TIME end_time;
7472 struct testfilter source;
7473 struct testclock clock;
7474 IGraphBuilder *graph;
7475 IMediaStream *stream;
7476 VIDEOINFO video_info;
7477 DDSURFACEDESC desc;
7478 IDirectDraw *ddraw;
7479 AM_MEDIA_TYPE mt;
7480 HANDLE thread;
7481 HANDLE event;
7482 HRESULT hr;
7483 ULONG ref;
7484 IPin *pin;
7485 RECT rect;
7486 int i;
7488 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
7489 ok(hr == S_OK, "Got hr %#x.\n", hr);
7490 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
7491 ok(hr == S_OK, "Got hr %#x.\n", hr);
7492 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
7493 ok(hr == S_OK, "Got hr %#x.\n", hr);
7494 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
7495 ok(hr == S_OK, "Got hr %#x.\n", hr);
7496 hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
7497 ok(hr == S_OK, "Got hr %#x.\n", hr);
7498 hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw);
7499 ok(hr == S_OK, "Got hr %#x.\n", hr);
7500 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
7501 ok(hr == S_OK, "Got hr %#x.\n", hr);
7502 ok(graph != NULL, "Expected non-NULL graph.\n");
7503 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **)&media_control);
7504 ok(hr == S_OK, "Got hr %#x.\n", hr);
7505 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
7506 ok(hr == S_OK, "Got hr %#x.\n", hr);
7507 testfilter_init(&source);
7508 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
7509 ok(hr == S_OK, "Got hr %#x.\n", hr);
7510 testclock_init(&clock);
7511 event = CreateEventW(NULL, FALSE, FALSE, NULL);
7512 ok(event != NULL, "Expected non-NULL event.");
7513 cookie.advise_time_called_event = CreateEventW(NULL, FALSE, FALSE, NULL);
7514 ok(cookie.advise_time_called_event != NULL, "Expected non-NULL event.");
7516 hr = IMediaFilter_SetSyncSource(media_filter, NULL);
7517 ok(hr == S_OK, "Got hr %#x.\n", hr);
7519 desc = rgb24_format;
7520 desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
7521 desc.dwWidth = 4;
7522 desc.dwHeight = 5;
7523 desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
7524 hr = IDirectDraw_CreateSurface(ddraw, &desc, &surface, NULL);
7525 ok(hr == S_OK, "Got hr %#x.\n", hr);
7526 /* Make the rect width equal to the surface width, as the native
7527 * implementation incorrectly handles rects that are not full-width
7528 * when the ddraw stream's custom allocator is not used. */
7529 SetRect(&rect, 0, 1, 4, 3);
7530 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, surface, &rect, 0, &stream_sample);
7531 ok(hr == S_OK, "Got hr %#x.\n", hr);
7533 hr = IDirectDrawStreamSample_Update(stream_sample, 0, event, apc_func, 0);
7534 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
7536 hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
7537 ok(hr == MS_E_NOTRUNNING, "Got hr %#x.\n", hr);
7539 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7540 ok(hr == S_OK, "Got hr %#x.\n", hr);
7542 hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
7543 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
7545 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7546 ok(hr == S_OK, "Got hr %#x.\n", hr);
7547 video_info = rgb24_video_info;
7548 video_info.bmiHeader.biWidth = 4;
7549 video_info.bmiHeader.biHeight = -2;
7550 mt = rgb24_mt;
7551 mt.pbFormat = (BYTE *)&video_info;
7552 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
7553 ok(hr == S_OK, "Got hr %#x.\n", hr);
7555 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7556 ok(hr == S_OK, "Got hr %#x.\n", hr);
7558 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7559 ok(hr == S_OK, "Got hr %#x.\n", hr);
7560 for (i = 0; i < 5; ++i)
7561 memcpy((BYTE *)desc.lpSurface + i * desc.u1.lPitch, initial_data, 12);
7562 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7563 ok(hr == S_OK, "Got hr %#x.\n", hr);
7565 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
7567 ammediastream_mem_input_pin = mem_input_pin;
7568 ammediastream_media_sample = media_sample;
7569 ammediastream_sleep_time = 0;
7570 ammediastream_expected_hr = S_OK;
7571 thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
7573 Sleep(100);
7574 hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
7575 ok(hr == S_OK, "Got hr %#x.\n", hr);
7576 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7577 ok(hr == S_OK, "Got hr %#x.\n", hr);
7578 ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7579 ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.u1.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
7580 ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.u1.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
7581 ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7582 ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7583 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7584 ok(hr == S_OK, "Got hr %#x.\n", hr);
7586 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
7587 CloseHandle(thread);
7589 ref = IMediaSample_Release(media_sample);
7590 ok(!ref, "Got outstanding refcount %d.\n", ref);
7592 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7593 ok(hr == S_OK, "Got hr %#x.\n", hr);
7594 IGraphBuilder_Disconnect(graph, pin);
7595 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
7596 video_info = rgb24_video_info;
7597 video_info.bmiHeader.biWidth = 4;
7598 video_info.bmiHeader.biHeight = 2;
7599 mt = rgb24_mt;
7600 mt.pbFormat = (BYTE *)&video_info;
7601 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
7602 ok(hr == S_OK, "Got hr %#x.\n", hr);
7603 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7604 ok(hr == S_OK, "Got hr %#x.\n", hr);
7606 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7607 ok(hr == S_OK, "Got hr %#x.\n", hr);
7608 for (i = 0; i < 5; ++i)
7609 memcpy((BYTE *)desc.lpSurface + i * desc.u1.lPitch, initial_data, 12);
7610 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7611 ok(hr == S_OK, "Got hr %#x.\n", hr);
7613 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
7615 ammediastream_mem_input_pin = mem_input_pin;
7616 ammediastream_media_sample = media_sample;
7617 ammediastream_sleep_time = 0;
7618 ammediastream_expected_hr = S_OK;
7619 thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
7621 Sleep(100);
7622 hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
7623 ok(hr == S_OK, "Got hr %#x.\n", hr);
7624 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7625 ok(hr == S_OK, "Got hr %#x.\n", hr);
7626 ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7627 ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.u1.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
7628 ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.u1.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
7629 ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7630 ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7631 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7632 ok(hr == S_OK, "Got hr %#x.\n", hr);
7634 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
7635 CloseHandle(thread);
7637 ref = IMediaSample_Release(media_sample);
7638 ok(!ref, "Got outstanding refcount %d.\n", ref);
7640 hr = IPin_EndOfStream(pin);
7641 ok(hr == S_OK, "Got hr %#x.\n", hr);
7643 hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
7644 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
7646 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7647 ok(hr == S_OK, "Got hr %#x.\n", hr);
7648 hr = IMediaControl_Pause(media_control);
7649 ok(hr == S_OK, "Got hr %#x.\n", hr);
7651 hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
7652 ok(hr == MS_E_NOTRUNNING, "Got hr %#x.\n", hr);
7654 hr = IMediaControl_Stop(media_control);
7655 ok(hr == S_OK, "Got hr %#x.\n", hr);
7656 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7657 ok(hr == S_OK, "Got hr %#x.\n", hr);
7659 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7660 ok(hr == S_OK, "Got hr %#x.\n", hr);
7661 for (i = 0; i < 5; ++i)
7662 memcpy((BYTE *)desc.lpSurface + i * desc.u1.lPitch, initial_data, 12);
7663 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7664 ok(hr == S_OK, "Got hr %#x.\n", hr);
7666 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
7668 ammediastream_mem_input_pin = mem_input_pin;
7669 ammediastream_media_sample = media_sample;
7670 ammediastream_sleep_time = 100;
7671 ammediastream_expected_hr = S_OK;
7672 thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
7674 hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
7675 ok(hr == S_OK, "Got hr %#x.\n", hr);
7676 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7677 ok(hr == S_OK, "Got hr %#x.\n", hr);
7678 ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7679 ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.u1.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
7680 ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.u1.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
7681 ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7682 ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7683 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7684 ok(hr == S_OK, "Got hr %#x.\n", hr);
7686 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
7687 CloseHandle(thread);
7689 ref = IMediaSample_Release(media_sample);
7690 ok(!ref, "Got outstanding refcount %d.\n", ref);
7692 ammediastream_pin = pin;
7693 ammediastream_sleep_time = 100;
7694 ammediastream_expected_hr = S_OK;
7695 thread = CreateThread(NULL, 0, ammediastream_end_of_stream, NULL, 0, NULL);
7697 hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
7698 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
7700 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
7701 CloseHandle(thread);
7703 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7704 ok(hr == S_OK, "Got hr %#x.\n", hr);
7705 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7706 ok(hr == S_OK, "Got hr %#x.\n", hr);
7708 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7709 ok(hr == S_OK, "Got hr %#x.\n", hr);
7710 for (i = 0; i < 5; ++i)
7711 memcpy((BYTE *)desc.lpSurface + i * desc.u1.lPitch, initial_data, 12);
7712 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7713 ok(hr == S_OK, "Got hr %#x.\n", hr);
7715 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
7717 ammediastream_mem_input_pin = mem_input_pin;
7718 ammediastream_media_sample = media_sample;
7719 ammediastream_sleep_time = 100;
7720 ammediastream_expected_hr = S_OK;
7721 thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
7723 hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_CONTINUOUS, NULL, NULL, 0);
7724 ok(hr == S_OK, "Got hr %#x.\n", hr);
7725 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7726 ok(hr == S_OK, "Got hr %#x.\n", hr);
7727 ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7728 ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.u1.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
7729 ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.u1.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
7730 ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7731 ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7732 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7733 ok(hr == S_OK, "Got hr %#x.\n", hr);
7735 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
7736 CloseHandle(thread);
7738 ref = IMediaSample_Release(media_sample);
7739 ok(!ref, "Got outstanding refcount %d.\n", ref);
7741 hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
7742 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
7744 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7745 ok(hr == S_OK, "Got hr %#x.\n", hr);
7746 for (i = 0; i < 5; ++i)
7747 memcpy((BYTE *)desc.lpSurface + i * desc.u1.lPitch, initial_data, 12);
7748 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7749 ok(hr == S_OK, "Got hr %#x.\n", hr);
7751 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
7752 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
7753 ok(hr == S_OK, "Got hr %#x.\n", hr);
7754 ref = IMediaSample_Release(media_sample);
7755 ok(!ref, "Got outstanding refcount %d.\n", ref);
7757 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7758 ok(hr == S_OK, "Got hr %#x.\n", hr);
7759 ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7760 ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.u1.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
7761 ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.u1.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
7762 ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7763 ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7764 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7765 ok(hr == S_OK, "Got hr %#x.\n", hr);
7767 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7768 ok(hr == S_OK, "Got hr %#x.\n", hr);
7769 for (i = 0; i < 5; ++i)
7770 memcpy((BYTE *)desc.lpSurface + i * desc.u1.lPitch, initial_data, 12);
7771 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7772 ok(hr == S_OK, "Got hr %#x.\n", hr);
7774 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
7775 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
7776 ok(hr == S_OK, "Got hr %#x.\n", hr);
7777 ref = IMediaSample_Release(media_sample);
7778 ok(!ref, "Got outstanding refcount %d.\n", ref);
7780 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7781 ok(hr == S_OK, "Got hr %#x.\n", hr);
7782 ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7783 ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.u1.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
7784 ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.u1.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
7785 ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7786 ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7787 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7788 ok(hr == S_OK, "Got hr %#x.\n", hr);
7790 hr = IPin_EndOfStream(pin);
7791 ok(hr == S_OK, "Got hr %#x.\n", hr);
7793 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7794 ok(hr == S_OK, "Got hr %#x.\n", hr);
7795 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7796 ok(hr == S_OK, "Got hr %#x.\n", hr);
7798 hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
7799 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
7800 EXPECT_REF(stream_sample, 1);
7802 hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
7803 ok(hr == MS_E_BUSY, "Got hr %#x.\n", hr);
7805 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7806 ok(hr == S_OK, "Got hr %#x.\n", hr);
7807 hr = IMediaFilter_SetSyncSource(media_filter, &clock.IReferenceClock_iface);
7808 ok(hr == S_OK, "Got hr %#x.\n", hr);
7809 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7810 ok(hr == S_OK, "Got hr %#x.\n", hr);
7812 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7813 ok(hr == S_OK, "Got hr %#x.\n", hr);
7814 for (i = 0; i < 5; ++i)
7815 memcpy((BYTE *)desc.lpSurface + i * desc.u1.lPitch, initial_data, 12);
7816 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7817 ok(hr == S_OK, "Got hr %#x.\n", hr);
7819 hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
7820 ok(hr == MS_E_BUSY, "Got hr %#x.\n", hr);
7822 clock.advise_time_cookie = &cookie;
7824 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
7825 start_time = 11111111;
7826 end_time = 11111111;
7827 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
7828 ok(hr == S_OK, "Got hr %#x.\n", hr);
7830 ammediastream_mem_input_pin = mem_input_pin;
7831 ammediastream_media_sample = media_sample;
7832 ammediastream_sleep_time = 0;
7833 ammediastream_expected_hr = S_OK;
7834 thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
7835 ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
7836 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
7838 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7839 ok(hr == S_OK, "Got hr %#x.\n", hr);
7840 for (i = 0; i < 5; ++i)
7841 ok(memcmp((BYTE *)desc.lpSurface + i * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7842 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7843 ok(hr == S_OK, "Got hr %#x.\n", hr);
7845 SetEvent(cookie.event);
7847 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
7848 CloseHandle(thread);
7850 hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
7851 ok(hr == S_OK, "Got hr %#x.\n", hr);
7852 ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7853 ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.u1.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
7854 ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.u1.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
7855 ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7856 ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.u1.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
7857 hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
7858 ok(hr == S_OK, "Got hr %#x.\n", hr);
7860 ref = IMediaSample_Release(media_sample);
7861 ok(!ref, "Got outstanding refcount %d.\n", ref);
7863 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7864 ok(hr == S_OK, "Got hr %#x.\n", hr);
7865 IGraphBuilder_Disconnect(graph, pin);
7866 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
7867 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7868 ok(hr == S_OK, "Got hr %#x.\n", hr);
7870 hr = IDirectDrawStreamSample_Update(stream_sample, 0, NULL, NULL, 0);
7871 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
7873 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
7874 ok(hr == S_OK, "Got hr %#x.\n", hr);
7876 CloseHandle(cookie.advise_time_called_event);
7877 CloseHandle(event);
7878 ref = IDirectDrawStreamSample_Release(stream_sample);
7879 ok(!ref, "Got outstanding refcount %d.\n", ref);
7880 ref = IDirectDrawSurface_Release(surface);
7881 ok(!ref, "Got outstanding refcount %d.\n", ref);
7882 ref = IAMMultiMediaStream_Release(mmstream);
7883 ok(!ref, "Got outstanding refcount %d.\n", ref);
7884 IMediaControl_Release(media_control);
7885 IMediaFilter_Release(media_filter);
7886 ref = IGraphBuilder_Release(graph);
7887 ok(!ref, "Got outstanding refcount %d.\n", ref);
7888 IPin_Release(pin);
7889 IMemInputPin_Release(mem_input_pin);
7890 IDirectDrawMediaStream_Release(ddraw_stream);
7891 ref = IMediaStream_Release(stream);
7892 ok(!ref, "Got outstanding refcount %d.\n", ref);
7893 ref = IDirectDraw_Release(ddraw);
7894 ok(!ref, "Got outstanding refcount %d.\n", ref);
7897 static void test_ddrawstreamsample_completion_status(void)
7899 static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
7900 IAMMultiMediaStream *mmstream = create_ammultimediastream();
7901 struct advise_time_cookie cookie = { 0 };
7902 IDirectDrawStreamSample *stream_sample1;
7903 IDirectDrawStreamSample *stream_sample2;
7904 IDirectDrawMediaStream *ddraw_stream;
7905 STREAM_TIME filter_start_time;
7906 IMediaStreamFilter *filter;
7907 IMediaSample *media_sample;
7908 IMediaFilter *media_filter;
7909 struct testfilter source;
7910 struct testclock clock;
7911 VIDEOINFO video_info;
7912 IGraphBuilder *graph;
7913 IMediaStream *stream;
7914 AM_MEDIA_TYPE mt;
7915 HANDLE thread;
7916 HRESULT hr;
7917 ULONG ref;
7918 IPin *pin;
7920 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
7921 ok(hr == S_OK, "Got hr %#x.\n", hr);
7922 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
7923 ok(hr == S_OK, "Got hr %#x.\n", hr);
7924 ok(!!filter, "Expected non-null filter.\n");
7925 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
7926 ok(hr == S_OK, "Got hr %#x.\n", hr);
7927 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
7928 ok(hr == S_OK, "Got hr %#x.\n", hr);
7929 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
7930 ok(hr == S_OK, "Got hr %#x.\n", hr);
7931 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
7932 ok(hr == S_OK, "Got hr %#x.\n", hr);
7933 ok(graph != NULL, "Expected non-NULL graph.\n");
7934 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&media_filter);
7935 ok(hr == S_OK, "Got hr %#x.\n", hr);
7936 testfilter_init(&source);
7937 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
7938 ok(hr == S_OK, "Got hr %#x.\n", hr);
7939 testclock_init(&clock);
7940 cookie.advise_time_called_event = CreateEventW(NULL, FALSE, FALSE, NULL);
7942 hr = IMediaFilter_SetSyncSource(media_filter, NULL);
7943 ok(hr == S_OK, "Got hr %#x.\n", hr);
7945 video_info = rgb32_video_info;
7946 video_info.bmiHeader.biWidth = 3;
7947 video_info.bmiHeader.biHeight = 1;
7948 mt = rgb32_mt;
7949 mt.pbFormat = (BYTE *)&video_info;
7950 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
7951 ok(hr == S_OK, "Got hr %#x.\n", hr);
7952 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
7953 ok(hr == S_OK, "Got hr %#x.\n", hr);
7955 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample1);
7956 ok(hr == S_OK, "Got hr %#x.\n", hr);
7957 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample2);
7958 ok(hr == S_OK, "Got hr %#x.\n", hr);
7960 /* Initial status is S_OK. */
7961 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
7962 ok(hr == S_OK, "Got hr %#x.\n", hr);
7964 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
7965 ok(hr == S_OK, "Got hr %#x.\n", hr);
7967 /* Update changes the status to MS_S_PENDING. */
7968 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
7969 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
7971 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
7972 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
7974 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, 100);
7975 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
7977 /* Each Receive call changes the status of one queued sample to S_OK in the same order Update was called. */
7978 hr = IDirectDrawStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
7979 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
7981 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
7982 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
7984 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
7985 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
7986 ok(hr == S_OK, "Got hr %#x.\n", hr);
7987 ref = IMediaSample_Release(media_sample);
7988 ok(!ref, "Got outstanding refcount %d.\n", ref);
7990 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
7991 ok(hr == S_OK, "Got hr %#x.\n", hr);
7993 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
7994 ok(hr == S_OK, "Got hr %#x.\n", hr);
7996 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
7997 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
7999 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
8000 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
8001 ok(hr == S_OK, "Got hr %#x.\n", hr);
8002 ref = IMediaSample_Release(media_sample);
8003 ok(!ref, "Got outstanding refcount %d.\n", ref);
8005 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
8006 ok(hr == S_OK, "Got hr %#x.\n", hr);
8008 /* COMPSTAT_NOUPDATEOK removes the sample from the queue and changes the status to MS_S_NOUPDATE. */
8009 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8010 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8012 hr = IDirectDrawStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
8013 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8015 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
8016 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8018 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
8019 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8021 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
8022 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
8023 ok(hr == S_OK, "Got hr %#x.\n", hr);
8024 ref = IMediaSample_Release(media_sample);
8025 ok(!ref, "Got outstanding refcount %d.\n", ref);
8027 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8028 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8030 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
8031 ok(hr == S_OK, "Got hr %#x.\n", hr);
8033 /* COMPSTAT_ABORT removes the sample from the queue and changes the status to MS_S_NOUPDATE. */
8034 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8035 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8037 hr = IDirectDrawStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
8038 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8040 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT, 0);
8041 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8043 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
8044 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8046 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
8047 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
8048 ok(hr == S_OK, "Got hr %#x.\n", hr);
8049 ref = IMediaSample_Release(media_sample);
8050 ok(!ref, "Got outstanding refcount %d.\n", ref);
8052 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8053 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8055 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
8056 ok(hr == S_OK, "Got hr %#x.\n", hr);
8058 /* COMPSTAT_WAIT has no effect when combined with COMPSTAT_NOUPDATEOK. */
8059 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8060 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8062 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK | COMPSTAT_WAIT, INFINITE);
8063 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8065 /* COMPSTAT_WAIT has no effect when combined with COMPSTAT_ABORT. */
8066 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8067 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8069 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT | COMPSTAT_WAIT, INFINITE);
8070 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8072 /* EndOfStream changes the status of the queued samples to MS_S_ENDOFSTREAM. */
8073 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8074 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8076 hr = IPin_EndOfStream(pin);
8077 ok(hr == S_OK, "Got hr %#x.\n", hr);
8079 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8080 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
8082 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
8083 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
8085 /* Update after EndOfStream changes the status to MS_S_ENDOFSTREAM. */
8086 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8087 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
8089 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8090 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
8092 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
8093 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
8095 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8096 ok(hr == S_OK, "Got hr %#x.\n", hr);
8097 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8098 ok(hr == S_OK, "Got hr %#x.\n", hr);
8100 /* Continuous update can be canceled by COMPSTAT_NOUPDATEOK. */
8101 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
8102 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8104 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
8105 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8107 /* Continuous update can be canceled by COMPSTAT_ABORT. */
8108 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
8109 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8111 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT, 0);
8112 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8114 /* If a sample is in countinuous update mode, when Receive is called it's status remains MS_S_PENDING
8115 * and the sample is moved to the end of the queue. */
8116 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
8117 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8119 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
8120 ok(hr == MS_E_BUSY, "Got hr %#x.\n", hr);
8122 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8123 ok(hr == MS_E_BUSY, "Got hr %#x.\n", hr);
8125 hr = IDirectDrawStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
8126 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8128 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8129 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8131 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
8132 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
8133 ok(hr == S_OK, "Got hr %#x.\n", hr);
8134 ref = IMediaSample_Release(media_sample);
8135 ok(!ref, "Got outstanding refcount %d.\n", ref);
8137 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8138 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8140 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
8141 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8143 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
8144 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
8145 ok(hr == S_OK, "Got hr %#x.\n", hr);
8146 ref = IMediaSample_Release(media_sample);
8147 ok(!ref, "Got outstanding refcount %d.\n", ref);
8149 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8150 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8152 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
8153 ok(hr == S_OK, "Got hr %#x.\n", hr);
8155 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
8156 ok(hr == S_OK, "Got hr %#x.\n", hr);
8158 /* In continuous update mode, flushing does not affect the status. */
8159 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
8160 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8162 hr = IPin_BeginFlush(pin);
8163 ok(hr == S_OK, "Got hr %#x.\n", hr);
8165 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8166 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8168 hr = IPin_EndFlush(pin);
8169 ok(hr == S_OK, "Got hr %#x.\n", hr);
8171 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8172 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8174 /* In continuous update mode, stopping and running the stream does not affect the status. */
8175 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8176 ok(hr == S_OK, "Got hr %#x.\n", hr);
8178 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8179 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8181 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8182 ok(hr == S_OK, "Got hr %#x.\n", hr);
8184 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8185 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8187 /* In continuous update mode, EndOfStream changes the status to MS_S_ENDOFSTREAM. */
8188 hr = IPin_EndOfStream(pin);
8189 ok(hr == S_OK, "Got hr %#x.\n", hr);
8191 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8192 ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
8194 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8195 ok(hr == S_OK, "Got hr %#x.\n", hr);
8196 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8197 ok(hr == S_OK, "Got hr %#x.\n", hr);
8199 /* COMPSTAT_WAIT resets the sample to the non-continuous update mode. */
8200 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
8201 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8203 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, 0);
8204 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8206 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
8207 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
8208 ok(hr == S_OK, "Got hr %#x.\n", hr);
8209 ref = IMediaSample_Release(media_sample);
8210 ok(!ref, "Got outstanding refcount %d.\n", ref);
8212 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8213 ok(hr == S_OK, "Got hr %#x.\n", hr);
8215 /* In continuous update mode, CompletionStatus with COMPSTAT_WAIT returns when Receive is called. */
8216 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
8217 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8219 streamsample_sample = (IStreamSample *)stream_sample1;
8220 streamsample_flags = COMPSTAT_WAIT;
8221 streamsample_timeout = INFINITE;
8222 streamsample_expected_hr = S_OK;
8223 thread = CreateThread(NULL, 0, streamsample_completion_status, NULL, 0, NULL);
8224 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "CompletionStatus returned prematurely.\n");
8226 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
8227 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
8228 ok(hr == S_OK, "Got hr %#x.\n", hr);
8229 ref = IMediaSample_Release(media_sample);
8230 ok(!ref, "Got outstanding refcount %d.\n", ref);
8232 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8233 CloseHandle(thread);
8235 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8236 ok(hr == S_OK, "Got hr %#x.\n", hr);
8238 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8239 ok(hr == S_OK, "Got hr %#x.\n", hr);
8240 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8241 ok(hr == S_OK, "Got hr %#x.\n", hr);
8243 /* CompletionStatus with COMPSTAT_WAIT returns when Receive is called. */
8244 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8245 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8247 streamsample_sample = (IStreamSample *)stream_sample1;
8248 streamsample_flags = COMPSTAT_WAIT;
8249 streamsample_timeout = INFINITE;
8250 streamsample_expected_hr = S_OK;
8251 thread = CreateThread(NULL, 0, streamsample_completion_status, NULL, 0, NULL);
8252 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "CompletionStatus returned prematurely.\n");
8254 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
8255 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
8256 ok(hr == S_OK, "Got hr %#x.\n", hr);
8257 ref = IMediaSample_Release(media_sample);
8258 ok(!ref, "Got outstanding refcount %d.\n", ref);
8260 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8261 CloseHandle(thread);
8263 /* CompletionStatus with COMPSTAT_WAIT returns when EndOfStream is called. */
8264 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8265 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8267 streamsample_sample = (IStreamSample *)stream_sample1;
8268 streamsample_flags = COMPSTAT_WAIT;
8269 streamsample_timeout = INFINITE;
8270 streamsample_expected_hr = MS_S_ENDOFSTREAM;
8271 thread = CreateThread(NULL, 0, streamsample_completion_status, NULL, 0, NULL);
8272 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "CompletionStatus returned prematurely.\n");
8274 hr = IPin_EndOfStream(pin);
8275 ok(hr == S_OK, "Got hr %#x.\n", hr);
8277 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8278 CloseHandle(thread);
8280 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8281 ok(hr == S_OK, "Got hr %#x.\n", hr);
8282 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8283 ok(hr == S_OK, "Got hr %#x.\n", hr);
8285 /* Stopping and running the stream does not affect the status and does not remove the sample from the queue. */
8286 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8287 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8289 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8290 ok(hr == S_OK, "Got hr %#x.\n", hr);
8292 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8293 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8295 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8296 ok(hr == S_OK, "Got hr %#x.\n", hr);
8298 media_sample = ammediastream_allocate_sample(&source, test_data, 6);
8299 hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
8300 ok(hr == S_OK, "Got hr %#x.\n", hr);
8301 ref = IMediaSample_Release(media_sample);
8302 ok(!ref, "Got outstanding refcount %d.\n", ref);
8304 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8305 ok(hr == S_OK, "Got hr %#x.\n", hr);
8307 /* When the stream is stopped Update does not change the status. */
8308 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8309 ok(hr == S_OK, "Got hr %#x.\n", hr);
8311 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8312 ok(hr == MS_E_NOTRUNNING, "Got hr %#x.\n", hr);
8314 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8315 ok(hr == S_OK, "Got hr %#x.\n", hr);
8317 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, INFINITE);
8318 ok(hr == S_OK, "Got hr %#x.\n", hr);
8320 /* When the wait time is less than 1ms the sample is updated immediately. */
8321 hr = IMediaFilter_SetSyncSource(media_filter, &clock.IReferenceClock_iface);
8322 ok(hr == S_OK, "Got hr %#x.\n", hr);
8324 clock.time = 12345678;
8326 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8327 ok(hr == S_OK, "Got hr %#x.\n", hr);
8329 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &filter_start_time);
8330 ok(hr == S_OK, "Got hr %#x.\n", hr);
8332 clock.time = 12345678 - filter_start_time + 11111111;
8334 clock.advise_time_cookie = &cookie;
8336 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8337 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8339 thread = ammediastream_async_receive_time(&source,
8340 11111111 + 9999, 11111111 + 9999, test_data, sizeof(test_data));
8341 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8342 CloseHandle(thread);
8344 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, INFINITE);
8345 ok(hr == S_OK, "Got hr %#x.\n", hr);
8347 /* When the wait time is 1ms or greater AdviseTime is called
8348 * with base equal to the sample start time and offset equal to the filter start time. */
8349 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8350 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8352 thread = ammediastream_async_receive_time(&source,
8353 11111111 + 10000, 11111111 + 10000, test_data, sizeof(test_data));
8354 ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
8355 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8357 ok(cookie.base == 11111111 + 10000, "Got base %s.\n", wine_dbgstr_longlong(cookie.base));
8358 ok(cookie.offset == 12345678 - filter_start_time, "Got offset %s.\n", wine_dbgstr_longlong(cookie.offset));
8360 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8361 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8363 clock.time = 12345678 - filter_start_time + 11111111 + 10000;
8364 SetEvent(cookie.event);
8366 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8367 CloseHandle(thread);
8369 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8370 ok(hr == S_OK, "Got hr %#x.\n", hr);
8372 /* NewSegment does not affect the values passed to AdviseTime. */
8373 hr = IPin_NewSegment(pin, 22222222, 33333333, 1.0);
8374 ok(hr == S_OK, "Got hr %#x.\n", hr);
8376 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8377 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8379 thread = ammediastream_async_receive_time(&source,
8380 11111111 + 20000, 11111111 + 20000, test_data, sizeof(test_data));
8381 ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
8382 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8384 ok(cookie.base == 11111111 + 20000, "Got base %s.\n", wine_dbgstr_longlong(cookie.base));
8385 ok(cookie.offset == 12345678 - filter_start_time, "Got offset %s.\n", wine_dbgstr_longlong(cookie.offset));
8387 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
8388 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8390 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8392 clock.time = 12345678 - filter_start_time + 11111111 + 20000;
8393 SetEvent(cookie.event);
8395 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8397 /* COMPSTAT_NOUPDATEOK does not cause Receive to return.
8398 * Receive waits for the next sample to be queued and updates it. */
8399 hr = IDirectDrawStreamSample_Update(stream_sample1, 0, NULL, NULL, 0);
8400 ok(hr == S_OK, "Got hr %#x.\n", hr);
8402 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8403 CloseHandle(thread);
8405 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8406 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8408 thread = ammediastream_async_receive_time(&source,
8409 11111111 + 30000, 11111111 + 30000, test_data, sizeof(test_data));
8410 ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
8411 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8413 ok(cookie.base == 11111111 + 30000, "Got base %s.\n", wine_dbgstr_longlong(cookie.base));
8414 ok(cookie.offset == 12345678 - filter_start_time, "Got offset %s.\n", wine_dbgstr_longlong(cookie.offset));
8416 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK | COMPSTAT_WAIT, INFINITE);
8417 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8419 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8421 clock.time = 12345678 - filter_start_time + 11111111 + 30000;
8422 SetEvent(cookie.event);
8424 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8426 hr = IDirectDrawStreamSample_Update(stream_sample1, 0, NULL, NULL, 0);
8427 ok(hr == S_OK, "Got hr %#x.\n", hr);
8429 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8430 CloseHandle(thread);
8432 /* COMPSTAT_ABORT does not cause Receive to return.
8433 * Receive waits for the next sample to be queued and updates it. */
8434 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8435 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8437 thread = ammediastream_async_receive_time(&source,
8438 11111111 + 40000, 11111111 + 40000, test_data, sizeof(test_data));
8439 ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
8440 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8442 ok(cookie.base == 11111111 + 40000, "Got base %s.\n", wine_dbgstr_longlong(cookie.base));
8443 ok(cookie.offset == 12345678 - filter_start_time, "Got offset %s.\n", wine_dbgstr_longlong(cookie.offset));
8445 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT, 0);
8446 ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
8448 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8450 clock.time = 12345678 - filter_start_time + 11111111 + 40000;
8451 SetEvent(cookie.event);
8453 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8455 hr = IDirectDrawStreamSample_Update(stream_sample1, 0, NULL, NULL, 0);
8456 ok(hr == S_OK, "Got hr %#x.\n", hr);
8458 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8459 CloseHandle(thread);
8461 /* Stopping the stream causes Receive to return and leaves the sample with MS_S_PENDING status. */
8462 hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
8463 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8465 thread = ammediastream_async_receive_time(&source,
8466 11111111 + 50000, 11111111 + 50000, test_data, sizeof(test_data));
8467 ok(!WaitForSingleObject(cookie.advise_time_called_event, 2000), "Expected AdviseTime to be called.\n");
8468 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Receive returned prematurely.\n");
8470 ok(cookie.base == 11111111 + 50000, "Got base %s.\n", wine_dbgstr_longlong(cookie.base));
8471 ok(cookie.offset == 12345678 - filter_start_time, "Got offset %s.\n", wine_dbgstr_longlong(cookie.offset));
8473 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8474 ok(hr == S_OK, "Got hr %#x.\n", hr);
8476 ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
8477 CloseHandle(thread);
8479 hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
8480 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8482 IGraphBuilder_Disconnect(graph, pin);
8483 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
8485 CloseHandle(cookie.advise_time_called_event);
8486 ref = IDirectDrawStreamSample_Release(stream_sample1);
8487 ok(!ref, "Got outstanding refcount %d.\n", ref);
8488 ref = IDirectDrawStreamSample_Release(stream_sample2);
8489 ok(!ref, "Got outstanding refcount %d.\n", ref);
8490 ref = IAMMultiMediaStream_Release(mmstream);
8491 ok(!ref, "Got outstanding refcount %d.\n", ref);
8492 IMediaFilter_Release(media_filter);
8493 ref = IGraphBuilder_Release(graph);
8494 ok(!ref, "Got outstanding refcount %d.\n", ref);
8495 ref = IMediaStreamFilter_Release(filter);
8496 ok(!ref, "Got outstanding refcount %d.\n", ref);
8497 IPin_Release(pin);
8498 IDirectDrawMediaStream_Release(ddraw_stream);
8499 ref = IMediaStream_Release(stream);
8500 ok(!ref, "Got outstanding refcount %d.\n", ref);
8503 static void test_ddrawstreamsample_get_sample_times(void)
8505 static const BYTE test_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
8506 IAMMultiMediaStream *mmstream = create_ammultimediastream();
8507 IDirectDrawStreamSample *stream_sample;
8508 IMediaFilter *graph_media_filter;
8509 IDirectDrawMediaStream *ddraw_stream;
8510 STREAM_TIME filter_start_time;
8511 IMemInputPin *mem_input_pin;
8512 IMediaStreamFilter *filter;
8513 IMediaSample *media_sample;
8514 struct testfilter source;
8515 STREAM_TIME current_time;
8516 struct testclock clock;
8517 STREAM_TIME start_time;
8518 STREAM_TIME end_time;
8519 IGraphBuilder *graph;
8520 IMediaStream *stream;
8521 VIDEOINFO video_info;
8522 AM_MEDIA_TYPE mt;
8523 HRESULT hr;
8524 ULONG ref;
8525 IPin *pin;
8527 hr = IAMMultiMediaStream_Initialize(mmstream, STREAMTYPE_READ, 0, NULL);
8528 ok(hr == S_OK, "Got hr %#x.\n", hr);
8529 hr = IAMMultiMediaStream_GetFilter(mmstream, &filter);
8530 ok(hr == S_OK, "Got hr %#x.\n", hr);
8531 ok(!!filter, "Expected non-null filter.\n");
8532 hr = IAMMultiMediaStream_AddMediaStream(mmstream, NULL, &MSPID_PrimaryVideo, 0, &stream);
8533 ok(hr == S_OK, "Got hr %#x.\n", hr);
8534 hr = IMediaStream_QueryInterface(stream, &IID_IDirectDrawMediaStream, (void **)&ddraw_stream);
8535 ok(hr == S_OK, "Got hr %#x.\n", hr);
8536 hr = IMediaStream_QueryInterface(stream, &IID_IPin, (void **)&pin);
8537 ok(hr == S_OK, "Got hr %#x.\n", hr);
8538 hr = IMediaStream_QueryInterface(stream, &IID_IMemInputPin, (void **)&mem_input_pin);
8539 ok(hr == S_OK, "Got hr %#x.\n", hr);
8540 hr = IAMMultiMediaStream_GetFilterGraph(mmstream, &graph);
8541 ok(hr == S_OK, "Got hr %#x.\n", hr);
8542 ok(graph != NULL, "Expected non-NULL graph.\n");
8543 hr = IGraphBuilder_QueryInterface(graph, &IID_IMediaFilter, (void **)&graph_media_filter);
8544 ok(hr == S_OK, "Got hr %#x.\n", hr);
8545 testfilter_init(&source);
8546 hr = IGraphBuilder_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
8547 ok(hr == S_OK, "Got hr %#x.\n", hr);
8548 testclock_init(&clock);
8550 video_info = rgb32_video_info;
8551 video_info.bmiHeader.biWidth = 3;
8552 video_info.bmiHeader.biHeight = 1;
8553 mt = rgb32_mt;
8554 mt.pbFormat = (BYTE *)&video_info;
8555 hr = IGraphBuilder_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
8556 ok(hr == S_OK, "Got hr %#x.\n", hr);
8558 hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &stream_sample);
8559 ok(hr == S_OK, "Got hr %#x.\n", hr);
8561 clock.time = 12345678;
8563 current_time = 0xdeadbeefdeadbeef;
8564 hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
8565 ok(hr == S_OK, "Got hr %#x.\n", hr);
8566 ok(current_time == 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time));
8568 IMediaFilter_SetSyncSource(graph_media_filter, &clock.IReferenceClock_iface);
8569 ok(hr == S_OK, "Got hr %#x.\n", hr);
8571 current_time = 0xdeadbeefdeadbeef;
8572 hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
8573 ok(hr == S_OK, "Got hr %#x.\n", hr);
8574 ok(current_time == 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time));
8576 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
8577 ok(hr == S_OK, "Got hr %#x.\n", hr);
8579 hr = IMediaStreamFilter_GetCurrentStreamTime(filter, &filter_start_time);
8580 ok(hr == S_OK, "Got hr %#x.\n", hr);
8582 clock.get_time_hr = E_FAIL;
8584 current_time = 0xdeadbeefdeadbeef;
8585 hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
8586 ok(hr == S_OK, "Got hr %#x.\n", hr);
8587 ok(current_time == 0xdeadbeefddf15da1 + filter_start_time, "Expected current time %s, got %s.\n",
8588 wine_dbgstr_longlong(0xdeadbeefddf15da1 + filter_start_time), wine_dbgstr_longlong(current_time));
8590 clock.get_time_hr = S_OK;
8592 current_time = 0xdeadbeefdeadbeef;
8593 hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
8594 ok(hr == S_OK, "Got hr %#x.\n", hr);
8595 ok(current_time == filter_start_time, "Expected current time %s, got %s.\n",
8596 wine_dbgstr_longlong(filter_start_time), wine_dbgstr_longlong(current_time));
8598 clock.time = 23456789;
8600 current_time = 0xdeadbeefdeadbeef;
8601 hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, NULL, NULL, &current_time);
8602 ok(hr == S_OK, "Got hr %#x.\n", hr);
8603 ok(current_time == filter_start_time + 11111111, "Expected current time %s, got %s.\n",
8604 wine_dbgstr_longlong(filter_start_time + 11111111), wine_dbgstr_longlong(current_time));
8606 start_time = 0xdeadbeefdeadbeef;
8607 end_time = 0xdeadbeefdeadbeef;
8608 hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
8609 ok(hr == S_OK, "Got hr %#x.\n", hr);
8610 ok(start_time == 0, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
8611 ok(end_time == 0, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
8613 hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
8614 ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
8616 media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
8617 start_time = 12345678;
8618 end_time = 23456789;
8619 hr = IMediaSample_SetTime(media_sample, &start_time, &end_time);
8620 ok(hr == S_OK, "Got hr %#x.\n", hr);
8621 hr = IMemInputPin_Receive(mem_input_pin, media_sample);
8622 ok(hr == S_OK, "Got hr %#x.\n", hr);
8623 IMediaSample_Release(media_sample);
8625 start_time = 0xdeadbeefdeadbeef;
8626 end_time = 0xdeadbeefdeadbeef;
8627 hr = IDirectDrawStreamSample_GetSampleTimes(stream_sample, &start_time, &end_time, NULL);
8628 ok(hr == S_OK, "Got hr %#x.\n", hr);
8629 ok(start_time == 12345678, "Got start time %s.\n", wine_dbgstr_longlong(start_time));
8630 ok(end_time == 23456789, "Got end time %s.\n", wine_dbgstr_longlong(end_time));
8632 hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
8633 ok(hr == S_OK, "Got hr %#x.\n", hr);
8634 IGraphBuilder_Disconnect(graph, pin);
8635 IGraphBuilder_Disconnect(graph, &source.source.pin.IPin_iface);
8637 ref = IDirectDrawStreamSample_Release(stream_sample);
8638 ok(!ref, "Got outstanding refcount %d.\n", ref);
8639 ref = IAMMultiMediaStream_Release(mmstream);
8640 ok(!ref, "Got outstanding refcount %d.\n", ref);
8641 IMediaFilter_Release(graph_media_filter);
8642 ref = IGraphBuilder_Release(graph);
8643 ok(!ref, "Got outstanding refcount %d.\n", ref);
8644 ref = IMediaStreamFilter_Release(filter);
8645 ok(!ref, "Got outstanding refcount %d.\n", ref);
8646 IPin_Release(pin);
8647 IMemInputPin_Release(mem_input_pin);
8648 IDirectDrawMediaStream_Release(ddraw_stream);
8649 ref = IMediaStream_Release(stream);
8650 ok(!ref, "Got outstanding refcount %d.\n", ref);
8653 START_TEST(amstream)
8655 const WCHAR *test_avi_path;
8657 CoInitializeEx(NULL, COINIT_MULTITHREADED);
8659 test_interfaces();
8660 test_add_stream();
8661 test_media_streams();
8662 test_enum_pins();
8663 test_find_pin();
8664 test_pin_info();
8665 test_initialize();
8666 test_set_state();
8667 test_enum_media_types();
8668 test_media_types();
8670 test_avi_path = load_resource(L"test.avi");
8672 test_openfile(test_avi_path);
8673 test_mmstream_get_duration(test_avi_path);
8675 unload_resource(test_avi_path);
8677 test_audiodata_query_interface();
8678 test_audiodata_get_info();
8679 test_audiodata_set_buffer();
8680 test_audiodata_set_actual();
8681 test_audiodata_get_format();
8682 test_audiodata_set_format();
8684 test_audiostream_get_format();
8685 test_audiostream_set_format();
8686 test_audiostream_receive_connection();
8687 test_audiostream_receive();
8688 test_audiostream_initialize();
8689 test_audiostream_begin_flush_end_flush();
8690 test_audiostream_new_segment();
8692 test_audiostreamsample_update();
8693 test_audiostreamsample_completion_status();
8694 test_audiostreamsample_get_sample_times();
8695 test_audiostreamsample_get_media_stream();
8696 test_audiostreamsample_get_audio_data();
8698 test_ddrawstream_initialize();
8699 test_ddrawstream_getsetdirectdraw();
8700 test_ddrawstream_receive_connection();
8701 test_ddrawstream_create_sample();
8702 test_ddrawstream_get_format();
8703 test_ddrawstream_set_format();
8704 test_ddrawstream_receive();
8705 test_ddrawstream_begin_flush_end_flush();
8706 test_ddrawstream_new_segment();
8707 test_ddrawstream_get_time_per_frame();
8709 test_ddrawstreamsample_get_media_stream();
8710 test_ddrawstreamsample_update();
8711 test_ddrawstreamsample_completion_status();
8712 test_ddrawstreamsample_get_sample_times();
8714 test_ammediastream_join_am_multi_media_stream();
8715 test_ammediastream_join_filter();
8716 test_ammediastream_join_filter_graph();
8717 test_ammediastream_set_state();
8718 test_ammediastream_end_of_stream();
8720 test_mediastreamfilter_get_state();
8721 test_mediastreamfilter_stop_pause_run();
8722 test_mediastreamfilter_support_seeking();
8723 test_mediastreamfilter_seeking();
8724 test_mediastreamfilter_get_current_stream_time();
8725 test_mediastreamfilter_reference_time_to_stream_time();
8726 test_mediastreamfilter_wait_until();
8728 CoUninitialize();