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
22 #define NONAMELESSUNION
23 #define WINE_NO_NAMELESS_EXTENSION
25 #include "wine/test.h"
33 #include "wmcodecdsp.h"
34 #include "wine/strmbase.h"
36 static const WAVEFORMATEX audio_format
=
38 .wFormatTag
= WAVE_FORMAT_PCM
,
40 .nSamplesPerSec
= 11025,
43 .nAvgBytesPerSec
= 2 * 11025,
46 static const AM_MEDIA_TYPE audio_mt
=
48 /* MEDIATYPE_Audio, MEDIASUBTYPE_PCM, FORMAT_WaveFormatEx */
49 .majortype
= {0x73647561, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
50 .subtype
= {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
51 .formattype
= {0x05589f81, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
52 .cbFormat
= sizeof(WAVEFORMATEX
),
53 .pbFormat
= (BYTE
*)&audio_format
,
56 static const VIDEOINFO rgb8_video_info
=
58 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
59 .bmiHeader
.biWidth
= 333,
60 .bmiHeader
.biHeight
= -444,
61 .bmiHeader
.biPlanes
= 1,
62 .bmiHeader
.biBitCount
= 8,
63 .bmiHeader
.biCompression
= BI_RGB
,
66 static const VIDEOINFO rgb555_video_info
=
68 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
69 .bmiHeader
.biWidth
= 333,
70 .bmiHeader
.biHeight
= -444,
71 .bmiHeader
.biPlanes
= 1,
72 .bmiHeader
.biBitCount
= 16,
73 .bmiHeader
.biCompression
= BI_RGB
,
76 static const VIDEOINFO rgb565_video_info
=
78 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
79 .bmiHeader
.biWidth
= 333,
80 .bmiHeader
.biHeight
= -444,
81 .bmiHeader
.biPlanes
= 1,
82 .bmiHeader
.biBitCount
= 16,
83 .bmiHeader
.biCompression
= BI_BITFIELDS
,
84 .u
.dwBitMasks
= {0xf800, 0x07e0, 0x001f},
87 static const VIDEOINFO rgb24_video_info
=
89 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
90 .bmiHeader
.biWidth
= 333,
91 .bmiHeader
.biHeight
= -444,
92 .bmiHeader
.biPlanes
= 1,
93 .bmiHeader
.biBitCount
= 24,
94 .bmiHeader
.biCompression
= BI_RGB
,
97 static const VIDEOINFO rgb32_video_info
=
99 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
100 .bmiHeader
.biWidth
= 333,
101 .bmiHeader
.biHeight
= -444,
102 .bmiHeader
.biPlanes
= 1,
103 .bmiHeader
.biBitCount
= 32,
104 .bmiHeader
.biCompression
= BI_RGB
,
107 static const AM_MEDIA_TYPE rgb8_mt
=
109 /* MEDIATYPE_Video, MEDIASUBTYPE_RGB8, FORMAT_VideoInfo */
110 .majortype
= {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
111 .subtype
= {0xe436eb7a, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
112 .formattype
= {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
113 .cbFormat
= sizeof(VIDEOINFO
),
114 .pbFormat
= (BYTE
*)&rgb8_video_info
,
117 static const AM_MEDIA_TYPE rgb555_mt
=
119 /* MEDIATYPE_Video, MEDIASUBTYPE_RGB555, FORMAT_VideoInfo */
120 .majortype
= {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
121 .subtype
= {0xe436eb7c, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
122 .formattype
= {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
123 .cbFormat
= sizeof(VIDEOINFO
),
124 .pbFormat
= (BYTE
*)&rgb555_video_info
,
127 static const AM_MEDIA_TYPE rgb565_mt
=
129 /* MEDIATYPE_Video, MEDIASUBTYPE_RGB565, FORMAT_VideoInfo */
130 .majortype
= {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
131 .subtype
= {0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
132 .formattype
= {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
133 .cbFormat
= sizeof(VIDEOINFO
),
134 .pbFormat
= (BYTE
*)&rgb565_video_info
,
137 static const AM_MEDIA_TYPE rgb24_mt
=
139 /* MEDIATYPE_Video, MEDIASUBTYPE_RGB24, FORMAT_VideoInfo */
140 .majortype
= {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
141 .subtype
= {0xe436eb7d, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
142 .formattype
= {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
143 .cbFormat
= sizeof(VIDEOINFO
),
144 .pbFormat
= (BYTE
*)&rgb24_video_info
,
147 static const AM_MEDIA_TYPE rgb32_mt
=
149 /* MEDIATYPE_Video, MEDIASUBTYPE_RGB32, FORMAT_VideoInfo */
150 .majortype
= {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
151 .subtype
= {0xe436eb7e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
152 .formattype
= {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
153 .cbFormat
= sizeof(VIDEOINFO
),
154 .pbFormat
= (BYTE
*)&rgb32_video_info
,
157 static const DDSURFACEDESC rgb8_format
=
159 .dwSize
= sizeof(DDSURFACEDESC
),
160 .dwFlags
= DDSD_PIXELFORMAT
,
161 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
162 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED8
,
163 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 8,
166 static const DDSURFACEDESC rgb555_format
=
168 .dwSize
= sizeof(DDSURFACEDESC
),
169 .dwFlags
= DDSD_PIXELFORMAT
,
170 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
171 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
,
172 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 16,
173 .ddpfPixelFormat
.u2
.dwRBitMask
= 0x7c00,
174 .ddpfPixelFormat
.u3
.dwGBitMask
= 0x03e0,
175 .ddpfPixelFormat
.u4
.dwBBitMask
= 0x001f,
178 static const DDSURFACEDESC rgb565_format
=
180 .dwSize
= sizeof(DDSURFACEDESC
),
181 .dwFlags
= DDSD_PIXELFORMAT
,
182 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
183 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
,
184 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 16,
185 .ddpfPixelFormat
.u2
.dwRBitMask
= 0xf800,
186 .ddpfPixelFormat
.u3
.dwGBitMask
= 0x07e0,
187 .ddpfPixelFormat
.u4
.dwBBitMask
= 0x001f,
190 static const DDSURFACEDESC rgb24_format
=
192 .dwSize
= sizeof(DDSURFACEDESC
),
193 .dwFlags
= DDSD_PIXELFORMAT
,
194 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
195 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
,
196 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 24,
197 .ddpfPixelFormat
.u2
.dwRBitMask
= 0xff0000,
198 .ddpfPixelFormat
.u3
.dwGBitMask
= 0x00ff00,
199 .ddpfPixelFormat
.u4
.dwBBitMask
= 0x0000ff,
202 static const DDSURFACEDESC rgb32_format
=
204 .dwSize
= sizeof(DDSURFACEDESC
),
205 .dwFlags
= DDSD_PIXELFORMAT
,
206 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
207 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
,
208 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 32,
209 .ddpfPixelFormat
.u2
.dwRBitMask
= 0xff0000,
210 .ddpfPixelFormat
.u3
.dwGBitMask
= 0x00ff00,
211 .ddpfPixelFormat
.u4
.dwBBitMask
= 0x0000ff,
214 static const DDSURFACEDESC argb32_format
=
216 .dwSize
= sizeof(DDSURFACEDESC
),
217 .dwFlags
= DDSD_PIXELFORMAT
,
218 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
219 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
,
220 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 32,
221 .ddpfPixelFormat
.u2
.dwRBitMask
= 0xff0000,
222 .ddpfPixelFormat
.u3
.dwGBitMask
= 0x00ff00,
223 .ddpfPixelFormat
.u4
.dwBBitMask
= 0x0000ff,
224 .ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
= 0xff000000,
227 static const DDSURFACEDESC yuy2_format
=
229 .dwSize
= sizeof(DDSURFACEDESC
),
230 .dwFlags
= DDSD_PIXELFORMAT
,
231 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
232 .ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
,
233 .ddpfPixelFormat
.dwFourCC
= MAKEFOURCC('Y', 'U', 'Y', '2'),
234 .ddpfPixelFormat
.u1
.dwYUVBitCount
= 16,
237 static const DDSURFACEDESC yv12_format
=
239 .dwSize
= sizeof(DDSURFACEDESC
),
240 .dwFlags
= DDSD_PIXELFORMAT
,
241 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
242 .ddpfPixelFormat
.dwFlags
= DDPF_FOURCC
,
243 .ddpfPixelFormat
.dwFourCC
= MAKEFOURCC('Y', 'V', '1', '2'),
244 .ddpfPixelFormat
.u1
.dwYUVBitCount
= 12,
247 static const WCHAR primary_video_sink_id
[] = L
"I{A35FF56A-9FDA-11D0-8FDF-00C04FD9189D}";
248 static const WCHAR primary_audio_sink_id
[] = L
"I{A35FF56B-9FDA-11D0-8FDF-00C04FD9189D}";
250 static const WCHAR
*load_resource(const WCHAR
*name
)
252 HMODULE module
= GetModuleHandleA(NULL
);
260 path
= calloc(MAX_PATH
+ 1, sizeof(WCHAR
));
261 ok(!!path
, "Failed to allocate temp path string.\n");
262 GetTempPathW(MAX_PATH
+ 1, path
);
265 file
= CreateFileW(path
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
266 ok(file
!= INVALID_HANDLE_VALUE
, "Failed to create file %s, error %u.\n", wine_dbgstr_w(path
), GetLastError());
268 resource
= FindResourceW(module
, name
, (const WCHAR
*)RT_RCDATA
);
269 ok(!!resource
, "Failed to find resource %s, error %u.\n", wine_dbgstr_w(name
), GetLastError());
271 size
= SizeofResource(module
, resource
);
272 ptr
= LockResource(LoadResource(module
, resource
));
274 WriteFile(file
, ptr
, size
, &written
, NULL
);
275 ok(written
== size
, "Failed to write file %s.\n", wine_dbgstr_w(path
));
282 static void unload_resource(const WCHAR
*path
)
284 BOOL ret
= DeleteFileW(path
);
285 ok(ret
, "Failed to delete file %s.\n", wine_dbgstr_w(path
));
289 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
290 static void _expect_ref(IUnknown
* obj
, ULONG ref
, int line
)
293 IUnknown_AddRef(obj
);
294 rc
= IUnknown_Release(obj
);
295 ok_(__FILE__
,line
)(rc
== ref
, "expected refcount %d, got %d\n", ref
, rc
);
298 static IAMMultiMediaStream
*create_ammultimediastream(void)
300 IAMMultiMediaStream
*stream
= NULL
;
301 HRESULT hr
= CoCreateInstance(&CLSID_AMMultiMediaStream
, NULL
, CLSCTX_INPROC_SERVER
,
302 &IID_IAMMultiMediaStream
, (void **)&stream
);
303 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
307 static ULONG
get_refcount(void *iface
)
309 IUnknown
*unknown
= iface
;
310 IUnknown_AddRef(unknown
);
311 return IUnknown_Release(unknown
);
314 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
315 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
317 IUnknown
*iface
= iface_ptr
;
318 HRESULT hr
, expected_hr
;
321 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
323 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
324 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
326 IUnknown_Release(unk
);
329 static void test_interfaces(void)
331 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
332 IMediaStreamFilter
*filter
;
333 IMediaStream
*stream
;
337 check_interface(mmstream
, &IID_IAMMultiMediaStream
, TRUE
);
338 check_interface(mmstream
, &IID_IMultiMediaStream
, TRUE
);
339 check_interface(mmstream
, &IID_IUnknown
, TRUE
);
341 check_interface(mmstream
, &IID_IAMMediaStream
, FALSE
);
342 check_interface(mmstream
, &IID_IAMMediaTypeStream
, FALSE
);
343 check_interface(mmstream
, &IID_IAudioMediaStream
, FALSE
);
344 check_interface(mmstream
, &IID_IBaseFilter
, FALSE
);
345 check_interface(mmstream
, &IID_IDirectDrawMediaStream
, FALSE
);
346 check_interface(mmstream
, &IID_IMediaFilter
, FALSE
);
347 check_interface(mmstream
, &IID_IMediaStream
, FALSE
);
348 check_interface(mmstream
, &IID_IMediaStreamFilter
, FALSE
);
349 check_interface(mmstream
, &IID_IPin
, FALSE
);
351 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
352 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
354 check_interface(filter
, &IID_IBaseFilter
, TRUE
);
355 check_interface(filter
, &IID_IMediaFilter
, TRUE
);
356 check_interface(filter
, &IID_IMediaStreamFilter
, TRUE
);
357 check_interface(filter
, &IID_IPersist
, TRUE
);
358 check_interface(filter
, &IID_IUnknown
, TRUE
);
360 check_interface(filter
, &IID_IAMMediaStream
, FALSE
);
361 check_interface(filter
, &IID_IAMMediaTypeStream
, FALSE
);
362 check_interface(filter
, &IID_IAMMultiMediaStream
, FALSE
);
363 check_interface(filter
, &IID_IAudioMediaStream
, FALSE
);
364 check_interface(filter
, &IID_IDirectDrawMediaStream
, FALSE
);
365 check_interface(filter
, &IID_IMediaStream
, FALSE
);
366 check_interface(filter
, &IID_IMultiMediaStream
, FALSE
);
367 check_interface(filter
, &IID_IPin
, FALSE
);
369 IMediaStreamFilter_Release(filter
);
371 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
372 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
374 check_interface(stream
, &IID_IAMMediaStream
, TRUE
);
375 check_interface(stream
, &IID_IAudioMediaStream
, TRUE
);
376 check_interface(stream
, &IID_IMediaStream
, TRUE
);
377 check_interface(stream
, &IID_IMemInputPin
, TRUE
);
378 check_interface(stream
, &IID_IPin
, TRUE
);
379 check_interface(stream
, &IID_IUnknown
, TRUE
);
381 check_interface(stream
, &IID_IAMMediaTypeStream
, FALSE
);
382 check_interface(stream
, &IID_IAMMultiMediaStream
, FALSE
);
383 check_interface(stream
, &IID_IBaseFilter
, FALSE
);
384 check_interface(stream
, &IID_IDirectDrawMediaStream
, FALSE
);
385 check_interface(stream
, &IID_IMediaFilter
, FALSE
);
386 check_interface(stream
, &IID_IMediaStreamFilter
, FALSE
);
387 check_interface(stream
, &IID_IMultiMediaStream
, FALSE
);
388 check_interface(stream
, &IID_IPersist
, FALSE
);
390 IMediaStream_Release(stream
);
392 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
393 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
395 check_interface(stream
, &IID_IAMMediaStream
, TRUE
);
396 check_interface(stream
, &IID_IDirectDrawMediaStream
, TRUE
);
397 check_interface(stream
, &IID_IMediaStream
, TRUE
);
398 check_interface(stream
, &IID_IMemInputPin
, TRUE
);
399 check_interface(stream
, &IID_IPin
, TRUE
);
400 check_interface(stream
, &IID_IUnknown
, TRUE
);
402 check_interface(stream
, &IID_IAMMediaTypeStream
, FALSE
);
403 check_interface(stream
, &IID_IAMMultiMediaStream
, FALSE
);
404 check_interface(stream
, &IID_IAudioMediaStream
, FALSE
);
405 check_interface(stream
, &IID_IBaseFilter
, FALSE
);
406 check_interface(stream
, &IID_IDirectDraw
, FALSE
);
407 check_interface(stream
, &IID_IMediaFilter
, FALSE
);
408 check_interface(stream
, &IID_IMediaStreamFilter
, FALSE
);
409 check_interface(stream
, &IID_IMultiMediaStream
, FALSE
);
410 check_interface(stream
, &IID_IPersist
, FALSE
);
412 IMediaStream_Release(stream
);
414 ref
= IAMMultiMediaStream_Release(mmstream
);
415 ok(!ref
, "Got outstanding refcount %u.\n", ref
);
418 static void test_openfile(const WCHAR
*test_avi_path
)
420 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
421 IMediaControl
*media_control
;
422 IMediaStreamFilter
*filter
;
423 IMediaFilter
*media_filter
;
424 IReferenceClock
*clock
;
425 IGraphBuilder
*graph
;
430 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
431 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
432 ok(!graph
, "Expected NULL graph.\n");
434 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
435 ok(!!filter
, "Expected non-NULL filter.\n");
436 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
438 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
440 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_NORENDER
);
441 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
443 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
445 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
446 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
447 ok(!!graph
, "Expected non-NULL graph.\n");
448 IGraphBuilder_Release(graph
);
449 IMediaStreamFilter_Release(filter
);
451 ref
= IAMMultiMediaStream_Release(mmstream
);
452 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
454 mmstream
= create_ammultimediastream();
455 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
456 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
457 ok(!graph
, "Expected NULL graph.\n");
459 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
460 ok(!!filter
, "Expected non-NULL filter.\n");
461 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
463 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
465 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, 0);
466 ok(hr
== VFW_E_CANNOT_CONNECT
, "Got hr %#x.\n", hr
);
468 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
470 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
471 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
472 ok(!!graph
, "Expected non-NULL graph.\n");
473 IGraphBuilder_Release(graph
);
474 IMediaStreamFilter_Release(filter
);
476 ref
= IAMMultiMediaStream_Release(mmstream
);
477 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
479 mmstream
= create_ammultimediastream();
480 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
481 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
482 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
483 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
484 ok(!!graph
, "Expected non-NULL graph.\n");
485 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
486 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
487 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
488 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
490 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
492 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, 0);
493 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
495 check_interface(filter
, &IID_IMediaSeeking
, TRUE
);
497 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
498 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
501 IMediaFilter_GetSyncSource(media_filter
, &clock
);
502 ok(!!clock
, "Expected non-NULL clock.\n");
504 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
505 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
507 ref
= IAMMultiMediaStream_Release(mmstream
);
508 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
509 IMediaFilter_Release(media_filter
);
510 ref
= IGraphBuilder_Release(graph
);
511 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
512 ref
= IMediaStreamFilter_Release(filter
);
513 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
514 ref
= IReferenceClock_Release(clock
);
515 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
517 mmstream
= create_ammultimediastream();
518 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
519 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
520 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
521 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
522 ok(!!graph
, "Expected non-NULL graph.\n");
523 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaControl
, (void **)&media_control
);
524 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
526 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_RUN
);
527 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
530 hr
= IMediaControl_GetState(media_control
, INFINITE
, &state
);
531 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
532 ok(state
== State_Running
, "Got state %#x.\n", state
);
534 ref
= IAMMultiMediaStream_Release(mmstream
);
535 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
536 IMediaControl_Release(media_control
);
537 ref
= IGraphBuilder_Release(graph
);
538 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
540 mmstream
= create_ammultimediastream();
541 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
542 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
543 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
544 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
545 ok(!!graph
, "Expected non-NULL graph.\n");
546 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
547 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
549 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_NOCLOCK
);
550 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
552 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
553 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
555 clock
= (IReferenceClock
*)0xdeadbeef;
556 IMediaFilter_GetSyncSource(media_filter
, &clock
);
557 ok(!clock
, "Got clock %p.\n", clock
);
559 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
560 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
562 ref
= IAMMultiMediaStream_Release(mmstream
);
563 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
564 IMediaFilter_Release(media_filter
);
565 ref
= IGraphBuilder_Release(graph
);
566 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
569 static void test_mmstream_get_duration(const WCHAR
*test_avi_path
)
571 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
572 HRESULT hr
, audio_hr
;
576 duration
= 0xdeadbeefdeadbeefULL
;
577 hr
= IAMMultiMediaStream_GetDuration(mmstream
, &duration
);
578 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
579 ok(duration
== 0xdeadbeefdeadbeefULL
, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
581 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, NULL
);
582 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
584 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, AMMSF_ADDDEFAULTRENDERER
, NULL
);
585 ok(hr
== S_OK
|| hr
== VFW_E_NO_AUDIO_HARDWARE
, "Got hr %#x.\n", hr
);
588 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, 0);
589 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
591 duration
= 0xdeadbeefdeadbeefULL
;
592 hr
= IAMMultiMediaStream_GetDuration(mmstream
, &duration
);
593 if (audio_hr
== S_OK
)
595 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
596 ok(duration
== 1000000LL, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
600 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
601 ok(!duration
, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
604 ref
= IAMMultiMediaStream_Release(mmstream
);
605 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
607 mmstream
= create_ammultimediastream();
608 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
609 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
611 duration
= 0xdeadbeefdeadbeefULL
;
612 hr
= IAMMultiMediaStream_GetDuration(mmstream
, &duration
);
613 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
614 ok(duration
== 0, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
616 ref
= IAMMultiMediaStream_Release(mmstream
);
617 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
619 mmstream
= create_ammultimediastream();
621 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, 0);
622 ok(hr
== VFW_E_CANNOT_CONNECT
, "Got hr %#x.\n", hr
);
624 duration
= 0xdeadbeefdeadbeefULL
;
625 hr
= IAMMultiMediaStream_GetDuration(mmstream
, &duration
);
626 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
627 ok(duration
== 0, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
629 ref
= IAMMultiMediaStream_Release(mmstream
);
630 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
632 mmstream
= create_ammultimediastream();
633 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
634 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
636 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_NORENDER
);
637 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
639 duration
= 0xdeadbeefdeadbeefULL
;
640 hr
= IAMMultiMediaStream_GetDuration(mmstream
, &duration
);
641 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
642 ok(duration
== 0, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
644 ref
= IAMMultiMediaStream_Release(mmstream
);
645 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
648 static const GUID test_mspid
= {0x88888888};
652 IAMMediaStream IAMMediaStream_iface
;
656 IAMMultiMediaStream
*mmstream
;
657 IMediaStreamFilter
*filter
;
660 HRESULT set_state_result
;
663 static struct teststream
*impl_from_IAMMediaStream(IAMMediaStream
*iface
)
665 return CONTAINING_RECORD(iface
, struct teststream
, IAMMediaStream_iface
);
668 static struct teststream
*impl_from_IPin(IPin
*iface
)
670 return CONTAINING_RECORD(iface
, struct teststream
, IPin_iface
);
673 static HRESULT WINAPI
pin_QueryInterface(IPin
*iface
, REFIID iid
, void **out
)
675 struct teststream
*stream
= impl_from_IPin(iface
);
676 return IAMMediaStream_QueryInterface(&stream
->IAMMediaStream_iface
, iid
, out
);
679 static ULONG WINAPI
pin_AddRef(IPin
*iface
)
681 struct teststream
*stream
= impl_from_IPin(iface
);
682 return IAMMediaStream_AddRef(&stream
->IAMMediaStream_iface
);
685 static ULONG WINAPI
pin_Release(IPin
*iface
)
687 struct teststream
*stream
= impl_from_IPin(iface
);
688 return IAMMediaStream_Release(&stream
->IAMMediaStream_iface
);
691 static HRESULT WINAPI
pin_Connect(IPin
*iface
, IPin
*peer
, const AM_MEDIA_TYPE
*mt
)
693 ok(0, "Unexpected call.\n");
697 static HRESULT WINAPI
pin_ReceiveConnection(IPin
*iface
, IPin
*peer
, const AM_MEDIA_TYPE
*mt
)
699 ok(0, "Unexpected call.\n");
703 static HRESULT WINAPI
pin_Disconnect(IPin
*iface
)
705 if (winetest_debug
> 1) trace("Disconnect\n");
709 static HRESULT WINAPI
pin_ConnectedTo(IPin
*iface
, IPin
**peer
)
711 if (winetest_debug
> 1) trace("ConnectedTo\n");
715 static HRESULT WINAPI
pin_ConnectionMediaType(IPin
*iface
, AM_MEDIA_TYPE
*mt
)
717 ok(0, "Unexpected call.\n");
721 static HRESULT WINAPI
pin_QueryPinInfo(IPin
*iface
, PIN_INFO
*info
)
723 ok(0, "Unexpected call.\n");
727 static HRESULT WINAPI
pin_QueryDirection(IPin
*iface
, PIN_DIRECTION
*dir
)
729 if (winetest_debug
> 1) trace("QueryDirection\n");
734 static HRESULT WINAPI
pin_QueryId(IPin
*iface
, WCHAR
**id
)
736 ok(0, "Unexpected call.\n");
740 static HRESULT WINAPI
pin_QueryAccept(IPin
*iface
, const AM_MEDIA_TYPE
*mt
)
742 ok(0, "Unexpected call.\n");
746 static HRESULT WINAPI
pin_EnumMediaTypes(IPin
*iface
, IEnumMediaTypes
**out
)
748 ok(0, "Unexpected call.\n");
752 static HRESULT WINAPI
pin_QueryInternalConnections(IPin
*iface
, IPin
**pins
, ULONG
*count
)
754 ok(0, "Unexpected call.\n");
758 static HRESULT WINAPI
pin_EndOfStream(IPin
*iface
)
760 ok(0, "Unexpected call.\n");
764 static HRESULT WINAPI
pin_BeginFlush(IPin
*iface
)
766 ok(0, "Unexpected call.\n");
770 static HRESULT WINAPI
pin_EndFlush(IPin
*iface
)
772 ok(0, "Unexpected call.\n");
776 static HRESULT WINAPI
pin_NewSegment(IPin
*iface
, REFERENCE_TIME start
, REFERENCE_TIME stop
, double rate
)
778 ok(0, "Unexpected call.\n");
782 static const IPinVtbl pin_vtbl
=
788 pin_ReceiveConnection
,
791 pin_ConnectionMediaType
,
797 pin_QueryInternalConnections
,
804 static HRESULT WINAPI
stream_QueryInterface(IAMMediaStream
*iface
, REFIID iid
, void **out
)
806 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
808 if (winetest_debug
> 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid
));
810 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IMediaStream
) || IsEqualGUID(iid
, &IID_IAMMediaStream
))
812 IAMMediaStream_AddRef(iface
);
816 else if (IsEqualGUID(iid
, &IID_IPin
))
818 IAMMediaStream_AddRef(iface
);
819 *out
= &stream
->IPin_iface
;
823 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(iid
));
824 return E_NOINTERFACE
;
827 static ULONG WINAPI
stream_AddRef(IAMMediaStream
*iface
)
829 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
830 return InterlockedIncrement(&stream
->refcount
);
833 static ULONG WINAPI
stream_Release(IAMMediaStream
*iface
)
835 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
836 return InterlockedDecrement(&stream
->refcount
);
839 static HRESULT WINAPI
stream_GetMultiMediaStream(IAMMediaStream
*iface
, IMultiMediaStream
**mmstream
)
841 ok(0, "Unexpected call.\n");
845 static HRESULT WINAPI
stream_GetInformation(IAMMediaStream
*iface
, MSPID
*id
, STREAM_TYPE
*type
)
847 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
848 if (winetest_debug
> 1) trace("GetInformation(%p, %p)\n", id
, type
);
852 *type
= STREAMTYPE_READ
;
856 static HRESULT WINAPI
stream_SetSameFormat(IAMMediaStream
*iface
, IMediaStream
*ref
, DWORD flags
)
858 ok(0, "Unexpected call.\n");
862 static HRESULT WINAPI
stream_AllocateSample(IAMMediaStream
*iface
, DWORD flags
, IStreamSample
**sample
)
864 ok(0, "Unexpected call.\n");
868 static HRESULT WINAPI
stream_CreateSharedSample(IAMMediaStream
*iface
,
869 IStreamSample
*existing
, DWORD flags
, IStreamSample
**out
)
871 ok(0, "Unexpected call.\n");
875 static HRESULT WINAPI
stream_SendEndOfStream(IAMMediaStream
*iface
, DWORD flags
)
877 ok(0, "Unexpected call.\n");
881 static HRESULT WINAPI
stream_Initialize(IAMMediaStream
*iface
, IUnknown
*source
,
882 DWORD flags
, REFMSPID id
, const STREAM_TYPE type
)
884 ok(0, "Unexpected call.\n");
888 static HRESULT WINAPI
stream_SetState(IAMMediaStream
*iface
, FILTER_STATE state
)
890 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
891 if (winetest_debug
> 1) trace("SetState(%#x)\n", state
);
892 if (SUCCEEDED(stream
->set_state_result
))
893 stream
->state
= state
;
894 return stream
->set_state_result
;
897 static HRESULT WINAPI
stream_JoinAMMultiMediaStream(IAMMediaStream
*iface
, IAMMultiMediaStream
*mmstream
)
899 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
900 if (winetest_debug
> 1) trace("JoinAMMultiMediaStream(%p)\n", mmstream
);
901 stream
->mmstream
= mmstream
;
905 static HRESULT WINAPI
stream_JoinFilter(IAMMediaStream
*iface
, IMediaStreamFilter
*filter
)
907 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
908 if (winetest_debug
> 1) trace("JoinFilter(%p)\n", filter
);
909 stream
->filter
= filter
;
913 static HRESULT WINAPI
stream_JoinFilterGraph(IAMMediaStream
*iface
, IFilterGraph
*graph
)
915 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
916 if (winetest_debug
> 1) trace("JoinFilterGraph(%p)\n", graph
);
917 stream
->graph
= graph
;
921 static const IAMMediaStreamVtbl stream_vtbl
=
923 stream_QueryInterface
,
926 stream_GetMultiMediaStream
,
927 stream_GetInformation
,
928 stream_SetSameFormat
,
929 stream_AllocateSample
,
930 stream_CreateSharedSample
,
931 stream_SendEndOfStream
,
934 stream_JoinAMMultiMediaStream
,
936 stream_JoinFilterGraph
,
939 static void teststream_init(struct teststream
*stream
)
941 memset(stream
, 0, sizeof(*stream
));
942 stream
->IAMMediaStream_iface
.lpVtbl
= &stream_vtbl
;
943 stream
->IPin_iface
.lpVtbl
= &pin_vtbl
;
944 stream
->refcount
= 1;
945 stream
->mspid
= test_mspid
;
946 stream
->set_state_result
= S_OK
;
949 #define check_enum_stream(a,b,c,d) check_enum_stream_(__LINE__,a,b,c,d)
950 static void check_enum_stream_(int line
, IAMMultiMediaStream
*mmstream
,
951 IMediaStreamFilter
*filter
, LONG index
, IMediaStream
*expect
)
953 IMediaStream
*stream
= NULL
, *stream2
= NULL
;
956 hr
= IAMMultiMediaStream_EnumMediaStreams(mmstream
, index
, &stream
);
957 ok_(__FILE__
, line
)(hr
== (expect
? S_OK
: S_FALSE
),
958 "IAMMultiMediaStream::EnumMediaStreams() returned %#x.\n", hr
);
959 hr
= IMediaStreamFilter_EnumMediaStreams(filter
, index
, &stream2
);
960 ok_(__FILE__
, line
)(hr
== (expect
? S_OK
: S_FALSE
),
961 "IMediaStreamFilter::EnumMediaStreams() returned %#x.\n", hr
);
964 ok_(__FILE__
, line
)(stream
== expect
, "Expected stream %p, got %p.\n", expect
, stream
);
965 ok_(__FILE__
, line
)(stream2
== expect
, "Expected stream %p, got %p.\n", expect
, stream2
);
966 IMediaStream_Release(stream
);
967 IMediaStream_Release(stream2
);
973 struct strmbase_filter filter
;
974 struct strmbase_source source
;
975 IMediaSeeking IMediaSeeking_iface
;
976 LONGLONG current_position
;
977 LONGLONG stop_position
;
978 const AM_MEDIA_TYPE
*preferred_mt
;
979 HANDLE wait_state_event
;
980 HRESULT get_duration_hr
;
981 HRESULT get_stop_position_hr
;
982 HRESULT set_positions_hr
;
983 HRESULT init_stream_hr
;
984 HRESULT cleanup_stream_hr
;
985 HRESULT wait_state_hr
;
986 HRESULT is_format_supported_hr
;
989 static inline struct testfilter
*impl_from_BaseFilter(struct strmbase_filter
*iface
)
991 return CONTAINING_RECORD(iface
, struct testfilter
, filter
);
994 static struct strmbase_pin
*testfilter_get_pin(struct strmbase_filter
*iface
, unsigned int index
)
996 struct testfilter
*filter
= impl_from_BaseFilter(iface
);
998 return &filter
->source
.pin
;
1002 static void testfilter_destroy(struct strmbase_filter
*iface
)
1004 struct testfilter
*filter
= impl_from_BaseFilter(iface
);
1005 CloseHandle(filter
->wait_state_event
);
1006 strmbase_source_cleanup(&filter
->source
);
1007 strmbase_filter_cleanup(&filter
->filter
);
1010 static HRESULT
testfilter_init_stream(struct strmbase_filter
*iface
)
1012 struct testfilter
*filter
= impl_from_BaseFilter(iface
);
1015 if (SUCCEEDED(filter
->init_stream_hr
) && filter
->source
.pin
.peer
)
1017 hr
= IMemAllocator_Commit(filter
->source
.pAllocator
);
1018 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1021 return filter
->init_stream_hr
;
1024 static HRESULT
testfilter_cleanup_stream(struct strmbase_filter
*iface
)
1026 struct testfilter
*filter
= impl_from_BaseFilter(iface
);
1029 if (SUCCEEDED(filter
->cleanup_stream_hr
) && filter
->source
.pin
.peer
)
1031 hr
= IMemAllocator_Decommit(filter
->source
.pAllocator
);
1032 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1035 return filter
->cleanup_stream_hr
;
1038 static HRESULT
testfilter_wait_state(struct strmbase_filter
*iface
, DWORD timeout
)
1040 struct testfilter
*filter
= impl_from_BaseFilter(iface
);
1043 LeaveCriticalSection(&filter
->filter
.filter_cs
);
1044 WaitForSingleObject(filter
->wait_state_event
, timeout
);
1045 EnterCriticalSection(&filter
->filter
.filter_cs
);
1047 hr
= filter
->wait_state_hr
;
1052 static const struct strmbase_filter_ops testfilter_ops
=
1054 .filter_get_pin
= testfilter_get_pin
,
1055 .filter_destroy
= testfilter_destroy
,
1056 .filter_init_stream
= testfilter_init_stream
,
1057 .filter_cleanup_stream
= testfilter_cleanup_stream
,
1058 .filter_wait_state
= testfilter_wait_state
,
1061 static inline struct testfilter
*impl_from_base_pin(struct strmbase_pin
*iface
)
1063 return CONTAINING_RECORD(iface
, struct testfilter
, source
.pin
);
1066 static HRESULT
testsource_get_media_type(struct strmbase_pin
*iface
, unsigned int index
, AM_MEDIA_TYPE
*mt
)
1068 struct testfilter
*filter
= impl_from_base_pin(iface
);
1070 if (index
< 1 && filter
->preferred_mt
)
1071 return CopyMediaType(mt
, filter
->preferred_mt
);
1073 return VFW_S_NO_MORE_ITEMS
;
1076 static HRESULT
testsource_query_interface(struct strmbase_pin
*iface
, REFIID iid
, void **out
)
1078 struct testfilter
*filter
= impl_from_base_pin(iface
);
1080 if (IsEqualGUID(iid
, &IID_IMediaSeeking
) && filter
->IMediaSeeking_iface
.lpVtbl
)
1081 *out
= &filter
->IMediaSeeking_iface
;
1083 return E_NOINTERFACE
;
1085 IUnknown_AddRef((IUnknown
*)*out
);
1090 static HRESULT WINAPI
testsource_DecideAllocator(struct strmbase_source
*iface
, IMemInputPin
*pin
, IMemAllocator
**alloc
)
1092 ALLOCATOR_PROPERTIES props
= {0};
1095 /* AMDirectDrawStream tries to use it's custom allocator and
1096 * when it is able to do so it's behavior changes slightly
1097 * (e.g. it uses dynamic format change instead of reconnecting in SetFormat).
1098 * We don't yet implement the custom allocator so force the standard one for now. */
1099 hr
= BaseOutputPinImpl_InitAllocator(iface
, alloc
);
1100 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1102 IMemInputPin_GetAllocatorRequirements(pin
, &props
);
1103 hr
= iface
->pFuncsTable
->pfnDecideBufferSize(iface
, *alloc
, &props
);
1104 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1106 return IMemInputPin_NotifyAllocator(pin
, *alloc
, FALSE
);
1109 static HRESULT WINAPI
testsource_DecideBufferSize(struct strmbase_source
*iface
,
1110 IMemAllocator
*alloc
, ALLOCATOR_PROPERTIES
*requested
)
1112 ALLOCATOR_PROPERTIES actual
;
1114 if (!requested
->cbAlign
)
1115 requested
->cbAlign
= 1;
1117 if (requested
->cbBuffer
< 4096)
1118 requested
->cbBuffer
= 4096;
1120 if (!requested
->cBuffers
)
1121 requested
->cBuffers
= 2;
1123 return IMemAllocator_SetProperties(alloc
, requested
, &actual
);
1126 static const struct strmbase_source_ops testsource_ops
=
1128 .base
.pin_get_media_type
= testsource_get_media_type
,
1129 .base
.pin_query_interface
= testsource_query_interface
,
1130 .pfnAttemptConnection
= BaseOutputPinImpl_AttemptConnection
,
1131 .pfnDecideBufferSize
= testsource_DecideBufferSize
,
1132 .pfnDecideAllocator
= testsource_DecideAllocator
,
1135 static void testfilter_init(struct testfilter
*filter
)
1137 static const GUID clsid
= {0xabacab};
1138 memset(filter
, 0, sizeof(*filter
));
1139 strmbase_filter_init(&filter
->filter
, NULL
, &clsid
, &testfilter_ops
);
1140 strmbase_source_init(&filter
->source
, &filter
->filter
, L
"", &testsource_ops
);
1141 filter
->stop_position
= 0x8000000000000000ULL
;
1142 filter
->wait_state_event
= CreateEventW(NULL
, TRUE
, TRUE
, NULL
);
1145 static inline struct testfilter
*impl_from_IMediaSeeking(IMediaSeeking
*iface
)
1147 return CONTAINING_RECORD(iface
, struct testfilter
, IMediaSeeking_iface
);
1150 static HRESULT WINAPI
testsource_seeking_QueryInterface(IMediaSeeking
*iface
, REFIID iid
, void **out
)
1152 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1153 return IBaseFilter_QueryInterface(&filter
->filter
.IBaseFilter_iface
, iid
, out
);
1156 static ULONG WINAPI
testsource_seeking_AddRef(IMediaSeeking
*iface
)
1158 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1159 return IBaseFilter_AddRef(&filter
->filter
.IBaseFilter_iface
);
1162 static ULONG WINAPI
testsource_seeking_Release(IMediaSeeking
*iface
)
1164 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1165 return IBaseFilter_Release(&filter
->filter
.IBaseFilter_iface
);
1168 static HRESULT WINAPI
testsource_seeking_GetCapabilities(IMediaSeeking
*iface
, DWORD
*capabilities
)
1173 static HRESULT WINAPI
testsource_seeking_CheckCapabilities(IMediaSeeking
*iface
, DWORD
*capabilities
)
1175 ok(0, "Unexpected call.\n");
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");
1195 static HRESULT WINAPI
testsource_seeking_GetTimeFormat(IMediaSeeking
*iface
, GUID
*format
)
1197 ok(0, "Unexpected call.\n");
1201 static HRESULT WINAPI
testsource_seeking_IsUsingTimeFormat(IMediaSeeking
*iface
, const GUID
*format
)
1206 static HRESULT WINAPI
testsource_seeking_SetTimeFormat(IMediaSeeking
*iface
, const GUID
*format
)
1208 ok(0, "Unexpected call.\n");
1212 static HRESULT WINAPI
testsource_seeking_GetDuration(IMediaSeeking
*iface
, LONGLONG
*duration
)
1214 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1216 if (SUCCEEDED(filter
->get_duration_hr
))
1217 *duration
= 0x8000000000000000ULL
;
1219 return filter
->get_duration_hr
;
1222 static HRESULT WINAPI
testsource_seeking_GetStopPosition(IMediaSeeking
*iface
, LONGLONG
*stop
)
1224 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1226 if (SUCCEEDED(filter
->get_stop_position_hr
))
1227 *stop
= 0x8000000000000000ULL
;
1229 return filter
->get_stop_position_hr
;
1232 static HRESULT WINAPI
testsource_seeking_GetCurrentPosition(IMediaSeeking
*iface
, LONGLONG
*current
)
1234 ok(0, "Unexpected call.\n");
1238 static HRESULT WINAPI
testsource_seeking_ConvertTimeFormat(IMediaSeeking
*iface
, LONGLONG
*target
,
1239 const GUID
*target_format
, LONGLONG source
, const GUID
*source_format
)
1241 ok(0, "Unexpected call.\n");
1245 static HRESULT WINAPI
testsource_seeking_SetPositions(IMediaSeeking
*iface
, LONGLONG
*current_ptr
, DWORD current_flags
,
1246 LONGLONG
*stop_ptr
, DWORD stop_flags
)
1248 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1250 if (SUCCEEDED(filter
->set_positions_hr
))
1253 filter
->current_position
= *current_ptr
;
1256 filter
->stop_position
= *stop_ptr
;
1259 return filter
->set_positions_hr
;
1262 static HRESULT WINAPI
testsource_seeking_GetPositions(IMediaSeeking
*iface
, LONGLONG
*current
, LONGLONG
*stop
)
1264 ok(0, "Unexpected call.\n");
1268 static HRESULT WINAPI
testsource_seeking_GetAvailable(IMediaSeeking
*iface
, LONGLONG
*earliest
, LONGLONG
*latest
)
1270 ok(0, "Unexpected call.\n");
1274 static HRESULT WINAPI
testsource_seeking_SetRate(IMediaSeeking
*iface
, double rate
)
1276 ok(0, "Unexpected call.\n");
1280 static HRESULT WINAPI
testsource_seeking_GetRate(IMediaSeeking
*iface
, double *rate
)
1282 ok(0, "Unexpected call.\n");
1286 static HRESULT WINAPI
testsource_seeking_GetPreroll(IMediaSeeking
*iface
, LONGLONG
*preroll
)
1288 ok(0, "Unexpected call.\n");
1292 static const IMediaSeekingVtbl testsource_seeking_vtbl
=
1294 testsource_seeking_QueryInterface
,
1295 testsource_seeking_AddRef
,
1296 testsource_seeking_Release
,
1297 testsource_seeking_GetCapabilities
,
1298 testsource_seeking_CheckCapabilities
,
1299 testsource_seeking_IsFormatSupported
,
1300 testsource_seeking_QueryPreferredFormat
,
1301 testsource_seeking_GetTimeFormat
,
1302 testsource_seeking_IsUsingTimeFormat
,
1303 testsource_seeking_SetTimeFormat
,
1304 testsource_seeking_GetDuration
,
1305 testsource_seeking_GetStopPosition
,
1306 testsource_seeking_GetCurrentPosition
,
1307 testsource_seeking_ConvertTimeFormat
,
1308 testsource_seeking_SetPositions
,
1309 testsource_seeking_GetPositions
,
1310 testsource_seeking_GetAvailable
,
1311 testsource_seeking_SetRate
,
1312 testsource_seeking_GetRate
,
1313 testsource_seeking_GetPreroll
,
1316 #define check_get_stream(a,b,c,d) check_get_stream_(__LINE__,a,b,c,d)
1317 static void check_get_stream_(int line
, IAMMultiMediaStream
*mmstream
,
1318 IMediaStreamFilter
*filter
, const GUID
*mspid
, IMediaStream
*expect
)
1320 IMediaStream
*stream
= NULL
, *stream2
= NULL
;
1323 hr
= IAMMultiMediaStream_GetMediaStream(mmstream
, mspid
, &stream
);
1324 ok_(__FILE__
, line
)(hr
== (expect
? S_OK
: MS_E_NOSTREAM
),
1325 "IAMMultiMediaStream::GetMediaStream() returned %#x.\n", hr
);
1326 hr
= IMediaStreamFilter_GetMediaStream(filter
, mspid
, &stream2
);
1327 ok_(__FILE__
, line
)(hr
== (expect
? S_OK
: MS_E_NOSTREAM
),
1328 "IMediaStreamFilter::GetMediaStream() returned %#x.\n", hr
);
1331 ok_(__FILE__
, line
)(stream
== expect
, "Expected stream %p, got %p.\n", expect
, stream
);
1332 ok_(__FILE__
, line
)(stream2
== expect
, "Expected stream %p, got %p.\n", expect
, stream2
);
1335 if (stream
) IMediaStream_Release(stream
);
1336 if (stream2
) IMediaStream_Release(stream2
);
1339 static void test_add_stream(void)
1341 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
1342 IMediaStream
*video_stream
, *audio_stream
, *stream
;
1343 IDirectDrawMediaStream
*ddraw_stream
;
1344 IMediaStreamFilter
*stream_filter
;
1345 struct teststream teststream
;
1346 IDirectDraw
*ddraw
, *ddraw2
;
1347 IEnumFilters
*enum_filters
;
1348 IBaseFilter
*filters
[3];
1349 IGraphBuilder
*graph
;
1355 teststream_init(&teststream
);
1357 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &stream_filter
);
1358 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1360 hr
= IAMMultiMediaStream_EnumMediaStreams(mmstream
, 0, NULL
);
1361 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1362 hr
= IMediaStreamFilter_EnumMediaStreams(stream_filter
, 0, NULL
);
1363 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1365 hr
= IAMMultiMediaStream_GetMediaStream(mmstream
, &MSPID_PrimaryAudio
, NULL
);
1366 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1367 hr
= IMediaStreamFilter_GetMediaStream(stream_filter
, &MSPID_PrimaryAudio
, NULL
);
1368 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1369 hr
= IAMMultiMediaStream_GetMediaStream(mmstream
, &MSPID_PrimaryVideo
, NULL
);
1370 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1371 hr
= IMediaStreamFilter_GetMediaStream(stream_filter
, &MSPID_PrimaryVideo
, NULL
);
1372 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1374 check_enum_stream(mmstream
, stream_filter
, 0, NULL
);
1376 check_get_stream(mmstream
, stream_filter
, NULL
, NULL
);
1377 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryAudio
, NULL
);
1378 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryVideo
, NULL
);
1379 check_get_stream(mmstream
, stream_filter
, &test_mspid
, NULL
);
1381 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &test_mspid
, 0, &stream
);
1382 ok(hr
== MS_E_PURPOSEID
, "Got hr %#x.\n", hr
);
1384 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &video_stream
);
1385 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1387 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
1388 ok(hr
== MS_E_PURPOSEID
, "Got hr %#x.\n", hr
);
1390 hr
= IAMMultiMediaStream_EnumMediaStreams(mmstream
, 0, NULL
);
1391 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1392 hr
= IMediaStreamFilter_EnumMediaStreams(stream_filter
, 0, NULL
);
1393 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1394 hr
= IAMMultiMediaStream_EnumMediaStreams(mmstream
, 1, NULL
);
1395 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1396 hr
= IMediaStreamFilter_EnumMediaStreams(stream_filter
, 1, NULL
);
1397 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1399 check_enum_stream(mmstream
, stream_filter
, 0, video_stream
);
1400 check_enum_stream(mmstream
, stream_filter
, 1, NULL
);
1402 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryVideo
, video_stream
);
1403 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryAudio
, NULL
);
1404 check_get_stream(mmstream
, stream_filter
, &test_mspid
, NULL
);
1406 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &audio_stream
);
1407 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1409 check_enum_stream(mmstream
, stream_filter
, 0, video_stream
);
1410 check_enum_stream(mmstream
, stream_filter
, 1, audio_stream
);
1411 check_enum_stream(mmstream
, stream_filter
, 2, NULL
);
1413 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryVideo
, video_stream
);
1414 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryAudio
, audio_stream
);
1415 check_get_stream(mmstream
, stream_filter
, &test_mspid
, NULL
);
1417 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)&teststream
, &IID_IUnknown
, 0, &stream
);
1418 ok(hr
== MS_E_PURPOSEID
, "Got hr %#x.\n", hr
);
1420 hr
= IMediaStreamFilter_QueryFilterInfo(stream_filter
, &info
);
1421 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1423 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)&teststream
, &test_mspid
, 0, &stream
);
1424 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1425 ok(stream
== (IMediaStream
*)&teststream
, "Streams didn't match.\n");
1426 IMediaStream_Release(stream
);
1427 ok(teststream
.mmstream
== mmstream
, "IAMMultiMediaStream objects didn't match.\n");
1428 ok(teststream
.filter
== stream_filter
, "IMediaStreamFilter objects didn't match.\n");
1429 ok(teststream
.graph
== info
.pGraph
, "IFilterGraph objects didn't match.\n");
1431 IFilterGraph_Release(info
.pGraph
);
1433 check_enum_stream(mmstream
, stream_filter
, 0, video_stream
);
1434 check_enum_stream(mmstream
, stream_filter
, 1, audio_stream
);
1435 check_enum_stream(mmstream
, stream_filter
, 2, (IMediaStream
*)&teststream
);
1436 check_enum_stream(mmstream
, stream_filter
, 3, NULL
);
1438 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryVideo
, video_stream
);
1439 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryAudio
, audio_stream
);
1440 check_get_stream(mmstream
, stream_filter
, &test_mspid
, (IMediaStream
*)&teststream
);
1442 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
1443 ok(hr
== MS_E_PURPOSEID
, "Got hr %#x.\n", hr
);
1445 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
1446 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1447 ok(!!graph
, "Expected a non-NULL graph.\n");
1449 hr
= IGraphBuilder_EnumFilters(graph
, &enum_filters
);
1450 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1451 hr
= IEnumFilters_Next(enum_filters
, 3, filters
, &count
);
1452 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1453 ok(count
== 1, "Got count %u.\n", count
);
1454 ok(filters
[0] == (IBaseFilter
*)stream_filter
,
1455 "Expected filter %p, got %p.\n", stream_filter
, filters
[0]);
1456 IBaseFilter_Release(filters
[0]);
1457 IEnumFilters_Release(enum_filters
);
1458 IGraphBuilder_Release(graph
);
1460 IMediaStreamFilter_Release(stream_filter
);
1461 ref
= IAMMultiMediaStream_Release(mmstream
);
1462 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1463 ref
= IMediaStream_Release(video_stream
);
1464 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1465 ref
= IMediaStream_Release(audio_stream
);
1466 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1467 ok(teststream
.refcount
== 1, "Got outstanding refcount %d.\n", teststream
.refcount
);
1469 /* The return parameter is optional. */
1471 mmstream
= create_ammultimediastream();
1473 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, NULL
);
1474 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1476 hr
= IAMMultiMediaStream_GetMediaStream(mmstream
, &MSPID_PrimaryVideo
, &stream
);
1477 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1478 IMediaStream_Release(stream
);
1480 ref
= IAMMultiMediaStream_Release(mmstream
);
1481 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1483 /* Test supplying a DirectDraw object with the primary video stream. */
1485 hr
= DirectDrawCreate(NULL
, &ddraw
, NULL
);
1486 ok(hr
== DD_OK
, "Got hr %#x.\n", hr
);
1487 mmstream
= create_ammultimediastream();
1489 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)ddraw
, &MSPID_PrimaryVideo
, 0, &video_stream
);
1490 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1492 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
1493 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1494 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw2
);
1495 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1496 ok(ddraw2
== ddraw
, "Expected IDirectDraw %p, got %p.\n", ddraw
, ddraw2
);
1497 IDirectDraw_Release(ddraw2
);
1498 IDirectDrawMediaStream_Release(ddraw_stream
);
1500 ref
= IAMMultiMediaStream_Release(mmstream
);
1501 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1502 ref
= IMediaStream_Release(video_stream
);
1503 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1504 ref
= IDirectDraw_Release(ddraw
);
1505 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1507 mmstream
= create_ammultimediastream();
1509 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &video_stream
);
1510 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1512 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
1513 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1514 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw
);
1515 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1516 ok(!!ddraw
, "Expected a non-NULL IDirectDraw.\n");
1517 IDirectDraw_Release(ddraw
);
1518 IDirectDrawMediaStream_Release(ddraw_stream
);
1520 ref
= IAMMultiMediaStream_Release(mmstream
);
1521 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1522 ref
= IMediaStream_Release(video_stream
);
1523 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1525 /* Test the AMMSF_ADDDEFAULTRENDERER flag. No stream is added; however, a
1526 * new filter will be added to the graph. */
1528 mmstream
= create_ammultimediastream();
1529 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &stream_filter
);
1530 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1532 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
,
1533 AMMSF_ADDDEFAULTRENDERER
, &video_stream
);
1534 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1536 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
,
1537 AMMSF_ADDDEFAULTRENDERER
, NULL
);
1538 ok(hr
== MS_E_PURPOSEID
, "Got hr %#x.\n", hr
);
1540 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
,
1541 AMMSF_ADDDEFAULTRENDERER
, &audio_stream
);
1542 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1544 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
,
1545 AMMSF_ADDDEFAULTRENDERER
, NULL
);
1546 ok(hr
== S_OK
|| hr
== VFW_E_NO_AUDIO_HARDWARE
, "Got hr %#x.\n", hr
);
1548 check_enum_stream(mmstream
, stream_filter
, 0, NULL
);
1550 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryAudio
, NULL
);
1551 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryVideo
, NULL
);
1555 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
1556 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1557 ok(!!graph
, "Got graph %p.\n", graph
);
1558 hr
= IGraphBuilder_EnumFilters(graph
, &enum_filters
);
1559 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1560 hr
= IEnumFilters_Next(enum_filters
, 3, filters
, &count
);
1561 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1562 ok(count
== 2, "Got count %u.\n", count
);
1563 ok(filters
[1] == (IBaseFilter
*)stream_filter
,
1564 "Expected filter %p, got %p.\n", stream_filter
, filters
[1]);
1565 hr
= IBaseFilter_GetClassID(filters
[0], &clsid
);
1566 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1567 ok(IsEqualGUID(&clsid
, &CLSID_DSoundRender
), "Got unexpected filter %s.\n", wine_dbgstr_guid(&clsid
));
1568 IBaseFilter_Release(filters
[0]);
1569 IBaseFilter_Release(filters
[1]);
1570 IEnumFilters_Release(enum_filters
);
1571 IGraphBuilder_Release(graph
);
1574 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &test_mspid
,
1575 AMMSF_ADDDEFAULTRENDERER
, NULL
);
1576 ok(hr
== MS_E_PURPOSEID
, "Got hr %#x.\n", hr
);
1577 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &test_mspid
,
1578 AMMSF_ADDDEFAULTRENDERER
, &audio_stream
);
1579 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1581 ref
= IAMMultiMediaStream_Release(mmstream
);
1582 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1583 ref
= IMediaStreamFilter_Release(stream_filter
);
1584 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1587 static void test_media_streams(void)
1589 IAMMultiMediaStream
*pams
;
1591 IMediaStream
*video_stream
= NULL
;
1592 IMediaStream
*audio_stream
= NULL
;
1593 IMediaStreamFilter
* media_stream_filter
= NULL
;
1595 if (!(pams
= create_ammultimediastream()))
1598 hr
= IAMMultiMediaStream_Initialize(pams
, STREAMTYPE_READ
, 0, NULL
);
1599 ok(hr
== S_OK
, "IAMMultiMediaStream_Initialize returned: %x\n", hr
);
1601 /* Retrieve media stream filter */
1602 hr
= IAMMultiMediaStream_GetFilter(pams
, NULL
);
1603 ok(hr
== E_POINTER
, "IAMMultiMediaStream_GetFilter returned: %x\n", hr
);
1604 hr
= IAMMultiMediaStream_GetFilter(pams
, &media_stream_filter
);
1605 ok(hr
== S_OK
, "IAMMultiMediaStream_GetFilter returned: %x\n", hr
);
1607 hr
= IAMMultiMediaStream_AddMediaStream(pams
, NULL
, &MSPID_PrimaryVideo
, 0, NULL
);
1608 ok(hr
== S_OK
, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr
);
1609 hr
= IAMMultiMediaStream_GetMediaStream(pams
, &MSPID_PrimaryVideo
, &video_stream
);
1610 ok(hr
== S_OK
, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr
);
1612 /* Check interfaces and samples for video */
1615 IAMMediaStream
* am_media_stream
;
1616 IMultiMediaStream
*multi_media_stream
;
1618 IAudioMediaStream
* audio_media_stream
;
1619 IDirectDrawMediaStream
*ddraw_stream
= NULL
;
1620 IDirectDrawStreamSample
*ddraw_sample
= NULL
;
1622 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IAMMediaStream
, (LPVOID
*)&am_media_stream
);
1623 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %x\n", hr
);
1624 ok((void*)am_media_stream
== (void*)video_stream
, "Not same interface, got %p expected %p\n", am_media_stream
, video_stream
);
1626 hr
= IAMMediaStream_GetMultiMediaStream(am_media_stream
, NULL
);
1627 ok(hr
== E_POINTER
, "Expected E_POINTER, got %x\n", hr
);
1629 multi_media_stream
= (void *)0xdeadbeef;
1630 hr
= IAMMediaStream_GetMultiMediaStream(am_media_stream
, &multi_media_stream
);
1631 ok(hr
== S_OK
, "IAMMediaStream_GetMultiMediaStream returned: %x\n", hr
);
1632 ok((void *)multi_media_stream
== (void *)pams
, "Expected %p, got %p\n", pams
, multi_media_stream
);
1633 IMultiMediaStream_Release(multi_media_stream
);
1635 IAMMediaStream_Release(am_media_stream
);
1637 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IPin
, (void **)&pin
);
1638 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %x\n", hr
);
1642 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IAudioMediaStream
, (LPVOID
*)&audio_media_stream
);
1643 ok(hr
== E_NOINTERFACE
, "IMediaStream_QueryInterface returned: %x\n", hr
);
1645 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IDirectDrawMediaStream
, (LPVOID
*)&ddraw_stream
);
1646 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %x\n", hr
);
1650 DDSURFACEDESC current_format
, desired_format
;
1651 IDirectDrawPalette
*palette
;
1654 hr
= IDirectDrawMediaStream_GetFormat(ddraw_stream
, ¤t_format
, &palette
, &desired_format
, &flags
);
1655 ok(hr
== MS_E_NOSTREAM
, "IDirectDrawoMediaStream_GetFormat returned: %x\n", hr
);
1657 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &ddraw_sample
);
1658 ok(hr
== S_OK
, "IDirectDrawMediaStream_CreateSample returned: %x\n", hr
);
1660 hr
= IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream
, NULL
);
1661 ok(hr
== E_POINTER
, "Expected E_POINTER, got %x\n", hr
);
1663 multi_media_stream
= (void *)0xdeadbeef;
1664 hr
= IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream
, &multi_media_stream
);
1665 ok(hr
== S_OK
, "IDirectDrawMediaStream_GetMultiMediaStream returned: %x\n", hr
);
1666 ok((void *)multi_media_stream
== (void *)pams
, "Expected %p, got %p\n", pams
, multi_media_stream
);
1667 IMultiMediaStream_Release(multi_media_stream
);
1671 IDirectDrawStreamSample_Release(ddraw_sample
);
1673 IDirectDrawMediaStream_Release(ddraw_stream
);
1676 hr
= IAMMultiMediaStream_AddMediaStream(pams
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
1677 ok(hr
== S_OK
, "IAMMultiMediaStream_AddMediaStream returned: %x\n", hr
);
1678 hr
= IAMMultiMediaStream_GetMediaStream(pams
, &MSPID_PrimaryAudio
, &audio_stream
);
1679 ok(hr
== S_OK
, "IAMMultiMediaStream_GetMediaStream returned: %x\n", hr
);
1681 /* Check interfaces and samples for audio */
1684 IAMMediaStream
* am_media_stream
;
1685 IMultiMediaStream
*multi_media_stream
;
1687 IDirectDrawMediaStream
* ddraw_stream
= NULL
;
1688 IAudioMediaStream
* audio_media_stream
= NULL
;
1689 IAudioStreamSample
*audio_sample
= NULL
;
1691 hr
= IMediaStream_QueryInterface(audio_stream
, &IID_IAMMediaStream
, (LPVOID
*)&am_media_stream
);
1692 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %x\n", hr
);
1693 ok((void*)am_media_stream
== (void*)audio_stream
, "Not same interface, got %p expected %p\n", am_media_stream
, audio_stream
);
1695 hr
= IAMMediaStream_GetMultiMediaStream(am_media_stream
, NULL
);
1696 ok(hr
== E_POINTER
, "Expected E_POINTER, got %x\n", hr
);
1698 multi_media_stream
= (void *)0xdeadbeef;
1699 hr
= IAMMediaStream_GetMultiMediaStream(am_media_stream
, &multi_media_stream
);
1700 ok(hr
== S_OK
, "IAMMediaStream_GetMultiMediaStream returned: %x\n", hr
);
1701 ok((void *)multi_media_stream
== (void *)pams
, "Expected %p, got %p\n", pams
, multi_media_stream
);
1702 IMultiMediaStream_Release(multi_media_stream
);
1704 IAMMediaStream_Release(am_media_stream
);
1706 hr
= IMediaStream_QueryInterface(audio_stream
, &IID_IPin
, (void **)&pin
);
1707 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %x\n", hr
);
1711 hr
= IMediaStream_QueryInterface(audio_stream
, &IID_IDirectDrawMediaStream
, (LPVOID
*)&ddraw_stream
);
1712 ok(hr
== E_NOINTERFACE
, "IMediaStream_QueryInterface returned: %x\n", hr
);
1714 hr
= IMediaStream_QueryInterface(audio_stream
, &IID_IAudioMediaStream
, (LPVOID
*)&audio_media_stream
);
1715 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %x\n", hr
);
1719 IAudioData
* audio_data
= NULL
;
1721 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
1722 ok(hr
== S_OK
, "CoCreateInstance returned: %x\n", hr
);
1724 hr
= IAudioMediaStream_CreateSample(audio_media_stream
, NULL
, 0, &audio_sample
);
1725 ok(hr
== E_POINTER
, "IAudioMediaStream_CreateSample returned: %x\n", hr
);
1727 EXPECT_REF(audio_stream
, 3);
1728 EXPECT_REF(audio_data
, 1);
1729 hr
= IAudioMediaStream_CreateSample(audio_media_stream
, audio_data
, 0, &audio_sample
);
1730 ok(hr
== S_OK
, "IAudioMediaStream_CreateSample returned: %x\n", hr
);
1731 EXPECT_REF(audio_stream
, 4);
1732 EXPECT_REF(audio_data
, 2);
1734 hr
= IAudioMediaStream_GetMultiMediaStream(audio_media_stream
, NULL
);
1735 ok(hr
== E_POINTER
, "Expected E_POINTER, got %x\n", hr
);
1737 multi_media_stream
= (void *)0xdeadbeef;
1738 hr
= IAudioMediaStream_GetMultiMediaStream(audio_media_stream
, &multi_media_stream
);
1739 ok(hr
== S_OK
, "IAudioMediaStream_GetMultiMediaStream returned: %x\n", hr
);
1740 ok((void *)multi_media_stream
== (void *)pams
, "Expected %p, got %p\n", pams
, multi_media_stream
);
1741 IMultiMediaStream_Release(multi_media_stream
);
1744 IAudioData_Release(audio_data
);
1746 IAudioStreamSample_Release(audio_sample
);
1747 if (audio_media_stream
)
1748 IAudioMediaStream_Release(audio_media_stream
);
1752 if (media_stream_filter
)
1754 IEnumPins
*enum_pins
;
1756 hr
= IMediaStreamFilter_EnumPins(media_stream_filter
, &enum_pins
);
1757 ok(hr
== S_OK
, "IBaseFilter_EnumPins returned: %x\n", hr
);
1760 IPin
* pins
[3] = { NULL
, NULL
, NULL
};
1762 ULONG expected_nb_pins
= audio_stream
? 2 : 1;
1765 hr
= IEnumPins_Next(enum_pins
, 3, pins
, &nb_pins
);
1766 ok(SUCCEEDED(hr
), "IEnumPins_Next returned: %x\n", hr
);
1767 ok(nb_pins
== expected_nb_pins
, "Number of pins is %u instead of %u\n", nb_pins
, expected_nb_pins
);
1768 for (i
= 0; i
< min(nb_pins
, expected_nb_pins
); i
++)
1772 hr
= IPin_ConnectedTo(pins
[i
], &pin
);
1773 ok(hr
== VFW_E_NOT_CONNECTED
, "IPin_ConnectedTo returned: %x\n", hr
);
1774 IPin_Release(pins
[i
]);
1776 IEnumPins_Release(enum_pins
);
1780 /* Test open file with no filename */
1781 hr
= IAMMultiMediaStream_OpenFile(pams
, NULL
, 0);
1782 ok(hr
== E_POINTER
, "IAMMultiMediaStream_OpenFile returned %x instead of %x\n", hr
, E_POINTER
);
1785 IMediaStream_Release(video_stream
);
1787 IMediaStream_Release(audio_stream
);
1788 if (media_stream_filter
)
1789 IMediaStreamFilter_Release(media_stream_filter
);
1791 IAMMultiMediaStream_Release(pams
);
1794 static void test_enum_pins(void)
1796 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
1797 IMediaStreamFilter
*filter
;
1798 IEnumPins
*enum1
, *enum2
;
1799 IMediaStream
*stream
;
1800 IPin
*pins
[3], *pin
;
1804 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
1805 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1807 ref
= get_refcount(filter
);
1808 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
1810 hr
= IMediaStreamFilter_EnumPins(filter
, NULL
);
1811 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1813 hr
= IMediaStreamFilter_EnumPins(filter
, &enum1
);
1814 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1815 ref
= get_refcount(filter
);
1816 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
1817 ref
= get_refcount(enum1
);
1818 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
1820 hr
= IEnumPins_Next(enum1
, 1, NULL
, NULL
);
1821 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1823 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
1824 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1826 hr
= IEnumPins_Reset(enum1
);
1827 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1829 hr
= IEnumPins_Skip(enum1
, 0);
1830 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1832 hr
= IEnumPins_Skip(enum1
, 1);
1833 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1835 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
1836 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1837 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
1838 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1840 /* Reset() isn't enough; we have to call EnumPins() again to see the updated
1842 hr
= IEnumPins_Reset(enum1
);
1843 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1845 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
1846 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1848 IEnumPins_Release(enum1
);
1850 hr
= IMediaStreamFilter_EnumPins(filter
, &enum1
);
1851 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1853 ref
= get_refcount(filter
);
1854 ok(ref
== 4, "Got unexpected refcount %d.\n", ref
);
1855 ref
= get_refcount(enum1
);
1856 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
1857 ref
= get_refcount(pin
);
1858 ok(ref
== 4, "Got unexpected refcount %d.\n", ref
);
1860 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
1861 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1862 ok(pins
[0] == pin
, "Expected pin %p, got %p.\n", pin
, pins
[0]);
1863 ref
= get_refcount(filter
);
1864 ok(ref
== 4, "Got unexpected refcount %d.\n", ref
);
1865 ref
= get_refcount(enum1
);
1866 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
1867 ref
= get_refcount(pin
);
1868 ok(ref
== 5, "Got unexpected refcount %d.\n", ref
);
1869 IPin_Release(pins
[0]);
1871 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
1872 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1874 hr
= IEnumPins_Reset(enum1
);
1875 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1877 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
1878 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1879 ok(count
== 1, "Got count %u.\n", count
);
1880 ok(pins
[0] == pin
, "Expected pin %p, got %p.\n", pin
, pins
[0]);
1881 IPin_Release(pins
[0]);
1883 hr
= IEnumPins_Reset(enum1
);
1884 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1886 hr
= IEnumPins_Next(enum1
, 2, pins
, NULL
);
1887 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1889 hr
= IEnumPins_Next(enum1
, 2, pins
, &count
);
1890 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1891 ok(count
== 1, "Got count %u.\n", count
);
1892 ok(pins
[0] == pin
, "Expected pin %p, got %p.\n", pin
, pins
[0]);
1893 IPin_Release(pins
[0]);
1895 hr
= IEnumPins_Reset(enum1
);
1896 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1898 hr
= IEnumPins_Clone(enum1
, &enum2
);
1899 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1901 hr
= IEnumPins_Skip(enum1
, 0);
1902 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1904 hr
= IEnumPins_Skip(enum1
, 1);
1905 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1907 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
1908 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1910 hr
= IEnumPins_Next(enum2
, 1, pins
, NULL
);
1911 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1912 ok(pins
[0] == pin
, "Expected pin %p, got %p.\n", pin
, pins
[0]);
1913 IPin_Release(pins
[0]);
1915 IEnumPins_Release(enum2
);
1916 IEnumPins_Release(enum1
);
1918 IMediaStreamFilter_Release(filter
);
1919 ref
= IAMMultiMediaStream_Release(mmstream
);
1920 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1921 IMediaStream_Release(stream
);
1922 ref
= IPin_Release(pin
);
1923 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1926 static void test_find_pin(void)
1928 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
1929 IMediaStreamFilter
*filter
;
1930 IMediaStream
*stream
;
1935 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
1936 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1938 hr
= IMediaStreamFilter_FindPin(filter
, primary_video_sink_id
, &pin2
);
1939 ok(hr
== VFW_E_NOT_FOUND
, "Got hr %#x.\n", hr
);
1941 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
1942 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1943 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
1944 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1946 hr
= IMediaStreamFilter_FindPin(filter
, primary_video_sink_id
, &pin2
);
1947 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1948 ok(pin2
== pin
, "Expected pin %p, got %p.\n", pin
, pin2
);
1952 IMediaStream_Release(stream
);
1953 IMediaStreamFilter_Release(filter
);
1954 ref
= IAMMultiMediaStream_Release(mmstream
);
1955 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1958 static void test_pin_info(void)
1960 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
1961 IMediaStreamFilter
*filter
;
1962 IMediaStream
*stream
;
1970 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
1971 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1973 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
1974 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1975 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
1976 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1978 hr
= IPin_QueryPinInfo(pin
, &info
);
1979 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1980 ok(info
.pFilter
== (IBaseFilter
*)filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
1981 ok(info
.dir
== PINDIR_INPUT
, "Got direction %d.\n", info
.dir
);
1982 ok(!wcscmp(info
.achName
, primary_video_sink_id
), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
1983 IBaseFilter_Release(info
.pFilter
);
1985 hr
= IPin_QueryDirection(pin
, &dir
);
1986 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1987 ok(dir
== PINDIR_INPUT
, "Got direction %d.\n", dir
);
1989 hr
= IPin_QueryId(pin
, &id
);
1990 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1991 ok(!wcscmp(id
, primary_video_sink_id
), "Got id %s.\n", wine_dbgstr_w(id
));
1994 hr
= IPin_QueryInternalConnections(pin
, NULL
, &count
);
1995 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
1998 IMediaStream_Release(stream
);
2000 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
2001 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2002 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2003 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2005 hr
= IPin_QueryPinInfo(pin
, &info
);
2006 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2007 ok(info
.pFilter
== (IBaseFilter
*)filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
2008 ok(info
.dir
== PINDIR_INPUT
, "Got direction %d.\n", info
.dir
);
2009 ok(!wcscmp(info
.achName
, primary_audio_sink_id
), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
2010 IBaseFilter_Release(info
.pFilter
);
2012 hr
= IPin_QueryDirection(pin
, &dir
);
2013 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2014 ok(dir
== PINDIR_INPUT
, "Got direction %d.\n", dir
);
2016 hr
= IPin_QueryId(pin
, &id
);
2017 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2018 ok(!wcscmp(id
, primary_audio_sink_id
), "Got id %s.\n", wine_dbgstr_w(id
));
2021 hr
= IPin_QueryInternalConnections(pin
, NULL
, &count
);
2022 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
2025 IMediaStream_Release(stream
);
2027 IMediaStreamFilter_Release(filter
);
2028 ref
= IAMMultiMediaStream_Release(mmstream
);
2029 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2034 IFilterGraph2 IFilterGraph2_iface
;
2035 IMediaEventSink IMediaEventSink_iface
;
2036 IUnknown
*inner_unk
;
2037 IFilterGraph2
*inner
;
2038 IMediaEventSink
*inner_event_sink
;
2040 unsigned int got_add_filter
;
2041 IBaseFilter
*filter
;
2042 WCHAR filter_name
[128];
2043 unsigned int got_notify
;
2045 LONG_PTR event_param1
;
2046 LONG_PTR event_param2
;
2049 static struct graph
*impl_from_IFilterGraph2(IFilterGraph2
*iface
)
2051 return CONTAINING_RECORD(iface
, struct graph
, IFilterGraph2_iface
);
2054 static struct graph
*impl_from_IMediaEventSink(IMediaEventSink
*iface
)
2056 return CONTAINING_RECORD(iface
, struct graph
, IMediaEventSink_iface
);
2059 static HRESULT WINAPI
graph_QueryInterface(IFilterGraph2
*iface
, REFIID iid
, void **out
)
2061 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2062 if (winetest_debug
> 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid
));
2063 if (IsEqualGUID(iid
, &IID_IFilterGraph2
)
2064 || IsEqualGUID(iid
, &IID_IGraphBuilder
)
2065 || IsEqualGUID(iid
, &IID_IFilterGraph
)
2066 || IsEqualGUID(iid
, &IID_IUnknown
))
2069 IFilterGraph2_AddRef(iface
);
2072 else if (IsEqualGUID(iid
, &IID_IMediaEventSink
))
2074 *out
= &graph
->IMediaEventSink_iface
;
2075 IFilterGraph2_AddRef(iface
);
2080 return IUnknown_QueryInterface(graph
->inner_unk
, iid
, out
);
2082 return E_NOINTERFACE
;
2085 static ULONG WINAPI
graph_AddRef(IFilterGraph2
*iface
)
2087 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2088 return InterlockedIncrement(&graph
->refcount
);
2091 static ULONG WINAPI
graph_Release(IFilterGraph2
*iface
)
2093 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2094 return InterlockedDecrement(&graph
->refcount
);
2097 static HRESULT WINAPI
graph_AddFilter(IFilterGraph2
*iface
, IBaseFilter
*filter
, const WCHAR
*name
)
2099 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2100 if (winetest_debug
> 1) trace("AddFilter(%p, %s)\n", filter
, wine_dbgstr_w(name
));
2101 ++graph
->got_add_filter
;
2102 graph
->filter
= filter
;
2104 wcscpy(graph
->filter_name
, name
);
2106 graph
->filter_name
[0] = 0;
2107 return IFilterGraph2_AddFilter(graph
->inner
, filter
, name
);
2110 static HRESULT WINAPI
graph_RemoveFilter(IFilterGraph2
*iface
, IBaseFilter
*filter
)
2112 ok(0, "Unexpected call.\n");
2116 static HRESULT WINAPI
graph_EnumFilters(IFilterGraph2
*iface
, IEnumFilters
**enumfilters
)
2118 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2119 if (winetest_debug
> 1) trace("EnumFilters()\n");
2120 return IFilterGraph2_EnumFilters(graph
->inner
, enumfilters
);
2123 static HRESULT WINAPI
graph_FindFilterByName(IFilterGraph2
*iface
, const WCHAR
*name
, IBaseFilter
**filter
)
2125 ok(0, "Unexpected call.\n");
2129 static HRESULT WINAPI
graph_ConnectDirect(IFilterGraph2
*iface
, IPin
*source
, IPin
*sink
, const AM_MEDIA_TYPE
*mt
)
2131 ok(0, "Unexpected call.\n");
2135 static HRESULT WINAPI
graph_Reconnect(IFilterGraph2
*iface
, IPin
*pin
)
2137 ok(0, "Unexpected call.\n");
2141 static HRESULT WINAPI
graph_Disconnect(IFilterGraph2
*iface
, IPin
*pin
)
2143 ok(0, "Unexpected call.\n");
2147 static HRESULT WINAPI
graph_SetDefaultSyncSource(IFilterGraph2
*iface
)
2149 ok(0, "Unexpected call.\n");
2153 static HRESULT WINAPI
graph_Connect(IFilterGraph2
*iface
, IPin
*source
, IPin
*sink
)
2155 ok(0, "Unexpected call.\n");
2159 static HRESULT WINAPI
graph_Render(IFilterGraph2
*iface
, IPin
*source
)
2161 ok(0, "Unexpected call.\n");
2165 static HRESULT WINAPI
graph_RenderFile(IFilterGraph2
*iface
, const WCHAR
*filename
, const WCHAR
*playlist
)
2167 ok(0, "Unexpected call.\n");
2171 static HRESULT WINAPI
graph_AddSourceFilter(IFilterGraph2
*iface
,
2172 const WCHAR
*filename
, const WCHAR
*filter_name
, IBaseFilter
**filter
)
2174 ok(0, "Unexpected call.\n");
2178 static HRESULT WINAPI
graph_SetLogFile(IFilterGraph2
*iface
, DWORD_PTR file
)
2180 ok(0, "Unexpected call.\n");
2184 static HRESULT WINAPI
graph_Abort(IFilterGraph2
*iface
)
2186 ok(0, "Unexpected call.\n");
2190 static HRESULT WINAPI
graph_ShouldOperationContinue(IFilterGraph2
*iface
)
2192 ok(0, "Unexpected call.\n");
2196 static HRESULT WINAPI
graph_AddSourceFilterForMoniker(IFilterGraph2
*iface
,
2197 IMoniker
*moniker
, IBindCtx
*bind_ctx
, const WCHAR
*filter_name
, IBaseFilter
**filter
)
2199 ok(0, "Unexpected call.\n");
2203 static HRESULT WINAPI
graph_ReconnectEx(IFilterGraph2
*iface
, IPin
*pin
, const AM_MEDIA_TYPE
*mt
)
2205 ok(0, "Unexpected call.\n");
2209 static HRESULT WINAPI
graph_RenderEx(IFilterGraph2
*iface
, IPin
*pin
, DWORD flags
, DWORD
*context
)
2211 ok(0, "Unexpected call.\n");
2215 static const IFilterGraph2Vtbl graph_vtbl
=
2217 graph_QueryInterface
,
2223 graph_FindFilterByName
,
2224 graph_ConnectDirect
,
2227 graph_SetDefaultSyncSource
,
2231 graph_AddSourceFilter
,
2234 graph_ShouldOperationContinue
,
2235 graph_AddSourceFilterForMoniker
,
2240 static HRESULT WINAPI
event_sink_QueryInterface(IMediaEventSink
*iface
, REFIID iid
, void **out
)
2242 struct graph
*graph
= impl_from_IMediaEventSink(iface
);
2243 return IFilterGraph2_QueryInterface(&graph
->IFilterGraph2_iface
, iid
, out
);
2246 static ULONG WINAPI
event_sink_AddRef(IMediaEventSink
*iface
)
2248 struct graph
*graph
= impl_from_IMediaEventSink(iface
);
2249 return IFilterGraph2_AddRef(&graph
->IFilterGraph2_iface
);
2252 static ULONG WINAPI
event_sink_Release(IMediaEventSink
*iface
)
2254 struct graph
*graph
= impl_from_IMediaEventSink(iface
);
2255 return IFilterGraph2_Release(&graph
->IFilterGraph2_iface
);
2258 static HRESULT WINAPI
event_sink_Notify(IMediaEventSink
*iface
,
2259 LONG code
, LONG_PTR param1
, LONG_PTR param2
)
2261 struct graph
*graph
= impl_from_IMediaEventSink(iface
);
2262 ++graph
->got_notify
;
2263 graph
->event_code
= code
;
2264 graph
->event_param1
= param1
;
2265 graph
->event_param2
= param2
;
2266 return IMediaEventSink_Notify(graph
->inner_event_sink
, code
, param1
, param2
);
2269 static const IMediaEventSinkVtbl event_sink_vtbl
=
2271 event_sink_QueryInterface
,
2277 static void graph_init(struct graph
*graph
)
2281 memset(graph
, 0, sizeof(*graph
));
2282 graph
->IFilterGraph2_iface
.lpVtbl
= &graph_vtbl
;
2283 graph
->IMediaEventSink_iface
.lpVtbl
= &event_sink_vtbl
;
2284 graph
->refcount
= 1;
2285 hr
= CoCreateInstance(&CLSID_FilterGraph
, (IUnknown
*)&graph
->IFilterGraph2_iface
, CLSCTX_INPROC_SERVER
,
2286 &IID_IUnknown
, (void **)&graph
->inner_unk
);
2287 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2288 hr
= IUnknown_QueryInterface(graph
->inner_unk
, &IID_IFilterGraph2
, (void **)&graph
->inner
);
2289 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2290 hr
= IUnknown_QueryInterface(graph
->inner_unk
, &IID_IMediaEventSink
, (void **)&graph
->inner_event_sink
);
2291 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2294 static void graph_destroy(struct graph
*graph
)
2298 IMediaEventSink_Release(graph
->inner_event_sink
);
2299 IFilterGraph2_Release(graph
->inner
);
2300 ref
= IUnknown_Release(graph
->inner_unk
);
2301 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2304 static void test_initialize(void)
2306 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
2307 IMediaStreamFilter
*filter
;
2308 IGraphBuilder
*ret_graph
;
2309 IMediaStream
*stream
;
2315 ret_graph
= (IGraphBuilder
*)0xdeadbeef;
2316 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2317 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2318 ok(!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2320 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
2321 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2322 ok(!!filter
, "Expected a non-NULL filter.");
2323 IMediaStreamFilter_Release(filter
);
2325 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2326 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2328 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2329 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2330 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_WRITE
, 0, NULL
);
2331 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2332 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2333 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2335 ret_graph
= (IGraphBuilder
*)0xdeadbeef;
2336 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2337 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2338 ok(!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2340 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2341 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2343 hr
= IMediaStream_GetInformation(stream
, NULL
, &type
);
2344 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2345 ok(type
== STREAMTYPE_READ
, "Got type %u.\n", type
);
2346 IMediaStream_Release(stream
);
2349 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2350 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2351 ok(!!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2352 IGraphBuilder_Release(ret_graph
);
2354 ref
= IAMMultiMediaStream_Release(mmstream
);
2355 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2357 mmstream
= create_ammultimediastream();
2359 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_WRITE
, 0, NULL
);
2360 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2362 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_WRITE
, 0, NULL
);
2363 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2364 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2365 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2366 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2367 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2369 ret_graph
= (IGraphBuilder
*)0xdeadbeef;
2370 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2371 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2372 ok(!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2374 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2375 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2377 hr
= IMediaStream_GetInformation(stream
, NULL
, &type
);
2378 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2379 ok(type
== STREAMTYPE_WRITE
, "Got type %u.\n", type
);
2380 IMediaStream_Release(stream
);
2382 ref
= IAMMultiMediaStream_Release(mmstream
);
2383 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2385 mmstream
= create_ammultimediastream();
2387 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2388 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2390 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2391 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2392 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2393 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2394 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_WRITE
, 0, NULL
);
2395 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2397 ret_graph
= (IGraphBuilder
*)0xdeadbeef;
2398 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2399 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2400 ok(!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2402 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2403 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2405 hr
= IMediaStream_GetInformation(stream
, NULL
, &type
);
2406 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2407 ok(type
== STREAMTYPE_TRANSFORM
, "Got type %u.\n", type
);
2408 IMediaStream_Release(stream
);
2410 ref
= IAMMultiMediaStream_Release(mmstream
);
2411 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2413 mmstream
= create_ammultimediastream();
2415 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2416 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2419 hr
= IMediaStream_GetInformation(stream
, NULL
, &type
);
2420 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2421 ok(type
== STREAMTYPE_READ
, "Got type %u.\n", type
);
2424 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2425 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2426 ok(!!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2427 IGraphBuilder_Release(ret_graph
);
2429 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2430 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2433 hr
= IMediaStream_GetInformation(stream
, NULL
, &type
);
2434 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2435 ok(type
== STREAMTYPE_READ
, "Got type %u.\n", type
);
2437 IMediaStream_Release(stream
);
2438 ref
= IAMMultiMediaStream_Release(mmstream
);
2439 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2441 /* Test with a custom filter graph. */
2443 mmstream
= create_ammultimediastream();
2447 ret_graph
= (IGraphBuilder
*)0xdeadbeef;
2448 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2449 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2450 ok(!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2452 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
2453 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2454 ok(!!filter
, "Expected a non-NULL filter.");
2456 graph
.got_add_filter
= 0;
2457 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, (IGraphBuilder
*)&graph
.IFilterGraph2_iface
);
2458 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2459 ok(graph
.got_add_filter
== 1, "Got %d calls to IGraphBuilder::AddFilter().\n", graph
.got_add_filter
);
2460 ok(graph
.filter
== (IBaseFilter
*)filter
, "Got filter %p.\n", filter
);
2461 ok(!wcscmp(graph
.filter_name
, L
"MediaStreamFilter"), "Got unexpected name %s.\n", wine_dbgstr_w(graph
.filter_name
));
2463 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2464 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2465 ok(ret_graph
== (IGraphBuilder
*)&graph
, "Got unexpected graph %p.\n", ret_graph
);
2466 IGraphBuilder_Release(ret_graph
);
2468 graph
.got_add_filter
= 0;
2469 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
2470 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2471 ok(!graph
.got_add_filter
, "Got %d calls to IGraphBuilder::AddFilter().\n", graph
.got_add_filter
);
2473 graph
.got_add_filter
= 0;
2474 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, NULL
);
2475 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2476 ok(!graph
.got_add_filter
, "Got %d calls to IGraphBuilder::AddFilter().\n", graph
.got_add_filter
);
2478 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, (IGraphBuilder
*)&graph
);
2479 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2480 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2481 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2482 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_WRITE
, 0, NULL
);
2483 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2484 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2485 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2487 IMediaStreamFilter_Release(filter
);
2488 ref
= IAMMultiMediaStream_Release(mmstream
);
2489 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2491 graph_destroy(&graph
);
2494 static IAMMultiMediaStream
*mmstream_mmstream
;
2495 static STREAM_STATE mmstream_state
;
2497 static DWORD CALLBACK
mmstream_set_state(void *param
)
2501 hr
= IAMMultiMediaStream_SetState(mmstream_mmstream
, mmstream_state
);
2502 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2507 static void test_set_state(void)
2509 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
2510 IMediaControl
*media_control
;
2511 struct testfilter source
;
2512 IGraphBuilder
*graph
;
2518 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2519 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2520 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
2521 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2522 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
2523 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2524 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
2525 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaControl
, (void **)&media_control
);
2526 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2527 testfilter_init(&source
);
2529 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
2530 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2532 source
.init_stream_hr
= E_FAIL
;
2533 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2534 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
2535 source
.init_stream_hr
= S_OK
;
2536 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2537 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2539 source
.init_stream_hr
= S_FALSE
;
2540 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2541 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2542 source
.init_stream_hr
= S_OK
;
2543 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2544 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2546 source
.wait_state_hr
= E_FAIL
;
2547 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2548 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2549 source
.wait_state_hr
= S_OK
;
2550 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2551 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2553 source
.wait_state_hr
= VFW_S_STATE_INTERMEDIATE
;
2554 ResetEvent(source
.wait_state_event
);
2556 mmstream_mmstream
= mmstream
;
2557 mmstream_state
= STREAMSTATE_RUN
;
2558 thread
= CreateThread(NULL
, 0, mmstream_set_state
, NULL
, 0, NULL
);
2560 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "SetState returned prematurely.\n");
2562 EnterCriticalSection(&source
.filter
.filter_cs
);
2563 source
.wait_state_hr
= S_OK
;
2564 SetEvent(source
.wait_state_event
);
2565 LeaveCriticalSection(&source
.filter
.filter_cs
);
2567 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
2568 CloseHandle(thread
);
2570 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2571 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2573 source
.init_stream_hr
= E_FAIL
;
2574 source
.wait_state_hr
= VFW_S_STATE_INTERMEDIATE
;
2575 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2576 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
2577 source
.init_stream_hr
= S_OK
;
2578 source
.wait_state_hr
= S_OK
;
2579 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2580 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2582 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2583 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2584 source
.cleanup_stream_hr
= E_FAIL
;
2585 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2586 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
2587 source
.cleanup_stream_hr
= S_OK
;
2588 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2589 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2591 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2592 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2593 source
.cleanup_stream_hr
= S_FALSE
;
2594 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2595 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2596 source
.cleanup_stream_hr
= S_OK
;
2598 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2599 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2600 source
.wait_state_hr
= VFW_S_STATE_INTERMEDIATE
;
2601 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2602 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2603 source
.wait_state_hr
= S_OK
;
2605 /* Crashes on native. */
2608 hr
= IAMMultiMediaStream_GetState(mmstream
, NULL
);
2609 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2613 hr
= IAMMultiMediaStream_GetState(mmstream
, &state
);
2614 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2615 ok(state
== STREAMSTATE_STOP
, "Got state %#x.\n", state
);
2617 hr
= IMediaControl_Run(media_control
);
2618 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2621 hr
= IAMMultiMediaStream_GetState(mmstream
, &state
);
2622 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2623 ok(state
== STREAMSTATE_STOP
, "Got state %#x.\n", state
);
2625 hr
= IMediaControl_Stop(media_control
);
2626 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2628 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2629 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2632 hr
= IAMMultiMediaStream_GetState(mmstream
, &state
);
2633 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2634 ok(state
== STREAMSTATE_RUN
, "Got state %#x.\n", state
);
2636 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2637 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2640 hr
= IAMMultiMediaStream_GetState(mmstream
, &state
);
2641 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2642 ok(state
== STREAMSTATE_STOP
, "Got state %#x.\n", state
);
2644 source
.init_stream_hr
= E_FAIL
;
2645 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2646 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
2649 hr
= IAMMultiMediaStream_GetState(mmstream
, &state
);
2650 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2651 ok(state
== STREAMSTATE_STOP
, "Got state %#x.\n", state
);
2653 ref
= IAMMultiMediaStream_Release(mmstream
);
2654 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2655 IMediaControl_Release(media_control
);
2656 ref
= IGraphBuilder_Release(graph
);
2657 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2660 static void test_enum_media_types(void)
2662 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
2663 IEnumMediaTypes
*enum1
, *enum2
;
2664 AM_MEDIA_TYPE
*mts
[2];
2665 IMediaStream
*stream
;
2670 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2671 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2672 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2673 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2675 hr
= IPin_EnumMediaTypes(pin
, &enum1
);
2676 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2678 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
2679 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2681 hr
= IEnumMediaTypes_Next(enum1
, 0, mts
, &count
);
2682 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2683 ok(!count
, "Got count %u.\n", count
);
2685 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2686 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2687 ok(count
== 1, "Got count %u.\n", count
);
2688 CoTaskMemFree(mts
[0]);
2690 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2691 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2692 ok(!count
, "Got count %u.\n", count
);
2694 hr
= IEnumMediaTypes_Reset(enum1
);
2695 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2697 hr
= IEnumMediaTypes_Next(enum1
, 2, mts
, &count
);
2698 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2699 ok(count
== 1, "Got count %u.\n", count
);
2700 CoTaskMemFree(mts
[0]);
2702 hr
= IEnumMediaTypes_Reset(enum1
);
2703 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2705 hr
= IEnumMediaTypes_Clone(enum1
, &enum2
);
2706 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2708 hr
= IEnumMediaTypes_Skip(enum1
, 2);
2709 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2711 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2712 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2713 ok(!count
, "Got count %u.\n", count
);
2715 hr
= IEnumMediaTypes_Next(enum2
, 1, mts
, &count
);
2716 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2717 ok(count
== 1, "Got count %u.\n", count
);
2718 CoTaskMemFree(mts
[0]);
2720 IEnumMediaTypes_Release(enum2
);
2721 IEnumMediaTypes_Release(enum1
);
2723 IMediaStream_Release(stream
);
2725 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
2726 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2727 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2728 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2730 hr
= IPin_EnumMediaTypes(pin
, &enum1
);
2731 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2733 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
2734 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2736 hr
= IEnumMediaTypes_Next(enum1
, 0, mts
, &count
);
2737 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2738 ok(!count
, "Got count %u.\n", count
);
2740 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2741 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2742 ok(count
== 1, "Got count %u.\n", count
);
2743 CoTaskMemFree(mts
[0]->pbFormat
);
2744 CoTaskMemFree(mts
[0]);
2746 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2747 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2748 ok(!count
, "Got count %u.\n", count
);
2750 hr
= IEnumMediaTypes_Reset(enum1
);
2751 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2753 hr
= IEnumMediaTypes_Next(enum1
, 2, mts
, &count
);
2754 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2755 ok(count
== 1, "Got count %u.\n", count
);
2756 CoTaskMemFree(mts
[0]->pbFormat
);
2757 CoTaskMemFree(mts
[0]);
2759 hr
= IEnumMediaTypes_Reset(enum1
);
2760 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2762 hr
= IEnumMediaTypes_Clone(enum1
, &enum2
);
2763 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2765 hr
= IEnumMediaTypes_Skip(enum1
, 2);
2766 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2768 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2769 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2770 ok(!count
, "Got count %u.\n", count
);
2772 hr
= IEnumMediaTypes_Next(enum2
, 1, mts
, &count
);
2773 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2774 ok(count
== 1, "Got count %u.\n", count
);
2775 CoTaskMemFree(mts
[0]->pbFormat
);
2776 CoTaskMemFree(mts
[0]);
2778 IEnumMediaTypes_Release(enum2
);
2779 IEnumMediaTypes_Release(enum1
);
2781 IMediaStream_Release(stream
);
2783 ref
= IAMMultiMediaStream_Release(mmstream
);
2784 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2787 static void test_media_types(void)
2789 static const VIDEOINFOHEADER2 req_vih2
;
2790 static const VIDEOINFOHEADER req_vih
;
2791 static const MPEG2VIDEOINFO req_m2vi
;
2792 static const MPEG1VIDEOINFO req_m1vi
;
2793 static const WAVEFORMATEX req_wfx
;
2794 static const WAVEFORMATEX expect_wfx
=
2796 .wFormatTag
= WAVE_FORMAT_PCM
,
2798 .nSamplesPerSec
= 11025,
2799 .nAvgBytesPerSec
= 11025 * 2,
2801 .wBitsPerSample
= 16,
2804 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
2805 IEnumMediaTypes
*enummt
;
2806 IMediaStream
*stream
;
2821 {&GUID_NULL
, NULL
, 0 },
2822 {&FORMAT_None
, NULL
, 0 },
2823 {&FORMAT_WaveFormatEx
, (BYTE
*)&req_wfx
, sizeof(WAVEFORMATEX
)},
2824 {&FORMAT_MPEG2Video
, (BYTE
*)&req_m2vi
, sizeof(MPEG2VIDEOINFO
)},
2825 {&FORMAT_MPEGVideo
, (BYTE
*)&req_m1vi
, sizeof(MPEG2VIDEOINFO
)},
2826 {&FORMAT_VideoInfo2
, (BYTE
*)&req_vih2
, sizeof(VIDEOINFOHEADER2
)},
2827 {&FORMAT_VideoInfo
, (BYTE
*)&req_vih
, sizeof(VIDEOINFOHEADER
)},
2830 static const GUID
*rejected_subtypes
[] =
2834 &MEDIASUBTYPE_RGB565
,
2835 &MEDIASUBTYPE_RGB555
,
2836 &MEDIASUBTYPE_RGB24
,
2837 &MEDIASUBTYPE_RGB32
,
2838 &MEDIASUBTYPE_ARGB32
,
2839 &MEDIASUBTYPE_ARGB1555
,
2840 &MEDIASUBTYPE_ARGB4444
,
2852 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2853 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2854 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2855 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2857 hr
= IPin_EnumMediaTypes(pin
, &enummt
);
2858 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2860 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, NULL
);
2861 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2863 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, &count
);
2864 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2865 ok(count
== 1, "Got count %u.\n", count
);
2866 ok(IsEqualGUID(&pmt
->majortype
, &MEDIATYPE_Video
), "Got major type %s\n",
2867 wine_dbgstr_guid(&pmt
->majortype
));
2868 ok(IsEqualGUID(&pmt
->subtype
, &MEDIASUBTYPE_RGB8
), "Got subtype %s\n",
2869 wine_dbgstr_guid(&pmt
->subtype
));
2870 ok(pmt
->bFixedSizeSamples
== TRUE
, "Got fixed size %d.\n", pmt
->bFixedSizeSamples
);
2871 ok(!pmt
->bTemporalCompression
, "Got temporal compression %d.\n", pmt
->bTemporalCompression
);
2872 ok(pmt
->lSampleSize
== 10000, "Got sample size %u.\n", pmt
->lSampleSize
);
2873 ok(IsEqualGUID(&pmt
->formattype
, &GUID_NULL
), "Got format type %s.\n",
2874 wine_dbgstr_guid(&pmt
->formattype
));
2875 ok(!pmt
->pUnk
, "Got pUnk %p.\n", pmt
->pUnk
);
2877 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
2879 pmt
->formattype
= *tests
[i
].type
;
2880 pmt
->cbFormat
= tests
[i
].size
;
2881 pmt
->pbFormat
= tests
[i
].format
;
2882 hr
= IPin_QueryAccept(pin
, pmt
);
2883 ok(hr
== (i
== 6 ? S_OK
: VFW_E_TYPE_NOT_ACCEPTED
), "Got hr %#x.\n", hr
);
2886 pmt
->bFixedSizeSamples
= FALSE
;
2887 pmt
->bTemporalCompression
= TRUE
;
2888 pmt
->lSampleSize
= 123;
2889 hr
= IPin_QueryAccept(pin
, pmt
);
2890 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2892 pmt
->majortype
= MEDIATYPE_NULL
;
2893 hr
= IPin_QueryAccept(pin
, pmt
);
2894 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
2895 pmt
->majortype
= MEDIATYPE_Audio
;
2896 hr
= IPin_QueryAccept(pin
, pmt
);
2897 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
2898 pmt
->majortype
= MEDIATYPE_Stream
;
2899 hr
= IPin_QueryAccept(pin
, pmt
);
2900 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
2901 pmt
->majortype
= MEDIATYPE_Video
;
2903 for (i
= 0; i
< ARRAY_SIZE(rejected_subtypes
); ++i
)
2905 pmt
->subtype
= *rejected_subtypes
[i
];
2906 hr
= IPin_QueryAccept(pin
, pmt
);
2907 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x for subtype %s.\n",
2908 hr
, wine_dbgstr_guid(rejected_subtypes
[i
]));
2913 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, &count
);
2914 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2916 IEnumMediaTypes_Release(enummt
);
2918 IMediaStream_Release(stream
);
2920 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
2921 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2922 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2923 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2925 hr
= IPin_EnumMediaTypes(pin
, &enummt
);
2926 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2928 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, NULL
);
2929 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2931 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, &count
);
2932 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2933 ok(count
== 1, "Got count %u.\n", count
);
2934 ok(IsEqualGUID(&pmt
->majortype
, &MEDIATYPE_Audio
), "Got major type %s\n",
2935 wine_dbgstr_guid(&pmt
->majortype
));
2936 ok(IsEqualGUID(&pmt
->subtype
, &GUID_NULL
), "Got subtype %s\n",
2937 wine_dbgstr_guid(&pmt
->subtype
));
2938 ok(pmt
->bFixedSizeSamples
== TRUE
, "Got fixed size %d.\n", pmt
->bFixedSizeSamples
);
2939 ok(!pmt
->bTemporalCompression
, "Got temporal compression %d.\n", pmt
->bTemporalCompression
);
2940 ok(pmt
->lSampleSize
== 2, "Got sample size %u.\n", pmt
->lSampleSize
);
2941 ok(IsEqualGUID(&pmt
->formattype
, &FORMAT_WaveFormatEx
), "Got format type %s.\n",
2942 wine_dbgstr_guid(&pmt
->formattype
));
2943 ok(!pmt
->pUnk
, "Got pUnk %p.\n", pmt
->pUnk
);
2944 ok(pmt
->cbFormat
== sizeof(WAVEFORMATEX
), "Got format size %u.\n", pmt
->cbFormat
);
2945 ok(!memcmp(pmt
->pbFormat
, &expect_wfx
, pmt
->cbFormat
), "Format blocks didn't match.\n");
2947 hr
= IPin_QueryAccept(pin
, pmt
);
2948 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
2950 CoTaskMemFree(pmt
->pbFormat
);
2953 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, &count
);
2954 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2956 IEnumMediaTypes_Release(enummt
);
2958 IMediaStream_Release(stream
);
2960 ref
= IAMMultiMediaStream_Release(mmstream
);
2961 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2964 static IUnknown
*create_audio_data(void)
2966 IUnknown
*audio_data
= NULL
;
2967 HRESULT result
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
,
2968 &IID_IUnknown
, (void **)&audio_data
);
2969 ok(S_OK
== result
, "got 0x%08x\n", result
);
2973 static void test_audiodata_query_interface(void)
2975 IUnknown
*unknown
= create_audio_data();
2976 IMemoryData
*memory_data
= NULL
;
2977 IAudioData
*audio_data
= NULL
;
2981 result
= IUnknown_QueryInterface(unknown
, &IID_IMemoryData
, (void **)&memory_data
);
2982 ok(E_NOINTERFACE
== result
, "got 0x%08x\n", result
);
2984 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
2985 ok(S_OK
== result
, "got 0x%08x\n", result
);
2988 result
= IAudioData_QueryInterface(audio_data
, &IID_IMemoryData
, (void **)&memory_data
);
2989 ok(E_NOINTERFACE
== result
, "got 0x%08x\n", result
);
2991 IAudioData_Release(audio_data
);
2994 IUnknown_Release(unknown
);
2997 static void test_audiodata_get_info(void)
2999 IUnknown
*unknown
= create_audio_data();
3000 IAudioData
*audio_data
= NULL
;
3004 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3007 /* test_audiodata_query_interface handles this case */
3008 skip("No IAudioData\n");
3012 result
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, NULL
);
3013 ok(MS_E_NOTINIT
== result
, "got 0x%08x\n", result
);
3015 IAudioData_Release(audio_data
);
3018 IUnknown_Release(unknown
);
3021 static void test_audiodata_set_buffer(void)
3023 IUnknown
*unknown
= create_audio_data();
3024 IAudioData
*audio_data
= NULL
;
3025 BYTE buffer
[100] = {0};
3031 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3034 /* test_audiodata_query_interface handles this case */
3035 skip("No IAudioData\n");
3039 result
= IAudioData_SetBuffer(audio_data
, 100, NULL
, 0);
3040 ok(S_OK
== result
, "got 0x%08x\n", result
);
3042 data
= (BYTE
*)0xdeadbeef;
3043 length
= 0xdeadbeef;
3044 result
= IAudioData_GetInfo(audio_data
, &length
, &data
, NULL
);
3045 ok(S_OK
== result
, "got 0x%08x\n", result
);
3046 ok(100 == length
, "got %u\n", length
);
3047 ok(NULL
!= data
, "got %p\n", data
);
3049 result
= IAudioData_SetBuffer(audio_data
, 0, buffer
, 0);
3050 ok(E_INVALIDARG
== result
, "got 0x%08x\n", result
);
3052 result
= IAudioData_SetBuffer(audio_data
, sizeof(buffer
), buffer
, 0);
3053 ok(S_OK
== result
, "got 0x%08x\n", result
);
3055 data
= (BYTE
*)0xdeadbeef;
3056 length
= 0xdeadbeef;
3057 result
= IAudioData_GetInfo(audio_data
, &length
, &data
, NULL
);
3058 ok(S_OK
== result
, "got 0x%08x\n", result
);
3059 ok(sizeof(buffer
) == length
, "got %u\n", length
);
3060 ok(buffer
== data
, "got %p\n", data
);
3062 IAudioData_Release(audio_data
);
3065 IUnknown_Release(unknown
);
3068 static void test_audiodata_set_actual(void)
3070 IUnknown
*unknown
= create_audio_data();
3071 IAudioData
*audio_data
= NULL
;
3072 BYTE buffer
[100] = {0};
3073 DWORD actual_data
= 0;
3077 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3080 /* test_audiodata_query_interface handles this case */
3081 skip("No IAudioData\n");
3085 result
= IAudioData_SetActual(audio_data
, 0);
3086 ok(S_OK
== result
, "got 0x%08x\n", result
);
3088 result
= IAudioData_SetBuffer(audio_data
, sizeof(buffer
), buffer
, 0);
3089 ok(S_OK
== result
, "got 0x%08x\n", result
);
3091 result
= IAudioData_SetActual(audio_data
, sizeof(buffer
) + 1);
3092 ok(E_INVALIDARG
== result
, "got 0x%08x\n", result
);
3094 result
= IAudioData_SetActual(audio_data
, sizeof(buffer
));
3095 ok(S_OK
== result
, "got 0x%08x\n", result
);
3097 actual_data
= 0xdeadbeef;
3098 result
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_data
);
3099 ok(S_OK
== result
, "got 0x%08x\n", result
);
3100 ok(sizeof(buffer
) == actual_data
, "got %u\n", actual_data
);
3102 result
= IAudioData_SetActual(audio_data
, 0);
3103 ok(S_OK
== result
, "got 0x%08x\n", result
);
3105 actual_data
= 0xdeadbeef;
3106 result
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_data
);
3107 ok(S_OK
== result
, "got 0x%08x\n", result
);
3108 ok(0 == actual_data
, "got %u\n", actual_data
);
3110 IAudioData_Release(audio_data
);
3113 IUnknown_Release(unknown
);
3116 static void test_audiodata_get_format(void)
3118 IUnknown
*unknown
= create_audio_data();
3119 IAudioData
*audio_data
= NULL
;
3120 WAVEFORMATEX wave_format
= {0};
3124 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3127 /* test_audiodata_query_interface handles this case */
3128 skip("No IAudioData\n");
3132 result
= IAudioData_GetFormat(audio_data
, NULL
);
3133 ok(E_POINTER
== result
, "got 0x%08x\n", result
);
3135 wave_format
.wFormatTag
= 0xdead;
3136 wave_format
.nChannels
= 0xdead;
3137 wave_format
.nSamplesPerSec
= 0xdeadbeef;
3138 wave_format
.nAvgBytesPerSec
= 0xdeadbeef;
3139 wave_format
.nBlockAlign
= 0xdead;
3140 wave_format
.wBitsPerSample
= 0xdead;
3141 wave_format
.cbSize
= 0xdead;
3142 result
= IAudioData_GetFormat(audio_data
, &wave_format
);
3143 ok(S_OK
== result
, "got 0x%08x\n", result
);
3144 ok(WAVE_FORMAT_PCM
== wave_format
.wFormatTag
, "got %u\n", wave_format
.wFormatTag
);
3145 ok(1 == wave_format
.nChannels
, "got %u\n", wave_format
.nChannels
);
3146 ok(11025 == wave_format
.nSamplesPerSec
, "got %u\n", wave_format
.nSamplesPerSec
);
3147 ok(22050 == wave_format
.nAvgBytesPerSec
, "got %u\n", wave_format
.nAvgBytesPerSec
);
3148 ok(2 == wave_format
.nBlockAlign
, "got %u\n", wave_format
.nBlockAlign
);
3149 ok(16 == wave_format
.wBitsPerSample
, "got %u\n", wave_format
.wBitsPerSample
);
3150 ok(0 == wave_format
.cbSize
, "got %u\n", wave_format
.cbSize
);
3152 IAudioData_Release(audio_data
);
3155 IUnknown_Release(unknown
);
3158 static void test_audiodata_set_format(void)
3160 IUnknown
*unknown
= create_audio_data();
3161 IAudioData
*audio_data
= NULL
;
3162 WAVEFORMATPCMEX wave_format
= {{0}};
3166 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3169 /* test_audiodata_query_interface handles this case */
3170 skip("No IAudioData\n");
3174 result
= IAudioData_SetFormat(audio_data
, NULL
);
3175 ok(E_POINTER
== result
, "got 0x%08x\n", result
);
3177 wave_format
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
3178 wave_format
.Format
.nChannels
= 2;
3179 wave_format
.Format
.nSamplesPerSec
= 44100;
3180 wave_format
.Format
.nAvgBytesPerSec
= 176400;
3181 wave_format
.Format
.nBlockAlign
= 4;
3182 wave_format
.Format
.wBitsPerSample
= 16;
3183 wave_format
.Format
.cbSize
= 22;
3184 wave_format
.Samples
.wValidBitsPerSample
= 16;
3185 wave_format
.dwChannelMask
= KSAUDIO_SPEAKER_STEREO
;
3186 wave_format
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
3187 result
= IAudioData_SetFormat(audio_data
, &wave_format
.Format
);
3188 ok(E_INVALIDARG
== result
, "got 0x%08x\n", result
);
3190 wave_format
.Format
.wFormatTag
= WAVE_FORMAT_PCM
;
3191 wave_format
.Format
.nChannels
= 2;
3192 wave_format
.Format
.nSamplesPerSec
= 44100;
3193 wave_format
.Format
.nAvgBytesPerSec
= 176400;
3194 wave_format
.Format
.nBlockAlign
= 4;
3195 wave_format
.Format
.wBitsPerSample
= 16;
3196 wave_format
.Format
.cbSize
= 0;
3197 result
= IAudioData_SetFormat(audio_data
, &wave_format
.Format
);
3198 ok(S_OK
== result
, "got 0x%08x\n", result
);
3200 wave_format
.Format
.wFormatTag
= 0xdead;
3201 wave_format
.Format
.nChannels
= 0xdead;
3202 wave_format
.Format
.nSamplesPerSec
= 0xdeadbeef;
3203 wave_format
.Format
.nAvgBytesPerSec
= 0xdeadbeef;
3204 wave_format
.Format
.nBlockAlign
= 0xdead;
3205 wave_format
.Format
.wBitsPerSample
= 0xdead;
3206 wave_format
.Format
.cbSize
= 0xdead;
3207 result
= IAudioData_GetFormat(audio_data
, &wave_format
.Format
);
3208 ok(S_OK
== result
, "got 0x%08x\n", result
);
3209 ok(WAVE_FORMAT_PCM
== wave_format
.Format
.wFormatTag
, "got %u\n", wave_format
.Format
.wFormatTag
);
3210 ok(2 == wave_format
.Format
.nChannels
, "got %u\n", wave_format
.Format
.nChannels
);
3211 ok(44100 == wave_format
.Format
.nSamplesPerSec
, "got %u\n", wave_format
.Format
.nSamplesPerSec
);
3212 ok(176400 == wave_format
.Format
.nAvgBytesPerSec
, "got %u\n", wave_format
.Format
.nAvgBytesPerSec
);
3213 ok(4 == wave_format
.Format
.nBlockAlign
, "got %u\n", wave_format
.Format
.nBlockAlign
);
3214 ok(16 == wave_format
.Format
.wBitsPerSample
, "got %u\n", wave_format
.Format
.wBitsPerSample
);
3215 ok(0 == wave_format
.Format
.cbSize
, "got %u\n", wave_format
.Format
.cbSize
);
3217 IAudioData_Release(audio_data
);
3220 IUnknown_Release(unknown
);
3223 struct advise_time_cookie
3228 HANDLE advise_time_called_event
;
3229 BOOL unadvise_called
;
3234 IReferenceClock IReferenceClock_iface
;
3237 struct advise_time_cookie
*advise_time_cookie
;
3238 HRESULT get_time_hr
;
3241 static inline struct testclock
*impl_from_IReferenceClock(IReferenceClock
*iface
)
3243 return CONTAINING_RECORD(iface
, struct testclock
, IReferenceClock_iface
);
3246 static HRESULT WINAPI
testclock_QueryInterface(IReferenceClock
*iface
, REFIID iid
, void **out
)
3248 if (winetest_debug
> 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid
));
3249 if (IsEqualGUID(iid
, &IID_IReferenceClock
)
3250 || IsEqualGUID(iid
, &IID_IUnknown
))
3253 IReferenceClock_AddRef(iface
);
3256 return E_NOINTERFACE
;
3259 static ULONG WINAPI
testclock_AddRef(IReferenceClock
*iface
)
3261 struct testclock
*clock
= impl_from_IReferenceClock(iface
);
3262 return InterlockedIncrement(&clock
->refcount
);
3265 static ULONG WINAPI
testclock_Release(IReferenceClock
*iface
)
3267 struct testclock
*clock
= impl_from_IReferenceClock(iface
);
3268 return InterlockedDecrement(&clock
->refcount
);
3271 static HRESULT WINAPI
testclock_GetTime(IReferenceClock
*iface
, REFERENCE_TIME
*time
)
3273 struct testclock
*clock
= impl_from_IReferenceClock(iface
);
3274 if (SUCCEEDED(clock
->get_time_hr
))
3275 *time
= clock
->time
;
3276 return clock
->get_time_hr
;
3279 static HRESULT WINAPI
testclock_AdviseTime(IReferenceClock
*iface
, REFERENCE_TIME base
, REFERENCE_TIME offset
, HEVENT event
, DWORD_PTR
*cookie
)
3281 struct testclock
*clock
= impl_from_IReferenceClock(iface
);
3282 if (clock
->advise_time_cookie
)
3284 clock
->advise_time_cookie
->base
= base
;
3285 clock
->advise_time_cookie
->offset
= offset
;
3286 clock
->advise_time_cookie
->event
= (HANDLE
)event
;
3287 SetEvent(clock
->advise_time_cookie
->advise_time_called_event
);
3291 SetEvent((HANDLE
)event
);
3293 *cookie
= (DWORD_PTR
)clock
->advise_time_cookie
;
3297 static HRESULT WINAPI
testclock_AdvisePeriodic(IReferenceClock
*iface
, REFERENCE_TIME start
, REFERENCE_TIME period
, HSEMAPHORE semaphore
, DWORD_PTR
*cookie
)
3299 ok(0, "Unexpected call.\n");
3303 static HRESULT WINAPI
testclock_Unadvise(IReferenceClock
*iface
, DWORD_PTR cookie
)
3306 ((struct advise_time_cookie
*)cookie
)->unadvise_called
= TRUE
;
3310 static IReferenceClockVtbl testclock_vtbl
=
3312 testclock_QueryInterface
,
3316 testclock_AdviseTime
,
3317 testclock_AdvisePeriodic
,
3321 static void testclock_init(struct testclock
*clock
)
3323 memset(clock
, 0, sizeof(*clock
));
3324 clock
->IReferenceClock_iface
.lpVtbl
= &testclock_vtbl
;
3327 static void test_audiostream_get_format(void)
3329 static const WAVEFORMATEX pin_format
=
3331 .wFormatTag
= WAVE_FORMAT_PCM
,
3333 .nSamplesPerSec
= 44100,
3334 .wBitsPerSample
= 16,
3336 .nAvgBytesPerSec
= 4 * 44100,
3340 .majortype
= MEDIATYPE_Audio
,
3341 .subtype
= MEDIASUBTYPE_PCM
,
3342 .formattype
= FORMAT_WaveFormatEx
,
3343 .cbFormat
= sizeof(WAVEFORMATEX
),
3344 .pbFormat
= (BYTE
*)&pin_format
,
3346 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
3347 IAudioMediaStream
*audio_stream
;
3348 struct testfilter source
;
3349 IGraphBuilder
*graph
;
3350 IMediaStream
*stream
;
3351 WAVEFORMATEX format
;
3356 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3357 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3358 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
3359 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3360 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3361 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3363 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
3364 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3365 ok(!!graph
, "Expected non-NULL graph.\n");
3367 testfilter_init(&source
);
3369 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, L
"source");
3370 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3372 hr
= IAudioMediaStream_GetFormat(audio_stream
, NULL
);
3373 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
3375 hr
= IAudioMediaStream_GetFormat(audio_stream
, &format
);
3376 ok(hr
== MS_E_NOSTREAM
, "Got hr %#x.\n", hr
);
3378 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3379 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3381 memset(&format
, 0xcc, sizeof(format
));
3382 hr
= IAudioMediaStream_GetFormat(audio_stream
, &format
);
3383 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3384 ok(format
.wFormatTag
== WAVE_FORMAT_PCM
, "Got tag %#x.\n", format
.wFormatTag
);
3385 ok(format
.nChannels
== 2, "Got %u channels.\n", format
.nChannels
);
3386 ok(format
.nSamplesPerSec
== 44100, "Got sample rate %u.\n", format
.nSamplesPerSec
);
3387 ok(format
.nAvgBytesPerSec
== 176400, "Got %u bytes/sec.\n", format
.nAvgBytesPerSec
);
3388 ok(format
.nBlockAlign
== 4, "Got alignment %u.\n", format
.nBlockAlign
);
3389 ok(format
.wBitsPerSample
== 16, "Got %u bits/sample.\n", format
.wBitsPerSample
);
3390 ok(!format
.cbSize
, "Got extra size %u.\n", format
.cbSize
);
3392 hr
= IGraphBuilder_Disconnect(graph
, pin
);
3393 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3394 hr
= IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3395 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3397 hr
= IAudioMediaStream_GetFormat(audio_stream
, &format
);
3398 ok(hr
== MS_E_NOSTREAM
, "Got hr %#x.\n", hr
);
3400 ref
= IAMMultiMediaStream_Release(mmstream
);
3401 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3402 ref
= IGraphBuilder_Release(graph
);
3403 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3405 IAudioMediaStream_Release(audio_stream
);
3406 ref
= IMediaStream_Release(stream
);
3407 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3408 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
3409 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3412 static HRESULT
set_audiostream_format(const WAVEFORMATEX
*format
)
3414 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
3415 IAudioMediaStream
*audio_stream
;
3416 IMediaStream
*stream
;
3420 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3421 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3422 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
3423 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3425 hr
= IAudioMediaStream_SetFormat(audio_stream
, format
);
3427 ref
= IAMMultiMediaStream_Release(mmstream
);
3428 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3429 IAudioMediaStream_Release(audio_stream
);
3430 ref
= IMediaStream_Release(stream
);
3431 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3436 static void test_audiostream_set_format(void)
3438 static const WAVEFORMATEX valid_format
=
3440 .wFormatTag
= WAVE_FORMAT_PCM
,
3442 .nSamplesPerSec
= 44100,
3443 .wBitsPerSample
= 16,
3445 .nAvgBytesPerSec
= 4 * 44100,
3448 const AM_MEDIA_TYPE mt
=
3450 .majortype
= MEDIATYPE_Audio
,
3451 .subtype
= MEDIASUBTYPE_PCM
,
3452 .formattype
= FORMAT_WaveFormatEx
,
3453 .cbFormat
= sizeof(WAVEFORMATEX
),
3454 .pbFormat
= (BYTE
*)&valid_format
,
3457 WAVEFORMATEXTENSIBLE extensible_format
;
3458 IAudioMediaStream
*audio_stream
;
3459 IAMMultiMediaStream
*mmstream
;
3460 struct testfilter source
;
3461 IGraphBuilder
*graph
;
3462 IMediaStream
*stream
;
3463 WAVEFORMATEX format
;
3468 hr
= set_audiostream_format(&valid_format
);
3469 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3470 hr
= set_audiostream_format(NULL
);
3471 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
3473 extensible_format
.Format
= valid_format
;
3474 extensible_format
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
3475 extensible_format
.Format
.cbSize
= sizeof(WAVEFORMATEXTENSIBLE
) - sizeof(WAVEFORMATEX
);
3476 extensible_format
.Samples
.wValidBitsPerSample
= valid_format
.wBitsPerSample
;
3477 extensible_format
.dwChannelMask
= KSAUDIO_SPEAKER_STEREO
;
3478 extensible_format
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
3479 hr
= set_audiostream_format(&extensible_format
.Format
);
3480 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
3482 format
= valid_format
;
3483 format
.nBlockAlign
= 1;
3484 hr
= set_audiostream_format(&format
);
3485 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3487 format
= valid_format
;
3488 format
.nAvgBytesPerSec
= 1234;
3489 hr
= set_audiostream_format(&format
);
3490 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3492 mmstream
= create_ammultimediastream();
3494 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3495 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3496 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
3497 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3499 hr
= IAudioMediaStream_SetFormat(audio_stream
, &valid_format
);
3500 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3502 hr
= IAudioMediaStream_GetFormat(audio_stream
, &format
);
3503 ok(hr
== MS_E_NOSTREAM
, "Got hr %#x.\n", hr
);
3505 format
= valid_format
;
3506 format
.nChannels
= 1;
3507 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3508 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
3510 format
= valid_format
;
3511 format
.nSamplesPerSec
= 11025;
3512 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3513 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
3515 format
= valid_format
;
3516 format
.nAvgBytesPerSec
= 1234;
3517 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3518 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
3520 format
= valid_format
;
3521 format
.nBlockAlign
= 1;
3522 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3523 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
3525 format
= valid_format
;
3526 format
.wBitsPerSample
= 8;
3527 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3528 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
3530 format
= valid_format
;
3532 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3533 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
3535 hr
= IAudioMediaStream_SetFormat(audio_stream
, &valid_format
);
3536 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3538 ref
= IAMMultiMediaStream_Release(mmstream
);
3539 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3540 IAudioMediaStream_Release(audio_stream
);
3541 ref
= IMediaStream_Release(stream
);
3542 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3544 mmstream
= create_ammultimediastream();
3546 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3547 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3548 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
3549 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3550 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3551 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3553 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
3554 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3555 ok(!!graph
, "Expected non-NULL graph.\n");
3557 testfilter_init(&source
);
3559 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
3560 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3562 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3563 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3565 format
= valid_format
;
3566 format
.nChannels
= 1;
3567 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3568 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
3570 hr
= IGraphBuilder_Disconnect(graph
, pin
);
3571 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3572 hr
= IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3573 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3575 format
= valid_format
;
3576 format
.nChannels
= 1;
3577 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3578 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3580 ref
= IAMMultiMediaStream_Release(mmstream
);
3581 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3582 ref
= IGraphBuilder_Release(graph
);
3583 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3585 IAudioMediaStream_Release(audio_stream
);
3586 ref
= IMediaStream_Release(stream
);
3587 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3588 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
3589 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3592 static void test_audiostream_receive_connection(void)
3594 WAVEFORMATEXTENSIBLE extensible_format
;
3595 IAudioMediaStream
*audio_stream
;
3596 IAMMultiMediaStream
*mmstream
;
3597 struct testfilter source
;
3598 IGraphBuilder
*graph
;
3599 IMediaStream
*stream
;
3600 WAVEFORMATEX format
;
3606 mmstream
= create_ammultimediastream();
3607 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3608 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3609 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
3610 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3611 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3612 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3613 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
3614 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3615 ok(graph
!= NULL
, "Expected non-null graph\n");
3616 testfilter_init(&source
);
3617 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
3618 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3620 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
3621 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3622 IGraphBuilder_Disconnect(graph
, pin
);
3623 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3626 mt
.majortype
= GUID_NULL
;
3627 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3628 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3631 mt
.subtype
= MEDIASUBTYPE_RGB24
;
3632 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3633 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3634 IGraphBuilder_Disconnect(graph
, pin
);
3635 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3638 mt
.formattype
= GUID_NULL
;
3639 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3640 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3643 mt
.cbFormat
= sizeof(WAVEFORMATEX
) - 1;
3644 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3645 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3647 extensible_format
.Format
= audio_format
;
3648 extensible_format
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
3649 extensible_format
.Format
.cbSize
= sizeof(WAVEFORMATEXTENSIBLE
) - sizeof(WAVEFORMATEX
);
3650 extensible_format
.Samples
.wValidBitsPerSample
= audio_format
.wBitsPerSample
;
3651 extensible_format
.dwChannelMask
= KSAUDIO_SPEAKER_STEREO
;
3652 extensible_format
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
3654 mt
.cbFormat
= sizeof(extensible_format
);
3655 mt
.pbFormat
= (BYTE
*)&extensible_format
;
3656 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3657 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
3659 hr
= IAudioMediaStream_SetFormat(audio_stream
, &audio_format
);
3660 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3662 format
= audio_format
;
3663 format
.nChannels
= 2;
3665 mt
.pbFormat
= (BYTE
*)&format
;
3666 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3667 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
3669 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
3670 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3671 IGraphBuilder_Disconnect(graph
, pin
);
3672 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3674 ref
= IAMMultiMediaStream_Release(mmstream
);
3675 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3676 ref
= IGraphBuilder_Release(graph
);
3677 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3679 IAudioMediaStream_Release(audio_stream
);
3680 ref
= IMediaStream_Release(stream
);
3681 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3682 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
3683 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3686 static void test_ddrawstream_receive_connection(void)
3688 static const VIDEOINFOHEADER req_vih
;
3689 IDirectDrawMediaStream
*ddraw_stream
;
3690 IAMMultiMediaStream
*mmstream
;
3691 struct testfilter source
;
3692 DDSURFACEDESC format
;
3693 IMediaStream
*stream
;
3694 VIDEOINFO video_info
;
3701 static const VIDEOINFO yuy2_video_info
=
3703 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
3704 .bmiHeader
.biWidth
= 333,
3705 .bmiHeader
.biHeight
= -444,
3706 .bmiHeader
.biPlanes
= 1,
3707 .bmiHeader
.biBitCount
= 16,
3708 .bmiHeader
.biCompression
= MAKEFOURCC('Y', 'U', 'Y', '2'),
3711 const AM_MEDIA_TYPE yuy2_mt
=
3713 .majortype
= MEDIATYPE_Video
,
3714 .subtype
= MEDIASUBTYPE_YUY2
,
3715 .formattype
= FORMAT_VideoInfo
,
3716 .cbFormat
= sizeof(VIDEOINFOHEADER
),
3717 .pbFormat
= (BYTE
*)&yuy2_video_info
,
3720 const AM_MEDIA_TYPE video_mt
=
3722 .majortype
= MEDIATYPE_Video
,
3723 .subtype
= MEDIASUBTYPE_RGB8
,
3724 .formattype
= FORMAT_VideoInfo
,
3725 .cbFormat
= sizeof(VIDEOINFOHEADER
),
3726 .pbFormat
= (BYTE
*)&req_vih
,
3729 static const GUID
*subtypes
[] =
3731 &MEDIASUBTYPE_RGB24
,
3732 &MEDIASUBTYPE_RGB32
,
3733 &MEDIASUBTYPE_RGB555
,
3734 &MEDIASUBTYPE_RGB565
,
3737 &MEDIASUBTYPE_ARGB32
,
3738 &MEDIASUBTYPE_ARGB1555
,
3739 &MEDIASUBTYPE_ARGB4444
,
3751 mmstream
= create_ammultimediastream();
3752 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
3753 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3754 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
3755 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3756 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3757 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3759 testfilter_init(&source
);
3762 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3763 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3764 hr
= IPin_Disconnect(pin
);
3765 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3767 for (i
= 0; i
< ARRAY_SIZE(subtypes
); ++i
)
3770 mt
.subtype
= *subtypes
[i
];
3771 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3772 ok(hr
== (i
< 4 ? S_OK
: VFW_E_TYPE_NOT_ACCEPTED
), "Got hr %#x.\n", hr
);
3775 hr
= IPin_Disconnect(pin
);
3776 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3780 format
= rgb8_format
;
3781 format
.dwFlags
= DDSD_WIDTH
;
3782 format
.dwWidth
= 222;
3783 format
.dwHeight
= 555;
3784 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
3785 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3787 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb32_mt
);
3788 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3789 hr
= IPin_Disconnect(pin
);
3790 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3792 format
= rgb8_format
;
3793 format
.dwFlags
= DDSD_HEIGHT
;
3794 format
.dwWidth
= 333;
3795 format
.dwHeight
= 444;
3796 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
3797 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3799 video_info
= rgb555_video_info
;
3800 video_info
.bmiHeader
.biWidth
= 333;
3801 video_info
.bmiHeader
.biHeight
= 444;
3803 mt
.pbFormat
= (BYTE
*)&video_info
;
3804 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3805 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3806 hr
= IPin_Disconnect(pin
);
3807 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3809 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb32_mt
);
3810 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3811 hr
= IPin_Disconnect(pin
);
3812 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3814 video_info
= rgb32_video_info
;
3815 video_info
.bmiHeader
.biWidth
= 332;
3816 video_info
.bmiHeader
.biHeight
= 444;
3818 mt
.pbFormat
= (BYTE
*)&video_info
;
3819 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3820 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3822 video_info
= rgb32_video_info
;
3823 video_info
.bmiHeader
.biWidth
= 333;
3824 video_info
.bmiHeader
.biHeight
= 443;
3826 mt
.pbFormat
= (BYTE
*)&video_info
;
3827 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3828 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3830 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb8_format
, NULL
);
3831 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3833 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb555_mt
);
3834 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3836 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb8_mt
);
3837 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3838 hr
= IPin_Disconnect(pin
);
3839 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3841 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb555_format
, NULL
);
3842 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3844 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb565_mt
);
3845 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3847 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb555_mt
);
3848 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3849 hr
= IPin_Disconnect(pin
);
3850 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3852 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb565_format
, NULL
);
3853 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3855 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb24_mt
);
3856 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3858 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb565_mt
);
3859 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3860 hr
= IPin_Disconnect(pin
);
3861 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3863 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb24_format
, NULL
);
3864 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3866 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb32_mt
);
3867 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3869 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb24_mt
);
3870 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3871 hr
= IPin_Disconnect(pin
);
3872 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3874 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb32_format
, NULL
);
3875 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3877 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb8_mt
);
3878 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3880 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb32_mt
);
3881 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3882 hr
= IPin_Disconnect(pin
);
3883 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3885 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &yuy2_format
, NULL
);
3886 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3888 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &yuy2_mt
);
3889 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3891 format
= yuy2_format
;
3892 format
.ddpfPixelFormat
.u2
.dwRBitMask
= 0xf800;
3893 format
.ddpfPixelFormat
.u3
.dwGBitMask
= 0x07e0;
3894 format
.ddpfPixelFormat
.u4
.dwBBitMask
= 0x001f;
3895 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
3896 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3898 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb565_mt
);
3899 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
3901 format
= rgb8_format
;
3903 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
3904 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3906 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb565_mt
);
3907 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3908 hr
= IPin_Disconnect(pin
);
3909 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3911 ref
= IAMMultiMediaStream_Release(mmstream
);
3912 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3914 IDirectDrawMediaStream_Release(ddraw_stream
);
3915 ref
= IMediaStream_Release(stream
);
3916 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3917 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
3918 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3921 static void test_audiostream_receive(void)
3923 ALLOCATOR_PROPERTIES properties
=
3930 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
3931 ALLOCATOR_PROPERTIES actual
;
3932 struct testfilter source
;
3933 IMemAllocator
*allocator
;
3934 IGraphBuilder
*graph
;
3935 IMediaStream
*stream
;
3936 IMediaSample
*sample1
;
3937 IMediaSample
*sample2
;
3938 IMediaSample
*sample3
;
3943 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
3944 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3945 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3946 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3947 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3948 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3949 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
3950 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3951 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
3952 testfilter_init(&source
);
3953 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
3954 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3955 hr
= CoCreateInstance(&CLSID_MemoryAllocator
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMemAllocator
, (void **)&allocator
);
3956 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3957 hr
= IMemAllocator_SetProperties(allocator
, &properties
, &actual
);
3958 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3959 hr
= IMemAllocator_Commit(allocator
);
3960 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3962 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
3963 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3965 hr
= IMemAllocator_GetBuffer(allocator
, &sample1
, NULL
, NULL
, 0);
3966 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3967 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample1
);
3968 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
3969 ref
= IMediaSample_Release(sample1
);
3970 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3972 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
3973 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3975 hr
= IMemAllocator_GetBuffer(allocator
, &sample1
, NULL
, NULL
, 0);
3976 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3977 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample1
);
3978 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3979 ref
= get_refcount(sample1
);
3980 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
3982 hr
= IMemAllocator_GetBuffer(allocator
, &sample2
, NULL
, NULL
, 0);
3983 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3984 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample2
);
3985 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3986 ref
= get_refcount(sample2
);
3987 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
3989 hr
= IPin_EndOfStream(pin
);
3990 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3992 hr
= IMemAllocator_GetBuffer(allocator
, &sample3
, NULL
, NULL
, 0);
3993 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3994 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample3
);
3995 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3996 ref
= get_refcount(sample3
);
3997 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
3999 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4000 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4002 ref
= IMediaSample_Release(sample1
);
4003 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4004 ref
= IMediaSample_Release(sample2
);
4005 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4006 ref
= IMediaSample_Release(sample3
);
4007 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4009 hr
= IMemAllocator_GetBuffer(allocator
, &sample1
, NULL
, NULL
, 0);
4010 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4011 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample1
);
4012 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
4013 ref
= IMediaSample_Release(sample1
);
4014 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4016 IGraphBuilder_Disconnect(graph
, pin
);
4017 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
4019 hr
= IMemAllocator_Decommit(allocator
);
4020 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4022 ref
= IAMMultiMediaStream_Release(mmstream
);
4023 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4024 ref
= IGraphBuilder_Release(graph
);
4025 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4027 ref
= IMediaStream_Release(stream
);
4028 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4029 ref
= IMemAllocator_Release(allocator
);
4030 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4033 static void test_audiostream_initialize(void)
4035 IAMMediaStream
*stream
;
4041 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream
);
4042 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4044 /* Crashes on native. */
4047 hr
= IAMMediaStream_Initialize(stream
, NULL
, 0, NULL
, STREAMTYPE_WRITE
);
4048 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
4051 hr
= IAMMediaStream_Initialize(stream
, NULL
, 0, &test_mspid
, STREAMTYPE_WRITE
);
4052 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4054 hr
= IAMMediaStream_GetInformation(stream
, &mspid
, &type
);
4055 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4056 ok(IsEqualGUID(&mspid
, &test_mspid
), "Got mspid %s.\n", wine_dbgstr_guid(&mspid
));
4057 ok(type
== STREAMTYPE_WRITE
, "Got type %u.\n", type
);
4059 hr
= IAMMediaStream_Initialize(stream
, NULL
, 0, &MSPID_PrimaryAudio
, STREAMTYPE_READ
);
4060 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4062 hr
= IAMMediaStream_GetInformation(stream
, &mspid
, &type
);
4063 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4064 ok(IsEqualGUID(&mspid
, &MSPID_PrimaryAudio
), "Got mspid %s.\n", wine_dbgstr_guid(&mspid
));
4065 ok(type
== STREAMTYPE_READ
, "Got type %u.\n", type
);
4067 ref
= IAMMediaStream_Release(stream
);
4068 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4071 static void test_audiostream_begin_flush_end_flush(void)
4073 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
4074 IAudioStreamSample
*stream_sample
;
4075 IAudioMediaStream
*audio_stream
;
4076 IMediaSample
*media_sample
;
4077 struct testfilter source
;
4078 IAudioData
*audio_data
;
4079 IGraphBuilder
*graph
;
4080 IMediaStream
*stream
;
4085 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
4086 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4087 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
4088 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4089 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
4090 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4091 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
4092 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4093 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
4094 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4095 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
4096 testfilter_init(&source
);
4097 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
4098 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4099 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
4100 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4101 hr
= IAudioData_SetBuffer(audio_data
, 16, NULL
, 0);
4102 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4103 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &stream_sample
);
4104 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4106 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
4107 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4109 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4110 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4112 hr
= BaseOutputPinImpl_GetDeliveryBuffer(&source
.source
, &media_sample
, NULL
, NULL
, 0);
4113 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4114 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
4115 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4116 ref
= get_refcount(media_sample
);
4117 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
4119 hr
= IPin_EndOfStream(pin
);
4120 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4122 hr
= IPin_BeginFlush(pin
);
4123 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4125 ref
= IMediaSample_Release(media_sample
);
4126 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4128 hr
= BaseOutputPinImpl_GetDeliveryBuffer(&source
.source
, &media_sample
, NULL
, NULL
, 0);
4129 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4130 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
4131 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
4133 ref
= IMediaSample_Release(media_sample
);
4134 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4136 hr
= IAudioStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4137 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
4139 hr
= IPin_EndOfStream(pin
);
4140 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
4142 hr
= IPin_EndFlush(pin
);
4143 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4145 hr
= BaseOutputPinImpl_GetDeliveryBuffer(&source
.source
, &media_sample
, NULL
, NULL
, 0);
4146 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4147 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
4148 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4149 ref
= IMediaSample_Release(media_sample
);
4150 ok(ref
== 1, "Got outstanding refcount %d.\n", ref
);
4152 hr
= IPin_EndOfStream(pin
);
4153 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4155 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4156 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4158 IGraphBuilder_Disconnect(graph
, pin
);
4159 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
4161 ref
= IAudioStreamSample_Release(stream_sample
);
4162 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4163 ref
= IAudioData_Release(audio_data
);
4164 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4165 ref
= IAMMultiMediaStream_Release(mmstream
);
4166 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4167 ref
= IGraphBuilder_Release(graph
);
4168 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4170 IAudioMediaStream_Release(audio_stream
);
4171 ref
= IMediaStream_Release(stream
);
4172 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4175 static IMediaSample
*ammediastream_allocate_sample(struct testfilter
*source
, const BYTE
*input_data
, DWORD input_length
)
4177 IMediaSample
*sample
;
4181 hr
= BaseOutputPinImpl_GetDeliveryBuffer(&source
->source
, &sample
, NULL
, NULL
, 0);
4182 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4184 hr
= IMediaSample_GetPointer(sample
, &sample_data
);
4185 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4187 hr
= IMediaSample_SetActualDataLength(sample
, input_length
);
4188 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4190 memcpy(sample_data
, input_data
, input_length
);
4195 static void test_audiostream_new_segment(void)
4197 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
4198 static const BYTE test_data
[8] = { 0 };
4199 IAudioStreamSample
*stream_sample
;
4200 IAudioMediaStream
*audio_stream
;
4201 IMemInputPin
*mem_input_pin
;
4202 IMediaSample
*media_sample
;
4203 struct testfilter source
;
4204 IAudioData
*audio_data
;
4205 STREAM_TIME start_time
;
4206 STREAM_TIME end_time
;
4207 IGraphBuilder
*graph
;
4208 IMediaStream
*stream
;
4213 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
4214 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4215 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
4216 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4217 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
4218 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4219 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
4220 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4221 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
4222 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4223 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
4224 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4225 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
4226 testfilter_init(&source
);
4227 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
4228 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4229 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
4230 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4231 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &stream_sample
);
4232 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4233 hr
= IAudioData_SetBuffer(audio_data
, 5, NULL
, 0);
4234 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4236 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
4237 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4238 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4239 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4241 hr
= IPin_NewSegment(pin
, 11111111, 22222222, 1.0);
4242 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4244 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 5);
4245 start_time
= 12345678;
4246 end_time
= 23456789;
4247 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
4248 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4249 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
4250 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4251 IMediaSample_Release(media_sample
);
4253 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4254 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4256 start_time
= 0xdeadbeefdeadbeef;
4257 end_time
= 0xdeadbeefdeadbeef;
4258 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
4259 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4260 ok(start_time
== 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
4261 ok(end_time
== 23459057, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
4263 hr
= IPin_NewSegment(pin
, 11111111, 22222222, 2.0);
4264 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4266 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 5);
4267 start_time
= 12345678;
4268 end_time
= 23456789;
4269 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
4270 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4271 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
4272 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4273 IMediaSample_Release(media_sample
);
4275 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4276 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4278 start_time
= 0xdeadbeefdeadbeef;
4279 end_time
= 0xdeadbeefdeadbeef;
4280 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
4281 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4282 ok(start_time
== 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
4283 ok(end_time
== 23459057, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
4285 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4286 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4287 IGraphBuilder_Disconnect(graph
, pin
);
4288 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
4290 ref
= IAudioStreamSample_Release(stream_sample
);
4291 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4292 ref
= IAudioData_Release(audio_data
);
4293 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4294 ref
= IAMMultiMediaStream_Release(mmstream
);
4295 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4296 ref
= IGraphBuilder_Release(graph
);
4297 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4299 IMemInputPin_Release(mem_input_pin
);
4300 IAudioMediaStream_Release(audio_stream
);
4301 ref
= IMediaStream_Release(stream
);
4302 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4305 static void CALLBACK
apc_func(ULONG_PTR param
)
4309 static IPin
*ammediastream_pin
;
4310 static IMemInputPin
*ammediastream_mem_input_pin
;
4311 static IMediaSample
*ammediastream_media_sample
;
4312 static DWORD ammediastream_sleep_time
;
4313 static HRESULT ammediastream_expected_hr
;
4315 static DWORD CALLBACK
ammediastream_end_of_stream(void *param
)
4319 Sleep(ammediastream_sleep_time
);
4320 hr
= IPin_EndOfStream(ammediastream_pin
);
4321 ok(hr
== ammediastream_expected_hr
, "Got hr %#x.\n", hr
);
4326 static DWORD CALLBACK
ammediastream_receive(void *param
)
4330 Sleep(ammediastream_sleep_time
);
4331 hr
= IMemInputPin_Receive(ammediastream_mem_input_pin
, ammediastream_media_sample
);
4332 ok(hr
== ammediastream_expected_hr
, "Got hr %#x.\n", hr
);
4337 struct ammediastream_receive_release_param
4339 IMemInputPin
*mem_input_pin
;
4340 IMediaSample
*media_sample
;
4343 static DWORD CALLBACK
ammediastream_receive_release(void *p
)
4345 struct ammediastream_receive_release_param
*param
= (struct ammediastream_receive_release_param
*)p
;
4349 hr
= IMemInputPin_Receive(param
->mem_input_pin
, param
->media_sample
);
4350 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4352 ref
= IMediaSample_Release(param
->media_sample
);
4353 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4360 static HANDLE
ammediastream_async_receive_time(struct testfilter
*source
,
4361 REFERENCE_TIME start_time
, REFERENCE_TIME end_time
, const BYTE
*input_data
, DWORD input_length
)
4363 struct ammediastream_receive_release_param
*param
;
4364 IMediaSample
*sample
;
4367 sample
= ammediastream_allocate_sample(source
, input_data
, input_length
);
4368 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
4369 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4371 param
= calloc(1, sizeof(*param
));
4372 param
->mem_input_pin
= source
->source
.pMemInputPin
;
4373 param
->media_sample
= sample
;
4374 return CreateThread(NULL
, 0, ammediastream_receive_release
, param
, 0, NULL
);
4377 static IStreamSample
*streamsample_sample
;
4378 static DWORD streamsample_flags
;
4379 static DWORD streamsample_timeout
;
4380 static HRESULT streamsample_expected_hr
;
4382 static DWORD CALLBACK
streamsample_completion_status(void *param
)
4386 hr
= IStreamSample_CompletionStatus(streamsample_sample
, streamsample_flags
, streamsample_timeout
);
4387 ok(hr
== streamsample_expected_hr
, "Got hr %#x.\n", hr
);
4392 static void test_audiostreamsample_update(void)
4394 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
4395 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
4396 IAudioStreamSample
*stream_sample
;
4397 IAudioMediaStream
*audio_stream
;
4398 IMediaControl
*media_control
;
4399 IMemInputPin
*mem_input_pin
;
4400 IMediaSample
*media_sample1
;
4401 IMediaSample
*media_sample2
;
4402 struct testfilter source
;
4403 IAudioData
*audio_data
;
4404 IGraphBuilder
*graph
;
4405 IMediaStream
*stream
;
4406 DWORD actual_length
;
4414 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
4415 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4416 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
4417 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4418 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
4419 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4420 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
4421 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4422 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
4423 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4424 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
4425 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4426 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
4427 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaControl
, (void **)&media_control
);
4428 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4429 testfilter_init(&source
);
4430 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
4431 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4432 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
4433 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4434 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &stream_sample
);
4435 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4436 event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
4437 ok(event
!= NULL
, "Expected non-NULL event.");
4439 hr
= IAudioStreamSample_Update(stream_sample
, 0, event
, apc_func
, 0);
4440 ok(hr
== MS_E_NOTINIT
, "Got hr %#x.\n", hr
);
4442 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4443 ok(hr
== MS_E_NOTINIT
, "Got hr %#x.\n", hr
);
4445 hr
= IAudioData_SetBuffer(audio_data
, sizeof(buffer
), buffer
, 0);
4446 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4448 hr
= IAudioStreamSample_Update(stream_sample
, 0, event
, apc_func
, 0);
4449 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
4451 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4452 ok(hr
== MS_E_NOTRUNNING
, "Got hr %#x.\n", hr
);
4454 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4455 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4457 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4458 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
4460 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4461 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4462 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
4463 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4464 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4465 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4467 media_sample1
= ammediastream_allocate_sample(&source
, test_data
, 8);
4468 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample1
);
4469 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4470 ref
= get_refcount(media_sample1
);
4471 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
4473 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4474 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4476 hr
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_length
);
4477 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4478 ok(actual_length
== 6, "Got actual length %u.\n", actual_length
);
4480 ok(memcmp(buffer
, test_data
, 6) == 0, "Sample data didn't match.\n");
4482 ref
= get_refcount(media_sample1
);
4483 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
4485 media_sample2
= ammediastream_allocate_sample(&source
, test_data
, 8);
4486 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample2
);
4487 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4488 ref
= get_refcount(media_sample2
);
4489 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
4491 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4492 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4494 hr
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_length
);
4495 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4496 ok(actual_length
== 6, "Got actual length %u.\n", actual_length
);
4498 ok(memcmp(buffer
, &test_data
[6], 2) == 0, "Sample data didn't match.\n");
4499 ok(memcmp(&buffer
[2], test_data
, 4) == 0, "Sample data didn't match.\n");
4501 ref
= IMediaSample_Release(media_sample1
);
4502 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4504 hr
= IPin_EndOfStream(pin
);
4505 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4507 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4508 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4510 hr
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_length
);
4511 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4512 ok(actual_length
== 4, "Got actual length %u.\n", actual_length
);
4514 ok(memcmp(buffer
, &test_data
[4], 4) == 0, "Sample data didn't match.\n");
4516 ref
= IMediaSample_Release(media_sample2
);
4517 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4519 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4520 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
4522 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4523 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4524 hr
= IMediaControl_Pause(media_control
);
4525 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4527 media_sample1
= ammediastream_allocate_sample(&source
, test_data
, 6);
4528 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample1
);
4529 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4530 ref
= IMediaSample_Release(media_sample1
);
4531 ok(ref
== 1, "Got outstanding refcount %d.\n", ref
);
4533 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4534 ok(hr
== MS_E_NOTRUNNING
, "Got hr %#x.\n", hr
);
4536 hr
= IMediaControl_Stop(media_control
);
4537 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4538 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4539 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4541 media_sample1
= ammediastream_allocate_sample(&source
, test_data
, 6);
4543 ammediastream_mem_input_pin
= mem_input_pin
;
4544 ammediastream_media_sample
= media_sample1
;
4545 ammediastream_sleep_time
= 100;
4546 ammediastream_expected_hr
= S_OK
;
4547 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
4549 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4550 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4552 hr
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_length
);
4553 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4554 ok(actual_length
== 6, "Got actual length %u.\n", actual_length
);
4556 ok(memcmp(buffer
, test_data
, 6) == 0, "Sample data didn't match.\n");
4558 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
4559 CloseHandle(thread
);
4561 ref
= IMediaSample_Release(media_sample1
);
4562 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4564 ammediastream_pin
= pin
;
4565 ammediastream_sleep_time
= 100;
4566 ammediastream_expected_hr
= S_OK
;
4567 thread
= CreateThread(NULL
, 0, ammediastream_end_of_stream
, NULL
, 0, NULL
);
4569 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4570 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
4572 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
4573 CloseHandle(thread
);
4575 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4576 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4577 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4578 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4580 hr
= IAudioStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4581 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
4583 IAudioStreamSample_AddRef(stream_sample
);
4584 ref
= IAudioStreamSample_Release(stream_sample
);
4585 ok(ref
== 1, "Got outstanding refcount %d.\n", ref
);
4587 hr
= IAudioStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4588 ok(hr
== MS_E_BUSY
, "Got hr %#x.\n", hr
);
4590 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4591 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4592 IGraphBuilder_Disconnect(graph
, pin
);
4593 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
4594 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4595 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4597 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4598 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
4600 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4603 ref
= IAudioStreamSample_Release(stream_sample
);
4604 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4605 ref
= IAudioData_Release(audio_data
);
4606 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4607 ref
= IAMMultiMediaStream_Release(mmstream
);
4608 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4609 IMediaControl_Release(media_control
);
4610 ref
= IGraphBuilder_Release(graph
);
4611 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4613 IMemInputPin_Release(mem_input_pin
);
4614 IAudioMediaStream_Release(audio_stream
);
4615 ref
= IMediaStream_Release(stream
);
4616 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4619 void test_audiostreamsample_completion_status(void)
4621 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
4622 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
4623 IAudioStreamSample
*stream_sample1
;
4624 IAudioStreamSample
*stream_sample2
;
4625 IAudioMediaStream
*audio_stream
;
4626 IMediaSample
*media_sample
;
4627 struct testfilter source
;
4628 IAudioData
*audio_data1
;
4629 IAudioData
*audio_data2
;
4630 IGraphBuilder
*graph
;
4631 IMediaStream
*stream
;
4637 event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
4638 ok(event
!= NULL
, "Expected non-NULL event.");
4640 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
4641 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4642 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
4643 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4644 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
4645 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4646 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
4647 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4648 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
4649 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4650 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
4651 testfilter_init(&source
);
4652 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
4653 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4654 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data1
);
4655 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4656 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data2
);
4657 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4658 hr
= IAudioData_SetBuffer(audio_data1
, 6, NULL
, 0);
4659 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4660 hr
= IAudioData_SetBuffer(audio_data2
, 6, NULL
, 0);
4661 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4662 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data1
, 0, &stream_sample1
);
4663 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4664 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data2
, 0, &stream_sample2
);
4665 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4667 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
4668 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4669 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4670 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4672 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
4673 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4675 hr
= IAudioStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4676 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
4678 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
4679 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
4681 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 6);
4682 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
4683 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4684 ref
= IMediaSample_Release(media_sample
);
4685 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4687 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
4688 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4690 hr
= IAudioStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4691 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
4693 hr
= IAudioStreamSample_Update(stream_sample2
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4694 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
4696 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 12);
4697 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
4698 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4699 ref
= IMediaSample_Release(media_sample
);
4700 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4702 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
4703 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4705 hr
= IAudioStreamSample_CompletionStatus(stream_sample2
, 0, 0);
4706 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4708 hr
= IAudioStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4709 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
4711 hr
= IPin_EndOfStream(pin
);
4712 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4714 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
4715 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
4717 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4718 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4719 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4720 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4722 hr
= IAudioStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4723 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
4725 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4726 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4728 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
4729 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
4731 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4732 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4734 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 6);
4735 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
4736 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4737 ref
= IMediaSample_Release(media_sample
);
4738 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4740 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
4741 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4743 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4744 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4746 IGraphBuilder_Disconnect(graph
, pin
);
4747 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
4749 ref
= IAudioStreamSample_Release(stream_sample1
);
4750 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4751 ref
= IAudioStreamSample_Release(stream_sample2
);
4752 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4753 ref
= IAudioData_Release(audio_data1
);
4754 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4755 ref
= IAudioData_Release(audio_data2
);
4756 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4757 ref
= IAMMultiMediaStream_Release(mmstream
);
4758 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4759 ref
= IGraphBuilder_Release(graph
);
4760 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4762 IAudioMediaStream_Release(audio_stream
);
4763 ref
= IMediaStream_Release(stream
);
4764 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4769 static void test_audiostreamsample_get_sample_times(void)
4771 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
4772 static const BYTE test_data
[8] = { 0 };
4773 IAudioStreamSample
*stream_sample
;
4774 IMediaFilter
*graph_media_filter
;
4775 IAudioMediaStream
*audio_stream
;
4776 STREAM_TIME filter_start_time
;
4777 IMemInputPin
*mem_input_pin
;
4778 IMediaStreamFilter
*filter
;
4779 IMediaSample
*media_sample
;
4780 struct testfilter source
;
4781 STREAM_TIME current_time
;
4782 struct testclock clock
;
4783 IAudioData
*audio_data
;
4784 STREAM_TIME start_time
;
4785 STREAM_TIME end_time
;
4786 IGraphBuilder
*graph
;
4787 IMediaStream
*stream
;
4792 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
4793 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4794 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
4795 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4796 ok(!!filter
, "Expected non-null filter.\n");
4797 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
4798 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4799 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
4800 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4801 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
4802 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4803 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
4804 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4805 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
4806 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4807 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
4808 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&graph_media_filter
);
4809 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4810 testfilter_init(&source
);
4811 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
4812 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4813 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
4814 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4815 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &stream_sample
);
4816 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4817 hr
= IAudioData_SetBuffer(audio_data
, 5, NULL
, 0);
4818 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4819 testclock_init(&clock
);
4821 clock
.time
= 12345678;
4823 current_time
= 0xdeadbeefdeadbeef;
4824 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
4825 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4826 ok(current_time
== 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time
));
4828 IMediaFilter_SetSyncSource(graph_media_filter
, &clock
.IReferenceClock_iface
);
4829 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4831 current_time
= 0xdeadbeefdeadbeef;
4832 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
4833 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4834 ok(current_time
== 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time
));
4836 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
4837 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4838 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4839 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4841 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &filter_start_time
);
4842 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4844 clock
.get_time_hr
= E_FAIL
;
4846 current_time
= 0xdeadbeefdeadbeef;
4847 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
4848 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4849 ok(current_time
== 0xdeadbeefddf15da1 + filter_start_time
, "Expected current time %s, got %s.\n",
4850 wine_dbgstr_longlong(0xdeadbeefddf15da1 + filter_start_time
), wine_dbgstr_longlong(current_time
));
4852 clock
.get_time_hr
= S_OK
;
4854 current_time
= 0xdeadbeefdeadbeef;
4855 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
4856 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4857 ok(current_time
== filter_start_time
, "Expected current time %s, got %s.\n",
4858 wine_dbgstr_longlong(filter_start_time
), wine_dbgstr_longlong(current_time
));
4860 clock
.time
= 23456789;
4862 current_time
= 0xdeadbeefdeadbeef;
4863 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
4864 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4865 ok(current_time
== filter_start_time
+ 11111111, "Expected current time %s, got %s.\n",
4866 wine_dbgstr_longlong(filter_start_time
+ 11111111), wine_dbgstr_longlong(current_time
));
4868 start_time
= 0xdeadbeefdeadbeef;
4869 end_time
= 0xdeadbeefdeadbeef;
4870 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
4871 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4872 ok(start_time
== 0, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
4873 ok(end_time
== 0, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
4875 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 8);
4876 start_time
= 12345678;
4877 end_time
= 23456789;
4878 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
4879 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4880 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
4881 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4882 IMediaSample_Release(media_sample
);
4884 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4885 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4887 start_time
= 0xdeadbeefdeadbeef;
4888 end_time
= 0xdeadbeefdeadbeef;
4889 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
4890 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4891 ok(start_time
== 12345678, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
4892 ok(end_time
== 12347946, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
4894 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 6);
4895 start_time
= 12345678;
4896 end_time
= 23456789;
4897 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
4898 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4899 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
4900 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4901 IMediaSample_Release(media_sample
);
4903 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4904 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4906 start_time
= 0xdeadbeefdeadbeef;
4907 end_time
= 0xdeadbeefdeadbeef;
4908 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
4909 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4910 ok(start_time
== 12347946, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
4911 ok(end_time
== 12346585, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
4913 hr
= IPin_EndOfStream(pin
);
4914 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4916 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4917 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4919 start_time
= 0xdeadbeefdeadbeef;
4920 end_time
= 0xdeadbeefdeadbeef;
4921 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
4922 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4923 ok(start_time
== 12346585, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
4924 ok(end_time
== 12348399, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
4926 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4927 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4928 IGraphBuilder_Disconnect(graph
, pin
);
4929 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
4931 ref
= IAudioStreamSample_Release(stream_sample
);
4932 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4933 ref
= IAudioData_Release(audio_data
);
4934 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4935 ref
= IAMMultiMediaStream_Release(mmstream
);
4936 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4937 IMediaFilter_Release(graph_media_filter
);
4938 ref
= IGraphBuilder_Release(graph
);
4939 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4940 ref
= IMediaStreamFilter_Release(filter
);
4941 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4943 IMemInputPin_Release(mem_input_pin
);
4944 IAudioMediaStream_Release(audio_stream
);
4945 ref
= IMediaStream_Release(stream
);
4946 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4949 static void test_ddrawstream_initialize(void)
4951 IDirectDrawMediaStream
*ddraw_stream
;
4952 IAMMediaStream
*stream
;
4953 IDirectDraw
*ddraw2
;
4960 hr
= DirectDrawCreate(NULL
, &ddraw
, NULL
);
4961 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4963 hr
= CoCreateInstance(&CLSID_AMDirectDrawStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream
);
4964 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4966 hr
= IAMMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
4967 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4969 /* Crashes on native. */
4972 hr
= IAMMediaStream_Initialize(stream
, NULL
, 0, NULL
, STREAMTYPE_WRITE
);
4973 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
4976 hr
= IAMMediaStream_Initialize(stream
, NULL
, 0, &test_mspid
, STREAMTYPE_WRITE
);
4977 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4979 hr
= IAMMediaStream_GetInformation(stream
, &mspid
, &type
);
4980 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4981 ok(IsEqualGUID(&mspid
, &test_mspid
), "Got mspid %s.\n", wine_dbgstr_guid(&mspid
));
4982 ok(type
== STREAMTYPE_WRITE
, "Got type %u.\n", type
);
4984 hr
= IAMMediaStream_Initialize(stream
, (IUnknown
*)ddraw
, 0, &MSPID_PrimaryAudio
, STREAMTYPE_READ
);
4985 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4987 hr
= IAMMediaStream_GetInformation(stream
, &mspid
, &type
);
4988 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4989 ok(IsEqualGUID(&mspid
, &MSPID_PrimaryAudio
), "Got mspid %s.\n", wine_dbgstr_guid(&mspid
));
4990 ok(type
== STREAMTYPE_READ
, "Got type %u.\n", type
);
4992 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw2
);
4993 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
4994 ok(ddraw2
== ddraw
, "Expected ddraw %p, got %p.\n", ddraw
, ddraw2
);
4996 IDirectDrawMediaStream_Release(ddraw_stream
);
4997 ref
= IAMMediaStream_Release(stream
);
4998 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
4999 IDirectDraw_Release(ddraw2
);
5000 ref
= IDirectDraw_Release(ddraw
);
5001 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5004 #define check_ddrawstream_get_format(a,b,c) check_ddrawstream_get_format_(__LINE__,a,b,c)
5005 static void check_ddrawstream_get_format_(int line
, IDirectDrawMediaStream
*stream
,
5006 const AM_MEDIA_TYPE
*mt
, const DDSURFACEDESC
*expected_format
)
5008 DDSURFACEDESC current_format
;
5009 DDSURFACEDESC desired_format
;
5010 struct testfilter source
;
5011 FILTER_INFO filter_info
;
5012 DDSURFACEDESC format
;
5018 hr
= IDirectDrawMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5019 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5020 hr
= IPin_QueryPinInfo(pin
, &pin_info
);
5021 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5022 hr
= IBaseFilter_QueryFilterInfo(pin_info
.pFilter
, &filter_info
);
5023 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5025 testfilter_init(&source
);
5027 hr
= IFilterGraph_AddFilter(filter_info
.pGraph
, &source
.filter
.IBaseFilter_iface
, L
"source");
5028 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5030 hr
= IFilterGraph_ConnectDirect(filter_info
.pGraph
, &source
.source
.pin
.IPin_iface
, pin
, mt
);
5031 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5033 hr
= IDirectDrawMediaStream_GetFormat(stream
, NULL
, NULL
, NULL
, NULL
);
5034 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5036 memset(¤t_format
, 0xcc, sizeof(current_format
));
5037 current_format
.dwSize
= sizeof(current_format
);
5038 memset(&desired_format
, 0xcc, sizeof(desired_format
));
5039 desired_format
.dwSize
= sizeof(desired_format
);
5041 hr
= IDirectDrawMediaStream_GetFormat(stream
, ¤t_format
, NULL
, &desired_format
, &flags
);
5042 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5043 memset(&format
, 0xcc, sizeof(format
));
5044 format
.dwSize
= sizeof(format
);
5045 format
.ddpfPixelFormat
= expected_format
->ddpfPixelFormat
;
5046 format
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5047 format
.dwWidth
= 333;
5048 format
.dwHeight
= 444;
5049 format
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
5050 ok_(__FILE__
, line
)(memcmp(¤t_format
, &format
, sizeof(DDSURFACEDESC
)) == 0, "Current format didn't match.\n");
5051 format
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
5052 ok_(__FILE__
, line
)(memcmp(&desired_format
, &format
, sizeof(DDSURFACEDESC
)) == 0, "Desired format didn't match.\n");
5054 hr
= IFilterGraph_Disconnect(filter_info
.pGraph
, &source
.source
.pin
.IPin_iface
);
5055 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5056 hr
= IFilterGraph_Disconnect(filter_info
.pGraph
, pin
);
5057 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5059 hr
= IFilterGraph_RemoveFilter(filter_info
.pGraph
, &source
.filter
.IBaseFilter_iface
);
5060 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5062 IFilterGraph_Release(filter_info
.pGraph
);
5063 IBaseFilter_Release(pin_info
.pFilter
);
5067 static void test_ddrawstream_get_format(void)
5069 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5070 IDirectDrawMediaStream
*ddraw_stream
;
5071 DDSURFACEDESC current_format
;
5072 DDSURFACEDESC desired_format
;
5073 IDirectDrawPalette
*palette
;
5074 IMediaStream
*stream
;
5075 VIDEOINFO video_info
;
5081 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5082 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5083 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5084 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5086 current_format
.dwSize
= sizeof(current_format
);
5087 desired_format
.dwSize
= sizeof(desired_format
);
5088 hr
= IDirectDrawMediaStream_GetFormat(ddraw_stream
, ¤t_format
, &palette
, &desired_format
, &flags
);
5089 ok(hr
== MS_E_NOSTREAM
, "Got hr %#x.\n", hr
);
5091 video_info
= rgb32_video_info
;
5092 video_info
.rcSource
.right
= 222;
5093 video_info
.rcSource
.bottom
= 333;
5094 video_info
.rcTarget
.right
= 444;
5095 video_info
.rcTarget
.bottom
= 666;
5097 mt
.pbFormat
= (BYTE
*)&video_info
;
5098 check_ddrawstream_get_format(ddraw_stream
, &mt
, &rgb32_format
);
5100 video_info
= rgb32_video_info
;
5101 video_info
.bmiHeader
.biHeight
= 444;
5103 mt
.pbFormat
= (BYTE
*)&video_info
;
5104 check_ddrawstream_get_format(ddraw_stream
, &mt
, &rgb32_format
);
5106 check_ddrawstream_get_format(ddraw_stream
, &rgb8_mt
, &rgb8_format
);
5107 check_ddrawstream_get_format(ddraw_stream
, &rgb555_mt
, &rgb555_format
);
5108 check_ddrawstream_get_format(ddraw_stream
, &rgb565_mt
, &rgb565_format
);
5109 check_ddrawstream_get_format(ddraw_stream
, &rgb24_mt
, &rgb24_format
);
5110 check_ddrawstream_get_format(ddraw_stream
, &rgb32_mt
, &rgb32_format
);
5112 current_format
.dwSize
= sizeof(current_format
);
5113 desired_format
.dwSize
= sizeof(desired_format
);
5114 hr
= IDirectDrawMediaStream_GetFormat(ddraw_stream
, ¤t_format
, &palette
, &desired_format
, &flags
);
5115 ok(hr
== MS_E_NOSTREAM
, "Got hr %#x.\n", hr
);
5117 ref
= IAMMultiMediaStream_Release(mmstream
);
5118 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5119 IDirectDrawMediaStream_Release(ddraw_stream
);
5120 ref
= IMediaStream_Release(stream
);
5121 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5124 #define check_ddrawstream_set_format(a,b,c,d) check_ddrawstream_set_format_(__LINE__,a,b,c,d)
5125 static void check_ddrawstream_set_format_(int line
, IDirectDrawMediaStream
*stream
,
5126 const DDSURFACEDESC
*format
, const AM_MEDIA_TYPE
*mt
, HRESULT expected_hr
)
5128 struct testfilter source
;
5129 FILTER_INFO filter_info
;
5134 hr
= IDirectDrawMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5135 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5136 hr
= IPin_QueryPinInfo(pin
, &pin_info
);
5137 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5138 hr
= IBaseFilter_QueryFilterInfo(pin_info
.pFilter
, &filter_info
);
5139 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5141 testfilter_init(&source
);
5143 hr
= IFilterGraph_AddFilter(filter_info
.pGraph
, &source
.filter
.IBaseFilter_iface
, L
"source");
5144 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5146 hr
= IDirectDrawMediaStream_SetFormat(stream
, format
, NULL
);
5147 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x.\n", hr
);
5151 DDSURFACEDESC current_format
;
5152 DDSURFACEDESC desired_format
;
5155 hr
= IFilterGraph_ConnectDirect(filter_info
.pGraph
, &source
.source
.pin
.IPin_iface
, pin
, mt
);
5156 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5158 memset(¤t_format
, 0xcc, sizeof(current_format
));
5159 memset(&desired_format
, 0xcc, sizeof(desired_format
));
5161 current_format
.dwSize
= sizeof(current_format
);
5162 desired_format
.dwSize
= sizeof(desired_format
);
5163 hr
= IDirectDrawMediaStream_GetFormat(stream
, ¤t_format
, NULL
, &desired_format
, &flags
);
5164 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5165 if (format
->dwFlags
& DDSD_PIXELFORMAT
)
5167 ok_(__FILE__
, line
)(current_format
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
),
5168 "Got current format flags %#x.\n", current_format
.dwFlags
);
5169 ok_(__FILE__
, line
)(memcmp(¤t_format
.ddpfPixelFormat
, &format
->ddpfPixelFormat
, sizeof(DDPIXELFORMAT
)) == 0,
5170 "Current pixel format didn't match.\n");
5171 ok_(__FILE__
, line
)(memcmp(&desired_format
.ddpfPixelFormat
, &format
->ddpfPixelFormat
, sizeof(DDPIXELFORMAT
)) == 0,
5172 "Desired pixel format didn't match.\n");
5176 ok_(__FILE__
, line
)(current_format
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
),
5177 "Got flags %#x.\n", current_format
.dwFlags
);
5179 ok_(__FILE__
, line
)(desired_format
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
),
5180 "Got desired format flags %#x.\n", desired_format
.dwFlags
);
5181 ok_(__FILE__
, line
)(current_format
.ddsCaps
.dwCaps
== (DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
),
5182 "Got current format caps %#x.\n", current_format
.ddsCaps
.dwCaps
);
5183 ok_(__FILE__
, line
)(desired_format
.ddsCaps
.dwCaps
== (DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
),
5184 "Got desired format caps %#x.\n", desired_format
.ddsCaps
.dwCaps
);
5185 ok_(__FILE__
, line
)(flags
== 0, "Got flags %#x.\n", flags
);
5187 hr
= IFilterGraph_Disconnect(filter_info
.pGraph
, &source
.source
.pin
.IPin_iface
);
5188 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5189 hr
= IFilterGraph_Disconnect(filter_info
.pGraph
, pin
);
5190 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5193 hr
= IFilterGraph_RemoveFilter(filter_info
.pGraph
, &source
.filter
.IBaseFilter_iface
);
5194 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
5196 IFilterGraph_Release(filter_info
.pGraph
);
5197 IBaseFilter_Release(pin_info
.pFilter
);
5201 static void test_ddrawstream_set_format(void)
5203 static const DDSURFACEDESC rgb1_format
=
5205 .dwSize
= sizeof(DDSURFACEDESC
),
5206 .dwFlags
= DDSD_PIXELFORMAT
,
5207 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
5208 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED1
,
5209 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 1,
5211 static const DDSURFACEDESC rgb2_format
=
5213 .dwSize
= sizeof(DDSURFACEDESC
),
5214 .dwFlags
= DDSD_PIXELFORMAT
,
5215 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
5216 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED2
,
5217 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 2,
5219 static const DDSURFACEDESC rgb4_format
=
5221 .dwSize
= sizeof(DDSURFACEDESC
),
5222 .dwFlags
= DDSD_PIXELFORMAT
,
5223 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
5224 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED4
,
5225 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 4,
5227 static const DDSURFACEDESC rgb4to8_format
=
5229 .dwSize
= sizeof(DDSURFACEDESC
),
5230 .dwFlags
= DDSD_PIXELFORMAT
,
5231 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
5232 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXEDTO8
,
5233 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 4,
5235 static const DDSURFACEDESC rgb332_format
=
5237 .dwSize
= sizeof(DDSURFACEDESC
),
5238 .dwFlags
= DDSD_PIXELFORMAT
,
5239 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
5240 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
,
5241 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 8,
5242 .ddpfPixelFormat
.u2
.dwRBitMask
= 0xe0,
5243 .ddpfPixelFormat
.u3
.dwGBitMask
= 0x1c,
5244 .ddpfPixelFormat
.u4
.dwBBitMask
= 0x03,
5247 IDirectDrawMediaStream
*ddraw_stream
;
5248 IAMMultiMediaStream
*mmstream
;
5249 DDSURFACEDESC current_format
;
5250 DDSURFACEDESC desired_format
;
5251 struct testfilter source
;
5252 IGraphBuilder
*graph
;
5253 DDSURFACEDESC format
;
5254 IMediaStream
*stream
;
5255 VIDEOINFO video_info
;
5261 mmstream
= create_ammultimediastream();
5263 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5264 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5265 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5266 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5268 check_ddrawstream_set_format(ddraw_stream
, &rgb8_format
, &rgb8_mt
, S_OK
);
5269 check_ddrawstream_set_format(ddraw_stream
, &rgb555_format
, &rgb555_mt
, S_OK
);
5270 check_ddrawstream_set_format(ddraw_stream
, &rgb565_format
, &rgb565_mt
, S_OK
);
5271 check_ddrawstream_set_format(ddraw_stream
, &rgb24_format
, &rgb24_mt
, S_OK
);
5272 check_ddrawstream_set_format(ddraw_stream
, &rgb32_format
, &rgb32_mt
, S_OK
);
5273 check_ddrawstream_set_format(ddraw_stream
, &argb32_format
, &rgb32_mt
, S_OK
);
5274 check_ddrawstream_set_format(ddraw_stream
, &yuy2_format
, NULL
, S_OK
);
5275 check_ddrawstream_set_format(ddraw_stream
, &yv12_format
, NULL
, S_OK
);
5277 format
= rgb32_format
;
5278 format
.ddpfPixelFormat
.dwFlags
|= DDPF_ALPHAPIXELS
| DDPF_ALPHA
5279 | DDPF_COMPRESSED
| DDPF_RGBTOYUV
| DDPF_ZBUFFER
| DDPF_ZPIXELS
| DDPF_STENCILBUFFER
5280 | DDPF_ALPHAPREMULT
| DDPF_LUMINANCE
| DDPF_BUMPLUMINANCE
| DDPF_BUMPDUDV
;
5281 check_ddrawstream_set_format(ddraw_stream
, &format
, &rgb32_mt
, S_OK
);
5283 format
= yuy2_format
;
5284 format
.ddpfPixelFormat
.dwFlags
|= DDPF_ALPHAPIXELS
| DDPF_ALPHA
5285 | DDPF_PALETTEINDEXED4
| DDPF_PALETTEINDEXEDTO8
| DDPF_PALETTEINDEXED8
5286 | DDPF_RGB
| DDPF_COMPRESSED
| DDPF_RGBTOYUV
| DDPF_YUV
| DDPF_ZBUFFER
5287 | DDPF_PALETTEINDEXED1
| DDPF_PALETTEINDEXED2
| DDPF_ZPIXELS
5288 | DDPF_STENCILBUFFER
| DDPF_ALPHAPREMULT
| DDPF_LUMINANCE
5289 | DDPF_BUMPLUMINANCE
| DDPF_BUMPDUDV
;
5290 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, S_OK
);
5292 format
= rgb32_format
;
5293 format
.dwFlags
|= DDSD_CAPS
;
5294 format
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
5295 check_ddrawstream_set_format(ddraw_stream
, &format
, &rgb32_mt
, S_OK
);
5297 format
= rgb8_format
;
5299 check_ddrawstream_set_format(ddraw_stream
, &format
, &rgb32_mt
, S_OK
);
5301 check_ddrawstream_set_format(ddraw_stream
, &rgb1_format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5302 check_ddrawstream_set_format(ddraw_stream
, &rgb2_format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5303 check_ddrawstream_set_format(ddraw_stream
, &rgb4_format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5304 check_ddrawstream_set_format(ddraw_stream
, &rgb4to8_format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5305 check_ddrawstream_set_format(ddraw_stream
, &rgb332_format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5307 format
= rgb8_format
;
5308 format
.ddpfPixelFormat
.dwFlags
&= ~DDPF_RGB
;
5309 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5311 format
= rgb8_format
;
5312 format
.ddpfPixelFormat
.dwFlags
|= DDPF_PALETTEINDEXED1
;
5313 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5315 format
= rgb32_format
;
5316 format
.ddpfPixelFormat
.dwFlags
|= DDPF_PALETTEINDEXED8
;
5317 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5319 format
= rgb32_format
;
5320 format
.ddpfPixelFormat
.dwFlags
|= DDPF_YUV
;
5321 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5323 format
= rgb565_format
;
5324 format
.ddpfPixelFormat
.u2
.dwRBitMask
= 0x001f;
5325 format
.ddpfPixelFormat
.u3
.dwGBitMask
= 0x07e0;
5326 format
.ddpfPixelFormat
.u4
.dwBBitMask
= 0xf800;
5327 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5329 format
= rgb32_format
;
5330 format
.ddpfPixelFormat
.u2
.dwRBitMask
= 0x00ff00;
5331 format
.ddpfPixelFormat
.u3
.dwGBitMask
= 0x0000ff;
5332 format
.ddpfPixelFormat
.u4
.dwBBitMask
= 0xff0000;
5333 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5335 format
= yuy2_format
;
5336 format
.ddpfPixelFormat
.u1
.dwYUVBitCount
= 0;
5337 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, E_INVALIDARG
);
5339 format
= rgb32_format
;
5340 format
.dwSize
= sizeof(DDSURFACEDESC
) + 1;
5341 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, E_INVALIDARG
);
5343 format
= rgb32_format
;
5344 format
.ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
) + 1;
5345 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5347 ref
= IAMMultiMediaStream_Release(mmstream
);
5348 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5349 IDirectDrawMediaStream_Release(ddraw_stream
);
5350 ref
= IMediaStream_Release(stream
);
5351 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5353 mmstream
= create_ammultimediastream();
5355 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5356 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5357 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5358 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5359 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5360 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5362 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
5363 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5364 ok(!!graph
, "Expected non-NULL graph.\n");
5366 testfilter_init(&source
);
5368 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, L
"source");
5369 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5371 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &rgb8_mt
);
5372 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5374 source
.preferred_mt
= NULL
;
5376 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb555_format
, NULL
);
5377 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got hr %#x.\n", hr
);
5378 ok(IsEqualGUID(&source
.source
.pin
.mt
.subtype
, &MEDIASUBTYPE_RGB8
),
5379 "Got subtype %s.\n", wine_dbgstr_guid(&source
.source
.pin
.mt
.subtype
));
5380 hr
= IDirectDrawMediaStream_GetFormat(ddraw_stream
, ¤t_format
, NULL
, &desired_format
, NULL
);
5381 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5382 ok(current_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 8,
5383 "Got rgb bit count %u.\n", current_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
5384 ok(desired_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 8,
5385 "Got rgb bit count %u.\n", desired_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
5387 format
= rgb555_format
;
5389 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
5390 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5391 ok(IsEqualGUID(&source
.source
.pin
.mt
.subtype
, &MEDIASUBTYPE_RGB8
),
5392 "Got subtype %s.\n", wine_dbgstr_guid(&source
.source
.pin
.mt
.subtype
));
5394 source
.preferred_mt
= &rgb555_mt
;
5396 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb8_format
, NULL
);
5397 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5399 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb555_format
, NULL
);
5400 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5401 ok(IsEqualGUID(&source
.source
.pin
.mt
.subtype
, &MEDIASUBTYPE_RGB555
),
5402 "Got subtype %s.\n", wine_dbgstr_guid(&source
.source
.pin
.mt
.subtype
));
5403 hr
= IDirectDrawMediaStream_GetFormat(ddraw_stream
, ¤t_format
, NULL
, &desired_format
, NULL
);
5404 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5405 ok(current_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 16,
5406 "Got rgb bit count %u.\n", current_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
5407 ok(desired_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 16,
5408 "Got rgb bit count %u.\n", desired_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
5410 video_info
= rgb555_video_info
;
5411 video_info
.bmiHeader
.biWidth
= 222;
5412 video_info
.bmiHeader
.biHeight
= -555;
5414 mt
.pbFormat
= (BYTE
*)&video_info
;
5415 source
.preferred_mt
= &mt
;
5417 format
= rgb555_format
;
5418 format
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5419 format
.dwWidth
= 222;
5420 format
.dwHeight
= 555;
5421 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
5422 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5423 ok(IsEqualGUID(&source
.source
.pin
.mt
.subtype
, &MEDIASUBTYPE_RGB555
),
5424 "Got subtype %s.\n", wine_dbgstr_guid(&source
.source
.pin
.mt
.subtype
));
5425 ok(((VIDEOINFO
*)source
.source
.pin
.mt
.pbFormat
)->bmiHeader
.biWidth
== 222,
5426 "Got width %d.\n", ((VIDEOINFO
*)source
.source
.pin
.mt
.pbFormat
)->bmiHeader
.biWidth
);
5427 ok(((VIDEOINFO
*)source
.source
.pin
.mt
.pbFormat
)->bmiHeader
.biHeight
== -555,
5428 "Got height %d.\n", ((VIDEOINFO
*)source
.source
.pin
.mt
.pbFormat
)->bmiHeader
.biHeight
);
5430 hr
= IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
5431 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5432 hr
= IGraphBuilder_Disconnect(graph
, pin
);
5433 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5435 ref
= IAMMultiMediaStream_Release(mmstream
);
5436 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5437 ref
= IGraphBuilder_Release(graph
);
5438 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5440 IDirectDrawMediaStream_Release(ddraw_stream
);
5441 ref
= IMediaStream_Release(stream
);
5442 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5445 static void test_ddrawstream_receive(void)
5447 ALLOCATOR_PROPERTIES properties
=
5454 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5455 ALLOCATOR_PROPERTIES actual
;
5456 IMediaStreamFilter
*filter
;
5457 struct testfilter source
;
5458 IMemAllocator
*allocator
;
5459 IGraphBuilder
*graph
;
5460 IMediaStream
*stream
;
5461 IMediaSample
*sample
;
5467 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
5468 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5469 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
5470 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5471 ok(!!filter
, "Expected non-null filter.\n");
5472 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5473 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5474 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5475 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5476 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
5477 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5478 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
5479 testfilter_init(&source
);
5480 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
5481 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5482 hr
= CoCreateInstance(&CLSID_MemoryAllocator
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMemAllocator
, (void **)&allocator
);
5483 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5484 hr
= IMemAllocator_SetProperties(allocator
, &properties
, &actual
);
5485 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5486 hr
= IMemAllocator_Commit(allocator
);
5487 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5489 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &rgb32_mt
);
5490 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5492 hr
= IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
5493 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5494 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample
);
5495 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5496 ref
= IMediaSample_Release(sample
);
5497 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5499 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
5500 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5502 hr
= IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
5503 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5505 ammediastream_mem_input_pin
= source
.source
.pMemInputPin
;
5506 ammediastream_media_sample
= sample
;
5507 ammediastream_sleep_time
= 0;
5508 ammediastream_expected_hr
= S_OK
;
5509 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
5511 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
5513 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
5514 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5516 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
5517 CloseHandle(thread
);
5519 ref
= IMediaSample_Release(sample
);
5520 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5522 hr
= IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
5523 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5524 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample
);
5525 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5526 ref
= IMediaSample_Release(sample
);
5527 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5529 IGraphBuilder_Disconnect(graph
, pin
);
5530 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
5532 hr
= IMemAllocator_Decommit(allocator
);
5533 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5535 ref
= IAMMultiMediaStream_Release(mmstream
);
5536 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5537 ref
= IGraphBuilder_Release(graph
);
5538 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5539 ref
= IMediaStreamFilter_Release(filter
);
5540 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5542 ref
= IMediaStream_Release(stream
);
5543 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5544 ref
= IMemAllocator_Release(allocator
);
5545 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5548 static void test_ddrawstream_begin_flush_end_flush(void)
5550 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5551 IDirectDrawStreamSample
*stream_sample
;
5552 IDirectDrawMediaStream
*ddraw_stream
;
5553 IMediaSample
*media_sample
;
5554 IMediaFilter
*media_filter
;
5555 struct testfilter source
;
5556 IGraphBuilder
*graph
;
5557 IMediaStream
*stream
;
5558 VIDEOINFO video_info
;
5565 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
5566 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5567 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5568 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5569 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5570 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5571 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5572 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5573 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
5574 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5575 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
5576 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
5577 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5578 testfilter_init(&source
);
5579 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
5580 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5582 hr
= IMediaFilter_SetSyncSource(media_filter
, NULL
);
5583 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5585 video_info
= rgb32_video_info
;
5586 video_info
.bmiHeader
.biWidth
= 3;
5587 video_info
.bmiHeader
.biHeight
= 1;
5589 mt
.pbFormat
= (BYTE
*)&video_info
;
5590 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
5591 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5593 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample
);
5594 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5596 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
5597 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5599 hr
= BaseOutputPinImpl_GetDeliveryBuffer(&source
.source
, &media_sample
, NULL
, NULL
, 0);
5600 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5602 ammediastream_mem_input_pin
= source
.source
.pMemInputPin
;
5603 ammediastream_media_sample
= media_sample
;
5604 ammediastream_sleep_time
= 0;
5605 ammediastream_expected_hr
= S_FALSE
;
5606 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
5608 hr
= IPin_BeginFlush(pin
);
5609 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5611 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
5612 CloseHandle(thread
);
5614 ref
= IMediaSample_Release(media_sample
);
5615 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5617 hr
= BaseOutputPinImpl_GetDeliveryBuffer(&source
.source
, &media_sample
, NULL
, NULL
, 0);
5618 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5619 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
5620 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
5622 ref
= IMediaSample_Release(media_sample
);
5623 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5625 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
5626 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
5628 hr
= IPin_EndOfStream(pin
);
5629 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
5631 hr
= IPin_EndFlush(pin
);
5632 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5634 hr
= BaseOutputPinImpl_GetDeliveryBuffer(&source
.source
, &media_sample
, NULL
, NULL
, 0);
5635 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5636 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
5637 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5638 ref
= IMediaSample_Release(media_sample
);
5639 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5641 hr
= IPin_EndOfStream(pin
);
5642 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5644 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
5645 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5647 IGraphBuilder_Disconnect(graph
, pin
);
5648 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
5650 ref
= IDirectDrawStreamSample_Release(stream_sample
);
5651 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5652 ref
= IAMMultiMediaStream_Release(mmstream
);
5653 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5654 IMediaFilter_Release(media_filter
);
5655 ref
= IGraphBuilder_Release(graph
);
5656 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5658 IDirectDrawMediaStream_Release(ddraw_stream
);
5659 ref
= IMediaStream_Release(stream
);
5660 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5663 static void test_ddrawstream_new_segment(void)
5665 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
5666 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5667 IDirectDrawStreamSample
*stream_sample
;
5668 IDirectDrawMediaStream
*ddraw_stream
;
5669 IMemInputPin
*mem_input_pin
;
5670 IMediaSample
*media_sample
;
5671 IMediaFilter
*media_filter
;
5672 struct testfilter source
;
5673 STREAM_TIME start_time
;
5674 STREAM_TIME end_time
;
5675 IGraphBuilder
*graph
;
5676 IMediaStream
*stream
;
5677 VIDEOINFO video_info
;
5683 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
5684 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5685 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5686 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5687 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5688 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5689 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5690 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5691 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
5692 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5693 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
5694 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5695 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
5696 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
5697 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5698 testfilter_init(&source
);
5699 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
5700 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5702 hr
= IMediaFilter_SetSyncSource(media_filter
, NULL
);
5703 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5705 video_info
= rgb32_video_info
;
5706 video_info
.bmiHeader
.biWidth
= 3;
5707 video_info
.bmiHeader
.biHeight
= 1;
5709 mt
.pbFormat
= (BYTE
*)&video_info
;
5710 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
5711 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5713 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample
);
5714 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5716 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
5717 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5719 hr
= IPin_NewSegment(pin
, 11111111, 22222222, 1.0);
5720 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5722 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
5723 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
5725 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
5726 start_time
= 12345678;
5727 end_time
= 23456789;
5728 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
5729 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5730 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
5731 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5732 IMediaSample_Release(media_sample
);
5734 start_time
= 0xdeadbeefdeadbeef;
5735 end_time
= 0xdeadbeefdeadbeef;
5736 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
5737 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5738 ok(start_time
== 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
5739 ok(end_time
== 34567900, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
5741 hr
= IPin_NewSegment(pin
, 11111111, 22222222, 2.0);
5742 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5744 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
5745 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
5747 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
5748 start_time
= 12345678;
5749 end_time
= 23456789;
5750 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
5751 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5752 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
5753 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5754 IMediaSample_Release(media_sample
);
5756 start_time
= 0xdeadbeefdeadbeef;
5757 end_time
= 0xdeadbeefdeadbeef;
5758 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
5759 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5760 ok(start_time
== 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
5761 ok(end_time
== 34567900, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
5763 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
5764 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5765 IGraphBuilder_Disconnect(graph
, pin
);
5766 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
5768 ref
= IDirectDrawStreamSample_Release(stream_sample
);
5769 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5770 ref
= IAMMultiMediaStream_Release(mmstream
);
5771 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5772 IMediaFilter_Release(media_filter
);
5773 ref
= IGraphBuilder_Release(graph
);
5774 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5776 IMemInputPin_Release(mem_input_pin
);
5777 IDirectDrawMediaStream_Release(ddraw_stream
);
5778 ref
= IMediaStream_Release(stream
);
5779 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5782 static void test_ddrawstream_get_time_per_frame(void)
5784 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5785 IDirectDrawMediaStream
*ddraw_stream
;
5786 struct testfilter source
;
5787 STREAM_TIME frame_time
;
5788 IGraphBuilder
*graph
;
5789 IMediaStream
*stream
;
5790 VIDEOINFO video_info
;
5796 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
5797 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5798 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5799 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5800 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5801 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5802 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5803 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5804 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
5805 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5806 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
5807 testfilter_init(&source
);
5808 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
5809 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5811 hr
= IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream
, NULL
);
5812 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
5814 hr
= IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream
, &frame_time
);
5815 ok(hr
== MS_E_NOSTREAM
, "Got hr %#x.\n", hr
);
5817 video_info
= rgb32_video_info
;
5818 video_info
.AvgTimePerFrame
= 12345678;
5820 mt
.pbFormat
= (BYTE
*)&video_info
;
5821 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
5822 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5824 frame_time
= 0xdeadbeefdeadbeef;
5825 hr
= IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream
, &frame_time
);
5826 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5827 ok(frame_time
== 12345678, "Got frame time %s.\n", wine_dbgstr_longlong(frame_time
));
5829 ref
= IAMMultiMediaStream_Release(mmstream
);
5830 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5831 ref
= IGraphBuilder_Release(graph
);
5832 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5834 IDirectDrawMediaStream_Release(ddraw_stream
);
5835 ref
= IMediaStream_Release(stream
);
5836 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5839 static void check_ammediastream_join_am_multi_media_stream(const CLSID
*clsid
)
5841 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5842 IMultiMediaStream
*mmstream2
;
5843 IAMMediaStream
*stream
;
5848 hr
= CoCreateInstance(clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream
);
5849 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5851 mmstream_ref
= get_refcount(mmstream
);
5853 hr
= IAMMediaStream_JoinAMMultiMediaStream(stream
, mmstream
);
5854 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5856 ref
= get_refcount(mmstream
);
5857 ok(ref
== mmstream_ref
, "Expected outstanding refcount %d, got %d.\n", mmstream_ref
, ref
);
5859 hr
= IAMMediaStream_GetMultiMediaStream(stream
, &mmstream2
);
5860 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5861 ok(mmstream2
== (IMultiMediaStream
*)mmstream
, "Expected mmstream %p, got %p.\n", mmstream
, mmstream2
);
5863 IMultiMediaStream_Release(mmstream2
);
5865 hr
= IAMMediaStream_JoinAMMultiMediaStream(stream
, NULL
);
5866 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5868 hr
= IAMMediaStream_GetMultiMediaStream(stream
, &mmstream2
);
5869 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5870 ok(mmstream2
== NULL
, "Got mmstream %p.\n", mmstream2
);
5872 ref
= IAMMediaStream_Release(stream
);
5873 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5874 ref
= IAMMultiMediaStream_Release(mmstream
);
5875 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5878 static void test_ammediastream_join_am_multi_media_stream(void)
5880 check_ammediastream_join_am_multi_media_stream(&CLSID_AMAudioStream
);
5881 check_ammediastream_join_am_multi_media_stream(&CLSID_AMDirectDrawStream
);
5884 static void check_ammediastream_join_filter(const CLSID
*clsid
)
5886 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5887 IMediaStreamFilter
*filter
, *filter2
, *filter3
;
5888 IAMMediaStream
*stream
;
5892 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
5893 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5894 ok(!!filter
, "Expected non-null filter.\n");
5895 EXPECT_REF(filter
, 3);
5897 hr
= CoCreateInstance(clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream
);
5898 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5899 EXPECT_REF(filter
, 3);
5901 hr
= CoCreateInstance(&CLSID_MediaStreamFilter
, NULL
, CLSCTX_INPROC_SERVER
,
5902 &IID_IMediaStreamFilter
, (void **)&filter2
);
5903 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5904 EXPECT_REF(filter
, 3);
5905 EXPECT_REF(filter2
, 1);
5907 hr
= IAMMediaStream_JoinFilter(stream
, filter2
);
5908 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5909 EXPECT_REF(filter
, 3);
5910 EXPECT_REF(filter2
, 1);
5912 /* Crashes on native. */
5915 hr
= IAMMediaStream_JoinFilter(stream
, NULL
);
5916 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5919 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter3
);
5920 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5921 ok(filter3
== filter
, "Expected filter %p, got %p.\n", filter
, filter3
);
5922 EXPECT_REF(filter
, 4);
5924 IMediaStreamFilter_Release(filter3
);
5925 EXPECT_REF(filter
, 3);
5927 ref
= IMediaStreamFilter_Release(filter2
);
5928 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5929 ref
= IAMMediaStream_Release(stream
);
5930 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5931 EXPECT_REF(filter
, 3);
5932 ref
= IAMMultiMediaStream_Release(mmstream
);
5933 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5934 EXPECT_REF(filter
, 1);
5935 ref
= IMediaStreamFilter_Release(filter
);
5936 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
5939 static void test_ammediastream_join_filter(void)
5941 check_ammediastream_join_filter(&CLSID_AMAudioStream
);
5942 check_ammediastream_join_filter(&CLSID_AMDirectDrawStream
);
5945 static void check_ammediastream_join_filter_graph(const MSPID
*id
)
5947 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5948 IGraphBuilder
*builder
, *builder2
;
5949 IMediaStreamFilter
*filter
;
5950 IAMMediaStream
*stream
;
5951 IFilterGraph
*graph
;
5956 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
5957 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5958 ok(!!filter
, "Expected non-null filter.\n");
5960 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, id
, 0, (IMediaStream
**)&stream
);
5961 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5963 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &builder
);
5964 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5965 ok(!!builder
, "Expected non-null graph.\n");
5966 EXPECT_REF(builder
, 4);
5968 hr
= IMediaStreamFilter_QueryFilterInfo(filter
, &info
);
5969 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5970 ok(info
.pGraph
== (IFilterGraph
*)builder
, "Expected graph %p, got %p.\n", (IFilterGraph
*)builder
, info
.pGraph
);
5971 EXPECT_REF(builder
, 5);
5972 IFilterGraph_Release(info
.pGraph
);
5973 EXPECT_REF(builder
, 4);
5975 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterGraph
, (void **)&graph
);
5976 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5977 EXPECT_REF(builder
, 4);
5978 EXPECT_REF(graph
, 1);
5980 /* Crashes on native. */
5983 hr
= IAMMediaStream_JoinFilterGraph(stream
, NULL
);
5984 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
5987 hr
= IAMMediaStream_JoinFilterGraph(stream
, graph
);
5988 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5989 EXPECT_REF(builder
, 4);
5990 EXPECT_REF(graph
, 1);
5992 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &builder2
);
5993 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
5994 ok(builder2
== builder
, "Expected graph %p, got %p.\n", builder
, builder2
);
5995 EXPECT_REF(builder
, 5);
5996 EXPECT_REF(graph
, 1);
5997 IGraphBuilder_Release(builder2
);
5998 EXPECT_REF(builder
, 4);
5999 EXPECT_REF(graph
, 1);
6001 hr
= IMediaStreamFilter_QueryFilterInfo(filter
, &info
);
6002 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6003 ok(info
.pGraph
== (IFilterGraph
*)builder
, "Expected graph %p, got %p.\n", (IFilterGraph
*)builder
, info
.pGraph
);
6004 EXPECT_REF(builder
, 5);
6005 EXPECT_REF(graph
, 1);
6006 IFilterGraph_Release(info
.pGraph
);
6007 EXPECT_REF(builder
, 4);
6008 EXPECT_REF(graph
, 1);
6010 ref
= IFilterGraph_Release(graph
);
6011 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6012 ref
= IAMMultiMediaStream_Release(mmstream
);
6013 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6014 ref
= IGraphBuilder_Release(builder
);
6015 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6016 ref
= IMediaStreamFilter_Release(filter
);
6017 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6018 ref
= IAMMediaStream_Release(stream
);
6019 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6022 static void test_ammediastream_join_filter_graph(void)
6024 check_ammediastream_join_filter_graph(&MSPID_PrimaryAudio
);
6025 check_ammediastream_join_filter_graph(&MSPID_PrimaryVideo
);
6028 static void check_ammediastream_set_state(const MSPID
*id
)
6030 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6031 IAMMediaStream
*am_stream
;
6032 IMediaStream
*stream
;
6036 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6037 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6038 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, id
, 0, &stream
);
6039 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6040 hr
= IMediaStream_QueryInterface(stream
, &IID_IAMMediaStream
, (void **)&am_stream
);
6041 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6043 hr
= IAMMediaStream_SetState(am_stream
, 4);
6044 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6046 hr
= IAMMediaStream_SetState(am_stream
, State_Running
);
6047 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6049 hr
= IAMMediaStream_SetState(am_stream
, State_Paused
);
6050 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6052 hr
= IAMMediaStream_SetState(am_stream
, State_Stopped
);
6053 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6055 ref
= IAMMultiMediaStream_Release(mmstream
);
6056 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6057 IAMMediaStream_Release(am_stream
);
6058 ref
= IMediaStream_Release(stream
);
6059 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6062 static void test_ammediastream_set_state(void)
6064 check_ammediastream_set_state(&MSPID_PrimaryAudio
);
6065 check_ammediastream_set_state(&MSPID_PrimaryVideo
);
6068 static void check_ammediastream_end_of_stream(const MSPID
*id
, const AM_MEDIA_TYPE
*mt
)
6070 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6071 struct testfilter source
;
6072 IGraphBuilder
*graph
;
6073 IMediaStream
*stream
;
6078 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6079 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6080 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, id
, 0, &stream
);
6081 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6082 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
6083 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6084 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
6085 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6086 ok(!!graph
, "Expected non-NULL graph.\n");
6087 testfilter_init(&source
);
6088 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
6089 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6091 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, mt
);
6092 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6094 hr
= IPin_EndOfStream(pin
);
6095 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6097 hr
= IPin_EndOfStream(pin
);
6098 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
6100 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
6101 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6103 hr
= IPin_EndOfStream(pin
);
6104 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6106 hr
= IPin_EndOfStream(pin
);
6107 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
6109 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
6110 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6112 hr
= IPin_EndOfStream(pin
);
6113 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
6115 IGraphBuilder_Disconnect(graph
, pin
);
6116 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
6118 ref
= IAMMultiMediaStream_Release(mmstream
);
6119 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6120 ref
= IGraphBuilder_Release(graph
);
6121 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6123 ref
= IMediaStream_Release(stream
);
6124 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6127 static void test_ammediastream_end_of_stream(void)
6129 check_ammediastream_end_of_stream(&MSPID_PrimaryAudio
, &audio_mt
);
6130 check_ammediastream_end_of_stream(&MSPID_PrimaryVideo
, &rgb32_mt
);
6133 void test_mediastreamfilter_get_state(void)
6135 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6136 IMediaStreamFilter
*filter
;
6141 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6142 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6143 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6144 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6145 ok(!!filter
, "Expected non-null filter.\n");
6147 /* Crashes on native. */
6150 hr
= IMediaStreamFilter_GetState(filter
, 0, NULL
);
6151 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
6155 hr
= IMediaStreamFilter_GetState(filter
, 0, &state
);
6156 ok(state
== State_Stopped
, "Got state %#x.\n", state
);
6158 ref
= IAMMultiMediaStream_Release(mmstream
);
6159 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6160 ref
= IMediaStreamFilter_Release(filter
);
6161 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6164 void check_mediastreamfilter_state(FILTER_STATE expected_state
, HRESULT (*set_state
)(IMediaStreamFilter
*),
6165 HRESULT (*reset_state
)(IMediaStreamFilter
*))
6167 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6168 struct teststream teststream
, teststream2
;
6169 IMediaStreamFilter
*filter
;
6174 teststream_init(&teststream
);
6175 teststream_init(&teststream2
);
6177 teststream2
.mspid
.Data2
= 1;
6179 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6180 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6181 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)&teststream
, &teststream
.mspid
, 0, NULL
);
6182 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6183 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)&teststream2
, &teststream2
.mspid
, 0, NULL
);
6184 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6185 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6186 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6187 ok(filter
!= NULL
, "Expected non-null filter\n");
6189 hr
= reset_state(filter
);
6190 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6192 teststream
.state
= 0xcc;
6193 teststream2
.state
= 0xcc;
6194 hr
= set_state(filter
);
6195 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6196 ok(teststream
.state
== expected_state
, "Got state %#x.\n", teststream
.state
);
6197 ok(teststream2
.state
== expected_state
, "Got state %#x.\n", teststream2
.state
);
6198 hr
= IMediaStreamFilter_GetState(filter
, 0, &state
);
6199 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6200 ok(state
== expected_state
, "Got state %#x.\n", state
);
6202 teststream
.state
= 0xcc;
6203 teststream2
.state
= 0xcc;
6204 hr
= set_state(filter
);
6205 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6206 ok(teststream
.state
== 0xcc, "Got state %#x.\n", teststream
.state
);
6207 ok(teststream2
.state
== 0xcc, "Got state %#x.\n", teststream2
.state
);
6209 hr
= reset_state(filter
);
6210 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6212 teststream
.set_state_result
= E_FAIL
;
6213 teststream
.state
= 0xcc;
6214 teststream2
.state
= 0xcc;
6215 hr
= set_state(filter
);
6216 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6217 ok(teststream
.state
== 0xcc, "Got state %#x.\n", teststream
.state
);
6218 ok(teststream2
.state
== expected_state
, "Got state %#x.\n", teststream2
.state
);
6219 hr
= IMediaStreamFilter_GetState(filter
, 0, &state
);
6220 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6221 ok(state
== expected_state
, "Got state %#x.\n", state
);
6223 hr
= reset_state(filter
);
6224 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6226 teststream
.set_state_result
= E_FAIL
;
6227 teststream2
.set_state_result
= E_FAIL
;
6228 teststream
.state
= 0xcc;
6229 teststream2
.state
= 0xcc;
6230 hr
= set_state(filter
);
6231 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6232 ok(teststream
.state
== 0xcc, "Got state %#x.\n", teststream
.state
);
6233 ok(teststream2
.state
== 0xcc, "Got state %#x.\n", teststream2
.state
);
6234 hr
= IMediaStreamFilter_GetState(filter
, 0, &state
);
6235 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6236 ok(state
== expected_state
, "Got state %#x.\n", state
);
6238 ref
= IAMMultiMediaStream_Release(mmstream
);
6239 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6240 ref
= IMediaStreamFilter_Release(filter
);
6241 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6242 ok(teststream
.refcount
== 1, "Got outstanding refcount %d.\n", teststream
.refcount
);
6243 ok(teststream2
.refcount
== 1, "Got outstanding refcount %d.\n", teststream2
.refcount
);
6246 static HRESULT
mediastreamfilter_stop(IMediaStreamFilter
*filter
)
6248 return IMediaStreamFilter_Stop(filter
);
6251 static HRESULT
mediastreamfilter_pause(IMediaStreamFilter
*filter
)
6253 return IMediaStreamFilter_Pause(filter
);
6256 static HRESULT
mediastreamfilter_run(IMediaStreamFilter
*filter
)
6258 return IMediaStreamFilter_Run(filter
, 0);
6261 void test_mediastreamfilter_stop_pause_run(void)
6263 check_mediastreamfilter_state(State_Stopped
, mediastreamfilter_stop
, mediastreamfilter_run
);
6264 check_mediastreamfilter_state(State_Paused
, mediastreamfilter_pause
, mediastreamfilter_stop
);
6265 check_mediastreamfilter_state(State_Running
, mediastreamfilter_run
, mediastreamfilter_stop
);
6268 static void test_mediastreamfilter_support_seeking(void)
6270 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6271 static const MSPID mspid1
= {0x88888888, 1};
6272 static const MSPID mspid2
= {0x88888888, 2};
6273 static const MSPID mspid3
= {0x88888888, 3};
6274 struct testfilter source1
, source2
, source3
;
6275 IAMMediaStream
*stream1
, *stream2
, *stream3
;
6276 IMediaStreamFilter
*filter
;
6277 IPin
*pin1
, *pin2
, *pin3
;
6278 ULONG ref
, seeking_ref
;
6279 IGraphBuilder
*graph
;
6282 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6283 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6284 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream1
);
6285 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6286 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream2
);
6287 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6288 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream3
);
6289 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6290 hr
= IAMMediaStream_Initialize(stream1
, NULL
, 0, &mspid1
, STREAMTYPE_READ
);
6291 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6292 hr
= IAMMediaStream_Initialize(stream2
, NULL
, 0, &mspid2
, STREAMTYPE_READ
);
6293 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6294 hr
= IAMMediaStream_Initialize(stream3
, NULL
, 0, &mspid3
, STREAMTYPE_READ
);
6295 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6296 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream1
, &mspid1
, 0, NULL
);
6297 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6298 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream2
, &mspid2
, 0, NULL
);
6299 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6300 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream3
, &mspid3
, 0, NULL
);
6301 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6302 hr
= IAMMediaStream_QueryInterface(stream1
, &IID_IPin
, (void **)&pin1
);
6303 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6304 hr
= IAMMediaStream_QueryInterface(stream2
, &IID_IPin
, (void **)&pin2
);
6305 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6306 hr
= IAMMediaStream_QueryInterface(stream3
, &IID_IPin
, (void **)&pin3
);
6307 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6308 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6309 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6310 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
6311 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6312 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
6313 testfilter_init(&source1
);
6314 testfilter_init(&source2
);
6315 testfilter_init(&source3
);
6316 source2
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6317 source3
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6318 hr
= IGraphBuilder_AddFilter(graph
, &source1
.filter
.IBaseFilter_iface
, NULL
);
6319 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6320 hr
= IGraphBuilder_AddFilter(graph
, &source2
.filter
.IBaseFilter_iface
, NULL
);
6321 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6322 hr
= IGraphBuilder_AddFilter(graph
, &source3
.filter
.IBaseFilter_iface
, NULL
);
6323 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6325 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6326 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
6328 hr
= IGraphBuilder_ConnectDirect(graph
, &source1
.source
.pin
.IPin_iface
, pin1
, &audio_mt
);
6329 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6331 source2
.get_duration_hr
= E_FAIL
;
6333 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6334 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
6336 hr
= IGraphBuilder_ConnectDirect(graph
, &source2
.source
.pin
.IPin_iface
, pin2
, &audio_mt
);
6337 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6339 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6340 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
6342 hr
= IGraphBuilder_ConnectDirect(graph
, &source3
.source
.pin
.IPin_iface
, pin3
, &audio_mt
);
6343 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6345 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
6347 seeking_ref
= get_refcount(&source3
.IMediaSeeking_iface
);
6349 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6350 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6352 check_interface(filter
, &IID_IMediaSeeking
, TRUE
);
6354 ref
= get_refcount(&source3
.IMediaSeeking_iface
);
6355 ok(ref
== seeking_ref
, "Expected outstanding refcount %d, got %d.\n", seeking_ref
, ref
);
6357 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6358 ok(hr
== HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED
), "Got hr %#x.\n", hr
);
6360 IGraphBuilder_Disconnect(graph
, pin1
);
6361 IGraphBuilder_Disconnect(graph
, &source1
.source
.pin
.IPin_iface
);
6363 IGraphBuilder_Disconnect(graph
, pin2
);
6364 IGraphBuilder_Disconnect(graph
, &source2
.source
.pin
.IPin_iface
);
6366 IGraphBuilder_Disconnect(graph
, pin3
);
6367 IGraphBuilder_Disconnect(graph
, &source3
.source
.pin
.IPin_iface
);
6369 ref
= IAMMultiMediaStream_Release(mmstream
);
6370 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6371 ref
= IGraphBuilder_Release(graph
);
6372 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6373 ref
= IMediaStreamFilter_Release(filter
);
6374 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6376 ref
= IAMMediaStream_Release(stream1
);
6377 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6379 ref
= IAMMediaStream_Release(stream2
);
6380 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6382 ref
= IAMMediaStream_Release(stream3
);
6383 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6386 static void check_mediastreamfilter_seeking(void (*check
)(IMediaSeeking
*seeking
, struct testfilter
*source1
,
6387 struct testfilter
*source2
, struct testfilter
*source3
, HRESULT source2_hr
, HRESULT expected_hr
))
6389 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6390 static const MSPID mspid1
= {0x88888888, 1};
6391 static const MSPID mspid2
= {0x88888888, 2};
6392 static const MSPID mspid3
= {0x88888888, 3};
6393 IMediaStreamFilter
*filter
;
6394 struct testfilter source1
;
6395 struct testfilter source2
;
6396 struct testfilter source3
;
6397 IAMMediaStream
*stream1
;
6398 IAMMediaStream
*stream2
;
6399 IAMMediaStream
*stream3
;
6400 IMediaSeeking
*seeking
;
6401 IGraphBuilder
*graph
;
6408 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6409 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6410 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream1
);
6411 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6412 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream2
);
6413 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6414 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream3
);
6415 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6416 hr
= IAMMediaStream_Initialize(stream1
, NULL
, 0, &mspid1
, STREAMTYPE_READ
);
6417 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6418 hr
= IAMMediaStream_Initialize(stream2
, NULL
, 0, &mspid2
, STREAMTYPE_READ
);
6419 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6420 hr
= IAMMediaStream_Initialize(stream3
, NULL
, 0, &mspid3
, STREAMTYPE_READ
);
6421 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6422 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream1
, &mspid1
, 0, NULL
);
6423 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6424 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream2
, &mspid2
, 0, NULL
);
6425 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6426 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream3
, &mspid3
, 0, NULL
);
6427 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6428 hr
= IAMMediaStream_QueryInterface(stream1
, &IID_IPin
, (void **)&pin1
);
6429 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6430 hr
= IAMMediaStream_QueryInterface(stream2
, &IID_IPin
, (void **)&pin2
);
6431 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6432 hr
= IAMMediaStream_QueryInterface(stream3
, &IID_IPin
, (void **)&pin3
);
6433 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6434 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6435 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6436 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
6437 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6438 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
6439 testfilter_init(&source1
);
6440 testfilter_init(&source2
);
6441 testfilter_init(&source3
);
6442 source1
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6443 source2
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6444 source3
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6445 hr
= IGraphBuilder_AddFilter(graph
, &source1
.filter
.IBaseFilter_iface
, NULL
);
6446 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6447 hr
= IGraphBuilder_AddFilter(graph
, &source2
.filter
.IBaseFilter_iface
, NULL
);
6448 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6449 hr
= IGraphBuilder_AddFilter(graph
, &source3
.filter
.IBaseFilter_iface
, NULL
);
6450 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6452 hr
= IGraphBuilder_ConnectDirect(graph
, &source2
.source
.pin
.IPin_iface
, pin2
, &audio_mt
);
6453 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6454 hr
= IGraphBuilder_ConnectDirect(graph
, &source3
.source
.pin
.IPin_iface
, pin3
, &audio_mt
);
6455 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6457 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6458 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6460 hr
= IGraphBuilder_ConnectDirect(graph
, &source1
.source
.pin
.IPin_iface
, pin1
, &audio_mt
);
6461 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6463 hr
= IMediaStreamFilter_QueryInterface(filter
, &IID_IMediaSeeking
, (void **)&seeking
);
6464 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6466 check(seeking
, &source1
, &source2
, &source3
, S_OK
, S_OK
);
6467 check(seeking
, &source1
, &source2
, &source3
, E_FAIL
, E_FAIL
);
6468 check(seeking
, &source1
, &source2
, &source3
, E_NOTIMPL
, E_NOTIMPL
);
6470 source2
.IMediaSeeking_iface
.lpVtbl
= NULL
;
6472 check(seeking
, &source1
, &source2
, &source3
, S_OK
, E_NOTIMPL
);
6474 source2
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6476 IGraphBuilder_Disconnect(graph
, pin2
);
6477 IGraphBuilder_Disconnect(graph
, &source2
.source
.pin
.IPin_iface
);
6479 check(seeking
, &source1
, &source2
, &source3
, S_OK
, E_NOTIMPL
);
6481 IGraphBuilder_Disconnect(graph
, pin2
);
6482 IGraphBuilder_Disconnect(graph
, &source2
.source
.pin
.IPin_iface
);
6483 IGraphBuilder_Disconnect(graph
, pin3
);
6484 IGraphBuilder_Disconnect(graph
, &source3
.source
.pin
.IPin_iface
);
6486 ref
= IAMMultiMediaStream_Release(mmstream
);
6487 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6488 ref
= IGraphBuilder_Release(graph
);
6489 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6490 IMediaSeeking_Release(seeking
);
6491 ref
= IMediaStreamFilter_Release(filter
);
6492 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6494 ref
= IAMMediaStream_Release(stream1
);
6495 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6497 ref
= IAMMediaStream_Release(stream2
);
6498 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6500 ref
= IAMMediaStream_Release(stream3
);
6501 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6504 static void check_mediastreamfilter_set_positions(IMediaSeeking
*seeking
, struct testfilter
*source1
,
6505 struct testfilter
*source2
, struct testfilter
*source3
, HRESULT source2_hr
, HRESULT expected_hr
)
6507 LONGLONG current_position
= 12345678;
6508 LONGLONG stop_position
= 87654321;
6511 source2
->set_positions_hr
= source2_hr
;
6512 source1
->current_position
= 0xdeadbeefdeadbeefULL
;
6513 source1
->stop_position
= 0xdeadbeefdeadbeefULL
;
6514 source2
->current_position
= 0xdeadbeefdeadbeefULL
;
6515 source2
->stop_position
= 0xdeadbeefdeadbeefULL
;
6516 source3
->current_position
= 0xdeadbeefdeadbeefULL
;
6517 source3
->stop_position
= 0xdeadbeefdeadbeefULL
;
6518 hr
= IMediaSeeking_SetPositions(seeking
, ¤t_position
, AM_SEEKING_AbsolutePositioning
,
6519 &stop_position
, AM_SEEKING_AbsolutePositioning
);
6520 ok(hr
== expected_hr
, "Got hr %#x.\n", hr
);
6521 ok(source1
->current_position
== 0xdeadbeefdeadbeefULL
, "Got current position %s.\n",
6522 wine_dbgstr_longlong(source1
->current_position
));
6523 ok(source1
->stop_position
== 0xdeadbeefdeadbeefULL
, "Got stop position %s.\n",
6524 wine_dbgstr_longlong(source1
->stop_position
));
6525 if (SUCCEEDED(expected_hr
))
6527 ok(source2
->current_position
== 12345678, "Got current position %s.\n",
6528 wine_dbgstr_longlong(source2
->current_position
));
6529 ok(source2
->stop_position
== 87654321, "Got stop position %s.\n",
6530 wine_dbgstr_longlong(source2
->stop_position
));
6532 ok(source3
->current_position
== 0xdeadbeefdeadbeefULL
, "Got current position %s.\n",
6533 wine_dbgstr_longlong(source3
->current_position
));
6534 ok(source3
->stop_position
== 0xdeadbeefdeadbeefULL
, "Got stop position %s.\n",
6535 wine_dbgstr_longlong(source3
->stop_position
));
6538 static void check_mediastreamfilter_get_duration(IMediaSeeking
*seeking
, struct testfilter
*source1
,
6539 struct testfilter
*source2
, struct testfilter
*source3
, HRESULT source2_hr
, HRESULT expected_hr
)
6541 LONGLONG duration
= 0xdeadbeefdeadbeefULL
;
6544 source2
->get_duration_hr
= source2_hr
;
6545 hr
= IMediaSeeking_GetDuration(seeking
, &duration
);
6546 ok(hr
== expected_hr
, "Got hr %#x.\n", hr
);
6547 if (SUCCEEDED(expected_hr
))
6548 ok(duration
== 0x8000000000000000ULL
, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
6550 ok(duration
== 0xdeadbeefdeadbeefULL
, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
6553 static void check_mediastreamfilter_get_stop_position(IMediaSeeking
*seeking
, struct testfilter
*source1
,
6554 struct testfilter
*source2
, struct testfilter
*source3
, HRESULT source2_hr
, HRESULT expected_hr
)
6556 LONGLONG stop
= 0xdeadbeefdeadbeefULL
;
6559 source2
->get_stop_position_hr
= source2_hr
;
6560 hr
= IMediaSeeking_GetStopPosition(seeking
, &stop
);
6561 ok(hr
== expected_hr
, "Got hr %#x.\n", hr
);
6562 if (SUCCEEDED(expected_hr
))
6563 ok(stop
== 0x8000000000000000ULL
, "Got stop position %s.\n", wine_dbgstr_longlong(stop
));
6565 ok(stop
== 0xdeadbeefdeadbeefULL
, "Got stop position %s.\n", wine_dbgstr_longlong(stop
));
6568 static void check_mediastreamfilter_is_format_supported(IMediaSeeking
*seeking
, struct testfilter
*source1
,
6569 struct testfilter
*source2
, struct testfilter
*source3
, HRESULT source2_hr
, HRESULT expected_hr
)
6573 source2
->is_format_supported_hr
= source2_hr
;
6574 hr
= IMediaSeeking_IsFormatSupported(seeking
, &TIME_FORMAT_MEDIA_TIME
);
6575 ok(hr
== expected_hr
, "Got hr %#x.\n", hr
);
6578 static void test_mediastreamfilter_seeking(void)
6580 check_mediastreamfilter_seeking(check_mediastreamfilter_set_positions
);
6581 check_mediastreamfilter_seeking(check_mediastreamfilter_get_duration
);
6582 check_mediastreamfilter_seeking(check_mediastreamfilter_get_stop_position
);
6583 check_mediastreamfilter_seeking(check_mediastreamfilter_is_format_supported
);
6586 static void test_mediastreamfilter_get_current_stream_time(void)
6588 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6589 STREAM_TIME filter_start_time
;
6590 IMediaStreamFilter
*filter
;
6591 IMediaFilter
*media_filter
;
6592 struct testclock clock
;
6593 IGraphBuilder
*graph
;
6598 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6599 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6600 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6601 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6602 ok(!!filter
, "Expected non-null filter.\n");
6603 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
6604 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6605 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
6606 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6607 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
6608 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
6609 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6610 testclock_init(&clock
);
6612 /* Crashes on native. */
6615 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, NULL
);
6616 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
6617 hr
= IAMMultiMediaStream_GetTime(mmstream
, NULL
);
6618 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
6621 time
= 0xdeadbeefdeadbeef;
6622 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &time
);
6623 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
6624 ok(time
== 0, "Got time %s.\n", wine_dbgstr_longlong(time
));
6625 time
= 0xdeadbeefdeadbeef;
6626 hr
= IAMMultiMediaStream_GetTime(mmstream
, &time
);
6627 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
6628 ok(time
== 0, "Got time %s.\n", wine_dbgstr_longlong(time
));
6630 hr
= IMediaFilter_SetSyncSource(media_filter
, &clock
.IReferenceClock_iface
);
6631 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6633 clock
.get_time_hr
= E_FAIL
;
6635 time
= 0xdeadbeefdeadbeef;
6636 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &time
);
6637 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
6638 ok(time
== 0, "Got time %s.\n", wine_dbgstr_longlong(time
));
6639 time
= 0xdeadbeefdeadbeef;
6640 hr
= IAMMultiMediaStream_GetTime(mmstream
, &time
);
6641 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
6642 ok(time
== 0, "Got time %s.\n", wine_dbgstr_longlong(time
));
6644 clock
.time
= 23456789;
6645 clock
.get_time_hr
= S_OK
;
6647 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
6648 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6650 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &filter_start_time
);
6651 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6653 clock
.time
= 34567890;
6655 time
= 0xdeadbeefdeadbeef;
6656 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &time
);
6657 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6658 ok(time
== 11111101 + filter_start_time
, "Got time %s.\n", wine_dbgstr_longlong(time
));
6659 time
= 0xdeadbeefdeadbeef;
6660 hr
= IAMMultiMediaStream_GetTime(mmstream
, &time
);
6661 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6662 ok(time
== 11111101 + filter_start_time
, "Got time %s.\n", wine_dbgstr_longlong(time
));
6664 ref
= IAMMultiMediaStream_Release(mmstream
);
6665 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6666 IMediaFilter_Release(media_filter
);
6667 ref
= IGraphBuilder_Release(graph
);
6668 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6669 ref
= IMediaStreamFilter_Release(filter
);
6670 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6673 static void test_mediastreamfilter_reference_time_to_stream_time(void)
6675 IMediaStreamFilter
*filter
;
6676 struct testclock clock
;
6677 REFERENCE_TIME time
;
6681 hr
= CoCreateInstance(&CLSID_MediaStreamFilter
, NULL
, CLSCTX_INPROC_SERVER
,
6682 &IID_IMediaStreamFilter
, (void **)&filter
);
6683 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6684 testclock_init(&clock
);
6686 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, NULL
);
6687 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
6689 time
= 0xdeadbeefdeadbeef;
6690 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, &time
);
6691 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
6692 ok(time
== 0xdeadbeefdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(time
));
6694 hr
= IMediaStreamFilter_SetSyncSource(filter
, &clock
.IReferenceClock_iface
);
6695 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6697 clock
.get_time_hr
= E_FAIL
;
6699 /* Crashes on native. */
6702 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, NULL
);
6703 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
6706 time
= 0xdeadbeefdeadbeef;
6707 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, &time
);
6708 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6709 ok(time
== 0xdeadbeefdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(time
));
6711 hr
= IMediaStreamFilter_Run(filter
, 23456789);
6712 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6714 time
= 0xdeadbeefdeadbeef;
6715 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, &time
);
6716 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6717 ok(time
== 0xdeadbeefdd47d2da, "Got time %s.\n", wine_dbgstr_longlong(time
));
6719 clock
.time
= 34567890;
6720 clock
.get_time_hr
= S_OK
;
6722 time
= 0xdeadbeefdeadbeef;
6723 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, &time
);
6724 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6725 ok(time
== 0xdeadbeefdd47d2da, "Got time %s.\n", wine_dbgstr_longlong(time
));
6727 ref
= IMediaStreamFilter_Release(filter
);
6728 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6731 struct mediastreamfilter_wait_until_params
6733 IMediaStreamFilter
*filter
;
6734 REFERENCE_TIME time
;
6735 HRESULT expected_hr
;
6738 static DWORD CALLBACK
mediastreamfilter_wait_until(void *p
)
6740 struct mediastreamfilter_wait_until_params
*params
= (struct mediastreamfilter_wait_until_params
*)p
;
6743 hr
= IMediaStreamFilter_WaitUntil(params
->filter
, params
->time
);
6744 ok(hr
== params
->expected_hr
, "Got hr %#x.\n", hr
);
6749 static void test_mediastreamfilter_wait_until(void)
6751 struct mediastreamfilter_wait_until_params params1
;
6752 struct mediastreamfilter_wait_until_params params2
;
6753 struct advise_time_cookie cookie1
= { 0 };
6754 struct advise_time_cookie cookie2
= { 0 };
6755 IMediaStreamFilter
*filter
;
6756 struct testclock clock
;
6762 hr
= CoCreateInstance(&CLSID_MediaStreamFilter
, NULL
, CLSCTX_INPROC_SERVER
,
6763 &IID_IMediaStreamFilter
, (void **)&filter
);
6764 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6765 testclock_init(&clock
);
6766 cookie1
.advise_time_called_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6767 cookie2
.advise_time_called_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
6769 hr
= IMediaStreamFilter_Run(filter
, 12345678);
6770 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6772 hr
= IMediaStreamFilter_WaitUntil(filter
, 23456789);
6773 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
6775 hr
= IMediaStreamFilter_Stop(filter
);
6776 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6778 hr
= IMediaStreamFilter_SetSyncSource(filter
, &clock
.IReferenceClock_iface
);
6779 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6781 clock
.advise_time_cookie
= &cookie1
;
6783 params1
.filter
= filter
;
6784 params1
.time
= 23456789;
6785 params1
.expected_hr
= S_OK
;
6786 thread1
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms1
, 0, NULL
);
6787 ok(!WaitForSingleObject(cookie1
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
6788 ok(WaitForSingleObject(thread1
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
6790 ok(cookie1
.base
== 23456789, "Got base %s.\n", wine_dbgstr_longlong(cookie1
.base
));
6791 ok(cookie1
.offset
== 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie1
.offset
));
6792 ok(!!cookie1
.event
, "Expected non-NULL event.\n");
6794 SetEvent(cookie1
.event
);
6796 ok(!WaitForSingleObject(thread1
, 2000), "Wait timed out.\n");
6797 CloseHandle(thread1
);
6799 ok(!cookie1
.unadvise_called
, "Unexpected Unadvise call.\n");
6801 hr
= IMediaStreamFilter_Run(filter
, 12345678);
6802 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6804 clock
.time
= 30000000;
6806 clock
.advise_time_cookie
= &cookie1
;
6808 params1
.filter
= filter
;
6809 params1
.time
= 23456789;
6810 params1
.expected_hr
= S_OK
;
6811 thread1
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms1
, 0, NULL
);
6812 ok(!WaitForSingleObject(cookie1
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
6813 ok(WaitForSingleObject(thread1
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
6815 ok(cookie1
.base
== 23456789, "Got base %s.\n", wine_dbgstr_longlong(cookie1
.base
));
6816 ok(cookie1
.offset
== 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie1
.offset
));
6817 ok(!!cookie1
.event
, "Expected non-NULL event.\n");
6819 clock
.advise_time_cookie
= &cookie2
;
6821 params2
.filter
= filter
;
6822 params2
.time
= 11111111;
6823 params2
.expected_hr
= S_OK
;
6824 thread2
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms2
, 0, NULL
);
6825 ok(!WaitForSingleObject(cookie2
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
6826 ok(WaitForSingleObject(thread2
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
6828 ok(cookie2
.base
== 11111111, "Got base %s.\n", wine_dbgstr_longlong(cookie2
.base
));
6829 ok(cookie2
.offset
== 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie2
.offset
));
6830 ok(!!cookie2
.event
, "Expected non-NULL event.\n");
6832 SetEvent(cookie1
.event
);
6834 ok(!WaitForSingleObject(thread1
, 2000), "Wait timed out.\n");
6835 CloseHandle(thread1
);
6837 ok(WaitForSingleObject(thread2
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
6839 SetEvent(cookie2
.event
);
6841 ok(!WaitForSingleObject(thread2
, 2000), "Wait timed out.\n");
6842 CloseHandle(thread2
);
6844 clock
.advise_time_cookie
= &cookie1
;
6846 params1
.filter
= filter
;
6847 params1
.time
= 23456789;
6848 params1
.expected_hr
= S_FALSE
;
6849 thread1
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms1
, 0, NULL
);
6850 ok(!WaitForSingleObject(cookie1
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
6851 ok(WaitForSingleObject(thread1
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
6853 clock
.advise_time_cookie
= &cookie2
;
6855 params2
.filter
= filter
;
6856 params2
.time
= 23456789;
6857 params2
.expected_hr
= S_FALSE
;
6858 thread2
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms2
, 0, NULL
);
6859 ok(!WaitForSingleObject(cookie2
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
6860 ok(WaitForSingleObject(thread2
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
6862 hr
= IMediaStreamFilter_Flush(filter
, FALSE
);
6863 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6865 ok(cookie1
.unadvise_called
, "Expected Unadvise to be called.\n");
6866 ok(cookie2
.unadvise_called
, "Expected Unadvise to be called.\n");
6868 ok(!WaitForSingleObject(thread1
, 2000), "Wait timed out.\n");
6869 CloseHandle(thread1
);
6870 ok(!WaitForSingleObject(thread2
, 2000), "Wait timed out.\n");
6871 CloseHandle(thread2
);
6873 clock
.advise_time_cookie
= &cookie1
;
6875 params1
.filter
= filter
;
6876 params1
.time
= 23456789;
6877 params1
.expected_hr
= S_FALSE
;
6878 thread1
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms1
, 0, NULL
);
6879 ok(!WaitForSingleObject(cookie1
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
6880 ok(WaitForSingleObject(thread1
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
6882 clock
.advise_time_cookie
= &cookie2
;
6884 params2
.filter
= filter
;
6885 params2
.time
= 23456789;
6886 params2
.expected_hr
= S_FALSE
;
6887 thread2
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms2
, 0, NULL
);
6888 ok(!WaitForSingleObject(cookie2
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
6889 ok(WaitForSingleObject(thread2
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
6891 hr
= IMediaStreamFilter_Stop(filter
);
6892 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6894 ok(cookie1
.unadvise_called
, "Expected Unadvise to be called.\n");
6895 ok(cookie2
.unadvise_called
, "Expected Unadvise to be called.\n");
6897 ok(!WaitForSingleObject(thread1
, 2000), "Wait timed out.\n");
6898 CloseHandle(thread1
);
6899 ok(!WaitForSingleObject(thread2
, 2000), "Wait timed out.\n");
6900 CloseHandle(thread2
);
6902 CloseHandle(cookie1
.advise_time_called_event
);
6903 CloseHandle(cookie2
.advise_time_called_event
);
6905 ref
= IMediaStreamFilter_Release(filter
);
6906 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
6909 static void test_mediastreamfilter_end_of_stream(void)
6911 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6912 struct testfilter source1
, source2
;
6913 IMediaStream
*stream1
, *stream2
;
6914 IMediaControl
*media_control
;
6915 IMediaStreamFilter
*filter
;
6922 hr
= IFilterGraph2_QueryInterface(&graph
.IFilterGraph2_iface
, &IID_IMediaControl
, (void **)&media_control
);
6923 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6925 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, (IGraphBuilder
*)&graph
.IFilterGraph2_iface
);
6926 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6927 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream1
);
6928 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6929 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream2
);
6930 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6931 hr
= IMediaStream_QueryInterface(stream1
, &IID_IPin
, (void **)&pin1
);
6932 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6933 hr
= IMediaStream_QueryInterface(stream2
, &IID_IPin
, (void **)&pin2
);
6934 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6935 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6936 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6937 ok(filter
!= NULL
, "Expected non-null filter\n");
6938 testfilter_init(&source1
);
6939 testfilter_init(&source2
);
6940 hr
= IFilterGraph2_AddFilter(&graph
.IFilterGraph2_iface
, &source1
.filter
.IBaseFilter_iface
, NULL
);
6941 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6942 hr
= IFilterGraph2_AddFilter(&graph
.IFilterGraph2_iface
, &source2
.filter
.IBaseFilter_iface
, NULL
);
6943 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6945 hr
= IPin_Connect(&source1
.source
.pin
.IPin_iface
, pin1
, &audio_mt
);
6946 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6947 hr
= IPin_Connect(&source2
.source
.pin
.IPin_iface
, pin2
, &rgb32_mt
);
6948 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6950 /* Initially, EC_COMPLETE notifications are disabled. */
6951 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
6952 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6954 graph
.got_notify
= 0;
6956 hr
= IMediaStreamFilter_EndOfStream(filter
);
6957 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6958 hr
= IMediaStreamFilter_EndOfStream(filter
);
6959 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6961 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
6963 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
6964 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6966 /* Unsuccsessful call to SupportSeeking does not enable EC_COMPLETE notifications. */
6967 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6968 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
6970 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
6971 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6973 graph
.got_notify
= 0;
6975 hr
= IMediaStreamFilter_EndOfStream(filter
);
6976 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6977 hr
= IMediaStreamFilter_EndOfStream(filter
);
6978 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6980 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
6982 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
6983 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6985 /* Successful call to SupportSeeking enables EC_COMPLETE notifications. */
6986 source1
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6988 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6989 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6991 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
6992 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6994 graph
.got_notify
= 0;
6996 hr
= IMediaStreamFilter_EndOfStream(filter
);
6997 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
6999 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7001 hr
= IMediaStreamFilter_EndOfStream(filter
);
7002 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7004 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7006 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7007 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7009 /* EC_COMPLETE is sent on paused->running state transition
7010 * if EndOfStream has been called for all streams. */
7011 graph
.got_notify
= 0;
7013 hr
= IMediaStreamFilter_EndOfStream(filter
);
7014 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7015 hr
= IMediaStreamFilter_EndOfStream(filter
);
7016 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7018 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7020 hr
= IMediaControl_Pause(media_control
);
7021 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7023 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7025 hr
= IMediaControl_Run(media_control
);
7026 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7028 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7030 hr
= IMediaControl_Run(media_control
);
7031 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7033 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7035 hr
= IMediaControl_Stop(media_control
);
7036 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7038 /* EC_COMPLETE is sent on paused->running state transition
7039 * if EndOfStream has been called for all streams. */
7040 graph
.got_notify
= 0;
7042 hr
= IMediaStreamFilter_EndOfStream(filter
);
7043 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7044 hr
= IMediaStreamFilter_EndOfStream(filter
);
7045 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7047 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7049 hr
= IMediaControl_Pause(media_control
);
7050 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7052 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7054 hr
= IMediaControl_Run(media_control
);
7055 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7057 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7059 hr
= IMediaControl_Stop(media_control
);
7060 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7062 /* EndOfStream count is reset on paused->stopped state transition. */
7063 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7064 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7066 graph
.got_notify
= 0;
7068 hr
= IMediaStreamFilter_EndOfStream(filter
);
7069 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7071 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7072 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7073 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7074 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7076 hr
= IMediaStreamFilter_EndOfStream(filter
);
7077 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7079 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7081 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7082 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7084 /* EOS count is not reset on running->paused state transition. */
7085 hr
= IMediaControl_Run(media_control
);
7086 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7088 graph
.got_notify
= 0;
7090 hr
= IMediaStreamFilter_EndOfStream(filter
);
7091 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7093 hr
= IMediaControl_Pause(media_control
);
7094 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7095 hr
= IMediaControl_Run(media_control
);
7096 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7098 hr
= IMediaStreamFilter_EndOfStream(filter
);
7099 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7101 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7103 hr
= IMediaControl_Stop(media_control
);
7104 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7106 /* EndOfStream count is not reset when Stop() is called on an already stopped filter. */
7107 hr
= IMediaStreamFilter_EndOfStream(filter
);
7108 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7110 hr
= IMediaStreamFilter_Stop(filter
);
7111 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7113 hr
= IMediaStreamFilter_EndOfStream(filter
);
7114 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7116 graph
.got_notify
= 0;
7118 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7119 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7121 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7123 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7124 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7126 /* Flush with cancel_eos=TRUE decrements EOS count. */
7127 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7128 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7130 graph
.got_notify
= 0;
7132 hr
= IMediaStreamFilter_EndOfStream(filter
);
7133 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7135 hr
= IMediaStreamFilter_Flush(filter
, TRUE
);
7137 hr
= IMediaStreamFilter_EndOfStream(filter
);
7138 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7140 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7142 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7143 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7145 /* Flush followed by EndOfStream causes another EC_COMPLETE to be sent. */
7146 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7147 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7149 graph
.got_notify
= 0;
7151 hr
= IMediaStreamFilter_EndOfStream(filter
);
7152 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7153 hr
= IMediaStreamFilter_EndOfStream(filter
);
7154 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7156 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7158 hr
= IMediaStreamFilter_Flush(filter
, TRUE
);
7159 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7161 hr
= IMediaStreamFilter_EndOfStream(filter
);
7162 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7164 ok(graph
.got_notify
== 2, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7166 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7167 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7169 /* Flush decrements EOS count event when it is 0. */
7170 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7171 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7173 graph
.got_notify
= 0;
7175 hr
= IMediaStreamFilter_Flush(filter
, TRUE
);
7176 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7178 hr
= IMediaStreamFilter_EndOfStream(filter
);
7179 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7180 hr
= IMediaStreamFilter_EndOfStream(filter
);
7181 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7183 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7185 hr
= IMediaStreamFilter_EndOfStream(filter
);
7186 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7188 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7190 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7191 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7193 /* Flush with cancel_eos=FALSE does not decrement EOS count. */
7194 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7195 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7197 graph
.got_notify
= 0;
7199 hr
= IMediaStreamFilter_EndOfStream(filter
);
7200 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7202 hr
= IMediaStreamFilter_Flush(filter
, FALSE
);
7204 hr
= IMediaStreamFilter_EndOfStream(filter
);
7205 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7207 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7209 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7210 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7212 ref
= IAMMultiMediaStream_Release(mmstream
);
7213 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7214 IMediaControl_Release(media_control
);
7215 graph_destroy(&graph
);
7216 ref
= IMediaStreamFilter_Release(filter
);
7217 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7219 ref
= IMediaStream_Release(stream1
);
7220 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7222 ref
= IMediaStream_Release(stream2
);
7223 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7226 static void test_ddrawstream_getsetdirectdraw(void)
7228 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7229 IDirectDraw
*ddraw
, *ddraw2
, *ddraw3
, *ddraw4
;
7230 IDirectDrawMediaStream
*ddraw_stream
;
7231 IDirectDrawStreamSample
*sample
;
7232 IDirectDraw7
*ddraw7
;
7233 IMediaStream
*stream
;
7237 hr
= DirectDrawCreate(NULL
, &ddraw
, NULL
);
7238 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7239 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirectDraw7
, (void **)&ddraw7
);
7240 ok(hr
== DD_OK
, "Got hr %#x.\n", hr
);
7241 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, GetDesktopWindow(), DDSCL_NORMAL
);
7242 ok(hr
== DD_OK
, "Got hr %#x.\n", hr
);
7243 EXPECT_REF(ddraw
, 1);
7244 EXPECT_REF(ddraw7
, 1);
7246 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7247 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7249 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)ddraw7
, &MSPID_PrimaryVideo
, 0, &stream
);
7250 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7251 EXPECT_REF(ddraw
, 2);
7253 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
7254 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7256 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, NULL
);
7257 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
7259 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw2
);
7260 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7261 ok(ddraw2
== ddraw
, "Expected ddraw %p, got %p.\n", ddraw
, ddraw2
);
7262 EXPECT_REF(ddraw
, 3);
7264 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw3
);
7265 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7266 ok(ddraw3
== ddraw2
, "Expected ddraw %p, got %p.\n", ddraw2
, ddraw3
);
7267 EXPECT_REF(ddraw
, 4);
7268 IDirectDraw_Release(ddraw3
);
7269 EXPECT_REF(ddraw
, 3);
7271 /* The current ddraw is released when SetDirectDraw() is called. */
7272 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, NULL
);
7273 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7274 EXPECT_REF(ddraw
, 2);
7276 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw3
);
7277 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7278 ok(ddraw3
== NULL
, "Expected NULL, got %p.\n", ddraw3
);
7280 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, ddraw2
);
7281 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7282 EXPECT_REF(ddraw
, 3);
7284 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw3
);
7285 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7286 ok(ddraw3
== ddraw2
, "Expected ddraw %p, got %p.\n", ddraw2
, ddraw3
);
7287 EXPECT_REF(ddraw
, 4);
7288 IDirectDraw_Release(ddraw3
);
7289 EXPECT_REF(ddraw
, 3);
7291 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &sample
);
7292 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7294 /* SetDirectDraw() doesn't take an extra reference to the ddraw object
7295 * if there are samples extant. */
7296 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, ddraw2
);
7297 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7298 EXPECT_REF(ddraw
, 3);
7300 hr
= DirectDrawCreate(NULL
, &ddraw3
, NULL
);
7301 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7302 hr
= IDirectDraw_SetCooperativeLevel(ddraw3
, GetDesktopWindow(), DDSCL_NORMAL
);
7303 ok(hr
== DD_OK
, "Got hr %#x.\n", hr
);
7304 EXPECT_REF(ddraw3
, 1);
7306 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, ddraw3
);
7307 ok(hr
== MS_E_SAMPLEALLOC
, "Got hr %#x.\n", hr
);
7309 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw4
);
7310 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7311 ok(ddraw4
== ddraw2
, "Expected ddraw %p, got %p.\n", ddraw2
, ddraw4
);
7312 EXPECT_REF(ddraw
, 4);
7313 IDirectDraw_Release(ddraw4
);
7314 EXPECT_REF(ddraw
, 3);
7316 ref
= IDirectDrawStreamSample_Release(sample
);
7317 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7319 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, ddraw3
);
7320 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7321 EXPECT_REF(ddraw
, 2);
7322 EXPECT_REF(ddraw3
, 2);
7324 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw4
);
7325 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7326 ok(ddraw4
== ddraw3
, "Expected ddraw %p, got %p.\n", ddraw3
, ddraw4
);
7327 EXPECT_REF(ddraw3
, 3);
7328 IDirectDraw_Release(ddraw4
);
7329 EXPECT_REF(ddraw3
, 2);
7331 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, NULL
);
7332 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7333 EXPECT_REF(ddraw3
, 1);
7335 ref
= IDirectDraw_Release(ddraw3
);
7336 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7338 EXPECT_REF(stream
, 3);
7339 IDirectDrawMediaStream_Release(ddraw_stream
);
7340 EXPECT_REF(stream
, 2);
7341 ref
= IAMMultiMediaStream_Release(mmstream
);
7342 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7343 EXPECT_REF(stream
, 1);
7344 ref
= IMediaStream_Release(stream
);
7345 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7346 ref
= IDirectDraw7_Release(ddraw7
);
7347 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7348 IDirectDraw_Release(ddraw2
);
7349 EXPECT_REF(ddraw
, 1);
7350 ref
= IDirectDraw_Release(ddraw
);
7351 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7354 static void test_audiostreamsample_get_media_stream(void)
7356 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7357 IAudioStreamSample
*audio_sample
;
7358 IAudioMediaStream
*audio_stream
;
7359 IMediaStream
*stream
, *stream2
;
7360 IAudioData
*audio_data
;
7364 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7365 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7367 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
7368 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7370 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
7371 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7373 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
7374 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7376 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &audio_sample
);
7377 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7379 /* Crashes on native. */
7382 hr
= IAudioStreamSample_GetMediaStream(audio_sample
, NULL
);
7383 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
7386 EXPECT_REF(stream
, 4);
7387 hr
= IAudioStreamSample_GetMediaStream(audio_sample
, &stream2
);
7388 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7389 ok(stream2
== stream
, "Expected stream %p, got %p.\n", stream
, stream2
);
7390 EXPECT_REF(stream
, 5);
7392 IMediaStream_Release(stream2
);
7394 IAudioMediaStream_Release(audio_stream
);
7395 ref
= IAudioStreamSample_Release(audio_sample
);
7396 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7397 ref
= IAudioData_Release(audio_data
);
7398 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7399 ref
= IAMMultiMediaStream_Release(mmstream
);
7400 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7401 ref
= IMediaStream_Release(stream
);
7402 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7405 static void test_audiostreamsample_get_audio_data(void)
7407 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7408 IAudioData
*audio_data
, *audio_data2
;
7409 IAudioStreamSample
*audio_sample
;
7410 IAudioMediaStream
*audio_stream
;
7411 IMediaStream
*stream
;
7415 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7416 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7418 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
7419 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7421 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
7422 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7424 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
7425 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7427 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &audio_sample
);
7428 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7430 hr
= IAudioStreamSample_GetAudioData(audio_sample
, NULL
);
7431 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
7433 EXPECT_REF(audio_data
, 2);
7434 hr
= IAudioStreamSample_GetAudioData(audio_sample
, &audio_data2
);
7435 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7436 ok(audio_data2
== audio_data
, "Expected audio data %p, got %p.\n", audio_data
, audio_data2
);
7437 EXPECT_REF(audio_data
, 3);
7439 IAudioData_Release(audio_data2
);
7441 IAudioMediaStream_Release(audio_stream
);
7442 ref
= IAudioStreamSample_Release(audio_sample
);
7443 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7444 ref
= IAudioData_Release(audio_data
);
7445 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7446 ref
= IAMMultiMediaStream_Release(mmstream
);
7447 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7448 ref
= IMediaStream_Release(stream
);
7449 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7452 #define get_ddrawstream_create_sample_desc(a,b,c,d) get_ddrawstream_create_sample_desc_(__LINE__,a,b,c,d)
7453 static void get_ddrawstream_create_sample_desc_(int line
, const DDSURFACEDESC
*format1
,
7454 const DDSURFACEDESC
*format2
, const AM_MEDIA_TYPE
*mt
, DDSURFACEDESC
*desc
)
7456 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7457 IDirectDrawMediaStream
*ddraw_stream
;
7458 IDirectDrawStreamSample
*sample
;
7459 IDirectDrawSurface
*surface
;
7460 struct testfilter source
;
7461 IGraphBuilder
*graph
;
7462 IMediaStream
*stream
;
7467 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7468 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7469 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
7470 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7471 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
7472 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7473 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
7474 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7475 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
7476 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7478 testfilter_init(&source
);
7480 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
7481 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7485 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, format1
, NULL
);
7486 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7490 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, format2
, NULL
);
7491 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7495 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, mt
);
7496 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7498 hr
= IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
7499 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7500 hr
= IGraphBuilder_Disconnect(graph
, pin
);
7501 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7504 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &sample
);
7505 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7507 hr
= IDirectDrawStreamSample_GetSurface(sample
, &surface
, NULL
);
7508 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7509 ok_(__FILE__
, line
)(!!surface
, "Expected non-NULL sufrace.\n");
7511 desc
->dwSize
= sizeof(*desc
);
7512 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, desc
);
7513 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
7515 ref
= IDirectDrawStreamSample_Release(sample
);
7516 ok_(__FILE__
, line
)(!ref
, "Got outstanding refcount %d.\n", ref
);
7517 ref
= IDirectDrawSurface_Release(surface
);
7518 ok_(__FILE__
, line
)(!ref
, "Got outstanding refcount %d.\n", ref
);
7519 ref
= IAMMultiMediaStream_Release(mmstream
);
7520 ok_(__FILE__
, line
)(!ref
, "Got outstanding refcount %d.\n", ref
);
7521 ref
= IGraphBuilder_Release(graph
);
7522 ok_(__FILE__
, line
)(!ref
, "Got outstanding refcount %d.\n", ref
);
7524 IDirectDrawMediaStream_Release(ddraw_stream
);
7525 ref
= IMediaStream_Release(stream
);
7526 ok_(__FILE__
, line
)(!ref
, "Got outstanding refcount %d.\n", ref
);
7529 static void test_ddrawstream_create_sample(void)
7531 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7532 DDSURFACEDESC desc2
= { sizeof(desc2
) };
7533 IDirectDrawSurface
*surface
, *surface2
;
7534 DDSURFACEDESC desc
= { sizeof(desc
) };
7535 IDirectDrawMediaStream
*ddraw_stream
;
7536 IDirectDrawStreamSample
*sample
;
7537 DDSURFACEDESC format1
;
7538 DDSURFACEDESC format2
;
7539 IMediaStream
*stream
;
7545 hr
= DirectDrawCreate(NULL
, &ddraw
, NULL
);
7546 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7548 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
7549 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7551 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7552 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7554 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)ddraw
, &MSPID_PrimaryVideo
, 0, &stream
);
7555 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7557 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
7558 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7560 /* Crashes on native. */
7563 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, NULL
);
7564 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
7567 SetRectEmpty(&rect
);
7568 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, &rect
, 0, &sample
);
7569 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
7571 EXPECT_REF(mmstream
, 1);
7572 EXPECT_REF(stream
, 3);
7573 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &sample
);
7574 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7575 EXPECT_REF(mmstream
, 2);
7576 EXPECT_REF(stream
, 4);
7578 hr
= IDirectDrawStreamSample_GetSurface(sample
, NULL
, NULL
);
7579 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7581 hr
= IDirectDrawStreamSample_GetSurface(sample
, NULL
, &rect
);
7582 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7584 hr
= IDirectDrawStreamSample_GetSurface(sample
, &surface
, NULL
);
7585 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7586 ok(surface
!= NULL
, "Expected non-NULL surface.\n");
7587 IDirectDrawSurface_Release(surface
);
7590 hr
= IDirectDrawStreamSample_GetSurface(sample
, &surface
, &rect
);
7591 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7592 ok(surface
!= NULL
, "Expected non-NULL surface.\n");
7594 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
);
7595 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7596 ok(desc
.dwWidth
== 100, "Expected width 100, got %d.\n", desc
.dwWidth
);
7597 ok(desc
.dwHeight
== 100, "Expected height 100, got %d.\n", desc
.dwHeight
);
7598 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Expected format flags DDPF_RGB, got %#x.\n", desc
.ddpfPixelFormat
.dwFlags
);
7599 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
, "Expected non-zero RGB bit count.\n");
7600 IDirectDrawSurface_Release(surface
);
7601 IDirectDrawStreamSample_Release(sample
);
7602 EXPECT_REF(stream
, 3);
7604 memset(&desc
, 0, sizeof(desc
));
7605 desc
.dwSize
= sizeof(desc
);
7606 desc
.dwFlags
= DDSD_CAPS
;
7607 desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
7608 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
);
7609 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7611 EXPECT_REF(surface
, 1);
7612 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, surface
, NULL
, 0, &sample
);
7613 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7614 EXPECT_REF(surface
, 2);
7617 SetRectEmpty(&rect
);
7618 hr
= IDirectDrawStreamSample_GetSurface(sample
, &surface2
, &rect
);
7619 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7620 ok(surface2
== surface
, "Expected surface %p, got %p.\n", surface
, surface2
);
7621 ok(rect
.right
> 0 && rect
.bottom
> 0, "Got rect %d, %d.\n", rect
.right
, rect
.bottom
);
7622 EXPECT_REF(surface
, 3);
7623 IDirectDrawSurface_Release(surface2
);
7624 EXPECT_REF(surface
, 2);
7625 IDirectDrawStreamSample_Release(sample
);
7626 EXPECT_REF(surface
, 1);
7628 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, surface
, &rect
, 0, &sample
);
7629 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7631 ref
= IDirectDrawStreamSample_Release(sample
);
7632 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7633 ref
= IDirectDrawSurface_Release(surface
);
7634 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7636 memset(&desc
, 0, sizeof(desc
));
7637 desc
.dwSize
= sizeof(desc
);
7638 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
;
7640 desc
.dwHeight
= 400;
7641 desc
.ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
);
7642 desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
7643 desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
= 32;
7644 desc
.ddpfPixelFormat
.u2
.dwRBitMask
= 0xff0000;
7645 desc
.ddpfPixelFormat
.u3
.dwGBitMask
= 0x00ff00;
7646 desc
.ddpfPixelFormat
.u4
.dwBBitMask
= 0x0000ff;
7647 desc
.ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
= 0xff000000;
7648 desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7649 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
);
7650 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7652 SetRect(&rect
, 111, 100, 333, 300);
7654 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, surface
, &rect
, 0, &sample
);
7655 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7656 ref
= IDirectDrawStreamSample_Release(sample
);
7657 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7659 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &sample
);
7660 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7662 hr
= IDirectDrawStreamSample_GetSurface(sample
, &surface2
, &rect
);
7663 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7665 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
);
7666 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7667 hr
= IDirectDrawSurface_GetSurfaceDesc(surface2
, &desc2
);
7668 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7669 ok(desc2
.dwWidth
== 222, "Got width %u.\n", desc2
.dwWidth
);
7670 ok(desc2
.dwHeight
== 200, "Got height %u.\n", desc2
.dwHeight
);
7671 ok(memcmp(&desc2
.ddpfPixelFormat
, &desc
.ddpfPixelFormat
, sizeof(DDPIXELFORMAT
)) == 0,
7672 "Pixel format didn't match.\n");
7674 ref
= IDirectDrawStreamSample_Release(sample
);
7675 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7676 ref
= IDirectDrawSurface_Release(surface
);
7677 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7678 ref
= IDirectDrawSurface_Release(surface2
);
7679 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7681 memset(&desc
, 0, sizeof(desc
));
7682 desc
.dwSize
= sizeof(desc
);
7683 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
;
7685 desc
.dwHeight
= 400;
7686 desc
.ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
);
7687 desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED4
;
7688 desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
= 4;
7689 desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7690 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
);
7691 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7693 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, surface
, NULL
, 0, &sample
);
7694 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got hr %#x.\n", hr
);
7696 IDirectDrawMediaStream_Release(ddraw_stream
);
7697 ref
= IDirectDrawSurface_Release(surface
);
7698 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7699 ref
= IAMMultiMediaStream_Release(mmstream
);
7700 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7701 ref
= IMediaStream_Release(stream
);
7702 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7703 ref
= IDirectDraw_Release(ddraw
);
7704 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7706 format1
= rgb8_format
;
7707 format1
.dwFlags
= 0;
7708 format1
.dwWidth
= 333;
7709 format1
.dwHeight
= 444;
7710 get_ddrawstream_create_sample_desc(&format1
, NULL
, NULL
, &desc
);
7711 ok(desc
.dwWidth
== 100, "Got width %u.\n", desc
.dwWidth
);
7712 ok(desc
.dwHeight
== 100, "Got height %u.\n", desc
.dwHeight
);
7713 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got flags %#x.\n", desc
.ddpfPixelFormat
.dwFlags
);
7714 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 32, "Got rgb bit count %u.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
7715 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xff0000, "Got r bit mask %#x.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
7716 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x00ff00, "Got g bit mask %#x.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
7717 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x0000ff, "Got b bit mask %#x.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
7719 format1
= rgb8_format
;
7720 format1
.dwFlags
|= DDSD_WIDTH
;
7721 format1
.dwWidth
= 333;
7722 format1
.dwHeight
= 444;
7723 format2
= rgb8_format
;
7724 format2
.dwFlags
= 0;
7725 get_ddrawstream_create_sample_desc(&format1
, &format2
, NULL
, &desc
);
7726 ok(desc
.dwWidth
== 333, "Got width %u.\n", desc
.dwWidth
);
7727 ok(desc
.dwHeight
== 444, "Got height %u.\n", desc
.dwHeight
);
7729 format1
= rgb8_format
;
7730 format1
.dwFlags
|= DDSD_HEIGHT
;
7731 format1
.dwWidth
= 333;
7732 format1
.dwHeight
= 444;
7733 format2
= rgb8_format
;
7734 format2
.dwFlags
= 0;
7735 get_ddrawstream_create_sample_desc(&format1
, &format2
, NULL
, &desc
);
7736 ok(desc
.dwWidth
== 333, "Got width %u.\n", desc
.dwWidth
);
7737 ok(desc
.dwHeight
== 444, "Got height %u.\n", desc
.dwHeight
);
7739 get_ddrawstream_create_sample_desc(NULL
, NULL
, &rgb8_mt
, &desc
);
7740 ok(desc
.dwWidth
== 333, "Got width %u.\n", desc
.dwWidth
);
7741 ok(desc
.dwHeight
== 444, "Got height %u.\n", desc
.dwHeight
);
7742 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got flags %#x.\n", desc
.ddpfPixelFormat
.dwFlags
);
7743 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 32, "Got rgb bit count %u.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
7744 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xff0000, "Got r bit mask %#x.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
7745 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x00ff00, "Got g bit mask %#x.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
7746 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x0000ff, "Got b bit mask %#x.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
7748 get_ddrawstream_create_sample_desc(&rgb565_format
, NULL
, NULL
, &desc
);
7749 ok(desc
.dwWidth
== 100, "Got width %u.\n", desc
.dwWidth
);
7750 ok(desc
.dwHeight
== 100, "Got height %u.\n", desc
.dwHeight
);
7751 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got flags %#x.\n", desc
.ddpfPixelFormat
.dwFlags
);
7752 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 16, "Got rgb bit count %u.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
7753 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xf800, "Got r bit mask %#x.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
7754 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x07e0, "Got g bit mask %#x.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
7755 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x001f, "Got b bit mask %#x.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
7757 get_ddrawstream_create_sample_desc(&argb32_format
, NULL
, NULL
, &desc
);
7758 ok(desc
.dwWidth
== 100, "Got width %u.\n", desc
.dwWidth
);
7759 ok(desc
.dwHeight
== 100, "Got height %u.\n", desc
.dwHeight
);
7760 ok(desc
.ddpfPixelFormat
.dwFlags
== (DDPF_RGB
| DDPF_ALPHAPIXELS
), "Got flags %#x.\n", desc
.ddpfPixelFormat
.dwFlags
);
7761 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 32, "Got rgb bit count %u.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
7762 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xff0000, "Got r bit mask %#x.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
7763 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x00ff00, "Got g bit mask %#x.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
7764 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x0000ff, "Got b bit mask %#x.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
7765 ok(desc
.ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
== 0xff000000,
7766 "Got alpha bit mask %#x.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
7768 format1
= rgb32_format
;
7769 format1
.dwFlags
|= DDSD_CAPS
;
7770 format1
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
7771 get_ddrawstream_create_sample_desc(&format1
, NULL
, NULL
, &desc
);
7772 ok(desc
.ddsCaps
.dwCaps
& DDSCAPS_OFFSCREENPLAIN
, "Expected set DDSCAPS_OFFSCREENPLAIN.\n");
7773 ok(desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
, "Expected set DDSCAPS_SYSTEMMEMORY.\n");
7774 ok(!(desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
), "Expected unset DDSCAPS_VIDEOMEMORY.\n");
7775 ok(desc
.dwWidth
== 100, "Got width %u.\n", desc
.dwWidth
);
7776 ok(desc
.dwHeight
== 100, "Got height %u.\n", desc
.dwHeight
);
7777 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got flags %#x.\n", desc
.ddpfPixelFormat
.dwFlags
);
7778 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 32, "Got rgb bit count %u.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
7779 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xff0000, "Got r bit mask %#x.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
7780 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x00ff00, "Got g bit mask %#x.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
7781 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x0000ff, "Got b bit mask %#x.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
7783 format1
= rgb32_format
;
7784 format1
.dwFlags
|= DDSD_CKSRCBLT
;
7785 format1
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff;
7786 format1
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff;
7787 get_ddrawstream_create_sample_desc(&format1
, NULL
, NULL
, &desc
);
7788 ok(!(desc
.dwFlags
& DDSD_CKSRCBLT
), "Expected unset DDSD_CKSRCBLT.\n");
7789 ok(desc
.dwWidth
== 100, "Got width %u.\n", desc
.dwWidth
);
7790 ok(desc
.dwHeight
== 100, "Got height %u.\n", desc
.dwHeight
);
7791 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got flags %#x.\n", desc
.ddpfPixelFormat
.dwFlags
);
7792 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 32, "Got rgb bit count %u.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
7793 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xff0000, "Got r bit mask %#x.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
7794 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x00ff00, "Got g bit mask %#x.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
7795 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x0000ff, "Got b bit mask %#x.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
7796 ok(desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0, "Got color key low value %#x.\n",
7797 desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
);
7798 ok(desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0, "Got color key high value %#x.\n",
7799 desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
7802 static void test_ddrawstreamsample_get_media_stream(void)
7804 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7805 IDirectDrawMediaStream
*ddraw_stream
;
7806 IDirectDrawStreamSample
*sample
;
7807 IMediaStream
*stream
, *stream2
;
7812 hr
= DirectDrawCreate(NULL
, &ddraw
, NULL
);
7813 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7815 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
7816 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7818 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7819 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7821 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)ddraw
, &MSPID_PrimaryVideo
, 0, &stream
);
7822 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7824 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
7825 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7827 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &sample
);
7828 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7830 /* Crashes on native. */
7833 hr
= IDirectDrawStreamSample_GetMediaStream(sample
, NULL
);
7834 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
7837 EXPECT_REF(stream
, 4);
7838 hr
= IDirectDrawStreamSample_GetMediaStream(sample
, &stream2
);
7839 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7840 ok(stream2
== stream
, "Expected stream %p, got %p.\n", stream
, stream2
);
7841 EXPECT_REF(stream
, 5);
7842 IMediaStream_Release(stream2
);
7843 EXPECT_REF(stream
, 4);
7845 IDirectDrawMediaStream_Release(ddraw_stream
);
7846 ref
= IDirectDrawStreamSample_Release(sample
);
7847 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7848 ref
= IAMMultiMediaStream_Release(mmstream
);
7849 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7850 ref
= IMediaStream_Release(stream
);
7851 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7852 ref
= IDirectDraw_Release(ddraw
);
7853 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7856 static void test_ddrawstreamsample_update(void)
7858 static const BYTE initial_data
[] =
7860 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
7862 static const BYTE test_data
[] =
7864 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
7865 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
7867 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7868 IDirectDrawStreamSample
*stream_sample
;
7869 struct advise_time_cookie cookie
= {0};
7870 IDirectDrawMediaStream
*ddraw_stream
;
7871 IMediaControl
*media_control
;
7872 IDirectDrawSurface
*surface
;
7873 IMemInputPin
*mem_input_pin
;
7874 IMediaSample
*media_sample
;
7875 IMediaFilter
*media_filter
;
7876 REFERENCE_TIME start_time
;
7877 REFERENCE_TIME end_time
;
7878 struct testfilter source
;
7879 struct testclock clock
;
7880 IGraphBuilder
*graph
;
7881 IMediaStream
*stream
;
7882 VIDEOINFO video_info
;
7894 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7895 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7896 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
7897 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7898 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
7899 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7900 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
7901 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7902 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
7903 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7904 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw
);
7905 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7906 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
7907 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7908 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
7909 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaControl
, (void **)&media_control
);
7910 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7911 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
7912 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7913 testfilter_init(&source
);
7914 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
7915 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7916 testclock_init(&clock
);
7917 event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
7918 ok(event
!= NULL
, "Expected non-NULL event.");
7919 cookie
.advise_time_called_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
7920 ok(cookie
.advise_time_called_event
!= NULL
, "Expected non-NULL event.");
7922 hr
= IMediaFilter_SetSyncSource(media_filter
, NULL
);
7923 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7925 desc
= rgb24_format
;
7926 desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
7929 desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
7930 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
);
7931 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7932 /* Make the rect width equal to the surface width, as the native
7933 * implementation incorrectly handles rects that are not full-width
7934 * when the ddraw stream's custom allocator is not used. */
7935 SetRect(&rect
, 0, 1, 4, 3);
7936 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, surface
, &rect
, 0, &stream_sample
);
7937 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7939 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, event
, apc_func
, 0);
7940 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
7942 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
7943 ok(hr
== MS_E_NOTRUNNING
, "Got hr %#x.\n", hr
);
7945 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7946 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7948 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
7949 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
7951 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7952 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7953 video_info
= rgb24_video_info
;
7954 video_info
.bmiHeader
.biWidth
= 4;
7955 video_info
.bmiHeader
.biHeight
= -2;
7957 mt
.pbFormat
= (BYTE
*)&video_info
;
7958 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
7959 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7961 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7962 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7964 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
7965 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7966 for (i
= 0; i
< 5; ++i
)
7967 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
7968 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
7969 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7971 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
7973 ammediastream_mem_input_pin
= mem_input_pin
;
7974 ammediastream_media_sample
= media_sample
;
7975 ammediastream_sleep_time
= 0;
7976 ammediastream_expected_hr
= S_OK
;
7977 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
7980 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
7981 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7982 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
7983 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7984 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
7985 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
7986 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
7987 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
7988 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
7989 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
7990 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
7992 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
7993 CloseHandle(thread
);
7995 ref
= IMediaSample_Release(media_sample
);
7996 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
7998 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7999 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8000 IGraphBuilder_Disconnect(graph
, pin
);
8001 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
8002 video_info
= rgb24_video_info
;
8003 video_info
.bmiHeader
.biWidth
= 4;
8004 video_info
.bmiHeader
.biHeight
= 2;
8006 mt
.pbFormat
= (BYTE
*)&video_info
;
8007 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
8008 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8009 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8010 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8012 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8013 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8014 for (i
= 0; i
< 5; ++i
)
8015 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8016 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8017 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8019 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8021 ammediastream_mem_input_pin
= mem_input_pin
;
8022 ammediastream_media_sample
= media_sample
;
8023 ammediastream_sleep_time
= 0;
8024 ammediastream_expected_hr
= S_OK
;
8025 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
8028 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8029 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8030 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8031 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8032 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8033 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8034 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8035 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8036 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8037 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8038 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8040 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8041 CloseHandle(thread
);
8043 ref
= IMediaSample_Release(media_sample
);
8044 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8046 hr
= IPin_EndOfStream(pin
);
8047 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8049 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8050 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
8052 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8053 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8054 hr
= IMediaControl_Pause(media_control
);
8055 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8057 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8058 ok(hr
== MS_E_NOTRUNNING
, "Got hr %#x.\n", hr
);
8060 hr
= IMediaControl_Stop(media_control
);
8061 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8062 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8063 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8065 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8066 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8067 for (i
= 0; i
< 5; ++i
)
8068 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8069 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8070 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8072 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8074 ammediastream_mem_input_pin
= mem_input_pin
;
8075 ammediastream_media_sample
= media_sample
;
8076 ammediastream_sleep_time
= 100;
8077 ammediastream_expected_hr
= S_OK
;
8078 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
8080 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8081 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8082 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8083 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8084 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8085 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8086 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8087 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8088 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8089 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8090 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8092 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8093 CloseHandle(thread
);
8095 ref
= IMediaSample_Release(media_sample
);
8096 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8098 ammediastream_pin
= pin
;
8099 ammediastream_sleep_time
= 100;
8100 ammediastream_expected_hr
= S_OK
;
8101 thread
= CreateThread(NULL
, 0, ammediastream_end_of_stream
, NULL
, 0, NULL
);
8103 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8104 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
8106 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8107 CloseHandle(thread
);
8109 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8110 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8111 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8112 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8114 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8115 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8116 for (i
= 0; i
< 5; ++i
)
8117 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8118 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8119 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8121 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8123 ammediastream_mem_input_pin
= mem_input_pin
;
8124 ammediastream_media_sample
= media_sample
;
8125 ammediastream_sleep_time
= 100;
8126 ammediastream_expected_hr
= S_OK
;
8127 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
8129 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8130 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8131 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8132 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8133 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8134 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8135 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8136 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8137 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8138 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8139 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8141 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8142 CloseHandle(thread
);
8144 ref
= IMediaSample_Release(media_sample
);
8145 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8147 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8148 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8150 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8151 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8152 for (i
= 0; i
< 5; ++i
)
8153 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8154 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8155 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8157 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8158 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8159 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8160 ref
= IMediaSample_Release(media_sample
);
8161 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8163 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8164 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8165 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8166 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8167 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8168 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8169 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8170 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8171 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8173 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8174 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8175 for (i
= 0; i
< 5; ++i
)
8176 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8177 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8178 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8180 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8181 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8182 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8183 ref
= IMediaSample_Release(media_sample
);
8184 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8186 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8187 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8188 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8189 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8190 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8191 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8192 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8193 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8194 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8196 hr
= IPin_EndOfStream(pin
);
8197 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8199 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8200 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8201 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8202 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8204 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8205 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8206 EXPECT_REF(stream_sample
, 1);
8208 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8209 ok(hr
== MS_E_BUSY
, "Got hr %#x.\n", hr
);
8211 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8212 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8213 hr
= IMediaFilter_SetSyncSource(media_filter
, &clock
.IReferenceClock_iface
);
8214 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8215 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8216 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8218 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8219 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8220 for (i
= 0; i
< 5; ++i
)
8221 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8222 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8223 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8225 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8226 ok(hr
== MS_E_BUSY
, "Got hr %#x.\n", hr
);
8228 clock
.advise_time_cookie
= &cookie
;
8230 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8231 start_time
= 11111111;
8232 end_time
= 11111111;
8233 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
8234 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8236 ammediastream_mem_input_pin
= mem_input_pin
;
8237 ammediastream_media_sample
= media_sample
;
8238 ammediastream_sleep_time
= 0;
8239 ammediastream_expected_hr
= S_OK
;
8240 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
8241 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
8242 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8244 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8245 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8246 for (i
= 0; i
< 5; ++i
)
8247 ok(memcmp((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8248 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8249 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8251 SetEvent(cookie
.event
);
8253 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8254 CloseHandle(thread
);
8256 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8257 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8258 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8259 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8260 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8261 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8262 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8263 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8264 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8266 ref
= IMediaSample_Release(media_sample
);
8267 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8269 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8270 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8271 IGraphBuilder_Disconnect(graph
, pin
);
8272 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
8273 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8274 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8276 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8277 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
8279 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8280 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8282 CloseHandle(cookie
.advise_time_called_event
);
8284 ref
= IDirectDrawStreamSample_Release(stream_sample
);
8285 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8286 ref
= IDirectDrawSurface_Release(surface
);
8287 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8288 ref
= IAMMultiMediaStream_Release(mmstream
);
8289 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8290 IMediaControl_Release(media_control
);
8291 IMediaFilter_Release(media_filter
);
8292 ref
= IGraphBuilder_Release(graph
);
8293 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8295 IMemInputPin_Release(mem_input_pin
);
8296 IDirectDrawMediaStream_Release(ddraw_stream
);
8297 ref
= IMediaStream_Release(stream
);
8298 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8299 ref
= IDirectDraw_Release(ddraw
);
8300 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8303 static void test_ddrawstreamsample_completion_status(void)
8305 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
8306 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
8307 struct advise_time_cookie cookie
= { 0 };
8308 IDirectDrawStreamSample
*stream_sample1
;
8309 IDirectDrawStreamSample
*stream_sample2
;
8310 IDirectDrawMediaStream
*ddraw_stream
;
8311 STREAM_TIME filter_start_time
;
8312 IMediaStreamFilter
*filter
;
8313 IMediaSample
*media_sample
;
8314 IMediaFilter
*media_filter
;
8315 struct testfilter source
;
8316 struct testclock clock
;
8317 VIDEOINFO video_info
;
8318 IGraphBuilder
*graph
;
8319 IMediaStream
*stream
;
8326 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
8327 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8328 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
8329 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8330 ok(!!filter
, "Expected non-null filter.\n");
8331 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
8332 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8333 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
8334 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8335 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
8336 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8337 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
8338 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8339 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
8340 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
8341 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8342 testfilter_init(&source
);
8343 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
8344 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8345 testclock_init(&clock
);
8346 cookie
.advise_time_called_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
8348 hr
= IMediaFilter_SetSyncSource(media_filter
, NULL
);
8349 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8351 video_info
= rgb32_video_info
;
8352 video_info
.bmiHeader
.biWidth
= 3;
8353 video_info
.bmiHeader
.biHeight
= 1;
8355 mt
.pbFormat
= (BYTE
*)&video_info
;
8356 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
8357 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8358 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8359 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8361 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample1
);
8362 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8363 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample2
);
8364 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8366 /* Initial status is S_OK. */
8367 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8368 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8370 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
8371 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8373 /* Update changes the status to MS_S_PENDING. */
8374 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8375 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8377 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8378 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8380 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, 100);
8381 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8383 /* Each Receive call changes the status of one queued sample to S_OK in the same order Update was called. */
8384 hr
= IDirectDrawStreamSample_Update(stream_sample2
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8385 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8387 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
8388 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8390 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8391 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8392 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8393 ref
= IMediaSample_Release(media_sample
);
8394 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8396 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8397 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8399 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
8400 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8402 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
8403 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8405 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8406 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8407 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8408 ref
= IMediaSample_Release(media_sample
);
8409 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8411 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
8412 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8414 /* COMPSTAT_NOUPDATEOK removes the sample from the queue and changes the status to MS_S_NOUPDATE. */
8415 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8416 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8418 hr
= IDirectDrawStreamSample_Update(stream_sample2
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8419 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8421 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
, 0);
8422 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8424 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
8425 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8427 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8428 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8429 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8430 ref
= IMediaSample_Release(media_sample
);
8431 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8433 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8434 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8436 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
8437 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8439 /* COMPSTAT_ABORT removes the sample from the queue and changes the status to MS_S_NOUPDATE. */
8440 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8441 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8443 hr
= IDirectDrawStreamSample_Update(stream_sample2
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8444 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8446 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_ABORT
, 0);
8447 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8449 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
8450 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8452 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8453 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8454 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8455 ref
= IMediaSample_Release(media_sample
);
8456 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8458 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8459 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8461 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
8462 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8464 /* COMPSTAT_WAIT has no effect when combined with COMPSTAT_NOUPDATEOK. */
8465 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8466 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8468 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
| COMPSTAT_WAIT
, INFINITE
);
8469 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8471 /* COMPSTAT_WAIT has no effect when combined with COMPSTAT_ABORT. */
8472 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8473 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8475 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_ABORT
| COMPSTAT_WAIT
, INFINITE
);
8476 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8478 /* EndOfStream changes the status of the queued samples to MS_S_ENDOFSTREAM. */
8479 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8480 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8482 hr
= IPin_EndOfStream(pin
);
8483 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8485 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8486 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
8488 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
8489 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
8491 /* Update after EndOfStream changes the status to MS_S_ENDOFSTREAM. */
8492 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8493 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
8495 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8496 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
8498 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
8499 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
8501 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8502 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8503 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8504 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8506 /* Continuous update can be canceled by COMPSTAT_NOUPDATEOK. */
8507 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8508 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8510 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
, 0);
8511 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8513 /* Continuous update can be canceled by COMPSTAT_ABORT. */
8514 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8515 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8517 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_ABORT
, 0);
8518 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8520 /* If a sample is in countinuous update mode, when Receive is called it's status remains MS_S_PENDING
8521 * and the sample is moved to the end of the queue. */
8522 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8523 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8525 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8526 ok(hr
== MS_E_BUSY
, "Got hr %#x.\n", hr
);
8528 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8529 ok(hr
== MS_E_BUSY
, "Got hr %#x.\n", hr
);
8531 hr
= IDirectDrawStreamSample_Update(stream_sample2
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8532 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8534 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8535 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8537 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8538 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8539 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8540 ref
= IMediaSample_Release(media_sample
);
8541 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8543 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8544 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8546 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
8547 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8549 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8550 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8551 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8552 ref
= IMediaSample_Release(media_sample
);
8553 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8555 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8556 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8558 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
8559 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8561 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
, 0);
8562 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8564 /* In continuous update mode, flushing does not affect the status. */
8565 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8566 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8568 hr
= IPin_BeginFlush(pin
);
8569 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8571 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8572 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8574 hr
= IPin_EndFlush(pin
);
8575 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8577 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8578 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8580 /* In continuous update mode, stopping and running the stream does not affect the status. */
8581 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8582 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8584 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8585 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8587 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8588 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8590 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8591 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8593 /* In continuous update mode, EndOfStream changes the status to MS_S_ENDOFSTREAM. */
8594 hr
= IPin_EndOfStream(pin
);
8595 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8597 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8598 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#x.\n", hr
);
8600 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8601 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8602 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8603 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8605 /* COMPSTAT_WAIT resets the sample to the non-continuous update mode. */
8606 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8607 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8609 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, 0);
8610 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8612 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8613 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8614 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8615 ref
= IMediaSample_Release(media_sample
);
8616 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8618 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8619 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8621 /* In continuous update mode, CompletionStatus with COMPSTAT_WAIT returns when Receive is called. */
8622 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8623 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8625 streamsample_sample
= (IStreamSample
*)stream_sample1
;
8626 streamsample_flags
= COMPSTAT_WAIT
;
8627 streamsample_timeout
= INFINITE
;
8628 streamsample_expected_hr
= S_OK
;
8629 thread
= CreateThread(NULL
, 0, streamsample_completion_status
, NULL
, 0, NULL
);
8630 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "CompletionStatus returned prematurely.\n");
8632 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8633 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8634 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8635 ref
= IMediaSample_Release(media_sample
);
8636 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8638 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8639 CloseHandle(thread
);
8641 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8642 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8644 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8645 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8646 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8647 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8649 /* CompletionStatus with COMPSTAT_WAIT returns when Receive is called. */
8650 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8651 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8653 streamsample_sample
= (IStreamSample
*)stream_sample1
;
8654 streamsample_flags
= COMPSTAT_WAIT
;
8655 streamsample_timeout
= INFINITE
;
8656 streamsample_expected_hr
= S_OK
;
8657 thread
= CreateThread(NULL
, 0, streamsample_completion_status
, NULL
, 0, NULL
);
8658 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "CompletionStatus returned prematurely.\n");
8660 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8661 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8662 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8663 ref
= IMediaSample_Release(media_sample
);
8664 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8666 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8667 CloseHandle(thread
);
8669 /* CompletionStatus with COMPSTAT_WAIT returns when EndOfStream is called. */
8670 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8671 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8673 streamsample_sample
= (IStreamSample
*)stream_sample1
;
8674 streamsample_flags
= COMPSTAT_WAIT
;
8675 streamsample_timeout
= INFINITE
;
8676 streamsample_expected_hr
= MS_S_ENDOFSTREAM
;
8677 thread
= CreateThread(NULL
, 0, streamsample_completion_status
, NULL
, 0, NULL
);
8678 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "CompletionStatus returned prematurely.\n");
8680 hr
= IPin_EndOfStream(pin
);
8681 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8683 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8684 CloseHandle(thread
);
8686 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8687 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8688 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8689 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8691 /* Stopping and running the stream does not affect the status and does not remove the sample from the queue. */
8692 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8693 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8695 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8696 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8698 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8699 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8701 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8702 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8704 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 6);
8705 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8706 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8707 ref
= IMediaSample_Release(media_sample
);
8708 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8710 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8711 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8713 /* When the stream is stopped Update does not change the status. */
8714 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8715 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8717 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8718 ok(hr
== MS_E_NOTRUNNING
, "Got hr %#x.\n", hr
);
8720 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8721 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8723 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
8724 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8726 /* When the wait time is less than 1ms the sample is updated immediately. */
8727 hr
= IMediaFilter_SetSyncSource(media_filter
, &clock
.IReferenceClock_iface
);
8728 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8730 clock
.time
= 12345678;
8732 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8733 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8735 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &filter_start_time
);
8736 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8738 clock
.time
= 12345678 - filter_start_time
+ 11111111;
8740 clock
.advise_time_cookie
= &cookie
;
8742 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8743 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8745 thread
= ammediastream_async_receive_time(&source
,
8746 11111111 + 9999, 11111111 + 9999, test_data
, sizeof(test_data
));
8747 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8748 CloseHandle(thread
);
8750 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, INFINITE
);
8751 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8753 /* When the wait time is 1ms or greater AdviseTime is called
8754 * with base equal to the sample start time and offset equal to the filter start time. */
8755 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8756 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8758 thread
= ammediastream_async_receive_time(&source
,
8759 11111111 + 10000, 11111111 + 10000, test_data
, sizeof(test_data
));
8760 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
8761 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8763 ok(cookie
.base
== 11111111 + 10000, "Got base %s.\n", wine_dbgstr_longlong(cookie
.base
));
8764 ok(cookie
.offset
== 12345678 - filter_start_time
, "Got offset %s.\n", wine_dbgstr_longlong(cookie
.offset
));
8766 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8767 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8769 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 10000;
8770 SetEvent(cookie
.event
);
8772 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8773 CloseHandle(thread
);
8775 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8776 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8778 /* NewSegment does not affect the values passed to AdviseTime. */
8779 hr
= IPin_NewSegment(pin
, 22222222, 33333333, 1.0);
8780 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8782 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8783 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8785 thread
= ammediastream_async_receive_time(&source
,
8786 11111111 + 20000, 11111111 + 20000, test_data
, sizeof(test_data
));
8787 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
8788 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8790 ok(cookie
.base
== 11111111 + 20000, "Got base %s.\n", wine_dbgstr_longlong(cookie
.base
));
8791 ok(cookie
.offset
== 12345678 - filter_start_time
, "Got offset %s.\n", wine_dbgstr_longlong(cookie
.offset
));
8793 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
, 0);
8794 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8796 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8798 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 20000;
8799 SetEvent(cookie
.event
);
8801 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8803 /* COMPSTAT_NOUPDATEOK does not cause Receive to return.
8804 * Receive waits for the next sample to be queued and updates it. */
8805 hr
= IDirectDrawStreamSample_Update(stream_sample1
, 0, NULL
, NULL
, 0);
8806 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8808 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8809 CloseHandle(thread
);
8811 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8812 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8814 thread
= ammediastream_async_receive_time(&source
,
8815 11111111 + 30000, 11111111 + 30000, test_data
, sizeof(test_data
));
8816 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
8817 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8819 ok(cookie
.base
== 11111111 + 30000, "Got base %s.\n", wine_dbgstr_longlong(cookie
.base
));
8820 ok(cookie
.offset
== 12345678 - filter_start_time
, "Got offset %s.\n", wine_dbgstr_longlong(cookie
.offset
));
8822 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
| COMPSTAT_WAIT
, INFINITE
);
8823 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8825 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8827 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 30000;
8828 SetEvent(cookie
.event
);
8830 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8832 hr
= IDirectDrawStreamSample_Update(stream_sample1
, 0, NULL
, NULL
, 0);
8833 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8835 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8836 CloseHandle(thread
);
8838 /* COMPSTAT_ABORT does not cause Receive to return.
8839 * Receive waits for the next sample to be queued and updates it. */
8840 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8841 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8843 thread
= ammediastream_async_receive_time(&source
,
8844 11111111 + 40000, 11111111 + 40000, test_data
, sizeof(test_data
));
8845 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
8846 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8848 ok(cookie
.base
== 11111111 + 40000, "Got base %s.\n", wine_dbgstr_longlong(cookie
.base
));
8849 ok(cookie
.offset
== 12345678 - filter_start_time
, "Got offset %s.\n", wine_dbgstr_longlong(cookie
.offset
));
8851 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_ABORT
, 0);
8852 ok(hr
== MS_S_NOUPDATE
, "Got hr %#x.\n", hr
);
8854 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8856 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 40000;
8857 SetEvent(cookie
.event
);
8859 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8861 hr
= IDirectDrawStreamSample_Update(stream_sample1
, 0, NULL
, NULL
, 0);
8862 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8864 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8865 CloseHandle(thread
);
8867 /* Stopping the stream causes Receive to return and leaves the sample with MS_S_PENDING status. */
8868 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8869 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8871 thread
= ammediastream_async_receive_time(&source
,
8872 11111111 + 50000, 11111111 + 50000, test_data
, sizeof(test_data
));
8873 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
8874 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8876 ok(cookie
.base
== 11111111 + 50000, "Got base %s.\n", wine_dbgstr_longlong(cookie
.base
));
8877 ok(cookie
.offset
== 12345678 - filter_start_time
, "Got offset %s.\n", wine_dbgstr_longlong(cookie
.offset
));
8879 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8880 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8882 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8883 CloseHandle(thread
);
8885 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
8886 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
8888 IGraphBuilder_Disconnect(graph
, pin
);
8889 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
8891 CloseHandle(cookie
.advise_time_called_event
);
8892 ref
= IDirectDrawStreamSample_Release(stream_sample1
);
8893 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8894 ref
= IDirectDrawStreamSample_Release(stream_sample2
);
8895 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8896 ref
= IAMMultiMediaStream_Release(mmstream
);
8897 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8898 IMediaFilter_Release(media_filter
);
8899 ref
= IGraphBuilder_Release(graph
);
8900 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8901 ref
= IMediaStreamFilter_Release(filter
);
8902 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8904 IDirectDrawMediaStream_Release(ddraw_stream
);
8905 ref
= IMediaStream_Release(stream
);
8906 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
8909 static void test_ddrawstreamsample_get_sample_times(void)
8911 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
8912 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
8913 IDirectDrawStreamSample
*stream_sample
;
8914 IMediaFilter
*graph_media_filter
;
8915 IDirectDrawMediaStream
*ddraw_stream
;
8916 STREAM_TIME filter_start_time
;
8917 IMemInputPin
*mem_input_pin
;
8918 IMediaStreamFilter
*filter
;
8919 IMediaSample
*media_sample
;
8920 struct testfilter source
;
8921 STREAM_TIME current_time
;
8922 struct testclock clock
;
8923 STREAM_TIME start_time
;
8924 STREAM_TIME end_time
;
8925 IGraphBuilder
*graph
;
8926 IMediaStream
*stream
;
8927 VIDEOINFO video_info
;
8933 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
8934 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8935 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
8936 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8937 ok(!!filter
, "Expected non-null filter.\n");
8938 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
8939 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8940 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
8941 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8942 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
8943 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8944 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
8945 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8946 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
8947 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8948 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
8949 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&graph_media_filter
);
8950 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8951 testfilter_init(&source
);
8952 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
8953 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8954 testclock_init(&clock
);
8956 video_info
= rgb32_video_info
;
8957 video_info
.bmiHeader
.biWidth
= 3;
8958 video_info
.bmiHeader
.biHeight
= 1;
8960 mt
.pbFormat
= (BYTE
*)&video_info
;
8961 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
8962 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8964 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample
);
8965 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8967 clock
.time
= 12345678;
8969 current_time
= 0xdeadbeefdeadbeef;
8970 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
8971 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8972 ok(current_time
== 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time
));
8974 IMediaFilter_SetSyncSource(graph_media_filter
, &clock
.IReferenceClock_iface
);
8975 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8977 current_time
= 0xdeadbeefdeadbeef;
8978 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
8979 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8980 ok(current_time
== 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time
));
8982 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8983 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8985 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &filter_start_time
);
8986 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8988 clock
.get_time_hr
= E_FAIL
;
8990 current_time
= 0xdeadbeefdeadbeef;
8991 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
8992 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
8993 ok(current_time
== 0xdeadbeefddf15da1 + filter_start_time
, "Expected current time %s, got %s.\n",
8994 wine_dbgstr_longlong(0xdeadbeefddf15da1 + filter_start_time
), wine_dbgstr_longlong(current_time
));
8996 clock
.get_time_hr
= S_OK
;
8998 current_time
= 0xdeadbeefdeadbeef;
8999 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
9000 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
9001 ok(current_time
== filter_start_time
, "Expected current time %s, got %s.\n",
9002 wine_dbgstr_longlong(filter_start_time
), wine_dbgstr_longlong(current_time
));
9004 clock
.time
= 23456789;
9006 current_time
= 0xdeadbeefdeadbeef;
9007 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
9008 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
9009 ok(current_time
== filter_start_time
+ 11111111, "Expected current time %s, got %s.\n",
9010 wine_dbgstr_longlong(filter_start_time
+ 11111111), wine_dbgstr_longlong(current_time
));
9012 start_time
= 0xdeadbeefdeadbeef;
9013 end_time
= 0xdeadbeefdeadbeef;
9014 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
9015 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
9016 ok(start_time
== 0, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
9017 ok(end_time
== 0, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
9019 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9020 ok(hr
== MS_S_PENDING
, "Got hr %#x.\n", hr
);
9022 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9023 start_time
= 12345678;
9024 end_time
= 23456789;
9025 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
9026 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
9027 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
9028 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
9029 IMediaSample_Release(media_sample
);
9031 start_time
= 0xdeadbeefdeadbeef;
9032 end_time
= 0xdeadbeefdeadbeef;
9033 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
9034 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
9035 ok(start_time
== 12345678, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
9036 ok(end_time
== 23456789, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
9038 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
9039 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
9040 IGraphBuilder_Disconnect(graph
, pin
);
9041 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
9043 ref
= IDirectDrawStreamSample_Release(stream_sample
);
9044 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
9045 ref
= IAMMultiMediaStream_Release(mmstream
);
9046 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
9047 IMediaFilter_Release(graph_media_filter
);
9048 ref
= IGraphBuilder_Release(graph
);
9049 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
9050 ref
= IMediaStreamFilter_Release(filter
);
9051 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
9053 IMemInputPin_Release(mem_input_pin
);
9054 IDirectDrawMediaStream_Release(ddraw_stream
);
9055 ref
= IMediaStream_Release(stream
);
9056 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
9059 START_TEST(amstream
)
9061 const WCHAR
*test_avi_path
;
9063 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
9067 test_media_streams();
9073 test_enum_media_types();
9076 test_avi_path
= load_resource(L
"test.avi");
9078 test_openfile(test_avi_path
);
9079 test_mmstream_get_duration(test_avi_path
);
9081 unload_resource(test_avi_path
);
9083 test_audiodata_query_interface();
9084 test_audiodata_get_info();
9085 test_audiodata_set_buffer();
9086 test_audiodata_set_actual();
9087 test_audiodata_get_format();
9088 test_audiodata_set_format();
9090 test_audiostream_get_format();
9091 test_audiostream_set_format();
9092 test_audiostream_receive_connection();
9093 test_audiostream_receive();
9094 test_audiostream_initialize();
9095 test_audiostream_begin_flush_end_flush();
9096 test_audiostream_new_segment();
9098 test_audiostreamsample_update();
9099 test_audiostreamsample_completion_status();
9100 test_audiostreamsample_get_sample_times();
9101 test_audiostreamsample_get_media_stream();
9102 test_audiostreamsample_get_audio_data();
9104 test_ddrawstream_initialize();
9105 test_ddrawstream_getsetdirectdraw();
9106 test_ddrawstream_receive_connection();
9107 test_ddrawstream_create_sample();
9108 test_ddrawstream_get_format();
9109 test_ddrawstream_set_format();
9110 test_ddrawstream_receive();
9111 test_ddrawstream_begin_flush_end_flush();
9112 test_ddrawstream_new_segment();
9113 test_ddrawstream_get_time_per_frame();
9115 test_ddrawstreamsample_get_media_stream();
9116 test_ddrawstreamsample_update();
9117 test_ddrawstreamsample_completion_status();
9118 test_ddrawstreamsample_get_sample_times();
9120 test_ammediastream_join_am_multi_media_stream();
9121 test_ammediastream_join_filter();
9122 test_ammediastream_join_filter_graph();
9123 test_ammediastream_set_state();
9124 test_ammediastream_end_of_stream();
9126 test_mediastreamfilter_get_state();
9127 test_mediastreamfilter_stop_pause_run();
9128 test_mediastreamfilter_support_seeking();
9129 test_mediastreamfilter_seeking();
9130 test_mediastreamfilter_get_current_stream_time();
9131 test_mediastreamfilter_reference_time_to_stream_time();
9132 test_mediastreamfilter_wait_until();
9133 test_mediastreamfilter_end_of_stream();