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 %lu.\n", wine_dbgstr_w(path
), GetLastError());
268 resource
= FindResourceW(module
, name
, (const WCHAR
*)RT_RCDATA
);
269 ok(!!resource
, "Failed to find resource %s, error %lu.\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 %ld, got %ld\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 %#lx.\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 %#lx, expected %#lx.\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 %#lx.\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 %#lx.\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
);
389 check_interface(stream
, &IID_IQualityControl
, FALSE
);
391 IMediaStream_Release(stream
);
393 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
394 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
396 check_interface(stream
, &IID_IAMMediaStream
, TRUE
);
397 check_interface(stream
, &IID_IDirectDrawMediaStream
, TRUE
);
398 check_interface(stream
, &IID_IMediaStream
, TRUE
);
399 check_interface(stream
, &IID_IMemInputPin
, TRUE
);
400 check_interface(stream
, &IID_IPin
, TRUE
);
401 check_interface(stream
, &IID_IUnknown
, TRUE
);
403 check_interface(stream
, &IID_IAMMediaTypeStream
, FALSE
);
404 check_interface(stream
, &IID_IAMMultiMediaStream
, FALSE
);
405 check_interface(stream
, &IID_IAudioMediaStream
, FALSE
);
406 check_interface(stream
, &IID_IBaseFilter
, FALSE
);
407 check_interface(stream
, &IID_IDirectDraw
, FALSE
);
408 check_interface(stream
, &IID_IMediaFilter
, FALSE
);
409 check_interface(stream
, &IID_IMediaStreamFilter
, FALSE
);
410 check_interface(stream
, &IID_IMultiMediaStream
, FALSE
);
411 check_interface(stream
, &IID_IPersist
, FALSE
);
412 check_interface(stream
, &IID_IQualityControl
, FALSE
);
414 IMediaStream_Release(stream
);
416 ref
= IAMMultiMediaStream_Release(mmstream
);
417 ok(!ref
, "Got outstanding refcount %lu.\n", ref
);
420 static void test_openfile(const WCHAR
*test_avi_path
)
422 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
423 IMediaControl
*media_control
;
424 IMediaStreamFilter
*filter
;
425 IMediaFilter
*media_filter
;
426 IReferenceClock
*clock
;
427 IGraphBuilder
*graph
;
432 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
433 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
434 ok(!graph
, "Expected NULL graph.\n");
436 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
437 ok(!!filter
, "Expected non-NULL filter.\n");
438 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
440 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
442 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_NORENDER
);
443 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
445 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
447 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
448 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
449 ok(!!graph
, "Expected non-NULL graph.\n");
450 IGraphBuilder_Release(graph
);
451 IMediaStreamFilter_Release(filter
);
453 ref
= IAMMultiMediaStream_Release(mmstream
);
454 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
456 mmstream
= create_ammultimediastream();
458 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
459 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
460 ok(!graph
, "Expected NULL graph.\n");
462 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
463 ok(!!filter
, "Expected non-NULL filter.\n");
464 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
466 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
468 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_RENDERALLSTREAMS
);
469 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
471 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
473 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
474 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
475 ok(!!graph
, "Expected non-NULL graph.\n");
477 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
478 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
480 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
481 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
484 IMediaFilter_GetSyncSource(media_filter
, &clock
);
485 ok(!!clock
, "Expected non-NULL clock.\n");
487 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
488 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
490 ref
= IAMMultiMediaStream_Release(mmstream
);
491 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
492 IMediaFilter_Release(media_filter
);
493 ref
= IGraphBuilder_Release(graph
);
494 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
495 ref
= IMediaStreamFilter_Release(filter
);
496 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
497 ref
= IReferenceClock_Release(clock
);
498 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
500 mmstream
= create_ammultimediastream();
501 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
502 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
503 ok(!graph
, "Expected NULL graph.\n");
505 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
506 ok(!!filter
, "Expected non-NULL filter.\n");
507 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
509 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
511 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_RENDERTOEXISTING
);
512 ok(hr
== VFW_E_CANNOT_CONNECT
, "Got hr %#lx.\n", hr
);
514 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
516 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
517 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
518 ok(!!graph
, "Expected non-NULL graph.\n");
519 IGraphBuilder_Release(graph
);
520 IMediaStreamFilter_Release(filter
);
522 ref
= IAMMultiMediaStream_Release(mmstream
);
523 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
525 mmstream
= create_ammultimediastream();
526 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
527 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
528 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
529 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
530 ok(!!graph
, "Expected non-NULL graph.\n");
531 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
532 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
533 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
534 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
536 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
538 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_RENDERTOEXISTING
);
539 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
541 check_interface(filter
, &IID_IMediaSeeking
, TRUE
);
543 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
544 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
547 IMediaFilter_GetSyncSource(media_filter
, &clock
);
548 ok(!!clock
, "Expected non-NULL clock.\n");
550 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
551 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
553 ref
= IAMMultiMediaStream_Release(mmstream
);
554 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
555 IMediaFilter_Release(media_filter
);
556 ref
= IGraphBuilder_Release(graph
);
557 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
558 ref
= IMediaStreamFilter_Release(filter
);
559 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
560 ref
= IReferenceClock_Release(clock
);
561 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
563 mmstream
= create_ammultimediastream();
564 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
565 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
566 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
567 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
568 ok(!!graph
, "Expected non-NULL graph.\n");
569 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaControl
, (void **)&media_control
);
570 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
572 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_RUN
);
573 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
576 hr
= IMediaControl_GetState(media_control
, INFINITE
, &state
);
577 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
578 ok(state
== State_Running
, "Got state %#lx.\n", state
);
580 ref
= IAMMultiMediaStream_Release(mmstream
);
581 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
582 IMediaControl_Release(media_control
);
583 ref
= IGraphBuilder_Release(graph
);
584 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
586 mmstream
= create_ammultimediastream();
587 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
588 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
589 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
590 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
591 ok(!!graph
, "Expected non-NULL graph.\n");
592 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
593 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
595 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_NOCLOCK
);
596 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
598 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
599 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
601 clock
= (IReferenceClock
*)0xdeadbeef;
602 IMediaFilter_GetSyncSource(media_filter
, &clock
);
603 ok(!clock
, "Got clock %p.\n", clock
);
605 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
606 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
608 ref
= IAMMultiMediaStream_Release(mmstream
);
609 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
610 IMediaFilter_Release(media_filter
);
611 ref
= IGraphBuilder_Release(graph
);
612 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
615 static void test_mmstream_get_duration(const WCHAR
*test_avi_path
)
617 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
618 HRESULT hr
, audio_hr
;
622 duration
= 0xdeadbeefdeadbeefULL
;
623 hr
= IAMMultiMediaStream_GetDuration(mmstream
, &duration
);
624 ok(hr
== E_NOINTERFACE
, "Got hr %#lx.\n", hr
);
625 ok(duration
== 0xdeadbeefdeadbeefULL
, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
627 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, NULL
);
628 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
630 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, AMMSF_ADDDEFAULTRENDERER
, NULL
);
631 ok(hr
== S_OK
|| hr
== VFW_E_NO_AUDIO_HARDWARE
, "Got hr %#lx.\n", hr
);
634 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_RENDERTOEXISTING
);
635 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
637 duration
= 0xdeadbeefdeadbeefULL
;
638 hr
= IAMMultiMediaStream_GetDuration(mmstream
, &duration
);
639 if (audio_hr
== S_OK
)
641 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
642 ok(duration
== 1000000LL, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
646 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
647 ok(!duration
, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
650 ref
= IAMMultiMediaStream_Release(mmstream
);
651 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
653 mmstream
= create_ammultimediastream();
654 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
655 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
657 duration
= 0xdeadbeefdeadbeefULL
;
658 hr
= IAMMultiMediaStream_GetDuration(mmstream
, &duration
);
659 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
660 ok(duration
== 0, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
662 ref
= IAMMultiMediaStream_Release(mmstream
);
663 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
665 mmstream
= create_ammultimediastream();
667 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_RENDERTOEXISTING
);
668 ok(hr
== VFW_E_CANNOT_CONNECT
, "Got hr %#lx.\n", hr
);
670 duration
= 0xdeadbeefdeadbeefULL
;
671 hr
= IAMMultiMediaStream_GetDuration(mmstream
, &duration
);
672 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
673 ok(duration
== 0, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
675 ref
= IAMMultiMediaStream_Release(mmstream
);
676 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
678 mmstream
= create_ammultimediastream();
679 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
680 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
682 hr
= IAMMultiMediaStream_OpenFile(mmstream
, test_avi_path
, AMMSF_NORENDER
);
683 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
685 duration
= 0xdeadbeefdeadbeefULL
;
686 hr
= IAMMultiMediaStream_GetDuration(mmstream
, &duration
);
687 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
688 ok(duration
== 0, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
690 ref
= IAMMultiMediaStream_Release(mmstream
);
691 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
694 static const GUID test_mspid
= {0x88888888};
698 IAMMediaStream IAMMediaStream_iface
;
702 IAMMultiMediaStream
*mmstream
;
703 IMediaStreamFilter
*filter
;
706 HRESULT set_state_result
;
709 static struct teststream
*impl_from_IAMMediaStream(IAMMediaStream
*iface
)
711 return CONTAINING_RECORD(iface
, struct teststream
, IAMMediaStream_iface
);
714 static struct teststream
*impl_from_IPin(IPin
*iface
)
716 return CONTAINING_RECORD(iface
, struct teststream
, IPin_iface
);
719 static HRESULT WINAPI
pin_QueryInterface(IPin
*iface
, REFIID iid
, void **out
)
721 struct teststream
*stream
= impl_from_IPin(iface
);
722 return IAMMediaStream_QueryInterface(&stream
->IAMMediaStream_iface
, iid
, out
);
725 static ULONG WINAPI
pin_AddRef(IPin
*iface
)
727 struct teststream
*stream
= impl_from_IPin(iface
);
728 return IAMMediaStream_AddRef(&stream
->IAMMediaStream_iface
);
731 static ULONG WINAPI
pin_Release(IPin
*iface
)
733 struct teststream
*stream
= impl_from_IPin(iface
);
734 return IAMMediaStream_Release(&stream
->IAMMediaStream_iface
);
737 static HRESULT WINAPI
pin_Connect(IPin
*iface
, IPin
*peer
, const AM_MEDIA_TYPE
*mt
)
739 ok(0, "Unexpected call.\n");
743 static HRESULT WINAPI
pin_ReceiveConnection(IPin
*iface
, IPin
*peer
, const AM_MEDIA_TYPE
*mt
)
745 ok(0, "Unexpected call.\n");
749 static HRESULT WINAPI
pin_Disconnect(IPin
*iface
)
751 if (winetest_debug
> 1) trace("Disconnect\n");
755 static HRESULT WINAPI
pin_ConnectedTo(IPin
*iface
, IPin
**peer
)
757 if (winetest_debug
> 1) trace("ConnectedTo\n");
761 static HRESULT WINAPI
pin_ConnectionMediaType(IPin
*iface
, AM_MEDIA_TYPE
*mt
)
763 ok(0, "Unexpected call.\n");
767 static HRESULT WINAPI
pin_QueryPinInfo(IPin
*iface
, PIN_INFO
*info
)
769 ok(0, "Unexpected call.\n");
773 static HRESULT WINAPI
pin_QueryDirection(IPin
*iface
, PIN_DIRECTION
*dir
)
775 if (winetest_debug
> 1) trace("QueryDirection\n");
780 static HRESULT WINAPI
pin_QueryId(IPin
*iface
, WCHAR
**id
)
782 ok(0, "Unexpected call.\n");
786 static HRESULT WINAPI
pin_QueryAccept(IPin
*iface
, const AM_MEDIA_TYPE
*mt
)
788 ok(0, "Unexpected call.\n");
792 static HRESULT WINAPI
pin_EnumMediaTypes(IPin
*iface
, IEnumMediaTypes
**out
)
794 ok(0, "Unexpected call.\n");
798 static HRESULT WINAPI
pin_QueryInternalConnections(IPin
*iface
, IPin
**pins
, ULONG
*count
)
800 ok(0, "Unexpected call.\n");
804 static HRESULT WINAPI
pin_EndOfStream(IPin
*iface
)
806 ok(0, "Unexpected call.\n");
810 static HRESULT WINAPI
pin_BeginFlush(IPin
*iface
)
812 ok(0, "Unexpected call.\n");
816 static HRESULT WINAPI
pin_EndFlush(IPin
*iface
)
818 ok(0, "Unexpected call.\n");
822 static HRESULT WINAPI
pin_NewSegment(IPin
*iface
, REFERENCE_TIME start
, REFERENCE_TIME stop
, double rate
)
824 ok(0, "Unexpected call.\n");
828 static const IPinVtbl pin_vtbl
=
834 pin_ReceiveConnection
,
837 pin_ConnectionMediaType
,
843 pin_QueryInternalConnections
,
850 static HRESULT WINAPI
stream_QueryInterface(IAMMediaStream
*iface
, REFIID iid
, void **out
)
852 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
854 if (winetest_debug
> 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid
));
856 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IMediaStream
) || IsEqualGUID(iid
, &IID_IAMMediaStream
))
858 IAMMediaStream_AddRef(iface
);
862 else if (IsEqualGUID(iid
, &IID_IPin
))
864 IAMMediaStream_AddRef(iface
);
865 *out
= &stream
->IPin_iface
;
869 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(iid
));
870 return E_NOINTERFACE
;
873 static ULONG WINAPI
stream_AddRef(IAMMediaStream
*iface
)
875 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
876 return InterlockedIncrement(&stream
->refcount
);
879 static ULONG WINAPI
stream_Release(IAMMediaStream
*iface
)
881 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
882 return InterlockedDecrement(&stream
->refcount
);
885 static HRESULT WINAPI
stream_GetMultiMediaStream(IAMMediaStream
*iface
, IMultiMediaStream
**mmstream
)
887 ok(0, "Unexpected call.\n");
891 static HRESULT WINAPI
stream_GetInformation(IAMMediaStream
*iface
, MSPID
*id
, STREAM_TYPE
*type
)
893 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
894 if (winetest_debug
> 1) trace("GetInformation(%p, %p)\n", id
, type
);
898 *type
= STREAMTYPE_READ
;
902 static HRESULT WINAPI
stream_SetSameFormat(IAMMediaStream
*iface
, IMediaStream
*ref
, DWORD flags
)
904 ok(0, "Unexpected call.\n");
908 static HRESULT WINAPI
stream_AllocateSample(IAMMediaStream
*iface
, DWORD flags
, IStreamSample
**sample
)
910 ok(0, "Unexpected call.\n");
914 static HRESULT WINAPI
stream_CreateSharedSample(IAMMediaStream
*iface
,
915 IStreamSample
*existing
, DWORD flags
, IStreamSample
**out
)
917 ok(0, "Unexpected call.\n");
921 static HRESULT WINAPI
stream_SendEndOfStream(IAMMediaStream
*iface
, DWORD flags
)
923 ok(0, "Unexpected call.\n");
927 static HRESULT WINAPI
stream_Initialize(IAMMediaStream
*iface
, IUnknown
*source
,
928 DWORD flags
, REFMSPID id
, const STREAM_TYPE type
)
930 ok(0, "Unexpected call.\n");
934 static HRESULT WINAPI
stream_SetState(IAMMediaStream
*iface
, FILTER_STATE state
)
936 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
937 if (winetest_debug
> 1) trace("SetState(%#x)\n", state
);
938 if (SUCCEEDED(stream
->set_state_result
))
939 stream
->state
= state
;
940 return stream
->set_state_result
;
943 static HRESULT WINAPI
stream_JoinAMMultiMediaStream(IAMMediaStream
*iface
, IAMMultiMediaStream
*mmstream
)
945 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
946 if (winetest_debug
> 1) trace("JoinAMMultiMediaStream(%p)\n", mmstream
);
947 stream
->mmstream
= mmstream
;
951 static HRESULT WINAPI
stream_JoinFilter(IAMMediaStream
*iface
, IMediaStreamFilter
*filter
)
953 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
954 if (winetest_debug
> 1) trace("JoinFilter(%p)\n", filter
);
955 stream
->filter
= filter
;
959 static HRESULT WINAPI
stream_JoinFilterGraph(IAMMediaStream
*iface
, IFilterGraph
*graph
)
961 struct teststream
*stream
= impl_from_IAMMediaStream(iface
);
962 if (winetest_debug
> 1) trace("JoinFilterGraph(%p)\n", graph
);
963 stream
->graph
= graph
;
967 static const IAMMediaStreamVtbl stream_vtbl
=
969 stream_QueryInterface
,
972 stream_GetMultiMediaStream
,
973 stream_GetInformation
,
974 stream_SetSameFormat
,
975 stream_AllocateSample
,
976 stream_CreateSharedSample
,
977 stream_SendEndOfStream
,
980 stream_JoinAMMultiMediaStream
,
982 stream_JoinFilterGraph
,
985 static void teststream_init(struct teststream
*stream
)
987 memset(stream
, 0, sizeof(*stream
));
988 stream
->IAMMediaStream_iface
.lpVtbl
= &stream_vtbl
;
989 stream
->IPin_iface
.lpVtbl
= &pin_vtbl
;
990 stream
->refcount
= 1;
991 stream
->mspid
= test_mspid
;
992 stream
->set_state_result
= S_OK
;
995 #define check_enum_stream(a,b,c,d) check_enum_stream_(__LINE__,a,b,c,d)
996 static void check_enum_stream_(int line
, IAMMultiMediaStream
*mmstream
,
997 IMediaStreamFilter
*filter
, LONG index
, IMediaStream
*expect
)
999 IMediaStream
*stream
= NULL
, *stream2
= NULL
;
1002 hr
= IAMMultiMediaStream_EnumMediaStreams(mmstream
, index
, &stream
);
1003 ok_(__FILE__
, line
)(hr
== (expect
? S_OK
: S_FALSE
),
1004 "IAMMultiMediaStream::EnumMediaStreams() returned %#lx.\n", hr
);
1005 hr
= IMediaStreamFilter_EnumMediaStreams(filter
, index
, &stream2
);
1006 ok_(__FILE__
, line
)(hr
== (expect
? S_OK
: S_FALSE
),
1007 "IMediaStreamFilter::EnumMediaStreams() returned %#lx.\n", hr
);
1010 ok_(__FILE__
, line
)(stream
== expect
, "Expected stream %p, got %p.\n", expect
, stream
);
1011 ok_(__FILE__
, line
)(stream2
== expect
, "Expected stream %p, got %p.\n", expect
, stream2
);
1012 IMediaStream_Release(stream
);
1013 IMediaStream_Release(stream2
);
1019 struct strmbase_filter filter
;
1020 struct strmbase_source source
;
1021 IMediaSeeking IMediaSeeking_iface
;
1022 IQualityControl IQualityControl_iface
;
1023 LONGLONG current_position
;
1024 LONGLONG stop_position
;
1025 const AM_MEDIA_TYPE
*preferred_mt
;
1026 HANDLE wait_state_event
;
1027 IBaseFilter
*qc_notify_sender
;
1028 Quality qc_notify_quality
;
1029 HRESULT get_duration_hr
;
1030 HRESULT get_stop_position_hr
;
1031 HRESULT set_positions_hr
;
1032 HRESULT init_stream_hr
;
1033 HRESULT cleanup_stream_hr
;
1034 HRESULT wait_state_hr
;
1035 HRESULT is_format_supported_hr
;
1036 HRESULT qc_notify_hr
;
1039 static inline struct testfilter
*impl_from_BaseFilter(struct strmbase_filter
*iface
)
1041 return CONTAINING_RECORD(iface
, struct testfilter
, filter
);
1044 static struct strmbase_pin
*testfilter_get_pin(struct strmbase_filter
*iface
, unsigned int index
)
1046 struct testfilter
*filter
= impl_from_BaseFilter(iface
);
1048 return &filter
->source
.pin
;
1052 static void testfilter_destroy(struct strmbase_filter
*iface
)
1054 struct testfilter
*filter
= impl_from_BaseFilter(iface
);
1055 CloseHandle(filter
->wait_state_event
);
1056 strmbase_source_cleanup(&filter
->source
);
1057 strmbase_filter_cleanup(&filter
->filter
);
1060 static HRESULT
testfilter_init_stream(struct strmbase_filter
*iface
)
1062 struct testfilter
*filter
= impl_from_BaseFilter(iface
);
1065 if (SUCCEEDED(filter
->init_stream_hr
) && filter
->source
.pin
.peer
)
1067 hr
= IMemAllocator_Commit(filter
->source
.pAllocator
);
1068 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1071 return filter
->init_stream_hr
;
1074 static HRESULT
testfilter_cleanup_stream(struct strmbase_filter
*iface
)
1076 struct testfilter
*filter
= impl_from_BaseFilter(iface
);
1079 if (SUCCEEDED(filter
->cleanup_stream_hr
) && filter
->source
.pin
.peer
)
1081 hr
= IMemAllocator_Decommit(filter
->source
.pAllocator
);
1082 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1085 return filter
->cleanup_stream_hr
;
1088 static HRESULT
testfilter_wait_state(struct strmbase_filter
*iface
, DWORD timeout
)
1090 struct testfilter
*filter
= impl_from_BaseFilter(iface
);
1093 LeaveCriticalSection(&filter
->filter
.filter_cs
);
1094 WaitForSingleObject(filter
->wait_state_event
, timeout
);
1095 EnterCriticalSection(&filter
->filter
.filter_cs
);
1097 hr
= filter
->wait_state_hr
;
1102 static const struct strmbase_filter_ops testfilter_ops
=
1104 .filter_get_pin
= testfilter_get_pin
,
1105 .filter_destroy
= testfilter_destroy
,
1106 .filter_init_stream
= testfilter_init_stream
,
1107 .filter_cleanup_stream
= testfilter_cleanup_stream
,
1108 .filter_wait_state
= testfilter_wait_state
,
1111 static inline struct testfilter
*impl_from_base_pin(struct strmbase_pin
*iface
)
1113 return CONTAINING_RECORD(iface
, struct testfilter
, source
.pin
);
1116 static HRESULT
testsource_get_media_type(struct strmbase_pin
*iface
, unsigned int index
, AM_MEDIA_TYPE
*mt
)
1118 struct testfilter
*filter
= impl_from_base_pin(iface
);
1120 if (index
< 1 && filter
->preferred_mt
)
1121 return CopyMediaType(mt
, filter
->preferred_mt
);
1123 return VFW_S_NO_MORE_ITEMS
;
1126 static HRESULT
testsource_query_interface(struct strmbase_pin
*iface
, REFIID iid
, void **out
)
1128 struct testfilter
*filter
= impl_from_base_pin(iface
);
1130 if (IsEqualGUID(iid
, &IID_IMediaSeeking
) && filter
->IMediaSeeking_iface
.lpVtbl
)
1131 *out
= &filter
->IMediaSeeking_iface
;
1132 else if (IsEqualGUID(iid
, &IID_IQualityControl
) && filter
->IQualityControl_iface
.lpVtbl
)
1133 *out
= &filter
->IQualityControl_iface
;
1135 return E_NOINTERFACE
;
1137 IUnknown_AddRef((IUnknown
*)*out
);
1142 static HRESULT WINAPI
testsource_DecideAllocator(struct strmbase_source
*iface
, IMemInputPin
*pin
, IMemAllocator
**alloc
)
1144 ALLOCATOR_PROPERTIES props
= {0};
1147 /* AMDirectDrawStream tries to use it's custom allocator and
1148 * when it is able to do so it's behavior changes slightly
1149 * (e.g. it uses dynamic format change instead of reconnecting in SetFormat).
1150 * We don't yet implement the custom allocator so force the standard one for now. */
1151 hr
= CoCreateInstance(&CLSID_MemoryAllocator
, NULL
, CLSCTX_INPROC_SERVER
,
1152 &IID_IMemAllocator
, (void **)alloc
);
1153 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1155 IMemInputPin_GetAllocatorRequirements(pin
, &props
);
1156 hr
= iface
->pFuncsTable
->pfnDecideBufferSize(iface
, *alloc
, &props
);
1157 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1159 return IMemInputPin_NotifyAllocator(pin
, *alloc
, FALSE
);
1162 static HRESULT WINAPI
testsource_DecideBufferSize(struct strmbase_source
*iface
,
1163 IMemAllocator
*alloc
, ALLOCATOR_PROPERTIES
*requested
)
1165 ALLOCATOR_PROPERTIES actual
;
1167 if (!requested
->cbAlign
)
1168 requested
->cbAlign
= 1;
1170 if (requested
->cbBuffer
< 4096)
1171 requested
->cbBuffer
= 4096;
1173 if (!requested
->cBuffers
)
1174 requested
->cBuffers
= 2;
1176 return IMemAllocator_SetProperties(alloc
, requested
, &actual
);
1179 static const struct strmbase_source_ops testsource_ops
=
1181 .base
.pin_get_media_type
= testsource_get_media_type
,
1182 .base
.pin_query_interface
= testsource_query_interface
,
1183 .pfnAttemptConnection
= BaseOutputPinImpl_AttemptConnection
,
1184 .pfnDecideBufferSize
= testsource_DecideBufferSize
,
1185 .pfnDecideAllocator
= testsource_DecideAllocator
,
1188 static void testfilter_init(struct testfilter
*filter
)
1190 static const GUID clsid
= {0xabacab};
1191 memset(filter
, 0, sizeof(*filter
));
1192 strmbase_filter_init(&filter
->filter
, NULL
, &clsid
, &testfilter_ops
);
1193 strmbase_source_init(&filter
->source
, &filter
->filter
, L
"", &testsource_ops
);
1194 filter
->stop_position
= 0x8000000000000000ULL
;
1195 filter
->wait_state_event
= CreateEventW(NULL
, TRUE
, TRUE
, NULL
);
1198 static inline struct testfilter
*impl_from_IMediaSeeking(IMediaSeeking
*iface
)
1200 return CONTAINING_RECORD(iface
, struct testfilter
, IMediaSeeking_iface
);
1203 static HRESULT WINAPI
testsource_seeking_QueryInterface(IMediaSeeking
*iface
, REFIID iid
, void **out
)
1205 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1206 return IBaseFilter_QueryInterface(&filter
->filter
.IBaseFilter_iface
, iid
, out
);
1209 static ULONG WINAPI
testsource_seeking_AddRef(IMediaSeeking
*iface
)
1211 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1212 return IBaseFilter_AddRef(&filter
->filter
.IBaseFilter_iface
);
1215 static ULONG WINAPI
testsource_seeking_Release(IMediaSeeking
*iface
)
1217 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1218 return IBaseFilter_Release(&filter
->filter
.IBaseFilter_iface
);
1221 static HRESULT WINAPI
testsource_seeking_GetCapabilities(IMediaSeeking
*iface
, DWORD
*capabilities
)
1226 static HRESULT WINAPI
testsource_seeking_CheckCapabilities(IMediaSeeking
*iface
, DWORD
*capabilities
)
1228 ok(0, "Unexpected call.\n");
1232 static HRESULT WINAPI
testsource_seeking_IsFormatSupported(IMediaSeeking
*iface
, const GUID
*format
)
1234 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1236 ok(IsEqualGUID(format
, &TIME_FORMAT_MEDIA_TIME
),
1237 "Got format %s.\n", wine_dbgstr_guid(format
));
1239 return filter
->is_format_supported_hr
;
1242 static HRESULT WINAPI
testsource_seeking_QueryPreferredFormat(IMediaSeeking
*iface
, GUID
*format
)
1244 ok(0, "Unexpected call.\n");
1248 static HRESULT WINAPI
testsource_seeking_GetTimeFormat(IMediaSeeking
*iface
, GUID
*format
)
1250 ok(0, "Unexpected call.\n");
1254 static HRESULT WINAPI
testsource_seeking_IsUsingTimeFormat(IMediaSeeking
*iface
, const GUID
*format
)
1259 static HRESULT WINAPI
testsource_seeking_SetTimeFormat(IMediaSeeking
*iface
, const GUID
*format
)
1261 ok(0, "Unexpected call.\n");
1265 static HRESULT WINAPI
testsource_seeking_GetDuration(IMediaSeeking
*iface
, LONGLONG
*duration
)
1267 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1269 if (SUCCEEDED(filter
->get_duration_hr
))
1270 *duration
= 0x8000000000000000ULL
;
1272 return filter
->get_duration_hr
;
1275 static HRESULT WINAPI
testsource_seeking_GetStopPosition(IMediaSeeking
*iface
, LONGLONG
*stop
)
1277 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1279 if (SUCCEEDED(filter
->get_stop_position_hr
))
1280 *stop
= 0x8000000000000000ULL
;
1282 return filter
->get_stop_position_hr
;
1285 static HRESULT WINAPI
testsource_seeking_GetCurrentPosition(IMediaSeeking
*iface
, LONGLONG
*current
)
1291 static HRESULT WINAPI
testsource_seeking_ConvertTimeFormat(IMediaSeeking
*iface
, LONGLONG
*target
,
1292 const GUID
*target_format
, LONGLONG source
, const GUID
*source_format
)
1294 ok(0, "Unexpected call.\n");
1298 static HRESULT WINAPI
testsource_seeking_SetPositions(IMediaSeeking
*iface
, LONGLONG
*current_ptr
, DWORD current_flags
,
1299 LONGLONG
*stop_ptr
, DWORD stop_flags
)
1301 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
1303 if (SUCCEEDED(filter
->set_positions_hr
))
1306 filter
->current_position
= *current_ptr
;
1309 filter
->stop_position
= *stop_ptr
;
1312 return filter
->set_positions_hr
;
1315 static HRESULT WINAPI
testsource_seeking_GetPositions(IMediaSeeking
*iface
, LONGLONG
*current
, LONGLONG
*stop
)
1317 ok(0, "Unexpected call.\n");
1321 static HRESULT WINAPI
testsource_seeking_GetAvailable(IMediaSeeking
*iface
, LONGLONG
*earliest
, LONGLONG
*latest
)
1323 ok(0, "Unexpected call.\n");
1327 static HRESULT WINAPI
testsource_seeking_SetRate(IMediaSeeking
*iface
, double rate
)
1329 ok(0, "Unexpected call.\n");
1333 static HRESULT WINAPI
testsource_seeking_GetRate(IMediaSeeking
*iface
, double *rate
)
1335 ok(0, "Unexpected call.\n");
1339 static HRESULT WINAPI
testsource_seeking_GetPreroll(IMediaSeeking
*iface
, LONGLONG
*preroll
)
1341 ok(0, "Unexpected call.\n");
1345 static const IMediaSeekingVtbl testsource_seeking_vtbl
=
1347 testsource_seeking_QueryInterface
,
1348 testsource_seeking_AddRef
,
1349 testsource_seeking_Release
,
1350 testsource_seeking_GetCapabilities
,
1351 testsource_seeking_CheckCapabilities
,
1352 testsource_seeking_IsFormatSupported
,
1353 testsource_seeking_QueryPreferredFormat
,
1354 testsource_seeking_GetTimeFormat
,
1355 testsource_seeking_IsUsingTimeFormat
,
1356 testsource_seeking_SetTimeFormat
,
1357 testsource_seeking_GetDuration
,
1358 testsource_seeking_GetStopPosition
,
1359 testsource_seeking_GetCurrentPosition
,
1360 testsource_seeking_ConvertTimeFormat
,
1361 testsource_seeking_SetPositions
,
1362 testsource_seeking_GetPositions
,
1363 testsource_seeking_GetAvailable
,
1364 testsource_seeking_SetRate
,
1365 testsource_seeking_GetRate
,
1366 testsource_seeking_GetPreroll
,
1369 static inline struct testfilter
*impl_from_IQualityControl(IQualityControl
*iface
)
1371 return CONTAINING_RECORD(iface
, struct testfilter
, IQualityControl_iface
);
1374 static HRESULT WINAPI
testsource_qc_QueryInterface(IQualityControl
*iface
, REFIID iid
, void **out
)
1376 struct testfilter
*filter
= impl_from_IQualityControl(iface
);
1377 return IBaseFilter_QueryInterface(&filter
->filter
.IBaseFilter_iface
, iid
, out
);
1380 static ULONG WINAPI
testsource_qc_AddRef(IQualityControl
*iface
)
1382 struct testfilter
*filter
= impl_from_IQualityControl(iface
);
1383 return IBaseFilter_AddRef(&filter
->filter
.IBaseFilter_iface
);
1386 static ULONG WINAPI
testsource_qc_Release(IQualityControl
*iface
)
1388 struct testfilter
*filter
= impl_from_IQualityControl(iface
);
1389 return IBaseFilter_Release(&filter
->filter
.IBaseFilter_iface
);
1392 static HRESULT WINAPI
testsource_qc_Notify(IQualityControl
*iface
, IBaseFilter
*sender
, Quality q
)
1394 struct testfilter
*filter
= impl_from_IQualityControl(iface
);
1396 filter
->qc_notify_sender
= sender
;
1397 filter
->qc_notify_quality
= q
;
1399 return filter
->qc_notify_hr
;
1402 static HRESULT WINAPI
testsource_qc_SetSink(IQualityControl
*iface
, IQualityControl
*sink
)
1404 ok(0, "Unexpected call.\n");
1408 static const IQualityControlVtbl testsource_qc_vtbl
=
1410 testsource_qc_QueryInterface
,
1411 testsource_qc_AddRef
,
1412 testsource_qc_Release
,
1413 testsource_qc_Notify
,
1414 testsource_qc_SetSink
,
1417 #define check_get_stream(a,b,c,d) check_get_stream_(__LINE__,a,b,c,d)
1418 static void check_get_stream_(int line
, IAMMultiMediaStream
*mmstream
,
1419 IMediaStreamFilter
*filter
, const GUID
*mspid
, IMediaStream
*expect
)
1421 IMediaStream
*stream
= NULL
, *stream2
= NULL
;
1424 hr
= IAMMultiMediaStream_GetMediaStream(mmstream
, mspid
, &stream
);
1425 ok_(__FILE__
, line
)(hr
== (expect
? S_OK
: MS_E_NOSTREAM
),
1426 "IAMMultiMediaStream::GetMediaStream() returned %#lx.\n", hr
);
1427 hr
= IMediaStreamFilter_GetMediaStream(filter
, mspid
, &stream2
);
1428 ok_(__FILE__
, line
)(hr
== (expect
? S_OK
: MS_E_NOSTREAM
),
1429 "IMediaStreamFilter::GetMediaStream() returned %#lx.\n", hr
);
1432 ok_(__FILE__
, line
)(stream
== expect
, "Expected stream %p, got %p.\n", expect
, stream
);
1433 ok_(__FILE__
, line
)(stream2
== expect
, "Expected stream %p, got %p.\n", expect
, stream2
);
1436 if (stream
) IMediaStream_Release(stream
);
1437 if (stream2
) IMediaStream_Release(stream2
);
1440 static void test_add_stream(void)
1442 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
1443 IMediaStream
*video_stream
, *audio_stream
, *stream
;
1444 IDirectDrawMediaStream
*ddraw_stream
;
1445 IMediaStreamFilter
*stream_filter
;
1446 struct teststream teststream
;
1447 IDirectDraw
*ddraw
, *ddraw2
;
1448 IEnumFilters
*enum_filters
;
1449 IBaseFilter
*filters
[3];
1450 IGraphBuilder
*graph
;
1456 teststream_init(&teststream
);
1458 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &stream_filter
);
1459 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1461 hr
= IAMMultiMediaStream_EnumMediaStreams(mmstream
, 0, NULL
);
1462 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1463 hr
= IMediaStreamFilter_EnumMediaStreams(stream_filter
, 0, NULL
);
1464 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1466 hr
= IAMMultiMediaStream_GetMediaStream(mmstream
, &MSPID_PrimaryAudio
, NULL
);
1467 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
1468 hr
= IMediaStreamFilter_GetMediaStream(stream_filter
, &MSPID_PrimaryAudio
, NULL
);
1469 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
1470 hr
= IAMMultiMediaStream_GetMediaStream(mmstream
, &MSPID_PrimaryVideo
, NULL
);
1471 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
1472 hr
= IMediaStreamFilter_GetMediaStream(stream_filter
, &MSPID_PrimaryVideo
, NULL
);
1473 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
1475 check_enum_stream(mmstream
, stream_filter
, 0, NULL
);
1477 check_get_stream(mmstream
, stream_filter
, NULL
, NULL
);
1478 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryAudio
, NULL
);
1479 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryVideo
, NULL
);
1480 check_get_stream(mmstream
, stream_filter
, &test_mspid
, NULL
);
1482 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &test_mspid
, 0, &stream
);
1483 ok(hr
== MS_E_PURPOSEID
, "Got hr %#lx.\n", hr
);
1485 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &video_stream
);
1486 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1488 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
1489 ok(hr
== MS_E_PURPOSEID
, "Got hr %#lx.\n", hr
);
1491 hr
= IAMMultiMediaStream_EnumMediaStreams(mmstream
, 0, NULL
);
1492 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
1493 hr
= IMediaStreamFilter_EnumMediaStreams(stream_filter
, 0, NULL
);
1494 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
1495 hr
= IAMMultiMediaStream_EnumMediaStreams(mmstream
, 1, NULL
);
1496 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1497 hr
= IMediaStreamFilter_EnumMediaStreams(stream_filter
, 1, NULL
);
1498 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1500 check_enum_stream(mmstream
, stream_filter
, 0, video_stream
);
1501 check_enum_stream(mmstream
, stream_filter
, 1, NULL
);
1503 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryVideo
, video_stream
);
1504 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryAudio
, NULL
);
1505 check_get_stream(mmstream
, stream_filter
, &test_mspid
, NULL
);
1507 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &audio_stream
);
1508 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1510 check_enum_stream(mmstream
, stream_filter
, 0, video_stream
);
1511 check_enum_stream(mmstream
, stream_filter
, 1, audio_stream
);
1512 check_enum_stream(mmstream
, stream_filter
, 2, NULL
);
1514 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryVideo
, video_stream
);
1515 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryAudio
, audio_stream
);
1516 check_get_stream(mmstream
, stream_filter
, &test_mspid
, NULL
);
1518 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)&teststream
, &IID_IUnknown
, 0, &stream
);
1519 ok(hr
== MS_E_PURPOSEID
, "Got hr %#lx.\n", hr
);
1521 hr
= IMediaStreamFilter_QueryFilterInfo(stream_filter
, &info
);
1522 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1524 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)&teststream
, &test_mspid
, 0, &stream
);
1525 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1526 ok(stream
== (IMediaStream
*)&teststream
, "Streams didn't match.\n");
1527 IMediaStream_Release(stream
);
1528 ok(teststream
.mmstream
== mmstream
, "IAMMultiMediaStream objects didn't match.\n");
1529 ok(teststream
.filter
== stream_filter
, "IMediaStreamFilter objects didn't match.\n");
1530 ok(teststream
.graph
== info
.pGraph
, "IFilterGraph objects didn't match.\n");
1532 IFilterGraph_Release(info
.pGraph
);
1534 check_enum_stream(mmstream
, stream_filter
, 0, video_stream
);
1535 check_enum_stream(mmstream
, stream_filter
, 1, audio_stream
);
1536 check_enum_stream(mmstream
, stream_filter
, 2, (IMediaStream
*)&teststream
);
1537 check_enum_stream(mmstream
, stream_filter
, 3, NULL
);
1539 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryVideo
, video_stream
);
1540 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryAudio
, audio_stream
);
1541 check_get_stream(mmstream
, stream_filter
, &test_mspid
, (IMediaStream
*)&teststream
);
1543 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
1544 ok(hr
== MS_E_PURPOSEID
, "Got hr %#lx.\n", hr
);
1546 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
1547 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1548 ok(!!graph
, "Expected a non-NULL graph.\n");
1550 hr
= IGraphBuilder_EnumFilters(graph
, &enum_filters
);
1551 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1552 hr
= IEnumFilters_Next(enum_filters
, 3, filters
, &count
);
1553 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1554 ok(count
== 1, "Got count %lu.\n", count
);
1555 ok(filters
[0] == (IBaseFilter
*)stream_filter
,
1556 "Expected filter %p, got %p.\n", stream_filter
, filters
[0]);
1557 IBaseFilter_Release(filters
[0]);
1558 IEnumFilters_Release(enum_filters
);
1559 IGraphBuilder_Release(graph
);
1561 IMediaStreamFilter_Release(stream_filter
);
1562 ref
= IAMMultiMediaStream_Release(mmstream
);
1563 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1564 ref
= IMediaStream_Release(video_stream
);
1565 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1566 ref
= IMediaStream_Release(audio_stream
);
1567 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1568 ok(teststream
.refcount
== 1, "Got outstanding refcount %ld.\n", teststream
.refcount
);
1570 /* The return parameter is optional. */
1572 mmstream
= create_ammultimediastream();
1574 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, NULL
);
1575 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1577 hr
= IAMMultiMediaStream_GetMediaStream(mmstream
, &MSPID_PrimaryVideo
, &stream
);
1578 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1579 IMediaStream_Release(stream
);
1581 ref
= IAMMultiMediaStream_Release(mmstream
);
1582 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1584 /* Test supplying a DirectDraw object with the primary video stream. */
1586 hr
= DirectDrawCreate(NULL
, &ddraw
, NULL
);
1587 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
1588 mmstream
= create_ammultimediastream();
1590 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)ddraw
, &MSPID_PrimaryVideo
, 0, &video_stream
);
1591 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1593 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
1594 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1595 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw2
);
1596 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1597 ok(ddraw2
== ddraw
, "Expected IDirectDraw %p, got %p.\n", ddraw
, ddraw2
);
1598 IDirectDraw_Release(ddraw2
);
1599 IDirectDrawMediaStream_Release(ddraw_stream
);
1601 ref
= IAMMultiMediaStream_Release(mmstream
);
1602 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1603 ref
= IMediaStream_Release(video_stream
);
1604 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1605 ref
= IDirectDraw_Release(ddraw
);
1606 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1608 mmstream
= create_ammultimediastream();
1610 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &video_stream
);
1611 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1613 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
1614 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1615 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw
);
1616 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1617 ok(!!ddraw
, "Expected a non-NULL IDirectDraw.\n");
1618 IDirectDraw_Release(ddraw
);
1619 IDirectDrawMediaStream_Release(ddraw_stream
);
1621 ref
= IAMMultiMediaStream_Release(mmstream
);
1622 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1623 ref
= IMediaStream_Release(video_stream
);
1624 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1626 /* Test the AMMSF_ADDDEFAULTRENDERER flag. No stream is added; however, a
1627 * new filter will be added to the graph. */
1629 mmstream
= create_ammultimediastream();
1630 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &stream_filter
);
1631 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1633 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
,
1634 AMMSF_ADDDEFAULTRENDERER
, &video_stream
);
1635 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
1637 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
,
1638 AMMSF_ADDDEFAULTRENDERER
, NULL
);
1639 ok(hr
== MS_E_PURPOSEID
, "Got hr %#lx.\n", hr
);
1641 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
,
1642 AMMSF_ADDDEFAULTRENDERER
, &audio_stream
);
1643 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
1645 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
,
1646 AMMSF_ADDDEFAULTRENDERER
, NULL
);
1647 ok(hr
== S_OK
|| hr
== VFW_E_NO_AUDIO_HARDWARE
, "Got hr %#lx.\n", hr
);
1649 check_enum_stream(mmstream
, stream_filter
, 0, NULL
);
1651 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryAudio
, NULL
);
1652 check_get_stream(mmstream
, stream_filter
, &MSPID_PrimaryVideo
, NULL
);
1656 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
1657 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1658 ok(!!graph
, "Got graph %p.\n", graph
);
1659 hr
= IGraphBuilder_EnumFilters(graph
, &enum_filters
);
1660 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1661 hr
= IEnumFilters_Next(enum_filters
, 3, filters
, &count
);
1662 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1663 ok(count
== 2, "Got count %lu.\n", count
);
1664 ok(filters
[1] == (IBaseFilter
*)stream_filter
,
1665 "Expected filter %p, got %p.\n", stream_filter
, filters
[1]);
1666 hr
= IBaseFilter_GetClassID(filters
[0], &clsid
);
1667 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1668 ok(IsEqualGUID(&clsid
, &CLSID_DSoundRender
), "Got unexpected filter %s.\n", wine_dbgstr_guid(&clsid
));
1669 IBaseFilter_Release(filters
[0]);
1670 IBaseFilter_Release(filters
[1]);
1671 IEnumFilters_Release(enum_filters
);
1672 IGraphBuilder_Release(graph
);
1675 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &test_mspid
,
1676 AMMSF_ADDDEFAULTRENDERER
, NULL
);
1677 ok(hr
== MS_E_PURPOSEID
, "Got hr %#lx.\n", hr
);
1678 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &test_mspid
,
1679 AMMSF_ADDDEFAULTRENDERER
, &audio_stream
);
1680 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
1682 ref
= IAMMultiMediaStream_Release(mmstream
);
1683 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1684 ref
= IMediaStreamFilter_Release(stream_filter
);
1685 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
1688 static void test_media_streams(void)
1690 IAMMultiMediaStream
*pams
;
1692 IMediaStream
*video_stream
= NULL
;
1693 IMediaStream
*audio_stream
= NULL
;
1694 IMediaStreamFilter
* media_stream_filter
= NULL
;
1696 if (!(pams
= create_ammultimediastream()))
1699 hr
= IAMMultiMediaStream_Initialize(pams
, STREAMTYPE_READ
, 0, NULL
);
1700 ok(hr
== S_OK
, "IAMMultiMediaStream_Initialize returned: %lx\n", hr
);
1702 /* Retrieve media stream filter */
1703 hr
= IAMMultiMediaStream_GetFilter(pams
, NULL
);
1704 ok(hr
== E_POINTER
, "IAMMultiMediaStream_GetFilter returned: %lx\n", hr
);
1705 hr
= IAMMultiMediaStream_GetFilter(pams
, &media_stream_filter
);
1706 ok(hr
== S_OK
, "IAMMultiMediaStream_GetFilter returned: %lx\n", hr
);
1708 hr
= IAMMultiMediaStream_AddMediaStream(pams
, NULL
, &MSPID_PrimaryVideo
, 0, NULL
);
1709 ok(hr
== S_OK
, "IAMMultiMediaStream_AddMediaStream returned: %lx\n", hr
);
1710 hr
= IAMMultiMediaStream_GetMediaStream(pams
, &MSPID_PrimaryVideo
, &video_stream
);
1711 ok(hr
== S_OK
, "IAMMultiMediaStream_GetMediaStream returned: %lx\n", hr
);
1713 /* Check interfaces and samples for video */
1716 IAMMediaStream
* am_media_stream
;
1717 IMultiMediaStream
*multi_media_stream
;
1719 IAudioMediaStream
* audio_media_stream
;
1720 IDirectDrawMediaStream
*ddraw_stream
= NULL
;
1721 IDirectDrawStreamSample
*ddraw_sample
= NULL
;
1723 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IAMMediaStream
, (LPVOID
*)&am_media_stream
);
1724 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %lx\n", hr
);
1725 ok((void*)am_media_stream
== (void*)video_stream
, "Not same interface, got %p expected %p\n", am_media_stream
, video_stream
);
1727 hr
= IAMMediaStream_GetMultiMediaStream(am_media_stream
, NULL
);
1728 ok(hr
== E_POINTER
, "Expected E_POINTER, got %lx\n", hr
);
1730 multi_media_stream
= (void *)0xdeadbeef;
1731 hr
= IAMMediaStream_GetMultiMediaStream(am_media_stream
, &multi_media_stream
);
1732 ok(hr
== S_OK
, "IAMMediaStream_GetMultiMediaStream returned: %lx\n", hr
);
1733 ok((void *)multi_media_stream
== (void *)pams
, "Expected %p, got %p\n", pams
, multi_media_stream
);
1734 IMultiMediaStream_Release(multi_media_stream
);
1736 IAMMediaStream_Release(am_media_stream
);
1738 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IPin
, (void **)&pin
);
1739 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %lx\n", hr
);
1743 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IAudioMediaStream
, (LPVOID
*)&audio_media_stream
);
1744 ok(hr
== E_NOINTERFACE
, "IMediaStream_QueryInterface returned: %lx\n", hr
);
1746 hr
= IMediaStream_QueryInterface(video_stream
, &IID_IDirectDrawMediaStream
, (LPVOID
*)&ddraw_stream
);
1747 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %lx\n", hr
);
1751 DDSURFACEDESC current_format
, desired_format
;
1752 IDirectDrawPalette
*palette
;
1755 hr
= IDirectDrawMediaStream_GetFormat(ddraw_stream
, ¤t_format
, &palette
, &desired_format
, &flags
);
1756 ok(hr
== MS_E_NOSTREAM
, "IDirectDrawoMediaStream_GetFormat returned: %lx\n", hr
);
1758 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &ddraw_sample
);
1759 ok(hr
== S_OK
, "IDirectDrawMediaStream_CreateSample returned: %lx\n", hr
);
1761 hr
= IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream
, NULL
);
1762 ok(hr
== E_POINTER
, "Expected E_POINTER, got %lx\n", hr
);
1764 multi_media_stream
= (void *)0xdeadbeef;
1765 hr
= IDirectDrawMediaStream_GetMultiMediaStream(ddraw_stream
, &multi_media_stream
);
1766 ok(hr
== S_OK
, "IDirectDrawMediaStream_GetMultiMediaStream returned: %lx\n", hr
);
1767 ok((void *)multi_media_stream
== (void *)pams
, "Expected %p, got %p\n", pams
, multi_media_stream
);
1768 IMultiMediaStream_Release(multi_media_stream
);
1772 IDirectDrawStreamSample_Release(ddraw_sample
);
1774 IDirectDrawMediaStream_Release(ddraw_stream
);
1777 hr
= IAMMultiMediaStream_AddMediaStream(pams
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
1778 ok(hr
== S_OK
, "IAMMultiMediaStream_AddMediaStream returned: %lx\n", hr
);
1779 hr
= IAMMultiMediaStream_GetMediaStream(pams
, &MSPID_PrimaryAudio
, &audio_stream
);
1780 ok(hr
== S_OK
, "IAMMultiMediaStream_GetMediaStream returned: %lx\n", hr
);
1782 /* Check interfaces and samples for audio */
1785 IAMMediaStream
* am_media_stream
;
1786 IMultiMediaStream
*multi_media_stream
;
1788 IDirectDrawMediaStream
* ddraw_stream
= NULL
;
1789 IAudioMediaStream
* audio_media_stream
= NULL
;
1790 IAudioStreamSample
*audio_sample
= NULL
;
1792 hr
= IMediaStream_QueryInterface(audio_stream
, &IID_IAMMediaStream
, (LPVOID
*)&am_media_stream
);
1793 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %lx\n", hr
);
1794 ok((void*)am_media_stream
== (void*)audio_stream
, "Not same interface, got %p expected %p\n", am_media_stream
, audio_stream
);
1796 hr
= IAMMediaStream_GetMultiMediaStream(am_media_stream
, NULL
);
1797 ok(hr
== E_POINTER
, "Expected E_POINTER, got %lx\n", hr
);
1799 multi_media_stream
= (void *)0xdeadbeef;
1800 hr
= IAMMediaStream_GetMultiMediaStream(am_media_stream
, &multi_media_stream
);
1801 ok(hr
== S_OK
, "IAMMediaStream_GetMultiMediaStream returned: %lx\n", hr
);
1802 ok((void *)multi_media_stream
== (void *)pams
, "Expected %p, got %p\n", pams
, multi_media_stream
);
1803 IMultiMediaStream_Release(multi_media_stream
);
1805 IAMMediaStream_Release(am_media_stream
);
1807 hr
= IMediaStream_QueryInterface(audio_stream
, &IID_IPin
, (void **)&pin
);
1808 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %lx\n", hr
);
1812 hr
= IMediaStream_QueryInterface(audio_stream
, &IID_IDirectDrawMediaStream
, (LPVOID
*)&ddraw_stream
);
1813 ok(hr
== E_NOINTERFACE
, "IMediaStream_QueryInterface returned: %lx\n", hr
);
1815 hr
= IMediaStream_QueryInterface(audio_stream
, &IID_IAudioMediaStream
, (LPVOID
*)&audio_media_stream
);
1816 ok(hr
== S_OK
, "IMediaStream_QueryInterface returned: %lx\n", hr
);
1820 IAudioData
* audio_data
= NULL
;
1822 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
1823 ok(hr
== S_OK
, "CoCreateInstance returned: %lx\n", hr
);
1825 hr
= IAudioMediaStream_CreateSample(audio_media_stream
, NULL
, 0, &audio_sample
);
1826 ok(hr
== E_POINTER
, "IAudioMediaStream_CreateSample returned: %lx\n", hr
);
1828 EXPECT_REF(audio_stream
, 3);
1829 EXPECT_REF(audio_data
, 1);
1830 hr
= IAudioMediaStream_CreateSample(audio_media_stream
, audio_data
, 0, &audio_sample
);
1831 ok(hr
== S_OK
, "IAudioMediaStream_CreateSample returned: %lx\n", hr
);
1832 EXPECT_REF(audio_stream
, 4);
1833 EXPECT_REF(audio_data
, 2);
1835 hr
= IAudioMediaStream_GetMultiMediaStream(audio_media_stream
, NULL
);
1836 ok(hr
== E_POINTER
, "Expected E_POINTER, got %lx\n", hr
);
1838 multi_media_stream
= (void *)0xdeadbeef;
1839 hr
= IAudioMediaStream_GetMultiMediaStream(audio_media_stream
, &multi_media_stream
);
1840 ok(hr
== S_OK
, "IAudioMediaStream_GetMultiMediaStream returned: %lx\n", hr
);
1841 ok((void *)multi_media_stream
== (void *)pams
, "Expected %p, got %p\n", pams
, multi_media_stream
);
1842 IMultiMediaStream_Release(multi_media_stream
);
1845 IAudioData_Release(audio_data
);
1847 IAudioStreamSample_Release(audio_sample
);
1848 if (audio_media_stream
)
1849 IAudioMediaStream_Release(audio_media_stream
);
1853 if (media_stream_filter
)
1855 IEnumPins
*enum_pins
;
1857 hr
= IMediaStreamFilter_EnumPins(media_stream_filter
, &enum_pins
);
1858 ok(hr
== S_OK
, "IBaseFilter_EnumPins returned: %lx\n", hr
);
1861 IPin
* pins
[3] = { NULL
, NULL
, NULL
};
1863 ULONG expected_nb_pins
= audio_stream
? 2 : 1;
1866 hr
= IEnumPins_Next(enum_pins
, 3, pins
, &nb_pins
);
1867 ok(SUCCEEDED(hr
), "IEnumPins_Next returned: %lx\n", hr
);
1868 ok(nb_pins
== expected_nb_pins
, "Number of pins is %lu instead of %lu\n", nb_pins
, expected_nb_pins
);
1869 for (i
= 0; i
< min(nb_pins
, expected_nb_pins
); i
++)
1873 hr
= IPin_ConnectedTo(pins
[i
], &pin
);
1874 ok(hr
== VFW_E_NOT_CONNECTED
, "IPin_ConnectedTo returned: %lx\n", hr
);
1875 IPin_Release(pins
[i
]);
1877 IEnumPins_Release(enum_pins
);
1881 /* Test open file with no filename */
1882 hr
= IAMMultiMediaStream_OpenFile(pams
, NULL
, AMMSF_RENDERTOEXISTING
);
1883 ok(hr
== E_POINTER
, "IAMMultiMediaStream_OpenFile returned %lx instead of %lx\n", hr
, E_POINTER
);
1886 IMediaStream_Release(video_stream
);
1888 IMediaStream_Release(audio_stream
);
1889 if (media_stream_filter
)
1890 IMediaStreamFilter_Release(media_stream_filter
);
1892 IAMMultiMediaStream_Release(pams
);
1895 static void test_enum_pins(void)
1897 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
1898 IMediaStream
*stream0
, *stream1
;
1899 IPin
*pins
[3], *pin0
, *pin1
;
1900 IMediaStreamFilter
*filter
;
1901 IEnumPins
*enum1
, *enum2
;
1905 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
1906 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1908 ref
= get_refcount(filter
);
1909 ok(ref
== 3, "Got unexpected refcount %ld.\n", ref
);
1911 hr
= IMediaStreamFilter_EnumPins(filter
, NULL
);
1912 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
1914 hr
= IMediaStreamFilter_EnumPins(filter
, &enum1
);
1915 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1916 ref
= get_refcount(filter
);
1917 ok(ref
== 3, "Got unexpected refcount %ld.\n", ref
);
1918 ref
= get_refcount(enum1
);
1919 ok(ref
== 1, "Got unexpected refcount %ld.\n", ref
);
1921 hr
= IEnumPins_Next(enum1
, 1, NULL
, NULL
);
1922 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
1924 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
1925 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1927 hr
= IEnumPins_Reset(enum1
);
1928 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1930 hr
= IEnumPins_Skip(enum1
, 0);
1931 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1933 hr
= IEnumPins_Skip(enum1
, 1);
1934 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1936 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream0
);
1937 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1938 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream1
);
1939 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1940 hr
= IMediaStream_QueryInterface(stream0
, &IID_IPin
, (void **)&pin0
);
1941 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1942 hr
= IMediaStream_QueryInterface(stream1
, &IID_IPin
, (void **)&pin1
);
1943 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1945 /* Reset() isn't enough; we have to call EnumPins() again to see the updated
1947 hr
= IEnumPins_Reset(enum1
);
1948 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1950 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
1951 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1953 IEnumPins_Release(enum1
);
1955 hr
= IMediaStreamFilter_EnumPins(filter
, &enum1
);
1956 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1958 ref
= get_refcount(filter
);
1959 ok(ref
== 4, "Got unexpected refcount %ld.\n", ref
);
1960 ref
= get_refcount(enum1
);
1961 ok(ref
== 1, "Got unexpected refcount %ld.\n", ref
);
1962 ref
= get_refcount(pin0
);
1963 ok(ref
== 4, "Got unexpected refcount %ld.\n", ref
);
1964 ref
= get_refcount(pin1
);
1965 ok(ref
== 4, "Got unexpected refcount %ld.\n", ref
);
1967 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
1968 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1969 ok(pins
[0] == pin0
, "Expected pin %p, got %p.\n", pin0
, pins
[0]);
1970 ref
= get_refcount(filter
);
1971 ok(ref
== 4, "Got unexpected refcount %ld.\n", ref
);
1972 ref
= get_refcount(enum1
);
1973 ok(ref
== 1, "Got unexpected refcount %ld.\n", ref
);
1974 ref
= get_refcount(pin0
);
1975 ok(ref
== 5, "Got unexpected refcount %ld.\n", ref
);
1976 IPin_Release(pins
[0]);
1978 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
1979 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1980 ok(pins
[0] == pin1
, "Expected pin %p, got %p.\n", pin1
, pins
[0]);
1981 ref
= get_refcount(filter
);
1982 ok(ref
== 4, "Got unexpected refcount %ld.\n", ref
);
1983 ref
= get_refcount(enum1
);
1984 ok(ref
== 1, "Got unexpected refcount %ld.\n", ref
);
1985 ref
= get_refcount(pin1
);
1986 ok(ref
== 5, "Got unexpected refcount %ld.\n", ref
);
1987 IPin_Release(pins
[0]);
1989 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
1990 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
1992 hr
= IEnumPins_Reset(enum1
);
1993 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1995 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
1996 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1997 ok(count
== 1, "Got count %lu.\n", count
);
1998 ok(pins
[0] == pin0
, "Expected pin %p, got %p.\n", pin0
, pins
[0]);
1999 IPin_Release(pins
[0]);
2001 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
2002 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2003 ok(count
== 1, "Got count %lu.\n", count
);
2004 ok(pins
[0] == pin1
, "Expected pin %p, got %p.\n", pin1
, pins
[0]);
2005 IPin_Release(pins
[0]);
2007 hr
= IEnumPins_Reset(enum1
);
2008 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2010 hr
= IEnumPins_Next(enum1
, 3, pins
, NULL
);
2011 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
2013 hr
= IEnumPins_Next(enum1
, 3, pins
, &count
);
2014 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
2015 ok(count
== 2, "Got count %lu.\n", count
);
2016 ok(pins
[0] == pin0
, "Expected pin %p, got %p.\n", pin0
, pins
[0]);
2017 ok(pins
[1] == pin1
, "Expected pin %p, got %p.\n", pin1
, pins
[1]);
2018 IPin_Release(pins
[0]);
2019 IPin_Release(pins
[1]);
2021 hr
= IEnumPins_Reset(enum1
);
2022 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2024 hr
= IEnumPins_Clone(enum1
, &enum2
);
2025 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2027 hr
= IEnumPins_Skip(enum1
, 0);
2028 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2030 hr
= IEnumPins_Skip(enum1
, 2);
2031 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
2033 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
2034 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
2036 hr
= IEnumPins_Next(enum2
, 1, pins
, NULL
);
2037 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2038 ok(pins
[0] == pin0
, "Expected pin %p, got %p.\n", pin0
, pins
[0]);
2039 IPin_Release(pins
[0]);
2041 hr
= IEnumPins_Next(enum2
, 1, pins
, NULL
);
2042 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2043 ok(pins
[0] == pin1
, "Expected pin %p, got %p.\n", pin1
, pins
[0]);
2044 IPin_Release(pins
[0]);
2046 IEnumPins_Release(enum2
);
2047 IEnumPins_Release(enum1
);
2049 IMediaStreamFilter_Release(filter
);
2050 ref
= IAMMultiMediaStream_Release(mmstream
);
2051 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2052 IMediaStream_Release(stream1
);
2053 IMediaStream_Release(stream0
);
2054 ref
= IPin_Release(pin1
);
2055 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2056 ref
= IPin_Release(pin0
);
2057 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2060 static void test_find_pin(void)
2062 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
2063 IMediaStreamFilter
*filter
;
2064 IMediaStream
*stream
;
2069 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
2070 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2072 hr
= IMediaStreamFilter_FindPin(filter
, primary_video_sink_id
, &pin2
);
2073 ok(hr
== VFW_E_NOT_FOUND
, "Got hr %#lx.\n", hr
);
2075 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2076 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2077 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2078 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2080 hr
= IMediaStreamFilter_FindPin(filter
, primary_video_sink_id
, &pin2
);
2081 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2082 ok(pin2
== pin
, "Expected pin %p, got %p.\n", pin
, pin2
);
2086 IMediaStream_Release(stream
);
2087 IMediaStreamFilter_Release(filter
);
2088 ref
= IAMMultiMediaStream_Release(mmstream
);
2089 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2092 static void test_pin_info(void)
2094 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
2095 IMediaStreamFilter
*filter
;
2096 IMediaStream
*stream
;
2104 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
2105 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2107 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2108 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2109 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2110 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2112 hr
= IPin_QueryPinInfo(pin
, &info
);
2113 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2114 ok(info
.pFilter
== (IBaseFilter
*)filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
2115 ok(info
.dir
== PINDIR_INPUT
, "Got direction %d.\n", info
.dir
);
2116 ok(!wcscmp(info
.achName
, primary_video_sink_id
), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
2117 IBaseFilter_Release(info
.pFilter
);
2119 hr
= IPin_QueryDirection(pin
, &dir
);
2120 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2121 ok(dir
== PINDIR_INPUT
, "Got direction %d.\n", dir
);
2123 hr
= IPin_QueryId(pin
, &id
);
2124 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2125 ok(!wcscmp(id
, primary_video_sink_id
), "Got id %s.\n", wine_dbgstr_w(id
));
2128 hr
= IPin_QueryInternalConnections(pin
, NULL
, &count
);
2129 ok(hr
== E_NOTIMPL
, "Got hr %#lx.\n", hr
);
2132 IMediaStream_Release(stream
);
2134 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
2135 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2136 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2137 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2139 hr
= IPin_QueryPinInfo(pin
, &info
);
2140 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2141 ok(info
.pFilter
== (IBaseFilter
*)filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
2142 ok(info
.dir
== PINDIR_INPUT
, "Got direction %d.\n", info
.dir
);
2143 ok(!wcscmp(info
.achName
, primary_audio_sink_id
), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
2144 IBaseFilter_Release(info
.pFilter
);
2146 hr
= IPin_QueryDirection(pin
, &dir
);
2147 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2148 ok(dir
== PINDIR_INPUT
, "Got direction %d.\n", dir
);
2150 hr
= IPin_QueryId(pin
, &id
);
2151 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2152 ok(!wcscmp(id
, primary_audio_sink_id
), "Got id %s.\n", wine_dbgstr_w(id
));
2155 hr
= IPin_QueryInternalConnections(pin
, NULL
, &count
);
2156 ok(hr
== E_NOTIMPL
, "Got hr %#lx.\n", hr
);
2159 IMediaStream_Release(stream
);
2161 IMediaStreamFilter_Release(filter
);
2162 ref
= IAMMultiMediaStream_Release(mmstream
);
2163 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2168 IFilterGraph2 IFilterGraph2_iface
;
2169 IMediaEventSink IMediaEventSink_iface
;
2170 IUnknown
*inner_unk
;
2171 IFilterGraph2
*inner
;
2172 IMediaEventSink
*inner_event_sink
;
2174 unsigned int got_add_filter
;
2175 IBaseFilter
*filter
;
2176 WCHAR filter_name
[128];
2177 unsigned int got_notify
;
2179 LONG_PTR event_param1
;
2180 LONG_PTR event_param2
;
2183 static struct graph
*impl_from_IFilterGraph2(IFilterGraph2
*iface
)
2185 return CONTAINING_RECORD(iface
, struct graph
, IFilterGraph2_iface
);
2188 static struct graph
*impl_from_IMediaEventSink(IMediaEventSink
*iface
)
2190 return CONTAINING_RECORD(iface
, struct graph
, IMediaEventSink_iface
);
2193 static HRESULT WINAPI
graph_QueryInterface(IFilterGraph2
*iface
, REFIID iid
, void **out
)
2195 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2196 if (winetest_debug
> 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid
));
2197 if (IsEqualGUID(iid
, &IID_IFilterGraph2
)
2198 || IsEqualGUID(iid
, &IID_IGraphBuilder
)
2199 || IsEqualGUID(iid
, &IID_IFilterGraph
)
2200 || IsEqualGUID(iid
, &IID_IUnknown
))
2203 IFilterGraph2_AddRef(iface
);
2206 else if (IsEqualGUID(iid
, &IID_IMediaEventSink
))
2208 *out
= &graph
->IMediaEventSink_iface
;
2209 IFilterGraph2_AddRef(iface
);
2214 return IUnknown_QueryInterface(graph
->inner_unk
, iid
, out
);
2216 return E_NOINTERFACE
;
2219 static ULONG WINAPI
graph_AddRef(IFilterGraph2
*iface
)
2221 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2222 return InterlockedIncrement(&graph
->refcount
);
2225 static ULONG WINAPI
graph_Release(IFilterGraph2
*iface
)
2227 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2228 return InterlockedDecrement(&graph
->refcount
);
2231 static HRESULT WINAPI
graph_AddFilter(IFilterGraph2
*iface
, IBaseFilter
*filter
, const WCHAR
*name
)
2233 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2234 if (winetest_debug
> 1) trace("AddFilter(%p, %s)\n", filter
, wine_dbgstr_w(name
));
2235 ++graph
->got_add_filter
;
2236 graph
->filter
= filter
;
2238 wcscpy(graph
->filter_name
, name
);
2240 graph
->filter_name
[0] = 0;
2241 return IFilterGraph2_AddFilter(graph
->inner
, filter
, name
);
2244 static HRESULT WINAPI
graph_RemoveFilter(IFilterGraph2
*iface
, IBaseFilter
*filter
)
2246 ok(0, "Unexpected call.\n");
2250 static HRESULT WINAPI
graph_EnumFilters(IFilterGraph2
*iface
, IEnumFilters
**enumfilters
)
2252 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2253 if (winetest_debug
> 1) trace("EnumFilters()\n");
2254 return IFilterGraph2_EnumFilters(graph
->inner
, enumfilters
);
2257 static HRESULT WINAPI
graph_FindFilterByName(IFilterGraph2
*iface
, const WCHAR
*name
, IBaseFilter
**filter
)
2259 ok(0, "Unexpected call.\n");
2263 static HRESULT WINAPI
graph_ConnectDirect(IFilterGraph2
*iface
, IPin
*source
, IPin
*sink
, const AM_MEDIA_TYPE
*mt
)
2265 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2266 return IFilterGraph2_ConnectDirect(graph
->inner
, source
, sink
, mt
);
2269 static HRESULT WINAPI
graph_Reconnect(IFilterGraph2
*iface
, IPin
*pin
)
2271 ok(0, "Unexpected call.\n");
2275 static HRESULT WINAPI
graph_Disconnect(IFilterGraph2
*iface
, IPin
*pin
)
2277 struct graph
*graph
= impl_from_IFilterGraph2(iface
);
2278 return IFilterGraph2_Disconnect(graph
->inner
, pin
);
2281 static HRESULT WINAPI
graph_SetDefaultSyncSource(IFilterGraph2
*iface
)
2283 ok(0, "Unexpected call.\n");
2287 static HRESULT WINAPI
graph_Connect(IFilterGraph2
*iface
, IPin
*source
, IPin
*sink
)
2289 ok(0, "Unexpected call.\n");
2293 static HRESULT WINAPI
graph_Render(IFilterGraph2
*iface
, IPin
*source
)
2295 ok(0, "Unexpected call.\n");
2299 static HRESULT WINAPI
graph_RenderFile(IFilterGraph2
*iface
, const WCHAR
*filename
, const WCHAR
*playlist
)
2301 ok(0, "Unexpected call.\n");
2305 static HRESULT WINAPI
graph_AddSourceFilter(IFilterGraph2
*iface
,
2306 const WCHAR
*filename
, const WCHAR
*filter_name
, IBaseFilter
**filter
)
2308 ok(0, "Unexpected call.\n");
2312 static HRESULT WINAPI
graph_SetLogFile(IFilterGraph2
*iface
, DWORD_PTR file
)
2314 ok(0, "Unexpected call.\n");
2318 static HRESULT WINAPI
graph_Abort(IFilterGraph2
*iface
)
2320 ok(0, "Unexpected call.\n");
2324 static HRESULT WINAPI
graph_ShouldOperationContinue(IFilterGraph2
*iface
)
2326 ok(0, "Unexpected call.\n");
2330 static HRESULT WINAPI
graph_AddSourceFilterForMoniker(IFilterGraph2
*iface
,
2331 IMoniker
*moniker
, IBindCtx
*bind_ctx
, const WCHAR
*filter_name
, IBaseFilter
**filter
)
2333 ok(0, "Unexpected call.\n");
2337 static HRESULT WINAPI
graph_ReconnectEx(IFilterGraph2
*iface
, IPin
*pin
, const AM_MEDIA_TYPE
*mt
)
2339 ok(0, "Unexpected call.\n");
2343 static HRESULT WINAPI
graph_RenderEx(IFilterGraph2
*iface
, IPin
*pin
, DWORD flags
, DWORD
*context
)
2345 ok(0, "Unexpected call.\n");
2349 static const IFilterGraph2Vtbl graph_vtbl
=
2351 graph_QueryInterface
,
2357 graph_FindFilterByName
,
2358 graph_ConnectDirect
,
2361 graph_SetDefaultSyncSource
,
2365 graph_AddSourceFilter
,
2368 graph_ShouldOperationContinue
,
2369 graph_AddSourceFilterForMoniker
,
2374 static HRESULT WINAPI
event_sink_QueryInterface(IMediaEventSink
*iface
, REFIID iid
, void **out
)
2376 struct graph
*graph
= impl_from_IMediaEventSink(iface
);
2377 return IFilterGraph2_QueryInterface(&graph
->IFilterGraph2_iface
, iid
, out
);
2380 static ULONG WINAPI
event_sink_AddRef(IMediaEventSink
*iface
)
2382 struct graph
*graph
= impl_from_IMediaEventSink(iface
);
2383 return IFilterGraph2_AddRef(&graph
->IFilterGraph2_iface
);
2386 static ULONG WINAPI
event_sink_Release(IMediaEventSink
*iface
)
2388 struct graph
*graph
= impl_from_IMediaEventSink(iface
);
2389 return IFilterGraph2_Release(&graph
->IFilterGraph2_iface
);
2392 static HRESULT WINAPI
event_sink_Notify(IMediaEventSink
*iface
,
2393 LONG code
, LONG_PTR param1
, LONG_PTR param2
)
2395 struct graph
*graph
= impl_from_IMediaEventSink(iface
);
2396 ++graph
->got_notify
;
2397 graph
->event_code
= code
;
2398 graph
->event_param1
= param1
;
2399 graph
->event_param2
= param2
;
2400 return IMediaEventSink_Notify(graph
->inner_event_sink
, code
, param1
, param2
);
2403 static const IMediaEventSinkVtbl event_sink_vtbl
=
2405 event_sink_QueryInterface
,
2411 static void graph_init(struct graph
*graph
)
2415 memset(graph
, 0, sizeof(*graph
));
2416 graph
->IFilterGraph2_iface
.lpVtbl
= &graph_vtbl
;
2417 graph
->IMediaEventSink_iface
.lpVtbl
= &event_sink_vtbl
;
2418 graph
->refcount
= 1;
2419 hr
= CoCreateInstance(&CLSID_FilterGraph
, (IUnknown
*)&graph
->IFilterGraph2_iface
, CLSCTX_INPROC_SERVER
,
2420 &IID_IUnknown
, (void **)&graph
->inner_unk
);
2421 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2422 hr
= IUnknown_QueryInterface(graph
->inner_unk
, &IID_IFilterGraph2
, (void **)&graph
->inner
);
2423 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2424 hr
= IUnknown_QueryInterface(graph
->inner_unk
, &IID_IMediaEventSink
, (void **)&graph
->inner_event_sink
);
2425 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2428 static void graph_destroy(struct graph
*graph
)
2432 IMediaEventSink_Release(graph
->inner_event_sink
);
2433 IFilterGraph2_Release(graph
->inner
);
2434 ref
= IUnknown_Release(graph
->inner_unk
);
2435 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2438 static void test_initialize(void)
2440 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
2441 IMediaStreamFilter
*filter
;
2442 IGraphBuilder
*ret_graph
;
2443 IMediaStream
*stream
;
2449 ret_graph
= (IGraphBuilder
*)0xdeadbeef;
2450 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2451 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2452 ok(!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2454 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
2455 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2456 ok(!!filter
, "Expected a non-NULL filter.");
2457 IMediaStreamFilter_Release(filter
);
2459 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2460 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2462 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2463 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2464 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_WRITE
, 0, NULL
);
2465 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
2466 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2467 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
2469 ret_graph
= (IGraphBuilder
*)0xdeadbeef;
2470 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2471 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2472 ok(!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2474 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2475 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2477 hr
= IMediaStream_GetInformation(stream
, NULL
, &type
);
2478 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2479 ok(type
== STREAMTYPE_READ
, "Got type %u.\n", type
);
2480 IMediaStream_Release(stream
);
2483 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2484 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2485 ok(!!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2486 IGraphBuilder_Release(ret_graph
);
2488 ref
= IAMMultiMediaStream_Release(mmstream
);
2489 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2491 mmstream
= create_ammultimediastream();
2493 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_WRITE
, 0, NULL
);
2494 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2496 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_WRITE
, 0, NULL
);
2497 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2498 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2499 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
2500 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2501 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
2503 ret_graph
= (IGraphBuilder
*)0xdeadbeef;
2504 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2505 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2506 ok(!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2508 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2509 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2511 hr
= IMediaStream_GetInformation(stream
, NULL
, &type
);
2512 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2513 ok(type
== STREAMTYPE_WRITE
, "Got type %u.\n", type
);
2514 IMediaStream_Release(stream
);
2516 ref
= IAMMultiMediaStream_Release(mmstream
);
2517 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2519 mmstream
= create_ammultimediastream();
2521 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2522 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2524 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2525 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2526 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2527 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
2528 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_WRITE
, 0, NULL
);
2529 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
2531 ret_graph
= (IGraphBuilder
*)0xdeadbeef;
2532 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2533 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2534 ok(!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2536 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2537 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2539 hr
= IMediaStream_GetInformation(stream
, NULL
, &type
);
2540 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2541 ok(type
== STREAMTYPE_TRANSFORM
, "Got type %u.\n", type
);
2542 IMediaStream_Release(stream
);
2544 ref
= IAMMultiMediaStream_Release(mmstream
);
2545 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2547 mmstream
= create_ammultimediastream();
2549 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2550 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2553 hr
= IMediaStream_GetInformation(stream
, NULL
, &type
);
2554 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2555 ok(type
== STREAMTYPE_READ
, "Got type %u.\n", type
);
2558 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2559 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2560 ok(!!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2561 IGraphBuilder_Release(ret_graph
);
2563 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2564 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2567 hr
= IMediaStream_GetInformation(stream
, NULL
, &type
);
2568 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2569 ok(type
== STREAMTYPE_READ
, "Got type %u.\n", type
);
2571 IMediaStream_Release(stream
);
2572 ref
= IAMMultiMediaStream_Release(mmstream
);
2573 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2575 /* Test with a custom filter graph. */
2577 mmstream
= create_ammultimediastream();
2581 ret_graph
= (IGraphBuilder
*)0xdeadbeef;
2582 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2583 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2584 ok(!ret_graph
, "Got unexpected graph %p.\n", ret_graph
);
2586 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
2587 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2588 ok(!!filter
, "Expected a non-NULL filter.");
2590 graph
.got_add_filter
= 0;
2591 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, (IGraphBuilder
*)&graph
.IFilterGraph2_iface
);
2592 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2593 ok(graph
.got_add_filter
== 1, "Got %d calls to IGraphBuilder::AddFilter().\n", graph
.got_add_filter
);
2594 ok(graph
.filter
== (IBaseFilter
*)filter
, "Got filter %p.\n", filter
);
2595 ok(!wcscmp(graph
.filter_name
, L
"MediaStreamFilter"), "Got unexpected name %s.\n", wine_dbgstr_w(graph
.filter_name
));
2597 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &ret_graph
);
2598 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2599 ok(ret_graph
== (IGraphBuilder
*)&graph
, "Got unexpected graph %p.\n", ret_graph
);
2600 IGraphBuilder_Release(ret_graph
);
2602 graph
.got_add_filter
= 0;
2603 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
2604 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2605 ok(!graph
.got_add_filter
, "Got %d calls to IGraphBuilder::AddFilter().\n", graph
.got_add_filter
);
2607 graph
.got_add_filter
= 0;
2608 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, NULL
);
2609 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2610 ok(!graph
.got_add_filter
, "Got %d calls to IGraphBuilder::AddFilter().\n", graph
.got_add_filter
);
2612 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, (IGraphBuilder
*)&graph
);
2613 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
2614 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2615 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2616 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_WRITE
, 0, NULL
);
2617 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
2618 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_TRANSFORM
, 0, NULL
);
2619 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
2621 IMediaStreamFilter_Release(filter
);
2622 ref
= IAMMultiMediaStream_Release(mmstream
);
2623 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2625 graph_destroy(&graph
);
2628 static IAMMultiMediaStream
*mmstream_mmstream
;
2629 static STREAM_STATE mmstream_state
;
2631 static DWORD CALLBACK
mmstream_set_state(void *param
)
2635 hr
= IAMMultiMediaStream_SetState(mmstream_mmstream
, mmstream_state
);
2636 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2641 static void test_set_state(void)
2643 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
2644 IMediaControl
*media_control
;
2645 struct testfilter source
;
2646 IGraphBuilder
*graph
;
2652 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
2653 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2654 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
2655 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2656 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
2657 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2658 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
2659 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaControl
, (void **)&media_control
);
2660 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2661 testfilter_init(&source
);
2663 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
2664 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2666 source
.init_stream_hr
= E_FAIL
;
2667 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2668 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
2669 source
.init_stream_hr
= S_OK
;
2670 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2671 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2673 source
.init_stream_hr
= S_FALSE
;
2674 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2675 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2676 source
.init_stream_hr
= S_OK
;
2677 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2678 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2680 source
.wait_state_hr
= E_FAIL
;
2681 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2682 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2683 source
.wait_state_hr
= S_OK
;
2684 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2685 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2687 source
.wait_state_hr
= VFW_S_STATE_INTERMEDIATE
;
2688 ResetEvent(source
.wait_state_event
);
2690 mmstream_mmstream
= mmstream
;
2691 mmstream_state
= STREAMSTATE_RUN
;
2692 thread
= CreateThread(NULL
, 0, mmstream_set_state
, NULL
, 0, NULL
);
2694 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "SetState returned prematurely.\n");
2696 EnterCriticalSection(&source
.filter
.filter_cs
);
2697 source
.wait_state_hr
= S_OK
;
2698 SetEvent(source
.wait_state_event
);
2699 LeaveCriticalSection(&source
.filter
.filter_cs
);
2701 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
2702 CloseHandle(thread
);
2704 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2705 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2707 source
.init_stream_hr
= E_FAIL
;
2708 source
.wait_state_hr
= VFW_S_STATE_INTERMEDIATE
;
2709 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2710 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
2711 source
.init_stream_hr
= S_OK
;
2712 source
.wait_state_hr
= S_OK
;
2713 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2714 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2716 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2717 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2718 source
.cleanup_stream_hr
= E_FAIL
;
2719 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2720 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
2721 source
.cleanup_stream_hr
= S_OK
;
2722 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2723 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2725 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2726 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2727 source
.cleanup_stream_hr
= S_FALSE
;
2728 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2729 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
2730 source
.cleanup_stream_hr
= S_OK
;
2732 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2733 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2734 source
.wait_state_hr
= VFW_S_STATE_INTERMEDIATE
;
2735 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2736 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2737 source
.wait_state_hr
= S_OK
;
2739 /* Crashes on native. */
2742 hr
= IAMMultiMediaStream_GetState(mmstream
, NULL
);
2743 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
2747 hr
= IAMMultiMediaStream_GetState(mmstream
, &state
);
2748 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2749 ok(state
== STREAMSTATE_STOP
, "Got state %#x.\n", state
);
2751 hr
= IMediaControl_Run(media_control
);
2752 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2755 hr
= IAMMultiMediaStream_GetState(mmstream
, &state
);
2756 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2757 ok(state
== STREAMSTATE_STOP
, "Got state %#x.\n", state
);
2759 hr
= IMediaControl_Stop(media_control
);
2760 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2762 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2763 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2766 hr
= IAMMultiMediaStream_GetState(mmstream
, &state
);
2767 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2768 ok(state
== STREAMSTATE_RUN
, "Got state %#x.\n", state
);
2770 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
2771 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2774 hr
= IAMMultiMediaStream_GetState(mmstream
, &state
);
2775 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2776 ok(state
== STREAMSTATE_STOP
, "Got state %#x.\n", state
);
2778 source
.init_stream_hr
= E_FAIL
;
2779 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
2780 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
2783 hr
= IAMMultiMediaStream_GetState(mmstream
, &state
);
2784 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2785 ok(state
== STREAMSTATE_STOP
, "Got state %#x.\n", state
);
2787 ref
= IAMMultiMediaStream_Release(mmstream
);
2788 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2789 IMediaControl_Release(media_control
);
2790 ref
= IGraphBuilder_Release(graph
);
2791 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2794 static void test_enum_media_types(void)
2796 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
2797 IEnumMediaTypes
*enum1
, *enum2
;
2798 AM_MEDIA_TYPE
*mts
[2];
2799 IMediaStream
*stream
;
2804 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2805 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2806 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2807 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2809 hr
= IPin_EnumMediaTypes(pin
, &enum1
);
2810 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2812 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
2813 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
2815 hr
= IEnumMediaTypes_Next(enum1
, 0, mts
, &count
);
2816 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2817 ok(!count
, "Got count %lu.\n", count
);
2819 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2820 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2821 ok(count
== 1, "Got count %lu.\n", count
);
2822 CoTaskMemFree(mts
[0]);
2824 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2825 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
2826 ok(!count
, "Got count %lu.\n", count
);
2828 hr
= IEnumMediaTypes_Reset(enum1
);
2829 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2831 hr
= IEnumMediaTypes_Next(enum1
, 2, mts
, &count
);
2832 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
2833 ok(count
== 1, "Got count %lu.\n", count
);
2834 CoTaskMemFree(mts
[0]);
2836 hr
= IEnumMediaTypes_Reset(enum1
);
2837 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2839 hr
= IEnumMediaTypes_Clone(enum1
, &enum2
);
2840 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2842 hr
= IEnumMediaTypes_Skip(enum1
, 2);
2843 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2845 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2846 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
2847 ok(!count
, "Got count %lu.\n", count
);
2849 hr
= IEnumMediaTypes_Next(enum2
, 1, mts
, &count
);
2850 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2851 ok(count
== 1, "Got count %lu.\n", count
);
2852 CoTaskMemFree(mts
[0]);
2854 IEnumMediaTypes_Release(enum2
);
2855 IEnumMediaTypes_Release(enum1
);
2857 IMediaStream_Release(stream
);
2859 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
2860 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2861 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2862 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2864 hr
= IPin_EnumMediaTypes(pin
, &enum1
);
2865 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2867 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
2868 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
2870 hr
= IEnumMediaTypes_Next(enum1
, 0, mts
, &count
);
2871 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2872 ok(!count
, "Got count %lu.\n", count
);
2874 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2875 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2876 ok(count
== 1, "Got count %lu.\n", count
);
2877 CoTaskMemFree(mts
[0]->pbFormat
);
2878 CoTaskMemFree(mts
[0]);
2880 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2881 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
2882 ok(!count
, "Got count %lu.\n", count
);
2884 hr
= IEnumMediaTypes_Reset(enum1
);
2885 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2887 hr
= IEnumMediaTypes_Next(enum1
, 2, mts
, &count
);
2888 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
2889 ok(count
== 1, "Got count %lu.\n", count
);
2890 CoTaskMemFree(mts
[0]->pbFormat
);
2891 CoTaskMemFree(mts
[0]);
2893 hr
= IEnumMediaTypes_Reset(enum1
);
2894 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2896 hr
= IEnumMediaTypes_Clone(enum1
, &enum2
);
2897 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2899 hr
= IEnumMediaTypes_Skip(enum1
, 2);
2900 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2902 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
2903 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
2904 ok(!count
, "Got count %lu.\n", count
);
2906 hr
= IEnumMediaTypes_Next(enum2
, 1, mts
, &count
);
2907 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2908 ok(count
== 1, "Got count %lu.\n", count
);
2909 CoTaskMemFree(mts
[0]->pbFormat
);
2910 CoTaskMemFree(mts
[0]);
2912 IEnumMediaTypes_Release(enum2
);
2913 IEnumMediaTypes_Release(enum1
);
2915 IMediaStream_Release(stream
);
2917 ref
= IAMMultiMediaStream_Release(mmstream
);
2918 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
2921 static void test_media_types(void)
2923 static const VIDEOINFOHEADER2 req_vih2
;
2924 static const VIDEOINFOHEADER req_vih
;
2925 static const MPEG2VIDEOINFO req_m2vi
;
2926 static const MPEG1VIDEOINFO req_m1vi
;
2927 static const WAVEFORMATEX req_wfx
;
2928 static const WAVEFORMATEX expect_wfx
=
2930 .wFormatTag
= WAVE_FORMAT_PCM
,
2932 .nSamplesPerSec
= 11025,
2933 .nAvgBytesPerSec
= 11025 * 2,
2935 .wBitsPerSample
= 16,
2938 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
2939 IEnumMediaTypes
*enummt
;
2940 IMediaStream
*stream
;
2955 {&GUID_NULL
, NULL
, 0 },
2956 {&FORMAT_None
, NULL
, 0 },
2957 {&FORMAT_WaveFormatEx
, (BYTE
*)&req_wfx
, sizeof(WAVEFORMATEX
)},
2958 {&FORMAT_MPEG2Video
, (BYTE
*)&req_m2vi
, sizeof(MPEG2VIDEOINFO
)},
2959 {&FORMAT_MPEGVideo
, (BYTE
*)&req_m1vi
, sizeof(MPEG2VIDEOINFO
)},
2960 {&FORMAT_VideoInfo2
, (BYTE
*)&req_vih2
, sizeof(VIDEOINFOHEADER2
)},
2961 {&FORMAT_VideoInfo
, (BYTE
*)&req_vih
, sizeof(VIDEOINFOHEADER
)},
2964 static const GUID
*rejected_subtypes
[] =
2968 &MEDIASUBTYPE_RGB565
,
2969 &MEDIASUBTYPE_RGB555
,
2970 &MEDIASUBTYPE_RGB24
,
2971 &MEDIASUBTYPE_RGB32
,
2972 &MEDIASUBTYPE_ARGB32
,
2973 &MEDIASUBTYPE_ARGB1555
,
2974 &MEDIASUBTYPE_ARGB4444
,
2986 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
2987 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2988 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
2989 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2991 hr
= IPin_EnumMediaTypes(pin
, &enummt
);
2992 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2994 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, NULL
);
2995 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
2997 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, &count
);
2998 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
2999 ok(count
== 1, "Got count %lu.\n", count
);
3000 ok(IsEqualGUID(&pmt
->majortype
, &MEDIATYPE_Video
), "Got major type %s\n",
3001 wine_dbgstr_guid(&pmt
->majortype
));
3002 ok(IsEqualGUID(&pmt
->subtype
, &MEDIASUBTYPE_RGB8
), "Got subtype %s\n",
3003 wine_dbgstr_guid(&pmt
->subtype
));
3004 ok(pmt
->bFixedSizeSamples
== TRUE
, "Got fixed size %d.\n", pmt
->bFixedSizeSamples
);
3005 ok(!pmt
->bTemporalCompression
, "Got temporal compression %d.\n", pmt
->bTemporalCompression
);
3006 ok(pmt
->lSampleSize
== 10000, "Got sample size %lu.\n", pmt
->lSampleSize
);
3007 ok(IsEqualGUID(&pmt
->formattype
, &GUID_NULL
), "Got format type %s.\n",
3008 wine_dbgstr_guid(&pmt
->formattype
));
3009 ok(!pmt
->pUnk
, "Got pUnk %p.\n", pmt
->pUnk
);
3011 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
3013 pmt
->formattype
= *tests
[i
].type
;
3014 pmt
->cbFormat
= tests
[i
].size
;
3015 pmt
->pbFormat
= tests
[i
].format
;
3016 hr
= IPin_QueryAccept(pin
, pmt
);
3017 ok(hr
== (i
== 6 ? S_OK
: VFW_E_TYPE_NOT_ACCEPTED
), "Got hr %#lx.\n", hr
);
3020 pmt
->bFixedSizeSamples
= FALSE
;
3021 pmt
->bTemporalCompression
= TRUE
;
3022 pmt
->lSampleSize
= 123;
3023 hr
= IPin_QueryAccept(pin
, pmt
);
3024 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3026 pmt
->majortype
= MEDIATYPE_NULL
;
3027 hr
= IPin_QueryAccept(pin
, pmt
);
3028 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
3029 pmt
->majortype
= MEDIATYPE_Audio
;
3030 hr
= IPin_QueryAccept(pin
, pmt
);
3031 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
3032 pmt
->majortype
= MEDIATYPE_Stream
;
3033 hr
= IPin_QueryAccept(pin
, pmt
);
3034 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
3035 pmt
->majortype
= MEDIATYPE_Video
;
3037 for (i
= 0; i
< ARRAY_SIZE(rejected_subtypes
); ++i
)
3039 pmt
->subtype
= *rejected_subtypes
[i
];
3040 hr
= IPin_QueryAccept(pin
, pmt
);
3041 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx for subtype %s.\n",
3042 hr
, wine_dbgstr_guid(rejected_subtypes
[i
]));
3047 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, &count
);
3048 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
3050 IEnumMediaTypes_Release(enummt
);
3052 IMediaStream_Release(stream
);
3054 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3055 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3056 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3057 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3059 hr
= IPin_EnumMediaTypes(pin
, &enummt
);
3060 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3062 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, NULL
);
3063 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
3065 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, &count
);
3066 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3067 ok(count
== 1, "Got count %lu.\n", count
);
3068 ok(IsEqualGUID(&pmt
->majortype
, &MEDIATYPE_Audio
), "Got major type %s\n",
3069 wine_dbgstr_guid(&pmt
->majortype
));
3070 ok(IsEqualGUID(&pmt
->subtype
, &GUID_NULL
), "Got subtype %s\n",
3071 wine_dbgstr_guid(&pmt
->subtype
));
3072 ok(pmt
->bFixedSizeSamples
== TRUE
, "Got fixed size %d.\n", pmt
->bFixedSizeSamples
);
3073 ok(!pmt
->bTemporalCompression
, "Got temporal compression %d.\n", pmt
->bTemporalCompression
);
3074 ok(pmt
->lSampleSize
== 2, "Got sample size %lu.\n", pmt
->lSampleSize
);
3075 ok(IsEqualGUID(&pmt
->formattype
, &FORMAT_WaveFormatEx
), "Got format type %s.\n",
3076 wine_dbgstr_guid(&pmt
->formattype
));
3077 ok(!pmt
->pUnk
, "Got pUnk %p.\n", pmt
->pUnk
);
3078 ok(pmt
->cbFormat
== sizeof(WAVEFORMATEX
), "Got format size %lu.\n", pmt
->cbFormat
);
3079 ok(!memcmp(pmt
->pbFormat
, &expect_wfx
, pmt
->cbFormat
), "Format blocks didn't match.\n");
3081 hr
= IPin_QueryAccept(pin
, pmt
);
3082 ok(hr
== E_NOTIMPL
, "Got hr %#lx.\n", hr
);
3084 CoTaskMemFree(pmt
->pbFormat
);
3087 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, &count
);
3088 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
3090 IEnumMediaTypes_Release(enummt
);
3092 IMediaStream_Release(stream
);
3094 ref
= IAMMultiMediaStream_Release(mmstream
);
3095 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3098 static void test_get_end_of_stream_event_handle(void)
3100 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
3101 IMediaStreamFilter
*filter
;
3102 struct testfilter source
;
3103 IGraphBuilder
*graph
;
3104 IMediaStream
*stream
;
3110 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
3111 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3112 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
3113 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3114 ok(!!filter
, "Expected non-null filter.\n");
3115 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
3116 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3117 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3118 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3119 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
3120 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3121 ok(!!graph
, "Expected non-NULL graph.\n");
3122 testfilter_init(&source
);
3123 source
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
3124 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
3125 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3127 hr
= IAMMultiMediaStream_GetEndOfStreamEventHandle(mmstream
, NULL
);
3128 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
3130 event
= INVALID_HANDLE_VALUE
;
3131 hr
= IAMMultiMediaStream_GetEndOfStreamEventHandle(mmstream
, &event
);
3132 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3134 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &rgb32_mt
);
3135 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3137 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
3138 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3140 ok(WaitForSingleObject(event
, 0) == WAIT_TIMEOUT
, "Event should not be signaled.\n");
3142 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
3143 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3145 ok(WaitForSingleObject(event
, 0) == WAIT_TIMEOUT
, "Event should not be signaled.\n");
3147 hr
= IPin_EndOfStream(pin
);
3148 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3150 ok(WaitForSingleObject(event
, 0) == 0, "Event should be signaled.\n");
3152 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
3153 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3155 ok(WaitForSingleObject(event
, 0) == 0, "Event should be signaled.\n");
3157 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
3158 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3160 ok(WaitForSingleObject(event
, 0) == WAIT_TIMEOUT
, "Event should not be signaled.\n");
3162 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
3163 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3165 IGraphBuilder_Disconnect(graph
, pin
);
3166 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3168 ref
= IAMMultiMediaStream_Release(mmstream
);
3169 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3170 ref
= IGraphBuilder_Release(graph
);
3171 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3172 ref
= IMediaStreamFilter_Release(filter
);
3173 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3175 ref
= IMediaStream_Release(stream
);
3176 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3179 static IUnknown
*create_audio_data(void)
3181 IUnknown
*audio_data
= NULL
;
3182 HRESULT result
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
,
3183 &IID_IUnknown
, (void **)&audio_data
);
3184 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3188 static void test_audiodata_query_interface(void)
3190 IUnknown
*unknown
= create_audio_data();
3191 IMemoryData
*memory_data
= NULL
;
3192 IAudioData
*audio_data
= NULL
;
3196 result
= IUnknown_QueryInterface(unknown
, &IID_IMemoryData
, (void **)&memory_data
);
3197 ok(E_NOINTERFACE
== result
, "got 0x%08lx\n", result
);
3199 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3200 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3203 result
= IAudioData_QueryInterface(audio_data
, &IID_IMemoryData
, (void **)&memory_data
);
3204 ok(E_NOINTERFACE
== result
, "got 0x%08lx\n", result
);
3206 IAudioData_Release(audio_data
);
3209 IUnknown_Release(unknown
);
3212 static void test_audiodata_get_info(void)
3214 IUnknown
*unknown
= create_audio_data();
3215 IAudioData
*audio_data
= NULL
;
3219 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3222 /* test_audiodata_query_interface handles this case */
3223 skip("No IAudioData\n");
3227 result
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, NULL
);
3228 ok(MS_E_NOTINIT
== result
, "got 0x%08lx\n", result
);
3230 IAudioData_Release(audio_data
);
3233 IUnknown_Release(unknown
);
3236 static void test_audiodata_set_buffer(void)
3238 IUnknown
*unknown
= create_audio_data();
3239 IAudioData
*audio_data
= NULL
;
3240 BYTE buffer
[100] = {0};
3246 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3249 /* test_audiodata_query_interface handles this case */
3250 skip("No IAudioData\n");
3254 result
= IAudioData_SetBuffer(audio_data
, 100, NULL
, 0);
3255 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3257 data
= (BYTE
*)0xdeadbeef;
3258 length
= 0xdeadbeef;
3259 result
= IAudioData_GetInfo(audio_data
, &length
, &data
, NULL
);
3260 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3261 ok(100 == length
, "got %lu\n", length
);
3262 ok(NULL
!= data
, "got %p\n", data
);
3264 result
= IAudioData_SetBuffer(audio_data
, 0, buffer
, 0);
3265 ok(E_INVALIDARG
== result
, "got 0x%08lx\n", result
);
3267 result
= IAudioData_SetBuffer(audio_data
, sizeof(buffer
), buffer
, 0);
3268 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3270 data
= (BYTE
*)0xdeadbeef;
3271 length
= 0xdeadbeef;
3272 result
= IAudioData_GetInfo(audio_data
, &length
, &data
, NULL
);
3273 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3274 ok(sizeof(buffer
) == length
, "got %lu\n", length
);
3275 ok(buffer
== data
, "got %p\n", data
);
3277 IAudioData_Release(audio_data
);
3280 IUnknown_Release(unknown
);
3283 static void test_audiodata_set_actual(void)
3285 IUnknown
*unknown
= create_audio_data();
3286 IAudioData
*audio_data
= NULL
;
3287 BYTE buffer
[100] = {0};
3288 DWORD actual_data
= 0;
3292 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3295 /* test_audiodata_query_interface handles this case */
3296 skip("No IAudioData\n");
3300 result
= IAudioData_SetActual(audio_data
, 0);
3301 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3303 result
= IAudioData_SetBuffer(audio_data
, sizeof(buffer
), buffer
, 0);
3304 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3306 result
= IAudioData_SetActual(audio_data
, sizeof(buffer
) + 1);
3307 ok(E_INVALIDARG
== result
, "got 0x%08lx\n", result
);
3309 result
= IAudioData_SetActual(audio_data
, sizeof(buffer
));
3310 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3312 actual_data
= 0xdeadbeef;
3313 result
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_data
);
3314 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3315 ok(sizeof(buffer
) == actual_data
, "got %lu\n", actual_data
);
3317 result
= IAudioData_SetActual(audio_data
, 0);
3318 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3320 actual_data
= 0xdeadbeef;
3321 result
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_data
);
3322 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3323 ok(0 == actual_data
, "got %lu\n", actual_data
);
3325 IAudioData_Release(audio_data
);
3328 IUnknown_Release(unknown
);
3331 static void test_audiodata_get_format(void)
3333 IUnknown
*unknown
= create_audio_data();
3334 IAudioData
*audio_data
= NULL
;
3335 WAVEFORMATEX wave_format
= {0};
3339 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3342 /* test_audiodata_query_interface handles this case */
3343 skip("No IAudioData\n");
3347 result
= IAudioData_GetFormat(audio_data
, NULL
);
3348 ok(E_POINTER
== result
, "got 0x%08lx\n", result
);
3350 wave_format
.wFormatTag
= 0xdead;
3351 wave_format
.nChannels
= 0xdead;
3352 wave_format
.nSamplesPerSec
= 0xdeadbeef;
3353 wave_format
.nAvgBytesPerSec
= 0xdeadbeef;
3354 wave_format
.nBlockAlign
= 0xdead;
3355 wave_format
.wBitsPerSample
= 0xdead;
3356 wave_format
.cbSize
= 0xdead;
3357 result
= IAudioData_GetFormat(audio_data
, &wave_format
);
3358 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3359 ok(WAVE_FORMAT_PCM
== wave_format
.wFormatTag
, "got %u\n", wave_format
.wFormatTag
);
3360 ok(1 == wave_format
.nChannels
, "got %u\n", wave_format
.nChannels
);
3361 ok(11025 == wave_format
.nSamplesPerSec
, "got %lu\n", wave_format
.nSamplesPerSec
);
3362 ok(22050 == wave_format
.nAvgBytesPerSec
, "got %lu\n", wave_format
.nAvgBytesPerSec
);
3363 ok(2 == wave_format
.nBlockAlign
, "got %u\n", wave_format
.nBlockAlign
);
3364 ok(16 == wave_format
.wBitsPerSample
, "got %u\n", wave_format
.wBitsPerSample
);
3365 ok(0 == wave_format
.cbSize
, "got %u\n", wave_format
.cbSize
);
3367 IAudioData_Release(audio_data
);
3370 IUnknown_Release(unknown
);
3373 static void test_audiodata_set_format(void)
3375 IUnknown
*unknown
= create_audio_data();
3376 IAudioData
*audio_data
= NULL
;
3377 WAVEFORMATPCMEX wave_format
= {{0}};
3381 result
= IUnknown_QueryInterface(unknown
, &IID_IAudioData
, (void **)&audio_data
);
3384 /* test_audiodata_query_interface handles this case */
3385 skip("No IAudioData\n");
3389 result
= IAudioData_SetFormat(audio_data
, NULL
);
3390 ok(E_POINTER
== result
, "got 0x%08lx\n", result
);
3392 wave_format
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
3393 wave_format
.Format
.nChannels
= 2;
3394 wave_format
.Format
.nSamplesPerSec
= 44100;
3395 wave_format
.Format
.nAvgBytesPerSec
= 176400;
3396 wave_format
.Format
.nBlockAlign
= 4;
3397 wave_format
.Format
.wBitsPerSample
= 16;
3398 wave_format
.Format
.cbSize
= 22;
3399 wave_format
.Samples
.wValidBitsPerSample
= 16;
3400 wave_format
.dwChannelMask
= KSAUDIO_SPEAKER_STEREO
;
3401 wave_format
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
3402 result
= IAudioData_SetFormat(audio_data
, &wave_format
.Format
);
3403 ok(E_INVALIDARG
== result
, "got 0x%08lx\n", result
);
3405 wave_format
.Format
.wFormatTag
= WAVE_FORMAT_PCM
;
3406 wave_format
.Format
.nChannels
= 2;
3407 wave_format
.Format
.nSamplesPerSec
= 44100;
3408 wave_format
.Format
.nAvgBytesPerSec
= 176400;
3409 wave_format
.Format
.nBlockAlign
= 4;
3410 wave_format
.Format
.wBitsPerSample
= 16;
3411 wave_format
.Format
.cbSize
= 0;
3412 result
= IAudioData_SetFormat(audio_data
, &wave_format
.Format
);
3413 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3415 wave_format
.Format
.wFormatTag
= 0xdead;
3416 wave_format
.Format
.nChannels
= 0xdead;
3417 wave_format
.Format
.nSamplesPerSec
= 0xdeadbeef;
3418 wave_format
.Format
.nAvgBytesPerSec
= 0xdeadbeef;
3419 wave_format
.Format
.nBlockAlign
= 0xdead;
3420 wave_format
.Format
.wBitsPerSample
= 0xdead;
3421 wave_format
.Format
.cbSize
= 0xdead;
3422 result
= IAudioData_GetFormat(audio_data
, &wave_format
.Format
);
3423 ok(S_OK
== result
, "got 0x%08lx\n", result
);
3424 ok(WAVE_FORMAT_PCM
== wave_format
.Format
.wFormatTag
, "got %u\n", wave_format
.Format
.wFormatTag
);
3425 ok(2 == wave_format
.Format
.nChannels
, "got %u\n", wave_format
.Format
.nChannels
);
3426 ok(44100 == wave_format
.Format
.nSamplesPerSec
, "got %lu\n", wave_format
.Format
.nSamplesPerSec
);
3427 ok(176400 == wave_format
.Format
.nAvgBytesPerSec
, "got %lu\n", wave_format
.Format
.nAvgBytesPerSec
);
3428 ok(4 == wave_format
.Format
.nBlockAlign
, "got %u\n", wave_format
.Format
.nBlockAlign
);
3429 ok(16 == wave_format
.Format
.wBitsPerSample
, "got %u\n", wave_format
.Format
.wBitsPerSample
);
3430 ok(0 == wave_format
.Format
.cbSize
, "got %u\n", wave_format
.Format
.cbSize
);
3432 IAudioData_Release(audio_data
);
3435 IUnknown_Release(unknown
);
3438 struct advise_time_cookie
3443 HANDLE advise_time_called_event
;
3444 BOOL unadvise_called
;
3449 IReferenceClock IReferenceClock_iface
;
3452 struct advise_time_cookie
*advise_time_cookie
;
3453 HRESULT get_time_hr
;
3456 static inline struct testclock
*impl_from_IReferenceClock(IReferenceClock
*iface
)
3458 return CONTAINING_RECORD(iface
, struct testclock
, IReferenceClock_iface
);
3461 static HRESULT WINAPI
testclock_QueryInterface(IReferenceClock
*iface
, REFIID iid
, void **out
)
3463 if (winetest_debug
> 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid
));
3464 if (IsEqualGUID(iid
, &IID_IReferenceClock
)
3465 || IsEqualGUID(iid
, &IID_IUnknown
))
3468 IReferenceClock_AddRef(iface
);
3471 return E_NOINTERFACE
;
3474 static ULONG WINAPI
testclock_AddRef(IReferenceClock
*iface
)
3476 struct testclock
*clock
= impl_from_IReferenceClock(iface
);
3477 return InterlockedIncrement(&clock
->refcount
);
3480 static ULONG WINAPI
testclock_Release(IReferenceClock
*iface
)
3482 struct testclock
*clock
= impl_from_IReferenceClock(iface
);
3483 return InterlockedDecrement(&clock
->refcount
);
3486 static HRESULT WINAPI
testclock_GetTime(IReferenceClock
*iface
, REFERENCE_TIME
*time
)
3488 struct testclock
*clock
= impl_from_IReferenceClock(iface
);
3489 if (SUCCEEDED(clock
->get_time_hr
))
3490 *time
= clock
->time
;
3491 return clock
->get_time_hr
;
3494 static HRESULT WINAPI
testclock_AdviseTime(IReferenceClock
*iface
, REFERENCE_TIME base
, REFERENCE_TIME offset
, HEVENT event
, DWORD_PTR
*cookie
)
3496 struct testclock
*clock
= impl_from_IReferenceClock(iface
);
3497 if (clock
->advise_time_cookie
)
3499 clock
->advise_time_cookie
->base
= base
;
3500 clock
->advise_time_cookie
->offset
= offset
;
3501 clock
->advise_time_cookie
->event
= (HANDLE
)event
;
3502 SetEvent(clock
->advise_time_cookie
->advise_time_called_event
);
3506 SetEvent((HANDLE
)event
);
3508 *cookie
= (DWORD_PTR
)clock
->advise_time_cookie
;
3512 static HRESULT WINAPI
testclock_AdvisePeriodic(IReferenceClock
*iface
, REFERENCE_TIME start
, REFERENCE_TIME period
, HSEMAPHORE semaphore
, DWORD_PTR
*cookie
)
3514 ok(0, "Unexpected call.\n");
3518 static HRESULT WINAPI
testclock_Unadvise(IReferenceClock
*iface
, DWORD_PTR cookie
)
3521 ((struct advise_time_cookie
*)cookie
)->unadvise_called
= TRUE
;
3525 static IReferenceClockVtbl testclock_vtbl
=
3527 testclock_QueryInterface
,
3531 testclock_AdviseTime
,
3532 testclock_AdvisePeriodic
,
3536 static void testclock_init(struct testclock
*clock
)
3538 memset(clock
, 0, sizeof(*clock
));
3539 clock
->IReferenceClock_iface
.lpVtbl
= &testclock_vtbl
;
3542 static void test_audiostream_get_format(void)
3544 static const WAVEFORMATEX pin_format
=
3546 .wFormatTag
= WAVE_FORMAT_PCM
,
3548 .nSamplesPerSec
= 44100,
3549 .wBitsPerSample
= 16,
3551 .nAvgBytesPerSec
= 4 * 44100,
3555 .majortype
= MEDIATYPE_Audio
,
3556 .subtype
= MEDIASUBTYPE_PCM
,
3557 .formattype
= FORMAT_WaveFormatEx
,
3558 .cbFormat
= sizeof(WAVEFORMATEX
),
3559 .pbFormat
= (BYTE
*)&pin_format
,
3561 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
3562 IAudioMediaStream
*audio_stream
;
3563 struct testfilter source
;
3564 IGraphBuilder
*graph
;
3565 IMediaStream
*stream
;
3566 WAVEFORMATEX format
;
3571 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3572 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3573 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
3574 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3575 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3576 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3578 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
3579 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3580 ok(!!graph
, "Expected non-NULL graph.\n");
3582 testfilter_init(&source
);
3584 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, L
"source");
3585 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3587 hr
= IAudioMediaStream_GetFormat(audio_stream
, NULL
);
3588 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
3590 hr
= IAudioMediaStream_GetFormat(audio_stream
, &format
);
3591 ok(hr
== MS_E_NOSTREAM
, "Got hr %#lx.\n", hr
);
3593 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3594 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3596 memset(&format
, 0xcc, sizeof(format
));
3597 hr
= IAudioMediaStream_GetFormat(audio_stream
, &format
);
3598 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3599 ok(format
.wFormatTag
== WAVE_FORMAT_PCM
, "Got tag %#x.\n", format
.wFormatTag
);
3600 ok(format
.nChannels
== 2, "Got %u channels.\n", format
.nChannels
);
3601 ok(format
.nSamplesPerSec
== 44100, "Got sample rate %lu.\n", format
.nSamplesPerSec
);
3602 ok(format
.nAvgBytesPerSec
== 176400, "Got %lu bytes/sec.\n", format
.nAvgBytesPerSec
);
3603 ok(format
.nBlockAlign
== 4, "Got alignment %u.\n", format
.nBlockAlign
);
3604 ok(format
.wBitsPerSample
== 16, "Got %u bits/sample.\n", format
.wBitsPerSample
);
3605 ok(!format
.cbSize
, "Got extra size %u.\n", format
.cbSize
);
3607 hr
= IGraphBuilder_Disconnect(graph
, pin
);
3608 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3609 hr
= IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3610 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3612 hr
= IAudioMediaStream_GetFormat(audio_stream
, &format
);
3613 ok(hr
== MS_E_NOSTREAM
, "Got hr %#lx.\n", hr
);
3615 ref
= IAMMultiMediaStream_Release(mmstream
);
3616 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3617 ref
= IGraphBuilder_Release(graph
);
3618 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3620 IAudioMediaStream_Release(audio_stream
);
3621 ref
= IMediaStream_Release(stream
);
3622 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3623 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
3624 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3627 static HRESULT
set_audiostream_format(const WAVEFORMATEX
*format
)
3629 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
3630 IAudioMediaStream
*audio_stream
;
3631 IMediaStream
*stream
;
3635 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3636 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3637 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
3638 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3640 hr
= IAudioMediaStream_SetFormat(audio_stream
, format
);
3642 ref
= IAMMultiMediaStream_Release(mmstream
);
3643 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3644 IAudioMediaStream_Release(audio_stream
);
3645 ref
= IMediaStream_Release(stream
);
3646 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3651 static void test_audiostream_set_format(void)
3653 static const WAVEFORMATEX valid_format
=
3655 .wFormatTag
= WAVE_FORMAT_PCM
,
3657 .nSamplesPerSec
= 44100,
3658 .wBitsPerSample
= 16,
3660 .nAvgBytesPerSec
= 4 * 44100,
3663 const AM_MEDIA_TYPE mt
=
3665 .majortype
= MEDIATYPE_Audio
,
3666 .subtype
= MEDIASUBTYPE_PCM
,
3667 .formattype
= FORMAT_WaveFormatEx
,
3668 .cbFormat
= sizeof(WAVEFORMATEX
),
3669 .pbFormat
= (BYTE
*)&valid_format
,
3672 WAVEFORMATEXTENSIBLE extensible_format
;
3673 IAudioMediaStream
*audio_stream
;
3674 IAMMultiMediaStream
*mmstream
;
3675 struct testfilter source
;
3676 IGraphBuilder
*graph
;
3677 IMediaStream
*stream
;
3678 WAVEFORMATEX format
;
3683 hr
= set_audiostream_format(&valid_format
);
3684 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3685 hr
= set_audiostream_format(NULL
);
3686 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
3688 extensible_format
.Format
= valid_format
;
3689 extensible_format
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
3690 extensible_format
.Format
.cbSize
= sizeof(WAVEFORMATEXTENSIBLE
) - sizeof(WAVEFORMATEX
);
3691 extensible_format
.Samples
.wValidBitsPerSample
= valid_format
.wBitsPerSample
;
3692 extensible_format
.dwChannelMask
= KSAUDIO_SPEAKER_STEREO
;
3693 extensible_format
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
3694 hr
= set_audiostream_format(&extensible_format
.Format
);
3695 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
3697 format
= valid_format
;
3698 format
.nBlockAlign
= 1;
3699 hr
= set_audiostream_format(&format
);
3700 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3702 format
= valid_format
;
3703 format
.nAvgBytesPerSec
= 1234;
3704 hr
= set_audiostream_format(&format
);
3705 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3707 mmstream
= create_ammultimediastream();
3709 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3710 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3711 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
3712 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3714 hr
= IAudioMediaStream_SetFormat(audio_stream
, &valid_format
);
3715 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3717 hr
= IAudioMediaStream_GetFormat(audio_stream
, &format
);
3718 ok(hr
== MS_E_NOSTREAM
, "Got hr %#lx.\n", hr
);
3720 format
= valid_format
;
3721 format
.nChannels
= 1;
3722 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3723 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
3725 format
= valid_format
;
3726 format
.nSamplesPerSec
= 11025;
3727 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3728 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
3730 format
= valid_format
;
3731 format
.nAvgBytesPerSec
= 1234;
3732 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3733 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
3735 format
= valid_format
;
3736 format
.nBlockAlign
= 1;
3737 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3738 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
3740 format
= valid_format
;
3741 format
.wBitsPerSample
= 8;
3742 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3743 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
3745 format
= valid_format
;
3747 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3748 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
3750 hr
= IAudioMediaStream_SetFormat(audio_stream
, &valid_format
);
3751 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3753 ref
= IAMMultiMediaStream_Release(mmstream
);
3754 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3755 IAudioMediaStream_Release(audio_stream
);
3756 ref
= IMediaStream_Release(stream
);
3757 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3759 mmstream
= create_ammultimediastream();
3761 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3762 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3763 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
3764 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3765 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3766 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3768 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
3769 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3770 ok(!!graph
, "Expected non-NULL graph.\n");
3772 testfilter_init(&source
);
3774 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
3775 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3777 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3778 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3780 format
= valid_format
;
3781 format
.nChannels
= 1;
3782 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3783 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
3785 hr
= IGraphBuilder_Disconnect(graph
, pin
);
3786 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3787 hr
= IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3788 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3790 format
= valid_format
;
3791 format
.nChannels
= 1;
3792 hr
= IAudioMediaStream_SetFormat(audio_stream
, &format
);
3793 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3795 ref
= IAMMultiMediaStream_Release(mmstream
);
3796 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3797 ref
= IGraphBuilder_Release(graph
);
3798 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3800 IAudioMediaStream_Release(audio_stream
);
3801 ref
= IMediaStream_Release(stream
);
3802 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3803 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
3804 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3807 static void test_audiostream_receive_connection(void)
3809 WAVEFORMATEXTENSIBLE extensible_format
;
3810 IAudioMediaStream
*audio_stream
;
3811 IAMMultiMediaStream
*mmstream
;
3812 struct testfilter source
;
3813 IGraphBuilder
*graph
;
3814 IMediaStream
*stream
;
3815 WAVEFORMATEX format
;
3821 mmstream
= create_ammultimediastream();
3822 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
3823 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3824 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
3825 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3826 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3827 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3828 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
3829 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3830 ok(graph
!= NULL
, "Expected non-null graph\n");
3831 testfilter_init(&source
);
3832 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
3833 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3835 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
3836 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3837 IGraphBuilder_Disconnect(graph
, pin
);
3838 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3841 mt
.majortype
= GUID_NULL
;
3842 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3843 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
3846 mt
.subtype
= MEDIASUBTYPE_RGB24
;
3847 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3848 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3849 IGraphBuilder_Disconnect(graph
, pin
);
3850 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3853 mt
.formattype
= GUID_NULL
;
3854 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3855 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
3858 mt
.cbFormat
= sizeof(WAVEFORMATEX
) - 1;
3859 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3860 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
3862 extensible_format
.Format
= audio_format
;
3863 extensible_format
.Format
.wFormatTag
= WAVE_FORMAT_EXTENSIBLE
;
3864 extensible_format
.Format
.cbSize
= sizeof(WAVEFORMATEXTENSIBLE
) - sizeof(WAVEFORMATEX
);
3865 extensible_format
.Samples
.wValidBitsPerSample
= audio_format
.wBitsPerSample
;
3866 extensible_format
.dwChannelMask
= KSAUDIO_SPEAKER_STEREO
;
3867 extensible_format
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
3869 mt
.cbFormat
= sizeof(extensible_format
);
3870 mt
.pbFormat
= (BYTE
*)&extensible_format
;
3871 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3872 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
3874 hr
= IAudioMediaStream_SetFormat(audio_stream
, &audio_format
);
3875 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3877 format
= audio_format
;
3878 format
.nChannels
= 2;
3880 mt
.pbFormat
= (BYTE
*)&format
;
3881 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
3882 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
3884 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
3885 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3886 IGraphBuilder_Disconnect(graph
, pin
);
3887 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
3889 ref
= IAMMultiMediaStream_Release(mmstream
);
3890 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3891 ref
= IGraphBuilder_Release(graph
);
3892 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3894 IAudioMediaStream_Release(audio_stream
);
3895 ref
= IMediaStream_Release(stream
);
3896 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3897 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
3898 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
3901 static void test_ddrawstream_receive_connection(void)
3903 static const VIDEOINFOHEADER req_vih
;
3904 IDirectDrawMediaStream
*ddraw_stream
;
3905 IAMMultiMediaStream
*mmstream
;
3906 struct testfilter source
;
3907 DDSURFACEDESC format
;
3908 IMediaStream
*stream
;
3909 VIDEOINFO video_info
;
3916 static const VIDEOINFO yuy2_video_info
=
3918 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
3919 .bmiHeader
.biWidth
= 333,
3920 .bmiHeader
.biHeight
= -444,
3921 .bmiHeader
.biPlanes
= 1,
3922 .bmiHeader
.biBitCount
= 16,
3923 .bmiHeader
.biCompression
= MAKEFOURCC('Y', 'U', 'Y', '2'),
3926 const AM_MEDIA_TYPE yuy2_mt
=
3928 .majortype
= MEDIATYPE_Video
,
3929 .subtype
= MEDIASUBTYPE_YUY2
,
3930 .formattype
= FORMAT_VideoInfo
,
3931 .cbFormat
= sizeof(VIDEOINFOHEADER
),
3932 .pbFormat
= (BYTE
*)&yuy2_video_info
,
3935 const AM_MEDIA_TYPE video_mt
=
3937 .majortype
= MEDIATYPE_Video
,
3938 .subtype
= MEDIASUBTYPE_RGB8
,
3939 .formattype
= FORMAT_VideoInfo
,
3940 .cbFormat
= sizeof(VIDEOINFOHEADER
),
3941 .pbFormat
= (BYTE
*)&req_vih
,
3944 static const GUID
*subtypes
[] =
3946 &MEDIASUBTYPE_RGB24
,
3947 &MEDIASUBTYPE_RGB32
,
3948 &MEDIASUBTYPE_RGB555
,
3949 &MEDIASUBTYPE_RGB565
,
3952 &MEDIASUBTYPE_ARGB32
,
3953 &MEDIASUBTYPE_ARGB1555
,
3954 &MEDIASUBTYPE_ARGB4444
,
3966 mmstream
= create_ammultimediastream();
3967 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
3968 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3969 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
3970 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3971 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
3972 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3974 testfilter_init(&source
);
3977 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3978 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3979 hr
= IPin_Disconnect(pin
);
3980 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3982 for (i
= 0; i
< ARRAY_SIZE(subtypes
); ++i
)
3985 mt
.subtype
= *subtypes
[i
];
3986 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
3987 ok(hr
== (i
< 4 ? S_OK
: VFW_E_TYPE_NOT_ACCEPTED
), "Got hr %#lx.\n", hr
);
3990 hr
= IPin_Disconnect(pin
);
3991 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
3995 format
= rgb8_format
;
3996 format
.dwFlags
= DDSD_WIDTH
;
3997 format
.dwWidth
= 222;
3998 format
.dwHeight
= 555;
3999 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
4000 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4002 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb32_mt
);
4003 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4004 hr
= IPin_Disconnect(pin
);
4005 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4007 format
= rgb8_format
;
4008 format
.dwFlags
= DDSD_HEIGHT
;
4009 format
.dwWidth
= 333;
4010 format
.dwHeight
= 444;
4011 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
4012 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4014 video_info
= rgb555_video_info
;
4015 video_info
.bmiHeader
.biWidth
= 333;
4016 video_info
.bmiHeader
.biHeight
= 444;
4018 mt
.pbFormat
= (BYTE
*)&video_info
;
4019 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
4020 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4021 hr
= IPin_Disconnect(pin
);
4022 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4024 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb32_mt
);
4025 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4026 hr
= IPin_Disconnect(pin
);
4027 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4029 video_info
= rgb32_video_info
;
4030 video_info
.bmiHeader
.biWidth
= 332;
4031 video_info
.bmiHeader
.biHeight
= 444;
4033 mt
.pbFormat
= (BYTE
*)&video_info
;
4034 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
4035 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
4037 video_info
= rgb32_video_info
;
4038 video_info
.bmiHeader
.biWidth
= 333;
4039 video_info
.bmiHeader
.biHeight
= 443;
4041 mt
.pbFormat
= (BYTE
*)&video_info
;
4042 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &mt
);
4043 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
4045 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb8_format
, NULL
);
4046 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4048 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb555_mt
);
4049 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
4051 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb8_mt
);
4052 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4053 hr
= IPin_Disconnect(pin
);
4054 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4056 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb555_format
, NULL
);
4057 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4059 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb565_mt
);
4060 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
4062 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb555_mt
);
4063 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4064 hr
= IPin_Disconnect(pin
);
4065 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4067 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb565_format
, NULL
);
4068 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4070 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb24_mt
);
4071 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
4073 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb565_mt
);
4074 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4075 hr
= IPin_Disconnect(pin
);
4076 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4078 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb24_format
, NULL
);
4079 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4081 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb32_mt
);
4082 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
4084 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb24_mt
);
4085 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4086 hr
= IPin_Disconnect(pin
);
4087 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4089 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb32_format
, NULL
);
4090 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4092 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb8_mt
);
4093 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
4095 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb32_mt
);
4096 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4097 hr
= IPin_Disconnect(pin
);
4098 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4100 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &yuy2_format
, NULL
);
4101 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4103 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &yuy2_mt
);
4104 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
4106 format
= yuy2_format
;
4107 format
.ddpfPixelFormat
.u2
.dwRBitMask
= 0xf800;
4108 format
.ddpfPixelFormat
.u3
.dwGBitMask
= 0x07e0;
4109 format
.ddpfPixelFormat
.u4
.dwBBitMask
= 0x001f;
4110 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
4111 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4113 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb565_mt
);
4114 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#lx.\n", hr
);
4116 format
= rgb8_format
;
4118 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
4119 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4121 hr
= IPin_ReceiveConnection(pin
, &source
.source
.pin
.IPin_iface
, &rgb565_mt
);
4122 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4123 hr
= IPin_Disconnect(pin
);
4124 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4126 ref
= IAMMultiMediaStream_Release(mmstream
);
4127 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4129 IDirectDrawMediaStream_Release(ddraw_stream
);
4130 ref
= IMediaStream_Release(stream
);
4131 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4132 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
4133 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4136 static void test_audiostream_receive(void)
4138 ALLOCATOR_PROPERTIES properties
=
4145 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
4146 ALLOCATOR_PROPERTIES actual
;
4147 struct testfilter source
;
4148 IMemAllocator
*allocator
;
4149 IGraphBuilder
*graph
;
4150 IMediaStream
*stream
;
4151 IMediaSample
*sample1
;
4152 IMediaSample
*sample2
;
4153 IMediaSample
*sample3
;
4158 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
4159 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4160 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
4161 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4162 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
4163 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4164 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
4165 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4166 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
4167 testfilter_init(&source
);
4168 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
4169 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4170 hr
= CoCreateInstance(&CLSID_MemoryAllocator
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMemAllocator
, (void **)&allocator
);
4171 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4172 hr
= IMemAllocator_SetProperties(allocator
, &properties
, &actual
);
4173 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4174 hr
= IMemAllocator_Commit(allocator
);
4175 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4177 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
4178 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4180 hr
= IMemAllocator_GetBuffer(allocator
, &sample1
, NULL
, NULL
, 0);
4181 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4182 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample1
);
4183 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#lx.\n", hr
);
4184 ref
= IMediaSample_Release(sample1
);
4185 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4187 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4188 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4190 hr
= IMemAllocator_GetBuffer(allocator
, &sample1
, NULL
, NULL
, 0);
4191 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4192 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample1
);
4193 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4194 ref
= get_refcount(sample1
);
4195 ok(ref
== 2, "Got unexpected refcount %ld.\n", ref
);
4197 hr
= IMemAllocator_GetBuffer(allocator
, &sample2
, NULL
, NULL
, 0);
4198 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4199 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample2
);
4200 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4201 ref
= get_refcount(sample2
);
4202 ok(ref
== 2, "Got unexpected refcount %ld.\n", ref
);
4204 hr
= IPin_EndOfStream(pin
);
4205 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4207 hr
= IMemAllocator_GetBuffer(allocator
, &sample3
, NULL
, NULL
, 0);
4208 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4209 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample3
);
4210 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4211 ref
= get_refcount(sample3
);
4212 ok(ref
== 2, "Got unexpected refcount %ld.\n", ref
);
4214 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4215 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4217 ref
= IMediaSample_Release(sample1
);
4218 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4219 ref
= IMediaSample_Release(sample2
);
4220 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4221 ref
= IMediaSample_Release(sample3
);
4222 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4224 hr
= IMemAllocator_GetBuffer(allocator
, &sample1
, NULL
, NULL
, 0);
4225 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4226 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample1
);
4227 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#lx.\n", hr
);
4228 ref
= IMediaSample_Release(sample1
);
4229 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4231 IGraphBuilder_Disconnect(graph
, pin
);
4232 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
4234 hr
= IMemAllocator_Decommit(allocator
);
4235 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4237 ref
= IAMMultiMediaStream_Release(mmstream
);
4238 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4239 ref
= IGraphBuilder_Release(graph
);
4240 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4242 ref
= IMediaStream_Release(stream
);
4243 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4244 ref
= IMemAllocator_Release(allocator
);
4245 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4248 static void test_audiostream_initialize(void)
4250 IAMMediaStream
*stream
;
4256 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream
);
4257 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4259 /* Crashes on native. */
4262 hr
= IAMMediaStream_Initialize(stream
, NULL
, 0, NULL
, STREAMTYPE_WRITE
);
4263 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
4266 hr
= IAMMediaStream_Initialize(stream
, NULL
, 0, &test_mspid
, STREAMTYPE_WRITE
);
4267 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4269 hr
= IAMMediaStream_GetInformation(stream
, &mspid
, &type
);
4270 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4271 ok(IsEqualGUID(&mspid
, &test_mspid
), "Got mspid %s.\n", wine_dbgstr_guid(&mspid
));
4272 ok(type
== STREAMTYPE_WRITE
, "Got type %u.\n", type
);
4274 hr
= IAMMediaStream_Initialize(stream
, NULL
, 0, &MSPID_PrimaryAudio
, STREAMTYPE_READ
);
4275 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4277 hr
= IAMMediaStream_GetInformation(stream
, &mspid
, &type
);
4278 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4279 ok(IsEqualGUID(&mspid
, &MSPID_PrimaryAudio
), "Got mspid %s.\n", wine_dbgstr_guid(&mspid
));
4280 ok(type
== STREAMTYPE_READ
, "Got type %u.\n", type
);
4282 ref
= IAMMediaStream_Release(stream
);
4283 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4286 static void test_audiostream_begin_flush_end_flush(void)
4288 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
4289 static const MSPID mspid
= {0x88888888, 1};
4290 IAudioStreamSample
*stream_sample
;
4291 IAudioMediaStream
*audio_stream
;
4292 IMediaStreamFilter
*filter
;
4293 IMediaSample
*media_sample
;
4294 struct testfilter source2
;
4295 struct testfilter source
;
4296 IAMMediaStream
*stream2
;
4297 IAudioData
*audio_data
;
4298 IMediaStream
*stream
;
4306 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, (IGraphBuilder
*)&graph
.IFilterGraph2_iface
);
4307 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4308 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
4309 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4310 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream2
);
4311 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4312 hr
= IAMMediaStream_Initialize(stream2
, NULL
, 0, &mspid
, STREAMTYPE_READ
);
4313 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4314 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream2
, &mspid
, 0, NULL
);
4315 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4316 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
4317 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4318 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
4319 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4320 hr
= IAMMediaStream_QueryInterface(stream2
, &IID_IPin
, (void **)&pin2
);
4321 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4322 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
4323 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4324 testfilter_init(&source
);
4325 testfilter_init(&source2
);
4326 source
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
4327 hr
= IFilterGraph2_AddFilter(&graph
.IFilterGraph2_iface
, &source
.filter
.IBaseFilter_iface
, NULL
);
4328 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4329 hr
= IFilterGraph2_AddFilter(&graph
.IFilterGraph2_iface
, &source2
.filter
.IBaseFilter_iface
, NULL
);
4330 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4331 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
4332 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4333 hr
= IAudioData_SetBuffer(audio_data
, 16, NULL
, 0);
4334 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4335 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &stream_sample
);
4336 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4338 hr
= IFilterGraph2_ConnectDirect(&graph
.IFilterGraph2_iface
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
4339 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4340 hr
= IFilterGraph2_ConnectDirect(&graph
.IFilterGraph2_iface
, &source2
.source
.pin
.IPin_iface
, pin2
, &audio_mt
);
4341 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4343 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
4344 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4346 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4347 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4349 hr
= IMemAllocator_GetBuffer(source
.source
.pAllocator
, &media_sample
, NULL
, NULL
, 0);
4350 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4351 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
4352 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4353 ref
= get_refcount(media_sample
);
4354 ok(ref
== 2, "Got unexpected refcount %ld.\n", ref
);
4356 hr
= IPin_EndOfStream(pin
);
4357 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4359 hr
= IPin_BeginFlush(pin
);
4360 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4362 ref
= IMediaSample_Release(media_sample
);
4363 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4365 hr
= IMemAllocator_GetBuffer(source
.source
.pAllocator
, &media_sample
, NULL
, NULL
, 0);
4366 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4367 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
4368 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
4370 ref
= IMediaSample_Release(media_sample
);
4371 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4373 hr
= IAudioStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4374 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
4376 hr
= IPin_EndOfStream(pin
);
4377 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
4379 hr
= IPin_EndFlush(pin
);
4380 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4382 hr
= IMemAllocator_GetBuffer(source
.source
.pAllocator
, &media_sample
, NULL
, NULL
, 0);
4383 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4384 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
4385 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4386 ref
= IMediaSample_Release(media_sample
);
4387 ok(ref
== 1, "Got outstanding refcount %ld.\n", ref
);
4389 hr
= IPin_EndOfStream(pin
);
4390 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4392 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4393 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4394 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4395 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4397 hr
= IPin_BeginFlush(pin
);
4398 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4399 hr
= IPin_EndFlush(pin
);
4400 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4402 hr
= IPin_EndOfStream(pin
);
4403 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4405 graph
.got_notify
= 0;
4407 hr
= IPin_EndOfStream(pin2
);
4408 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4410 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
4411 ok(graph
.event_code
== EC_COMPLETE
, "Got event code %ld.\n", graph
.event_code
);
4413 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4414 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4415 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4416 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4418 hr
= IPin_EndOfStream(pin
);
4419 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4421 hr
= IPin_BeginFlush(pin
);
4422 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4423 hr
= IPin_EndFlush(pin
);
4424 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4426 graph
.got_notify
= 0;
4427 graph
.event_code
= 0xcc;
4429 hr
= IPin_EndOfStream(pin2
);
4430 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4432 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
4434 hr
= IPin_EndOfStream(pin
);
4435 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4437 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
4438 ok(graph
.event_code
== EC_COMPLETE
, "Got event code %ld.\n", graph
.event_code
);
4440 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4441 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4442 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4443 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4445 hr
= IPin_EndOfStream(pin
);
4446 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4448 hr
= IPin_BeginFlush(pin
);
4449 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4450 hr
= IPin_EndFlush(pin
);
4451 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4452 hr
= IPin_BeginFlush(pin
);
4453 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4454 hr
= IPin_EndFlush(pin
);
4455 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4457 hr
= IPin_EndOfStream(pin
);
4458 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4460 graph
.got_notify
= 0;
4461 graph
.event_code
= 0xcc;
4463 hr
= IPin_EndOfStream(pin2
);
4464 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4466 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
4467 ok(graph
.event_code
== EC_COMPLETE
, "Got event code %ld.\n", graph
.event_code
);
4469 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4470 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4472 IFilterGraph2_Disconnect(&graph
.IFilterGraph2_iface
, pin
);
4473 IFilterGraph2_Disconnect(&graph
.IFilterGraph2_iface
, &source
.source
.pin
.IPin_iface
);
4474 IFilterGraph2_Disconnect(&graph
.IFilterGraph2_iface
, pin2
);
4475 IFilterGraph2_Disconnect(&graph
.IFilterGraph2_iface
, &source2
.source
.pin
.IPin_iface
);
4477 ref
= IAudioStreamSample_Release(stream_sample
);
4478 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4479 ref
= IAudioData_Release(audio_data
);
4480 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4481 ref
= IAMMultiMediaStream_Release(mmstream
);
4482 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4483 graph_destroy(&graph
);
4484 ref
= IMediaStreamFilter_Release(filter
);
4485 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4487 IAudioMediaStream_Release(audio_stream
);
4488 ref
= IMediaStream_Release(stream
);
4489 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4491 ref
= IAMMediaStream_Release(stream2
);
4492 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4495 static IMediaSample
*ammediastream_allocate_sample(struct testfilter
*source
, const BYTE
*input_data
, DWORD input_length
)
4497 IMediaSample
*sample
;
4501 hr
= IMemAllocator_GetBuffer(source
->source
.pAllocator
, &sample
, NULL
, NULL
, 0);
4502 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4504 hr
= IMediaSample_GetPointer(sample
, &sample_data
);
4505 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4507 hr
= IMediaSample_SetActualDataLength(sample
, input_length
);
4508 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4510 memcpy(sample_data
, input_data
, input_length
);
4515 static void test_audiostream_new_segment(void)
4517 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
4518 static const BYTE test_data
[8] = { 0 };
4519 IAudioStreamSample
*stream_sample
;
4520 IAudioMediaStream
*audio_stream
;
4521 IMemInputPin
*mem_input_pin
;
4522 IMediaSample
*media_sample
;
4523 struct testfilter source
;
4524 IAudioData
*audio_data
;
4525 STREAM_TIME start_time
;
4526 STREAM_TIME end_time
;
4527 IGraphBuilder
*graph
;
4528 IMediaStream
*stream
;
4533 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
4534 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4535 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
4536 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4537 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
4538 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4539 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
4540 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4541 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
4542 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4543 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
4544 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4545 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
4546 testfilter_init(&source
);
4547 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
4548 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4549 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
4550 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4551 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &stream_sample
);
4552 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4553 hr
= IAudioData_SetBuffer(audio_data
, 5, NULL
, 0);
4554 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4556 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
4557 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4558 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4559 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4561 hr
= IPin_NewSegment(pin
, 11111111, 22222222, 1.0);
4562 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4564 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 5);
4565 start_time
= 12345678;
4566 end_time
= 23456789;
4567 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
4568 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4569 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
4570 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4571 IMediaSample_Release(media_sample
);
4573 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4574 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4576 start_time
= 0xdeadbeefdeadbeef;
4577 end_time
= 0xdeadbeefdeadbeef;
4578 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
4579 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4580 ok(start_time
== 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
4581 ok(end_time
== 23459057, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
4583 hr
= IPin_NewSegment(pin
, 11111111, 22222222, 2.0);
4584 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4586 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 5);
4587 start_time
= 12345678;
4588 end_time
= 23456789;
4589 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
4590 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4591 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
4592 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4593 IMediaSample_Release(media_sample
);
4595 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4596 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4598 start_time
= 0xdeadbeefdeadbeef;
4599 end_time
= 0xdeadbeefdeadbeef;
4600 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
4601 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4602 ok(start_time
== 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
4603 ok(end_time
== 23459057, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
4605 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4606 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4607 IGraphBuilder_Disconnect(graph
, pin
);
4608 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
4610 ref
= IAudioStreamSample_Release(stream_sample
);
4611 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4612 ref
= IAudioData_Release(audio_data
);
4613 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4614 ref
= IAMMultiMediaStream_Release(mmstream
);
4615 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4616 ref
= IGraphBuilder_Release(graph
);
4617 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4619 IMemInputPin_Release(mem_input_pin
);
4620 IAudioMediaStream_Release(audio_stream
);
4621 ref
= IMediaStream_Release(stream
);
4622 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4625 static void CALLBACK
apc_func(ULONG_PTR param
)
4629 static IPin
*ammediastream_pin
;
4630 static IMemInputPin
*ammediastream_mem_input_pin
;
4631 static IMediaSample
*ammediastream_media_sample
;
4632 static DWORD ammediastream_sleep_time
;
4633 static HRESULT ammediastream_expected_hr
;
4635 static DWORD CALLBACK
ammediastream_end_of_stream(void *param
)
4639 Sleep(ammediastream_sleep_time
);
4640 hr
= IPin_EndOfStream(ammediastream_pin
);
4641 ok(hr
== ammediastream_expected_hr
, "Got hr %#lx.\n", hr
);
4646 static DWORD CALLBACK
ammediastream_receive(void *param
)
4650 Sleep(ammediastream_sleep_time
);
4651 hr
= IMemInputPin_Receive(ammediastream_mem_input_pin
, ammediastream_media_sample
);
4652 ok(hr
== ammediastream_expected_hr
, "Got hr %#lx.\n", hr
);
4657 struct ammediastream_receive_release_param
4659 IMemInputPin
*mem_input_pin
;
4660 IMediaSample
*media_sample
;
4663 static DWORD CALLBACK
ammediastream_receive_release(void *p
)
4665 struct ammediastream_receive_release_param
*param
= (struct ammediastream_receive_release_param
*)p
;
4669 hr
= IMemInputPin_Receive(param
->mem_input_pin
, param
->media_sample
);
4670 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4672 ref
= IMediaSample_Release(param
->media_sample
);
4673 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4680 static HANDLE
ammediastream_async_receive_time(struct testfilter
*source
,
4681 REFERENCE_TIME start_time
, REFERENCE_TIME end_time
, const BYTE
*input_data
, DWORD input_length
)
4683 struct ammediastream_receive_release_param
*param
;
4684 IMediaSample
*sample
;
4687 sample
= ammediastream_allocate_sample(source
, input_data
, input_length
);
4688 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
4689 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4691 param
= calloc(1, sizeof(*param
));
4692 param
->mem_input_pin
= source
->source
.pMemInputPin
;
4693 param
->media_sample
= sample
;
4694 return CreateThread(NULL
, 0, ammediastream_receive_release
, param
, 0, NULL
);
4697 static IStreamSample
*streamsample_sample
;
4698 static DWORD streamsample_flags
;
4699 static DWORD streamsample_timeout
;
4700 static HRESULT streamsample_expected_hr
;
4702 static DWORD CALLBACK
streamsample_completion_status(void *param
)
4706 hr
= IStreamSample_CompletionStatus(streamsample_sample
, streamsample_flags
, streamsample_timeout
);
4707 ok(hr
== streamsample_expected_hr
, "Got hr %#lx.\n", hr
);
4712 static void test_audiostreamsample_update(void)
4714 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
4715 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
4716 IAudioStreamSample
*stream_sample
;
4717 IAudioMediaStream
*audio_stream
;
4718 IMediaControl
*media_control
;
4719 IMemInputPin
*mem_input_pin
;
4720 IMediaSample
*media_sample1
;
4721 IMediaSample
*media_sample2
;
4722 struct testfilter source
;
4723 IAudioData
*audio_data
;
4724 IGraphBuilder
*graph
;
4725 IMediaStream
*stream
;
4726 DWORD actual_length
;
4734 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
4735 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4736 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
4737 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4738 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
4739 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4740 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
4741 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4742 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
4743 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4744 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
4745 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4746 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
4747 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaControl
, (void **)&media_control
);
4748 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4749 testfilter_init(&source
);
4750 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
4751 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4752 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
4753 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4754 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &stream_sample
);
4755 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4756 event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
4757 ok(event
!= NULL
, "Expected non-NULL event.");
4759 hr
= IAudioStreamSample_Update(stream_sample
, 0, event
, apc_func
, 0);
4760 ok(hr
== MS_E_NOTINIT
, "Got hr %#lx.\n", hr
);
4762 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4763 ok(hr
== MS_E_NOTINIT
, "Got hr %#lx.\n", hr
);
4765 hr
= IAudioData_SetBuffer(audio_data
, sizeof(buffer
), buffer
, 0);
4766 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4768 hr
= IAudioStreamSample_Update(stream_sample
, 0, event
, apc_func
, 0);
4769 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
4771 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4772 ok(hr
== MS_E_NOTRUNNING
, "Got hr %#lx.\n", hr
);
4774 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4775 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4777 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4778 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
4780 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4781 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4782 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
4783 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4784 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4785 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4787 media_sample1
= ammediastream_allocate_sample(&source
, test_data
, 8);
4788 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample1
);
4789 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4790 ref
= get_refcount(media_sample1
);
4791 ok(ref
== 2, "Got unexpected refcount %ld.\n", ref
);
4793 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4794 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4796 hr
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_length
);
4797 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4798 ok(actual_length
== 6, "Got actual length %lu.\n", actual_length
);
4800 ok(memcmp(buffer
, test_data
, 6) == 0, "Sample data didn't match.\n");
4802 ref
= get_refcount(media_sample1
);
4803 ok(ref
== 2, "Got unexpected refcount %ld.\n", ref
);
4805 media_sample2
= ammediastream_allocate_sample(&source
, test_data
, 8);
4806 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample2
);
4807 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4808 ref
= get_refcount(media_sample2
);
4809 ok(ref
== 2, "Got unexpected refcount %ld.\n", ref
);
4811 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4812 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4814 hr
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_length
);
4815 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4816 ok(actual_length
== 6, "Got actual length %lu.\n", actual_length
);
4818 ok(memcmp(buffer
, &test_data
[6], 2) == 0, "Sample data didn't match.\n");
4819 ok(memcmp(&buffer
[2], test_data
, 4) == 0, "Sample data didn't match.\n");
4821 ref
= IMediaSample_Release(media_sample1
);
4822 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4824 hr
= IPin_EndOfStream(pin
);
4825 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4827 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4828 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4830 hr
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_length
);
4831 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4832 ok(actual_length
== 4, "Got actual length %lu.\n", actual_length
);
4834 ok(memcmp(buffer
, &test_data
[4], 4) == 0, "Sample data didn't match.\n");
4836 ref
= IMediaSample_Release(media_sample2
);
4837 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4839 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4840 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
4842 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4843 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4844 hr
= IMediaControl_Pause(media_control
);
4845 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4847 media_sample1
= ammediastream_allocate_sample(&source
, test_data
, 6);
4848 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample1
);
4849 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4850 ref
= IMediaSample_Release(media_sample1
);
4851 ok(ref
== 1, "Got outstanding refcount %ld.\n", ref
);
4853 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4854 ok(hr
== MS_E_NOTRUNNING
, "Got hr %#lx.\n", hr
);
4856 hr
= IMediaControl_Stop(media_control
);
4857 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4858 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4859 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4861 media_sample1
= ammediastream_allocate_sample(&source
, test_data
, 6);
4863 ammediastream_mem_input_pin
= mem_input_pin
;
4864 ammediastream_media_sample
= media_sample1
;
4865 ammediastream_sleep_time
= 100;
4866 ammediastream_expected_hr
= S_OK
;
4867 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
4869 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4870 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4872 hr
= IAudioData_GetInfo(audio_data
, NULL
, NULL
, &actual_length
);
4873 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4874 ok(actual_length
== 6, "Got actual length %lu.\n", actual_length
);
4876 ok(memcmp(buffer
, test_data
, 6) == 0, "Sample data didn't match.\n");
4878 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
4879 CloseHandle(thread
);
4881 ref
= IMediaSample_Release(media_sample1
);
4882 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4884 ammediastream_pin
= pin
;
4885 ammediastream_sleep_time
= 100;
4886 ammediastream_expected_hr
= S_OK
;
4887 thread
= CreateThread(NULL
, 0, ammediastream_end_of_stream
, NULL
, 0, NULL
);
4889 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4890 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
4892 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
4893 CloseHandle(thread
);
4895 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4896 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4897 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4898 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4900 hr
= IAudioStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4901 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
4903 IAudioStreamSample_AddRef(stream_sample
);
4904 ref
= IAudioStreamSample_Release(stream_sample
);
4905 ok(ref
== 1, "Got outstanding refcount %ld.\n", ref
);
4907 hr
= IAudioStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4908 ok(hr
== MS_E_BUSY
, "Got hr %#lx.\n", hr
);
4910 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4911 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4912 IGraphBuilder_Disconnect(graph
, pin
);
4913 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
4914 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4915 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4917 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
4918 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
4920 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
4923 ref
= IAudioStreamSample_Release(stream_sample
);
4924 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4925 ref
= IAudioData_Release(audio_data
);
4926 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4927 ref
= IAMMultiMediaStream_Release(mmstream
);
4928 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4929 IMediaControl_Release(media_control
);
4930 ref
= IGraphBuilder_Release(graph
);
4931 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4933 IMemInputPin_Release(mem_input_pin
);
4934 IAudioMediaStream_Release(audio_stream
);
4935 ref
= IMediaStream_Release(stream
);
4936 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
4939 void test_audiostreamsample_completion_status(void)
4941 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
4942 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
4943 IAudioStreamSample
*stream_sample1
;
4944 IAudioStreamSample
*stream_sample2
;
4945 IAudioMediaStream
*audio_stream
;
4946 IMediaSample
*media_sample
;
4947 struct testfilter source
;
4948 IAudioData
*audio_data1
;
4949 IAudioData
*audio_data2
;
4950 IGraphBuilder
*graph
;
4951 IMediaStream
*stream
;
4957 event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
4958 ok(event
!= NULL
, "Expected non-NULL event.");
4960 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
4961 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4962 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
4963 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4964 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
4965 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4966 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
4967 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4968 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
4969 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4970 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
4971 testfilter_init(&source
);
4972 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
4973 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4974 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data1
);
4975 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4976 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data2
);
4977 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4978 hr
= IAudioData_SetBuffer(audio_data1
, 6, NULL
, 0);
4979 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4980 hr
= IAudioData_SetBuffer(audio_data2
, 6, NULL
, 0);
4981 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4982 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data1
, 0, &stream_sample1
);
4983 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4984 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data2
, 0, &stream_sample2
);
4985 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4987 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
4988 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4989 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
4990 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4992 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
4993 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
4995 hr
= IAudioStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
4996 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
4998 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
4999 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
5001 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 6);
5002 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
5003 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5004 ref
= IMediaSample_Release(media_sample
);
5005 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5007 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
5008 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5010 hr
= IAudioStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
5011 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
5013 hr
= IAudioStreamSample_Update(stream_sample2
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
5014 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
5016 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 12);
5017 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
5018 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5019 ref
= IMediaSample_Release(media_sample
);
5020 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5022 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
5023 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5025 hr
= IAudioStreamSample_CompletionStatus(stream_sample2
, 0, 0);
5026 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5028 hr
= IAudioStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
5029 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
5031 hr
= IPin_EndOfStream(pin
);
5032 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5034 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
5035 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
5037 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
5038 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5039 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
5040 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5042 hr
= IAudioStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
5043 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
5045 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
5046 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5048 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
5049 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
5051 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
5052 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5054 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 6);
5055 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
5056 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5057 ref
= IMediaSample_Release(media_sample
);
5058 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5060 hr
= IAudioStreamSample_CompletionStatus(stream_sample1
, 0, 0);
5061 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5063 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
5064 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5066 IGraphBuilder_Disconnect(graph
, pin
);
5067 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
5069 ref
= IAudioStreamSample_Release(stream_sample1
);
5070 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5071 ref
= IAudioStreamSample_Release(stream_sample2
);
5072 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5073 ref
= IAudioData_Release(audio_data1
);
5074 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5075 ref
= IAudioData_Release(audio_data2
);
5076 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5077 ref
= IAMMultiMediaStream_Release(mmstream
);
5078 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5079 ref
= IGraphBuilder_Release(graph
);
5080 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5082 IAudioMediaStream_Release(audio_stream
);
5083 ref
= IMediaStream_Release(stream
);
5084 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5089 static void test_audiostreamsample_get_sample_times(void)
5091 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5092 static const BYTE test_data
[8] = { 0 };
5093 IAudioStreamSample
*stream_sample
;
5094 IMediaFilter
*graph_media_filter
;
5095 IAudioMediaStream
*audio_stream
;
5096 STREAM_TIME filter_start_time
;
5097 IMemInputPin
*mem_input_pin
;
5098 IMediaStreamFilter
*filter
;
5099 IMediaSample
*media_sample
;
5100 struct testfilter source
;
5101 STREAM_TIME current_time
;
5102 struct testclock clock
;
5103 IAudioData
*audio_data
;
5104 STREAM_TIME start_time
;
5105 STREAM_TIME end_time
;
5106 IGraphBuilder
*graph
;
5107 IMediaStream
*stream
;
5112 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
5113 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5114 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
5115 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5116 ok(!!filter
, "Expected non-null filter.\n");
5117 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
5118 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5119 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
5120 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5121 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5122 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5123 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
5124 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5125 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
5126 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5127 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
5128 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&graph_media_filter
);
5129 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5130 testfilter_init(&source
);
5131 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
5132 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5133 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
5134 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5135 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &stream_sample
);
5136 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5137 hr
= IAudioData_SetBuffer(audio_data
, 5, NULL
, 0);
5138 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5139 testclock_init(&clock
);
5141 clock
.time
= 12345678;
5143 current_time
= 0xdeadbeefdeadbeef;
5144 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
5145 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5146 ok(current_time
== 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time
));
5148 hr
= IMediaFilter_SetSyncSource(graph_media_filter
, &clock
.IReferenceClock_iface
);
5149 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5151 current_time
= 0xdeadbeefdeadbeef;
5152 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
5153 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5154 ok(current_time
== 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time
));
5156 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &audio_mt
);
5157 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5158 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
5159 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5161 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &filter_start_time
);
5162 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5164 clock
.get_time_hr
= E_FAIL
;
5166 current_time
= 0xdeadbeefdeadbeef;
5167 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
5168 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5169 ok(current_time
== 0xdeadbeefddf15da1 + filter_start_time
, "Expected current time %s, got %s.\n",
5170 wine_dbgstr_longlong(0xdeadbeefddf15da1 + filter_start_time
), wine_dbgstr_longlong(current_time
));
5172 clock
.get_time_hr
= S_OK
;
5174 current_time
= 0xdeadbeefdeadbeef;
5175 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
5176 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5177 ok(current_time
== filter_start_time
, "Expected current time %s, got %s.\n",
5178 wine_dbgstr_longlong(filter_start_time
), wine_dbgstr_longlong(current_time
));
5180 clock
.time
= 23456789;
5182 current_time
= 0xdeadbeefdeadbeef;
5183 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
5184 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5185 ok(current_time
== filter_start_time
+ 11111111, "Expected current time %s, got %s.\n",
5186 wine_dbgstr_longlong(filter_start_time
+ 11111111), wine_dbgstr_longlong(current_time
));
5188 start_time
= 0xdeadbeefdeadbeef;
5189 end_time
= 0xdeadbeefdeadbeef;
5190 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
5191 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5192 ok(start_time
== 0, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
5193 ok(end_time
== 0, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
5195 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 8);
5196 start_time
= 12345678;
5197 end_time
= 23456789;
5198 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
5199 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5200 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
5201 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5202 IMediaSample_Release(media_sample
);
5204 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
5205 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5207 start_time
= 0xdeadbeefdeadbeef;
5208 end_time
= 0xdeadbeefdeadbeef;
5209 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
5210 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5211 ok(start_time
== 12345678, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
5212 ok(end_time
== 12347946, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
5214 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 6);
5215 start_time
= 12345678;
5216 end_time
= 23456789;
5217 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
5218 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5219 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
5220 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5221 IMediaSample_Release(media_sample
);
5223 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
5224 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5226 start_time
= 0xdeadbeefdeadbeef;
5227 end_time
= 0xdeadbeefdeadbeef;
5228 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
5229 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5230 ok(start_time
== 12347946, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
5231 ok(end_time
== 12346585, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
5233 hr
= IPin_EndOfStream(pin
);
5234 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5236 hr
= IAudioStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
5237 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5239 start_time
= 0xdeadbeefdeadbeef;
5240 end_time
= 0xdeadbeefdeadbeef;
5241 hr
= IAudioStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
5242 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5243 ok(start_time
== 12346585, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
5244 ok(end_time
== 12348399, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
5246 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
5247 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5248 IGraphBuilder_Disconnect(graph
, pin
);
5249 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
5251 ref
= IAudioStreamSample_Release(stream_sample
);
5252 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5253 ref
= IAudioData_Release(audio_data
);
5254 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5255 ref
= IAMMultiMediaStream_Release(mmstream
);
5256 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5257 IMediaFilter_Release(graph_media_filter
);
5258 ref
= IGraphBuilder_Release(graph
);
5259 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5260 ref
= IMediaStreamFilter_Release(filter
);
5261 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5263 IMemInputPin_Release(mem_input_pin
);
5264 IAudioMediaStream_Release(audio_stream
);
5265 ref
= IMediaStream_Release(stream
);
5266 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5269 static void test_ddrawstream_initialize(void)
5271 IDirectDrawMediaStream
*ddraw_stream
;
5272 IAMMediaStream
*stream
;
5273 IDirectDraw
*ddraw2
;
5280 hr
= DirectDrawCreate(NULL
, &ddraw
, NULL
);
5281 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5283 hr
= CoCreateInstance(&CLSID_AMDirectDrawStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream
);
5284 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5286 hr
= IAMMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5287 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5289 /* Crashes on native. */
5292 hr
= IAMMediaStream_Initialize(stream
, NULL
, 0, NULL
, STREAMTYPE_WRITE
);
5293 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
5296 hr
= IAMMediaStream_Initialize(stream
, NULL
, 0, &test_mspid
, STREAMTYPE_WRITE
);
5297 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5299 hr
= IAMMediaStream_GetInformation(stream
, &mspid
, &type
);
5300 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5301 ok(IsEqualGUID(&mspid
, &test_mspid
), "Got mspid %s.\n", wine_dbgstr_guid(&mspid
));
5302 ok(type
== STREAMTYPE_WRITE
, "Got type %u.\n", type
);
5304 hr
= IAMMediaStream_Initialize(stream
, (IUnknown
*)ddraw
, 0, &MSPID_PrimaryAudio
, STREAMTYPE_READ
);
5305 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5307 hr
= IAMMediaStream_GetInformation(stream
, &mspid
, &type
);
5308 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5309 ok(IsEqualGUID(&mspid
, &MSPID_PrimaryAudio
), "Got mspid %s.\n", wine_dbgstr_guid(&mspid
));
5310 ok(type
== STREAMTYPE_READ
, "Got type %u.\n", type
);
5312 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw2
);
5313 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5314 ok(ddraw2
== ddraw
, "Expected ddraw %p, got %p.\n", ddraw
, ddraw2
);
5316 IDirectDrawMediaStream_Release(ddraw_stream
);
5317 ref
= IAMMediaStream_Release(stream
);
5318 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5319 IDirectDraw_Release(ddraw2
);
5320 ref
= IDirectDraw_Release(ddraw
);
5321 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5324 #define check_ddrawstream_get_format(a,b,c) check_ddrawstream_get_format_(__LINE__,a,b,c)
5325 static void check_ddrawstream_get_format_(int line
, IDirectDrawMediaStream
*stream
,
5326 const AM_MEDIA_TYPE
*mt
, const DDSURFACEDESC
*expected_format
)
5328 DDSURFACEDESC current_format
;
5329 DDSURFACEDESC desired_format
;
5330 struct testfilter source
;
5331 FILTER_INFO filter_info
;
5332 DDSURFACEDESC format
;
5338 hr
= IDirectDrawMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5339 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5340 hr
= IPin_QueryPinInfo(pin
, &pin_info
);
5341 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5342 hr
= IBaseFilter_QueryFilterInfo(pin_info
.pFilter
, &filter_info
);
5343 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5345 testfilter_init(&source
);
5347 hr
= IFilterGraph_AddFilter(filter_info
.pGraph
, &source
.filter
.IBaseFilter_iface
, L
"source");
5348 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5350 hr
= IFilterGraph_ConnectDirect(filter_info
.pGraph
, &source
.source
.pin
.IPin_iface
, pin
, mt
);
5351 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5353 hr
= IDirectDrawMediaStream_GetFormat(stream
, NULL
, NULL
, NULL
, NULL
);
5354 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5356 memset(¤t_format
, 0xcc, sizeof(current_format
));
5357 current_format
.dwSize
= sizeof(current_format
);
5358 memset(&desired_format
, 0xcc, sizeof(desired_format
));
5359 desired_format
.dwSize
= sizeof(desired_format
);
5361 hr
= IDirectDrawMediaStream_GetFormat(stream
, ¤t_format
, NULL
, &desired_format
, &flags
);
5362 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5363 memset(&format
, 0xcc, sizeof(format
));
5364 format
.dwSize
= sizeof(format
);
5365 format
.ddpfPixelFormat
= expected_format
->ddpfPixelFormat
;
5366 format
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
5367 format
.dwWidth
= 333;
5368 format
.dwHeight
= 444;
5369 format
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
;
5370 ok_(__FILE__
, line
)(memcmp(¤t_format
, &format
, sizeof(DDSURFACEDESC
)) == 0, "Current format didn't match.\n");
5371 format
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
;
5372 ok_(__FILE__
, line
)(memcmp(&desired_format
, &format
, sizeof(DDSURFACEDESC
)) == 0, "Desired format didn't match.\n");
5374 hr
= IFilterGraph_Disconnect(filter_info
.pGraph
, &source
.source
.pin
.IPin_iface
);
5375 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5376 hr
= IFilterGraph_Disconnect(filter_info
.pGraph
, pin
);
5377 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5379 hr
= IFilterGraph_RemoveFilter(filter_info
.pGraph
, &source
.filter
.IBaseFilter_iface
);
5380 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5382 IFilterGraph_Release(filter_info
.pGraph
);
5383 IBaseFilter_Release(pin_info
.pFilter
);
5387 static void test_ddrawstream_get_format(void)
5389 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5390 IDirectDrawMediaStream
*ddraw_stream
;
5391 DDSURFACEDESC current_format
;
5392 DDSURFACEDESC desired_format
;
5393 IDirectDrawPalette
*palette
;
5394 IMediaStream
*stream
;
5395 VIDEOINFO video_info
;
5401 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5402 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5403 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5404 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5406 current_format
.dwSize
= sizeof(current_format
);
5407 desired_format
.dwSize
= sizeof(desired_format
);
5408 hr
= IDirectDrawMediaStream_GetFormat(ddraw_stream
, ¤t_format
, &palette
, &desired_format
, &flags
);
5409 ok(hr
== MS_E_NOSTREAM
, "Got hr %#lx.\n", hr
);
5411 video_info
= rgb32_video_info
;
5412 video_info
.rcSource
.right
= 222;
5413 video_info
.rcSource
.bottom
= 333;
5414 video_info
.rcTarget
.right
= 444;
5415 video_info
.rcTarget
.bottom
= 666;
5417 mt
.pbFormat
= (BYTE
*)&video_info
;
5418 check_ddrawstream_get_format(ddraw_stream
, &mt
, &rgb32_format
);
5420 video_info
= rgb32_video_info
;
5421 video_info
.bmiHeader
.biHeight
= 444;
5423 mt
.pbFormat
= (BYTE
*)&video_info
;
5424 check_ddrawstream_get_format(ddraw_stream
, &mt
, &rgb32_format
);
5426 check_ddrawstream_get_format(ddraw_stream
, &rgb8_mt
, &rgb8_format
);
5427 check_ddrawstream_get_format(ddraw_stream
, &rgb555_mt
, &rgb555_format
);
5428 check_ddrawstream_get_format(ddraw_stream
, &rgb565_mt
, &rgb565_format
);
5429 check_ddrawstream_get_format(ddraw_stream
, &rgb24_mt
, &rgb24_format
);
5430 check_ddrawstream_get_format(ddraw_stream
, &rgb32_mt
, &rgb32_format
);
5432 current_format
.dwSize
= sizeof(current_format
);
5433 desired_format
.dwSize
= sizeof(desired_format
);
5434 hr
= IDirectDrawMediaStream_GetFormat(ddraw_stream
, ¤t_format
, &palette
, &desired_format
, &flags
);
5435 ok(hr
== MS_E_NOSTREAM
, "Got hr %#lx.\n", hr
);
5437 ref
= IAMMultiMediaStream_Release(mmstream
);
5438 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5439 IDirectDrawMediaStream_Release(ddraw_stream
);
5440 ref
= IMediaStream_Release(stream
);
5441 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5444 #define check_ddrawstream_set_format(a,b,c,d) check_ddrawstream_set_format_(__LINE__,a,b,c,d)
5445 static void check_ddrawstream_set_format_(int line
, IDirectDrawMediaStream
*stream
,
5446 const DDSURFACEDESC
*format
, const AM_MEDIA_TYPE
*mt
, HRESULT expected_hr
)
5448 struct testfilter source
;
5449 FILTER_INFO filter_info
;
5454 hr
= IDirectDrawMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5455 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5456 hr
= IPin_QueryPinInfo(pin
, &pin_info
);
5457 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5458 hr
= IBaseFilter_QueryFilterInfo(pin_info
.pFilter
, &filter_info
);
5459 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5461 testfilter_init(&source
);
5463 hr
= IFilterGraph_AddFilter(filter_info
.pGraph
, &source
.filter
.IBaseFilter_iface
, L
"source");
5464 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5466 hr
= IDirectDrawMediaStream_SetFormat(stream
, format
, NULL
);
5467 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#lx.\n", hr
);
5471 DDSURFACEDESC current_format
;
5472 DDSURFACEDESC desired_format
;
5475 hr
= IFilterGraph_ConnectDirect(filter_info
.pGraph
, &source
.source
.pin
.IPin_iface
, pin
, mt
);
5476 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5478 memset(¤t_format
, 0xcc, sizeof(current_format
));
5479 memset(&desired_format
, 0xcc, sizeof(desired_format
));
5481 current_format
.dwSize
= sizeof(current_format
);
5482 desired_format
.dwSize
= sizeof(desired_format
);
5483 hr
= IDirectDrawMediaStream_GetFormat(stream
, ¤t_format
, NULL
, &desired_format
, &flags
);
5484 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5485 if (format
->dwFlags
& DDSD_PIXELFORMAT
)
5487 ok_(__FILE__
, line
)(current_format
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
| DDSD_PIXELFORMAT
),
5488 "Got current format flags %#lx.\n", current_format
.dwFlags
);
5489 ok_(__FILE__
, line
)(memcmp(¤t_format
.ddpfPixelFormat
, &format
->ddpfPixelFormat
, sizeof(DDPIXELFORMAT
)) == 0,
5490 "Current pixel format didn't match.\n");
5491 ok_(__FILE__
, line
)(memcmp(&desired_format
.ddpfPixelFormat
, &format
->ddpfPixelFormat
, sizeof(DDPIXELFORMAT
)) == 0,
5492 "Desired pixel format didn't match.\n");
5496 ok_(__FILE__
, line
)(current_format
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
),
5497 "Got flags %#lx.\n", current_format
.dwFlags
);
5499 ok_(__FILE__
, line
)(desired_format
.dwFlags
== (DDSD_WIDTH
| DDSD_HEIGHT
),
5500 "Got desired format flags %#lx.\n", desired_format
.dwFlags
);
5501 ok_(__FILE__
, line
)(current_format
.ddsCaps
.dwCaps
== (DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
),
5502 "Got current format caps %#lx.\n", current_format
.ddsCaps
.dwCaps
);
5503 ok_(__FILE__
, line
)(desired_format
.ddsCaps
.dwCaps
== (DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_SYSTEMMEMORY
),
5504 "Got desired format caps %#lx.\n", desired_format
.ddsCaps
.dwCaps
);
5505 ok_(__FILE__
, line
)(flags
== 0, "Got flags %#lx.\n", flags
);
5507 hr
= IFilterGraph_Disconnect(filter_info
.pGraph
, &source
.source
.pin
.IPin_iface
);
5508 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5509 hr
= IFilterGraph_Disconnect(filter_info
.pGraph
, pin
);
5510 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5513 hr
= IFilterGraph_RemoveFilter(filter_info
.pGraph
, &source
.filter
.IBaseFilter_iface
);
5514 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5516 IFilterGraph_Release(filter_info
.pGraph
);
5517 IBaseFilter_Release(pin_info
.pFilter
);
5521 static void test_ddrawstream_set_format(void)
5523 static const DDSURFACEDESC rgb1_format
=
5525 .dwSize
= sizeof(DDSURFACEDESC
),
5526 .dwFlags
= DDSD_PIXELFORMAT
,
5527 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
5528 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED1
,
5529 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 1,
5531 static const DDSURFACEDESC rgb2_format
=
5533 .dwSize
= sizeof(DDSURFACEDESC
),
5534 .dwFlags
= DDSD_PIXELFORMAT
,
5535 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
5536 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED2
,
5537 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 2,
5539 static const DDSURFACEDESC rgb4_format
=
5541 .dwSize
= sizeof(DDSURFACEDESC
),
5542 .dwFlags
= DDSD_PIXELFORMAT
,
5543 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
5544 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED4
,
5545 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 4,
5547 static const DDSURFACEDESC rgb4to8_format
=
5549 .dwSize
= sizeof(DDSURFACEDESC
),
5550 .dwFlags
= DDSD_PIXELFORMAT
,
5551 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
5552 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXEDTO8
,
5553 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 4,
5555 static const DDSURFACEDESC rgb332_format
=
5557 .dwSize
= sizeof(DDSURFACEDESC
),
5558 .dwFlags
= DDSD_PIXELFORMAT
,
5559 .ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
),
5560 .ddpfPixelFormat
.dwFlags
= DDPF_RGB
,
5561 .ddpfPixelFormat
.u1
.dwRGBBitCount
= 8,
5562 .ddpfPixelFormat
.u2
.dwRBitMask
= 0xe0,
5563 .ddpfPixelFormat
.u3
.dwGBitMask
= 0x1c,
5564 .ddpfPixelFormat
.u4
.dwBBitMask
= 0x03,
5567 IDirectDrawMediaStream
*ddraw_stream
;
5568 IAMMultiMediaStream
*mmstream
;
5569 DDSURFACEDESC current_format
;
5570 DDSURFACEDESC desired_format
;
5571 struct testfilter source
;
5572 IGraphBuilder
*graph
;
5573 DDSURFACEDESC format
;
5574 IMediaStream
*stream
;
5575 VIDEOINFO video_info
;
5581 mmstream
= create_ammultimediastream();
5583 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5584 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5585 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5586 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5588 check_ddrawstream_set_format(ddraw_stream
, &rgb8_format
, &rgb8_mt
, S_OK
);
5589 check_ddrawstream_set_format(ddraw_stream
, &rgb555_format
, &rgb555_mt
, S_OK
);
5590 check_ddrawstream_set_format(ddraw_stream
, &rgb565_format
, &rgb565_mt
, S_OK
);
5591 check_ddrawstream_set_format(ddraw_stream
, &rgb24_format
, &rgb24_mt
, S_OK
);
5592 check_ddrawstream_set_format(ddraw_stream
, &rgb32_format
, &rgb32_mt
, S_OK
);
5593 check_ddrawstream_set_format(ddraw_stream
, &argb32_format
, &rgb32_mt
, S_OK
);
5594 check_ddrawstream_set_format(ddraw_stream
, &yuy2_format
, NULL
, S_OK
);
5595 check_ddrawstream_set_format(ddraw_stream
, &yv12_format
, NULL
, S_OK
);
5597 format
= rgb32_format
;
5598 format
.ddpfPixelFormat
.dwFlags
|= DDPF_ALPHAPIXELS
| DDPF_ALPHA
5599 | DDPF_COMPRESSED
| DDPF_RGBTOYUV
| DDPF_ZBUFFER
| DDPF_ZPIXELS
| DDPF_STENCILBUFFER
5600 | DDPF_ALPHAPREMULT
| DDPF_LUMINANCE
| DDPF_BUMPLUMINANCE
| DDPF_BUMPDUDV
;
5601 check_ddrawstream_set_format(ddraw_stream
, &format
, &rgb32_mt
, S_OK
);
5603 format
= yuy2_format
;
5604 format
.ddpfPixelFormat
.dwFlags
|= DDPF_ALPHAPIXELS
| DDPF_ALPHA
5605 | DDPF_PALETTEINDEXED4
| DDPF_PALETTEINDEXEDTO8
| DDPF_PALETTEINDEXED8
5606 | DDPF_RGB
| DDPF_COMPRESSED
| DDPF_RGBTOYUV
| DDPF_YUV
| DDPF_ZBUFFER
5607 | DDPF_PALETTEINDEXED1
| DDPF_PALETTEINDEXED2
| DDPF_ZPIXELS
5608 | DDPF_STENCILBUFFER
| DDPF_ALPHAPREMULT
| DDPF_LUMINANCE
5609 | DDPF_BUMPLUMINANCE
| DDPF_BUMPDUDV
;
5610 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, S_OK
);
5612 format
= rgb32_format
;
5613 format
.dwFlags
|= DDSD_CAPS
;
5614 format
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
5615 check_ddrawstream_set_format(ddraw_stream
, &format
, &rgb32_mt
, S_OK
);
5617 format
= rgb8_format
;
5619 check_ddrawstream_set_format(ddraw_stream
, &format
, &rgb32_mt
, S_OK
);
5621 check_ddrawstream_set_format(ddraw_stream
, &rgb1_format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5622 check_ddrawstream_set_format(ddraw_stream
, &rgb2_format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5623 check_ddrawstream_set_format(ddraw_stream
, &rgb4_format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5624 check_ddrawstream_set_format(ddraw_stream
, &rgb4to8_format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5625 check_ddrawstream_set_format(ddraw_stream
, &rgb332_format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5627 format
= rgb8_format
;
5628 format
.ddpfPixelFormat
.dwFlags
&= ~DDPF_RGB
;
5629 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5631 format
= rgb8_format
;
5632 format
.ddpfPixelFormat
.dwFlags
|= DDPF_PALETTEINDEXED1
;
5633 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5635 format
= rgb32_format
;
5636 format
.ddpfPixelFormat
.dwFlags
|= DDPF_PALETTEINDEXED8
;
5637 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5639 format
= rgb32_format
;
5640 format
.ddpfPixelFormat
.dwFlags
|= DDPF_YUV
;
5641 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5643 format
= rgb565_format
;
5644 format
.ddpfPixelFormat
.u2
.dwRBitMask
= 0x001f;
5645 format
.ddpfPixelFormat
.u3
.dwGBitMask
= 0x07e0;
5646 format
.ddpfPixelFormat
.u4
.dwBBitMask
= 0xf800;
5647 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5649 format
= rgb32_format
;
5650 format
.ddpfPixelFormat
.u2
.dwRBitMask
= 0x00ff00;
5651 format
.ddpfPixelFormat
.u3
.dwGBitMask
= 0x0000ff;
5652 format
.ddpfPixelFormat
.u4
.dwBBitMask
= 0xff0000;
5653 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5655 format
= yuy2_format
;
5656 format
.ddpfPixelFormat
.u1
.dwYUVBitCount
= 0;
5657 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, E_INVALIDARG
);
5659 format
= rgb32_format
;
5660 format
.dwSize
= sizeof(DDSURFACEDESC
) + 1;
5661 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, E_INVALIDARG
);
5663 format
= rgb32_format
;
5664 format
.ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
) + 1;
5665 check_ddrawstream_set_format(ddraw_stream
, &format
, NULL
, DDERR_INVALIDSURFACETYPE
);
5667 ref
= IAMMultiMediaStream_Release(mmstream
);
5668 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5669 IDirectDrawMediaStream_Release(ddraw_stream
);
5670 ref
= IMediaStream_Release(stream
);
5671 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5673 mmstream
= create_ammultimediastream();
5675 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5676 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5677 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5678 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5679 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5680 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5682 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
5683 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5684 ok(!!graph
, "Expected non-NULL graph.\n");
5686 testfilter_init(&source
);
5688 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, L
"source");
5689 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5691 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &rgb8_mt
);
5692 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5694 source
.preferred_mt
= NULL
;
5696 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb555_format
, NULL
);
5697 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got hr %#lx.\n", hr
);
5698 ok(IsEqualGUID(&source
.source
.pin
.mt
.subtype
, &MEDIASUBTYPE_RGB8
),
5699 "Got subtype %s.\n", wine_dbgstr_guid(&source
.source
.pin
.mt
.subtype
));
5700 hr
= IDirectDrawMediaStream_GetFormat(ddraw_stream
, ¤t_format
, NULL
, &desired_format
, NULL
);
5701 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5702 ok(current_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 8,
5703 "Got rgb bit count %lu.\n", current_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
5704 ok(desired_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 8,
5705 "Got rgb bit count %lu.\n", desired_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
5707 format
= rgb555_format
;
5709 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
5710 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5711 ok(IsEqualGUID(&source
.source
.pin
.mt
.subtype
, &MEDIASUBTYPE_RGB8
),
5712 "Got subtype %s.\n", wine_dbgstr_guid(&source
.source
.pin
.mt
.subtype
));
5714 source
.preferred_mt
= &rgb555_mt
;
5716 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb8_format
, NULL
);
5717 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5719 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &rgb555_format
, NULL
);
5720 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5721 ok(IsEqualGUID(&source
.source
.pin
.mt
.subtype
, &MEDIASUBTYPE_RGB555
),
5722 "Got subtype %s.\n", wine_dbgstr_guid(&source
.source
.pin
.mt
.subtype
));
5723 hr
= IDirectDrawMediaStream_GetFormat(ddraw_stream
, ¤t_format
, NULL
, &desired_format
, NULL
);
5724 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5725 ok(current_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 16,
5726 "Got rgb bit count %lu.\n", current_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
5727 ok(desired_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 16,
5728 "Got rgb bit count %lu.\n", desired_format
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
5730 video_info
= rgb555_video_info
;
5731 video_info
.bmiHeader
.biWidth
= 222;
5732 video_info
.bmiHeader
.biHeight
= -555;
5734 mt
.pbFormat
= (BYTE
*)&video_info
;
5735 source
.preferred_mt
= &mt
;
5737 format
= rgb555_format
;
5738 format
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
;
5739 format
.dwWidth
= 222;
5740 format
.dwHeight
= 555;
5741 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, &format
, NULL
);
5742 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5743 ok(IsEqualGUID(&source
.source
.pin
.mt
.subtype
, &MEDIASUBTYPE_RGB555
),
5744 "Got subtype %s.\n", wine_dbgstr_guid(&source
.source
.pin
.mt
.subtype
));
5745 ok(((VIDEOINFO
*)source
.source
.pin
.mt
.pbFormat
)->bmiHeader
.biWidth
== 222,
5746 "Got width %ld.\n", ((VIDEOINFO
*)source
.source
.pin
.mt
.pbFormat
)->bmiHeader
.biWidth
);
5747 ok(((VIDEOINFO
*)source
.source
.pin
.mt
.pbFormat
)->bmiHeader
.biHeight
== -555,
5748 "Got height %ld.\n", ((VIDEOINFO
*)source
.source
.pin
.mt
.pbFormat
)->bmiHeader
.biHeight
);
5750 hr
= IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
5751 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5752 hr
= IGraphBuilder_Disconnect(graph
, pin
);
5753 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5755 ref
= IAMMultiMediaStream_Release(mmstream
);
5756 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5757 ref
= IGraphBuilder_Release(graph
);
5758 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5760 IDirectDrawMediaStream_Release(ddraw_stream
);
5761 ref
= IMediaStream_Release(stream
);
5762 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5765 static void test_ddrawstream_receive(void)
5767 ALLOCATOR_PROPERTIES properties
=
5774 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5775 ALLOCATOR_PROPERTIES actual
;
5776 IMediaStreamFilter
*filter
;
5777 struct testfilter source
;
5778 IMemAllocator
*allocator
;
5779 IGraphBuilder
*graph
;
5780 IMediaStream
*stream
;
5781 IMediaSample
*sample
;
5787 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
5788 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5789 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
5790 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5791 ok(!!filter
, "Expected non-null filter.\n");
5792 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5793 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5794 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5795 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5796 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
5797 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5798 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
5799 testfilter_init(&source
);
5800 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
5801 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5802 hr
= CoCreateInstance(&CLSID_MemoryAllocator
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMemAllocator
, (void **)&allocator
);
5803 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5804 hr
= IMemAllocator_SetProperties(allocator
, &properties
, &actual
);
5805 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5806 hr
= IMemAllocator_Commit(allocator
);
5807 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5809 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &rgb32_mt
);
5810 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5812 hr
= IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
5813 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5814 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample
);
5815 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5816 ref
= IMediaSample_Release(sample
);
5817 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5819 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
5820 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5822 hr
= IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
5823 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5825 ammediastream_mem_input_pin
= source
.source
.pMemInputPin
;
5826 ammediastream_media_sample
= sample
;
5827 ammediastream_sleep_time
= 0;
5828 ammediastream_expected_hr
= S_OK
;
5829 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
5831 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
5833 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
5834 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5836 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
5837 CloseHandle(thread
);
5839 ref
= IMediaSample_Release(sample
);
5840 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5842 hr
= IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
5843 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5844 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, sample
);
5845 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5846 ref
= IMediaSample_Release(sample
);
5847 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5849 IGraphBuilder_Disconnect(graph
, pin
);
5850 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
5852 hr
= IMemAllocator_Decommit(allocator
);
5853 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5855 ref
= IAMMultiMediaStream_Release(mmstream
);
5856 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5857 ref
= IGraphBuilder_Release(graph
);
5858 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5859 ref
= IMediaStreamFilter_Release(filter
);
5860 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5862 ref
= IMediaStream_Release(stream
);
5863 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5864 ref
= IMemAllocator_Release(allocator
);
5865 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5868 static void test_ddrawstream_begin_flush_end_flush(void)
5870 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
5871 static const MSPID mspid
= {0x88888888, 1};
5872 IDirectDrawStreamSample
*stream_sample
;
5873 IDirectDrawMediaStream
*ddraw_stream
;
5874 IMediaStreamFilter
*filter
;
5875 IMediaSample
*media_sample
;
5876 IMediaFilter
*media_filter
;
5877 struct testfilter source2
;
5878 struct testfilter source
;
5879 IAMMediaStream
*stream2
;
5880 IMediaStream
*stream
;
5881 VIDEOINFO video_info
;
5891 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, (IGraphBuilder
*)&graph
.IFilterGraph2_iface
);
5892 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5893 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
5894 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5895 hr
= CoCreateInstance(&CLSID_AMDirectDrawStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream2
);
5896 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5897 hr
= IAMMediaStream_Initialize(stream2
, NULL
, 0, &mspid
, STREAMTYPE_READ
);
5898 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5899 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream2
, &mspid
, 0, NULL
);
5900 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5901 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
5902 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5903 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
5904 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5905 hr
= IAMMediaStream_QueryInterface(stream2
, &IID_IPin
, (void **)&pin2
);
5906 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5907 hr
= IFilterGraph2_QueryInterface(&graph
.IFilterGraph2_iface
, &IID_IMediaFilter
, (void **)&media_filter
);
5908 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5909 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
5910 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5911 testfilter_init(&source
);
5912 testfilter_init(&source2
);
5913 source
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
5914 hr
= IFilterGraph2_AddFilter(&graph
.IFilterGraph2_iface
, &source
.filter
.IBaseFilter_iface
, NULL
);
5915 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5916 hr
= IFilterGraph2_AddFilter(&graph
.IFilterGraph2_iface
, &source2
.filter
.IBaseFilter_iface
, NULL
);
5917 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5919 hr
= IMediaFilter_SetSyncSource(media_filter
, NULL
);
5920 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5922 video_info
= rgb32_video_info
;
5923 video_info
.bmiHeader
.biWidth
= 3;
5924 video_info
.bmiHeader
.biHeight
= 1;
5926 mt
.pbFormat
= (BYTE
*)&video_info
;
5927 hr
= IFilterGraph2_ConnectDirect(&graph
.IFilterGraph2_iface
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
5928 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5929 hr
= IFilterGraph2_ConnectDirect(&graph
.IFilterGraph2_iface
, &source2
.source
.pin
.IPin_iface
, pin2
, &mt
);
5930 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5932 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
5933 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5935 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample
);
5936 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5938 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
5939 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5941 hr
= IMemAllocator_GetBuffer(source
.source
.pAllocator
, &media_sample
, NULL
, NULL
, 0);
5942 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5944 ammediastream_mem_input_pin
= source
.source
.pMemInputPin
;
5945 ammediastream_media_sample
= media_sample
;
5946 ammediastream_sleep_time
= 0;
5947 ammediastream_expected_hr
= S_FALSE
;
5948 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
5950 hr
= IPin_BeginFlush(pin
);
5951 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5953 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
5954 CloseHandle(thread
);
5956 ref
= IMediaSample_Release(media_sample
);
5957 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5959 hr
= IMemAllocator_GetBuffer(source
.source
.pAllocator
, &media_sample
, NULL
, NULL
, 0);
5960 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5961 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
5962 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
5964 ref
= IMediaSample_Release(media_sample
);
5965 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5967 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
5968 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
5970 hr
= IPin_EndOfStream(pin
);
5971 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
5973 hr
= IPin_EndFlush(pin
);
5974 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5976 hr
= IMemAllocator_GetBuffer(source
.source
.pAllocator
, &media_sample
, NULL
, NULL
, 0);
5977 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5978 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
5979 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5980 ref
= IMediaSample_Release(media_sample
);
5981 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
5983 hr
= IPin_EndOfStream(pin
);
5984 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5986 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
5987 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5988 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
5989 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5991 hr
= IPin_BeginFlush(pin
);
5992 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5993 hr
= IPin_EndFlush(pin
);
5994 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5996 hr
= IPin_EndOfStream(pin
);
5997 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
5999 graph
.got_notify
= 0;
6001 hr
= IPin_EndOfStream(pin2
);
6002 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6004 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
6005 ok(graph
.event_code
== EC_COMPLETE
, "Got event code %ld.\n", graph
.event_code
);
6007 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
6008 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6009 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
6010 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6012 hr
= IPin_EndOfStream(pin
);
6013 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6015 hr
= IPin_BeginFlush(pin
);
6016 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6017 hr
= IPin_EndFlush(pin
);
6018 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6020 graph
.got_notify
= 0;
6021 graph
.event_code
= 0xcc;
6023 hr
= IPin_EndOfStream(pin2
);
6024 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6026 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
6028 hr
= IPin_EndOfStream(pin
);
6029 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6031 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
6032 ok(graph
.event_code
== EC_COMPLETE
, "Got event code %ld.\n", graph
.event_code
);
6034 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
6035 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6036 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
6037 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6039 hr
= IPin_EndOfStream(pin
);
6040 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6042 hr
= IPin_BeginFlush(pin
);
6043 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6044 hr
= IPin_EndFlush(pin
);
6045 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6046 hr
= IPin_BeginFlush(pin
);
6047 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6048 hr
= IPin_EndFlush(pin
);
6049 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6051 hr
= IPin_EndOfStream(pin
);
6052 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6054 graph
.got_notify
= 0;
6055 graph
.event_code
= 0xcc;
6057 hr
= IPin_EndOfStream(pin2
);
6058 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6060 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
6061 ok(graph
.event_code
== EC_COMPLETE
, "Got event code %ld.\n", graph
.event_code
);
6063 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
6064 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6066 IFilterGraph2_Disconnect(&graph
.IFilterGraph2_iface
, pin
);
6067 IFilterGraph2_Disconnect(&graph
.IFilterGraph2_iface
, &source
.source
.pin
.IPin_iface
);
6068 IFilterGraph2_Disconnect(&graph
.IFilterGraph2_iface
, pin2
);
6069 IFilterGraph2_Disconnect(&graph
.IFilterGraph2_iface
, &source2
.source
.pin
.IPin_iface
);
6071 ref
= IDirectDrawStreamSample_Release(stream_sample
);
6072 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6073 ref
= IAMMultiMediaStream_Release(mmstream
);
6074 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6075 IMediaFilter_Release(media_filter
);
6076 graph_destroy(&graph
);
6077 ref
= IMediaStreamFilter_Release(filter
);
6078 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6080 IDirectDrawMediaStream_Release(ddraw_stream
);
6081 ref
= IMediaStream_Release(stream
);
6082 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6084 ref
= IAMMediaStream_Release(stream2
);
6085 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6088 static void test_ddrawstream_new_segment(void)
6090 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
6091 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6092 IDirectDrawStreamSample
*stream_sample
;
6093 IDirectDrawMediaStream
*ddraw_stream
;
6094 IMemInputPin
*mem_input_pin
;
6095 IMediaSample
*media_sample
;
6096 IMediaFilter
*media_filter
;
6097 struct testfilter source
;
6098 STREAM_TIME start_time
;
6099 STREAM_TIME end_time
;
6100 IGraphBuilder
*graph
;
6101 IMediaStream
*stream
;
6102 VIDEOINFO video_info
;
6108 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6109 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6110 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
6111 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6112 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
6113 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6114 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
6115 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6116 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
6117 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6118 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
6119 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6120 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
6121 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
6122 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6123 testfilter_init(&source
);
6124 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
6125 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6127 hr
= IMediaFilter_SetSyncSource(media_filter
, NULL
);
6128 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6130 video_info
= rgb32_video_info
;
6131 video_info
.bmiHeader
.biWidth
= 3;
6132 video_info
.bmiHeader
.biHeight
= 1;
6134 mt
.pbFormat
= (BYTE
*)&video_info
;
6135 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
6136 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6138 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample
);
6139 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6141 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
6142 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6144 hr
= IPin_NewSegment(pin
, 11111111, 22222222, 1.0);
6145 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6147 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
6148 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
6150 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
6151 start_time
= 12345678;
6152 end_time
= 23456789;
6153 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
6154 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6155 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
6156 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6157 IMediaSample_Release(media_sample
);
6159 start_time
= 0xdeadbeefdeadbeef;
6160 end_time
= 0xdeadbeefdeadbeef;
6161 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
6162 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6163 ok(start_time
== 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
6164 ok(end_time
== 34567900, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
6166 hr
= IPin_NewSegment(pin
, 11111111, 22222222, 2.0);
6167 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6169 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
6170 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
6172 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
6173 start_time
= 12345678;
6174 end_time
= 23456789;
6175 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
6176 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6177 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
6178 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6179 IMediaSample_Release(media_sample
);
6181 start_time
= 0xdeadbeefdeadbeef;
6182 end_time
= 0xdeadbeefdeadbeef;
6183 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
6184 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6185 ok(start_time
== 23456789, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
6186 ok(end_time
== 34567900, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
6188 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
6189 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6190 IGraphBuilder_Disconnect(graph
, pin
);
6191 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
6193 ref
= IDirectDrawStreamSample_Release(stream_sample
);
6194 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6195 ref
= IAMMultiMediaStream_Release(mmstream
);
6196 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6197 IMediaFilter_Release(media_filter
);
6198 ref
= IGraphBuilder_Release(graph
);
6199 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6201 IMemInputPin_Release(mem_input_pin
);
6202 IDirectDrawMediaStream_Release(ddraw_stream
);
6203 ref
= IMediaStream_Release(stream
);
6204 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6207 static void test_ddrawstream_get_time_per_frame(void)
6209 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6210 IDirectDrawMediaStream
*ddraw_stream
;
6211 struct testfilter source
;
6212 STREAM_TIME frame_time
;
6213 IGraphBuilder
*graph
;
6214 IMediaStream
*stream
;
6215 VIDEOINFO video_info
;
6221 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6222 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6223 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
6224 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6225 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
6226 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6227 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
6228 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6229 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
6230 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6231 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
6232 testfilter_init(&source
);
6233 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
6234 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6236 hr
= IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream
, NULL
);
6237 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
6239 hr
= IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream
, &frame_time
);
6240 ok(hr
== MS_E_NOSTREAM
, "Got hr %#lx.\n", hr
);
6242 video_info
= rgb32_video_info
;
6243 video_info
.AvgTimePerFrame
= 12345678;
6245 mt
.pbFormat
= (BYTE
*)&video_info
;
6246 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
6247 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6249 frame_time
= 0xdeadbeefdeadbeef;
6250 hr
= IDirectDrawMediaStream_GetTimePerFrame(ddraw_stream
, &frame_time
);
6251 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6252 ok(frame_time
== 12345678, "Got frame time %s.\n", wine_dbgstr_longlong(frame_time
));
6254 ref
= IAMMultiMediaStream_Release(mmstream
);
6255 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6256 ref
= IGraphBuilder_Release(graph
);
6257 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6259 IDirectDrawMediaStream_Release(ddraw_stream
);
6260 ref
= IMediaStream_Release(stream
);
6261 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6264 static void check_ammediastream_join_am_multi_media_stream(const CLSID
*clsid
)
6266 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6267 IMultiMediaStream
*mmstream2
;
6268 IAMMediaStream
*stream
;
6273 hr
= CoCreateInstance(clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream
);
6274 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6276 mmstream_ref
= get_refcount(mmstream
);
6278 hr
= IAMMediaStream_JoinAMMultiMediaStream(stream
, mmstream
);
6279 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6281 ref
= get_refcount(mmstream
);
6282 ok(ref
== mmstream_ref
, "Expected outstanding refcount %ld, got %ld.\n", mmstream_ref
, ref
);
6284 hr
= IAMMediaStream_GetMultiMediaStream(stream
, &mmstream2
);
6285 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6286 ok(mmstream2
== (IMultiMediaStream
*)mmstream
, "Expected mmstream %p, got %p.\n", mmstream
, mmstream2
);
6288 IMultiMediaStream_Release(mmstream2
);
6290 hr
= IAMMediaStream_JoinAMMultiMediaStream(stream
, NULL
);
6291 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6293 hr
= IAMMediaStream_GetMultiMediaStream(stream
, &mmstream2
);
6294 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6295 ok(mmstream2
== NULL
, "Got mmstream %p.\n", mmstream2
);
6297 ref
= IAMMediaStream_Release(stream
);
6298 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6299 ref
= IAMMultiMediaStream_Release(mmstream
);
6300 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6303 static void test_ammediastream_join_am_multi_media_stream(void)
6305 check_ammediastream_join_am_multi_media_stream(&CLSID_AMAudioStream
);
6306 check_ammediastream_join_am_multi_media_stream(&CLSID_AMDirectDrawStream
);
6309 static void check_ammediastream_join_filter(const CLSID
*clsid
)
6311 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6312 IMediaStreamFilter
*filter
, *filter2
, *filter3
;
6313 IAMMediaStream
*stream
;
6317 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6318 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6319 ok(!!filter
, "Expected non-null filter.\n");
6320 EXPECT_REF(filter
, 3);
6322 hr
= CoCreateInstance(clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream
);
6323 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6324 EXPECT_REF(filter
, 3);
6326 hr
= CoCreateInstance(&CLSID_MediaStreamFilter
, NULL
, CLSCTX_INPROC_SERVER
,
6327 &IID_IMediaStreamFilter
, (void **)&filter2
);
6328 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6329 EXPECT_REF(filter
, 3);
6330 EXPECT_REF(filter2
, 1);
6332 hr
= IAMMediaStream_JoinFilter(stream
, filter2
);
6333 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6334 EXPECT_REF(filter
, 3);
6335 EXPECT_REF(filter2
, 1);
6337 /* Crashes on native. */
6340 hr
= IAMMediaStream_JoinFilter(stream
, NULL
);
6341 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6344 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter3
);
6345 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6346 ok(filter3
== filter
, "Expected filter %p, got %p.\n", filter
, filter3
);
6347 EXPECT_REF(filter
, 4);
6349 IMediaStreamFilter_Release(filter3
);
6350 EXPECT_REF(filter
, 3);
6352 ref
= IMediaStreamFilter_Release(filter2
);
6353 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6354 ref
= IAMMediaStream_Release(stream
);
6355 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6356 EXPECT_REF(filter
, 3);
6357 ref
= IAMMultiMediaStream_Release(mmstream
);
6358 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6359 EXPECT_REF(filter
, 1);
6360 ref
= IMediaStreamFilter_Release(filter
);
6361 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6364 static void test_ammediastream_join_filter(void)
6366 check_ammediastream_join_filter(&CLSID_AMAudioStream
);
6367 check_ammediastream_join_filter(&CLSID_AMDirectDrawStream
);
6370 static void check_ammediastream_join_filter_graph(const MSPID
*id
)
6372 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6373 IGraphBuilder
*builder
, *builder2
;
6374 IMediaStreamFilter
*filter
;
6375 IAMMediaStream
*stream
;
6376 IFilterGraph
*graph
;
6381 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6382 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6383 ok(!!filter
, "Expected non-null filter.\n");
6385 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, id
, 0, (IMediaStream
**)&stream
);
6386 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6388 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &builder
);
6389 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6390 ok(!!builder
, "Expected non-null graph.\n");
6391 EXPECT_REF(builder
, 4);
6393 hr
= IMediaStreamFilter_QueryFilterInfo(filter
, &info
);
6394 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6395 ok(info
.pGraph
== (IFilterGraph
*)builder
, "Expected graph %p, got %p.\n", (IFilterGraph
*)builder
, info
.pGraph
);
6396 EXPECT_REF(builder
, 5);
6397 IFilterGraph_Release(info
.pGraph
);
6398 EXPECT_REF(builder
, 4);
6400 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterGraph
, (void **)&graph
);
6401 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6402 EXPECT_REF(builder
, 4);
6403 EXPECT_REF(graph
, 1);
6405 /* Crashes on native. */
6408 hr
= IAMMediaStream_JoinFilterGraph(stream
, NULL
);
6409 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
6412 hr
= IAMMediaStream_JoinFilterGraph(stream
, graph
);
6413 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6414 EXPECT_REF(builder
, 4);
6415 EXPECT_REF(graph
, 1);
6417 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &builder2
);
6418 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6419 ok(builder2
== builder
, "Expected graph %p, got %p.\n", builder
, builder2
);
6420 EXPECT_REF(builder
, 5);
6421 EXPECT_REF(graph
, 1);
6422 IGraphBuilder_Release(builder2
);
6423 EXPECT_REF(builder
, 4);
6424 EXPECT_REF(graph
, 1);
6426 hr
= IMediaStreamFilter_QueryFilterInfo(filter
, &info
);
6427 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6428 ok(info
.pGraph
== (IFilterGraph
*)builder
, "Expected graph %p, got %p.\n", (IFilterGraph
*)builder
, info
.pGraph
);
6429 EXPECT_REF(builder
, 5);
6430 EXPECT_REF(graph
, 1);
6431 IFilterGraph_Release(info
.pGraph
);
6432 EXPECT_REF(builder
, 4);
6433 EXPECT_REF(graph
, 1);
6435 ref
= IFilterGraph_Release(graph
);
6436 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6437 ref
= IAMMultiMediaStream_Release(mmstream
);
6438 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6439 ref
= IGraphBuilder_Release(builder
);
6440 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6441 ref
= IMediaStreamFilter_Release(filter
);
6442 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6443 ref
= IAMMediaStream_Release(stream
);
6444 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6447 static void test_ammediastream_join_filter_graph(void)
6449 check_ammediastream_join_filter_graph(&MSPID_PrimaryAudio
);
6450 check_ammediastream_join_filter_graph(&MSPID_PrimaryVideo
);
6453 static void check_ammediastream_set_state(const MSPID
*id
)
6455 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6456 IAMMediaStream
*am_stream
;
6457 IMediaStream
*stream
;
6461 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6462 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6463 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, id
, 0, &stream
);
6464 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6465 hr
= IMediaStream_QueryInterface(stream
, &IID_IAMMediaStream
, (void **)&am_stream
);
6466 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6468 hr
= IAMMediaStream_SetState(am_stream
, 4);
6469 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6471 hr
= IAMMediaStream_SetState(am_stream
, State_Running
);
6472 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6474 hr
= IAMMediaStream_SetState(am_stream
, State_Paused
);
6475 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6477 hr
= IAMMediaStream_SetState(am_stream
, State_Stopped
);
6478 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6480 ref
= IAMMultiMediaStream_Release(mmstream
);
6481 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6482 IAMMediaStream_Release(am_stream
);
6483 ref
= IMediaStream_Release(stream
);
6484 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6487 static void test_ammediastream_set_state(void)
6489 check_ammediastream_set_state(&MSPID_PrimaryAudio
);
6490 check_ammediastream_set_state(&MSPID_PrimaryVideo
);
6493 static void check_ammediastream_end_of_stream(const CLSID
*clsid
, const MSPID
*id
, const AM_MEDIA_TYPE
*mt
)
6495 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6496 IMediaStreamFilter
*filter
;
6497 struct testfilter source
;
6498 IMediaStream
*stream
;
6506 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, (IGraphBuilder
*)&graph
.IFilterGraph2_iface
);
6507 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6508 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, id
, 0, &stream
);
6509 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6510 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
6511 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6512 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6513 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6514 testfilter_init(&source
);
6515 source
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6516 hr
= IFilterGraph2_AddFilter(&graph
.IFilterGraph2_iface
, &source
.filter
.IBaseFilter_iface
, NULL
);
6517 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6519 hr
= IFilterGraph2_ConnectDirect(&graph
.IFilterGraph2_iface
, &source
.source
.pin
.IPin_iface
, pin
, mt
);
6520 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6522 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6523 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6525 hr
= IPin_EndOfStream(pin
);
6526 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6528 hr
= IPin_EndOfStream(pin
);
6529 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
6531 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
6532 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6534 hr
= IPin_EndOfStream(pin
);
6535 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6537 hr
= IPin_EndOfStream(pin
);
6538 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
6540 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
6541 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6543 hr
= IPin_EndOfStream(pin
);
6544 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
6546 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
6547 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6549 graph
.got_notify
= 0;
6550 graph
.event_code
= 0xcc;
6552 hr
= IPin_EndOfStream(pin
);
6553 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6555 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
6556 ok(graph
.event_code
== EC_COMPLETE
, "Got event code %ld.\n", graph
.event_code
);
6558 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
6559 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6561 IFilterGraph2_Disconnect(&graph
.IFilterGraph2_iface
, pin
);
6562 IFilterGraph2_Disconnect(&graph
.IFilterGraph2_iface
, &source
.source
.pin
.IPin_iface
);
6564 ref
= IAMMultiMediaStream_Release(mmstream
);
6565 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6566 graph_destroy(&graph
);
6567 ref
= IMediaStreamFilter_Release(filter
);
6568 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6570 ref
= IMediaStream_Release(stream
);
6571 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6574 static void test_ammediastream_end_of_stream(void)
6576 check_ammediastream_end_of_stream(&CLSID_AMAudioStream
, &MSPID_PrimaryAudio
, &audio_mt
);
6577 check_ammediastream_end_of_stream(&CLSID_AMDirectDrawStream
, &MSPID_PrimaryVideo
, &rgb32_mt
);
6580 void test_mediastreamfilter_get_state(void)
6582 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6583 IMediaStreamFilter
*filter
;
6588 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6589 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6590 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6591 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6592 ok(!!filter
, "Expected non-null filter.\n");
6594 /* Crashes on native. */
6597 hr
= IMediaStreamFilter_GetState(filter
, 0, NULL
);
6598 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
6602 hr
= IMediaStreamFilter_GetState(filter
, 0, &state
);
6603 ok(state
== State_Stopped
, "Got state %#x.\n", state
);
6605 ref
= IAMMultiMediaStream_Release(mmstream
);
6606 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6607 ref
= IMediaStreamFilter_Release(filter
);
6608 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6611 void check_mediastreamfilter_state(FILTER_STATE expected_state
, HRESULT (*set_state
)(IMediaStreamFilter
*),
6612 HRESULT (*reset_state
)(IMediaStreamFilter
*))
6614 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6615 struct teststream teststream
, teststream2
;
6616 IMediaStreamFilter
*filter
;
6621 teststream_init(&teststream
);
6622 teststream_init(&teststream2
);
6624 teststream2
.mspid
.Data2
= 1;
6626 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6627 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6628 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)&teststream
, &teststream
.mspid
, 0, NULL
);
6629 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6630 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)&teststream2
, &teststream2
.mspid
, 0, NULL
);
6631 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6632 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6633 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6634 ok(filter
!= NULL
, "Expected non-null filter\n");
6636 hr
= reset_state(filter
);
6637 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6639 teststream
.state
= 0xcc;
6640 teststream2
.state
= 0xcc;
6641 hr
= set_state(filter
);
6642 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6643 ok(teststream
.state
== expected_state
, "Got state %#x.\n", teststream
.state
);
6644 ok(teststream2
.state
== expected_state
, "Got state %#x.\n", teststream2
.state
);
6645 hr
= IMediaStreamFilter_GetState(filter
, 0, &state
);
6646 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6647 ok(state
== expected_state
, "Got state %#x.\n", state
);
6649 teststream
.state
= 0xcc;
6650 teststream2
.state
= 0xcc;
6651 hr
= set_state(filter
);
6652 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6653 ok(teststream
.state
== 0xcc, "Got state %#x.\n", teststream
.state
);
6654 ok(teststream2
.state
== 0xcc, "Got state %#x.\n", teststream2
.state
);
6656 hr
= reset_state(filter
);
6657 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6659 teststream
.set_state_result
= E_FAIL
;
6660 teststream
.state
= 0xcc;
6661 teststream2
.state
= 0xcc;
6662 hr
= set_state(filter
);
6663 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6664 ok(teststream
.state
== 0xcc, "Got state %#x.\n", teststream
.state
);
6665 ok(teststream2
.state
== expected_state
, "Got state %#x.\n", teststream2
.state
);
6666 hr
= IMediaStreamFilter_GetState(filter
, 0, &state
);
6667 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6668 ok(state
== expected_state
, "Got state %#x.\n", state
);
6670 hr
= reset_state(filter
);
6671 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6673 teststream
.set_state_result
= E_FAIL
;
6674 teststream2
.set_state_result
= E_FAIL
;
6675 teststream
.state
= 0xcc;
6676 teststream2
.state
= 0xcc;
6677 hr
= set_state(filter
);
6678 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6679 ok(teststream
.state
== 0xcc, "Got state %#x.\n", teststream
.state
);
6680 ok(teststream2
.state
== 0xcc, "Got state %#x.\n", teststream2
.state
);
6681 hr
= IMediaStreamFilter_GetState(filter
, 0, &state
);
6682 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6683 ok(state
== expected_state
, "Got state %#x.\n", state
);
6685 ref
= IAMMultiMediaStream_Release(mmstream
);
6686 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6687 ref
= IMediaStreamFilter_Release(filter
);
6688 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6689 ok(teststream
.refcount
== 1, "Got outstanding refcount %ld.\n", teststream
.refcount
);
6690 ok(teststream2
.refcount
== 1, "Got outstanding refcount %ld.\n", teststream2
.refcount
);
6693 static HRESULT
mediastreamfilter_stop(IMediaStreamFilter
*filter
)
6695 return IMediaStreamFilter_Stop(filter
);
6698 static HRESULT
mediastreamfilter_pause(IMediaStreamFilter
*filter
)
6700 return IMediaStreamFilter_Pause(filter
);
6703 static HRESULT
mediastreamfilter_run(IMediaStreamFilter
*filter
)
6705 return IMediaStreamFilter_Run(filter
, 0);
6708 void test_mediastreamfilter_stop_pause_run(void)
6710 check_mediastreamfilter_state(State_Stopped
, mediastreamfilter_stop
, mediastreamfilter_run
);
6711 check_mediastreamfilter_state(State_Paused
, mediastreamfilter_pause
, mediastreamfilter_stop
);
6712 check_mediastreamfilter_state(State_Running
, mediastreamfilter_run
, mediastreamfilter_stop
);
6715 static void test_mediastreamfilter_support_seeking(void)
6717 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6718 static const MSPID mspid1
= {0x88888888, 1};
6719 static const MSPID mspid2
= {0x88888888, 2};
6720 static const MSPID mspid3
= {0x88888888, 3};
6721 struct testfilter source1
, source2
, source3
;
6722 IAMMediaStream
*stream1
, *stream2
, *stream3
;
6723 IMediaStreamFilter
*filter
;
6724 IPin
*pin1
, *pin2
, *pin3
;
6725 ULONG ref
, seeking_ref
;
6726 IGraphBuilder
*graph
;
6729 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6730 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6731 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream1
);
6732 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6733 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream2
);
6734 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6735 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream3
);
6736 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6737 hr
= IAMMediaStream_Initialize(stream1
, NULL
, 0, &mspid1
, STREAMTYPE_READ
);
6738 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6739 hr
= IAMMediaStream_Initialize(stream2
, NULL
, 0, &mspid2
, STREAMTYPE_READ
);
6740 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6741 hr
= IAMMediaStream_Initialize(stream3
, NULL
, 0, &mspid3
, STREAMTYPE_READ
);
6742 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6743 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream1
, &mspid1
, 0, NULL
);
6744 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6745 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream2
, &mspid2
, 0, NULL
);
6746 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6747 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream3
, &mspid3
, 0, NULL
);
6748 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6749 hr
= IAMMediaStream_QueryInterface(stream1
, &IID_IPin
, (void **)&pin1
);
6750 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6751 hr
= IAMMediaStream_QueryInterface(stream2
, &IID_IPin
, (void **)&pin2
);
6752 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6753 hr
= IAMMediaStream_QueryInterface(stream3
, &IID_IPin
, (void **)&pin3
);
6754 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6755 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6756 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6757 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
6758 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6759 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
6760 testfilter_init(&source1
);
6761 testfilter_init(&source2
);
6762 testfilter_init(&source3
);
6763 source2
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6764 source3
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6765 hr
= IGraphBuilder_AddFilter(graph
, &source1
.filter
.IBaseFilter_iface
, NULL
);
6766 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6767 hr
= IGraphBuilder_AddFilter(graph
, &source2
.filter
.IBaseFilter_iface
, NULL
);
6768 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6769 hr
= IGraphBuilder_AddFilter(graph
, &source3
.filter
.IBaseFilter_iface
, NULL
);
6770 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6772 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6773 ok(hr
== E_NOINTERFACE
, "Got hr %#lx.\n", hr
);
6775 hr
= IGraphBuilder_ConnectDirect(graph
, &source1
.source
.pin
.IPin_iface
, pin1
, &audio_mt
);
6776 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6778 source2
.get_duration_hr
= E_FAIL
;
6780 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6781 ok(hr
== E_NOINTERFACE
, "Got hr %#lx.\n", hr
);
6783 hr
= IGraphBuilder_ConnectDirect(graph
, &source2
.source
.pin
.IPin_iface
, pin2
, &audio_mt
);
6784 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6786 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6787 ok(hr
== E_NOINTERFACE
, "Got hr %#lx.\n", hr
);
6789 hr
= IGraphBuilder_ConnectDirect(graph
, &source3
.source
.pin
.IPin_iface
, pin3
, &audio_mt
);
6790 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6792 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
6794 seeking_ref
= get_refcount(&source3
.IMediaSeeking_iface
);
6796 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6797 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6799 check_interface(filter
, &IID_IMediaSeeking
, TRUE
);
6801 ref
= get_refcount(&source3
.IMediaSeeking_iface
);
6802 ok(ref
== seeking_ref
, "Expected outstanding refcount %ld, got %ld.\n", seeking_ref
, ref
);
6804 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6805 ok(hr
== HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED
), "Got hr %#lx.\n", hr
);
6807 IGraphBuilder_Disconnect(graph
, pin1
);
6808 IGraphBuilder_Disconnect(graph
, &source1
.source
.pin
.IPin_iface
);
6810 IGraphBuilder_Disconnect(graph
, pin2
);
6811 IGraphBuilder_Disconnect(graph
, &source2
.source
.pin
.IPin_iface
);
6813 IGraphBuilder_Disconnect(graph
, pin3
);
6814 IGraphBuilder_Disconnect(graph
, &source3
.source
.pin
.IPin_iface
);
6816 ref
= IAMMultiMediaStream_Release(mmstream
);
6817 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6818 ref
= IGraphBuilder_Release(graph
);
6819 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6820 ref
= IMediaStreamFilter_Release(filter
);
6821 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6823 ref
= IAMMediaStream_Release(stream1
);
6824 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6826 ref
= IAMMediaStream_Release(stream2
);
6827 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6829 ref
= IAMMediaStream_Release(stream3
);
6830 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6833 static void check_mediastreamfilter_seeking(void (*check
)(IMediaSeeking
*seeking
, struct testfilter
*source1
,
6834 struct testfilter
*source2
, struct testfilter
*source3
, HRESULT source2_hr
, HRESULT expected_hr
))
6836 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
6837 static const MSPID mspid1
= {0x88888888, 1};
6838 static const MSPID mspid2
= {0x88888888, 2};
6839 static const MSPID mspid3
= {0x88888888, 3};
6840 IMediaStreamFilter
*filter
;
6841 struct testfilter source1
;
6842 struct testfilter source2
;
6843 struct testfilter source3
;
6844 IAMMediaStream
*stream1
;
6845 IAMMediaStream
*stream2
;
6846 IAMMediaStream
*stream3
;
6847 IMediaSeeking
*seeking
;
6848 IGraphBuilder
*graph
;
6855 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
6856 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6857 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream1
);
6858 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6859 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream2
);
6860 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6861 hr
= CoCreateInstance(&CLSID_AMAudioStream
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAMMediaStream
, (void **)&stream3
);
6862 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6863 hr
= IAMMediaStream_Initialize(stream1
, NULL
, 0, &mspid1
, STREAMTYPE_READ
);
6864 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6865 hr
= IAMMediaStream_Initialize(stream2
, NULL
, 0, &mspid2
, STREAMTYPE_READ
);
6866 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6867 hr
= IAMMediaStream_Initialize(stream3
, NULL
, 0, &mspid3
, STREAMTYPE_READ
);
6868 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6869 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream1
, &mspid1
, 0, NULL
);
6870 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6871 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream2
, &mspid2
, 0, NULL
);
6872 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6873 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)stream3
, &mspid3
, 0, NULL
);
6874 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6875 hr
= IAMMediaStream_QueryInterface(stream1
, &IID_IPin
, (void **)&pin1
);
6876 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6877 hr
= IAMMediaStream_QueryInterface(stream2
, &IID_IPin
, (void **)&pin2
);
6878 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6879 hr
= IAMMediaStream_QueryInterface(stream3
, &IID_IPin
, (void **)&pin3
);
6880 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6881 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
6882 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6883 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
6884 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6885 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
6886 testfilter_init(&source1
);
6887 testfilter_init(&source2
);
6888 testfilter_init(&source3
);
6889 source1
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6890 source2
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6891 source3
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6892 hr
= IGraphBuilder_AddFilter(graph
, &source1
.filter
.IBaseFilter_iface
, NULL
);
6893 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6894 hr
= IGraphBuilder_AddFilter(graph
, &source2
.filter
.IBaseFilter_iface
, NULL
);
6895 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6896 hr
= IGraphBuilder_AddFilter(graph
, &source3
.filter
.IBaseFilter_iface
, NULL
);
6897 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6899 hr
= IGraphBuilder_ConnectDirect(graph
, &source2
.source
.pin
.IPin_iface
, pin2
, &audio_mt
);
6900 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6901 hr
= IGraphBuilder_ConnectDirect(graph
, &source3
.source
.pin
.IPin_iface
, pin3
, &audio_mt
);
6902 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6904 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
6905 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6907 hr
= IGraphBuilder_ConnectDirect(graph
, &source1
.source
.pin
.IPin_iface
, pin1
, &audio_mt
);
6908 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6910 hr
= IMediaStreamFilter_QueryInterface(filter
, &IID_IMediaSeeking
, (void **)&seeking
);
6911 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
6913 check(seeking
, &source1
, &source2
, &source3
, S_OK
, S_OK
);
6914 check(seeking
, &source1
, &source2
, &source3
, E_FAIL
, E_FAIL
);
6915 check(seeking
, &source1
, &source2
, &source3
, E_NOTIMPL
, E_NOTIMPL
);
6917 source2
.IMediaSeeking_iface
.lpVtbl
= NULL
;
6919 check(seeking
, &source1
, &source2
, &source3
, S_OK
, E_NOTIMPL
);
6921 source2
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
6923 IGraphBuilder_Disconnect(graph
, pin2
);
6924 IGraphBuilder_Disconnect(graph
, &source2
.source
.pin
.IPin_iface
);
6926 check(seeking
, &source1
, &source2
, &source3
, S_OK
, E_NOTIMPL
);
6928 IGraphBuilder_Disconnect(graph
, pin2
);
6929 IGraphBuilder_Disconnect(graph
, &source2
.source
.pin
.IPin_iface
);
6930 IGraphBuilder_Disconnect(graph
, pin3
);
6931 IGraphBuilder_Disconnect(graph
, &source3
.source
.pin
.IPin_iface
);
6933 ref
= IAMMultiMediaStream_Release(mmstream
);
6934 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6935 ref
= IGraphBuilder_Release(graph
);
6936 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6937 IMediaSeeking_Release(seeking
);
6938 ref
= IMediaStreamFilter_Release(filter
);
6939 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6941 ref
= IAMMediaStream_Release(stream1
);
6942 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6944 ref
= IAMMediaStream_Release(stream2
);
6945 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6947 ref
= IAMMediaStream_Release(stream3
);
6948 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
6951 static void check_mediastreamfilter_set_positions(IMediaSeeking
*seeking
, struct testfilter
*source1
,
6952 struct testfilter
*source2
, struct testfilter
*source3
, HRESULT source2_hr
, HRESULT expected_hr
)
6954 LONGLONG current_position
= 12345678;
6955 LONGLONG stop_position
= 87654321;
6958 source2
->set_positions_hr
= source2_hr
;
6959 source1
->current_position
= 0xdeadbeefdeadbeefULL
;
6960 source1
->stop_position
= 0xdeadbeefdeadbeefULL
;
6961 source2
->current_position
= 0xdeadbeefdeadbeefULL
;
6962 source2
->stop_position
= 0xdeadbeefdeadbeefULL
;
6963 source3
->current_position
= 0xdeadbeefdeadbeefULL
;
6964 source3
->stop_position
= 0xdeadbeefdeadbeefULL
;
6965 hr
= IMediaSeeking_SetPositions(seeking
, ¤t_position
, AM_SEEKING_AbsolutePositioning
,
6966 &stop_position
, AM_SEEKING_AbsolutePositioning
);
6967 ok(hr
== expected_hr
, "Got hr %#lx.\n", hr
);
6968 ok(source1
->current_position
== 0xdeadbeefdeadbeefULL
, "Got current position %s.\n",
6969 wine_dbgstr_longlong(source1
->current_position
));
6970 ok(source1
->stop_position
== 0xdeadbeefdeadbeefULL
, "Got stop position %s.\n",
6971 wine_dbgstr_longlong(source1
->stop_position
));
6972 if (SUCCEEDED(expected_hr
))
6974 ok(source2
->current_position
== 12345678, "Got current position %s.\n",
6975 wine_dbgstr_longlong(source2
->current_position
));
6976 ok(source2
->stop_position
== 87654321, "Got stop position %s.\n",
6977 wine_dbgstr_longlong(source2
->stop_position
));
6979 ok(source3
->current_position
== 0xdeadbeefdeadbeefULL
, "Got current position %s.\n",
6980 wine_dbgstr_longlong(source3
->current_position
));
6981 ok(source3
->stop_position
== 0xdeadbeefdeadbeefULL
, "Got stop position %s.\n",
6982 wine_dbgstr_longlong(source3
->stop_position
));
6985 static void check_mediastreamfilter_get_duration(IMediaSeeking
*seeking
, struct testfilter
*source1
,
6986 struct testfilter
*source2
, struct testfilter
*source3
, HRESULT source2_hr
, HRESULT expected_hr
)
6988 LONGLONG duration
= 0xdeadbeefdeadbeefULL
;
6991 source2
->get_duration_hr
= source2_hr
;
6992 hr
= IMediaSeeking_GetDuration(seeking
, &duration
);
6993 ok(hr
== expected_hr
, "Got hr %#lx.\n", hr
);
6994 if (SUCCEEDED(expected_hr
))
6995 ok(duration
== 0x8000000000000000ULL
, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
6997 ok(duration
== 0xdeadbeefdeadbeefULL
, "Got duration %s.\n", wine_dbgstr_longlong(duration
));
7000 static void check_mediastreamfilter_get_stop_position(IMediaSeeking
*seeking
, struct testfilter
*source1
,
7001 struct testfilter
*source2
, struct testfilter
*source3
, HRESULT source2_hr
, HRESULT expected_hr
)
7003 LONGLONG stop
= 0xdeadbeefdeadbeefULL
;
7006 source2
->get_stop_position_hr
= source2_hr
;
7007 hr
= IMediaSeeking_GetStopPosition(seeking
, &stop
);
7008 ok(hr
== expected_hr
, "Got hr %#lx.\n", hr
);
7009 if (SUCCEEDED(expected_hr
))
7010 ok(stop
== 0x8000000000000000ULL
, "Got stop position %s.\n", wine_dbgstr_longlong(stop
));
7012 ok(stop
== 0xdeadbeefdeadbeefULL
, "Got stop position %s.\n", wine_dbgstr_longlong(stop
));
7015 static void check_mediastreamfilter_is_format_supported(IMediaSeeking
*seeking
, struct testfilter
*source1
,
7016 struct testfilter
*source2
, struct testfilter
*source3
, HRESULT source2_hr
, HRESULT expected_hr
)
7020 source2
->is_format_supported_hr
= source2_hr
;
7021 hr
= IMediaSeeking_IsFormatSupported(seeking
, &TIME_FORMAT_MEDIA_TIME
);
7022 ok(hr
== expected_hr
, "Got hr %#lx.\n", hr
);
7025 static void test_mediastreamfilter_seeking(void)
7027 check_mediastreamfilter_seeking(check_mediastreamfilter_set_positions
);
7028 check_mediastreamfilter_seeking(check_mediastreamfilter_get_duration
);
7029 check_mediastreamfilter_seeking(check_mediastreamfilter_get_stop_position
);
7030 check_mediastreamfilter_seeking(check_mediastreamfilter_is_format_supported
);
7033 static void test_mediastreamfilter_get_current_stream_time(void)
7035 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7036 STREAM_TIME filter_start_time
;
7037 IMediaStreamFilter
*filter
;
7038 IMediaFilter
*media_filter
;
7039 struct testclock clock
;
7040 IGraphBuilder
*graph
;
7045 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7046 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7047 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
7048 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7049 ok(!!filter
, "Expected non-null filter.\n");
7050 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, NULL
);
7051 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7052 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
7053 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7054 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
7055 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
7056 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7057 testclock_init(&clock
);
7059 /* Crashes on native. */
7062 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, NULL
);
7063 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
7064 hr
= IAMMultiMediaStream_GetTime(mmstream
, NULL
);
7065 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
7068 time
= 0xdeadbeefdeadbeef;
7069 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &time
);
7070 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
7071 ok(time
== 0, "Got time %s.\n", wine_dbgstr_longlong(time
));
7072 time
= 0xdeadbeefdeadbeef;
7073 hr
= IAMMultiMediaStream_GetTime(mmstream
, &time
);
7074 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
7075 ok(time
== 0, "Got time %s.\n", wine_dbgstr_longlong(time
));
7077 hr
= IMediaFilter_SetSyncSource(media_filter
, &clock
.IReferenceClock_iface
);
7078 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7080 clock
.get_time_hr
= E_FAIL
;
7082 time
= 0xdeadbeefdeadbeef;
7083 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &time
);
7084 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
7085 ok(time
== 0, "Got time %s.\n", wine_dbgstr_longlong(time
));
7086 time
= 0xdeadbeefdeadbeef;
7087 hr
= IAMMultiMediaStream_GetTime(mmstream
, &time
);
7088 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
7089 ok(time
== 0, "Got time %s.\n", wine_dbgstr_longlong(time
));
7091 clock
.time
= 23456789;
7092 clock
.get_time_hr
= S_OK
;
7094 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7095 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7097 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &filter_start_time
);
7098 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7100 clock
.time
= 34567890;
7102 time
= 0xdeadbeefdeadbeef;
7103 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &time
);
7104 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7105 ok(time
== 11111101 + filter_start_time
, "Got time %s.\n", wine_dbgstr_longlong(time
));
7106 time
= 0xdeadbeefdeadbeef;
7107 hr
= IAMMultiMediaStream_GetTime(mmstream
, &time
);
7108 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7109 ok(time
== 11111101 + filter_start_time
, "Got time %s.\n", wine_dbgstr_longlong(time
));
7111 ref
= IAMMultiMediaStream_Release(mmstream
);
7112 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7113 IMediaFilter_Release(media_filter
);
7114 ref
= IGraphBuilder_Release(graph
);
7115 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7116 ref
= IMediaStreamFilter_Release(filter
);
7117 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7120 static void test_mediastreamfilter_reference_time_to_stream_time(void)
7122 IMediaStreamFilter
*filter
;
7123 struct testclock clock
;
7124 REFERENCE_TIME time
;
7128 hr
= CoCreateInstance(&CLSID_MediaStreamFilter
, NULL
, CLSCTX_INPROC_SERVER
,
7129 &IID_IMediaStreamFilter
, (void **)&filter
);
7130 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7131 testclock_init(&clock
);
7133 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, NULL
);
7134 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
7136 time
= 0xdeadbeefdeadbeef;
7137 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, &time
);
7138 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
7139 ok(time
== 0xdeadbeefdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(time
));
7141 hr
= IMediaStreamFilter_SetSyncSource(filter
, &clock
.IReferenceClock_iface
);
7142 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7144 clock
.get_time_hr
= E_FAIL
;
7146 /* Crashes on native. */
7149 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, NULL
);
7150 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
7153 time
= 0xdeadbeefdeadbeef;
7154 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, &time
);
7155 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7156 ok(time
== 0xdeadbeefdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(time
));
7158 hr
= IMediaStreamFilter_Run(filter
, 23456789);
7159 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7161 time
= 0xdeadbeefdeadbeef;
7162 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, &time
);
7163 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7164 ok(time
== 0xdeadbeefdd47d2da, "Got time %s.\n", wine_dbgstr_longlong(time
));
7166 clock
.time
= 34567890;
7167 clock
.get_time_hr
= S_OK
;
7169 time
= 0xdeadbeefdeadbeef;
7170 hr
= IMediaStreamFilter_ReferenceTimeToStreamTime(filter
, &time
);
7171 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7172 ok(time
== 0xdeadbeefdd47d2da, "Got time %s.\n", wine_dbgstr_longlong(time
));
7174 ref
= IMediaStreamFilter_Release(filter
);
7175 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7178 struct mediastreamfilter_wait_until_params
7180 IMediaStreamFilter
*filter
;
7181 REFERENCE_TIME time
;
7182 HRESULT expected_hr
;
7185 static DWORD CALLBACK
mediastreamfilter_wait_until(void *p
)
7187 struct mediastreamfilter_wait_until_params
*params
= (struct mediastreamfilter_wait_until_params
*)p
;
7190 hr
= IMediaStreamFilter_WaitUntil(params
->filter
, params
->time
);
7191 ok(hr
== params
->expected_hr
, "Got hr %#lx.\n", hr
);
7196 static void test_mediastreamfilter_wait_until(void)
7198 struct mediastreamfilter_wait_until_params params1
;
7199 struct mediastreamfilter_wait_until_params params2
;
7200 struct advise_time_cookie cookie1
= { 0 };
7201 struct advise_time_cookie cookie2
= { 0 };
7202 IMediaStreamFilter
*filter
;
7203 struct testclock clock
;
7209 hr
= CoCreateInstance(&CLSID_MediaStreamFilter
, NULL
, CLSCTX_INPROC_SERVER
,
7210 &IID_IMediaStreamFilter
, (void **)&filter
);
7211 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7212 testclock_init(&clock
);
7213 cookie1
.advise_time_called_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
7214 cookie2
.advise_time_called_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
7216 hr
= IMediaStreamFilter_Run(filter
, 12345678);
7217 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7219 hr
= IMediaStreamFilter_WaitUntil(filter
, 23456789);
7220 ok(hr
== E_FAIL
, "Got hr %#lx.\n", hr
);
7222 hr
= IMediaStreamFilter_Stop(filter
);
7223 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7225 hr
= IMediaStreamFilter_SetSyncSource(filter
, &clock
.IReferenceClock_iface
);
7226 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7228 clock
.advise_time_cookie
= &cookie1
;
7230 params1
.filter
= filter
;
7231 params1
.time
= 23456789;
7232 params1
.expected_hr
= S_OK
;
7233 thread1
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms1
, 0, NULL
);
7234 ok(!WaitForSingleObject(cookie1
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
7235 ok(WaitForSingleObject(thread1
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
7237 ok(cookie1
.base
== 23456789, "Got base %s.\n", wine_dbgstr_longlong(cookie1
.base
));
7238 ok(cookie1
.offset
== 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie1
.offset
));
7239 ok(!!cookie1
.event
, "Expected non-NULL event.\n");
7241 SetEvent(cookie1
.event
);
7243 ok(!WaitForSingleObject(thread1
, 2000), "Wait timed out.\n");
7244 CloseHandle(thread1
);
7246 ok(!cookie1
.unadvise_called
, "Unexpected Unadvise call.\n");
7248 hr
= IMediaStreamFilter_Run(filter
, 12345678);
7249 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7251 clock
.time
= 30000000;
7253 clock
.advise_time_cookie
= &cookie1
;
7255 params1
.filter
= filter
;
7256 params1
.time
= 23456789;
7257 params1
.expected_hr
= S_OK
;
7258 thread1
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms1
, 0, NULL
);
7259 ok(!WaitForSingleObject(cookie1
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
7260 ok(WaitForSingleObject(thread1
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
7262 ok(cookie1
.base
== 23456789, "Got base %s.\n", wine_dbgstr_longlong(cookie1
.base
));
7263 ok(cookie1
.offset
== 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie1
.offset
));
7264 ok(!!cookie1
.event
, "Expected non-NULL event.\n");
7266 clock
.advise_time_cookie
= &cookie2
;
7268 params2
.filter
= filter
;
7269 params2
.time
= 11111111;
7270 params2
.expected_hr
= S_OK
;
7271 thread2
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms2
, 0, NULL
);
7272 ok(!WaitForSingleObject(cookie2
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
7273 ok(WaitForSingleObject(thread2
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
7275 ok(cookie2
.base
== 11111111, "Got base %s.\n", wine_dbgstr_longlong(cookie2
.base
));
7276 ok(cookie2
.offset
== 12345678, "Got offset %s.\n", wine_dbgstr_longlong(cookie2
.offset
));
7277 ok(!!cookie2
.event
, "Expected non-NULL event.\n");
7279 SetEvent(cookie1
.event
);
7281 ok(!WaitForSingleObject(thread1
, 2000), "Wait timed out.\n");
7282 CloseHandle(thread1
);
7284 ok(WaitForSingleObject(thread2
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
7286 SetEvent(cookie2
.event
);
7288 ok(!WaitForSingleObject(thread2
, 2000), "Wait timed out.\n");
7289 CloseHandle(thread2
);
7291 clock
.advise_time_cookie
= &cookie1
;
7293 params1
.filter
= filter
;
7294 params1
.time
= 23456789;
7295 params1
.expected_hr
= S_FALSE
;
7296 thread1
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms1
, 0, NULL
);
7297 ok(!WaitForSingleObject(cookie1
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
7298 ok(WaitForSingleObject(thread1
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
7300 clock
.advise_time_cookie
= &cookie2
;
7302 params2
.filter
= filter
;
7303 params2
.time
= 23456789;
7304 params2
.expected_hr
= S_FALSE
;
7305 thread2
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms2
, 0, NULL
);
7306 ok(!WaitForSingleObject(cookie2
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
7307 ok(WaitForSingleObject(thread2
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
7309 hr
= IMediaStreamFilter_Flush(filter
, FALSE
);
7310 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7312 ok(cookie1
.unadvise_called
, "Expected Unadvise to be called.\n");
7313 ok(cookie2
.unadvise_called
, "Expected Unadvise to be called.\n");
7315 ok(!WaitForSingleObject(thread1
, 2000), "Wait timed out.\n");
7316 CloseHandle(thread1
);
7317 ok(!WaitForSingleObject(thread2
, 2000), "Wait timed out.\n");
7318 CloseHandle(thread2
);
7320 clock
.advise_time_cookie
= &cookie1
;
7322 params1
.filter
= filter
;
7323 params1
.time
= 23456789;
7324 params1
.expected_hr
= S_FALSE
;
7325 thread1
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms1
, 0, NULL
);
7326 ok(!WaitForSingleObject(cookie1
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
7327 ok(WaitForSingleObject(thread1
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
7329 clock
.advise_time_cookie
= &cookie2
;
7331 params2
.filter
= filter
;
7332 params2
.time
= 23456789;
7333 params2
.expected_hr
= S_FALSE
;
7334 thread2
= CreateThread(NULL
, 0, mediastreamfilter_wait_until
, ¶ms2
, 0, NULL
);
7335 ok(!WaitForSingleObject(cookie2
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
7336 ok(WaitForSingleObject(thread2
, 100) == WAIT_TIMEOUT
, "WaitUntil returned prematurely.\n");
7338 hr
= IMediaStreamFilter_Stop(filter
);
7339 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7341 ok(cookie1
.unadvise_called
, "Expected Unadvise to be called.\n");
7342 ok(cookie2
.unadvise_called
, "Expected Unadvise to be called.\n");
7344 ok(!WaitForSingleObject(thread1
, 2000), "Wait timed out.\n");
7345 CloseHandle(thread1
);
7346 ok(!WaitForSingleObject(thread2
, 2000), "Wait timed out.\n");
7347 CloseHandle(thread2
);
7349 CloseHandle(cookie1
.advise_time_called_event
);
7350 CloseHandle(cookie2
.advise_time_called_event
);
7352 ref
= IMediaStreamFilter_Release(filter
);
7353 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7356 static void test_mediastreamfilter_end_of_stream(void)
7358 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7359 struct testfilter source1
, source2
;
7360 IMediaStream
*stream1
, *stream2
;
7361 IMediaControl
*media_control
;
7362 IMediaStreamFilter
*filter
;
7369 hr
= IFilterGraph2_QueryInterface(&graph
.IFilterGraph2_iface
, &IID_IMediaControl
, (void **)&media_control
);
7370 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7372 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, (IGraphBuilder
*)&graph
.IFilterGraph2_iface
);
7373 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7374 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream1
);
7375 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7376 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream2
);
7377 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7378 hr
= IMediaStream_QueryInterface(stream1
, &IID_IPin
, (void **)&pin1
);
7379 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7380 hr
= IMediaStream_QueryInterface(stream2
, &IID_IPin
, (void **)&pin2
);
7381 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7382 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
7383 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7384 ok(filter
!= NULL
, "Expected non-null filter\n");
7385 testfilter_init(&source1
);
7386 testfilter_init(&source2
);
7387 hr
= IFilterGraph2_AddFilter(&graph
.IFilterGraph2_iface
, &source1
.filter
.IBaseFilter_iface
, NULL
);
7388 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7389 hr
= IFilterGraph2_AddFilter(&graph
.IFilterGraph2_iface
, &source2
.filter
.IBaseFilter_iface
, NULL
);
7390 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7392 hr
= IPin_Connect(&source1
.source
.pin
.IPin_iface
, pin1
, &audio_mt
);
7393 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7394 hr
= IPin_Connect(&source2
.source
.pin
.IPin_iface
, pin2
, &rgb32_mt
);
7395 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7397 /* Initially, EC_COMPLETE notifications are disabled. */
7398 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7399 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7401 graph
.got_notify
= 0;
7403 hr
= IMediaStreamFilter_EndOfStream(filter
);
7404 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7405 hr
= IMediaStreamFilter_EndOfStream(filter
);
7406 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7408 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7410 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7411 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7413 /* Unsuccsessful call to SupportSeeking does not enable EC_COMPLETE notifications. */
7414 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
7415 ok(hr
== E_NOINTERFACE
, "Got hr %#lx.\n", hr
);
7417 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7418 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7420 graph
.got_notify
= 0;
7422 hr
= IMediaStreamFilter_EndOfStream(filter
);
7423 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7424 hr
= IMediaStreamFilter_EndOfStream(filter
);
7425 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7427 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7429 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7430 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7432 /* Successful call to SupportSeeking enables EC_COMPLETE notifications. */
7433 source1
.IMediaSeeking_iface
.lpVtbl
= &testsource_seeking_vtbl
;
7435 hr
= IMediaStreamFilter_SupportSeeking(filter
, TRUE
);
7436 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7438 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7439 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7441 graph
.got_notify
= 0;
7443 hr
= IMediaStreamFilter_EndOfStream(filter
);
7444 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7446 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7448 hr
= IMediaStreamFilter_EndOfStream(filter
);
7449 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7451 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7453 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7454 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7456 /* EC_COMPLETE is sent on paused->running state transition
7457 * if EndOfStream has been called for all streams. */
7458 graph
.got_notify
= 0;
7460 hr
= IMediaStreamFilter_EndOfStream(filter
);
7461 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7462 hr
= IMediaStreamFilter_EndOfStream(filter
);
7463 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7465 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7467 hr
= IMediaControl_Pause(media_control
);
7468 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7470 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7472 hr
= IMediaControl_Run(media_control
);
7473 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7475 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7477 hr
= IMediaControl_Run(media_control
);
7478 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7480 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7482 hr
= IMediaControl_Stop(media_control
);
7483 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7485 /* EC_COMPLETE is sent on paused->running state transition
7486 * if EndOfStream has been called for all streams. */
7487 graph
.got_notify
= 0;
7489 hr
= IMediaStreamFilter_EndOfStream(filter
);
7490 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7491 hr
= IMediaStreamFilter_EndOfStream(filter
);
7492 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7494 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7496 hr
= IMediaControl_Pause(media_control
);
7497 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7499 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7501 hr
= IMediaControl_Run(media_control
);
7502 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7504 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7506 hr
= IMediaControl_Stop(media_control
);
7507 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7509 /* EndOfStream count is reset on paused->stopped state transition. */
7510 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7511 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7513 graph
.got_notify
= 0;
7515 hr
= IMediaStreamFilter_EndOfStream(filter
);
7516 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7518 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7519 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7520 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7521 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7523 hr
= IMediaStreamFilter_EndOfStream(filter
);
7524 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7526 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7528 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7529 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7531 /* EOS count is not reset on running->paused state transition. */
7532 hr
= IMediaControl_Run(media_control
);
7533 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7535 graph
.got_notify
= 0;
7537 hr
= IMediaStreamFilter_EndOfStream(filter
);
7538 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7540 hr
= IMediaControl_Pause(media_control
);
7541 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7542 hr
= IMediaControl_Run(media_control
);
7543 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7545 hr
= IMediaStreamFilter_EndOfStream(filter
);
7546 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7548 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7550 hr
= IMediaControl_Stop(media_control
);
7551 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7553 /* EndOfStream count is not reset when Stop() is called on an already stopped filter. */
7554 hr
= IMediaStreamFilter_EndOfStream(filter
);
7555 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7557 hr
= IMediaStreamFilter_Stop(filter
);
7558 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7560 hr
= IMediaStreamFilter_EndOfStream(filter
);
7561 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7563 graph
.got_notify
= 0;
7565 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7566 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7568 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7570 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7571 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7573 /* Flush with cancel_eos=TRUE decrements EOS count. */
7574 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7575 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7577 graph
.got_notify
= 0;
7579 hr
= IMediaStreamFilter_EndOfStream(filter
);
7580 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7582 hr
= IMediaStreamFilter_Flush(filter
, TRUE
);
7584 hr
= IMediaStreamFilter_EndOfStream(filter
);
7585 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7587 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7589 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7590 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7592 /* Flush followed by EndOfStream causes another EC_COMPLETE to be sent. */
7593 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7594 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7596 graph
.got_notify
= 0;
7598 hr
= IMediaStreamFilter_EndOfStream(filter
);
7599 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7600 hr
= IMediaStreamFilter_EndOfStream(filter
);
7601 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7603 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7605 hr
= IMediaStreamFilter_Flush(filter
, TRUE
);
7606 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7608 hr
= IMediaStreamFilter_EndOfStream(filter
);
7609 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7611 ok(graph
.got_notify
== 2, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7613 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7614 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7616 /* Flush decrements EOS count event when it is 0. */
7617 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7618 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7620 graph
.got_notify
= 0;
7622 hr
= IMediaStreamFilter_Flush(filter
, TRUE
);
7623 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7625 hr
= IMediaStreamFilter_EndOfStream(filter
);
7626 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7627 hr
= IMediaStreamFilter_EndOfStream(filter
);
7628 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7630 ok(graph
.got_notify
== 0, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7632 hr
= IMediaStreamFilter_EndOfStream(filter
);
7633 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7635 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7637 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7638 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7640 /* Flush with cancel_eos=FALSE does not decrement EOS count. */
7641 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
7642 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7644 graph
.got_notify
= 0;
7646 hr
= IMediaStreamFilter_EndOfStream(filter
);
7647 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7649 hr
= IMediaStreamFilter_Flush(filter
, FALSE
);
7651 hr
= IMediaStreamFilter_EndOfStream(filter
);
7652 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7654 ok(graph
.got_notify
== 1, "Got %d calls to IMediaEventSink::Notify().\n", graph
.got_notify
);
7656 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
7657 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7659 ref
= IAMMultiMediaStream_Release(mmstream
);
7660 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7661 IMediaControl_Release(media_control
);
7662 graph_destroy(&graph
);
7663 ref
= IMediaStreamFilter_Release(filter
);
7664 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7666 ref
= IMediaStream_Release(stream1
);
7667 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7669 ref
= IMediaStream_Release(stream2
);
7670 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7673 static void test_ddrawstream_getsetdirectdraw(void)
7675 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7676 IDirectDraw
*ddraw
, *ddraw2
, *ddraw3
, *ddraw4
;
7677 IDirectDrawMediaStream
*ddraw_stream
;
7678 IDirectDrawStreamSample
*sample
;
7679 IDirectDraw7
*ddraw7
;
7680 IMediaStream
*stream
;
7684 hr
= DirectDrawCreate(NULL
, &ddraw
, NULL
);
7685 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7686 hr
= IDirectDraw_QueryInterface(ddraw
, &IID_IDirectDraw7
, (void **)&ddraw7
);
7687 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
7688 hr
= IDirectDraw7_SetCooperativeLevel(ddraw7
, GetDesktopWindow(), DDSCL_NORMAL
);
7689 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
7690 EXPECT_REF(ddraw
, 1);
7691 EXPECT_REF(ddraw7
, 1);
7693 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7694 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7696 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)ddraw7
, &MSPID_PrimaryVideo
, 0, &stream
);
7697 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7698 EXPECT_REF(ddraw
, 2);
7700 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
7701 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7703 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, NULL
);
7704 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
7706 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw2
);
7707 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7708 ok(ddraw2
== ddraw
, "Expected ddraw %p, got %p.\n", ddraw
, ddraw2
);
7709 EXPECT_REF(ddraw
, 3);
7711 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw3
);
7712 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7713 ok(ddraw3
== ddraw2
, "Expected ddraw %p, got %p.\n", ddraw2
, ddraw3
);
7714 EXPECT_REF(ddraw
, 4);
7715 IDirectDraw_Release(ddraw3
);
7716 EXPECT_REF(ddraw
, 3);
7718 /* The current ddraw is released when SetDirectDraw() is called. */
7719 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, NULL
);
7720 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7721 EXPECT_REF(ddraw
, 2);
7723 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw3
);
7724 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7725 ok(ddraw3
== NULL
, "Expected NULL, got %p.\n", ddraw3
);
7727 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, ddraw2
);
7728 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7729 EXPECT_REF(ddraw
, 3);
7731 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw3
);
7732 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7733 ok(ddraw3
== ddraw2
, "Expected ddraw %p, got %p.\n", ddraw2
, ddraw3
);
7734 EXPECT_REF(ddraw
, 4);
7735 IDirectDraw_Release(ddraw3
);
7736 EXPECT_REF(ddraw
, 3);
7738 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &sample
);
7739 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7741 /* SetDirectDraw() doesn't take an extra reference to the ddraw object
7742 * if there are samples extant. */
7743 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, ddraw2
);
7744 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7745 EXPECT_REF(ddraw
, 3);
7747 hr
= DirectDrawCreate(NULL
, &ddraw3
, NULL
);
7748 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7749 hr
= IDirectDraw_SetCooperativeLevel(ddraw3
, GetDesktopWindow(), DDSCL_NORMAL
);
7750 ok(hr
== DD_OK
, "Got hr %#lx.\n", hr
);
7751 EXPECT_REF(ddraw3
, 1);
7753 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, ddraw3
);
7754 ok(hr
== MS_E_SAMPLEALLOC
, "Got hr %#lx.\n", hr
);
7756 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw4
);
7757 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7758 ok(ddraw4
== ddraw2
, "Expected ddraw %p, got %p.\n", ddraw2
, ddraw4
);
7759 EXPECT_REF(ddraw
, 4);
7760 IDirectDraw_Release(ddraw4
);
7761 EXPECT_REF(ddraw
, 3);
7763 ref
= IDirectDrawStreamSample_Release(sample
);
7764 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7766 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, ddraw3
);
7767 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7768 EXPECT_REF(ddraw
, 2);
7769 EXPECT_REF(ddraw3
, 2);
7771 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw4
);
7772 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7773 ok(ddraw4
== ddraw3
, "Expected ddraw %p, got %p.\n", ddraw3
, ddraw4
);
7774 EXPECT_REF(ddraw3
, 3);
7775 IDirectDraw_Release(ddraw4
);
7776 EXPECT_REF(ddraw3
, 2);
7778 hr
= IDirectDrawMediaStream_SetDirectDraw(ddraw_stream
, NULL
);
7779 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7780 EXPECT_REF(ddraw3
, 1);
7782 ref
= IDirectDraw_Release(ddraw3
);
7783 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7785 EXPECT_REF(stream
, 3);
7786 IDirectDrawMediaStream_Release(ddraw_stream
);
7787 EXPECT_REF(stream
, 2);
7788 ref
= IAMMultiMediaStream_Release(mmstream
);
7789 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7790 EXPECT_REF(stream
, 1);
7791 ref
= IMediaStream_Release(stream
);
7792 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7793 ref
= IDirectDraw7_Release(ddraw7
);
7794 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7795 IDirectDraw_Release(ddraw2
);
7796 EXPECT_REF(ddraw
, 1);
7797 ref
= IDirectDraw_Release(ddraw
);
7798 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7801 static void test_audiostreamsample_get_media_stream(void)
7803 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7804 IAudioStreamSample
*audio_sample
;
7805 IAudioMediaStream
*audio_stream
;
7806 IMediaStream
*stream
, *stream2
;
7807 IAudioData
*audio_data
;
7811 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7812 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7814 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
7815 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7817 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
7818 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7820 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
7821 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7823 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &audio_sample
);
7824 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7826 /* Crashes on native. */
7829 hr
= IAudioStreamSample_GetMediaStream(audio_sample
, NULL
);
7830 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
7833 EXPECT_REF(stream
, 4);
7834 hr
= IAudioStreamSample_GetMediaStream(audio_sample
, &stream2
);
7835 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7836 ok(stream2
== stream
, "Expected stream %p, got %p.\n", stream
, stream2
);
7837 EXPECT_REF(stream
, 5);
7839 IMediaStream_Release(stream2
);
7841 IAudioMediaStream_Release(audio_stream
);
7842 ref
= IAudioStreamSample_Release(audio_sample
);
7843 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7844 ref
= IAudioData_Release(audio_data
);
7845 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7846 ref
= IAMMultiMediaStream_Release(mmstream
);
7847 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7848 ref
= IMediaStream_Release(stream
);
7849 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7852 static void test_audiostreamsample_get_audio_data(void)
7854 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7855 IAudioData
*audio_data
, *audio_data2
;
7856 IAudioStreamSample
*audio_sample
;
7857 IAudioMediaStream
*audio_stream
;
7858 IMediaStream
*stream
;
7862 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7863 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7865 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryAudio
, 0, &stream
);
7866 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7868 hr
= IMediaStream_QueryInterface(stream
, &IID_IAudioMediaStream
, (void **)&audio_stream
);
7869 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7871 hr
= CoCreateInstance(&CLSID_AMAudioData
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IAudioData
, (void **)&audio_data
);
7872 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7874 hr
= IAudioMediaStream_CreateSample(audio_stream
, audio_data
, 0, &audio_sample
);
7875 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7877 hr
= IAudioStreamSample_GetAudioData(audio_sample
, NULL
);
7878 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
7880 EXPECT_REF(audio_data
, 2);
7881 hr
= IAudioStreamSample_GetAudioData(audio_sample
, &audio_data2
);
7882 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7883 ok(audio_data2
== audio_data
, "Expected audio data %p, got %p.\n", audio_data
, audio_data2
);
7884 EXPECT_REF(audio_data
, 3);
7886 IAudioData_Release(audio_data2
);
7888 IAudioMediaStream_Release(audio_stream
);
7889 ref
= IAudioStreamSample_Release(audio_sample
);
7890 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7891 ref
= IAudioData_Release(audio_data
);
7892 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7893 ref
= IAMMultiMediaStream_Release(mmstream
);
7894 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7895 ref
= IMediaStream_Release(stream
);
7896 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
7899 #define get_ddrawstream_create_sample_desc(a,b,c,d) get_ddrawstream_create_sample_desc_(__LINE__,a,b,c,d)
7900 static void get_ddrawstream_create_sample_desc_(int line
, const DDSURFACEDESC
*format1
,
7901 const DDSURFACEDESC
*format2
, const AM_MEDIA_TYPE
*mt
, DDSURFACEDESC
*desc
)
7903 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7904 IDirectDrawMediaStream
*ddraw_stream
;
7905 IDirectDrawStreamSample
*sample
;
7906 IDirectDrawSurface
*surface
;
7907 struct testfilter source
;
7908 IGraphBuilder
*graph
;
7909 IMediaStream
*stream
;
7914 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7915 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7916 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
7917 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7918 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
7919 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7920 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
7921 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7922 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
7923 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7925 testfilter_init(&source
);
7927 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
7928 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7932 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, format1
, NULL
);
7933 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7937 hr
= IDirectDrawMediaStream_SetFormat(ddraw_stream
, format2
, NULL
);
7938 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7942 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, mt
);
7943 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7945 hr
= IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
7946 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7947 hr
= IGraphBuilder_Disconnect(graph
, pin
);
7948 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7951 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &sample
);
7952 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7954 hr
= IDirectDrawStreamSample_GetSurface(sample
, &surface
, NULL
);
7955 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7956 ok_(__FILE__
, line
)(!!surface
, "Expected non-NULL sufrace.\n");
7958 desc
->dwSize
= sizeof(*desc
);
7959 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, desc
);
7960 ok_(__FILE__
, line
)(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7962 ref
= IDirectDrawStreamSample_Release(sample
);
7963 ok_(__FILE__
, line
)(!ref
, "Got outstanding refcount %ld.\n", ref
);
7964 ref
= IDirectDrawSurface_Release(surface
);
7965 ok_(__FILE__
, line
)(!ref
, "Got outstanding refcount %ld.\n", ref
);
7966 ref
= IAMMultiMediaStream_Release(mmstream
);
7967 ok_(__FILE__
, line
)(!ref
, "Got outstanding refcount %ld.\n", ref
);
7968 ref
= IGraphBuilder_Release(graph
);
7969 ok_(__FILE__
, line
)(!ref
, "Got outstanding refcount %ld.\n", ref
);
7971 IDirectDrawMediaStream_Release(ddraw_stream
);
7972 ref
= IMediaStream_Release(stream
);
7973 ok_(__FILE__
, line
)(!ref
, "Got outstanding refcount %ld.\n", ref
);
7976 static void test_ddrawstream_create_sample(void)
7978 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
7979 DDSURFACEDESC desc2
= { sizeof(desc2
) };
7980 IDirectDrawSurface
*surface
, *surface2
;
7981 DDSURFACEDESC desc
= { sizeof(desc
) };
7982 IDirectDrawMediaStream
*ddraw_stream
;
7983 IDirectDrawStreamSample
*sample
;
7984 DDSURFACEDESC format1
;
7985 DDSURFACEDESC format2
;
7986 IMediaStream
*stream
;
7992 hr
= DirectDrawCreate(NULL
, &ddraw
, NULL
);
7993 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7995 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
7996 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7998 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
7999 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8001 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)ddraw
, &MSPID_PrimaryVideo
, 0, &stream
);
8002 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8004 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
8005 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8007 /* Crashes on native. */
8010 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, NULL
);
8011 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
8014 SetRectEmpty(&rect
);
8015 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, &rect
, 0, &sample
);
8016 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
8018 EXPECT_REF(mmstream
, 1);
8019 EXPECT_REF(stream
, 3);
8020 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &sample
);
8021 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8022 EXPECT_REF(mmstream
, 2);
8023 EXPECT_REF(stream
, 4);
8025 hr
= IDirectDrawStreamSample_GetSurface(sample
, NULL
, NULL
);
8026 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8028 hr
= IDirectDrawStreamSample_GetSurface(sample
, NULL
, &rect
);
8029 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8031 hr
= IDirectDrawStreamSample_GetSurface(sample
, &surface
, NULL
);
8032 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8033 ok(surface
!= NULL
, "Expected non-NULL surface.\n");
8034 IDirectDrawSurface_Release(surface
);
8037 hr
= IDirectDrawStreamSample_GetSurface(sample
, &surface
, &rect
);
8038 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8039 ok(surface
!= NULL
, "Expected non-NULL surface.\n");
8041 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
);
8042 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8043 ok(desc
.dwWidth
== 100, "Expected width 100, got %ld.\n", desc
.dwWidth
);
8044 ok(desc
.dwHeight
== 100, "Expected height 100, got %ld.\n", desc
.dwHeight
);
8045 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Expected format flags DDPF_RGB, got %#lx.\n", desc
.ddpfPixelFormat
.dwFlags
);
8046 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
, "Expected non-zero RGB bit count.\n");
8047 IDirectDrawSurface_Release(surface
);
8048 IDirectDrawStreamSample_Release(sample
);
8049 EXPECT_REF(stream
, 3);
8051 memset(&desc
, 0, sizeof(desc
));
8052 desc
.dwSize
= sizeof(desc
);
8053 desc
.dwFlags
= DDSD_CAPS
;
8054 desc
.ddsCaps
.dwCaps
= DDSCAPS_PRIMARYSURFACE
;
8055 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
);
8056 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8058 EXPECT_REF(surface
, 1);
8059 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, surface
, NULL
, 0, &sample
);
8060 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8061 EXPECT_REF(surface
, 2);
8064 SetRectEmpty(&rect
);
8065 hr
= IDirectDrawStreamSample_GetSurface(sample
, &surface2
, &rect
);
8066 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8067 ok(surface2
== surface
, "Expected surface %p, got %p.\n", surface
, surface2
);
8068 ok(rect
.right
> 0 && rect
.bottom
> 0, "Got rect %ld, %ld.\n", rect
.right
, rect
.bottom
);
8069 EXPECT_REF(surface
, 3);
8070 IDirectDrawSurface_Release(surface2
);
8071 EXPECT_REF(surface
, 2);
8072 IDirectDrawStreamSample_Release(sample
);
8073 EXPECT_REF(surface
, 1);
8075 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, surface
, &rect
, 0, &sample
);
8076 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8078 ref
= IDirectDrawStreamSample_Release(sample
);
8079 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8080 ref
= IDirectDrawSurface_Release(surface
);
8081 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8083 memset(&desc
, 0, sizeof(desc
));
8084 desc
.dwSize
= sizeof(desc
);
8085 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
;
8087 desc
.dwHeight
= 400;
8088 desc
.ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
);
8089 desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_ALPHAPIXELS
;
8090 desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
= 32;
8091 desc
.ddpfPixelFormat
.u2
.dwRBitMask
= 0xff0000;
8092 desc
.ddpfPixelFormat
.u3
.dwGBitMask
= 0x00ff00;
8093 desc
.ddpfPixelFormat
.u4
.dwBBitMask
= 0x0000ff;
8094 desc
.ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
= 0xff000000;
8095 desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
8096 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
);
8097 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8099 SetRect(&rect
, 111, 100, 333, 300);
8101 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, surface
, &rect
, 0, &sample
);
8102 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8103 ref
= IDirectDrawStreamSample_Release(sample
);
8104 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8106 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &sample
);
8107 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8109 hr
= IDirectDrawStreamSample_GetSurface(sample
, &surface2
, &rect
);
8110 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8112 hr
= IDirectDrawSurface_GetSurfaceDesc(surface
, &desc
);
8113 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8114 hr
= IDirectDrawSurface_GetSurfaceDesc(surface2
, &desc2
);
8115 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8116 ok(desc2
.dwWidth
== 222, "Got width %lu.\n", desc2
.dwWidth
);
8117 ok(desc2
.dwHeight
== 200, "Got height %lu.\n", desc2
.dwHeight
);
8118 ok(memcmp(&desc2
.ddpfPixelFormat
, &desc
.ddpfPixelFormat
, sizeof(DDPIXELFORMAT
)) == 0,
8119 "Pixel format didn't match.\n");
8121 ref
= IDirectDrawStreamSample_Release(sample
);
8122 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8123 ref
= IDirectDrawSurface_Release(surface
);
8124 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8125 ref
= IDirectDrawSurface_Release(surface2
);
8126 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8128 memset(&desc
, 0, sizeof(desc
));
8129 desc
.dwSize
= sizeof(desc
);
8130 desc
.dwFlags
= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_PIXELFORMAT
| DDSD_CAPS
;
8132 desc
.dwHeight
= 400;
8133 desc
.ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
);
8134 desc
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
| DDPF_PALETTEINDEXED4
;
8135 desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
= 4;
8136 desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
8137 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
);
8138 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8140 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, surface
, NULL
, 0, &sample
);
8141 ok(hr
== DDERR_INVALIDSURFACETYPE
, "Got hr %#lx.\n", hr
);
8143 IDirectDrawMediaStream_Release(ddraw_stream
);
8144 ref
= IDirectDrawSurface_Release(surface
);
8145 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8146 ref
= IAMMultiMediaStream_Release(mmstream
);
8147 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8148 ref
= IMediaStream_Release(stream
);
8149 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8150 ref
= IDirectDraw_Release(ddraw
);
8151 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8153 format1
= rgb8_format
;
8154 format1
.dwFlags
= 0;
8155 format1
.dwWidth
= 333;
8156 format1
.dwHeight
= 444;
8157 get_ddrawstream_create_sample_desc(&format1
, NULL
, NULL
, &desc
);
8158 ok(desc
.dwWidth
== 100, "Got width %lu.\n", desc
.dwWidth
);
8159 ok(desc
.dwHeight
== 100, "Got height %lu.\n", desc
.dwHeight
);
8160 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got flags %#lx.\n", desc
.ddpfPixelFormat
.dwFlags
);
8161 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 32, "Got rgb bit count %lu.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
8162 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xff0000, "Got r bit mask %#lx.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
8163 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x00ff00, "Got g bit mask %#lx.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
8164 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x0000ff, "Got b bit mask %#lx.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
8166 format1
= rgb8_format
;
8167 format1
.dwFlags
|= DDSD_WIDTH
;
8168 format1
.dwWidth
= 333;
8169 format1
.dwHeight
= 444;
8170 format2
= rgb8_format
;
8171 format2
.dwFlags
= 0;
8172 get_ddrawstream_create_sample_desc(&format1
, &format2
, NULL
, &desc
);
8173 ok(desc
.dwWidth
== 333, "Got width %lu.\n", desc
.dwWidth
);
8174 ok(desc
.dwHeight
== 444, "Got height %lu.\n", desc
.dwHeight
);
8176 format1
= rgb8_format
;
8177 format1
.dwFlags
|= DDSD_HEIGHT
;
8178 format1
.dwWidth
= 333;
8179 format1
.dwHeight
= 444;
8180 format2
= rgb8_format
;
8181 format2
.dwFlags
= 0;
8182 get_ddrawstream_create_sample_desc(&format1
, &format2
, NULL
, &desc
);
8183 ok(desc
.dwWidth
== 333, "Got width %lu.\n", desc
.dwWidth
);
8184 ok(desc
.dwHeight
== 444, "Got height %lu.\n", desc
.dwHeight
);
8186 get_ddrawstream_create_sample_desc(NULL
, NULL
, &rgb8_mt
, &desc
);
8187 ok(desc
.dwWidth
== 333, "Got width %lu.\n", desc
.dwWidth
);
8188 ok(desc
.dwHeight
== 444, "Got height %lu.\n", desc
.dwHeight
);
8189 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got flags %#lx.\n", desc
.ddpfPixelFormat
.dwFlags
);
8190 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 32, "Got rgb bit count %lu.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
8191 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xff0000, "Got r bit mask %#lx.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
8192 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x00ff00, "Got g bit mask %#lx.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
8193 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x0000ff, "Got b bit mask %#lx.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
8195 get_ddrawstream_create_sample_desc(&rgb565_format
, NULL
, NULL
, &desc
);
8196 ok(desc
.dwWidth
== 100, "Got width %lu.\n", desc
.dwWidth
);
8197 ok(desc
.dwHeight
== 100, "Got height %lu.\n", desc
.dwHeight
);
8198 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got flags %#lx.\n", desc
.ddpfPixelFormat
.dwFlags
);
8199 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 16, "Got rgb bit count %lu.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
8200 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xf800, "Got r bit mask %#lx.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
8201 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x07e0, "Got g bit mask %#lx.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
8202 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x001f, "Got b bit mask %#lx.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
8204 get_ddrawstream_create_sample_desc(&argb32_format
, NULL
, NULL
, &desc
);
8205 ok(desc
.dwWidth
== 100, "Got width %lu.\n", desc
.dwWidth
);
8206 ok(desc
.dwHeight
== 100, "Got height %lu.\n", desc
.dwHeight
);
8207 ok(desc
.ddpfPixelFormat
.dwFlags
== (DDPF_RGB
| DDPF_ALPHAPIXELS
), "Got flags %#lx.\n", desc
.ddpfPixelFormat
.dwFlags
);
8208 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 32, "Got rgb bit count %lu.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
8209 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xff0000, "Got r bit mask %#lx.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
8210 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x00ff00, "Got g bit mask %#lx.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
8211 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x0000ff, "Got b bit mask %#lx.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
8212 ok(desc
.ddpfPixelFormat
.u5
.dwRGBAlphaBitMask
== 0xff000000,
8213 "Got alpha bit mask %#lx.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
8215 format1
= rgb32_format
;
8216 format1
.dwFlags
|= DDSD_CAPS
;
8217 format1
.ddsCaps
.dwCaps
= DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_VIDEOMEMORY
;
8218 get_ddrawstream_create_sample_desc(&format1
, NULL
, NULL
, &desc
);
8219 ok(desc
.ddsCaps
.dwCaps
& DDSCAPS_OFFSCREENPLAIN
, "Expected set DDSCAPS_OFFSCREENPLAIN.\n");
8220 ok(desc
.ddsCaps
.dwCaps
& DDSCAPS_SYSTEMMEMORY
, "Expected set DDSCAPS_SYSTEMMEMORY.\n");
8221 ok(!(desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
), "Expected unset DDSCAPS_VIDEOMEMORY.\n");
8222 ok(desc
.dwWidth
== 100, "Got width %lu.\n", desc
.dwWidth
);
8223 ok(desc
.dwHeight
== 100, "Got height %lu.\n", desc
.dwHeight
);
8224 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got flags %#lx.\n", desc
.ddpfPixelFormat
.dwFlags
);
8225 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 32, "Got rgb bit count %lu.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
8226 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xff0000, "Got r bit mask %#lx.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
8227 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x00ff00, "Got g bit mask %#lx.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
8228 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x0000ff, "Got b bit mask %#lx.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
8230 format1
= rgb32_format
;
8231 format1
.dwFlags
|= DDSD_CKSRCBLT
;
8232 format1
.ddckCKSrcBlt
.dwColorSpaceLowValue
= 0xff00ff;
8233 format1
.ddckCKSrcBlt
.dwColorSpaceHighValue
= 0xff00ff;
8234 get_ddrawstream_create_sample_desc(&format1
, NULL
, NULL
, &desc
);
8235 ok(!(desc
.dwFlags
& DDSD_CKSRCBLT
), "Expected unset DDSD_CKSRCBLT.\n");
8236 ok(desc
.dwWidth
== 100, "Got width %lu.\n", desc
.dwWidth
);
8237 ok(desc
.dwHeight
== 100, "Got height %lu.\n", desc
.dwHeight
);
8238 ok(desc
.ddpfPixelFormat
.dwFlags
== DDPF_RGB
, "Got flags %#lx.\n", desc
.ddpfPixelFormat
.dwFlags
);
8239 ok(desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
== 32, "Got rgb bit count %lu.\n", desc
.ddpfPixelFormat
.u1
.dwRGBBitCount
);
8240 ok(desc
.ddpfPixelFormat
.u2
.dwRBitMask
== 0xff0000, "Got r bit mask %#lx.\n", desc
.ddpfPixelFormat
.u2
.dwRBitMask
);
8241 ok(desc
.ddpfPixelFormat
.u3
.dwGBitMask
== 0x00ff00, "Got g bit mask %#lx.\n", desc
.ddpfPixelFormat
.u3
.dwGBitMask
);
8242 ok(desc
.ddpfPixelFormat
.u4
.dwBBitMask
== 0x0000ff, "Got b bit mask %#lx.\n", desc
.ddpfPixelFormat
.u4
.dwBBitMask
);
8243 ok(desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
== 0, "Got color key low value %#lx.\n",
8244 desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
);
8245 ok(desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
== 0, "Got color key high value %#lx.\n",
8246 desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
);
8249 static void test_ddrawstream_qc(void)
8251 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
8252 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
8253 struct advise_time_cookie cookie
= { 0 };
8254 IDirectDrawStreamSample
*stream_sample
;
8255 IDirectDrawMediaStream
*ddraw_stream
;
8256 IMediaFilter
*graph_media_filter
;
8257 STREAM_TIME filter_start_time
;
8258 IMemInputPin
*mem_input_pin
;
8259 IMediaStreamFilter
*filter
;
8260 struct testfilter source
;
8261 struct testclock clock
;
8262 STREAM_TIME start_time
;
8263 STREAM_TIME end_time
;
8264 IGraphBuilder
*graph
;
8265 IMediaStream
*stream
;
8266 VIDEOINFO video_info
;
8273 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
8274 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8275 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
8276 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8277 ok(!!filter
, "Expected non-null filter.\n");
8278 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
8279 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8280 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
8281 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8282 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
8283 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8284 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
8285 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8286 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
8287 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8288 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
8289 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&graph_media_filter
);
8290 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8291 testfilter_init(&source
);
8292 source
.IQualityControl_iface
.lpVtbl
= &testsource_qc_vtbl
;
8293 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
8294 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8295 testclock_init(&clock
);
8296 cookie
.advise_time_called_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
8297 ok(cookie
.advise_time_called_event
!= NULL
, "Expected non-NULL event.");
8299 video_info
= rgb32_video_info
;
8300 video_info
.bmiHeader
.biWidth
= 3;
8301 video_info
.bmiHeader
.biHeight
= 1;
8303 mt
.pbFormat
= (BYTE
*)&video_info
;
8304 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
8305 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8307 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample
);
8308 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8310 /* There are no quality control messages without a sync source. */
8311 hr
= IMediaFilter_SetSyncSource(graph_media_filter
, NULL
);
8312 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8314 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8315 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8317 source
.qc_notify_sender
= (IBaseFilter
*)0xdeadbeef;
8318 source
.qc_notify_quality
.Type
= Flood
;
8319 source
.qc_notify_quality
.Proportion
= 0xdeadbeef;
8320 source
.qc_notify_quality
.Late
= 0xdeadbeef;
8321 source
.qc_notify_quality
.TimeStamp
= 0xdeadbeef;
8323 thread
= ammediastream_async_receive_time(&source
,
8324 11111111, 11111111, test_data
, sizeof(test_data
));
8325 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8327 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8328 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8330 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8331 CloseHandle(thread
);
8333 ok(source
.qc_notify_sender
== (IBaseFilter
*)0xdeadbeef, "Got sender %p.\n",
8334 source
.qc_notify_sender
);
8335 ok(source
.qc_notify_quality
.Type
== Flood
, "Got type %d.\n",
8336 source
.qc_notify_quality
.Type
);
8337 ok(source
.qc_notify_quality
.Proportion
== 0xdeadbeef, "Got proportion %ld.\n",
8338 source
.qc_notify_quality
.Proportion
);
8339 ok(source
.qc_notify_quality
.Late
== 0xdeadbeef,
8340 "Got late %s.\n", wine_dbgstr_longlong(source
.qc_notify_quality
.Late
));
8341 ok(source
.qc_notify_quality
.TimeStamp
== 0xdeadbeef, "Got time stamp %s.\n",
8342 wine_dbgstr_longlong(source
.qc_notify_quality
.TimeStamp
));
8344 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8345 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8347 hr
= IMediaFilter_SetSyncSource(graph_media_filter
, &clock
.IReferenceClock_iface
);
8348 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8350 clock
.time
= 12345678;
8352 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8353 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8355 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &filter_start_time
);
8356 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8358 /* Quality control message is sent on update completion, q.Late is computed
8359 * as a difference between sample start time and update completion time. */
8361 /* Test Update() before Reveive(). */
8362 source
.qc_notify_sender
= (IBaseFilter
*)0xdeadbeef;
8363 source
.qc_notify_quality
.Type
= Flood
;
8364 source
.qc_notify_quality
.Proportion
= 0xdeadbeef;
8365 source
.qc_notify_quality
.Late
= 0xdeadbeef;
8366 source
.qc_notify_quality
.TimeStamp
= 0xdeadbeef;
8368 clock
.time
= 12345678 - filter_start_time
+ 11111111;
8370 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8371 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
8373 clock
.advise_time_cookie
= &cookie
;
8374 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 100000;
8376 start_time
= 11111111 + 200000;
8377 end_time
= 11111111 + 200000;
8378 thread
= ammediastream_async_receive_time(&source
,
8379 start_time
, end_time
, test_data
, sizeof(test_data
));
8380 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Wait timed out.\n");
8382 ok(source
.qc_notify_sender
== (IBaseFilter
*)0xdeadbeef, "Got sender %p.\n",
8383 source
.qc_notify_sender
);
8384 ok(source
.qc_notify_quality
.Type
== Flood
, "Got type %d.\n",
8385 source
.qc_notify_quality
.Type
);
8386 ok(source
.qc_notify_quality
.Proportion
== 0xdeadbeef, "Got proportion %ld.\n",
8387 source
.qc_notify_quality
.Proportion
);
8388 ok(source
.qc_notify_quality
.Late
== 0xdeadbeef,
8389 "Got late %s.\n", wine_dbgstr_longlong(source
.qc_notify_quality
.Late
));
8390 ok(source
.qc_notify_quality
.TimeStamp
== 0xdeadbeef, "Got time stamp %s.\n",
8391 wine_dbgstr_longlong(source
.qc_notify_quality
.TimeStamp
));
8393 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 200000;
8395 SetEvent(cookie
.event
);
8397 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8398 CloseHandle(thread
);
8400 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample
, 0, 0);
8401 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8403 ok(source
.qc_notify_sender
== (IBaseFilter
*)filter
, "Got sender %p.\n",
8404 source
.qc_notify_sender
);
8405 ok(source
.qc_notify_quality
.Type
== Famine
, "Got type %d.\n",
8406 source
.qc_notify_quality
.Type
);
8407 ok(source
.qc_notify_quality
.Proportion
== 1000, "Got proportion %ld.\n",
8408 source
.qc_notify_quality
.Proportion
);
8409 ok(source
.qc_notify_quality
.Late
== 0, "Got late %s.\n",
8410 wine_dbgstr_longlong(source
.qc_notify_quality
.Late
));
8411 ok(source
.qc_notify_quality
.TimeStamp
== start_time
, "Got time stamp %s.\n",
8412 wine_dbgstr_longlong(source
.qc_notify_quality
.TimeStamp
));
8414 /* Test Update() after Reveive(). */
8415 source
.qc_notify_sender
= (IBaseFilter
*)0xdeadbeef;
8416 source
.qc_notify_quality
.Type
= Flood
;
8417 source
.qc_notify_quality
.Proportion
= 0xdeadbeef;
8418 source
.qc_notify_quality
.Late
= 0xdeadbeef;
8419 source
.qc_notify_quality
.TimeStamp
= 0xdeadbeef;
8421 clock
.advise_time_cookie
= &cookie
;
8422 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 300000;
8424 start_time
= 11111111 + 400000;
8425 end_time
= 11111111 + 400000;
8426 thread
= ammediastream_async_receive_time(&source
,
8427 start_time
, end_time
, test_data
, sizeof(test_data
));
8428 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Wait timed out.\n");
8430 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 400000;
8431 SetEvent(cookie
.event
);
8433 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8435 ok(source
.qc_notify_sender
== (IBaseFilter
*)0xdeadbeef, "Got sender %p.\n",
8436 source
.qc_notify_sender
);
8437 ok(source
.qc_notify_quality
.Type
== Flood
, "Got type %d.\n",
8438 source
.qc_notify_quality
.Type
);
8439 ok(source
.qc_notify_quality
.Proportion
== 0xdeadbeef, "Got proportion %ld.\n",
8440 source
.qc_notify_quality
.Proportion
);
8441 ok(source
.qc_notify_quality
.Late
== 0xdeadbeef,
8442 "Got late %s.\n", wine_dbgstr_longlong(source
.qc_notify_quality
.Late
));
8443 ok(source
.qc_notify_quality
.TimeStamp
== 0xdeadbeef, "Got time stamp %s.\n",
8444 wine_dbgstr_longlong(source
.qc_notify_quality
.TimeStamp
));
8446 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 500000;
8448 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8449 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8451 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8452 CloseHandle(thread
);
8454 ok(source
.qc_notify_sender
== (IBaseFilter
*)filter
, "Got sender %p.\n",
8455 source
.qc_notify_sender
);
8456 ok(source
.qc_notify_quality
.Type
== Famine
, "Got type %d.\n",
8457 source
.qc_notify_quality
.Type
);
8458 ok(source
.qc_notify_quality
.Proportion
== 1000, "Got proportion %ld.\n",
8459 source
.qc_notify_quality
.Proportion
);
8460 ok(source
.qc_notify_quality
.Late
== 100000, "Got late %s.\n",
8461 wine_dbgstr_longlong(source
.qc_notify_quality
.Late
));
8462 ok(source
.qc_notify_quality
.TimeStamp
== start_time
, "Got time stamp %s.\n",
8463 wine_dbgstr_longlong(source
.qc_notify_quality
.TimeStamp
));
8465 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8466 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8467 IGraphBuilder_Disconnect(graph
, pin
);
8468 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
8470 CloseHandle(cookie
.advise_time_called_event
);
8471 ref
= IDirectDrawStreamSample_Release(stream_sample
);
8472 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8473 ref
= IAMMultiMediaStream_Release(mmstream
);
8474 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8475 IMediaFilter_Release(graph_media_filter
);
8476 ref
= IGraphBuilder_Release(graph
);
8477 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8478 ref
= IMediaStreamFilter_Release(filter
);
8479 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8481 IMemInputPin_Release(mem_input_pin
);
8482 IDirectDrawMediaStream_Release(ddraw_stream
);
8483 ref
= IMediaStream_Release(stream
);
8484 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8487 static void test_ddrawstreamsample_get_media_stream(void)
8489 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
8490 IDirectDrawMediaStream
*ddraw_stream
;
8491 IDirectDrawStreamSample
*sample
;
8492 IMediaStream
*stream
, *stream2
;
8497 hr
= DirectDrawCreate(NULL
, &ddraw
, NULL
);
8498 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8500 hr
= IDirectDraw_SetCooperativeLevel(ddraw
, NULL
, DDSCL_NORMAL
);
8501 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8503 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
8504 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8506 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, (IUnknown
*)ddraw
, &MSPID_PrimaryVideo
, 0, &stream
);
8507 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8509 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
8510 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8512 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &sample
);
8513 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8515 /* Crashes on native. */
8518 hr
= IDirectDrawStreamSample_GetMediaStream(sample
, NULL
);
8519 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
8522 EXPECT_REF(stream
, 4);
8523 hr
= IDirectDrawStreamSample_GetMediaStream(sample
, &stream2
);
8524 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8525 ok(stream2
== stream
, "Expected stream %p, got %p.\n", stream
, stream2
);
8526 EXPECT_REF(stream
, 5);
8527 IMediaStream_Release(stream2
);
8528 EXPECT_REF(stream
, 4);
8530 IDirectDrawMediaStream_Release(ddraw_stream
);
8531 ref
= IDirectDrawStreamSample_Release(sample
);
8532 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8533 ref
= IAMMultiMediaStream_Release(mmstream
);
8534 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8535 ref
= IMediaStream_Release(stream
);
8536 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8537 ref
= IDirectDraw_Release(ddraw
);
8538 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8541 static void test_ddrawstreamsample_update(void)
8543 static const BYTE initial_data
[] =
8545 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
8547 static const BYTE test_data
[] =
8549 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
8550 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
8552 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
8553 IDirectDrawStreamSample
*stream_sample
;
8554 struct advise_time_cookie cookie
= {0};
8555 IDirectDrawMediaStream
*ddraw_stream
;
8556 IMediaControl
*media_control
;
8557 IDirectDrawSurface
*surface
;
8558 IMemInputPin
*mem_input_pin
;
8559 IMediaSample
*media_sample
;
8560 IMediaFilter
*media_filter
;
8561 REFERENCE_TIME start_time
;
8562 REFERENCE_TIME end_time
;
8563 struct testfilter source
;
8564 struct testclock clock
;
8565 IGraphBuilder
*graph
;
8566 IMediaStream
*stream
;
8567 VIDEOINFO video_info
;
8579 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
8580 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8581 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
8582 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8583 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
8584 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8585 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
8586 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8587 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
8588 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8589 hr
= IDirectDrawMediaStream_GetDirectDraw(ddraw_stream
, &ddraw
);
8590 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8591 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
8592 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8593 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
8594 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaControl
, (void **)&media_control
);
8595 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8596 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
8597 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8598 testfilter_init(&source
);
8599 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
8600 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8601 testclock_init(&clock
);
8602 event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
8603 ok(event
!= NULL
, "Expected non-NULL event.");
8604 cookie
.advise_time_called_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
8605 ok(cookie
.advise_time_called_event
!= NULL
, "Expected non-NULL event.");
8607 hr
= IMediaFilter_SetSyncSource(media_filter
, NULL
);
8608 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8610 desc
= rgb24_format
;
8611 desc
.dwFlags
|= DDSD_WIDTH
| DDSD_HEIGHT
| DDSD_CAPS
;
8614 desc
.ddsCaps
.dwCaps
= DDSCAPS_SYSTEMMEMORY
| DDSCAPS_OFFSCREENPLAIN
;
8615 hr
= IDirectDraw_CreateSurface(ddraw
, &desc
, &surface
, NULL
);
8616 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8617 /* Make the rect width equal to the surface width, as the native
8618 * implementation incorrectly handles rects that are not full-width
8619 * when the ddraw stream's custom allocator is not used. */
8620 SetRect(&rect
, 0, 1, 4, 3);
8621 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, surface
, &rect
, 0, &stream_sample
);
8622 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8624 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, event
, apc_func
, 0);
8625 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
8627 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8628 ok(hr
== MS_E_NOTRUNNING
, "Got hr %#lx.\n", hr
);
8630 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8631 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8633 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8634 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
8636 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8637 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8638 video_info
= rgb24_video_info
;
8639 video_info
.bmiHeader
.biWidth
= 4;
8640 video_info
.bmiHeader
.biHeight
= -2;
8642 mt
.pbFormat
= (BYTE
*)&video_info
;
8643 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
8644 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8646 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8647 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8649 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8650 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8651 for (i
= 0; i
< 5; ++i
)
8652 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8653 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8654 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8656 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8658 ammediastream_mem_input_pin
= mem_input_pin
;
8659 ammediastream_media_sample
= media_sample
;
8660 ammediastream_sleep_time
= 0;
8661 ammediastream_expected_hr
= S_OK
;
8662 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
8665 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8666 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8667 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8668 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8669 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8670 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8671 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8672 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8673 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8674 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8675 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8677 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8678 CloseHandle(thread
);
8680 ref
= IMediaSample_Release(media_sample
);
8681 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8683 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8684 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8685 IGraphBuilder_Disconnect(graph
, pin
);
8686 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
8687 video_info
= rgb24_video_info
;
8688 video_info
.bmiHeader
.biWidth
= 4;
8689 video_info
.bmiHeader
.biHeight
= 2;
8691 mt
.pbFormat
= (BYTE
*)&video_info
;
8692 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
8693 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8694 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8695 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8697 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8698 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8699 for (i
= 0; i
< 5; ++i
)
8700 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8701 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8702 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8704 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8706 ammediastream_mem_input_pin
= mem_input_pin
;
8707 ammediastream_media_sample
= media_sample
;
8708 ammediastream_sleep_time
= 0;
8709 ammediastream_expected_hr
= S_OK
;
8710 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
8713 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8714 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8715 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8716 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8717 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8718 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8719 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8720 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8721 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8722 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8723 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8725 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8726 CloseHandle(thread
);
8728 ref
= IMediaSample_Release(media_sample
);
8729 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8731 hr
= IPin_EndOfStream(pin
);
8732 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8734 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8735 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
8737 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8738 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8739 hr
= IMediaControl_Pause(media_control
);
8740 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8742 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8743 ok(hr
== MS_E_NOTRUNNING
, "Got hr %#lx.\n", hr
);
8745 hr
= IMediaControl_Stop(media_control
);
8746 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8747 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8748 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8750 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8751 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8752 for (i
= 0; i
< 5; ++i
)
8753 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8754 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8755 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8757 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8759 ammediastream_mem_input_pin
= mem_input_pin
;
8760 ammediastream_media_sample
= media_sample
;
8761 ammediastream_sleep_time
= 100;
8762 ammediastream_expected_hr
= S_OK
;
8763 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
8765 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8766 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8767 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8768 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8769 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8770 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8771 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8772 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8773 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8774 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8775 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8777 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8778 CloseHandle(thread
);
8780 ref
= IMediaSample_Release(media_sample
);
8781 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8783 ammediastream_pin
= pin
;
8784 ammediastream_sleep_time
= 100;
8785 ammediastream_expected_hr
= S_OK
;
8786 thread
= CreateThread(NULL
, 0, ammediastream_end_of_stream
, NULL
, 0, NULL
);
8788 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8789 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
8791 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8792 CloseHandle(thread
);
8794 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8795 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8796 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8797 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8799 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8800 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8801 for (i
= 0; i
< 5; ++i
)
8802 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8803 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8804 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8806 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8808 ammediastream_mem_input_pin
= mem_input_pin
;
8809 ammediastream_media_sample
= media_sample
;
8810 ammediastream_sleep_time
= 100;
8811 ammediastream_expected_hr
= S_OK
;
8812 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
8814 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8815 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8816 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8817 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8818 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8819 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8820 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8821 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8822 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8823 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8824 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8826 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8827 CloseHandle(thread
);
8829 ref
= IMediaSample_Release(media_sample
);
8830 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8832 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
8833 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
8835 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8836 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8837 for (i
= 0; i
< 5; ++i
)
8838 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8839 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8840 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8842 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8843 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8844 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8845 ref
= IMediaSample_Release(media_sample
);
8846 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8848 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8849 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8850 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8851 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8852 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8853 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8854 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8855 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8856 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8858 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8859 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8860 for (i
= 0; i
< 5; ++i
)
8861 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8862 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8863 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8865 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8866 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8867 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8868 ref
= IMediaSample_Release(media_sample
);
8869 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8871 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8872 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8873 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8874 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8875 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8876 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8877 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8878 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8879 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8881 hr
= IPin_EndOfStream(pin
);
8882 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8884 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8885 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8886 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8887 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8889 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, event
, NULL
, 0);
8890 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
8892 ok(WaitForSingleObject(event
, 0) == WAIT_TIMEOUT
, "Event should not be signaled.\n");
8894 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8895 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
8896 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8897 ref
= IMediaSample_Release(media_sample
);
8898 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8900 ok(WaitForSingleObject(event
, 0) == 0, "Event should be signaled.\n");
8902 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8903 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
8904 EXPECT_REF(stream_sample
, 1);
8906 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8907 ok(hr
== MS_E_BUSY
, "Got hr %#lx.\n", hr
);
8909 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8910 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8911 hr
= IMediaFilter_SetSyncSource(media_filter
, &clock
.IReferenceClock_iface
);
8912 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8913 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8914 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8916 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8917 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8918 for (i
= 0; i
< 5; ++i
)
8919 memcpy((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12);
8920 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8921 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8923 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
8924 ok(hr
== MS_E_BUSY
, "Got hr %#lx.\n", hr
);
8926 clock
.advise_time_cookie
= &cookie
;
8928 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
8929 start_time
= 11111111;
8930 end_time
= 11111111;
8931 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
8932 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8934 ammediastream_mem_input_pin
= mem_input_pin
;
8935 ammediastream_media_sample
= media_sample
;
8936 ammediastream_sleep_time
= 0;
8937 ammediastream_expected_hr
= S_OK
;
8938 thread
= CreateThread(NULL
, 0, ammediastream_receive
, NULL
, 0, NULL
);
8939 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
8940 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
8942 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8943 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8944 for (i
= 0; i
< 5; ++i
)
8945 ok(memcmp((BYTE
*)desc
.lpSurface
+ i
* desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8946 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8947 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8949 SetEvent(cookie
.event
);
8951 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
8952 CloseHandle(thread
);
8954 hr
= IDirectDrawSurface_Lock(surface
, NULL
, &desc
, 0, NULL
);
8955 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8956 ok(memcmp((BYTE
*)desc
.lpSurface
+ 0 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8957 ok(memcmp((BYTE
*)desc
.lpSurface
+ 1 * desc
.u1
.lPitch
, &test_data
[12], 12) == 0, "Sample data didn't match.\n");
8958 ok(memcmp((BYTE
*)desc
.lpSurface
+ 2 * desc
.u1
.lPitch
, &test_data
[0], 12) == 0, "Sample data didn't match.\n");
8959 ok(memcmp((BYTE
*)desc
.lpSurface
+ 3 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8960 ok(memcmp((BYTE
*)desc
.lpSurface
+ 4 * desc
.u1
.lPitch
, initial_data
, 12) == 0, "Sample data didn't match.\n");
8961 hr
= IDirectDrawSurface_Unlock(surface
, desc
.lpSurface
);
8962 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8964 ref
= IMediaSample_Release(media_sample
);
8965 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8967 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8968 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8969 IGraphBuilder_Disconnect(graph
, pin
);
8970 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
8971 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
8972 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8974 hr
= IDirectDrawStreamSample_Update(stream_sample
, 0, NULL
, NULL
, 0);
8975 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
8977 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
8978 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
8980 CloseHandle(cookie
.advise_time_called_event
);
8982 ref
= IDirectDrawStreamSample_Release(stream_sample
);
8983 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8984 ref
= IDirectDrawSurface_Release(surface
);
8985 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8986 ref
= IAMMultiMediaStream_Release(mmstream
);
8987 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8988 IMediaControl_Release(media_control
);
8989 IMediaFilter_Release(media_filter
);
8990 ref
= IGraphBuilder_Release(graph
);
8991 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8993 IMemInputPin_Release(mem_input_pin
);
8994 IDirectDrawMediaStream_Release(ddraw_stream
);
8995 ref
= IMediaStream_Release(stream
);
8996 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
8997 ref
= IDirectDraw_Release(ddraw
);
8998 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9001 static void test_ddrawstreamsample_completion_status(void)
9003 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
9004 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
9005 struct advise_time_cookie cookie
= { 0 };
9006 IDirectDrawStreamSample
*stream_sample1
;
9007 IDirectDrawStreamSample
*stream_sample2
;
9008 IDirectDrawMediaStream
*ddraw_stream
;
9009 STREAM_TIME filter_start_time
;
9010 IMediaStreamFilter
*filter
;
9011 IMediaSample
*media_sample
;
9012 IMediaFilter
*media_filter
;
9013 struct testfilter source
;
9014 struct testclock clock
;
9015 VIDEOINFO video_info
;
9016 IGraphBuilder
*graph
;
9017 IMediaStream
*stream
;
9024 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
9025 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9026 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
9027 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9028 ok(!!filter
, "Expected non-null filter.\n");
9029 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
9030 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9031 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
9032 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9033 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
9034 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9035 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
9036 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9037 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
9038 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&media_filter
);
9039 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9040 testfilter_init(&source
);
9041 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
9042 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9043 testclock_init(&clock
);
9044 cookie
.advise_time_called_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
9046 hr
= IMediaFilter_SetSyncSource(media_filter
, NULL
);
9047 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9049 video_info
= rgb32_video_info
;
9050 video_info
.bmiHeader
.biWidth
= 3;
9051 video_info
.bmiHeader
.biHeight
= 1;
9053 mt
.pbFormat
= (BYTE
*)&video_info
;
9054 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
9055 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9056 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
9057 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9059 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample1
);
9060 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9061 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample2
);
9062 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9064 /* Initial status is S_OK. */
9065 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9066 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9068 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
9069 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9071 /* Update changes the status to MS_S_PENDING. */
9072 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9073 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9075 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9076 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9078 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, 100);
9079 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9081 /* Each Receive call changes the status of one queued sample to S_OK in the same order Update was called. */
9082 hr
= IDirectDrawStreamSample_Update(stream_sample2
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9083 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9085 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
9086 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9088 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9089 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
9090 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9091 ref
= IMediaSample_Release(media_sample
);
9092 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9094 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9095 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9097 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
9098 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9100 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
9101 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9103 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9104 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
9105 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9106 ref
= IMediaSample_Release(media_sample
);
9107 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9109 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
9110 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9112 /* COMPSTAT_NOUPDATEOK removes the sample from the queue and changes the status to MS_S_NOUPDATE. */
9113 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9114 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9116 hr
= IDirectDrawStreamSample_Update(stream_sample2
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9117 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9119 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
, 0);
9120 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9122 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
9123 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9125 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9126 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
9127 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9128 ref
= IMediaSample_Release(media_sample
);
9129 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9131 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9132 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9134 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
9135 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9137 /* COMPSTAT_ABORT removes the sample from the queue and changes the status to MS_S_NOUPDATE. */
9138 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9139 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9141 hr
= IDirectDrawStreamSample_Update(stream_sample2
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9142 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9144 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_ABORT
, 0);
9145 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9147 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
9148 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9150 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9151 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
9152 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9153 ref
= IMediaSample_Release(media_sample
);
9154 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9156 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9157 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9159 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
9160 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9162 /* COMPSTAT_WAIT has no effect when combined with COMPSTAT_NOUPDATEOK. */
9163 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9164 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9166 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
| COMPSTAT_WAIT
, INFINITE
);
9167 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9169 /* COMPSTAT_WAIT has no effect when combined with COMPSTAT_ABORT. */
9170 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9171 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9173 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_ABORT
| COMPSTAT_WAIT
, INFINITE
);
9174 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9176 /* EndOfStream changes the status of the queued samples to MS_S_ENDOFSTREAM. */
9177 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9178 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9180 hr
= IPin_EndOfStream(pin
);
9181 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9183 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9184 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
9186 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
9187 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
9189 /* Update after EndOfStream changes the status to MS_S_ENDOFSTREAM. */
9190 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9191 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
9193 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9194 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
9196 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
9197 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
9199 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
9200 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9201 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
9202 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9204 /* Continuous update can be canceled by COMPSTAT_NOUPDATEOK. */
9205 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
9206 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9208 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
, 0);
9209 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9211 /* Continuous update can be canceled by COMPSTAT_ABORT. */
9212 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
9213 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9215 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_ABORT
, 0);
9216 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9218 /* If a sample is in countinuous update mode, when Receive is called it's status remains MS_S_PENDING
9219 * and the sample is moved to the end of the queue. */
9220 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
9221 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9223 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
9224 ok(hr
== MS_E_BUSY
, "Got hr %#lx.\n", hr
);
9226 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9227 ok(hr
== MS_E_BUSY
, "Got hr %#lx.\n", hr
);
9229 hr
= IDirectDrawStreamSample_Update(stream_sample2
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9230 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9232 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9233 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9235 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9236 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
9237 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9238 ref
= IMediaSample_Release(media_sample
);
9239 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9241 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9242 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9244 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
9245 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9247 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9248 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
9249 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9250 ref
= IMediaSample_Release(media_sample
);
9251 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9253 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9254 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9256 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample2
, 0, 0);
9257 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9259 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
, 0);
9260 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9262 /* In continuous update mode, flushing does not affect the status. */
9263 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
9264 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9266 hr
= IPin_BeginFlush(pin
);
9267 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9269 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9270 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9272 hr
= IPin_EndFlush(pin
);
9273 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9275 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9276 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9278 /* In continuous update mode, stopping and running the stream does not affect the status. */
9279 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
9280 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9282 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9283 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9285 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
9286 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9288 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9289 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9291 /* In continuous update mode, EndOfStream changes the status to MS_S_ENDOFSTREAM. */
9292 hr
= IPin_EndOfStream(pin
);
9293 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9295 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9296 ok(hr
== MS_S_ENDOFSTREAM
, "Got hr %#lx.\n", hr
);
9298 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
9299 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9300 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
9301 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9303 /* COMPSTAT_WAIT resets the sample to the non-continuous update mode. */
9304 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
9305 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9307 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, 0);
9308 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9310 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9311 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
9312 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9313 ref
= IMediaSample_Release(media_sample
);
9314 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9316 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9317 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9319 /* In continuous update mode, CompletionStatus with COMPSTAT_WAIT returns when Receive is called. */
9320 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
| SSUPDATE_CONTINUOUS
, NULL
, NULL
, 0);
9321 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9323 streamsample_sample
= (IStreamSample
*)stream_sample1
;
9324 streamsample_flags
= COMPSTAT_WAIT
;
9325 streamsample_timeout
= INFINITE
;
9326 streamsample_expected_hr
= S_OK
;
9327 thread
= CreateThread(NULL
, 0, streamsample_completion_status
, NULL
, 0, NULL
);
9328 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "CompletionStatus returned prematurely.\n");
9330 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9331 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
9332 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9333 ref
= IMediaSample_Release(media_sample
);
9334 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9336 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
9337 CloseHandle(thread
);
9339 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9340 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9342 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
9343 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9344 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
9345 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9347 /* CompletionStatus with COMPSTAT_WAIT returns when Receive is called. */
9348 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9349 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9351 streamsample_sample
= (IStreamSample
*)stream_sample1
;
9352 streamsample_flags
= COMPSTAT_WAIT
;
9353 streamsample_timeout
= INFINITE
;
9354 streamsample_expected_hr
= S_OK
;
9355 thread
= CreateThread(NULL
, 0, streamsample_completion_status
, NULL
, 0, NULL
);
9356 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "CompletionStatus returned prematurely.\n");
9358 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9359 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
9360 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9361 ref
= IMediaSample_Release(media_sample
);
9362 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9364 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
9365 CloseHandle(thread
);
9367 /* CompletionStatus with COMPSTAT_WAIT returns when EndOfStream is called. */
9368 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9369 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9371 streamsample_sample
= (IStreamSample
*)stream_sample1
;
9372 streamsample_flags
= COMPSTAT_WAIT
;
9373 streamsample_timeout
= INFINITE
;
9374 streamsample_expected_hr
= MS_S_ENDOFSTREAM
;
9375 thread
= CreateThread(NULL
, 0, streamsample_completion_status
, NULL
, 0, NULL
);
9376 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "CompletionStatus returned prematurely.\n");
9378 hr
= IPin_EndOfStream(pin
);
9379 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9381 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
9382 CloseHandle(thread
);
9384 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
9385 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9386 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
9387 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9389 /* Stopping and running the stream does not affect the status and does not remove the sample from the queue. */
9390 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9391 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9393 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
9394 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9396 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9397 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9399 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
9400 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9402 media_sample
= ammediastream_allocate_sample(&source
, test_data
, 6);
9403 hr
= IMemInputPin_Receive(source
.source
.pMemInputPin
, media_sample
);
9404 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9405 ref
= IMediaSample_Release(media_sample
);
9406 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9408 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9409 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9411 /* When the stream is stopped Update does not change the status. */
9412 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
9413 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9415 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9416 ok(hr
== MS_E_NOTRUNNING
, "Got hr %#lx.\n", hr
);
9418 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9419 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9421 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_WAIT
, INFINITE
);
9422 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9424 /* When the wait time is less than 1ms the sample is updated immediately. */
9425 hr
= IMediaFilter_SetSyncSource(media_filter
, &clock
.IReferenceClock_iface
);
9426 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9428 clock
.time
= 12345678;
9430 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
9431 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9433 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &filter_start_time
);
9434 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9436 clock
.time
= 12345678 - filter_start_time
+ 11111111;
9438 clock
.advise_time_cookie
= &cookie
;
9440 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9441 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9443 thread
= ammediastream_async_receive_time(&source
,
9444 11111111 + 9999, 11111111 + 9999, test_data
, sizeof(test_data
));
9445 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
9446 CloseHandle(thread
);
9448 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, INFINITE
);
9449 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9451 /* When the wait time is 1ms or greater AdviseTime is called
9452 * with base equal to the sample start time and offset equal to the filter start time. */
9453 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9454 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9456 thread
= ammediastream_async_receive_time(&source
,
9457 11111111 + 10000, 11111111 + 10000, test_data
, sizeof(test_data
));
9458 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
9459 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9461 ok(cookie
.base
== 11111111 + 10000, "Got base %s.\n", wine_dbgstr_longlong(cookie
.base
));
9462 ok(cookie
.offset
== 12345678 - filter_start_time
, "Got offset %s.\n", wine_dbgstr_longlong(cookie
.offset
));
9464 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9465 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9467 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 10000;
9468 SetEvent(cookie
.event
);
9470 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
9471 CloseHandle(thread
);
9473 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9474 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9476 /* NewSegment does not affect the values passed to AdviseTime. */
9477 hr
= IPin_NewSegment(pin
, 22222222, 33333333, 1.0);
9478 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9480 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9481 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9483 thread
= ammediastream_async_receive_time(&source
,
9484 11111111 + 20000, 11111111 + 20000, test_data
, sizeof(test_data
));
9485 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
9486 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9488 ok(cookie
.base
== 11111111 + 20000, "Got base %s.\n", wine_dbgstr_longlong(cookie
.base
));
9489 ok(cookie
.offset
== 12345678 - filter_start_time
, "Got offset %s.\n", wine_dbgstr_longlong(cookie
.offset
));
9491 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
, 0);
9492 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9494 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9496 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 20000;
9497 SetEvent(cookie
.event
);
9499 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9501 /* COMPSTAT_NOUPDATEOK does not cause Receive to return.
9502 * Receive waits for the next sample to be queued and updates it. */
9503 hr
= IDirectDrawStreamSample_Update(stream_sample1
, 0, NULL
, NULL
, 0);
9504 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9506 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
9507 CloseHandle(thread
);
9509 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9510 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9512 thread
= ammediastream_async_receive_time(&source
,
9513 11111111 + 30000, 11111111 + 30000, test_data
, sizeof(test_data
));
9514 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
9515 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9517 ok(cookie
.base
== 11111111 + 30000, "Got base %s.\n", wine_dbgstr_longlong(cookie
.base
));
9518 ok(cookie
.offset
== 12345678 - filter_start_time
, "Got offset %s.\n", wine_dbgstr_longlong(cookie
.offset
));
9520 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_NOUPDATEOK
| COMPSTAT_WAIT
, INFINITE
);
9521 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9523 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9525 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 30000;
9526 SetEvent(cookie
.event
);
9528 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9530 hr
= IDirectDrawStreamSample_Update(stream_sample1
, 0, NULL
, NULL
, 0);
9531 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9533 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
9534 CloseHandle(thread
);
9536 /* COMPSTAT_ABORT does not cause Receive to return.
9537 * Receive waits for the next sample to be queued and updates it. */
9538 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9539 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9541 thread
= ammediastream_async_receive_time(&source
,
9542 11111111 + 40000, 11111111 + 40000, test_data
, sizeof(test_data
));
9543 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
9544 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9546 ok(cookie
.base
== 11111111 + 40000, "Got base %s.\n", wine_dbgstr_longlong(cookie
.base
));
9547 ok(cookie
.offset
== 12345678 - filter_start_time
, "Got offset %s.\n", wine_dbgstr_longlong(cookie
.offset
));
9549 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, COMPSTAT_ABORT
, 0);
9550 ok(hr
== MS_S_NOUPDATE
, "Got hr %#lx.\n", hr
);
9552 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9554 clock
.time
= 12345678 - filter_start_time
+ 11111111 + 40000;
9555 SetEvent(cookie
.event
);
9557 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9559 hr
= IDirectDrawStreamSample_Update(stream_sample1
, 0, NULL
, NULL
, 0);
9560 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9562 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
9563 CloseHandle(thread
);
9565 /* Stopping the stream causes Receive to return and leaves the sample with MS_S_PENDING status. */
9566 hr
= IDirectDrawStreamSample_Update(stream_sample1
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9567 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9569 thread
= ammediastream_async_receive_time(&source
,
9570 11111111 + 50000, 11111111 + 50000, test_data
, sizeof(test_data
));
9571 ok(!WaitForSingleObject(cookie
.advise_time_called_event
, 2000), "Expected AdviseTime to be called.\n");
9572 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Receive returned prematurely.\n");
9574 ok(cookie
.base
== 11111111 + 50000, "Got base %s.\n", wine_dbgstr_longlong(cookie
.base
));
9575 ok(cookie
.offset
== 12345678 - filter_start_time
, "Got offset %s.\n", wine_dbgstr_longlong(cookie
.offset
));
9577 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
9578 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9580 ok(!WaitForSingleObject(thread
, 2000), "Wait timed out.\n");
9581 CloseHandle(thread
);
9583 hr
= IDirectDrawStreamSample_CompletionStatus(stream_sample1
, 0, 0);
9584 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9586 IGraphBuilder_Disconnect(graph
, pin
);
9587 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
9589 CloseHandle(cookie
.advise_time_called_event
);
9590 ref
= IDirectDrawStreamSample_Release(stream_sample1
);
9591 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9592 ref
= IDirectDrawStreamSample_Release(stream_sample2
);
9593 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9594 ref
= IAMMultiMediaStream_Release(mmstream
);
9595 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9596 IMediaFilter_Release(media_filter
);
9597 ref
= IGraphBuilder_Release(graph
);
9598 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9599 ref
= IMediaStreamFilter_Release(filter
);
9600 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9602 IDirectDrawMediaStream_Release(ddraw_stream
);
9603 ref
= IMediaStream_Release(stream
);
9604 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9607 static void test_ddrawstreamsample_get_sample_times(void)
9609 static const BYTE test_data
[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
9610 IAMMultiMediaStream
*mmstream
= create_ammultimediastream();
9611 IDirectDrawStreamSample
*stream_sample
;
9612 IMediaFilter
*graph_media_filter
;
9613 IDirectDrawMediaStream
*ddraw_stream
;
9614 STREAM_TIME filter_start_time
;
9615 IMemInputPin
*mem_input_pin
;
9616 IMediaStreamFilter
*filter
;
9617 IMediaSample
*media_sample
;
9618 struct testfilter source
;
9619 STREAM_TIME current_time
;
9620 struct testclock clock
;
9621 STREAM_TIME start_time
;
9622 STREAM_TIME end_time
;
9623 IGraphBuilder
*graph
;
9624 IMediaStream
*stream
;
9625 VIDEOINFO video_info
;
9631 hr
= IAMMultiMediaStream_Initialize(mmstream
, STREAMTYPE_READ
, 0, NULL
);
9632 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9633 hr
= IAMMultiMediaStream_GetFilter(mmstream
, &filter
);
9634 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9635 ok(!!filter
, "Expected non-null filter.\n");
9636 hr
= IAMMultiMediaStream_AddMediaStream(mmstream
, NULL
, &MSPID_PrimaryVideo
, 0, &stream
);
9637 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9638 hr
= IMediaStream_QueryInterface(stream
, &IID_IDirectDrawMediaStream
, (void **)&ddraw_stream
);
9639 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9640 hr
= IMediaStream_QueryInterface(stream
, &IID_IPin
, (void **)&pin
);
9641 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9642 hr
= IMediaStream_QueryInterface(stream
, &IID_IMemInputPin
, (void **)&mem_input_pin
);
9643 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9644 hr
= IAMMultiMediaStream_GetFilterGraph(mmstream
, &graph
);
9645 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9646 ok(graph
!= NULL
, "Expected non-NULL graph.\n");
9647 hr
= IGraphBuilder_QueryInterface(graph
, &IID_IMediaFilter
, (void **)&graph_media_filter
);
9648 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9649 testfilter_init(&source
);
9650 hr
= IGraphBuilder_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
9651 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9652 testclock_init(&clock
);
9654 video_info
= rgb32_video_info
;
9655 video_info
.bmiHeader
.biWidth
= 3;
9656 video_info
.bmiHeader
.biHeight
= 1;
9658 mt
.pbFormat
= (BYTE
*)&video_info
;
9659 hr
= IGraphBuilder_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
9660 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9662 hr
= IDirectDrawMediaStream_CreateSample(ddraw_stream
, NULL
, NULL
, 0, &stream_sample
);
9663 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9665 clock
.time
= 12345678;
9667 current_time
= 0xdeadbeefdeadbeef;
9668 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
9669 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9670 ok(current_time
== 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time
));
9672 hr
= IMediaFilter_SetSyncSource(graph_media_filter
, &clock
.IReferenceClock_iface
);
9673 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9675 current_time
= 0xdeadbeefdeadbeef;
9676 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
9677 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9678 ok(current_time
== 0, "Got current time %s.\n", wine_dbgstr_longlong(current_time
));
9680 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_RUN
);
9681 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9683 hr
= IMediaStreamFilter_GetCurrentStreamTime(filter
, &filter_start_time
);
9684 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9686 clock
.get_time_hr
= E_FAIL
;
9688 current_time
= 0xdeadbeefdeadbeef;
9689 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
9690 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9691 ok(current_time
== 0xdeadbeefddf15da1 + filter_start_time
, "Expected current time %s, got %s.\n",
9692 wine_dbgstr_longlong(0xdeadbeefddf15da1 + filter_start_time
), wine_dbgstr_longlong(current_time
));
9694 clock
.get_time_hr
= S_OK
;
9696 current_time
= 0xdeadbeefdeadbeef;
9697 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
9698 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9699 ok(current_time
== filter_start_time
, "Expected current time %s, got %s.\n",
9700 wine_dbgstr_longlong(filter_start_time
), wine_dbgstr_longlong(current_time
));
9702 clock
.time
= 23456789;
9704 current_time
= 0xdeadbeefdeadbeef;
9705 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, NULL
, NULL
, ¤t_time
);
9706 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9707 ok(current_time
== filter_start_time
+ 11111111, "Expected current time %s, got %s.\n",
9708 wine_dbgstr_longlong(filter_start_time
+ 11111111), wine_dbgstr_longlong(current_time
));
9710 start_time
= 0xdeadbeefdeadbeef;
9711 end_time
= 0xdeadbeefdeadbeef;
9712 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
9713 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9714 ok(start_time
== 0, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
9715 ok(end_time
== 0, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
9717 hr
= IDirectDrawStreamSample_Update(stream_sample
, SSUPDATE_ASYNC
, NULL
, NULL
, 0);
9718 ok(hr
== MS_S_PENDING
, "Got hr %#lx.\n", hr
);
9720 media_sample
= ammediastream_allocate_sample(&source
, test_data
, sizeof(test_data
));
9721 start_time
= 12345678;
9722 end_time
= 23456789;
9723 hr
= IMediaSample_SetTime(media_sample
, &start_time
, &end_time
);
9724 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9725 hr
= IMemInputPin_Receive(mem_input_pin
, media_sample
);
9726 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9727 IMediaSample_Release(media_sample
);
9729 start_time
= 0xdeadbeefdeadbeef;
9730 end_time
= 0xdeadbeefdeadbeef;
9731 hr
= IDirectDrawStreamSample_GetSampleTimes(stream_sample
, &start_time
, &end_time
, NULL
);
9732 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9733 ok(start_time
== 12345678, "Got start time %s.\n", wine_dbgstr_longlong(start_time
));
9734 ok(end_time
== 23456789, "Got end time %s.\n", wine_dbgstr_longlong(end_time
));
9736 hr
= IAMMultiMediaStream_SetState(mmstream
, STREAMSTATE_STOP
);
9737 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
9738 IGraphBuilder_Disconnect(graph
, pin
);
9739 IGraphBuilder_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
9741 ref
= IDirectDrawStreamSample_Release(stream_sample
);
9742 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9743 ref
= IAMMultiMediaStream_Release(mmstream
);
9744 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9745 IMediaFilter_Release(graph_media_filter
);
9746 ref
= IGraphBuilder_Release(graph
);
9747 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9748 ref
= IMediaStreamFilter_Release(filter
);
9749 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9751 IMemInputPin_Release(mem_input_pin
);
9752 IDirectDrawMediaStream_Release(ddraw_stream
);
9753 ref
= IMediaStream_Release(stream
);
9754 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
9757 START_TEST(amstream
)
9759 const WCHAR
*test_avi_path
;
9761 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
9765 test_media_streams();
9771 test_enum_media_types();
9773 test_get_end_of_stream_event_handle();
9775 test_avi_path
= load_resource(L
"test.avi");
9777 test_openfile(test_avi_path
);
9778 test_mmstream_get_duration(test_avi_path
);
9780 unload_resource(test_avi_path
);
9782 test_audiodata_query_interface();
9783 test_audiodata_get_info();
9784 test_audiodata_set_buffer();
9785 test_audiodata_set_actual();
9786 test_audiodata_get_format();
9787 test_audiodata_set_format();
9789 test_audiostream_get_format();
9790 test_audiostream_set_format();
9791 test_audiostream_receive_connection();
9792 test_audiostream_receive();
9793 test_audiostream_initialize();
9794 test_audiostream_begin_flush_end_flush();
9795 test_audiostream_new_segment();
9797 test_audiostreamsample_update();
9798 test_audiostreamsample_completion_status();
9799 test_audiostreamsample_get_sample_times();
9800 test_audiostreamsample_get_media_stream();
9801 test_audiostreamsample_get_audio_data();
9803 test_ddrawstream_initialize();
9804 test_ddrawstream_getsetdirectdraw();
9805 test_ddrawstream_receive_connection();
9806 test_ddrawstream_create_sample();
9807 test_ddrawstream_get_format();
9808 test_ddrawstream_set_format();
9809 test_ddrawstream_receive();
9810 test_ddrawstream_begin_flush_end_flush();
9811 test_ddrawstream_new_segment();
9812 test_ddrawstream_get_time_per_frame();
9813 test_ddrawstream_qc();
9815 test_ddrawstreamsample_get_media_stream();
9816 test_ddrawstreamsample_update();
9817 test_ddrawstreamsample_completion_status();
9818 test_ddrawstreamsample_get_sample_times();
9820 test_ammediastream_join_am_multi_media_stream();
9821 test_ammediastream_join_filter();
9822 test_ammediastream_join_filter_graph();
9823 test_ammediastream_set_state();
9824 test_ammediastream_end_of_stream();
9826 test_mediastreamfilter_get_state();
9827 test_mediastreamfilter_stop_pause_run();
9828 test_mediastreamfilter_support_seeking();
9829 test_mediastreamfilter_seeking();
9830 test_mediastreamfilter_get_current_stream_time();
9831 test_mediastreamfilter_reference_time_to_stream_time();
9832 test_mediastreamfilter_wait_until();
9833 test_mediastreamfilter_end_of_stream();