2 * Video Mixing Renderer 7 unit tests
4 * Copyright 2018 Zebediah Figura
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
26 #include "wine/strmbase.h"
27 #include "wine/test.h"
29 static IBaseFilter
*create_vmr7(DWORD mode
)
31 IBaseFilter
*filter
= NULL
;
32 IVMRFilterConfig
*config
;
33 HRESULT hr
= CoCreateInstance(&CLSID_VideoMixingRenderer
, NULL
, CLSCTX_INPROC_SERVER
,
34 &IID_IBaseFilter
, (void **)&filter
);
35 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
38 hr
= IBaseFilter_QueryInterface(filter
, &IID_IVMRFilterConfig
, (void **)&config
);
39 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
40 hr
= IVMRFilterConfig_SetRenderingMode(config
, mode
);
41 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
42 IVMRFilterConfig_Release(config
);
47 static HRESULT
set_mixing_mode(IBaseFilter
*filter
)
49 IVMRFilterConfig
*config
;
52 hr
= IBaseFilter_QueryInterface(filter
, &IID_IVMRFilterConfig
, (void **)&config
);
53 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
55 hr
= IVMRFilterConfig_SetNumberOfStreams(config
, 2);
56 todo_wine
ok(hr
== VFW_E_DDRAW_CAPS_NOT_SUITABLE
|| hr
== S_OK
, "Got hr %#x.\n", hr
);
58 IVMRFilterConfig_Release(config
);
62 static inline BOOL
compare_media_types(const AM_MEDIA_TYPE
*a
, const AM_MEDIA_TYPE
*b
)
64 return !memcmp(a
, b
, offsetof(AM_MEDIA_TYPE
, pbFormat
))
65 && !memcmp(a
->pbFormat
, b
->pbFormat
, a
->cbFormat
);
68 static BOOL
compare_double(double f
, double g
, unsigned int ulps
)
70 uint64_t x
= *(ULONGLONG
*)&f
;
71 uint64_t y
= *(ULONGLONG
*)&g
;
76 x
|= ((ULONGLONG
)1)<<63;
80 y
|= ((ULONGLONG
)1)<<63;
82 return (x
>y
? x
-y
: y
-x
) <= ulps
;
85 static IFilterGraph2
*create_graph(void)
89 hr
= CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IFilterGraph2
, (void **)&ret
);
90 ok(hr
== S_OK
, "Failed to create FilterGraph: %#x\n", hr
);
94 static ULONG
get_refcount(void *iface
)
96 IUnknown
*unknown
= iface
;
97 IUnknown_AddRef(unknown
);
98 return IUnknown_Release(unknown
);
101 static void test_filter_config(void)
103 IVMRFilterConfig
*config
;
108 hr
= CoCreateInstance(&CLSID_VideoMixingRenderer
, NULL
, CLSCTX_INPROC_SERVER
,
109 &IID_IVMRFilterConfig
, (void **)&config
);
110 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
112 hr
= IVMRFilterConfig_GetRenderingMode(config
, &mode
);
113 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
114 ok(mode
== VMRMode_Windowed
, "Got mode %#x.\n", mode
);
116 hr
= IVMRFilterConfig_SetRenderingMode(config
, VMRMode_Windowed
);
117 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
119 hr
= IVMRFilterConfig_GetRenderingMode(config
, &mode
);
120 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
121 ok(mode
== VMRMode_Windowed
, "Got mode %#x.\n", mode
);
123 hr
= IVMRFilterConfig_SetRenderingMode(config
, VMRMode_Windowed
);
124 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
126 ref
= IVMRFilterConfig_Release(config
);
127 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
129 hr
= CoCreateInstance(&CLSID_VideoMixingRenderer
, NULL
, CLSCTX_INPROC_SERVER
,
130 &IID_IVMRFilterConfig
, (void **)&config
);
131 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
133 hr
= IVMRFilterConfig_SetRenderingMode(config
, VMRMode_Windowless
);
134 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
136 hr
= IVMRFilterConfig_GetRenderingMode(config
, &mode
);
137 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
138 ok(mode
== VMRMode_Windowless
, "Got mode %#x.\n", mode
);
140 hr
= IVMRFilterConfig_SetRenderingMode(config
, VMRMode_Windowed
);
141 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
143 ref
= IVMRFilterConfig_Release(config
);
144 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
146 hr
= CoCreateInstance(&CLSID_VideoMixingRenderer
, NULL
, CLSCTX_INPROC_SERVER
,
147 &IID_IVMRFilterConfig
, (void **)&config
);
148 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
150 hr
= IVMRFilterConfig_SetRenderingMode(config
, VMRMode_Renderless
);
151 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
153 hr
= IVMRFilterConfig_GetRenderingMode(config
, &mode
);
154 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
155 ok(mode
== VMRMode_Renderless
, "Got mode %#x.\n", mode
);
157 hr
= IVMRFilterConfig_SetRenderingMode(config
, VMRMode_Windowless
);
158 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
160 ref
= IVMRFilterConfig_Release(config
);
161 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
163 hr
= CoCreateInstance(&CLSID_VideoMixingRenderer
, NULL
, CLSCTX_INPROC_SERVER
,
164 &IID_IVMRFilterConfig
, (void **)&config
);
165 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
167 hr
= IVMRFilterConfig_GetNumberOfStreams(config
, &count
);
168 todo_wine
ok(hr
== VFW_E_VMR_NOT_IN_MIXER_MODE
, "Got hr %#x.\n", hr
);
170 hr
= IVMRFilterConfig_SetNumberOfStreams(config
, 3);
171 if (hr
!= VFW_E_DDRAW_CAPS_NOT_SUITABLE
)
173 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
175 hr
= IVMRFilterConfig_GetNumberOfStreams(config
, &count
);
177 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
178 ok(count
== 3, "Got count %u.\n", count
);
181 hr
= IVMRFilterConfig_GetRenderingMode(config
, &mode
);
182 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
183 ok(mode
== VMRMode_Windowed
, "Got mode %#x.\n", mode
);
185 /* Despite MSDN, you can still change the rendering mode after setting the
187 hr
= IVMRFilterConfig_SetRenderingMode(config
, VMRMode_Windowless
);
188 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
190 hr
= IVMRFilterConfig_GetRenderingMode(config
, &mode
);
191 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
192 ok(mode
== VMRMode_Windowless
, "Got mode %#x.\n", mode
);
194 hr
= IVMRFilterConfig_GetNumberOfStreams(config
, &count
);
196 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
197 ok(count
== 3, "Got count %u.\n", count
);
201 skip("Mixing mode is not supported.\n");
203 ref
= IVMRFilterConfig_Release(config
);
204 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
207 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
208 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
210 IUnknown
*iface
= iface_ptr
;
211 HRESULT hr
, expected_hr
;
214 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
216 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
217 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
219 IUnknown_Release(unk
);
222 static void test_interfaces(void)
224 IBaseFilter
*filter
= create_vmr7(0);
228 check_interface(filter
, &IID_IAMCertifiedOutputProtection
, TRUE
);
229 check_interface(filter
, &IID_IAMFilterMiscFlags
, TRUE
);
230 check_interface(filter
, &IID_IBaseFilter
, TRUE
);
231 check_interface(filter
, &IID_IBasicVideo
, TRUE
);
232 todo_wine
check_interface(filter
, &IID_IBasicVideo2
, TRUE
);
233 todo_wine
check_interface(filter
, &IID_IKsPropertySet
, TRUE
);
234 check_interface(filter
, &IID_IMediaFilter
, TRUE
);
235 check_interface(filter
, &IID_IMediaPosition
, TRUE
);
236 check_interface(filter
, &IID_IMediaSeeking
, TRUE
);
237 check_interface(filter
, &IID_IPersist
, TRUE
);
238 check_interface(filter
, &IID_IQualityControl
, TRUE
);
239 todo_wine
check_interface(filter
, &IID_IQualProp
, TRUE
);
240 check_interface(filter
, &IID_IUnknown
, TRUE
);
241 check_interface(filter
, &IID_IVideoWindow
, TRUE
);
242 todo_wine
check_interface(filter
, &IID_IVMRAspectRatioControl
, TRUE
);
243 todo_wine
check_interface(filter
, &IID_IVMRDeinterlaceControl
, TRUE
);
244 check_interface(filter
, &IID_IVMRFilterConfig
, TRUE
);
245 todo_wine
check_interface(filter
, &IID_IVMRMixerBitmap
, TRUE
);
246 check_interface(filter
, &IID_IVMRMonitorConfig
, TRUE
);
248 check_interface(filter
, &IID_IBasicAudio
, FALSE
);
249 check_interface(filter
, &IID_IDirectDrawVideo
, FALSE
);
250 check_interface(filter
, &IID_IPersistPropertyBag
, FALSE
);
251 check_interface(filter
, &IID_IPin
, FALSE
);
252 check_interface(filter
, &IID_IReferenceClock
, FALSE
);
253 check_interface(filter
, &IID_IVMRAspectRatioControl9
, FALSE
);
254 check_interface(filter
, &IID_IVMRDeinterlaceControl9
, FALSE
);
255 check_interface(filter
, &IID_IVMRFilterConfig9
, FALSE
);
256 check_interface(filter
, &IID_IVMRMixerBitmap9
, FALSE
);
257 check_interface(filter
, &IID_IVMRMixerControl
, FALSE
);
258 check_interface(filter
, &IID_IVMRMixerControl9
, FALSE
);
259 check_interface(filter
, &IID_IVMRMonitorConfig9
, FALSE
);
260 check_interface(filter
, &IID_IVMRSurfaceAllocatorNotify
, FALSE
);
261 check_interface(filter
, &IID_IVMRSurfaceAllocatorNotify9
, FALSE
);
262 check_interface(filter
, &IID_IVMRWindowlessControl
, FALSE
);
263 check_interface(filter
, &IID_IVMRWindowlessControl9
, FALSE
);
265 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
267 check_interface(pin
, &IID_IMemInputPin
, TRUE
);
268 check_interface(pin
, &IID_IOverlay
, TRUE
);
269 check_interface(pin
, &IID_IPin
, TRUE
);
270 todo_wine
check_interface(pin
, &IID_IQualityControl
, TRUE
);
271 check_interface(pin
, &IID_IUnknown
, TRUE
);
273 check_interface(pin
, &IID_IKsPropertySet
, FALSE
);
274 check_interface(pin
, &IID_IMediaPosition
, FALSE
);
275 check_interface(pin
, &IID_IMediaSeeking
, FALSE
);
279 IBaseFilter_Release(filter
);
280 filter
= create_vmr7(VMRMode_Windowless
);
282 check_interface(filter
, &IID_IVMRMonitorConfig
, TRUE
);
283 check_interface(filter
, &IID_IVMRWindowlessControl
, TRUE
);
285 todo_wine
check_interface(filter
, &IID_IBasicVideo
, FALSE
);
286 check_interface(filter
, &IID_IBasicVideo2
, FALSE
);
287 todo_wine
check_interface(filter
, &IID_IVideoWindow
, FALSE
);
288 check_interface(filter
, &IID_IVMRSurfaceAllocatorNotify
, FALSE
);
289 check_interface(filter
, &IID_IVMRSurfaceAllocatorNotify9
, FALSE
);
290 check_interface(filter
, &IID_IVMRMixerControl
, FALSE
);
291 check_interface(filter
, &IID_IVMRMixerControl9
, FALSE
);
292 check_interface(filter
, &IID_IVMRMonitorConfig9
, FALSE
);
293 check_interface(filter
, &IID_IVMRWindowlessControl9
, FALSE
);
295 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
297 check_interface(pin
, &IID_IMemInputPin
, TRUE
);
298 check_interface(pin
, &IID_IOverlay
, TRUE
);
299 check_interface(pin
, &IID_IPin
, TRUE
);
300 todo_wine
check_interface(pin
, &IID_IQualityControl
, TRUE
);
301 check_interface(pin
, &IID_IUnknown
, TRUE
);
303 check_interface(pin
, &IID_IKsPropertySet
, FALSE
);
304 check_interface(pin
, &IID_IMediaPosition
, FALSE
);
305 check_interface(pin
, &IID_IMediaSeeking
, FALSE
);
309 IBaseFilter_Release(filter
);
310 filter
= create_vmr7(VMRMode_Renderless
);
312 check_interface(filter
, &IID_IVMRSurfaceAllocatorNotify
, TRUE
);
314 todo_wine
check_interface(filter
, &IID_IBasicVideo
, FALSE
);
315 check_interface(filter
, &IID_IBasicVideo2
, FALSE
);
316 todo_wine
check_interface(filter
, &IID_IVideoWindow
, FALSE
);
317 check_interface(filter
, &IID_IVMRMixerControl
, FALSE
);
318 todo_wine
check_interface(filter
, &IID_IVMRMonitorConfig
, FALSE
);
319 check_interface(filter
, &IID_IVMRMonitorConfig9
, FALSE
);
320 check_interface(filter
, &IID_IVMRSurfaceAllocatorNotify9
, FALSE
);
321 check_interface(filter
, &IID_IVMRWindowlessControl
, FALSE
);
322 check_interface(filter
, &IID_IVMRWindowlessControl9
, FALSE
);
324 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
326 check_interface(pin
, &IID_IMemInputPin
, TRUE
);
327 check_interface(pin
, &IID_IOverlay
, TRUE
);
328 check_interface(pin
, &IID_IPin
, TRUE
);
329 todo_wine
check_interface(pin
, &IID_IQualityControl
, TRUE
);
330 check_interface(pin
, &IID_IUnknown
, TRUE
);
332 check_interface(pin
, &IID_IKsPropertySet
, FALSE
);
333 check_interface(pin
, &IID_IMediaPosition
, FALSE
);
334 check_interface(pin
, &IID_IMediaSeeking
, FALSE
);
338 ref
= IBaseFilter_Release(filter
);
339 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
342 static const GUID test_iid
= {0x33333333};
343 static LONG outer_ref
= 1;
345 static HRESULT WINAPI
outer_QueryInterface(IUnknown
*iface
, REFIID iid
, void **out
)
347 if (IsEqualGUID(iid
, &IID_IUnknown
)
348 || IsEqualGUID(iid
, &IID_IBaseFilter
)
349 || IsEqualGUID(iid
, &test_iid
))
351 *out
= (IUnknown
*)0xdeadbeef;
354 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid
));
355 return E_NOINTERFACE
;
358 static ULONG WINAPI
outer_AddRef(IUnknown
*iface
)
360 return InterlockedIncrement(&outer_ref
);
363 static ULONG WINAPI
outer_Release(IUnknown
*iface
)
365 return InterlockedDecrement(&outer_ref
);
368 static const IUnknownVtbl outer_vtbl
=
370 outer_QueryInterface
,
375 static IUnknown test_outer
= {&outer_vtbl
};
377 static void test_aggregation(void)
379 IBaseFilter
*filter
, *filter2
;
380 IUnknown
*unk
, *unk2
;
384 filter
= (IBaseFilter
*)0xdeadbeef;
385 hr
= CoCreateInstance(&CLSID_VideoMixingRenderer
, &test_outer
, CLSCTX_INPROC_SERVER
,
386 &IID_IBaseFilter
, (void **)&filter
);
387 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
388 ok(!filter
, "Got interface %p.\n", filter
);
390 hr
= CoCreateInstance(&CLSID_VideoMixingRenderer
, &test_outer
, CLSCTX_INPROC_SERVER
,
391 &IID_IUnknown
, (void **)&unk
);
392 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
393 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
394 ok(unk
!= &test_outer
, "Returned IUnknown should not be outer IUnknown.\n");
395 ref
= get_refcount(unk
);
396 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
398 ref
= IUnknown_AddRef(unk
);
399 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
400 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
402 ref
= IUnknown_Release(unk
);
403 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
404 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
406 hr
= IUnknown_QueryInterface(unk
, &IID_IUnknown
, (void **)&unk2
);
407 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
408 ok(unk2
== unk
, "Got unexpected IUnknown %p.\n", unk2
);
409 IUnknown_Release(unk2
);
411 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void **)&filter
);
412 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
414 hr
= IBaseFilter_QueryInterface(filter
, &IID_IUnknown
, (void **)&unk2
);
415 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
416 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
418 hr
= IBaseFilter_QueryInterface(filter
, &IID_IBaseFilter
, (void **)&filter2
);
419 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
420 ok(filter2
== (IBaseFilter
*)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2
);
422 hr
= IUnknown_QueryInterface(unk
, &test_iid
, (void **)&unk2
);
423 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
424 ok(!unk2
, "Got unexpected IUnknown %p.\n", unk2
);
426 hr
= IBaseFilter_QueryInterface(filter
, &test_iid
, (void **)&unk2
);
427 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
428 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
430 IBaseFilter_Release(filter
);
431 ref
= IUnknown_Release(unk
);
432 ok(!ref
, "Got unexpected refcount %d.\n", ref
);
433 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
436 static void test_enum_pins(void)
438 IBaseFilter
*filter
= create_vmr7(0);
439 IEnumPins
*enum1
, *enum2
;
444 ref
= get_refcount(filter
);
445 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
447 hr
= IBaseFilter_EnumPins(filter
, NULL
);
448 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
450 hr
= IBaseFilter_EnumPins(filter
, &enum1
);
451 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
452 ref
= get_refcount(filter
);
453 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
454 ref
= get_refcount(enum1
);
455 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
457 hr
= IEnumPins_Next(enum1
, 1, NULL
, NULL
);
458 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
460 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
461 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
462 ref
= get_refcount(filter
);
463 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
464 ref
= get_refcount(pins
[0]);
465 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
466 ref
= get_refcount(enum1
);
467 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
468 IPin_Release(pins
[0]);
469 ref
= get_refcount(filter
);
470 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
472 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
473 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
475 hr
= IEnumPins_Reset(enum1
);
476 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
478 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
479 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
480 ok(count
== 1, "Got count %u.\n", count
);
481 IPin_Release(pins
[0]);
483 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
484 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
485 ok(!count
, "Got count %u.\n", count
);
487 hr
= IEnumPins_Reset(enum1
);
488 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
490 hr
= IEnumPins_Next(enum1
, 2, pins
, NULL
);
491 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
493 hr
= IEnumPins_Next(enum1
, 2, pins
, &count
);
494 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
495 ok(count
== 1, "Got count %u.\n", count
);
496 IPin_Release(pins
[0]);
498 hr
= IEnumPins_Reset(enum1
);
499 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
501 hr
= IEnumPins_Clone(enum1
, &enum2
);
502 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
504 hr
= IEnumPins_Skip(enum1
, 2);
505 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
507 hr
= IEnumPins_Skip(enum1
, 1);
508 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
510 hr
= IEnumPins_Skip(enum1
, 1);
511 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
513 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
514 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
516 hr
= IEnumPins_Next(enum2
, 1, pins
, NULL
);
517 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
518 IPin_Release(pins
[0]);
520 IEnumPins_Release(enum2
);
522 if (SUCCEEDED(set_mixing_mode(filter
)))
524 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
525 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
527 hr
= IEnumPins_Reset(enum1
);
528 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
530 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
531 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
532 IPin_Release(pins
[0]);
534 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
535 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
536 IPin_Release(pins
[0]);
538 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
539 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
541 hr
= IEnumPins_Reset(enum1
);
542 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
544 hr
= IEnumPins_Next(enum1
, 2, pins
, &count
);
545 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
546 ok(count
== 2, "Got count %u.\n", count
);
547 IPin_Release(pins
[0]);
548 IPin_Release(pins
[1]);
550 hr
= IEnumPins_Reset(enum1
);
551 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
553 hr
= IEnumPins_Next(enum1
, 3, pins
, &count
);
554 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
555 ok(count
== 2, "Got count %u.\n", count
);
556 IPin_Release(pins
[0]);
557 IPin_Release(pins
[1]);
560 skip("Mixing mode is not supported.\n");
562 IEnumPins_Release(enum1
);
563 ref
= IBaseFilter_Release(filter
);
564 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
567 static void test_find_pin(void)
569 IBaseFilter
*filter
= create_vmr7(0);
570 IEnumPins
*enum_pins
;
575 IBaseFilter_EnumPins(filter
, &enum_pins
);
577 hr
= IBaseFilter_FindPin(filter
, L
"input pin", &pin
);
578 ok(hr
== VFW_E_NOT_FOUND
, "Got hr %#x.\n", hr
);
580 hr
= IBaseFilter_FindPin(filter
, L
"In", &pin
);
581 ok(hr
== VFW_E_NOT_FOUND
, "Got hr %#x.\n", hr
);
583 hr
= IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
584 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
585 hr
= IEnumPins_Next(enum_pins
, 1, &pin2
, NULL
);
586 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
587 ok(pin
== pin2
, "Pins did not match.\n");
591 hr
= IBaseFilter_FindPin(filter
, L
"VMR input1", &pin
);
592 ok(hr
== VFW_E_NOT_FOUND
, "Got hr %#x.\n", hr
);
594 if (SUCCEEDED(set_mixing_mode(filter
)))
596 IEnumPins_Reset(enum_pins
);
598 hr
= IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
599 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
600 hr
= IEnumPins_Next(enum_pins
, 1, &pin2
, NULL
);
601 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
602 ok(pin
== pin2
, "Pins did not match.\n");
606 hr
= IBaseFilter_FindPin(filter
, L
"VMR Input1", &pin
);
607 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
608 hr
= IEnumPins_Next(enum_pins
, 1, &pin2
, NULL
);
609 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
610 ok(pin
== pin2
, "Pins did not match.\n");
614 hr
= IBaseFilter_FindPin(filter
, L
"VMR Input2", &pin
);
615 ok(hr
== VFW_E_NOT_FOUND
, "Got hr %#x.\n", hr
);
618 skip("Mixing mode is not supported.\n");
620 IEnumPins_Release(enum_pins
);
621 ref
= IBaseFilter_Release(filter
);
622 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
625 static void test_pin_info(void)
627 IBaseFilter
*filter
= create_vmr7(0);
635 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
636 hr
= IPin_QueryPinInfo(pin
, &info
);
637 ok(info
.pFilter
== filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
638 ok(info
.dir
== PINDIR_INPUT
, "Got direction %d.\n", info
.dir
);
639 ok(!wcscmp(info
.achName
, L
"VMR Input0"), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
640 IBaseFilter_Release(info
.pFilter
);
642 hr
= IPin_QueryDirection(pin
, &dir
);
643 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
644 ok(dir
== PINDIR_INPUT
, "Got direction %d.\n", dir
);
646 hr
= IPin_QueryId(pin
, &id
);
647 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
648 ok(!wcscmp(id
, L
"VMR Input0"), "Got id %s.\n", wine_dbgstr_w(id
));
651 hr
= IPin_QueryInternalConnections(pin
, NULL
, &count
);
652 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
656 if (SUCCEEDED(set_mixing_mode(filter
)))
658 IBaseFilter_FindPin(filter
, L
"VMR Input1", &pin
);
659 hr
= IPin_QueryPinInfo(pin
, &info
);
660 ok(info
.pFilter
== filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
661 ok(info
.dir
== PINDIR_INPUT
, "Got direction %d.\n", info
.dir
);
662 ok(!wcscmp(info
.achName
, L
"VMR Input1"), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
663 IBaseFilter_Release(info
.pFilter
);
665 hr
= IPin_QueryDirection(pin
, &dir
);
666 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
667 ok(dir
== PINDIR_INPUT
, "Got direction %d.\n", dir
);
669 hr
= IPin_QueryId(pin
, &id
);
670 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
671 ok(!wcscmp(id
, L
"VMR Input1"), "Got id %s.\n", wine_dbgstr_w(id
));
674 hr
= IPin_QueryInternalConnections(pin
, NULL
, &count
);
675 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
680 skip("Mixing mode is not supported.\n");
682 ref
= IBaseFilter_Release(filter
);
683 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
686 static void test_media_types(void)
688 IBaseFilter
*filter
= create_vmr7(0);
689 AM_MEDIA_TYPE
*mt
, req_mt
= {{0}};
690 VIDEOINFOHEADER vih
=
693 {sizeof(BITMAPINFOHEADER
), 32, 24, 1, 0, BI_RGB
}
695 IEnumMediaTypes
*enummt
;
701 static const GUID
*subtype_tests
[] =
704 &MEDIASUBTYPE_RGB565
,
709 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
711 hr
= IPin_EnumMediaTypes(pin
, &enummt
);
712 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
714 hr
= IEnumMediaTypes_Next(enummt
, 1, &mt
, NULL
);
715 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
717 IEnumMediaTypes_Release(enummt
);
719 req_mt
.majortype
= MEDIATYPE_Video
;
720 req_mt
.formattype
= FORMAT_VideoInfo
;
721 req_mt
.cbFormat
= sizeof(VIDEOINFOHEADER
);
722 req_mt
.pbFormat
= (BYTE
*)&vih
;
724 for (i
= 0; i
< ARRAY_SIZE(subtype_tests
); ++i
)
726 req_mt
.subtype
= *subtype_tests
[i
];
727 hr
= IPin_QueryAccept(pin
, &req_mt
);
728 ok(hr
== S_OK
, "Got hr %#x for subtype %s.\n", hr
, wine_dbgstr_guid(subtype_tests
[i
]));
731 req_mt
.subtype
= MEDIASUBTYPE_RGB8
;
732 hr
= IPin_QueryAccept(pin
, &req_mt
);
733 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
734 req_mt
.subtype
= MEDIASUBTYPE_RGB24
;
736 req_mt
.majortype
= MEDIATYPE_NULL
;
737 hr
= IPin_QueryAccept(pin
, &req_mt
);
738 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
739 req_mt
.majortype
= MEDIATYPE_Video
;
741 req_mt
.formattype
= FORMAT_None
;
742 hr
= IPin_QueryAccept(pin
, &req_mt
);
743 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
745 req_mt
.formattype
= GUID_NULL
;
746 hr
= IPin_QueryAccept(pin
, &req_mt
);
747 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
750 ref
= IBaseFilter_Release(filter
);
751 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
754 static void test_enum_media_types(void)
756 IBaseFilter
*filter
= create_vmr7(0);
757 IEnumMediaTypes
*enum1
, *enum2
;
758 AM_MEDIA_TYPE
*mts
[2];
763 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
765 hr
= IPin_EnumMediaTypes(pin
, &enum1
);
766 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
768 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
769 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
771 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
772 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
773 ok(!count
, "Got count %u.\n", count
);
775 hr
= IEnumMediaTypes_Reset(enum1
);
776 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
778 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
779 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
781 hr
= IEnumMediaTypes_Clone(enum1
, &enum2
);
782 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
784 hr
= IEnumMediaTypes_Skip(enum1
, 1);
785 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
787 hr
= IEnumMediaTypes_Next(enum2
, 1, mts
, NULL
);
788 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
790 IEnumMediaTypes_Release(enum1
);
791 IEnumMediaTypes_Release(enum2
);
794 ref
= IBaseFilter_Release(filter
);
795 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
798 static void test_unconnected_filter_state(void)
800 IBaseFilter
*filter
= create_vmr7(0);
805 hr
= IBaseFilter_GetState(filter
, 0, &state
);
806 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
807 ok(state
== State_Stopped
, "Got state %u.\n", state
);
809 hr
= IBaseFilter_Pause(filter
);
810 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
812 hr
= IBaseFilter_GetState(filter
, 0, &state
);
813 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
814 ok(state
== State_Paused
, "Got state %u.\n", state
);
816 hr
= IBaseFilter_Run(filter
, 0);
817 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
819 hr
= IBaseFilter_GetState(filter
, 0, &state
);
820 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
821 ok(state
== State_Running
, "Got state %u.\n", state
);
823 hr
= IBaseFilter_Pause(filter
);
824 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
826 hr
= IBaseFilter_GetState(filter
, 0, &state
);
827 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
828 ok(state
== State_Paused
, "Got state %u.\n", state
);
830 hr
= IBaseFilter_Stop(filter
);
831 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
833 hr
= IBaseFilter_GetState(filter
, 0, &state
);
834 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
835 ok(state
== State_Stopped
, "Got state %u.\n", state
);
837 hr
= IBaseFilter_Run(filter
, 0);
838 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
840 hr
= IBaseFilter_GetState(filter
, 0, &state
);
841 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
842 ok(state
== State_Running
, "Got state %u.\n", state
);
844 hr
= IBaseFilter_Stop(filter
);
845 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
847 hr
= IBaseFilter_GetState(filter
, 0, &state
);
848 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
849 ok(state
== State_Stopped
, "Got state %u.\n", state
);
851 ref
= IBaseFilter_Release(filter
);
852 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
857 struct strmbase_filter filter
;
858 struct strmbase_source source
;
861 static inline struct testfilter
*impl_from_strmbase_filter(struct strmbase_filter
*iface
)
863 return CONTAINING_RECORD(iface
, struct testfilter
, filter
);
866 static struct strmbase_pin
*testfilter_get_pin(struct strmbase_filter
*iface
, unsigned int index
)
868 struct testfilter
*filter
= impl_from_strmbase_filter(iface
);
870 return &filter
->source
.pin
;
874 static void testfilter_destroy(struct strmbase_filter
*iface
)
876 struct testfilter
*filter
= impl_from_strmbase_filter(iface
);
877 strmbase_source_cleanup(&filter
->source
);
878 strmbase_filter_cleanup(&filter
->filter
);
881 static const struct strmbase_filter_ops testfilter_ops
=
883 .filter_get_pin
= testfilter_get_pin
,
884 .filter_destroy
= testfilter_destroy
,
887 static HRESULT WINAPI
testsource_DecideAllocator(struct strmbase_source
*iface
,
888 IMemInputPin
*peer
, IMemAllocator
**allocator
)
893 static const struct strmbase_source_ops testsource_ops
=
895 .pfnAttemptConnection
= BaseOutputPinImpl_AttemptConnection
,
896 .pfnDecideAllocator
= testsource_DecideAllocator
,
899 static void testfilter_init(struct testfilter
*filter
)
901 static const GUID clsid
= {0xabacab};
902 strmbase_filter_init(&filter
->filter
, NULL
, &clsid
, &testfilter_ops
);
903 strmbase_source_init(&filter
->source
, &filter
->filter
, L
"", &testsource_ops
);
906 static void test_allocator(IMemInputPin
*input
)
908 IMemAllocator
*req_allocator
, *ret_allocator
;
909 ALLOCATOR_PROPERTIES props
, req_props
;
912 hr
= IMemInputPin_GetAllocatorRequirements(input
, &props
);
913 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
915 hr
= IMemInputPin_GetAllocator(input
, &ret_allocator
);
916 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
920 hr
= IMemAllocator_GetProperties(ret_allocator
, &props
);
921 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
922 ok(!props
.cBuffers
, "Got %d buffers.\n", props
.cBuffers
);
923 ok(!props
.cbBuffer
, "Got size %d.\n", props
.cbBuffer
);
924 ok(!props
.cbAlign
, "Got alignment %d.\n", props
.cbAlign
);
925 ok(!props
.cbPrefix
, "Got prefix %d.\n", props
.cbPrefix
);
927 hr
= IMemInputPin_NotifyAllocator(input
, ret_allocator
, TRUE
);
928 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
930 req_props
.cBuffers
= 1;
931 req_props
.cbBuffer
= 32 * 16 * 4;
932 req_props
.cbAlign
= 1;
933 req_props
.cbPrefix
= 0;
934 hr
= IMemAllocator_SetProperties(ret_allocator
, &req_props
, &props
);
935 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
936 ok(props
.cBuffers
== 1, "Got %d buffers.\n", props
.cBuffers
);
937 ok(props
.cbBuffer
== 32 * 16 * 4, "Got size %d.\n", props
.cbBuffer
);
938 ok(props
.cbAlign
== 1, "Got alignment %d.\n", props
.cbAlign
);
939 ok(!props
.cbPrefix
, "Got prefix %d.\n", props
.cbPrefix
);
941 IMemAllocator_Release(ret_allocator
);
944 hr
= IMemInputPin_NotifyAllocator(input
, NULL
, TRUE
);
945 todo_wine
ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
947 CoCreateInstance(&CLSID_MemoryAllocator
, NULL
, CLSCTX_INPROC_SERVER
,
948 &IID_IMemAllocator
, (void **)&req_allocator
);
950 hr
= IMemInputPin_NotifyAllocator(input
, req_allocator
, TRUE
);
951 todo_wine
ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
953 IMemAllocator_Release(req_allocator
);
956 struct frame_thread_params
959 IMediaSample
*sample
;
962 static DWORD WINAPI
frame_thread(void *arg
)
964 struct frame_thread_params
*params
= arg
;
967 if (winetest_debug
> 1) trace("%04x: Sending frame.\n", GetCurrentThreadId());
968 hr
= IMemInputPin_Receive(params
->sink
, params
->sample
);
969 if (winetest_debug
> 1) trace("%04x: Returned %#x.\n", GetCurrentThreadId(), hr
);
970 IMediaSample_Release(params
->sample
);
975 static HANDLE
send_frame(IMemInputPin
*sink
)
977 struct frame_thread_params
*params
= malloc(sizeof(*params
));
978 REFERENCE_TIME start_time
, end_time
;
979 IMemAllocator
*allocator
;
980 IMediaSample
*sample
;
985 hr
= IMemInputPin_GetAllocator(sink
, &allocator
);
986 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
988 hr
= IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
989 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
991 hr
= IMediaSample_GetPointer(sample
, &data
);
992 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
993 memset(data
, 0x55, IMediaSample_GetSize(sample
));
995 hr
= IMediaSample_SetActualDataLength(sample
, IMediaSample_GetSize(sample
));
996 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
999 end_time
= start_time
+ 10000000;
1000 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
1001 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1003 hr
= IMediaSample_SetPreroll(sample
, TRUE
);
1004 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1006 params
->sink
= sink
;
1007 params
->sample
= sample
;
1008 thread
= CreateThread(NULL
, 0, frame_thread
, params
, 0, NULL
);
1010 IMemAllocator_Release(allocator
);
1014 static HRESULT
join_thread_(int line
, HANDLE thread
)
1017 ok_(__FILE__
, line
)(!WaitForSingleObject(thread
, 1000), "Wait failed.\n");
1018 GetExitCodeThread(thread
, &ret
);
1019 CloseHandle(thread
);
1022 #define join_thread(a) join_thread_(__LINE__, a)
1024 static void commit_allocator(IMemInputPin
*input
)
1026 IMemAllocator
*allocator
;
1029 hr
= IMemInputPin_GetAllocator(input
, &allocator
);
1030 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1031 hr
= IMemAllocator_Commit(allocator
);
1032 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1033 IMemAllocator_Release(allocator
);
1036 static void test_filter_state(IMemInputPin
*input
, IMediaControl
*control
)
1038 IMemAllocator
*allocator
;
1039 IMediaSample
*sample
;
1040 OAFilterState state
;
1044 thread
= send_frame(input
);
1045 hr
= join_thread(thread
);
1046 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
1048 /* The renderer is not fully paused until it receives a sample. The thread
1049 * sending the sample blocks in IMemInputPin_Receive() until the filter is
1050 * stopped or run. */
1052 hr
= IMediaControl_Pause(control
);
1053 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1055 hr
= IMediaControl_GetState(control
, 0, &state
);
1056 ok(hr
== VFW_S_STATE_INTERMEDIATE
, "Got hr %#x.\n", hr
);
1058 thread
= send_frame(input
);
1060 hr
= IMediaControl_GetState(control
, 1000, &state
);
1061 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1063 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Thread should block in Receive().\n");
1065 hr
= IMediaControl_Stop(control
);
1066 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1068 hr
= join_thread(thread
);
1069 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1071 /* The sink will decommit our allocator for us when stopping, however it
1072 * will not recommit it when pausing. */
1073 hr
= IMemInputPin_GetAllocator(input
, &allocator
);
1074 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1075 hr
= IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
1076 todo_wine
ok(hr
== VFW_E_NOT_COMMITTED
, "Got hr %#x.\n", hr
);
1077 if (hr
== S_OK
) IMediaSample_Release(sample
);
1079 hr
= IMemAllocator_Commit(allocator
);
1080 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1081 thread
= send_frame(input
);
1082 hr
= join_thread(thread
);
1083 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
1085 hr
= IMediaControl_Pause(control
);
1086 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1088 hr
= IMediaControl_GetState(control
, 0, &state
);
1089 ok(hr
== VFW_S_STATE_INTERMEDIATE
, "Got hr %#x.\n", hr
);
1091 thread
= send_frame(input
);
1093 hr
= IMediaControl_GetState(control
, 1000, &state
);
1094 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1096 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Thread should block in Receive().\n");
1098 hr
= IMediaControl_Run(control
);
1099 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1101 hr
= IMediaControl_GetState(control
, 0, &state
);
1102 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1104 hr
= join_thread(thread
);
1105 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1107 thread
= send_frame(input
);
1108 hr
= join_thread(thread
);
1109 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1111 hr
= IMediaControl_Pause(control
);
1112 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1114 hr
= IMediaControl_GetState(control
, 0, &state
);
1115 todo_wine
ok(hr
== VFW_S_STATE_INTERMEDIATE
, "Got hr %#x.\n", hr
);
1117 thread
= send_frame(input
);
1119 hr
= IMediaControl_GetState(control
, 1000, &state
);
1120 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1122 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Thread should block in Receive().\n");
1124 hr
= IMediaControl_Run(control
);
1125 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1127 hr
= IMediaControl_GetState(control
, 0, &state
);
1128 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1130 hr
= join_thread(thread
);
1131 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1133 hr
= IMediaControl_Pause(control
);
1134 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1136 hr
= IMediaControl_GetState(control
, 0, &state
);
1137 todo_wine
ok(hr
== VFW_S_STATE_INTERMEDIATE
, "Got hr %#x.\n", hr
);
1139 hr
= IMediaControl_Stop(control
);
1140 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1142 hr
= IMediaControl_GetState(control
, 0, &state
);
1143 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1145 commit_allocator(input
);
1146 hr
= IMediaControl_Pause(control
);
1147 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1149 hr
= IMediaControl_GetState(control
, 0, &state
);
1150 ok(hr
== VFW_S_STATE_INTERMEDIATE
, "Got hr %#x.\n", hr
);
1152 hr
= IMediaControl_Run(control
);
1153 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1155 hr
= IMediaControl_GetState(control
, 0, &state
);
1156 todo_wine
ok(hr
== VFW_S_STATE_INTERMEDIATE
, "Got hr %#x.\n", hr
);
1158 thread
= send_frame(input
);
1159 hr
= join_thread(thread
);
1160 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1162 hr
= IMediaControl_GetState(control
, 0, &state
);
1163 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1165 hr
= IMediaControl_Stop(control
);
1166 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1168 hr
= IMediaControl_GetState(control
, 0, &state
);
1169 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1171 IMemAllocator_Release(allocator
);
1174 static void test_flushing(IPin
*pin
, IMemInputPin
*input
, IMediaControl
*control
)
1176 OAFilterState state
;
1180 commit_allocator(input
);
1181 hr
= IMediaControl_Pause(control
);
1182 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1184 thread
= send_frame(input
);
1185 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Thread should block in Receive().\n");
1187 hr
= IMediaControl_GetState(control
, 1000, &state
);
1188 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1190 hr
= IPin_BeginFlush(pin
);
1191 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1193 hr
= join_thread(thread
);
1194 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1196 thread
= send_frame(input
);
1197 hr
= join_thread(thread
);
1198 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1200 hr
= IPin_EndFlush(pin
);
1201 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1203 /* We dropped the sample we were holding, so now we need a new one... */
1205 hr
= IMediaControl_GetState(control
, 0, &state
);
1206 todo_wine
ok(hr
== VFW_S_STATE_INTERMEDIATE
, "Got hr %#x.\n", hr
);
1207 ok(state
== State_Paused
, "Got state %#x.\n", state
);
1209 thread
= send_frame(input
);
1210 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Thread should block in Receive().\n");
1212 hr
= IMediaControl_GetState(control
, 1000, &state
);
1213 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1214 ok(state
== State_Paused
, "Got state %#x.\n", state
);
1216 hr
= IMediaControl_Run(control
);
1217 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1218 hr
= join_thread(thread
);
1219 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1221 hr
= IPin_BeginFlush(pin
);
1222 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1224 thread
= send_frame(input
);
1225 hr
= join_thread(thread
);
1226 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1228 hr
= IPin_EndFlush(pin
);
1229 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1231 thread
= send_frame(input
);
1232 hr
= join_thread(thread
);
1233 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1235 hr
= IMediaControl_Stop(control
);
1236 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1239 static void test_current_image(IBaseFilter
*filter
, IMemInputPin
*input
,
1240 IMediaControl
*control
, const BITMAPINFOHEADER
*req_bih
)
1242 LONG buffer
[(sizeof(BITMAPINFOHEADER
) + 32 * 16 * 4) / 4];
1243 const BITMAPINFOHEADER
*bih
= (BITMAPINFOHEADER
*)buffer
;
1244 const DWORD
*data
= (DWORD
*)((char *)buffer
+ sizeof(BITMAPINFOHEADER
));
1245 BITMAPINFOHEADER expect_bih
= *req_bih
;
1246 OAFilterState state
;
1253 /* Note that the bitmap returned by GetCurrentImage() has a bit depth of
1254 * 32 regardless of the format used for pin connection. */
1255 expect_bih
.biBitCount
= 32;
1256 expect_bih
.biSizeImage
= 32 * 16 * 4;
1258 IBaseFilter_QueryInterface(filter
, &IID_IBasicVideo
, (void **)&video
);
1260 hr
= IBasicVideo_GetCurrentImage(video
, NULL
, NULL
);
1261 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1263 hr
= IBasicVideo_GetCurrentImage(video
, NULL
, buffer
);
1264 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
1267 hr
= IBasicVideo_GetCurrentImage(video
, &size
, NULL
);
1268 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1269 todo_wine
ok(size
== sizeof(BITMAPINFOHEADER
) + 32 * 16 * 4, "Got size %d.\n", size
);
1271 size
= sizeof(buffer
);
1272 hr
= IBasicVideo_GetCurrentImage(video
, &size
, buffer
);
1273 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1274 ok(size
== sizeof(buffer
), "Got size %d.\n", size
);
1275 ok(!memcmp(bih
, &expect_bih
, sizeof(BITMAPINFOHEADER
)), "Bitmap headers didn't match.\n");
1276 /* The contents seem to reflect the last frame rendered. */
1278 commit_allocator(input
);
1279 hr
= IMediaControl_Pause(control
);
1280 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1282 size
= sizeof(buffer
);
1283 hr
= IBasicVideo_GetCurrentImage(video
, &size
, buffer
);
1284 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1285 ok(size
== sizeof(buffer
), "Got size %d.\n", size
);
1286 ok(!memcmp(bih
, &expect_bih
, sizeof(BITMAPINFOHEADER
)), "Bitmap headers didn't match.\n");
1287 /* The contents seem to reflect the last frame rendered. */
1289 thread
= send_frame(input
);
1290 hr
= IMediaControl_GetState(control
, 1000, &state
);
1291 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1294 memset(buffer
, 0xcc, sizeof(buffer
));
1295 hr
= IBasicVideo_GetCurrentImage(video
, &size
, buffer
);
1296 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1297 ok(size
== 1, "Got size %d.\n", size
);
1299 size
= sizeof(buffer
);
1300 memset(buffer
, 0xcc, sizeof(buffer
));
1301 hr
= IBasicVideo_GetCurrentImage(video
, &size
, buffer
);
1302 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1303 ok(size
== sizeof(buffer
), "Got size %d.\n", size
);
1304 ok(!memcmp(bih
, &expect_bih
, sizeof(BITMAPINFOHEADER
)), "Bitmap headers didn't match.\n");
1305 for (i
= 0; i
< 32 * 16; ++i
)
1306 ok((data
[i
] & 0xffffff) == 0x555555, "Got unexpected color %08x at %u.\n", data
[i
], i
);
1308 hr
= IMediaControl_Run(control
);
1309 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1310 join_thread(thread
);
1312 size
= sizeof(buffer
);
1313 memset(buffer
, 0xcc, sizeof(buffer
));
1314 hr
= IBasicVideo_GetCurrentImage(video
, &size
, buffer
);
1315 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1316 ok(size
== sizeof(buffer
), "Got size %d.\n", size
);
1317 ok(!memcmp(bih
, &expect_bih
, sizeof(BITMAPINFOHEADER
)), "Bitmap headers didn't match.\n");
1318 for (i
= 0; i
< 32 * 16; ++i
)
1319 ok((data
[i
] & 0xffffff) == 0x555555, "Got unexpected color %08x at %u.\n", data
[i
], i
);
1321 hr
= IMediaControl_Stop(control
);
1322 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1324 IBasicVideo_Release(video
);
1327 static unsigned int check_ec_userabort(IMediaEvent
*eventsrc
, DWORD timeout
)
1329 LONG_PTR param1
, param2
;
1330 unsigned int ret
= 0;
1334 while ((hr
= IMediaEvent_GetEvent(eventsrc
, &code
, ¶m1
, ¶m2
, timeout
)) == S_OK
)
1336 if (code
== EC_USERABORT
)
1338 ok(!param1
, "Got param1 %#lx.\n", param1
);
1339 ok(!param2
, "Got param2 %#lx.\n", param2
);
1342 IMediaEvent_FreeEventParams(eventsrc
, code
, param1
, param2
);
1345 ok(hr
== E_ABORT
, "Got hr %#x.\n", hr
);
1350 static void test_window_close(IPin
*pin
, IMemInputPin
*input
, IMediaControl
*control
)
1352 IMediaEvent
*eventsrc
;
1353 OAFilterState state
;
1360 IMediaControl_QueryInterface(control
, &IID_IMediaEvent
, (void **)&eventsrc
);
1361 IPin_QueryInterface(pin
, &IID_IOverlay
, (void **)&overlay
);
1363 hr
= IOverlay_GetWindowHandle(overlay
, &hwnd
);
1364 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1365 IOverlay_Release(overlay
);
1367 commit_allocator(input
);
1368 hr
= IMediaControl_Pause(control
);
1369 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1370 ret
= check_ec_userabort(eventsrc
, 0);
1371 ok(!ret
, "Got unexpected EC_USERABORT.\n");
1373 SendMessageW(hwnd
, WM_CLOSE
, 0, 0);
1375 hr
= IMediaControl_GetState(control
, 1000, &state
);
1376 ok(hr
== VFW_S_STATE_INTERMEDIATE
, "Got hr %#x.\n", hr
);
1377 ret
= check_ec_userabort(eventsrc
, 0);
1378 todo_wine
ok(ret
== 1, "Expected EC_USERABORT.\n");
1380 todo_wine
ok(IsWindow(hwnd
), "Window should exist.\n");
1381 ok(!IsWindowVisible(hwnd
), "Window should be visible.\n");
1383 thread
= send_frame(input
);
1384 ret
= WaitForSingleObject(thread
, 1000);
1385 todo_wine
ok(ret
== WAIT_OBJECT_0
, "Wait failed\n");
1386 if (ret
== WAIT_OBJECT_0
)
1388 GetExitCodeThread(thread
, (DWORD
*)&hr
);
1389 ok(hr
== E_UNEXPECTED
, "Got hr %#x.\n", hr
);
1391 CloseHandle(thread
);
1393 hr
= IMediaControl_Run(control
);
1394 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1395 ret
= check_ec_userabort(eventsrc
, 0);
1396 ok(!ret
, "Got unexpected EC_USERABORT.\n");
1398 hr
= IMediaControl_Stop(control
);
1399 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1400 ret
= check_ec_userabort(eventsrc
, 0);
1401 ok(!ret
, "Got unexpected EC_USERABORT.\n");
1403 /* We receive an EC_USERABORT notification immediately. */
1405 commit_allocator(input
);
1406 hr
= IMediaControl_Run(control
);
1407 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1408 hr
= join_thread(send_frame(input
));
1409 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1410 hr
= IMediaControl_GetState(control
, 1000, &state
);
1411 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1412 ret
= check_ec_userabort(eventsrc
, 0);
1413 ok(!ret
, "Got unexpected EC_USERABORT.\n");
1415 SendMessageW(hwnd
, WM_CLOSE
, 0, 0);
1417 ret
= check_ec_userabort(eventsrc
, 0);
1418 todo_wine
ok(ret
== 1, "Expected EC_USERABORT.\n");
1420 todo_wine
ok(IsWindow(hwnd
), "Window should exist.\n");
1421 ok(!IsWindowVisible(hwnd
), "Window should be visible.\n");
1423 hr
= IMediaControl_Stop(control
);
1424 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1425 ret
= check_ec_userabort(eventsrc
, 0);
1426 ok(!ret
, "Got unexpected EC_USERABORT.\n");
1428 IMediaEvent_Release(eventsrc
);
1431 static void test_connect_pin(void)
1433 VIDEOINFOHEADER vih
=
1435 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
1436 .bmiHeader
.biWidth
= 32,
1437 .bmiHeader
.biHeight
= 16,
1438 .bmiHeader
.biPlanes
= 1,
1439 .bmiHeader
.biCompression
= BI_RGB
,
1441 AM_MEDIA_TYPE req_mt
=
1443 .majortype
= MEDIATYPE_Video
,
1444 .subtype
= MEDIASUBTYPE_WAVE
,
1445 .formattype
= FORMAT_VideoInfo
,
1446 .cbFormat
= sizeof(vih
),
1447 .pbFormat
= (BYTE
*)&vih
,
1449 ALLOCATOR_PROPERTIES req_props
= {1, 32 * 16 * 4, 1, 0}, ret_props
;
1450 IBaseFilter
*filter
= create_vmr7(VMRMode_Windowed
);
1451 IFilterGraph2
*graph
= create_graph();
1452 struct testfilter source
;
1453 IMemAllocator
*allocator
;
1454 IMediaControl
*control
;
1455 IMemInputPin
*input
;
1462 static const GUID
*subtype_tests
[] =
1464 &MEDIASUBTYPE_RGB565
,
1465 &MEDIASUBTYPE_RGB24
,
1466 &MEDIASUBTYPE_RGB32
,
1470 testfilter_init(&source
);
1472 IFilterGraph2_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
1473 IFilterGraph2_AddFilter(graph
, filter
, NULL
);
1474 IFilterGraph2_QueryInterface(graph
, &IID_IMediaControl
, (void **)&control
);
1476 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
1478 vih
.bmiHeader
.biBitCount
= 16;
1479 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
1480 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
1482 vih
.bmiHeader
.biBitCount
= 32;
1483 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
1484 if (hr
== VFW_E_TYPE_NOT_ACCEPTED
) /* w7u */
1486 vih
.bmiHeader
.biBitCount
= 24;
1487 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
1488 /* w7u is also rather buggy with its allocator. Requesting a size of
1489 * 32 * 16 * 4 succeeds and returns that size from SetProperties(), but
1490 * the actual samples only have a size of 32 * 16 * 3. */
1491 req_props
.cbBuffer
= 32 * 16 * 3;
1493 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1494 hr
= IFilterGraph2_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
1495 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1496 hr
= IFilterGraph2_Disconnect(graph
, pin
);
1497 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1499 for (i
= 0; i
< ARRAY_SIZE(subtype_tests
); ++i
)
1501 req_mt
.subtype
= *subtype_tests
[i
];
1502 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
1503 ok(hr
== S_OK
, "Got hr %#x for subtype %s.\n", hr
, wine_dbgstr_guid(subtype_tests
[i
]));
1505 hr
= IFilterGraph2_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
1506 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1507 hr
= IFilterGraph2_Disconnect(graph
, pin
);
1508 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1511 req_mt
.formattype
= FORMAT_None
;
1512 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
1513 ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
1514 req_mt
.formattype
= FORMAT_VideoInfo
;
1516 req_mt
.subtype
= MEDIASUBTYPE_RGB8
;
1517 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
1518 todo_wine
ok(hr
== VFW_E_TYPE_NOT_ACCEPTED
, "Got hr %#x.\n", hr
);
1521 IFilterGraph2_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
1522 IFilterGraph2_Disconnect(graph
, pin
);
1524 req_mt
.subtype
= MEDIASUBTYPE_RGB32
;
1526 peer
= (IPin
*)0xdeadbeef;
1527 hr
= IPin_ConnectedTo(pin
, &peer
);
1528 ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
1529 ok(!peer
, "Got peer %p.\n", peer
);
1531 hr
= IPin_ConnectionMediaType(pin
, &mt
);
1532 ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
1534 hr
= IMediaControl_Pause(control
);
1535 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1536 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
1537 ok(hr
== VFW_E_NOT_STOPPED
, "Got hr %#x.\n", hr
);
1538 hr
= IMediaControl_Stop(control
);
1539 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1541 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
1542 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1544 hr
= IPin_ConnectedTo(pin
, &peer
);
1545 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1546 ok(peer
== &source
.source
.pin
.IPin_iface
, "Got peer %p.\n", peer
);
1549 hr
= IPin_ConnectionMediaType(pin
, &mt
);
1550 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1551 ok(compare_media_types(&mt
, &req_mt
), "Media types didn't match.\n");
1553 /* Disconnecting while not stopped is broken: it returns S_OK, but
1554 * subsequent attempts to connect return VFW_E_ALREADY_CONNECTED. */
1556 IPin_QueryInterface(pin
, &IID_IMemInputPin
, (void **)&input
);
1558 test_allocator(input
);
1560 hr
= IMemInputPin_GetAllocator(input
, &allocator
);
1561 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1562 hr
= IMemAllocator_SetProperties(allocator
, &req_props
, &ret_props
);
1563 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1564 ok(!memcmp(&ret_props
, &req_props
, sizeof(req_props
)), "Properties did not match.\n");
1565 hr
= IMemAllocator_Commit(allocator
);
1566 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1567 IMemAllocator_Release(allocator
);
1569 hr
= IMemInputPin_ReceiveCanBlock(input
);
1570 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1572 test_filter_state(input
, control
);
1573 test_flushing(pin
, input
, control
);
1574 test_current_image(filter
, input
, control
, &vih
.bmiHeader
);
1575 test_window_close(pin
, input
, control
);
1577 hr
= IFilterGraph2_Disconnect(graph
, pin
);
1578 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1579 hr
= IFilterGraph2_Disconnect(graph
, pin
);
1580 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1581 ok(source
.source
.pin
.peer
== pin
, "Got peer %p.\n", peer
);
1582 IFilterGraph2_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
1584 peer
= (IPin
*)0xdeadbeef;
1585 hr
= IPin_ConnectedTo(pin
, &peer
);
1586 ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
1587 ok(!peer
, "Got peer %p.\n", peer
);
1589 hr
= IPin_ConnectionMediaType(pin
, &mt
);
1590 ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
1592 IMemInputPin_Release(input
);
1594 IMediaControl_Release(control
);
1595 ref
= IFilterGraph2_Release(graph
);
1596 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1597 ref
= IBaseFilter_Release(filter
);
1598 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1599 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
1600 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1603 static void test_overlay(void)
1605 IBaseFilter
*filter
= create_vmr7(0);
1612 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
1614 hr
= IPin_QueryInterface(pin
, &IID_IOverlay
, (void **)&overlay
);
1615 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1617 hwnd
= (HWND
)0xdeadbeef;
1618 hr
= IOverlay_GetWindowHandle(overlay
, &hwnd
);
1619 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1620 ok(hwnd
&& hwnd
!= (HWND
)0xdeadbeef, "Got invalid window %p.\n", hwnd
);
1622 IOverlay_Release(overlay
);
1624 ref
= IBaseFilter_Release(filter
);
1625 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1628 /* try to make sure pending X events have been processed before continuing */
1629 static void flush_events(void)
1635 time
= GetTickCount() + diff
;
1638 if (MsgWaitForMultipleObjects(0, NULL
, FALSE
, 100, QS_ALLINPUT
) == WAIT_TIMEOUT
)
1640 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
1641 DispatchMessageA(&msg
);
1642 diff
= time
- GetTickCount();
1646 static LRESULT CALLBACK
window_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1648 if (winetest_debug
> 1)
1649 trace("hwnd %p, msg %#x, wparam %#lx, lparam %#lx.\n", hwnd
, msg
, wparam
, lparam
);
1651 if (wparam
== 0xdeadbeef)
1654 return DefWindowProcA(hwnd
, msg
, wparam
, lparam
);
1657 static void test_video_window_caption(IVideoWindow
*window
, HWND hwnd
)
1663 hr
= IVideoWindow_get_Caption(window
, &caption
);
1664 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1665 ok(!wcscmp(caption
, L
"ActiveMovie Window"), "Got caption %s.\n", wine_dbgstr_w(caption
));
1666 SysFreeString(caption
);
1668 GetWindowTextW(hwnd
, text
, ARRAY_SIZE(text
));
1669 ok(!wcscmp(text
, L
"ActiveMovie Window"), "Got caption %s.\n", wine_dbgstr_w(text
));
1671 caption
= SysAllocString(L
"foo");
1672 hr
= IVideoWindow_put_Caption(window
, caption
);
1673 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1674 SysFreeString(caption
);
1676 hr
= IVideoWindow_get_Caption(window
, &caption
);
1677 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1678 ok(!wcscmp(caption
, L
"foo"), "Got caption %s.\n", wine_dbgstr_w(caption
));
1679 SysFreeString(caption
);
1681 GetWindowTextW(hwnd
, text
, ARRAY_SIZE(text
));
1682 ok(!wcscmp(text
, L
"foo"), "Got caption %s.\n", wine_dbgstr_w(text
));
1685 static void test_video_window_style(IVideoWindow
*window
, HWND hwnd
, HWND our_hwnd
)
1690 hr
= IVideoWindow_get_WindowStyle(window
, &style
);
1691 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1692 ok(style
== (WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_OVERLAPPEDWINDOW
),
1693 "Got style %#x.\n", style
);
1695 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
1696 ok(style
== (WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_OVERLAPPEDWINDOW
),
1697 "Got style %#x.\n", style
);
1699 hr
= IVideoWindow_put_WindowStyle(window
, style
| WS_DISABLED
);
1700 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1701 hr
= IVideoWindow_put_WindowStyle(window
, style
| WS_HSCROLL
);
1702 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1703 hr
= IVideoWindow_put_WindowStyle(window
, style
| WS_VSCROLL
);
1704 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1705 hr
= IVideoWindow_put_WindowStyle(window
, style
| WS_MAXIMIZE
);
1706 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1707 hr
= IVideoWindow_put_WindowStyle(window
, style
| WS_MINIMIZE
);
1708 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1710 hr
= IVideoWindow_put_WindowStyle(window
, style
& ~WS_CLIPCHILDREN
);
1711 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1713 hr
= IVideoWindow_get_WindowStyle(window
, &style
);
1714 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1715 ok(style
== (WS_CLIPSIBLINGS
| WS_OVERLAPPEDWINDOW
), "Got style %#x.\n", style
);
1717 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
1718 ok(style
== (WS_CLIPSIBLINGS
| WS_OVERLAPPEDWINDOW
), "Got style %#x.\n", style
);
1720 ok(GetActiveWindow() == our_hwnd
, "Got active window %p.\n", GetActiveWindow());
1722 hr
= IVideoWindow_get_WindowStyleEx(window
, &style
);
1723 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1724 ok(style
== WS_EX_WINDOWEDGE
, "Got style %#x.\n", style
);
1726 style
= GetWindowLongA(hwnd
, GWL_EXSTYLE
);
1727 ok(style
== WS_EX_WINDOWEDGE
, "Got style %#x.\n", style
);
1729 hr
= IVideoWindow_put_WindowStyleEx(window
, style
| WS_EX_TRANSPARENT
);
1730 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1732 hr
= IVideoWindow_get_WindowStyleEx(window
, &style
);
1733 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1734 ok(style
== (WS_EX_WINDOWEDGE
| WS_EX_TRANSPARENT
), "Got style %#x.\n", style
);
1736 style
= GetWindowLongA(hwnd
, GWL_EXSTYLE
);
1737 ok(style
== (WS_EX_WINDOWEDGE
| WS_EX_TRANSPARENT
), "Got style %#x.\n", style
);
1740 static BOOL CALLBACK
top_window_cb(HWND hwnd
, LPARAM ctx
)
1743 GetWindowThreadProcessId(hwnd
, &pid
);
1744 if (pid
== GetCurrentProcessId() && (GetWindowLongW(hwnd
, GWL_STYLE
) & WS_VISIBLE
))
1746 *(HWND
*)ctx
= hwnd
;
1752 static HWND
get_top_window(void)
1755 EnumWindows(top_window_cb
, (LPARAM
)&hwnd
);
1759 static void test_video_window_state(IVideoWindow
*window
, HWND hwnd
, HWND our_hwnd
)
1765 SetWindowPos(our_hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
1767 hr
= IVideoWindow_get_WindowState(window
, &state
);
1768 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1769 ok(state
== SW_HIDE
, "Got state %d.\n", state
);
1771 hr
= IVideoWindow_get_Visible(window
, &state
);
1772 ok(state
== OAFALSE
, "Got state %d.\n", state
);
1774 ok(!IsWindowVisible(hwnd
), "Window should not be visible.\n");
1775 ok(!IsIconic(hwnd
), "Window should not be minimized.\n");
1776 ok(!IsZoomed(hwnd
), "Window should not be maximized.\n");
1778 hr
= IVideoWindow_put_WindowState(window
, SW_SHOWNA
);
1779 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1781 hr
= IVideoWindow_get_WindowState(window
, &state
);
1782 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1783 ok(state
== SW_SHOW
, "Got state %d.\n", state
);
1785 hr
= IVideoWindow_get_Visible(window
, &state
);
1786 ok(state
== OATRUE
, "Got state %d.\n", state
);
1788 ok(IsWindowVisible(hwnd
), "Window should be visible.\n");
1789 ok(!IsIconic(hwnd
), "Window should not be minimized.\n");
1790 ok(!IsZoomed(hwnd
), "Window should not be maximized.\n");
1791 ok(GetActiveWindow() == our_hwnd
, "Got active window %p.\n", GetActiveWindow());
1792 top
= get_top_window();
1793 ok(top
== hwnd
, "Got top window %p.\n", top
);
1795 hr
= IVideoWindow_put_WindowState(window
, SW_MINIMIZE
);
1796 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1798 hr
= IVideoWindow_get_WindowState(window
, &state
);
1799 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1800 ok(state
== SW_MINIMIZE
, "Got state %d.\n", state
);
1802 hr
= IVideoWindow_get_Visible(window
, &state
);
1803 ok(state
== OATRUE
, "Got state %d.\n", state
);
1805 ok(IsWindowVisible(hwnd
), "Window should be visible.\n");
1806 ok(IsIconic(hwnd
), "Window should be minimized.\n");
1807 ok(!IsZoomed(hwnd
), "Window should not be maximized.\n");
1808 ok(GetActiveWindow() == our_hwnd
, "Got active window %p.\n", GetActiveWindow());
1810 hr
= IVideoWindow_put_WindowState(window
, SW_RESTORE
);
1811 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1813 hr
= IVideoWindow_get_WindowState(window
, &state
);
1814 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1815 ok(state
== SW_SHOW
, "Got state %d.\n", state
);
1817 hr
= IVideoWindow_get_Visible(window
, &state
);
1818 ok(state
== OATRUE
, "Got state %d.\n", state
);
1820 ok(IsWindowVisible(hwnd
), "Window should be visible.\n");
1821 ok(!IsIconic(hwnd
), "Window should not be minimized.\n");
1822 ok(!IsZoomed(hwnd
), "Window should not be maximized.\n");
1823 ok(GetActiveWindow() == hwnd
, "Got active window %p.\n", GetActiveWindow());
1825 hr
= IVideoWindow_put_WindowState(window
, SW_MAXIMIZE
);
1826 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1828 hr
= IVideoWindow_get_WindowState(window
, &state
);
1829 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1830 ok(state
== SW_MAXIMIZE
, "Got state %d.\n", state
);
1832 hr
= IVideoWindow_get_Visible(window
, &state
);
1833 ok(state
== OATRUE
, "Got state %d.\n", state
);
1835 ok(IsWindowVisible(hwnd
), "Window should be visible.\n");
1836 ok(!IsIconic(hwnd
), "Window should be minimized.\n");
1837 ok(IsZoomed(hwnd
), "Window should not be maximized.\n");
1838 ok(GetActiveWindow() == hwnd
, "Got active window %p.\n", GetActiveWindow());
1840 hr
= IVideoWindow_put_WindowState(window
, SW_RESTORE
);
1841 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1843 hr
= IVideoWindow_put_WindowState(window
, SW_HIDE
);
1844 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1846 hr
= IVideoWindow_get_WindowState(window
, &state
);
1847 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1848 ok(state
== SW_HIDE
, "Got state %d.\n", state
);
1850 hr
= IVideoWindow_get_Visible(window
, &state
);
1851 ok(state
== OAFALSE
, "Got state %d.\n", state
);
1853 ok(!IsWindowVisible(hwnd
), "Window should not be visible.\n");
1854 ok(!IsIconic(hwnd
), "Window should not be minimized.\n");
1855 ok(!IsZoomed(hwnd
), "Window should not be maximized.\n");
1856 ok(GetActiveWindow() == our_hwnd
, "Got active window %p.\n", GetActiveWindow());
1858 hr
= IVideoWindow_put_Visible(window
, OATRUE
);
1859 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1861 hr
= IVideoWindow_get_WindowState(window
, &state
);
1862 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1863 ok(state
== SW_SHOW
, "Got state %d.\n", state
);
1865 hr
= IVideoWindow_get_Visible(window
, &state
);
1866 ok(state
== OATRUE
, "Got state %d.\n", state
);
1868 ok(IsWindowVisible(hwnd
), "Window should be visible.\n");
1869 ok(!IsIconic(hwnd
), "Window should not be minimized.\n");
1870 ok(!IsZoomed(hwnd
), "Window should not be maximized.\n");
1871 ok(GetActiveWindow() == hwnd
, "Got active window %p.\n", GetActiveWindow());
1873 hr
= IVideoWindow_put_Visible(window
, OAFALSE
);
1874 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1876 hr
= IVideoWindow_get_WindowState(window
, &state
);
1877 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1878 ok(state
== SW_HIDE
, "Got state %d.\n", state
);
1880 hr
= IVideoWindow_get_Visible(window
, &state
);
1881 ok(state
== OAFALSE
, "Got state %d.\n", state
);
1883 ok(!IsWindowVisible(hwnd
), "Window should not be visible.\n");
1884 ok(!IsIconic(hwnd
), "Window should not be minimized.\n");
1885 ok(!IsZoomed(hwnd
), "Window should not be maximized.\n");
1886 ok(GetActiveWindow() == our_hwnd
, "Got active window %p.\n", GetActiveWindow());
1888 hr
= IVideoWindow_put_WindowState(window
, SW_SHOWNA
);
1889 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1891 hr
= IVideoWindow_SetWindowForeground(window
, TRUE
);
1892 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1894 SetWindowPos(our_hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
1895 hr
= IVideoWindow_SetWindowForeground(window
, OATRUE
);
1896 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1897 ok(GetActiveWindow() == hwnd
, "Got active window %p.\n", GetActiveWindow());
1898 ok(GetFocus() == hwnd
, "Got focus window %p.\n", GetFocus());
1899 ok(GetForegroundWindow() == hwnd
, "Got foreground window %p.\n", GetForegroundWindow());
1900 top
= get_top_window();
1901 ok(top
== hwnd
, "Got top window %p.\n", top
);
1903 hr
= IVideoWindow_SetWindowForeground(window
, OAFALSE
);
1904 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1905 ok(GetActiveWindow() == hwnd
, "Got active window %p.\n", GetActiveWindow());
1906 ok(GetFocus() == hwnd
, "Got focus window %p.\n", GetFocus());
1907 ok(GetForegroundWindow() == hwnd
, "Got foreground window %p.\n", GetForegroundWindow());
1908 top
= get_top_window();
1909 ok(top
== hwnd
, "Got top window %p.\n", top
);
1911 SetWindowPos(our_hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
1912 hr
= IVideoWindow_SetWindowForeground(window
, OAFALSE
);
1913 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1914 ok(GetActiveWindow() == our_hwnd
, "Got active window %p.\n", GetActiveWindow());
1915 ok(GetFocus() == our_hwnd
, "Got focus window %p.\n", GetFocus());
1916 ok(GetForegroundWindow() == our_hwnd
, "Got foreground window %p.\n", GetForegroundWindow());
1917 top
= get_top_window();
1918 ok(top
== hwnd
, "Got top window %p.\n", top
);
1921 static void test_video_window_position(IVideoWindow
*window
, HWND hwnd
, HWND our_hwnd
)
1923 LONG left
, width
, top
, height
, expect_width
, expect_height
;
1924 RECT rect
= {0, 0, 600, 400};
1928 SetWindowPos(our_hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
1930 AdjustWindowRect(&rect
, GetWindowLongA(hwnd
, GWL_STYLE
), FALSE
);
1931 expect_width
= rect
.right
- rect
.left
;
1932 expect_height
= rect
.bottom
- rect
.top
;
1934 hr
= IVideoWindow_put_Left(window
, 0);
1935 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1936 hr
= IVideoWindow_put_Top(window
, 0);
1937 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1939 hr
= IVideoWindow_get_Left(window
, &left
);
1940 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1941 ok(left
== 0, "Got left %d.\n", left
);
1942 hr
= IVideoWindow_get_Top(window
, &top
);
1943 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1944 ok(top
== 0, "Got top %d.\n", top
);
1945 hr
= IVideoWindow_get_Width(window
, &width
);
1946 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1947 ok(width
== expect_width
, "Got width %d.\n", width
);
1948 hr
= IVideoWindow_get_Height(window
, &height
);
1949 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1950 ok(height
== expect_height
, "Got height %d.\n", height
);
1951 hr
= IVideoWindow_GetWindowPosition(window
, &left
, &top
, &width
, &height
);
1952 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1953 ok(left
== 0, "Got left %d.\n", left
);
1954 ok(top
== 0, "Got top %d.\n", top
);
1955 ok(width
== expect_width
, "Got width %d.\n", width
);
1956 ok(height
== expect_height
, "Got height %d.\n", height
);
1957 GetWindowRect(hwnd
, &rect
);
1958 ok(rect
.left
== 0, "Got window left %d.\n", rect
.left
);
1959 ok(rect
.top
== 0, "Got window top %d.\n", rect
.top
);
1960 ok(rect
.right
== expect_width
, "Got window right %d.\n", rect
.right
);
1961 ok(rect
.bottom
== expect_height
, "Got window bottom %d.\n", rect
.bottom
);
1963 hr
= IVideoWindow_put_Left(window
, 10);
1964 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1966 hr
= IVideoWindow_get_Left(window
, &left
);
1967 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1968 ok(left
== 10, "Got left %d.\n", left
);
1969 hr
= IVideoWindow_get_Top(window
, &top
);
1970 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1971 ok(top
== 0, "Got top %d.\n", top
);
1972 hr
= IVideoWindow_get_Width(window
, &width
);
1973 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1974 ok(width
== expect_width
, "Got width %d.\n", width
);
1975 hr
= IVideoWindow_get_Height(window
, &height
);
1976 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1977 ok(height
== expect_height
, "Got height %d.\n", height
);
1978 hr
= IVideoWindow_GetWindowPosition(window
, &left
, &top
, &width
, &height
);
1979 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1980 ok(left
== 10, "Got left %d.\n", left
);
1981 ok(top
== 0, "Got top %d.\n", top
);
1982 ok(width
== expect_width
, "Got width %d.\n", width
);
1983 ok(height
== expect_height
, "Got height %d.\n", height
);
1984 GetWindowRect(hwnd
, &rect
);
1985 ok(rect
.left
== 10, "Got window left %d.\n", rect
.left
);
1986 ok(rect
.top
== 0, "Got window top %d.\n", rect
.top
);
1987 ok(rect
.right
== 10 + expect_width
, "Got window right %d.\n", rect
.right
);
1988 ok(rect
.bottom
== expect_height
, "Got window bottom %d.\n", rect
.bottom
);
1990 hr
= IVideoWindow_put_Height(window
, 200);
1991 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1993 hr
= IVideoWindow_get_Left(window
, &left
);
1994 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1995 ok(left
== 10, "Got left %d.\n", left
);
1996 hr
= IVideoWindow_get_Top(window
, &top
);
1997 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1998 ok(top
== 0, "Got top %d.\n", top
);
1999 hr
= IVideoWindow_get_Width(window
, &width
);
2000 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2001 ok(width
== expect_width
, "Got width %d.\n", width
);
2002 hr
= IVideoWindow_get_Height(window
, &height
);
2003 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2004 ok(height
== 200, "Got height %d.\n", height
);
2005 hr
= IVideoWindow_GetWindowPosition(window
, &left
, &top
, &width
, &height
);
2006 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2007 ok(left
== 10, "Got left %d.\n", left
);
2008 ok(top
== 0, "Got top %d.\n", top
);
2009 ok(width
== expect_width
, "Got width %d.\n", width
);
2010 ok(height
== 200, "Got height %d.\n", height
);
2011 GetWindowRect(hwnd
, &rect
);
2012 ok(rect
.left
== 10, "Got window left %d.\n", rect
.left
);
2013 ok(rect
.top
== 0, "Got window top %d.\n", rect
.top
);
2014 ok(rect
.right
== 10 + expect_width
, "Got window right %d.\n", rect
.right
);
2015 ok(rect
.bottom
== 200, "Got window bottom %d.\n", rect
.bottom
);
2017 hr
= IVideoWindow_SetWindowPosition(window
, 100, 200, 300, 400);
2018 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2020 hr
= IVideoWindow_get_Left(window
, &left
);
2021 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2022 ok(left
== 100, "Got left %d.\n", left
);
2023 hr
= IVideoWindow_get_Top(window
, &top
);
2024 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2025 ok(top
== 200, "Got top %d.\n", top
);
2026 hr
= IVideoWindow_get_Width(window
, &width
);
2027 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2028 ok(width
== 300, "Got width %d.\n", width
);
2029 hr
= IVideoWindow_get_Height(window
, &height
);
2030 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2031 ok(height
== 400, "Got height %d.\n", height
);
2032 hr
= IVideoWindow_GetWindowPosition(window
, &left
, &top
, &width
, &height
);
2033 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2034 ok(left
== 100, "Got left %d.\n", left
);
2035 ok(top
== 200, "Got top %d.\n", top
);
2036 ok(width
== 300, "Got width %d.\n", width
);
2037 ok(height
== 400, "Got height %d.\n", height
);
2038 GetWindowRect(hwnd
, &rect
);
2039 ok(rect
.left
== 100, "Got window left %d.\n", rect
.left
);
2040 ok(rect
.top
== 200, "Got window top %d.\n", rect
.top
);
2041 ok(rect
.right
== 400, "Got window right %d.\n", rect
.right
);
2042 ok(rect
.bottom
== 600, "Got window bottom %d.\n", rect
.bottom
);
2044 ok(GetActiveWindow() == our_hwnd
, "Got active window %p.\n", GetActiveWindow());
2045 top_hwnd
= get_top_window();
2046 ok(top_hwnd
== our_hwnd
, "Got top window %p.\n", top_hwnd
);
2049 static void test_video_window_owner(IVideoWindow
*window
, HWND hwnd
, HWND our_hwnd
)
2051 HWND parent
, top_hwnd
;
2056 SetWindowPos(our_hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
2058 hr
= IVideoWindow_get_Owner(window
, &oahwnd
);
2059 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2060 ok(!oahwnd
, "Got owner %#lx.\n", oahwnd
);
2062 parent
= GetAncestor(hwnd
, GA_PARENT
);
2063 ok(parent
== GetDesktopWindow(), "Got parent %p.\n", parent
);
2064 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
2065 ok(!(style
& WS_CHILD
), "Got style %#x.\n", style
);
2067 hr
= IVideoWindow_put_Owner(window
, (OAHWND
)our_hwnd
);
2068 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2070 hr
= IVideoWindow_get_Owner(window
, &oahwnd
);
2071 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2072 ok(oahwnd
== (OAHWND
)our_hwnd
, "Got owner %#lx.\n", oahwnd
);
2074 parent
= GetAncestor(hwnd
, GA_PARENT
);
2075 ok(parent
== our_hwnd
, "Got parent %p.\n", parent
);
2076 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
2077 ok((style
& WS_CHILD
), "Got style %#x.\n", style
);
2079 ok(GetActiveWindow() == our_hwnd
, "Got active window %p.\n", GetActiveWindow());
2080 top_hwnd
= get_top_window();
2081 ok(top_hwnd
== our_hwnd
, "Got top window %p.\n", top_hwnd
);
2083 ShowWindow(our_hwnd
, SW_HIDE
);
2085 hr
= IVideoWindow_put_Visible(window
, OATRUE
);
2086 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2088 hr
= IVideoWindow_get_Visible(window
, &state
);
2089 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2090 ok(state
== OAFALSE
, "Got state %d.\n", state
);
2092 hr
= IVideoWindow_put_Owner(window
, 0);
2093 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2095 hr
= IVideoWindow_get_Owner(window
, &oahwnd
);
2096 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2097 ok(!oahwnd
, "Got owner %#lx.\n", oahwnd
);
2099 parent
= GetAncestor(hwnd
, GA_PARENT
);
2100 ok(parent
== GetDesktopWindow(), "Got parent %p.\n", parent
);
2101 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
2102 ok(!(style
& WS_CHILD
), "Got style %#x.\n", style
);
2104 ok(GetActiveWindow() == hwnd
, "Got active window %p.\n", GetActiveWindow());
2105 top_hwnd
= get_top_window();
2106 ok(top_hwnd
== hwnd
, "Got top window %p.\n", top_hwnd
);
2108 hr
= IVideoWindow_get_Visible(window
, &state
);
2109 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2110 ok(state
== OATRUE
, "Got state %d.\n", state
);
2113 struct notify_message_params
2115 IVideoWindow
*window
;
2120 static DWORD CALLBACK
notify_message_proc(void *arg
)
2122 const struct notify_message_params
*params
= arg
;
2123 HRESULT hr
= IVideoWindow_NotifyOwnerMessage(params
->window
, (OAHWND
)params
->hwnd
, params
->message
, 0, 0);
2124 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2128 static void test_video_window_messages(IVideoWindow
*window
, HWND hwnd
, HWND our_hwnd
)
2130 struct notify_message_params params
;
2138 static UINT drain_tests
[] =
2166 hr
= IVideoWindow_get_MessageDrain(window
, &oahwnd
);
2167 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2168 ok(!oahwnd
, "Got window %#lx.\n", oahwnd
);
2170 hr
= IVideoWindow_put_MessageDrain(window
, (OAHWND
)our_hwnd
);
2171 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2173 hr
= IVideoWindow_get_MessageDrain(window
, &oahwnd
);
2174 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2175 ok(oahwnd
== (OAHWND
)our_hwnd
, "Got window %#lx.\n", oahwnd
);
2177 for (i
= 0; i
< ARRAY_SIZE(drain_tests
); ++i
)
2179 SendMessageA(hwnd
, drain_tests
[i
], 0xdeadbeef, 0);
2180 ret
= PeekMessageA(&msg
, 0, drain_tests
[i
], drain_tests
[i
], PM_REMOVE
);
2181 ok(ret
, "Expected a message.\n");
2182 ok(msg
.hwnd
== our_hwnd
, "Got hwnd %p.\n", msg
.hwnd
);
2183 ok(msg
.message
== drain_tests
[i
], "Got message %#x.\n", msg
.message
);
2184 ok(msg
.wParam
== 0xdeadbeef, "Got wparam %#lx.\n", msg
.wParam
);
2185 ok(!msg
.lParam
, "Got lparam %#lx.\n", msg
.lParam
);
2186 DispatchMessageA(&msg
);
2188 ret
= PeekMessageA(&msg
, 0, drain_tests
[i
], drain_tests
[i
], PM_REMOVE
);
2189 ok(!ret
, "Got unexpected message %#x.\n", msg
.message
);
2192 hr
= IVideoWindow_put_MessageDrain(window
, 0);
2193 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2195 hr
= IVideoWindow_put_Owner(window
, (OAHWND
)our_hwnd
);
2196 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2200 /* Demonstrate that messages should be sent, not posted, and that only some
2201 * messages should be forwarded. A previous implementation unconditionally
2202 * posted all messages. */
2204 hr
= IVideoWindow_NotifyOwnerMessage(window
, (OAHWND
)our_hwnd
, WM_SYSCOLORCHANGE
, 0, 0);
2205 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2207 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
2209 ok(msg
.message
!= WM_SYSCOLORCHANGE
, "WM_SYSCOLORCHANGE should not be posted.\n");
2210 DispatchMessageA(&msg
);
2213 hr
= IVideoWindow_NotifyOwnerMessage(window
, (OAHWND
)our_hwnd
, WM_FONTCHANGE
, 0, 0);
2214 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2216 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
2218 ok(msg
.message
!= WM_FONTCHANGE
, "WM_FONTCHANGE should not be posted.\n");
2219 DispatchMessageA(&msg
);
2222 params
.window
= window
;
2223 params
.hwnd
= our_hwnd
;
2224 params
.message
= WM_SYSCOLORCHANGE
;
2225 thread
= CreateThread(NULL
, 0, notify_message_proc
, ¶ms
, 0, NULL
);
2226 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Thread should block.\n");
2228 while ((ret
= MsgWaitForMultipleObjects(1, &thread
, FALSE
, 1000, QS_ALLINPUT
)) == 1)
2230 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
2232 ok(msg
.message
!= WM_SYSCOLORCHANGE
, "WM_SYSCOLORCHANGE should not be posted.\n");
2233 DispatchMessageA(&msg
);
2236 ok(!ret
, "Wait timed out.\n");
2237 CloseHandle(thread
);
2239 params
.message
= WM_FONTCHANGE
;
2240 thread
= CreateThread(NULL
, 0, notify_message_proc
, ¶ms
, 0, NULL
);
2241 ok(!WaitForSingleObject(thread
, 1000), "Thread should not block.\n");
2242 CloseHandle(thread
);
2244 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
2246 ok(msg
.message
!= WM_FONTCHANGE
, "WM_FONTCHANGE should not be posted.\n");
2247 DispatchMessageA(&msg
);
2250 hr
= IVideoWindow_put_Owner(window
, 0);
2251 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2254 static void test_video_window_autoshow(IVideoWindow
*window
, IFilterGraph2
*graph
, HWND hwnd
)
2256 IMediaControl
*control
;
2260 IFilterGraph2_QueryInterface(graph
, &IID_IMediaControl
, (void **)&control
);
2262 hr
= IVideoWindow_get_AutoShow(window
, &l
);
2263 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2264 ok(l
== OATRUE
, "Got %d.\n", l
);
2266 hr
= IVideoWindow_put_Visible(window
, OAFALSE
);
2267 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2269 hr
= IMediaControl_Pause(control
);
2270 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2272 hr
= IVideoWindow_get_Visible(window
, &l
);
2273 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2274 ok(l
== OATRUE
, "Got %d.\n", l
);
2276 hr
= IMediaControl_Stop(control
);
2277 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2279 hr
= IVideoWindow_get_Visible(window
, &l
);
2280 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2281 ok(l
== OATRUE
, "Got %d.\n", l
);
2283 hr
= IVideoWindow_put_AutoShow(window
, OAFALSE
);
2284 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2286 hr
= IVideoWindow_put_Visible(window
, OAFALSE
);
2287 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2289 hr
= IMediaControl_Pause(control
);
2290 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2292 hr
= IVideoWindow_get_Visible(window
, &l
);
2293 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2294 ok(l
== OAFALSE
, "Got %d.\n", l
);
2296 hr
= IMediaControl_Stop(control
);
2297 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2299 IMediaControl_Release(control
);
2302 static void test_video_window(void)
2304 ALLOCATOR_PROPERTIES req_props
= {1, 600 * 400 * 4, 1, 0}, ret_props
;
2305 VIDEOINFOHEADER vih
=
2307 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
2308 .bmiHeader
.biBitCount
= 32,
2309 .bmiHeader
.biWidth
= 600,
2310 .bmiHeader
.biHeight
= 400,
2311 .bmiHeader
.biPlanes
= 1,
2312 .bmiHeader
.biCompression
= BI_RGB
,
2314 AM_MEDIA_TYPE req_mt
=
2316 .majortype
= MEDIATYPE_Video
,
2317 .subtype
= MEDIASUBTYPE_RGB32
,
2318 .formattype
= FORMAT_VideoInfo
,
2319 .cbFormat
= sizeof(vih
),
2320 .pbFormat
= (BYTE
*)&vih
,
2322 IFilterGraph2
*graph
= create_graph();
2323 WNDCLASSA window_class
= {0};
2324 struct testfilter source
;
2325 IMemAllocator
*allocator
;
2326 LONG width
, height
, l
;
2327 IVideoWindow
*window
;
2328 IMemInputPin
*input
;
2329 IBaseFilter
*filter
;
2330 HWND hwnd
, our_hwnd
;
2339 window_class
.lpszClassName
= "wine_test_class";
2340 window_class
.lpfnWndProc
= window_proc
;
2341 RegisterClassA(&window_class
);
2342 our_hwnd
= CreateWindowA("wine_test_class", "test window", WS_VISIBLE
| WS_OVERLAPPEDWINDOW
,
2343 100, 200, 300, 400, NULL
, NULL
, NULL
, NULL
);
2346 filter
= create_vmr7(0);
2349 ok(GetActiveWindow() == our_hwnd
, "Got active window %p.\n", GetActiveWindow());
2351 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
2352 IPin_QueryInterface(pin
, &IID_IMemInputPin
, (void **)&input
);
2354 hr
= IPin_QueryInterface(pin
, &IID_IOverlay
, (void **)&overlay
);
2355 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2357 hr
= IOverlay_GetWindowHandle(overlay
, &hwnd
);
2358 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2359 if (winetest_debug
> 1) trace("ours %p, theirs %p\n", our_hwnd
, hwnd
);
2360 GetWindowRect(hwnd
, &rect
);
2362 tid
= GetWindowThreadProcessId(hwnd
, NULL
);
2363 ok(tid
== GetCurrentThreadId(), "Expected tid %#x, got %#x.\n", GetCurrentThreadId(), tid
);
2365 hr
= IBaseFilter_QueryInterface(filter
, &IID_IVideoWindow
, (void **)&window
);
2366 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2368 hr
= IVideoWindow_get_Caption(window
, &caption
);
2369 todo_wine
ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
2371 hr
= IVideoWindow_get_WindowStyle(window
, &l
);
2372 todo_wine
ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
2374 hr
= IVideoWindow_get_AutoShow(window
, &l
);
2375 todo_wine
ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
2377 testfilter_init(&source
);
2378 IFilterGraph2_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, NULL
);
2379 IFilterGraph2_AddFilter(graph
, filter
, NULL
);
2380 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
2381 if (hr
== VFW_E_TYPE_NOT_ACCEPTED
) /* w7u */
2383 req_mt
.subtype
= MEDIASUBTYPE_RGB24
;
2384 vih
.bmiHeader
.biBitCount
= 24;
2385 req_props
.cbBuffer
= 32 * 16 * 3;
2386 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
2388 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2390 hr
= IMemInputPin_GetAllocator(input
, &allocator
);
2391 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2394 hr
= IMemAllocator_SetProperties(allocator
, &req_props
, &ret_props
);
2395 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2396 ok(!memcmp(&ret_props
, &req_props
, sizeof(req_props
)), "Properties did not match.\n");
2397 hr
= IMemAllocator_Commit(allocator
);
2398 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2399 IMemAllocator_Release(allocator
);
2402 ok(GetActiveWindow() == our_hwnd
, "Got active window %p.\n", GetActiveWindow());
2404 test_video_window_caption(window
, hwnd
);
2405 test_video_window_style(window
, hwnd
, our_hwnd
);
2406 test_video_window_state(window
, hwnd
, our_hwnd
);
2407 test_video_window_position(window
, hwnd
, our_hwnd
);
2408 test_video_window_autoshow(window
, graph
, hwnd
);
2409 test_video_window_owner(window
, hwnd
, our_hwnd
);
2410 test_video_window_messages(window
, hwnd
, our_hwnd
);
2412 hr
= IVideoWindow_put_FullScreenMode(window
, OATRUE
);
2413 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
2414 hr
= IVideoWindow_get_FullScreenMode(window
, &l
);
2415 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
2417 hr
= IVideoWindow_GetMinIdealImageSize(window
, &width
, &height
);
2418 todo_wine
ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
2419 hr
= IVideoWindow_GetMaxIdealImageSize(window
, &width
, &height
);
2420 todo_wine
ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
2422 IFilterGraph2_Release(graph
);
2423 IVideoWindow_Release(window
);
2424 IOverlay_Release(overlay
);
2425 IMemInputPin_Release(input
);
2427 ref
= IBaseFilter_Release(filter
);
2428 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2429 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
2430 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2431 DestroyWindow(our_hwnd
);
2434 static void check_source_position_(int line
, IBasicVideo
*video
,
2435 LONG expect_left
, LONG expect_top
, LONG expect_width
, LONG expect_height
)
2437 LONG left
, top
, width
, height
, l
;
2440 left
= top
= width
= height
= 0xdeadbeef;
2441 hr
= IBasicVideo_GetSourcePosition(video
, &left
, &top
, &width
, &height
);
2442 ok_(__FILE__
,line
)(hr
== S_OK
, "Got hr %#x.\n", hr
);
2443 ok_(__FILE__
,line
)(left
== expect_left
, "Got left %d.\n", left
);
2444 ok_(__FILE__
,line
)(top
== expect_top
, "Got top %d.\n", top
);
2445 ok_(__FILE__
,line
)(width
== expect_width
, "Got width %d.\n", width
);
2446 ok_(__FILE__
,line
)(height
== expect_height
, "Got height %d.\n", height
);
2449 hr
= IBasicVideo_get_SourceLeft(video
, &l
);
2450 ok_(__FILE__
,line
)(hr
== S_OK
, "Failed to get left, hr %#x.\n", hr
);
2451 ok_(__FILE__
,line
)(l
== left
, "Got left %d.\n", l
);
2454 hr
= IBasicVideo_get_SourceTop(video
, &l
);
2455 ok_(__FILE__
,line
)(hr
== S_OK
, "Failed to get top, hr %#x.\n", hr
);
2456 ok_(__FILE__
,line
)(l
== top
, "Got top %d.\n", l
);
2459 hr
= IBasicVideo_get_SourceWidth(video
, &l
);
2460 ok_(__FILE__
,line
)(hr
== S_OK
, "Failed to get width, hr %#x.\n", hr
);
2461 ok_(__FILE__
,line
)(l
== width
, "Got width %d.\n", l
);
2464 hr
= IBasicVideo_get_SourceHeight(video
, &l
);
2465 ok_(__FILE__
,line
)(hr
== S_OK
, "Failed to get height, hr %#x.\n", hr
);
2466 ok_(__FILE__
,line
)(l
== height
, "Got height %d.\n", l
);
2468 #define check_source_position(a,b,c,d,e) check_source_position_(__LINE__,a,b,c,d,e)
2470 static void test_basic_video_source(IBasicVideo
*video
)
2474 check_source_position(video
, 0, 0, 600, 400);
2475 hr
= IBasicVideo_IsUsingDefaultSource(video
);
2476 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2478 hr
= IBasicVideo_put_SourceLeft(video
, -10);
2479 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2480 hr
= IBasicVideo_put_SourceLeft(video
, 10);
2481 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2483 hr
= IBasicVideo_put_SourceTop(video
, -10);
2484 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2485 hr
= IBasicVideo_put_SourceTop(video
, 10);
2486 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2488 hr
= IBasicVideo_put_SourceWidth(video
, -500);
2489 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2490 hr
= IBasicVideo_put_SourceWidth(video
, 0);
2491 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2492 hr
= IBasicVideo_put_SourceWidth(video
, 700);
2493 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2494 hr
= IBasicVideo_put_SourceWidth(video
, 500);
2495 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2496 check_source_position(video
, 0, 0, 500, 400);
2497 hr
= IBasicVideo_IsUsingDefaultSource(video
);
2498 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2500 hr
= IBasicVideo_put_SourceHeight(video
, -300);
2501 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2502 hr
= IBasicVideo_put_SourceHeight(video
, 0);
2503 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2504 hr
= IBasicVideo_put_SourceHeight(video
, 600);
2505 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2506 hr
= IBasicVideo_put_SourceHeight(video
, 300);
2507 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2508 check_source_position(video
, 0, 0, 500, 300);
2509 hr
= IBasicVideo_IsUsingDefaultSource(video
);
2510 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2512 hr
= IBasicVideo_put_SourceLeft(video
, -10);
2513 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2514 hr
= IBasicVideo_put_SourceLeft(video
, 10);
2515 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2516 check_source_position(video
, 10, 0, 500, 300);
2517 hr
= IBasicVideo_IsUsingDefaultSource(video
);
2518 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2520 hr
= IBasicVideo_put_SourceTop(video
, -10);
2521 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2522 hr
= IBasicVideo_put_SourceTop(video
, 20);
2523 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2524 check_source_position(video
, 10, 20, 500, 300);
2525 hr
= IBasicVideo_IsUsingDefaultSource(video
);
2526 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2528 hr
= IBasicVideo_SetSourcePosition(video
, 4, 5, 60, 40);
2529 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2530 check_source_position(video
, 4, 5, 60, 40);
2531 hr
= IBasicVideo_IsUsingDefaultSource(video
);
2532 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2534 hr
= IBasicVideo_SetSourcePosition(video
, 0, 0, 600, 400);
2535 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2536 check_source_position(video
, 0, 0, 600, 400);
2537 hr
= IBasicVideo_IsUsingDefaultSource(video
);
2538 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2540 hr
= IBasicVideo_SetSourcePosition(video
, 4, 5, 60, 40);
2541 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2542 hr
= IBasicVideo_SetDefaultSourcePosition(video
);
2543 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2544 check_source_position(video
, 0, 0, 600, 400);
2545 hr
= IBasicVideo_IsUsingDefaultSource(video
);
2546 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2549 static void check_destination_position_(int line
, IBasicVideo
*video
,
2550 LONG expect_left
, LONG expect_top
, LONG expect_width
, LONG expect_height
)
2552 LONG left
, top
, width
, height
, l
;
2555 left
= top
= width
= height
= 0xdeadbeef;
2556 hr
= IBasicVideo_GetDestinationPosition(video
, &left
, &top
, &width
, &height
);
2557 ok_(__FILE__
,line
)(hr
== S_OK
, "Failed to get position, hr %#x.\n", hr
);
2558 ok_(__FILE__
,line
)(left
== expect_left
, "Got left %d.\n", left
);
2559 ok_(__FILE__
,line
)(top
== expect_top
, "Got top %d.\n", top
);
2560 ok_(__FILE__
,line
)(width
== expect_width
, "Got width %d.\n", width
);
2561 ok_(__FILE__
,line
)(height
== expect_height
, "Got height %d.\n", height
);
2564 hr
= IBasicVideo_get_DestinationLeft(video
, &l
);
2565 ok_(__FILE__
,line
)(hr
== S_OK
, "Failed to get left, hr %#x.\n", hr
);
2566 ok_(__FILE__
,line
)(l
== left
, "Got left %d.\n", l
);
2569 hr
= IBasicVideo_get_DestinationTop(video
, &l
);
2570 ok_(__FILE__
,line
)(hr
== S_OK
, "Failed to get top, hr %#x.\n", hr
);
2571 ok_(__FILE__
,line
)(l
== top
, "Got top %d.\n", l
);
2574 hr
= IBasicVideo_get_DestinationWidth(video
, &l
);
2575 ok_(__FILE__
,line
)(hr
== S_OK
, "Failed to get width, hr %#x.\n", hr
);
2576 ok_(__FILE__
,line
)(l
== width
, "Got width %d.\n", l
);
2579 hr
= IBasicVideo_get_DestinationHeight(video
, &l
);
2580 ok_(__FILE__
,line
)(hr
== S_OK
, "Failed to get height, hr %#x.\n", hr
);
2581 ok_(__FILE__
,line
)(l
== height
, "Got height %d.\n", l
);
2583 #define check_destination_position(a,b,c,d,e) check_destination_position_(__LINE__,a,b,c,d,e)
2585 static void test_basic_video_destination(IBasicVideo
*video
)
2587 IVideoWindow
*window
;
2591 IBasicVideo_QueryInterface(video
, &IID_IVideoWindow
, (void **)&window
);
2593 check_destination_position(video
, 0, 0, 600, 400);
2594 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2595 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2597 hr
= IBasicVideo_put_DestinationLeft(video
, -10);
2598 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2599 check_destination_position(video
, -10, 0, 600, 400);
2600 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2601 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2603 hr
= IBasicVideo_put_DestinationLeft(video
, 10);
2604 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2605 check_destination_position(video
, 10, 0, 600, 400);
2606 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2607 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2609 hr
= IBasicVideo_put_DestinationTop(video
, -20);
2610 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2611 check_destination_position(video
, 10, -20, 600, 400);
2612 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2613 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2615 hr
= IBasicVideo_put_DestinationTop(video
, 20);
2616 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2617 check_destination_position(video
, 10, 20, 600, 400);
2618 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2619 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2621 hr
= IBasicVideo_put_DestinationWidth(video
, -700);
2622 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2623 hr
= IBasicVideo_put_DestinationWidth(video
, 0);
2624 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2625 hr
= IBasicVideo_put_DestinationWidth(video
, 700);
2626 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2627 check_destination_position(video
, 10, 20, 700, 400);
2628 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2629 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2631 hr
= IBasicVideo_put_DestinationWidth(video
, 500);
2632 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2633 check_destination_position(video
, 10, 20, 500, 400);
2634 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2635 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2637 hr
= IBasicVideo_put_DestinationHeight(video
, -500);
2638 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2639 hr
= IBasicVideo_put_DestinationHeight(video
, 0);
2640 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
2641 hr
= IBasicVideo_put_DestinationHeight(video
, 500);
2642 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2643 check_destination_position(video
, 10, 20, 500, 500);
2644 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2645 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2647 hr
= IBasicVideo_put_DestinationHeight(video
, 300);
2648 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2649 check_destination_position(video
, 10, 20, 500, 300);
2650 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2651 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2653 hr
= IBasicVideo_SetDestinationPosition(video
, 4, 5, 60, 40);
2654 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2655 check_destination_position(video
, 4, 5, 60, 40);
2656 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2657 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2659 hr
= IBasicVideo_SetDestinationPosition(video
, 0, 0, 600, 400);
2660 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2661 check_destination_position(video
, 0, 0, 600, 400);
2662 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2663 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2665 hr
= IBasicVideo_SetDestinationPosition(video
, 4, 5, 60, 40);
2666 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2667 hr
= IBasicVideo_SetDefaultDestinationPosition(video
);
2668 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2669 check_destination_position(video
, 0, 0, 600, 400);
2670 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2671 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2673 SetRect(&rect
, 100, 200, 500, 500);
2674 AdjustWindowRect(&rect
, WS_OVERLAPPEDWINDOW
, FALSE
);
2675 hr
= IVideoWindow_SetWindowPosition(window
, rect
.left
, rect
.top
,
2676 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
);
2677 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2678 check_destination_position(video
, 0, 0, 400, 300);
2679 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2680 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2682 hr
= IBasicVideo_SetDestinationPosition(video
, 0, 0, 400, 300);
2683 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2684 check_destination_position(video
, 0, 0, 400, 300);
2685 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2686 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2688 SetRect(&rect
, 100, 200, 600, 600);
2689 AdjustWindowRect(&rect
, WS_OVERLAPPEDWINDOW
, FALSE
);
2690 hr
= IVideoWindow_SetWindowPosition(window
, rect
.left
, rect
.top
,
2691 rect
.right
- rect
.left
, rect
.bottom
- rect
.top
);
2692 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2693 check_destination_position(video
, 0, 0, 400, 300);
2694 hr
= IBasicVideo_IsUsingDefaultDestination(video
);
2695 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
2697 IVideoWindow_Release(window
);
2700 static void test_basic_video(void)
2702 ALLOCATOR_PROPERTIES req_props
= {1, 600 * 400 * 4, 1, 0}, ret_props
;
2703 VIDEOINFOHEADER vih
=
2705 .AvgTimePerFrame
= 200000,
2706 .rcSource
= {4, 6, 16, 12},
2707 .rcTarget
= {40, 60, 120, 160},
2708 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
2709 .bmiHeader
.biBitCount
= 32,
2710 .bmiHeader
.biWidth
= 600,
2711 .bmiHeader
.biHeight
= 400,
2712 .bmiHeader
.biPlanes
= 1,
2713 .bmiHeader
.biCompression
= BI_RGB
,
2715 AM_MEDIA_TYPE req_mt
=
2717 .majortype
= MEDIATYPE_Video
,
2718 .subtype
= MEDIASUBTYPE_RGB32
,
2719 .formattype
= FORMAT_VideoInfo
,
2720 .cbFormat
= sizeof(vih
),
2721 .pbFormat
= (BYTE
*)&vih
,
2723 IBaseFilter
*filter
= create_vmr7(VMRMode_Windowed
);
2724 IFilterGraph2
*graph
= create_graph();
2725 LONG left
, top
, width
, height
, l
;
2726 struct testfilter source
;
2727 IMemAllocator
*allocator
;
2728 IMemInputPin
*input
;
2729 ITypeInfo
*typeinfo
;
2739 IBaseFilter_QueryInterface(filter
, &IID_IBasicVideo
, (void **)&video
);
2740 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
2741 IPin_QueryInterface(pin
, &IID_IMemInputPin
, (void **)&input
);
2743 hr
= IBasicVideo_GetTypeInfoCount(video
, &count
);
2744 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2745 ok(count
== 1, "Got count %u.\n", count
);
2747 hr
= IBasicVideo_GetTypeInfo(video
, 0, 0, &typeinfo
);
2748 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2749 hr
= ITypeInfo_GetTypeAttr(typeinfo
, &typeattr
);
2750 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2751 ok(typeattr
->typekind
== TKIND_DISPATCH
, "Got kind %u.\n", typeattr
->typekind
);
2752 ok(IsEqualGUID(&typeattr
->guid
, &IID_IBasicVideo
), "Got IID %s.\n", wine_dbgstr_guid(&typeattr
->guid
));
2753 ITypeInfo_ReleaseTypeAttr(typeinfo
, typeattr
);
2754 ITypeInfo_Release(typeinfo
);
2756 hr
= IBasicVideo_get_AvgTimePerFrame(video
, NULL
);
2757 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2758 hr
= IBasicVideo_get_AvgTimePerFrame(video
, &reftime
);
2759 ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
2761 hr
= IBasicVideo_get_BitRate(video
, NULL
);
2762 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2763 hr
= IBasicVideo_get_BitRate(video
, &l
);
2764 ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
2766 hr
= IBasicVideo_get_BitErrorRate(video
, NULL
);
2767 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2768 hr
= IBasicVideo_get_BitErrorRate(video
, &l
);
2769 ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
2771 hr
= IBasicVideo_get_VideoWidth(video
, NULL
);
2772 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2773 hr
= IBasicVideo_get_VideoHeight(video
, NULL
);
2774 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2776 hr
= IBasicVideo_get_SourceLeft(video
, NULL
);
2777 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2778 hr
= IBasicVideo_get_SourceWidth(video
, NULL
);
2779 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2780 hr
= IBasicVideo_get_SourceTop(video
, NULL
);
2781 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2782 hr
= IBasicVideo_get_SourceHeight(video
, NULL
);
2783 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2785 hr
= IBasicVideo_get_DestinationLeft(video
, NULL
);
2786 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2787 hr
= IBasicVideo_get_DestinationWidth(video
, NULL
);
2788 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2789 hr
= IBasicVideo_get_DestinationTop(video
, NULL
);
2790 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2791 hr
= IBasicVideo_get_DestinationHeight(video
, NULL
);
2792 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2794 hr
= IBasicVideo_GetSourcePosition(video
, NULL
, &top
, &width
, &height
);
2795 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2796 hr
= IBasicVideo_GetSourcePosition(video
, &left
, NULL
, &width
, &height
);
2797 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2798 hr
= IBasicVideo_GetSourcePosition(video
, &left
, &top
, NULL
, &height
);
2799 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2800 hr
= IBasicVideo_GetSourcePosition(video
, &left
, &top
, &width
, NULL
);
2801 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2803 hr
= IBasicVideo_GetDestinationPosition(video
, NULL
, &top
, &width
, &height
);
2804 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2805 hr
= IBasicVideo_GetDestinationPosition(video
, &left
, NULL
, &width
, &height
);
2806 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2807 hr
= IBasicVideo_GetDestinationPosition(video
, &left
, &top
, NULL
, &height
);
2808 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2809 hr
= IBasicVideo_GetDestinationPosition(video
, &left
, &top
, &width
, NULL
);
2810 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2812 hr
= IBasicVideo_GetVideoSize(video
, &width
, NULL
);
2813 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2814 hr
= IBasicVideo_GetVideoSize(video
, NULL
, &height
);
2815 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2817 hr
= IBasicVideo_GetVideoPaletteEntries(video
, 0, 1, NULL
, &l
);
2818 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2819 hr
= IBasicVideo_GetVideoPaletteEntries(video
, 0, 1, &l
, NULL
);
2820 todo_wine
ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
2822 testfilter_init(&source
);
2823 IFilterGraph2_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, L
"vmr9");
2824 IFilterGraph2_AddFilter(graph
, filter
, L
"source");
2825 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
2828 skip("Got E_FAIL when connecting.\n");
2831 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2833 hr
= IMemInputPin_GetAllocator(input
, &allocator
);
2834 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2837 hr
= IMemAllocator_SetProperties(allocator
, &req_props
, &ret_props
);
2838 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2839 ok(!memcmp(&ret_props
, &req_props
, sizeof(req_props
)), "Properties did not match.\n");
2840 hr
= IMemAllocator_Commit(allocator
);
2841 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2842 IMemAllocator_Release(allocator
);
2846 hr
= IBasicVideo_get_AvgTimePerFrame(video
, &reftime
);
2847 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2848 ok(compare_double(reftime
, 0.02, 1 << 28), "Got frame rate %.16e.\n", reftime
);
2851 hr
= IBasicVideo_get_BitRate(video
, &l
);
2852 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2853 ok(!l
, "Got bit rate %d.\n", l
);
2856 hr
= IBasicVideo_get_BitErrorRate(video
, &l
);
2857 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2858 ok(!l
, "Got bit rate %d.\n", l
);
2860 hr
= IBasicVideo_GetVideoPaletteEntries(video
, 0, 1, &l
, NULL
);
2861 todo_wine
ok(hr
== VFW_E_NO_PALETTE_AVAILABLE
, "Got hr %#x.\n", hr
);
2863 width
= height
= 0xdeadbeef;
2864 hr
= IBasicVideo_GetVideoSize(video
, &width
, &height
);
2865 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2866 ok(width
== 600, "Got width %d.\n", width
);
2867 ok(height
== 400, "Got height %d.\n", height
);
2869 test_basic_video_source(video
);
2870 test_basic_video_destination(video
);
2872 hr
= IFilterGraph2_Disconnect(graph
, &source
.source
.pin
.IPin_iface
);
2873 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2874 hr
= IFilterGraph2_Disconnect(graph
, pin
);
2875 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2877 vih
.bmiHeader
.biWidth
= 16;
2878 vih
.bmiHeader
.biHeight
= 16;
2879 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &req_mt
);
2880 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2882 hr
= IMemInputPin_GetAllocator(input
, &allocator
);
2883 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2886 hr
= IMemAllocator_SetProperties(allocator
, &req_props
, &ret_props
);
2887 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2888 ok(!memcmp(&ret_props
, &req_props
, sizeof(req_props
)), "Properties did not match.\n");
2889 hr
= IMemAllocator_Commit(allocator
);
2890 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2891 IMemAllocator_Release(allocator
);
2894 check_source_position(video
, 0, 0, 16, 16);
2896 SetRect(&rect
, 0, 0, 0, 0);
2897 AdjustWindowRectEx(&rect
, WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| WS_OVERLAPPEDWINDOW
, FALSE
, 0);
2898 check_destination_position(video
, 0, 0, max(16, GetSystemMetrics(SM_CXMIN
) - (rect
.right
- rect
.left
)),
2899 max(16, GetSystemMetrics(SM_CYMIN
) - (rect
.bottom
- rect
.top
)));
2902 ref
= IFilterGraph2_Release(graph
);
2903 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2904 IBasicVideo_Release(video
);
2905 IMemInputPin_Release(input
);
2907 ref
= IBaseFilter_Release(filter
);
2908 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2909 ref
= IBaseFilter_Release(&source
.filter
.IBaseFilter_iface
);
2910 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
2913 static void test_windowless_size(void)
2915 ALLOCATOR_PROPERTIES req_props
= {1, 32 * 16 * 4, 1, 0}, ret_props
;
2916 VIDEOINFOHEADER vih
=
2918 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
2919 .bmiHeader
.biWidth
= 32,
2920 .bmiHeader
.biHeight
= 16,
2921 .bmiHeader
.biBitCount
= 32,
2922 .bmiHeader
.biPlanes
= 1,
2926 .majortype
= MEDIATYPE_Video
,
2927 .subtype
= MEDIASUBTYPE_RGB32
,
2928 .formattype
= FORMAT_VideoInfo
,
2929 .cbFormat
= sizeof(vih
),
2930 .pbFormat
= (BYTE
*)&vih
,
2932 IBaseFilter
*filter
= create_vmr7(VMRMode_Windowless
);
2933 LONG width
, height
, aspect_width
, aspect_height
;
2934 IVMRWindowlessControl
*windowless_control
;
2935 IFilterGraph2
*graph
= create_graph();
2936 struct testfilter source
;
2937 IMemAllocator
*allocator
;
2938 RECT src
, dst
, expect
;
2939 IMemInputPin
*input
;
2945 IBaseFilter_QueryInterface(filter
, &IID_IVMRWindowlessControl
, (void **)&windowless_control
);
2946 IBaseFilter_FindPin(filter
, L
"VMR Input0", &pin
);
2947 IPin_QueryInterface(pin
, &IID_IMemInputPin
, (void **)&input
);
2948 testfilter_init(&source
);
2949 IFilterGraph2_AddFilter(graph
, &source
.filter
.IBaseFilter_iface
, L
"source");
2950 IFilterGraph2_AddFilter(graph
, filter
, L
"vmr7");
2951 window
= CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW
, 0, 0, 640, 480, 0, 0, 0, 0);
2952 ok(!!window
, "Failed to create a window.\n");
2954 hr
= IVMRWindowlessControl_SetVideoClippingWindow(windowless_control
, window
);
2955 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2957 hr
= IFilterGraph2_ConnectDirect(graph
, &source
.source
.pin
.IPin_iface
, pin
, &mt
);
2958 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2959 hr
= IMemInputPin_GetAllocator(input
, &allocator
);
2960 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2963 hr
= IMemAllocator_SetProperties(allocator
, &req_props
, &ret_props
);
2964 IMemAllocator_Release(allocator
);
2967 skip("Got E_FAIL when setting allocator properties.\n");
2970 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2971 ok(!memcmp(&ret_props
, &req_props
, sizeof(req_props
)), "Properties did not match.\n");
2974 hr
= IVMRWindowlessControl_GetNativeVideoSize(windowless_control
, NULL
, &height
, &aspect_width
, &aspect_height
);
2975 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2976 hr
= IVMRWindowlessControl_GetNativeVideoSize(windowless_control
, &width
, NULL
, &aspect_width
, &aspect_height
);
2977 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
2979 width
= height
= 0xdeadbeef;
2980 hr
= IVMRWindowlessControl_GetNativeVideoSize(windowless_control
, &width
, &height
, NULL
, NULL
);
2981 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2982 ok(width
== 32, "Got width %d.\n", width
);
2983 ok(height
== 16, "Got height %d.\n", height
);
2985 aspect_width
= aspect_height
= 0xdeadbeef;
2986 hr
= IVMRWindowlessControl_GetNativeVideoSize(windowless_control
, &width
, &height
, &aspect_width
, &aspect_height
);
2987 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2988 ok(aspect_width
== 32, "Got width %d.\n", aspect_width
);
2989 ok(aspect_height
== 16, "Got height %d.\n", aspect_height
);
2991 memset(&src
, 0xcc, sizeof(src
));
2992 hr
= IVMRWindowlessControl_GetVideoPosition(windowless_control
, &src
, NULL
);
2993 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
2994 SetRect(&expect
, 0, 0, 32, 16);
2995 ok(EqualRect(&src
, &expect
), "Got source rect %s.\n", wine_dbgstr_rect(&src
));
2997 memset(&dst
, 0xcc, sizeof(dst
));
2998 hr
= IVMRWindowlessControl_GetVideoPosition(windowless_control
, NULL
, &dst
);
2999 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3000 SetRect(&expect
, 0, 0, 0, 0);
3001 ok(EqualRect(&dst
, &expect
), "Got dest rect %s.\n", wine_dbgstr_rect(&dst
));
3003 SetRect(&src
, 4, 6, 16, 12);
3004 hr
= IVMRWindowlessControl_SetVideoPosition(windowless_control
, &src
, NULL
);
3005 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3007 memset(&src
, 0xcc, sizeof(src
));
3008 memset(&dst
, 0xcc, sizeof(dst
));
3009 hr
= IVMRWindowlessControl_GetVideoPosition(windowless_control
, &src
, &dst
);
3010 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3011 SetRect(&expect
, 4, 6, 16, 12);
3012 ok(EqualRect(&src
, &expect
), "Got source rect %s.\n", wine_dbgstr_rect(&src
));
3013 SetRect(&expect
, 0, 0, 0, 0);
3014 ok(EqualRect(&dst
, &expect
), "Got dest rect %s.\n", wine_dbgstr_rect(&dst
));
3016 SetRect(&dst
, 40, 60, 120, 160);
3017 hr
= IVMRWindowlessControl_SetVideoPosition(windowless_control
, NULL
, &dst
);
3018 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3020 memset(&src
, 0xcc, sizeof(src
));
3021 memset(&dst
, 0xcc, sizeof(dst
));
3022 hr
= IVMRWindowlessControl_GetVideoPosition(windowless_control
, &src
, &dst
);
3023 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
3024 SetRect(&expect
, 4, 6, 16, 12);
3025 ok(EqualRect(&src
, &expect
), "Got source rect %s.\n", wine_dbgstr_rect(&src
));
3026 SetRect(&expect
, 40, 60, 120, 160);
3027 ok(EqualRect(&dst
, &expect
), "Got dest rect %s.\n", wine_dbgstr_rect(&dst
));
3029 GetWindowRect(window
, &src
);
3030 SetRect(&expect
, 0, 0, 640, 480);
3031 ok(EqualRect(&src
, &expect
), "Got window rect %s.\n", wine_dbgstr_rect(&src
));
3034 ref
= IFilterGraph2_Release(graph
);
3035 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3036 IMemInputPin_Release(input
);
3038 IVMRWindowlessControl_Release(windowless_control
);
3039 ref
= IBaseFilter_Release(filter
);
3040 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
3041 DestroyWindow(window
);
3048 test_filter_config();
3055 test_enum_media_types();
3056 test_unconnected_filter_state();
3059 test_video_window();
3061 test_windowless_size();