ReactOS 0.4.17-dev-923-g4c9a150
vmr9.c
Go to the documentation of this file.
1/*
2 * Video Mixing Renderer 9 unit tests
3 *
4 * Copyright 2019 Zebediah Figura
5 *
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.
10 *
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.
15 *
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
19 */
20
21#include <stdint.h>
22#define COBJMACROS
23#include "ocidl.h"
24#include "olectl.h"
25#include "initguid.h"
26#include "dshow.h"
27#include "qedit.h"
28#include "d3d9.h"
29#include "vmr9.h"
30#include "videoacc.h"
31#include "wmcodecdsp.h"
32#include "wine/strmbase.h"
33#include "wine/test.h"
34
36{
39 HRESULT hr = CoCreateInstance(&CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER,
40 &IID_IBaseFilter, (void **)&filter);
41 ok(hr == S_OK, "Got hr %#lx.\n", hr);
42 if (mode)
43 {
44 hr = IBaseFilter_QueryInterface(filter, &IID_IVMRFilterConfig9, (void **)&config);
45 ok(hr == S_OK, "Got hr %#lx.\n", hr);
46 hr = IVMRFilterConfig9_SetRenderingMode(config, mode);
47 ok(hr == S_OK || broken(hr == E_FAIL), "Got hr %#lx.\n", hr);
48 IVMRFilterConfig9_Release(config);
49 }
50 return filter;
51}
52
54{
56 HRESULT hr;
57
58 hr = IBaseFilter_QueryInterface(filter, &IID_IVMRFilterConfig9, (void **)&config);
59 ok(hr == S_OK, "Got hr %#lx.\n", hr);
60
61 hr = IVMRFilterConfig9_SetNumberOfStreams(config, count);
62 ok(hr == S_OK, "Got hr %#lx.\n", hr);
63
64 IVMRFilterConfig9_Release(config);
65 return hr;
66}
67
69{
70 return !memcmp(a, b, offsetof(AM_MEDIA_TYPE, pbFormat))
71 && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat);
72}
73
74static BOOL compare_double(double f, double g, unsigned int ulps)
75{
76 uint64_t x = *(ULONGLONG *)&f;
77 uint64_t y = *(ULONGLONG *)&g;
78
79 if (f < 0)
80 x = ~x + 1;
81 else
82 x |= ((ULONGLONG)1)<<63;
83 if (g < 0)
84 y = ~y + 1;
85 else
86 y |= ((ULONGLONG)1)<<63;
87
88 return (x>y ? x-y : y-x) <= ulps;
89}
90
92{
94 HRESULT hr;
95 hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph2, (void **)&ret);
96 ok(hr == S_OK, "Got hr %#lx.\n", hr);
97 return ret;
98}
99
100static ULONG get_refcount(void *iface)
101{
102 IUnknown *unknown = iface;
103 IUnknown_AddRef(unknown);
104 return IUnknown_Release(unknown);
105}
106
107static void test_filter_config(void)
108{
111 HRESULT hr;
112 ULONG ref;
113
114 hr = CoCreateInstance(&CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER,
115 &IID_IVMRFilterConfig9, (void **)&config);
116 ok(hr == S_OK, "Got hr %#lx.\n", hr);
117
118 hr = IVMRFilterConfig9_GetRenderingMode(config, &mode);
119 ok(hr == S_OK, "Got hr %#lx.\n", hr);
120 ok(mode == VMRMode_Windowed, "Got mode %#lx.\n", mode);
121
122 hr = IVMRFilterConfig9_SetRenderingMode(config, VMR9Mode_Windowed);
123 ok(hr == S_OK || broken(hr == E_FAIL), "Got hr %#lx.\n", hr);
124
125 hr = IVMRFilterConfig9_GetRenderingMode(config, &mode);
126 ok(hr == S_OK, "Got hr %#lx.\n", hr);
127 ok(mode == VMR9Mode_Windowed, "Got mode %#lx.\n", mode);
128
129 hr = IVMRFilterConfig9_SetRenderingMode(config, VMR9Mode_Windowed);
130 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
131
132 ref = IVMRFilterConfig9_Release(config);
133 ok(!ref, "Got outstanding refcount %ld.\n", ref);
134
135 hr = CoCreateInstance(&CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER,
136 &IID_IVMRFilterConfig9, (void **)&config);
137 ok(hr == S_OK, "Got hr %#lx.\n", hr);
138
139 hr = IVMRFilterConfig9_SetRenderingMode(config, VMR9Mode_Windowless);
140 ok(hr == S_OK || broken(hr == E_FAIL), "Got hr %#lx.\n", hr);
141
142 hr = IVMRFilterConfig9_GetRenderingMode(config, &mode);
143 ok(hr == S_OK, "Got hr %#lx.\n", hr);
144 ok(mode == VMR9Mode_Windowless, "Got mode %#lx.\n", mode);
145
146 hr = IVMRFilterConfig9_SetRenderingMode(config, VMR9Mode_Windowed);
147 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
148
149 ref = IVMRFilterConfig9_Release(config);
150 ok(!ref, "Got outstanding refcount %ld.\n", ref);
151
152 hr = CoCreateInstance(&CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER,
153 &IID_IVMRFilterConfig9, (void **)&config);
154 ok(hr == S_OK, "Got hr %#lx.\n", hr);
155
156 hr = IVMRFilterConfig9_SetRenderingMode(config, VMR9Mode_Renderless);
157 ok(hr == S_OK, "Got hr %#lx.\n", hr);
158
159 hr = IVMRFilterConfig9_GetRenderingMode(config, &mode);
160 ok(hr == S_OK, "Got hr %#lx.\n", hr);
161 ok(mode == VMR9Mode_Renderless, "Got mode %#lx.\n", mode);
162
163 hr = IVMRFilterConfig9_SetRenderingMode(config, VMR9Mode_Windowless);
164 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
165
166 ref = IVMRFilterConfig9_Release(config);
167 ok(!ref, "Got outstanding refcount %ld.\n", ref);
168
169 hr = CoCreateInstance(&CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC_SERVER,
170 &IID_IVMRFilterConfig9, (void **)&config);
171 ok(hr == S_OK, "Got hr %#lx.\n", hr);
172
173 hr = IVMRFilterConfig9_GetNumberOfStreams(config, &count);
174 ok(hr == VFW_E_VMR_NOT_IN_MIXER_MODE, "Got hr %#lx.\n", hr);
175
176 hr = IVMRFilterConfig9_SetNumberOfStreams(config, 3);
177 ok(hr == S_OK, "Got hr %#lx.\n", hr);
178
179 hr = IVMRFilterConfig9_GetNumberOfStreams(config, &count);
180 ok(hr == S_OK, "Got hr %#lx.\n", hr);
181 ok(count == 3, "Got count %lu.\n", count);
182
183 hr = IVMRFilterConfig9_GetRenderingMode(config, &mode);
184 ok(hr == S_OK, "Got hr %#lx.\n", hr);
185 ok(mode == VMR9Mode_Windowed, "Got mode %#lx.\n", mode);
186
187 /* Despite MSDN, you can still change the rendering mode after setting the
188 * stream count. */
189 hr = IVMRFilterConfig9_SetRenderingMode(config, VMR9Mode_Windowless);
190 ok(hr == S_OK || broken(hr == E_FAIL), "Got hr %#lx.\n", hr);
191
192 hr = IVMRFilterConfig9_GetRenderingMode(config, &mode);
193 ok(hr == S_OK, "Got hr %#lx.\n", hr);
194 ok(mode == VMR9Mode_Windowless, "Got mode %#lx.\n", mode);
195
196 hr = IVMRFilterConfig9_GetNumberOfStreams(config, &count);
197 ok(hr == S_OK, "Got hr %#lx.\n", hr);
198 ok(count == 3, "Got count %lu.\n", count);
199
200 ref = IVMRFilterConfig9_Release(config);
201 ok(!ref, "Got outstanding refcount %ld.\n", ref);
202}
203
204#define check_interface_broken(a, b, c) check_interface_(__LINE__, a, b, c, TRUE)
205#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c, FALSE)
206static HRESULT check_interface_(unsigned int line, void *iface, REFIID riid, BOOL supported, BOOL is_broken)
207{
208 HRESULT hr, expected_hr, broken_hr;
209 IUnknown *unknown = iface, *out;
210
211 if (supported)
212 {
214 broken_hr = E_NOINTERFACE;
215 }
216 else
217 {
219 broken_hr = S_OK;
220 }
221
222 hr = IUnknown_QueryInterface(unknown, riid, (void **)&out);
223 ok_(__FILE__, line)(hr == expected_hr || broken(is_broken && hr == broken_hr),
224 "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
225 if (SUCCEEDED(hr))
226 IUnknown_Release(out);
227 return hr;
228}
229
231{
232 IPin *pin;
233
234 check_interface(filter, &IID_IAMCertifiedOutputProtection, TRUE);
235 check_interface(filter, &IID_IAMFilterMiscFlags, TRUE);
238 check_interface(filter, &IID_IMediaFilter, TRUE);
239 check_interface(filter, &IID_IMediaPosition, TRUE);
240 check_interface(filter, &IID_IMediaSeeking, TRUE);
242 check_interface(filter, &IID_IQualityControl, TRUE);
243 todo_wine check_interface(filter, &IID_IQualProp, TRUE);
245 check_interface(filter, &IID_IVMRAspectRatioControl9, TRUE);
246 todo_wine check_interface(filter, &IID_IVMRDeinterlaceControl9, TRUE);
247 check_interface(filter, &IID_IVMRFilterConfig9, TRUE);
248 check_interface(filter, &IID_IVMRMixerBitmap9, TRUE);
249
250 check_interface(filter, &IID_IAMVideoAccelerator, FALSE);
251 check_interface(filter, &IID_IBasicAudio, FALSE);
252 check_interface(filter, &IID_IDirectDrawVideo, FALSE);
255 check_interface(filter, &IID_IReferenceClock, FALSE);
256 check_interface(filter, &IID_IVMRAspectRatioControl, FALSE);
257 check_interface(filter, &IID_IVMRDeinterlaceControl, FALSE);
258 check_interface(filter, &IID_IVMRFilterConfig, FALSE);
259 check_interface(filter, &IID_IVMRMixerBitmap, FALSE);
260 check_interface(filter, &IID_IVMRMixerControl, FALSE);
261 check_interface(filter, &IID_IVMRMonitorConfig, FALSE);
262 check_interface(filter, &IID_IVMRSurfaceAllocatorNotify, FALSE);
263 check_interface(filter, &IID_IVMRWindowlessControl, FALSE);
264
265 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
266
267 check_interface(pin, &IID_IAMVideoAccelerator, TRUE);
268 check_interface(pin, &IID_IMemInputPin, TRUE);
269 check_interface(pin, &IID_IOverlay, TRUE);
271 todo_wine check_interface(pin, &IID_IQualityControl, TRUE);
273
275 check_interface(pin, &IID_IMediaPosition, FALSE);
276 check_interface(pin, &IID_IMediaSeeking, FALSE);
277
278 IPin_Release(pin);
279}
280
281static void test_interfaces(void)
282{
284 ULONG ref;
285
287
288 check_interface(filter, &IID_IBasicVideo, TRUE);
289 todo_wine check_interface(filter, &IID_IBasicVideo2, TRUE);
290 check_interface(filter, &IID_IVideoWindow, TRUE);
291 /* IVMRMonitorConfig9 may not be available if the d3d9 device has
292 * insufficient support. */
293 check_interface_broken(filter, &IID_IVMRMonitorConfig9, TRUE);
294
295 check_interface(filter, &IID_IVMRMixerControl9, FALSE);
296 check_interface(filter, &IID_IVMRSurfaceAllocatorNotify9, FALSE);
297 check_interface(filter, &IID_IVMRWindowlessControl9, FALSE);
298
299 ref = IBaseFilter_Release(filter);
300 ok(!ref, "Got outstanding refcount %ld.\n", ref);
301
304
305 /* IVMRMonitorConfig9 may not be available if the d3d9 device has
306 * insufficient support. */
307 check_interface_broken(filter, &IID_IVMRMonitorConfig9, TRUE);
308 check_interface(filter, &IID_IVMRWindowlessControl9, TRUE);
309
310 todo_wine check_interface(filter, &IID_IBasicVideo, FALSE);
311 check_interface(filter, &IID_IBasicVideo2, FALSE);
312 todo_wine check_interface(filter, &IID_IVideoWindow, FALSE);
313 check_interface(filter, &IID_IVMRMixerControl9, FALSE);
314 check_interface(filter, &IID_IVMRSurfaceAllocatorNotify9, FALSE);
315
316 ref = IBaseFilter_Release(filter);
317 ok(!ref, "Got outstanding refcount %ld.\n", ref);
318
321
322 check_interface(filter, &IID_IVMRSurfaceAllocatorNotify9, TRUE);
323
324 todo_wine check_interface(filter, &IID_IBasicVideo, FALSE);
325 check_interface(filter, &IID_IBasicVideo2, FALSE);
326 todo_wine check_interface(filter, &IID_IVideoWindow, FALSE);
327 check_interface(filter, &IID_IVMRMonitorConfig9, FALSE);
328 check_interface(filter, &IID_IVMRWindowlessControl9, FALSE);
329
330 ref = IBaseFilter_Release(filter);
331 ok(!ref, "Got outstanding refcount %ld.\n", ref);
332
336
337 check_interface(filter, &IID_IBasicVideo, TRUE);
338 todo_wine check_interface(filter, &IID_IBasicVideo2, TRUE);
339 check_interface(filter, &IID_IVideoWindow, TRUE);
340 check_interface(filter, &IID_IVMRMixerControl9, TRUE);
341 /* IVMRMonitorConfig9 may not be available if the d3d9 device has
342 * insufficient support. */
343 check_interface_broken(filter, &IID_IVMRMonitorConfig9, TRUE);
344
345 check_interface(filter, &IID_IVMRSurfaceAllocatorNotify9, FALSE);
346 check_interface(filter, &IID_IVMRWindowlessControl9, FALSE);
347
348 ref = IBaseFilter_Release(filter);
349 ok(!ref, "Got outstanding refcount %ld.\n", ref);
350}
351
352static const GUID test_iid = {0x33333333};
353static LONG outer_ref = 1;
354
356{
357 if (IsEqualGUID(iid, &IID_IUnknown)
359 || IsEqualGUID(iid, &test_iid))
360 {
361 *out = (IUnknown *)0xdeadbeef;
362 return S_OK;
363 }
364 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
365 return E_NOINTERFACE;
366}
367
369{
371}
372
374{
376}
377
378static const IUnknownVtbl outer_vtbl =
379{
383};
384
386
387static void test_aggregation(void)
388{
389 IBaseFilter *filter, *filter2;
390 IUnknown *unk, *unk2;
391 HRESULT hr;
392 ULONG ref;
393
394 filter = (IBaseFilter *)0xdeadbeef;
395 hr = CoCreateInstance(&CLSID_VideoMixingRenderer9, &test_outer, CLSCTX_INPROC_SERVER,
396 &IID_IBaseFilter, (void **)&filter);
397 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
398 ok(!filter, "Got interface %p.\n", filter);
399
400 hr = CoCreateInstance(&CLSID_VideoMixingRenderer9, &test_outer, CLSCTX_INPROC_SERVER,
401 &IID_IUnknown, (void **)&unk);
402 ok(hr == S_OK, "Got hr %#lx.\n", hr);
403 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
404 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
405 ref = get_refcount(unk);
406 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
407
408 ref = IUnknown_AddRef(unk);
409 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
410 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
411
412 ref = IUnknown_Release(unk);
413 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
414 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
415
416 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
417 ok(hr == S_OK, "Got hr %#lx.\n", hr);
418 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
419 IUnknown_Release(unk2);
420
421 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
422 ok(hr == S_OK, "Got hr %#lx.\n", hr);
423
424 hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
425 ok(hr == S_OK, "Got hr %#lx.\n", hr);
426 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
427
428 hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
429 ok(hr == S_OK, "Got hr %#lx.\n", hr);
430 ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
431
432 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
433 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
434 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
435
436 hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
437 ok(hr == S_OK, "Got hr %#lx.\n", hr);
438 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
439
440 IBaseFilter_Release(filter);
441 ref = IUnknown_Release(unk);
442 ok(!ref, "Got unexpected refcount %ld.\n", ref);
443 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
444}
445
446static void test_enum_pins(void)
447{
449 IEnumPins *enum1, *enum2;
450 ULONG count, ref;
451 IPin *pins[3];
452 HRESULT hr;
453
455 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
456
457 hr = IBaseFilter_EnumPins(filter, NULL);
458 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
459
460 hr = IBaseFilter_EnumPins(filter, &enum1);
461 ok(hr == S_OK, "Got hr %#lx.\n", hr);
463 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
464 ref = get_refcount(enum1);
465 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
466
467 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
468 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
469
470 hr = IEnumPins_Next(enum1, 1, pins, NULL);
471 ok(hr == S_OK, "Got hr %#lx.\n", hr);
473 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
474 ref = get_refcount(pins[0]);
475 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
476 ref = get_refcount(enum1);
477 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
478 IPin_Release(pins[0]);
480 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
481
482 hr = IEnumPins_Next(enum1, 1, pins, NULL);
483 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
484
485 hr = IEnumPins_Reset(enum1);
486 ok(hr == S_OK, "Got hr %#lx.\n", hr);
487
488 hr = IEnumPins_Next(enum1, 1, pins, &count);
489 ok(hr == S_OK, "Got hr %#lx.\n", hr);
490 ok(count == 1, "Got count %lu.\n", count);
491 IPin_Release(pins[0]);
492
493 hr = IEnumPins_Next(enum1, 1, pins, &count);
494 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
495 ok(!count, "Got count %lu.\n", count);
496
497 hr = IEnumPins_Reset(enum1);
498 ok(hr == S_OK, "Got hr %#lx.\n", hr);
499
500 hr = IEnumPins_Next(enum1, 2, pins, NULL);
501 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
502
503 hr = IEnumPins_Next(enum1, 2, pins, &count);
504 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
505 ok(count == 1, "Got count %lu.\n", count);
506 IPin_Release(pins[0]);
507
508 hr = IEnumPins_Reset(enum1);
509 ok(hr == S_OK, "Got hr %#lx.\n", hr);
510
511 hr = IEnumPins_Clone(enum1, &enum2);
512 ok(hr == S_OK, "Got hr %#lx.\n", hr);
513
514 hr = IEnumPins_Skip(enum1, 2);
515 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
516
517 hr = IEnumPins_Skip(enum1, 1);
518 ok(hr == S_OK, "Got hr %#lx.\n", hr);
519
520 hr = IEnumPins_Skip(enum1, 1);
521 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
522
523 hr = IEnumPins_Next(enum1, 1, pins, NULL);
524 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
525
526 hr = IEnumPins_Next(enum2, 1, pins, NULL);
527 ok(hr == S_OK, "Got hr %#lx.\n", hr);
528 IPin_Release(pins[0]);
529
530 IEnumPins_Release(enum2);
531
533
534 hr = IEnumPins_Next(enum1, 1, pins, NULL);
535 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
536
537 hr = IEnumPins_Reset(enum1);
538 ok(hr == S_OK, "Got hr %#lx.\n", hr);
539
540 hr = IEnumPins_Next(enum1, 1, pins, NULL);
541 ok(hr == S_OK, "Got hr %#lx.\n", hr);
542 IPin_Release(pins[0]);
543
544 hr = IEnumPins_Next(enum1, 1, pins, NULL);
545 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
546 if (hr == S_OK) IPin_Release(pins[0]);
547
548 hr = IEnumPins_Next(enum1, 1, pins, NULL);
549 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
550
551 hr = IEnumPins_Reset(enum1);
552 ok(hr == S_OK, "Got hr %#lx.\n", hr);
553
554 hr = IEnumPins_Next(enum1, 2, pins, &count);
555 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
556 todo_wine ok(count == 2, "Got count %lu.\n", count);
557 IPin_Release(pins[0]);
558 if (count > 1) IPin_Release(pins[1]);
559
560 hr = IEnumPins_Reset(enum1);
561 ok(hr == S_OK, "Got hr %#lx.\n", hr);
562
563 hr = IEnumPins_Next(enum1, 3, pins, &count);
564 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
565 todo_wine ok(count == 2, "Got count %lu.\n", count);
566 IPin_Release(pins[0]);
567 if (count > 1) IPin_Release(pins[1]);
568
569 IEnumPins_Release(enum1);
570 ref = IBaseFilter_Release(filter);
571 ok(!ref, "Got outstanding refcount %ld.\n", ref);
572}
573
574static void test_find_pin(void)
575{
578 IPin *pin, *pin2;
579 HRESULT hr;
580 ULONG ref;
581
582 IBaseFilter_EnumPins(filter, &enum_pins);
583
584 hr = IBaseFilter_FindPin(filter, L"input pin", &pin);
585 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
586
587 hr = IBaseFilter_FindPin(filter, L"In", &pin);
588 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
589
590 hr = IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
591 ok(hr == S_OK, "Got hr %#lx.\n", hr);
592 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
593 ok(hr == S_OK, "Got hr %#lx.\n", hr);
594 ok(pin == pin2, "Pins did not match.\n");
595 IPin_Release(pin);
596 IPin_Release(pin2);
597
598 hr = IBaseFilter_FindPin(filter, L"VMR Input1", &pin);
599 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
600
602
603 IEnumPins_Reset(enum_pins);
604
605 hr = IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
606 ok(hr == S_OK, "Got hr %#lx.\n", hr);
607 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
608 ok(hr == S_OK, "Got hr %#lx.\n", hr);
609 ok(pin == pin2, "Pins did not match.\n");
610 IPin_Release(pin);
611 IPin_Release(pin2);
612
613 hr = IBaseFilter_FindPin(filter, L"VMR Input1", &pin);
614 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
615 if (hr == S_OK)
616 {
617 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
618 ok(hr == S_OK, "Got hr %#lx.\n", hr);
619 ok(pin == pin2, "Pins did not match.\n");
620 IPin_Release(pin);
621 IPin_Release(pin2);
622 }
623
624 hr = IBaseFilter_FindPin(filter, L"VMR Input2", &pin);
625 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
626
627 IEnumPins_Release(enum_pins);
628 ref = IBaseFilter_Release(filter);
629 ok(!ref, "Got outstanding refcount %ld.\n", ref);
630}
631
632static void test_pin_info(void)
633{
636 ULONG count, ref;
638 HRESULT hr;
639 WCHAR *id;
640 IPin *pin;
641
642 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
643 hr = IPin_QueryPinInfo(pin, &info);
644 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
645 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
646 ok(!wcscmp(info.achName, L"VMR Input0"), "Got name %s.\n", wine_dbgstr_w(info.achName));
647 IBaseFilter_Release(info.pFilter);
648
649 hr = IPin_QueryDirection(pin, &dir);
650 ok(hr == S_OK, "Got hr %#lx.\n", hr);
651 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
652
653 hr = IPin_QueryId(pin, &id);
654 ok(hr == S_OK, "Got hr %#lx.\n", hr);
655 ok(!wcscmp(id, L"VMR Input0"), "Got id %s.\n", wine_dbgstr_w(id));
656 CoTaskMemFree(id);
657
658 hr = IPin_QueryInternalConnections(pin, NULL, &count);
659 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
660
661 IPin_Release(pin);
662
664
665 hr = IBaseFilter_FindPin(filter, L"VMR Input1", &pin);
666 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
667 if (hr == S_OK)
668 {
669 hr = IPin_QueryPinInfo(pin, &info);
670 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
671 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
672 ok(!wcscmp(info.achName, L"VMR Input1"), "Got name %s.\n", wine_dbgstr_w(info.achName));
673 IBaseFilter_Release(info.pFilter);
674
675 hr = IPin_QueryDirection(pin, &dir);
676 ok(hr == S_OK, "Got hr %#lx.\n", hr);
677 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
678
679 hr = IPin_QueryId(pin, &id);
680 ok(hr == S_OK, "Got hr %#lx.\n", hr);
681 ok(!wcscmp(id, L"VMR Input1"), "Got id %s.\n", wine_dbgstr_w(id));
682 CoTaskMemFree(id);
683
684 hr = IPin_QueryInternalConnections(pin, NULL, &count);
685 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
686
687 IPin_Release(pin);
688 }
689
690 ref = IBaseFilter_Release(filter);
691 ok(!ref, "Got outstanding refcount %ld.\n", ref);
692}
693
694static void test_media_types(void)
695{
697 AM_MEDIA_TYPE *mt, req_mt = {{0}};
698 VIDEOINFOHEADER vih =
699 {
700 {0}, {0}, 0, 0, 0,
701 {sizeof(BITMAPINFOHEADER), 32, 24, 1, 0, 0xdeadbeef}
702 };
703 IEnumMediaTypes *enummt;
704 unsigned int i;
705 HRESULT hr;
706 ULONG ref;
707 IPin *pin;
708
709 static const GUID *subtype_tests[] =
710 {
711 &MEDIASUBTYPE_RGB565,
712 &MEDIASUBTYPE_RGB24,
713 &MEDIASUBTYPE_RGB32,
714 };
715
716 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
717
718 hr = IPin_EnumMediaTypes(pin, &enummt);
719 ok(hr == S_OK, "Got hr %#lx.\n", hr);
720
721 hr = IEnumMediaTypes_Next(enummt, 1, &mt, NULL);
722 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
723
724 IEnumMediaTypes_Release(enummt);
725
726 req_mt.majortype = MEDIATYPE_Video;
727 req_mt.formattype = FORMAT_VideoInfo;
728 req_mt.cbFormat = sizeof(VIDEOINFOHEADER);
729 req_mt.pbFormat = (BYTE *)&vih;
730
731 for (i = 0; i < ARRAY_SIZE(subtype_tests); ++i)
732 {
733 req_mt.subtype = *subtype_tests[i];
734 hr = IPin_QueryAccept(pin, &req_mt);
735 ok(hr == S_OK, "Got hr %#lx for subtype %s.\n", hr, wine_dbgstr_guid(subtype_tests[i]));
736 }
737
738 req_mt.subtype = MEDIASUBTYPE_RGB8;
739 hr = IPin_QueryAccept(pin, &req_mt);
740 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
741 req_mt.subtype = MEDIASUBTYPE_NULL;
742 hr = IPin_QueryAccept(pin, &req_mt);
743 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
744 req_mt.subtype = MEDIASUBTYPE_RGB24;
745
746 req_mt.majortype = MEDIATYPE_NULL;
747 hr = IPin_QueryAccept(pin, &req_mt);
748 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
749 req_mt.majortype = MEDIATYPE_Video;
750
751 req_mt.formattype = FORMAT_None;
752 hr = IPin_QueryAccept(pin, &req_mt);
753 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
754
755 req_mt.formattype = GUID_NULL;
756 hr = IPin_QueryAccept(pin, &req_mt);
757 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
758
759 IPin_Release(pin);
760 ref = IBaseFilter_Release(filter);
761 ok(!ref, "Got outstanding refcount %ld.\n", ref);
762}
763
764static void test_enum_media_types(void)
765{
767 IEnumMediaTypes *enum1, *enum2;
768 AM_MEDIA_TYPE *mts[2];
769 ULONG ref, count;
770 HRESULT hr;
771 IPin *pin;
772
773 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
774
775 hr = IPin_EnumMediaTypes(pin, &enum1);
776 ok(hr == S_OK, "Got hr %#lx.\n", hr);
777
778 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
779 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
780
781 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
782 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
783 ok(!count, "Got count %lu.\n", count);
784
785 hr = IEnumMediaTypes_Reset(enum1);
786 ok(hr == S_OK, "Got hr %#lx.\n", hr);
787
788 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
789 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
790
791 hr = IEnumMediaTypes_Clone(enum1, &enum2);
792 ok(hr == S_OK, "Got hr %#lx.\n", hr);
793
794 hr = IEnumMediaTypes_Skip(enum1, 1);
795 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
796
797 hr = IEnumMediaTypes_Next(enum2, 1, mts, NULL);
798 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
799
800 IEnumMediaTypes_Release(enum1);
801 IEnumMediaTypes_Release(enum2);
802 IPin_Release(pin);
803
804 ref = IBaseFilter_Release(filter);
805 ok(!ref, "Got outstanding refcount %ld.\n", ref);
806}
807
809{
811 FILTER_STATE state;
812 HRESULT hr;
813 ULONG ref;
814
815 hr = IBaseFilter_GetState(filter, 0, &state);
816 ok(hr == S_OK, "Got hr %#lx.\n", hr);
817 ok(state == State_Stopped, "Got state %u.\n", state);
818
819 hr = IBaseFilter_Pause(filter);
820 ok(hr == S_OK, "Got hr %#lx.\n", hr);
821
822 hr = IBaseFilter_GetState(filter, 0, &state);
823 ok(hr == S_OK, "Got hr %#lx.\n", hr);
824 ok(state == State_Paused, "Got state %u.\n", state);
825
826 hr = IBaseFilter_Run(filter, 0);
827 ok(hr == S_OK, "Got hr %#lx.\n", hr);
828
829 hr = IBaseFilter_GetState(filter, 0, &state);
830 ok(hr == S_OK, "Got hr %#lx.\n", hr);
831 ok(state == State_Running, "Got state %u.\n", state);
832
833 hr = IBaseFilter_Pause(filter);
834 ok(hr == S_OK, "Got hr %#lx.\n", hr);
835
836 hr = IBaseFilter_GetState(filter, 0, &state);
837 ok(hr == S_OK, "Got hr %#lx.\n", hr);
838 ok(state == State_Paused, "Got state %u.\n", state);
839
840 hr = IBaseFilter_Stop(filter);
841 ok(hr == S_OK, "Got hr %#lx.\n", hr);
842
843 hr = IBaseFilter_GetState(filter, 0, &state);
844 ok(hr == S_OK, "Got hr %#lx.\n", hr);
845 ok(state == State_Stopped, "Got state %u.\n", state);
846
847 hr = IBaseFilter_Run(filter, 0);
848 ok(hr == S_OK, "Got hr %#lx.\n", hr);
849
850 hr = IBaseFilter_GetState(filter, 0, &state);
851 ok(hr == S_OK, "Got hr %#lx.\n", hr);
852 ok(state == State_Running, "Got state %u.\n", state);
853
854 hr = IBaseFilter_Stop(filter);
855 ok(hr == S_OK, "Got hr %#lx.\n", hr);
856
857 hr = IBaseFilter_GetState(filter, 0, &state);
858 ok(hr == S_OK, "Got hr %#lx.\n", hr);
859 ok(state == State_Stopped, "Got state %u.\n", state);
860
861 ref = IBaseFilter_Release(filter);
862 ok(!ref, "Got outstanding refcount %ld.\n", ref);
863}
864
865struct testfilter
866{
867 struct strmbase_filter filter;
868 struct strmbase_source source;
869};
870
871static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
872{
873 return CONTAINING_RECORD(iface, struct testfilter, filter);
874}
875
876static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
877{
879 if (!index)
880 return &filter->source.pin;
881 return NULL;
882}
883
884static void testfilter_destroy(struct strmbase_filter *iface)
885{
889}
890
892{
893 .filter_get_pin = testfilter_get_pin,
894 .filter_destroy = testfilter_destroy,
895};
896
899{
900 return S_OK;
901}
902
904{
905 .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
906 .pfnDecideAllocator = testsource_DecideAllocator,
907};
908
910{
911 static const GUID clsid = {0xabacab};
914}
915
917{
918 IMemAllocator *req_allocator, *ret_allocator;
919 ALLOCATOR_PROPERTIES props, req_props;
920 HRESULT hr;
921
922 hr = IMemInputPin_GetAllocatorRequirements(input, &props);
923 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
924
925 hr = IMemInputPin_GetAllocator(input, &ret_allocator);
926 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
927
928 if (hr == S_OK)
929 {
930 hr = IMemAllocator_GetProperties(ret_allocator, &props);
931 ok(hr == S_OK, "Got hr %#lx.\n", hr);
932 ok(!props.cBuffers, "Got %ld buffers.\n", props.cBuffers);
933 ok(!props.cbBuffer, "Got size %ld.\n", props.cbBuffer);
934 ok(!props.cbAlign, "Got alignment %ld.\n", props.cbAlign);
935 ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
936
937 hr = IMemInputPin_NotifyAllocator(input, ret_allocator, TRUE);
938 ok(hr == S_OK, "Got hr %#lx.\n", hr);
939
940 req_props.cBuffers = 1;
941 req_props.cbBuffer = 32 * 16 * 4;
942 req_props.cbAlign = 1;
943 req_props.cbPrefix = 0;
944 hr = IMemAllocator_SetProperties(ret_allocator, &req_props, &props);
945 ok(hr == S_OK, "Got hr %#lx.\n", hr);
946 ok(props.cBuffers == 1, "Got %ld buffers.\n", props.cBuffers);
947 ok(props.cbBuffer == 32 * 16 * 4, "Got size %ld.\n", props.cbBuffer);
948 ok(props.cbAlign == 1, "Got alignment %ld.\n", props.cbAlign);
949 ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
950
951 IMemAllocator_Release(ret_allocator);
952 }
953
954 hr = IMemInputPin_NotifyAllocator(input, NULL, TRUE);
955 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
956
957 CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
958 &IID_IMemAllocator, (void **)&req_allocator);
959
960 hr = IMemInputPin_NotifyAllocator(input, req_allocator, TRUE);
961 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
962
963 IMemAllocator_Release(req_allocator);
964}
965
967{
970};
971
973{
975 HRESULT hr;
976
977 if (winetest_debug > 1) trace("%04lx: Sending frame.\n", GetCurrentThreadId());
978 hr = IMemInputPin_Receive(params->sink, params->sample);
979 if (winetest_debug > 1) trace("%04lx: Returned %#lx.\n", GetCurrentThreadId(), hr);
980 IMediaSample_Release(params->sample);
981 free(params);
982 return hr;
983}
984
986{
987 struct frame_thread_params *params = malloc(sizeof(*params));
989 REFERENCE_TIME end_time;
992 LONG size, i;
993 HRESULT hr;
994 BYTE *data;
995
996 hr = IMemInputPin_GetAllocator(sink, &allocator);
997 ok(hr == S_OK, "Got hr %#lx.\n", hr);
998
999 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
1000 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1001
1002 size = IMediaSample_GetSize(sample);
1003 hr = IMediaSample_GetPointer(sample, &data);
1004 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1005 for (i = 0; i < size / sizeof(DWORD); ++i)
1006 ((DWORD *)data)[i] = color;
1007
1008 hr = IMediaSample_SetActualDataLength(sample, size);
1009 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1010
1011 start_time *= 10000000;
1012 end_time = start_time + 10000000;
1013 hr = IMediaSample_SetTime(sample, &start_time, &end_time);
1014 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1015
1016 hr = IMediaSample_SetPreroll(sample, TRUE);
1017 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1018
1019 params->sink = sink;
1020 params->sample = sample;
1022
1023 IMemAllocator_Release(allocator);
1024 return thread;
1025}
1026
1028{
1029 return send_frame_time(sink, 0, 0x007f007f);
1030}
1031
1033{
1034 DWORD ret;
1035 ok_(__FILE__, line)(!WaitForSingleObject(thread, 1000), "Wait failed.\n");
1038 return ret;
1039}
1040#define join_thread(a) join_thread_(__LINE__, a)
1041
1043{
1045 HRESULT hr;
1046
1047 hr = IMemInputPin_GetAllocator(input, &allocator);
1048 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1049 hr = IMemAllocator_Commit(allocator);
1050 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1051 IMemAllocator_Release(allocator);
1052}
1053
1054static void test_filter_state(IMemInputPin *input, IMediaControl *control)
1055{
1058 OAFilterState state;
1059 HANDLE thread;
1060 HRESULT hr;
1061
1064 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
1065
1066 /* The renderer is not fully paused until it receives a sample. The thread
1067 * sending the sample blocks in IMemInputPin_Receive() until the filter is
1068 * stopped or run. */
1069
1070 hr = IMediaControl_Pause(control);
1071 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1072
1073 hr = IMediaControl_GetState(control, 0, &state);
1074 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1075
1077
1078 hr = IMediaControl_GetState(control, 1000, &state);
1079 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1080
1081 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1082
1083 hr = IMediaControl_Stop(control);
1084 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1085
1087 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1088
1089 /* The sink will decommit our allocator for us when stopping, however it
1090 * will not recommit it when pausing. */
1091 hr = IMemInputPin_GetAllocator(input, &allocator);
1092 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1093 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
1094 todo_wine ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#lx.\n", hr);
1095 if (hr == S_OK) IMediaSample_Release(sample);
1096
1097 hr = IMemAllocator_Commit(allocator);
1098 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1101 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
1102
1103 hr = IMediaControl_Pause(control);
1104 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1105
1106 hr = IMediaControl_GetState(control, 0, &state);
1107 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1108
1110
1111 hr = IMediaControl_GetState(control, 1000, &state);
1112 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1113
1114 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1115
1116 hr = IMediaControl_Run(control);
1117 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1118
1119 hr = IMediaControl_GetState(control, 0, &state);
1120 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1121
1123 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1124
1127 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1128
1129 hr = IMediaControl_Pause(control);
1130 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1131
1132 hr = IMediaControl_GetState(control, 0, &state);
1133 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1134
1136
1137 hr = IMediaControl_GetState(control, 1000, &state);
1138 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1139
1140 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1141
1142 hr = IMediaControl_Run(control);
1143 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1144
1145 hr = IMediaControl_GetState(control, 0, &state);
1146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1147
1149 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1150
1151 hr = IMediaControl_Pause(control);
1152 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1153
1154 hr = IMediaControl_GetState(control, 0, &state);
1155 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1156
1157 hr = IMediaControl_Stop(control);
1158 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1159
1160 hr = IMediaControl_GetState(control, 0, &state);
1161 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1162
1164 hr = IMediaControl_Pause(control);
1165 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1166
1167 hr = IMediaControl_GetState(control, 0, &state);
1168 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1169
1170 hr = IMediaControl_Run(control);
1171 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1172
1173 hr = IMediaControl_GetState(control, 0, &state);
1174 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1175
1178 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1179
1180 hr = IMediaControl_GetState(control, 0, &state);
1181 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1182
1183 hr = IMediaControl_Stop(control);
1184 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1185
1186 hr = IMediaControl_GetState(control, 0, &state);
1187 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1188
1189 IMemAllocator_Release(allocator);
1190}
1191
1192static void test_flushing(IPin *pin, IMemInputPin *input, IMediaControl *control)
1193{
1194 OAFilterState state;
1195 HANDLE thread;
1196 HRESULT hr;
1197
1199 hr = IMediaControl_Pause(control);
1200 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1201
1203 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1204
1205 hr = IMediaControl_GetState(control, 1000, &state);
1206 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1207
1208 hr = IPin_BeginFlush(pin);
1209 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1210
1212 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1213
1216 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1217
1218 hr = IPin_EndFlush(pin);
1219 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1220
1221 /* We dropped the sample we were holding, so now we need a new one... */
1222
1223 hr = IMediaControl_GetState(control, 0, &state);
1224 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1225 ok(state == State_Paused, "Got state %#lx.\n", state);
1226
1228 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1229
1230 hr = IMediaControl_GetState(control, 1000, &state);
1231 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1232 ok(state == State_Paused, "Got state %#lx.\n", state);
1233
1234 hr = IMediaControl_Run(control);
1235 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1237 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1238
1239 hr = IPin_BeginFlush(pin);
1240 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1241
1244 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1245
1246 hr = IPin_EndFlush(pin);
1247 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1248
1251 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1252
1253 hr = IMediaControl_Stop(control);
1254 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1255}
1256
1257static unsigned int check_event_code(IMediaEvent *eventsrc, DWORD timeout, LONG expected_code, LONG_PTR expected1, LONG_PTR expected2)
1258{
1259 LONG_PTR param1, param2;
1260 unsigned int ret = 0;
1261 HRESULT hr;
1262 LONG code;
1263
1264 while ((hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, timeout)) == S_OK)
1265 {
1266 if (code == expected_code)
1267 {
1268 ok(param1 == expected1, "Got param1 %#Ix.\n", param1);
1269 ok(param2 == expected2, "Got param2 %#Ix.\n", param2);
1270 ret++;
1271 }
1272 IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
1273 timeout = 0;
1274 }
1275 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
1276
1277 return ret;
1278}
1279
1280static inline unsigned int check_ec_complete(IMediaEvent *eventsrc, DWORD timeout)
1281{
1282 return check_event_code(eventsrc, timeout, EC_COMPLETE, S_OK, 0);
1283}
1284
1285static void test_eos(IPin *pin, IMemInputPin *input, IMediaControl *control)
1286{
1287 IMediaEvent *eventsrc;
1288 OAFilterState state;
1289 HRESULT hr;
1290 BOOL ret;
1291
1292 IMediaControl_QueryInterface(control, &IID_IMediaEvent, (void **)&eventsrc);
1293
1295 hr = IMediaControl_Pause(control);
1296 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1297 ret = check_ec_complete(eventsrc, 0);
1298 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1299
1300 hr = IPin_EndOfStream(pin);
1301 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1302
1303 hr = IMediaControl_GetState(control, 1000, &state);
1304 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1305 ret = check_ec_complete(eventsrc, 0);
1306 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1307
1309 todo_wine ok(hr == E_UNEXPECTED, "Got hr %#lx.\n", hr);
1310
1311 hr = IMediaControl_Run(control);
1312 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1313 ret = check_ec_complete(eventsrc, 0);
1314 ok(ret == 1, "Expected EC_COMPLETE.\n");
1315
1316 hr = IMediaControl_Stop(control);
1317 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1318 ret = check_ec_complete(eventsrc, 0);
1319 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1320
1321 /* We do not receive an EC_COMPLETE notification until the last sample is
1322 * done rendering. */
1323
1325 hr = IMediaControl_Run(control);
1326 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1328 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1329 hr = IMediaControl_GetState(control, 1000, &state);
1330 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1331 ret = check_ec_complete(eventsrc, 0);
1332 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1333
1334 hr = IPin_EndOfStream(pin);
1335 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1336 ret = check_ec_complete(eventsrc, 0);
1337 todo_wine ok(!ret, "Got unexpected EC_COMPLETE.\n");
1338 ret = check_ec_complete(eventsrc, 1600);
1339 todo_wine ok(ret == 1, "Expected EC_COMPLETE.\n");
1340
1341 hr = IMediaControl_Stop(control);
1342 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1343 ret = check_ec_complete(eventsrc, 0);
1344 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1345
1346 /* Test sending EOS while flushing. */
1347
1349 hr = IMediaControl_Run(control);
1350 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1352 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1353
1354 hr = IPin_BeginFlush(pin);
1355 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1356 hr = IPin_EndOfStream(pin);
1357 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1358 hr = IPin_EndFlush(pin);
1359 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1360
1361 hr = IMediaControl_Stop(control);
1362 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1363 ret = check_ec_complete(eventsrc, 0);
1364 todo_wine ok(!ret, "Got unexpected EC_COMPLETE.\n");
1365
1366 /* Test sending EOS and then flushing or stopping. */
1367
1369 hr = IMediaControl_Run(control);
1370 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1372 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1373 hr = IMediaControl_GetState(control, 1000, &state);
1374 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1375
1376 hr = IPin_EndOfStream(pin);
1377 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1378 ret = check_ec_complete(eventsrc, 0);
1379 todo_wine ok(!ret, "Got unexpected EC_COMPLETE.\n");
1380
1381 hr = IPin_BeginFlush(pin);
1382 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1383 hr = IPin_EndFlush(pin);
1384 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1385
1387 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1388 hr = IPin_EndOfStream(pin);
1389 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1390 ret = check_ec_complete(eventsrc, 0);
1391 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1392
1393 hr = IMediaControl_Stop(control);
1394 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1395 ret = check_ec_complete(eventsrc, 0);
1396 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1397
1398 IMediaEvent_Release(eventsrc);
1399}
1400
1401static void test_sample_time(IPin *pin, IMemInputPin *input, IMediaControl *control)
1402{
1403 OAFilterState state;
1404 HANDLE thread;
1405 HRESULT hr;
1406
1408 hr = IMediaControl_Pause(control);
1409 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1410
1411 hr = IMediaControl_GetState(control, 0, &state);
1412 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1413
1414 thread = send_frame_time(input, 1, 0x000000ff); /* blue */
1415
1416 hr = IMediaControl_GetState(control, 1000, &state);
1417 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1418
1419 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1420
1421 hr = IMediaControl_Run(control);
1422 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1423
1424 ok(WaitForSingleObject(thread, 500) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1425
1427 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1428
1429 /* Sample time is relative to the time passed to Run(). Thus a sample
1430 * stamped at or earlier than 1s will now be displayed immediately, because
1431 * that time has already passed.
1432 * One may manually verify that all of the frames in this function are
1433 * rendered, including (by adding a Sleep() after sending the frame) the
1434 * cyan and green frames. Thus the VMR does not attempt to drop any frames
1435 * that it considers late. This remains true if the frames are marked as
1436 * discontinuous. */
1437
1438 hr = join_thread(send_frame_time(input, 1, 0x0000ffff)); /* cyan */
1439 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1440
1441 hr = join_thread(send_frame_time(input, 0, 0x0000ff00)); /* green */
1442 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1443
1444 hr = join_thread(send_frame_time(input, -2, 0x00ff0000)); /* red */
1445 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1446
1447 thread = send_frame_time(input, 1000000, 0x00ffffff); /* white */
1448 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1449
1450 hr = IPin_BeginFlush(pin);
1451 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1453 /* If the frame makes it to Receive() in time to be rendered, we get S_OK. */
1454 ok(hr == S_OK || hr == S_FALSE, "Got hr %#lx.\n", hr);
1455 hr = IPin_EndFlush(pin);
1456 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1457
1458 thread = send_frame_time(input, 1000000, 0x00ffff00); /* yellow */
1459 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1460
1461 hr = IMediaControl_Stop(control);
1462 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1464 /* If the frame makes it to Receive() in time to be rendered, we get S_OK. */
1465 ok(hr == S_OK || hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
1466}
1467
1469 IMediaControl *control, const BITMAPINFOHEADER *req_bih)
1470{
1471 LONG buffer[(sizeof(BITMAPINFOHEADER) + 32 * 16 * 4) / 4];
1473 const DWORD *data = (DWORD *)((char *)buffer + sizeof(BITMAPINFOHEADER));
1474 BITMAPINFOHEADER expect_bih = *req_bih;
1475 OAFilterState state;
1476 IBasicVideo *video;
1477 unsigned int i;
1478 HANDLE thread;
1479 HRESULT hr;
1480 LONG size;
1481
1482 expect_bih.biSizeImage = 32 * 16 * 4;
1483
1484 IBaseFilter_QueryInterface(filter, &IID_IBasicVideo, (void **)&video);
1485
1486 hr = IBasicVideo_GetCurrentImage(video, NULL, NULL);
1487 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1488
1489 hr = IBasicVideo_GetCurrentImage(video, NULL, buffer);
1490 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1491
1492 size = 0xdeadbeef;
1493 hr = IBasicVideo_GetCurrentImage(video, &size, NULL);
1494 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
1495 todo_wine ok(size == sizeof(BITMAPINFOHEADER) + 32 * 16 * 4, "Got size %ld.\n", size);
1496
1497 size = sizeof(buffer);
1498 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1499 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1500 ok(size == sizeof(buffer), "Got size %ld.\n", size);
1501 ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
1502 /* The contents seem to reflect the last frame rendered. */
1503
1505 hr = IMediaControl_Pause(control);
1506 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1507
1508 size = sizeof(buffer);
1509 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1510 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1511 ok(size == sizeof(buffer), "Got size %ld.\n", size);
1512 ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
1513 /* The contents seem to reflect the last frame rendered. */
1514
1516 hr = IMediaControl_GetState(control, 1000, &state);
1517 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1518
1519 size = 1;
1520 memset(buffer, 0xcc, sizeof(buffer));
1521 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1522 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1523 ok(size == 1, "Got size %ld.\n", size);
1524
1525 size = sizeof(buffer);
1526 memset(buffer, 0xcc, sizeof(buffer));
1527 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1528 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1529 ok(size == sizeof(buffer), "Got size %ld.\n", size);
1530 ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
1531 for (i = 0; i < 32 * 16; ++i)
1532 ok((data[i] & 0xffffff) == 0x7f007f, "Got unexpected color %08lx at %u.\n", data[i], i);
1533
1534 hr = IMediaControl_Run(control);
1535 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1537
1538 size = sizeof(buffer);
1539 memset(buffer, 0xcc, sizeof(buffer));
1540 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1541 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1542 ok(size == sizeof(buffer), "Got size %ld.\n", size);
1543 ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
1544 for (i = 0; i < 32 * 16; ++i)
1545 ok((data[i] & 0xffffff) == 0x7f007f, "Got unexpected color %08lx at %u.\n", data[i], i);
1546
1547 hr = IMediaControl_Stop(control);
1548 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1549
1550 IBasicVideo_Release(video);
1551}
1552
1553static inline unsigned int check_ec_userabort(IMediaEvent *eventsrc, DWORD timeout)
1554{
1555 return check_event_code(eventsrc, timeout, EC_USERABORT, 0, 0);
1556}
1557
1558static void test_window_close(IPin *pin, IMemInputPin *input, IMediaControl *control)
1559{
1560 IMediaEvent *eventsrc;
1561 OAFilterState state;
1562 IOverlay *overlay;
1563 HANDLE thread;
1564 HRESULT hr;
1565 HWND hwnd;
1566 BOOL ret;
1567
1568 IMediaControl_QueryInterface(control, &IID_IMediaEvent, (void **)&eventsrc);
1569 IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
1570
1571 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
1572 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1573 IOverlay_Release(overlay);
1574
1576 hr = IMediaControl_Pause(control);
1577 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1578 ret = check_ec_userabort(eventsrc, 0);
1579 ok(!ret, "Got unexpected EC_USERABORT.\n");
1580
1581 SendMessageW(hwnd, WM_CLOSE, 0, 0);
1582
1583 hr = IMediaControl_GetState(control, 1000, &state);
1584 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1585 ret = check_ec_userabort(eventsrc, 0);
1586 ok(ret == 1, "Expected EC_USERABORT.\n");
1587
1588 ok(IsWindow(hwnd), "Window should exist.\n");
1589 ok(!IsWindowVisible(hwnd), "Window should be invisible.\n");
1590
1593 todo_wine ok(ret == WAIT_OBJECT_0, "Wait failed\n");
1594 if (ret == WAIT_OBJECT_0)
1595 {
1597 ok(hr == E_UNEXPECTED, "Got hr %#lx.\n", hr);
1598 }
1600
1601 hr = IMediaControl_Run(control);
1602 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1603 ret = check_ec_userabort(eventsrc, 0);
1604 ok(!ret, "Got unexpected EC_USERABORT.\n");
1605
1606 hr = IMediaControl_Stop(control);
1607 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1608 ret = check_ec_userabort(eventsrc, 0);
1609 ok(!ret, "Got unexpected EC_USERABORT.\n");
1610
1611 /* We receive an EC_USERABORT notification immediately. */
1612
1614 hr = IMediaControl_Run(control);
1615 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1617 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1618 hr = IMediaControl_GetState(control, 1000, &state);
1619 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1620 ret = check_ec_userabort(eventsrc, 0);
1621 ok(!ret, "Got unexpected EC_USERABORT.\n");
1622
1623 SendMessageW(hwnd, WM_CLOSE, 0, 0);
1624
1625 ret = check_ec_userabort(eventsrc, 0);
1626 ok(ret == 1, "Expected EC_USERABORT.\n");
1627
1628 ok(IsWindow(hwnd), "Window should exist.\n");
1629 ok(!IsWindowVisible(hwnd), "Window should be visible.\n");
1630
1631 hr = IMediaControl_Stop(control);
1632 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1633 ret = check_ec_userabort(eventsrc, 0);
1634 ok(!ret, "Got unexpected EC_USERABORT.\n");
1635
1636 IMediaEvent_Release(eventsrc);
1637}
1638
1639static void test_connect_pin(void)
1640{
1641 VIDEOINFOHEADER vih =
1642 {
1644 .bmiHeader.biBitCount = 32,
1645 .bmiHeader.biWidth = 32,
1646 .bmiHeader.biHeight = 16,
1647 .bmiHeader.biPlanes = 1,
1648 .bmiHeader.biCompression = BI_RGB,
1649 };
1650 AM_MEDIA_TYPE req_mt =
1651 {
1652 .majortype = MEDIATYPE_Video,
1653 .formattype = FORMAT_VideoInfo,
1654 .cbFormat = sizeof(vih),
1655 .pbFormat = (BYTE *)&vih,
1656 };
1657 ALLOCATOR_PROPERTIES req_props = {1, 32 * 16 * 4, 1, 0}, ret_props;
1660 struct testfilter source;
1662 IMediaControl *control;
1664 unsigned int i, j;
1666 IPin *pin, *peer;
1667 HRESULT hr;
1668 ULONG ref;
1669
1670 static const GUID *subtype_tests[] =
1671 {
1672 &MEDIASUBTYPE_RGB555,
1673 &MEDIASUBTYPE_RGB565,
1674 &MEDIASUBTYPE_RGB24,
1675 &MEDIASUBTYPE_RGB32,
1676 };
1677 static const WORD bpp_tests[] = {15, 16, 24, 32};
1678
1680
1681 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
1682 IFilterGraph2_AddFilter(graph, filter, NULL);
1683 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
1684
1685 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
1686 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
1687
1688 for (i = 0; i < ARRAY_SIZE(subtype_tests); ++i)
1689 {
1690 req_mt.subtype = *subtype_tests[i];
1691
1692 for (j = 0; j < ARRAY_SIZE(bpp_tests); ++j)
1693 {
1694 vih.bmiHeader.biBitCount = bpp_tests[j];
1695
1696 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1697 if (hr == E_FAIL)
1698 {
1699 skip("Got E_FAIL when connecting.\n");
1700 goto out;
1701 }
1702 ok(hr == S_OK, "Got hr %#lx for subtype %s and bpp %u.\n", hr,
1703 wine_dbgstr_guid(subtype_tests[i]), bpp_tests[j]);
1704
1705 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
1706 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1707 hr = IFilterGraph2_Disconnect(graph, pin);
1708 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1709 }
1710 }
1711
1712 req_mt.formattype = FORMAT_None;
1713 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1714 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1715 req_mt.formattype = FORMAT_VideoInfo;
1716
1717 req_mt.subtype = MEDIASUBTYPE_RGB8;
1718 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1719 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1720 req_mt.subtype = MEDIASUBTYPE_WAVE;
1721 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1722 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1723 req_mt.subtype = MEDIASUBTYPE_RGB32;
1724
1725 peer = (IPin *)0xdeadbeef;
1726 hr = IPin_ConnectedTo(pin, &peer);
1727 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1728 ok(!peer, "Got peer %p.\n", peer);
1729
1730 hr = IPin_ConnectionMediaType(pin, &mt);
1731 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1732
1733 hr = IMediaControl_Pause(control);
1734 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1735 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1736 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
1737 hr = IMediaControl_Stop(control);
1738 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1739
1740 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1741 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1742
1743 hr = IPin_ConnectedTo(pin, &peer);
1744 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1745 ok(peer == &source.source.pin.IPin_iface, "Got peer %p.\n", peer);
1746 IPin_Release(peer);
1747
1748 hr = IPin_ConnectionMediaType(pin, &mt);
1749 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1750 ok(compare_media_types(&mt, &req_mt), "Media types didn't match.\n");
1751
1752 /* Disconnecting while not stopped is broken: it returns S_OK, but
1753 * subsequent attempts to connect return VFW_E_ALREADY_CONNECTED. */
1754
1756
1757 hr = IMemInputPin_GetAllocator(input, &allocator);
1758 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1759 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
1760 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1761 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
1762 hr = IMemAllocator_Commit(allocator);
1763 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1764 IMemAllocator_Release(allocator);
1765
1766 hr = IMemInputPin_ReceiveCanBlock(input);
1767 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1768
1771 test_eos(pin, input, control);
1775
1776 hr = IFilterGraph2_Disconnect(graph, pin);
1777 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1778 hr = IFilterGraph2_Disconnect(graph, pin);
1779 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1780 ok(source.source.pin.peer == pin, "Got peer %p.\n", source.source.pin.peer);
1781 IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
1782
1783 peer = (IPin *)0xdeadbeef;
1784 hr = IPin_ConnectedTo(pin, &peer);
1785 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1786 ok(!peer, "Got peer %p.\n", peer);
1787
1788 hr = IPin_ConnectionMediaType(pin, &mt);
1789 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1790
1791out:
1792 IMediaControl_Release(control);
1793 ref = IFilterGraph2_Release(graph);
1794 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1795 IMemInputPin_Release(input);
1796 IPin_Release(pin);
1797 ref = IBaseFilter_Release(filter);
1798 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1799 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
1800 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1801}
1802
1803static void test_overlay(void)
1804{
1806 IOverlay *overlay;
1807 HRESULT hr;
1808 ULONG ref;
1809 IPin *pin;
1810 HWND hwnd;
1811
1812 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
1813
1814 hr = IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
1815 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1816
1817 hwnd = (HWND)0xdeadbeef;
1818 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
1819 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1820 ok(hwnd && hwnd != (HWND)0xdeadbeef, "Got invalid window %p.\n", hwnd);
1821
1822 IOverlay_Release(overlay);
1823 IPin_Release(pin);
1824 ref = IBaseFilter_Release(filter);
1825 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1826
1828 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
1829
1830 hr = IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
1831 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1832
1833 hwnd = (HWND)0xdeadbeef;
1834 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
1835 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
1836 ok(hwnd == (HWND)0xdeadbeef, "Got window %p.\n", hwnd);
1837
1838 IOverlay_Release(overlay);
1839 IPin_Release(pin);
1840 ref = IBaseFilter_Release(filter);
1841 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1842
1844 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
1845
1846 hr = IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
1847 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1848
1849 hwnd = (HWND)0xdeadbeef;
1850 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
1851 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
1852 ok(hwnd == (HWND)0xdeadbeef, "Got window %p.\n", hwnd);
1853
1854 IOverlay_Release(overlay);
1855 IPin_Release(pin);
1856 ref = IBaseFilter_Release(filter);
1857 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1858}
1859
1860/* try to make sure pending X events have been processed before continuing */
1861static void flush_events(void)
1862{
1863 int diff = 200;
1864 DWORD time;
1865 MSG msg;
1866
1867 time = GetTickCount() + diff;
1868 while (diff > 0)
1869 {
1871 break;
1872 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
1874 diff = time - GetTickCount();
1875 }
1876}
1877
1879{
1880 if (winetest_debug > 1)
1881 trace("hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix.\n", hwnd, msg, wparam, lparam);
1882
1883 if (wparam == 0xdeadbeef)
1884 return 0;
1885
1886 return DefWindowProcA(hwnd, msg, wparam, lparam);
1887}
1888
1889static void test_video_window_caption(IVideoWindow *window, HWND hwnd)
1890{
1891 WCHAR text[50];
1892 BSTR caption;
1893 HRESULT hr;
1894
1895 hr = IVideoWindow_get_Caption(window, &caption);
1896 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1897 ok(!wcscmp(caption, L"ActiveMovie Window"), "Got caption %s.\n", wine_dbgstr_w(caption));
1898 SysFreeString(caption);
1899
1901 ok(!wcscmp(text, L"ActiveMovie Window"), "Got caption %s.\n", wine_dbgstr_w(text));
1902
1903 caption = SysAllocString(L"foo");
1904 hr = IVideoWindow_put_Caption(window, caption);
1905 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1906 SysFreeString(caption);
1907
1908 hr = IVideoWindow_get_Caption(window, &caption);
1909 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1910 ok(!wcscmp(caption, L"foo"), "Got caption %s.\n", wine_dbgstr_w(caption));
1911 SysFreeString(caption);
1912
1914 ok(!wcscmp(text, L"foo"), "Got caption %s.\n", wine_dbgstr_w(text));
1915}
1916
1917static void test_video_window_style(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
1918{
1919 HRESULT hr;
1920 LONG style;
1921
1922 hr = IVideoWindow_get_WindowStyle(window, &style);
1923 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1925 "Got style %#lx.\n", style);
1926
1929 "Got style %#lx.\n", style);
1930
1931 hr = IVideoWindow_put_WindowStyle(window, style | WS_DISABLED);
1932 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1933 hr = IVideoWindow_put_WindowStyle(window, style | WS_HSCROLL);
1934 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1935 hr = IVideoWindow_put_WindowStyle(window, style | WS_VSCROLL);
1936 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1937 hr = IVideoWindow_put_WindowStyle(window, style | WS_MAXIMIZE);
1938 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1939 hr = IVideoWindow_put_WindowStyle(window, style | WS_MINIMIZE);
1940 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1941
1942 hr = IVideoWindow_put_WindowStyle(window, style & ~WS_CLIPCHILDREN);
1943 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1944
1945 hr = IVideoWindow_get_WindowStyle(window, &style);
1946 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1947 ok(style == (WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW), "Got style %#lx.\n", style);
1948
1950 ok(style == (WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW), "Got style %#lx.\n", style);
1951
1953 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1954
1955 hr = IVideoWindow_get_WindowStyleEx(window, &style);
1956 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1957 ok(style == WS_EX_WINDOWEDGE, "Got style %#lx.\n", style);
1958
1960 ok(style == WS_EX_WINDOWEDGE, "Got style %#lx.\n", style);
1961
1962 hr = IVideoWindow_put_WindowStyleEx(window, style | WS_EX_TRANSPARENT);
1963 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1964
1965 hr = IVideoWindow_get_WindowStyleEx(window, &style);
1966 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1967 ok(style == (WS_EX_WINDOWEDGE | WS_EX_TRANSPARENT), "Got style %#lx.\n", style);
1968
1970 ok(style == (WS_EX_WINDOWEDGE | WS_EX_TRANSPARENT), "Got style %#lx.\n", style);
1971}
1972
1974{
1975 DWORD pid;
1978 {
1979 *(HWND *)ctx = hwnd;
1980 return FALSE;
1981 }
1982 return TRUE;
1983}
1984
1986{
1987 HWND hwnd;
1989 return hwnd;
1990}
1991
1992static void test_video_window_state(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
1993{
1994 HRESULT hr;
1995 LONG state;
1996 HWND top;
1997
1998 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1999
2000 hr = IVideoWindow_get_WindowState(window, &state);
2001 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2002 ok(state == SW_HIDE, "Got state %ld.\n", state);
2003
2004 hr = IVideoWindow_get_Visible(window, &state);
2005 ok(state == OAFALSE, "Got state %ld.\n", state);
2006
2007 ok(!IsWindowVisible(hwnd), "Window should not be visible.\n");
2008 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
2009 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
2010
2011 hr = IVideoWindow_put_WindowState(window, SW_SHOWNA);
2012 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2013
2014 hr = IVideoWindow_get_WindowState(window, &state);
2015 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2016 ok(state == SW_SHOW, "Got state %ld.\n", state);
2017
2018 hr = IVideoWindow_get_Visible(window, &state);
2019 ok(state == OATRUE, "Got state %ld.\n", state);
2020
2021 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
2022 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
2023 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
2024 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2025 top = get_top_window();
2026 ok(top == hwnd, "Got top window %p.\n", top);
2027
2028 hr = IVideoWindow_put_WindowState(window, SW_MINIMIZE);
2029 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2030
2031 hr = IVideoWindow_get_WindowState(window, &state);
2032 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2033 ok(state == SW_MINIMIZE, "Got state %ld.\n", state);
2034
2035 hr = IVideoWindow_get_Visible(window, &state);
2036 ok(state == OATRUE, "Got state %ld.\n", state);
2037
2038 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
2039 ok(IsIconic(hwnd), "Window should be minimized.\n");
2040 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
2041 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2042
2043 hr = IVideoWindow_put_WindowState(window, SW_RESTORE);
2044 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2045
2046 hr = IVideoWindow_get_WindowState(window, &state);
2047 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2048 ok(state == SW_SHOW, "Got state %ld.\n", state);
2049
2050 hr = IVideoWindow_get_Visible(window, &state);
2051 ok(state == OATRUE, "Got state %ld.\n", state);
2052
2053 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
2054 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
2055 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
2056 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
2057
2058 hr = IVideoWindow_put_WindowState(window, SW_MAXIMIZE);
2059 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2060
2061 hr = IVideoWindow_get_WindowState(window, &state);
2062 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2063 ok(state == SW_MAXIMIZE, "Got state %ld.\n", state);
2064
2065 hr = IVideoWindow_get_Visible(window, &state);
2066 ok(state == OATRUE, "Got state %ld.\n", state);
2067
2068 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
2069 ok(!IsIconic(hwnd), "Window should be minimized.\n");
2070 ok(IsZoomed(hwnd), "Window should not be maximized.\n");
2071 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
2072
2073 hr = IVideoWindow_put_WindowState(window, SW_RESTORE);
2074 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2075
2076 hr = IVideoWindow_put_WindowState(window, SW_HIDE);
2077 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2078
2079 hr = IVideoWindow_get_WindowState(window, &state);
2080 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2081 ok(state == SW_HIDE, "Got state %ld.\n", state);
2082
2083 hr = IVideoWindow_get_Visible(window, &state);
2084 ok(state == OAFALSE, "Got state %ld.\n", state);
2085
2086 ok(!IsWindowVisible(hwnd), "Window should not be visible.\n");
2087 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
2088 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
2089 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2090
2091 hr = IVideoWindow_put_Visible(window, OATRUE);
2092 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2093
2094 hr = IVideoWindow_get_WindowState(window, &state);
2095 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2096 ok(state == SW_SHOW, "Got state %ld.\n", state);
2097
2098 hr = IVideoWindow_get_Visible(window, &state);
2099 ok(state == OATRUE, "Got state %ld.\n", state);
2100
2101 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
2102 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
2103 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
2104 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
2105
2106 hr = IVideoWindow_put_Visible(window, OAFALSE);
2107 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2108
2109 hr = IVideoWindow_get_WindowState(window, &state);
2110 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2111 ok(state == SW_HIDE, "Got state %ld.\n", state);
2112
2113 hr = IVideoWindow_get_Visible(window, &state);
2114 ok(state == OAFALSE, "Got state %ld.\n", state);
2115
2116 ok(!IsWindowVisible(hwnd), "Window should not be visible.\n");
2117 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
2118 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
2119 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2120
2121 hr = IVideoWindow_put_WindowState(window, SW_SHOWNA);
2122 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2123
2124 hr = IVideoWindow_SetWindowForeground(window, TRUE);
2125 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2126
2127 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
2128 hr = IVideoWindow_SetWindowForeground(window, OATRUE);
2129 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2130 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
2131 ok(GetFocus() == hwnd, "Got focus window %p.\n", GetFocus());
2132 ok(GetForegroundWindow() == hwnd, "Got foreground window %p.\n", GetForegroundWindow());
2133 top = get_top_window();
2134 ok(top == hwnd, "Got top window %p.\n", top);
2135
2136 hr = IVideoWindow_SetWindowForeground(window, OAFALSE);
2137 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2138 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
2139 ok(GetFocus() == hwnd, "Got focus window %p.\n", GetFocus());
2140 ok(GetForegroundWindow() == hwnd, "Got foreground window %p.\n", GetForegroundWindow());
2141 top = get_top_window();
2142 ok(top == hwnd, "Got top window %p.\n", top);
2143
2144 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
2145 hr = IVideoWindow_SetWindowForeground(window, OAFALSE);
2146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2147 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2148 ok(GetFocus() == our_hwnd, "Got focus window %p.\n", GetFocus());
2149 ok(GetForegroundWindow() == our_hwnd, "Got foreground window %p.\n", GetForegroundWindow());
2150 top = get_top_window();
2151 ok(top == hwnd, "Got top window %p.\n", top);
2152}
2153
2154static void test_video_window_position(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
2155{
2156 LONG left, width, top, height, expect_width, expect_height;
2157 RECT rect = {0, 0, 600, 400};
2158 HWND top_hwnd;
2159 HRESULT hr;
2160
2161 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
2162
2164 expect_width = rect.right - rect.left;
2165 expect_height = rect.bottom - rect.top;
2166
2167 hr = IVideoWindow_put_Left(window, 0);
2168 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2169 hr = IVideoWindow_put_Top(window, 0);
2170 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2171
2172 hr = IVideoWindow_get_Left(window, &left);
2173 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2174 ok(left == 0, "Got left %ld.\n", left);
2175 hr = IVideoWindow_get_Top(window, &top);
2176 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2177 ok(top == 0, "Got top %ld.\n", top);
2178 hr = IVideoWindow_get_Width(window, &width);
2179 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2180 ok(width == expect_width, "Got width %ld.\n", width);
2181 hr = IVideoWindow_get_Height(window, &height);
2182 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2183 ok(height == expect_height, "Got height %ld.\n", height);
2184 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
2185 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2186 ok(left == 0, "Got left %ld.\n", left);
2187 ok(top == 0, "Got top %ld.\n", top);
2188 ok(width == expect_width, "Got width %ld.\n", width);
2189 ok(height == expect_height, "Got height %ld.\n", height);
2191 ok(rect.left == 0, "Got window left %ld.\n", rect.left);
2192 ok(rect.top == 0, "Got window top %ld.\n", rect.top);
2193 ok(rect.right == expect_width, "Got window right %ld.\n", rect.right);
2194 ok(rect.bottom == expect_height, "Got window bottom %ld.\n", rect.bottom);
2195
2196 hr = IVideoWindow_put_Left(window, 10);
2197 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2198
2199 hr = IVideoWindow_get_Left(window, &left);
2200 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2201 ok(left == 10, "Got left %ld.\n", left);
2202 hr = IVideoWindow_get_Top(window, &top);
2203 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2204 ok(top == 0, "Got top %ld.\n", top);
2205 hr = IVideoWindow_get_Width(window, &width);
2206 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2207 ok(width == expect_width, "Got width %ld.\n", width);
2208 hr = IVideoWindow_get_Height(window, &height);
2209 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2210 ok(height == expect_height, "Got height %ld.\n", height);
2211 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
2212 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2213 ok(left == 10, "Got left %ld.\n", left);
2214 ok(top == 0, "Got top %ld.\n", top);
2215 ok(width == expect_width, "Got width %ld.\n", width);
2216 ok(height == expect_height, "Got height %ld.\n", height);
2218 ok(rect.left == 10, "Got window left %ld.\n", rect.left);
2219 ok(rect.top == 0, "Got window top %ld.\n", rect.top);
2220 ok(rect.right == 10 + expect_width, "Got window right %ld.\n", rect.right);
2221 ok(rect.bottom == expect_height, "Got window bottom %ld.\n", rect.bottom);
2222
2223 hr = IVideoWindow_put_Height(window, 200);
2224 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2225
2226 hr = IVideoWindow_get_Left(window, &left);
2227 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2228 ok(left == 10, "Got left %ld.\n", left);
2229 hr = IVideoWindow_get_Top(window, &top);
2230 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2231 ok(top == 0, "Got top %ld.\n", top);
2232 hr = IVideoWindow_get_Width(window, &width);
2233 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2234 ok(width == expect_width, "Got width %ld.\n", width);
2235 hr = IVideoWindow_get_Height(window, &height);
2236 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2237 ok(height == 200, "Got height %ld.\n", height);
2238 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
2239 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2240 ok(left == 10, "Got left %ld.\n", left);
2241 ok(top == 0, "Got top %ld.\n", top);
2242 ok(width == expect_width, "Got width %ld.\n", width);
2243 ok(height == 200, "Got height %ld.\n", height);
2245 ok(rect.left == 10, "Got window left %ld.\n", rect.left);
2246 ok(rect.top == 0, "Got window top %ld.\n", rect.top);
2247 ok(rect.right == 10 + expect_width, "Got window right %ld.\n", rect.right);
2248 ok(rect.bottom == 200, "Got window bottom %ld.\n", rect.bottom);
2249
2250 hr = IVideoWindow_SetWindowPosition(window, 100, 200, 300, 400);
2251 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2252
2253 hr = IVideoWindow_get_Left(window, &left);
2254 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2255 ok(left == 100, "Got left %ld.\n", left);
2256 hr = IVideoWindow_get_Top(window, &top);
2257 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2258 ok(top == 200, "Got top %ld.\n", top);
2259 hr = IVideoWindow_get_Width(window, &width);
2260 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2261 ok(width == 300, "Got width %ld.\n", width);
2262 hr = IVideoWindow_get_Height(window, &height);
2263 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2264 ok(height == 400, "Got height %ld.\n", height);
2265 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
2266 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2267 ok(left == 100, "Got left %ld.\n", left);
2268 ok(top == 200, "Got top %ld.\n", top);
2269 ok(width == 300, "Got width %ld.\n", width);
2270 ok(height == 400, "Got height %ld.\n", height);
2272 ok(rect.left == 100, "Got window left %ld.\n", rect.left);
2273 ok(rect.top == 200, "Got window top %ld.\n", rect.top);
2274 ok(rect.right == 400, "Got window right %ld.\n", rect.right);
2275 ok(rect.bottom == 600, "Got window bottom %ld.\n", rect.bottom);
2276
2277 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2278 top_hwnd = get_top_window();
2279 ok(top_hwnd == our_hwnd, "Got top window %p.\n", top_hwnd);
2280}
2281
2282static void test_video_window_owner(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
2283{
2284 HWND parent, top_hwnd;
2285 LONG style, state;
2286 OAHWND oahwnd;
2287 HRESULT hr;
2288
2289 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
2290
2291 hr = IVideoWindow_get_Owner(window, &oahwnd);
2292 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2293 ok(!oahwnd, "Got owner %#Ix.\n", oahwnd);
2294
2296 ok(parent == GetDesktopWindow(), "Got parent %p.\n", parent);
2298 ok(!(style & WS_CHILD), "Got style %#lx.\n", style);
2299
2300 hr = IVideoWindow_put_Owner(window, (OAHWND)our_hwnd);
2301 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2302
2303 hr = IVideoWindow_get_Owner(window, &oahwnd);
2304 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2305 ok(oahwnd == (OAHWND)our_hwnd, "Got owner %#Ix.\n", oahwnd);
2306
2308 ok(parent == our_hwnd, "Got parent %p.\n", parent);
2310 ok((style & WS_CHILD), "Got style %#lx.\n", style);
2311
2312 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2313 top_hwnd = get_top_window();
2314 ok(top_hwnd == our_hwnd, "Got top window %p.\n", top_hwnd);
2315
2316 ShowWindow(our_hwnd, SW_HIDE);
2317
2318 hr = IVideoWindow_put_Visible(window, OATRUE);
2319 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2320
2321 hr = IVideoWindow_get_Visible(window, &state);
2322 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2323 ok(state == OAFALSE, "Got state %ld.\n", state);
2324
2325 hr = IVideoWindow_put_Owner(window, 0);
2326 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2327
2328 hr = IVideoWindow_get_Owner(window, &oahwnd);
2329 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2330 ok(!oahwnd, "Got owner %#Ix.\n", oahwnd);
2331
2333 ok(parent == GetDesktopWindow(), "Got parent %p.\n", parent);
2335 ok(!(style & WS_CHILD), "Got style %#lx.\n", style);
2336
2337 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
2338 top_hwnd = get_top_window();
2339 ok(top_hwnd == hwnd, "Got top window %p.\n", top_hwnd);
2340
2341 hr = IVideoWindow_get_Visible(window, &state);
2342 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2343 ok(state == OATRUE, "Got state %ld.\n", state);
2344}
2345
2347{
2348 IVideoWindow *window;
2349 HWND hwnd;
2350 UINT message;
2351};
2352
2354{
2355 const struct notify_message_params *params = arg;
2356 HRESULT hr = IVideoWindow_NotifyOwnerMessage(params->window, (OAHWND)params->hwnd, params->message, 0, 0);
2357 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2358 return 0;
2359}
2360
2361static void test_video_window_messages(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
2362{
2364 unsigned int i;
2365 OAHWND oahwnd;
2366 HANDLE thread;
2367 HRESULT hr;
2368 BOOL ret;
2369 MSG msg;
2370
2371 static UINT drain_tests[] =
2372 {
2383 WM_KEYDOWN,
2384 WM_KEYUP,
2395 };
2396
2397 flush_events();
2398
2399 hr = IVideoWindow_get_MessageDrain(window, &oahwnd);
2400 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2401 ok(!oahwnd, "Got window %#Ix.\n", oahwnd);
2402
2403 hr = IVideoWindow_put_MessageDrain(window, (OAHWND)our_hwnd);
2404 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2405
2406 hr = IVideoWindow_get_MessageDrain(window, &oahwnd);
2407 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2408 ok(oahwnd == (OAHWND)our_hwnd, "Got window %#Ix.\n", oahwnd);
2409
2410 for (i = 0; i < ARRAY_SIZE(drain_tests); ++i)
2411 {
2412 SendMessageA(hwnd, drain_tests[i], 0xdeadbeef, 0);
2413 ret = PeekMessageA(&msg, 0, drain_tests[i], drain_tests[i], PM_REMOVE);
2414 ok(ret, "Expected a message.\n");
2415 ok(msg.hwnd == our_hwnd, "Got hwnd %p.\n", msg.hwnd);
2416 ok(msg.message == drain_tests[i], "Got message %#x.\n", msg.message);
2417 ok(msg.wParam == 0xdeadbeef, "Got wparam %#Ix.\n", msg.wParam);
2418 ok(!msg.lParam, "Got lparam %#Ix.\n", msg.lParam);
2420
2421 ret = PeekMessageA(&msg, 0, drain_tests[i], drain_tests[i], PM_REMOVE);
2422 ok(!ret, "Got unexpected message %#x.\n", msg.message);
2423 }
2424
2425 hr = IVideoWindow_put_MessageDrain(window, 0);
2426 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2427
2428 hr = IVideoWindow_put_Owner(window, (OAHWND)our_hwnd);
2429 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2430
2431 flush_events();
2432
2433 /* Demonstrate that messages should be sent, not posted, and that only some
2434 * messages should be forwarded. A previous implementation unconditionally
2435 * posted all messages. */
2436
2437 hr = IVideoWindow_NotifyOwnerMessage(window, (OAHWND)our_hwnd, WM_SYSCOLORCHANGE, 0, 0);
2438 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2439
2440 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2441 {
2442 ok(msg.message != WM_SYSCOLORCHANGE, "WM_SYSCOLORCHANGE should not be posted.\n");
2444 }
2445
2446 hr = IVideoWindow_NotifyOwnerMessage(window, (OAHWND)our_hwnd, WM_FONTCHANGE, 0, 0);
2447 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2448
2449 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2450 {
2451 ok(msg.message != WM_FONTCHANGE, "WM_FONTCHANGE should not be posted.\n");
2453 }
2454
2455 params.window = window;
2456 params.hwnd = our_hwnd;
2457 params.message = WM_SYSCOLORCHANGE;
2459 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block.\n");
2460
2461 while ((ret = MsgWaitForMultipleObjects(1, &thread, FALSE, 1000, QS_ALLINPUT)) == 1)
2462 {
2463 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2464 {
2465 ok(msg.message != WM_SYSCOLORCHANGE, "WM_SYSCOLORCHANGE should not be posted.\n");
2467 }
2468 }
2469 ok(!ret, "Wait timed out.\n");
2471
2472 params.message = WM_FONTCHANGE;
2474 ok(!WaitForSingleObject(thread, 1000), "Thread should not block.\n");
2476
2477 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2478 {
2479 ok(msg.message != WM_FONTCHANGE, "WM_FONTCHANGE should not be posted.\n");
2481 }
2482
2483 hr = IVideoWindow_put_Owner(window, 0);
2484 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2485}
2486
2488{
2489 IMediaControl *control;
2490 HRESULT hr;
2491 LONG l;
2492
2493 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
2494
2495 hr = IVideoWindow_get_AutoShow(window, &l);
2496 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2497 ok(l == OATRUE, "Got %ld.\n", l);
2498
2499 hr = IVideoWindow_put_Visible(window, OAFALSE);
2500 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2501
2502 hr = IMediaControl_Pause(control);
2503 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2504
2505 hr = IVideoWindow_get_Visible(window, &l);
2506 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2507 ok(l == OATRUE, "Got %ld.\n", l);
2508
2509 hr = IMediaControl_Stop(control);
2510 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2511
2512 hr = IVideoWindow_get_Visible(window, &l);
2513 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2514 ok(l == OATRUE, "Got %ld.\n", l);
2515
2516 hr = IVideoWindow_put_AutoShow(window, OAFALSE);
2517 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2518
2519 hr = IVideoWindow_put_Visible(window, OAFALSE);
2520 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2521
2522 hr = IMediaControl_Pause(control);
2523 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2524
2525 hr = IVideoWindow_get_Visible(window, &l);
2526 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2527 ok(l == OAFALSE, "Got %ld.\n", l);
2528
2529 hr = IMediaControl_Stop(control);
2530 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2531
2532 IMediaControl_Release(control);
2533}
2534
2535static void test_video_window(void)
2536{
2537 ALLOCATOR_PROPERTIES req_props = {1, 600 * 400 * 4, 1, 0}, ret_props;
2538 VIDEOINFOHEADER vih =
2539 {
2541 .bmiHeader.biBitCount = 32,
2542 .bmiHeader.biWidth = 600,
2543 .bmiHeader.biHeight = 400,
2544 .bmiHeader.biPlanes = 1,
2545 .bmiHeader.biCompression = BI_RGB,
2546 };
2547 AM_MEDIA_TYPE req_mt =
2548 {
2549 .majortype = MEDIATYPE_Video,
2550 .subtype = MEDIASUBTYPE_RGB32,
2551 .formattype = FORMAT_VideoInfo,
2552 .cbFormat = sizeof(vih),
2553 .pbFormat = (BYTE *)&vih,
2554 };
2556 WNDCLASSA window_class = {0};
2557 struct testfilter source;
2559 MONITORINFO monitorinfo;
2560 IMediaControl *control;
2561 LONG width, height, l;
2562 IVideoWindow *window;
2565 HWND hwnd, our_hwnd;
2566 IOverlay *overlay;
2567 BSTR caption;
2568 HRESULT hr;
2569 DWORD tid;
2570 ULONG ref;
2571 IPin *pin;
2572 RECT rect;
2573
2574 window_class.lpszClassName = "wine_test_class";
2575 window_class.lpfnWndProc = window_proc;
2576 RegisterClassA(&window_class);
2577 our_hwnd = CreateWindowA("wine_test_class", "test window", WS_VISIBLE | WS_OVERLAPPEDWINDOW,
2578 100, 200, 300, 400, NULL, NULL, NULL, NULL);
2579 flush_events();
2580
2582 flush_events();
2583
2585 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2586
2587 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
2588 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
2589
2590 hr = IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
2591 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2592
2593 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
2594 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2595 if (winetest_debug > 1) trace("ours %p, theirs %p\n", our_hwnd, hwnd);
2597
2599 ok(tid == GetCurrentThreadId(), "Expected tid %#lx, got %#lx.\n", GetCurrentThreadId(), tid);
2600
2601 hr = IBaseFilter_QueryInterface(filter, &IID_IVideoWindow, (void **)&window);
2602 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2603
2604 hr = IVideoWindow_get_Caption(window, &caption);
2605 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2606
2607 caption = SysAllocString(L"foo");
2608 hr = IVideoWindow_put_Caption(window, caption);
2609 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2610 SysFreeString(caption);
2611
2612 hr = IVideoWindow_get_WindowStyle(window, &l);
2613 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2614
2615 hr = IVideoWindow_put_WindowStyle(window, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
2616 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2617
2618 hr = IVideoWindow_get_AutoShow(window, &l);
2619 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2620
2621 hr = IVideoWindow_put_AutoShow(window, OAFALSE);
2622 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2623
2624 hr = IVideoWindow_put_Owner(window, (OAHWND)our_hwnd);
2625 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2626
2627 hr = IVideoWindow_put_MessageDrain(window, (OAHWND)our_hwnd);
2628 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2629
2630 hr = IVideoWindow_put_Visible(window, OATRUE);
2631 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2632
2633 hr = IVideoWindow_SetWindowPosition(window, 100, 200, 300, 400);
2634 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2635
2637 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
2638 IFilterGraph2_AddFilter(graph, filter, NULL);
2639 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
2640 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
2641 if (hr == E_FAIL)
2642 {
2643 skip("Got E_FAIL when connecting.\n");
2644 goto out;
2645 }
2646 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2647
2648 hr = IMemInputPin_GetAllocator(input, &allocator);
2649 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
2650 if (hr == S_OK)
2651 {
2652 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
2653 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2654 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
2655 hr = IMemAllocator_Commit(allocator);
2656 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2657 IMemAllocator_Release(allocator);
2658 }
2659
2661 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2662
2670
2671 hr = IVideoWindow_put_FullScreenMode(window, OATRUE);
2672 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2673 hr = IVideoWindow_get_FullScreenMode(window, &l);
2674 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2675
2676 hr = IVideoWindow_GetMinIdealImageSize(window, &width, &height);
2677 todo_wine ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
2678 hr = IVideoWindow_GetMaxIdealImageSize(window, &width, &height);
2679 todo_wine ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
2680
2681 hr = IMediaControl_Pause(control);
2682 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2683
2684 monitorinfo.cbSize = sizeof(monitorinfo);
2685 GetMonitorInfoW(MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY), &monitorinfo);
2686
2687 hr = IVideoWindow_GetMinIdealImageSize(window, &width, &height);
2688 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2689 todo_wine ok(width == 1, "Got width %ld.\n", width);
2690 todo_wine ok(height == 1, "Got height %ld.\n", height);
2691 hr = IVideoWindow_GetMaxIdealImageSize(window, &width, &height);
2692 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2693 todo_wine ok(width == monitorinfo.rcMonitor.right + 1, "Expected width %ld, got %ld.\n",
2694 monitorinfo.rcMonitor.right + 1, width);
2695 todo_wine ok(height == monitorinfo.rcMonitor.bottom + 1, "Expected height %ld, got %ld.\n",
2696 monitorinfo.rcMonitor.bottom + 1, height);
2697
2698 hr = IMediaControl_Stop(control);
2699 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2700
2701out:
2702 IMediaControl_Release(control);
2703 IFilterGraph2_Release(graph);
2704 IVideoWindow_Release(window);
2705 IOverlay_Release(overlay);
2706 IMemInputPin_Release(input);
2707 IPin_Release(pin);
2708 ref = IBaseFilter_Release(filter);
2709 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2710 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
2711 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2712 DestroyWindow(our_hwnd);
2713}
2714
2716{
2717 D3DPRESENT_PARAMETERS present_parameters =
2718 {
2719 .Windowed = TRUE,
2720 .hDeviceWindow = window,
2721 .SwapEffect = D3DSWAPEFFECT_DISCARD,
2722 .BackBufferWidth = 640,
2723 .BackBufferHeight = 480,
2724 .BackBufferFormat = D3DFMT_A8R8G8B8,
2725 };
2727 IDirect3D9 *d3d;
2728 HRESULT hr;
2729
2731 ok(!!d3d, "Failed to create a D3D object.\n");
2732
2734 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
2735 IDirect3D9_Release(d3d);
2736 if (FAILED(hr))
2737 {
2738 skip("Failed to create a 3D device, hr %#lx.\n", hr);
2739 return NULL;
2740 }
2741 return device;
2742}
2743
2745{
2747 {
2749 .dwWidth = 32,
2750 .dwHeight = 16,
2751 .Format = D3DFMT_X8R8G8B8,
2752 .Pool = D3DPOOL_DEFAULT,
2753 .MinBuffers = 2,
2754 .szAspectRatio = {32, 16},
2755 .szNativeSize = {32, 16},
2756 };
2759 IDirect3DSurface9 *surfaces[2] = {0};
2760 IDirect3DDevice9 *device, *device2;
2761 RECT rect = {0, 0, 640, 480};
2762 IDirect3DTexture9 *container;
2764 DWORD count;
2765 HWND window;
2766 HRESULT hr;
2767 ULONG ref;
2768
2770 window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0,
2772 if (!(device = create_device(window)))
2773 {
2774 IBaseFilter_Release(filter);
2776 return;
2777 }
2778
2779 IBaseFilter_QueryInterface(filter, &IID_IVMRSurfaceAllocatorNotify9, (void **)&notify);
2780
2781 count = 2;
2782 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, &info, &count, surfaces);
2783 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
2784
2785 hr = IVMRSurfaceAllocatorNotify9_SetD3DDevice(notify, device, MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY));
2786 if (hr == E_NOINTERFACE)
2787 {
2788 win_skip("Direct3D does not support video rendering.\n");
2789 goto out;
2790 }
2791 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2792
2793 if (0) /* crashes on Windows */
2794 {
2795 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, NULL, &count, surfaces);
2796 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2797
2798 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, &info, NULL, surfaces);
2799 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2800 }
2801
2802 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, &info, &count, NULL);
2803 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2804
2805 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, &info, &count, surfaces);
2806 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2807 ok(count == 2, "Got count %lu.\n", count);
2808 ok(!!surfaces[0], "Surface 0 was not allocated.\n");
2809 ok(!!surfaces[1], "Surface 1 was not allocated.\n");
2810
2811 hr = IDirect3DSurface9_GetDevice(surfaces[0], &device2);
2812 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2813 ok(device2 == device, "Devices did not match.\n");
2814 IDirect3DDevice9_Release(device2);
2815
2816 hr = IDirect3DSurface9_GetContainer(surfaces[0], &IID_IDirect3DTexture9, (void **)&container);
2817 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
2818
2820 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2821 ok(desc.Format == info.Format, "Got format %#x.\n", desc.Format);
2822 ok(desc.Type == D3DRTYPE_SURFACE, "Got type %u.\n", desc.Type);
2823 ok(!desc.Usage, "Got usage %#lx.\n", desc.Usage);
2824 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u.\n", desc.Pool);
2825 ok(desc.MultiSampleType == D3DMULTISAMPLE_NONE, "Got multisample type %u.\n", desc.MultiSampleType);
2826 ok(!desc.MultiSampleQuality, "Got multisample quality %lu.\n", desc.MultiSampleQuality);
2827 ok(desc.Width == 32, "Got width %u.\n", desc.Width);
2828 ok(desc.Height == 16, "Got height %u.\n", desc.Height);
2829
2832
2833 surfaces[0] = surfaces[1] = NULL;
2834 count = 1;
2835 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, &info, &count, surfaces);
2836 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
2837 todo_wine ok(!count, "Got count %lu.\n", count);
2838 ok(!surfaces[0], "Surface 0 was allocated.\n");
2839 ok(!surfaces[1], "Surface 1 was allocated.\n");
2840
2841 count = 2;
2842 info.MinBuffers = 1;
2843 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, &info, &count, surfaces);
2844 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2845 ok(count == 2, "Got count %lu.\n", count);
2846 ok(!!surfaces[0], "Surface 0 was not allocated.\n");
2847 ok(!!surfaces[1], "Surface 1 was not allocated.\n");
2850
2851 count = 2;
2853 surfaces[0] = surfaces[1] = NULL;
2854 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, &info, &count, surfaces);
2855 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2856 ok(count == 2, "Got count %lu.\n", count);
2857 ok(!!surfaces[0], "Surface 0 was not allocated.\n");
2858 ok(!!surfaces[1], "Surface 1 was not allocated.\n");
2859
2860 hr = IDirect3DSurface9_GetDevice(surfaces[0], &device2);
2861 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2862 ok(device2 == device, "Devices did not match.\n");
2863 IDirect3DDevice9_Release(device2);
2864
2865 hr = IDirect3DSurface9_GetContainer(surfaces[0], &IID_IDirect3DTexture9, (void **)&container);
2866 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2868
2870 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2871 ok(desc.Format == info.Format, "Got format %#x.\n", desc.Format);
2872 ok(desc.Type == D3DRTYPE_SURFACE, "Got type %u.\n", desc.Type);
2873 ok(desc.Usage == D3DUSAGE_DYNAMIC, "Got usage %#lx.\n", desc.Usage);
2874 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u.\n", desc.Pool);
2875 ok(desc.MultiSampleType == D3DMULTISAMPLE_NONE, "Got multisample type %u.\n", desc.MultiSampleType);
2876 ok(!desc.MultiSampleQuality, "Got multisample quality %lu.\n", desc.MultiSampleQuality);
2877 ok(desc.Width == 32, "Got width %u.\n", desc.Width);
2878 ok(desc.Height == 16, "Got height %u.\n", desc.Height);
2879
2882
2883 info.Format = D3DFMT_R8G8B8;
2884 surfaces[0] = surfaces[1] = NULL;
2885 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, &info, &count, surfaces);
2886 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2887 ok(!count, "Got count %lu.\n", count);
2888 ok(!surfaces[0], "Surface 0 was allocated.\n");
2889 ok(!surfaces[1], "Surface 1 was allocated.\n");
2890
2891 info.Format = 0;
2893 count = 1;
2894 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, &info, &count, surfaces);
2895 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2896 ok(count == 1, "Got count %lu.\n", count);
2897 ok(!!surfaces[0], "Surface 0 was not allocated.\n");
2898 ok(info.Format != 0, "Expected a format.\n");
2899
2901 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2902 ok(desc.Format == info.Format, "Expected format %#x, got %#x.\n", info.Format, desc.Format);
2903 ok(desc.Type == D3DRTYPE_SURFACE, "Got type %u.\n", desc.Type);
2904 ok(desc.Usage == D3DUSAGE_RENDERTARGET, "Got usage %#lx.\n", desc.Usage);
2905 ok(desc.Pool == D3DPOOL_DEFAULT, "Got pool %u.\n", desc.Pool);
2906 ok(desc.MultiSampleType == D3DMULTISAMPLE_NONE, "Got multisample type %u.\n", desc.MultiSampleType);
2907 ok(!desc.MultiSampleQuality, "Got multisample quality %lu.\n", desc.MultiSampleQuality);
2908 ok(desc.Width == 32, "Got width %u.\n", desc.Width);
2909 ok(desc.Height == 16, "Got height %u.\n", desc.Height);
2910
2912
2913 info.Format = D3DFMT_A8R8G8B8;
2915 count = 1;
2916 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(notify, &info, &count, surfaces);
2917 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2918 ok(count == 1, "Got count %lu.\n", count);
2919
2920out:
2921 IVMRSurfaceAllocatorNotify9_Release(notify);
2922 ref = IBaseFilter_Release(filter);
2923 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2925 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2927}
2928
2929struct presenter
2930{
2933 LONG refcount;
2934
2941};
2942
2944{
2946}
2947
2949{
2951 return IVMRSurfaceAllocator9_QueryInterface(&presenter->IVMRSurfaceAllocator9_iface, iid, out);
2952}
2953
2955{
2957 return IVMRSurfaceAllocator9_AddRef(&presenter->IVMRSurfaceAllocator9_iface);
2958}
2959
2961{
2963 return IVMRSurfaceAllocator9_Release(&presenter->IVMRSurfaceAllocator9_iface);
2964}
2965
2967{
2968 if (winetest_debug > 1) trace("StartPresenting()\n");
2969 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
2970 return E_NOTIMPL;
2971}
2972
2974{
2975 if (winetest_debug > 1) trace("StopPresenting()\n");
2976 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
2977 return E_NOTIMPL;
2978}
2979
2981{
2984 static const RECT rect;
2985
2986 if (winetest_debug > 1) trace("PresentImage()\n");
2988 ok(device == presenter->device, "got %p, expected %p\n", device, presenter->device);
2990 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
2991 todo_wine ok(info->dwFlags == VMR9Sample_TimeValid, "Got flags %#lx.\n", info->dwFlags);
2992 ok(!info->rtStart, "Got start time %s.\n", wine_dbgstr_longlong(info->rtStart));
2993 ok(info->rtEnd == 10000000, "Got end time %s.\n", wine_dbgstr_longlong(info->rtEnd));
2994 todo_wine ok(info->szAspectRatio.cx == 120, "Got aspect ratio width %ld.\n", info->szAspectRatio.cx);
2995 todo_wine ok(info->szAspectRatio.cy == 60, "Got aspect ratio height %ld.\n", info->szAspectRatio.cy);
2996 ok(EqualRect(&info->rcSrc, &rect), "Got source rect %s.\n", wine_dbgstr_rect(&info->rcSrc));
2997 ok(EqualRect(&info->rcDst, &rect), "Got dest rect %s.\n", wine_dbgstr_rect(&info->rcDst));
2998 ok(!info->dwReserved1, "Got dwReserved1 %#lx.\n", info->dwReserved1);
2999 ok(!info->dwReserved2, "Got dwReserved2 %#lx.\n", info->dwReserved2);
3000
3002 return S_OK;
3003}
3004
3005static const IVMRImagePresenter9Vtbl presenter_vtbl =
3006{
3013};
3014
3016{
3018}
3019
3021{
3023
3024 if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
3025
3026 if (IsEqualGUID(iid, &IID_IVMRImagePresenter9))
3027 {
3029 IVMRImagePresenter9_AddRef(&presenter->IVMRImagePresenter9_iface);
3030 return S_OK;
3031 }
3032 ok(!IsEqualGUID(iid, &IID_IVMRSurfaceAllocatorEx9), "Unexpected query for IVMRSurfaceAllocatorEx9.\n");
3033 *out = NULL;
3034 return E_NOTIMPL;
3035}
3036
3038{
3041}
3042
3044{
3047}
3048
3051{
3053
3054 if (winetest_debug > 1) trace("InitializeDevice(flags %#lx, format %u)\n",
3055 info->dwFlags, info->Format);
3056 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
3057 ok(info->dwWidth == 32, "Got width %lu.\n", info->dwWidth);
3058 ok(info->dwHeight == 16, "Got height %lu.\n", info->dwHeight);
3059 todo_wine ok(info->MinBuffers == 5, "Got buffer count %lu.\n", info->MinBuffers);
3060 ok(info->Pool == D3DPOOL_DEFAULT, "Got pool %u\n", info->Pool);
3061 todo_wine ok(info->szAspectRatio.cx == 120, "Got aspect ratio width %ld.\n", info->szAspectRatio.cx);
3062 todo_wine ok(info->szAspectRatio.cy == 60, "Got aspect ratio height %ld.\n", info->szAspectRatio.cy);
3063 ok(info->szNativeSize.cx == 32, "Got native width %ld.\n", info->szNativeSize.cx);
3064 ok(info->szNativeSize.cy == 16, "Got native height %ld.\n", info->szNativeSize.cy);
3065 todo_wine ok(*buffer_count == 5, "Got buffer count %lu.\n", *buffer_count);
3066
3067 presenter->format = info->Format;
3068
3069 if (info->dwFlags != presenter->accept_flags)
3070 return 0xdeadbeef;
3071 return IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(presenter->notify,
3073}
3074
3076{
3078
3079 if (winetest_debug > 1) trace("TerminateDevice()\n");
3080 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
3081 /* Don't dereference the surfaces here, to mimic How to Survive. */
3083 return E_NOTIMPL;
3084}
3085
3088{
3090
3091 if (winetest_debug > 1) trace("GetSurface(index %lu)\n", index);
3092 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
3093 ok(!flags, "Got flags %#lx.\n", flags);
3094 ok(index < 5, "Got index %lu.\n", index);
3095
3096 /* Don't reference the surface here, to mimic How to Survive. */
3097 *surface = presenter->surfaces[index];
3098 return S_OK;
3099}
3100
3102{
3103 ok(0, "Unexpected call.\n");
3104 return E_NOTIMPL;
3105}
3106
3107static const IVMRSurfaceAllocator9Vtbl allocator_vtbl =
3108{
3116};
3117
3120{
3121 IMediaControl *control;
3122 OAFilterState state;
3123 HANDLE thread;
3124 HRESULT hr;
3125
3126 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
3127
3129
3130 hr = IMediaControl_Pause(control);
3131 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3133 hr = IMediaControl_GetState(control, 1000, &state);
3134 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3135 /* Atelier Sophie uses the VMR in renderless mode, calls
3136 * IMediaControl::Run() from a stopped state and expects that
3137 * IMediaControl::GetState() returns S_OK only after PresentImage() has
3138 * been called. */
3139 ok(presenter->got_PresentImage == 1, "Got %u calls to PresentImage().\n", presenter->got_PresentImage);
3140
3141 hr = IMediaControl_Run(control);
3142 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3144 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3145 ok(presenter->got_PresentImage == 1, "Got %u calls to PresentImage().\n", presenter->got_PresentImage);
3146
3147 hr = IMediaControl_Stop(control);
3148 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3149
3150 IMediaControl_Release(control);
3151}
3152
3154{
3155 VIDEOINFOHEADER vih =
3156 {
3157 .rcSource = {4, 6, 16, 12},
3158 .rcTarget = {40, 60, 160, 120},
3159 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
3160 .bmiHeader.biWidth = 32,
3161 .bmiHeader.biHeight = 16,
3162 };
3163 AM_MEDIA_TYPE req_mt =
3164 {
3165 .majortype = MEDIATYPE_Video,
3166 .formattype = FORMAT_VideoInfo,
3167 .cbFormat = sizeof(vih),
3168 .pbFormat = (BYTE *)&vih,
3169 };
3170 ALLOCATOR_PROPERTIES req_props = {5, 32 * 16 * 4, 1, 0}, ret_props;
3171 struct presenter presenter =
3172 {
3174 .IVMRImagePresenter9_iface.lpVtbl = &presenter_vtbl,
3175 .refcount = 1,
3176 };
3177 struct presenter presenter2 = presenter;
3179 RECT rect = {0, 0, 640, 480};
3180 struct testfilter source;
3186 unsigned int i;
3187 HWND window;
3188 HRESULT hr;
3189 ULONG ref;
3190 IPin *pin;
3191
3192 static const struct
3193 {
3194 const GUID *subtype;
3196 DWORD flags;
3197 }
3198 tests[] =
3199 {
3200 {&MEDIASUBTYPE_ARGB1555, D3DFMT_A1R5G5B5, VMR9AllocFlag_TextureSurface},
3201 {&MEDIASUBTYPE_ARGB32, D3DFMT_A8R8G8B8, VMR9AllocFlag_TextureSurface},
3202 {&MEDIASUBTYPE_ARGB4444, D3DFMT_A4R4G4B4, VMR9AllocFlag_TextureSurface},
3203
3204 {&MEDIASUBTYPE_RGB555, D3DFMT_X1R5G5B5, VMR9AllocFlag_OffscreenSurface},
3205 {&MEDIASUBTYPE_RGB555, D3DFMT_X1R5G5B5, VMR9AllocFlag_TextureSurface},
3206 {&MEDIASUBTYPE_RGB565, D3DFMT_R5G6B5, VMR9AllocFlag_OffscreenSurface},
3207 {&MEDIASUBTYPE_RGB565, D3DFMT_R5G6B5, VMR9AllocFlag_TextureSurface},
3208 {&MEDIASUBTYPE_RGB24, D3DFMT_R8G8B8, VMR9AllocFlag_OffscreenSurface},
3209 {&MEDIASUBTYPE_RGB24, D3DFMT_R8G8B8, VMR9AllocFlag_TextureSurface},
3210 {&MEDIASUBTYPE_RGB32, D3DFMT_X8R8G8B8, VMR9AllocFlag_OffscreenSurface},
3211 {&MEDIASUBTYPE_RGB32, D3DFMT_X8R8G8B8, VMR9AllocFlag_TextureSurface},
3212
3213 {&MEDIASUBTYPE_NV12, MAKEFOURCC('N','V','1','2'), VMR9AllocFlag_OffscreenSurface},
3214 {&MEDIASUBTYPE_UYVY, D3DFMT_UYVY, VMR9AllocFlag_OffscreenSurface},
3215 {&MEDIASUBTYPE_YUY2, D3DFMT_YUY2, VMR9AllocFlag_OffscreenSurface},
3216 {&MEDIASUBTYPE_YV12, MAKEFOURCC('Y','V','1','2'), VMR9AllocFlag_OffscreenSurface},
3217 };
3218
3220 window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0,
3222 if (!(device = create_device(window)))
3223 {
3225 return;
3226 }
3227
3229 IBaseFilter_QueryInterface(filter, &IID_IVMRSurfaceAllocatorNotify9, (void **)&notify);
3230
3231 hr = IVMRSurfaceAllocatorNotify9_SetD3DDevice(notify, device, MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY));
3233 if (hr == E_NOINTERFACE)
3234 {
3235 win_skip("Direct3D does not support video rendering.\n");
3236 goto out;
3237 }
3238 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3239
3240 hr = IVMRSurfaceAllocatorNotify9_AdviseSurfaceAllocator(notify, 0xabacab,
3242 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3243
3245
3247 graph = create_graph();
3248 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3249 IFilterGraph2_AddFilter(graph, filter, NULL);
3250 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
3251 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
3252
3253 for (i = 0; i < ARRAY_SIZE(tests); ++i)
3254 {
3255 req_mt.subtype = *tests[i].subtype;
3256 presenter.accept_flags = tests[i].flags;
3257
3258 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
3259 /* Connection never fails on Native, but Wine currently creates D3D
3260 * surfaces during IPin::ReceiveConnection() instead of
3261 * IMemAllocator::SetProperties(), so let that fail here for now. */
3262 if (hr != S_OK)
3263 {
3264 skip("Format %u (%#x), flags %#lx are not supported, hr %#lx.\n",
3266 continue;
3267 }
3268 ok(hr == S_OK, "Test %u: Got hr %#lx.\n", i, hr);
3269
3270 hr = IMemInputPin_GetAllocator(input, &allocator);
3271 todo_wine ok(hr == S_OK, "Test %u: Got hr %#lx.\n", i, hr);
3272 if (hr != S_OK)
3273 {
3275 hr = IMemInputPin_GetAllocator(input, &allocator);
3276 }
3277
3278 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
3279 if (hr != S_OK)
3280 {
3281 skip("Format %u (%#x), flags %#lx are not supported, hr %#lx.\n",
3283 IMemAllocator_Release(allocator);
3284 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
3285 ok(hr == S_OK, "Test %u: Got hr %#lx.\n", i, hr);
3286 hr = IFilterGraph2_Disconnect(graph, pin);
3287 ok(hr == S_OK, "Test %u: Got hr %#lx.\n", i, hr);
3288 continue;
3289 }
3290 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
3291 hr = IMemAllocator_Commit(allocator);
3292 ok(hr == S_OK, "Test %u: Got hr %#lx.\n", i, hr);
3293
3294 hr = IVMRSurfaceAllocatorNotify9_AdviseSurfaceAllocator(notify, 0xabacab,
3295 &presenter2.IVMRSurfaceAllocator9_iface);
3296 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
3297
3298 ok(presenter.format == tests[i].format, "Test %u: Got format %u (%#x).\n",
3300
3302
3303 hr = IMemAllocator_Decommit(allocator);
3304 ok(hr == S_OK, "Test %u: Got hr %#lx.\n", i, hr);
3305 IMemAllocator_Release(allocator);
3306
3307 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
3308 ok(hr == S_OK, "Test %u: Got hr %#lx.\n", i, hr);
3309 hr = IFilterGraph2_Disconnect(graph, pin);
3310 ok(hr == S_OK, "Test %u: Got hr %#lx.\n", i, hr);
3311 }
3312
3313 hr = IVMRSurfaceAllocatorNotify9_AdviseSurfaceAllocator(notify, 0xabacab, &presenter2.IVMRSurfaceAllocator9_iface);
3314 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3315
3316 ref = IFilterGraph2_Release(graph);
3317 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3318 IMemInputPin_Release(input);
3319 IPin_Release(pin);
3320
3321out:
3322 IVMRSurfaceAllocatorNotify9_Release(notify);
3323 ref = IBaseFilter_Release(filter);
3324 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3325 ok(presenter.refcount == 1, "Got outstanding refcount %ld.\n", presenter.refcount);
3326 ok(presenter2.refcount == 1, "Got outstanding refcount %ld.\n", presenter2.refcount);
3328 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3330}
3331
3332static void test_mixing_mode(void)
3333{
3334 IVMRWindowlessControl9 *windowless_control;
3335 IVMRMixerControl9 *mixer_control;
3337 DWORD stream_count = 0;
3339 unsigned int i;
3340 HWND window;
3341 HRESULT hr;
3342 ULONG ref;
3343
3344 static const VMR9Mode modes[] =
3345 {
3346 0,
3350 };
3351
3352 for (i = 0; i < ARRAY_SIZE(modes); ++i)
3353 {
3354 filter = create_vmr9(modes[i]);
3355 IBaseFilter_QueryInterface(filter, &IID_IVMRFilterConfig9, (void **)&config);
3356
3357 hr = IBaseFilter_QueryInterface(filter, &IID_IVMRMixerControl9, (void **)&mixer_control);
3358 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
3359
3360 hr = IVMRFilterConfig9_GetNumberOfStreams(config, &stream_count);
3361 ok(hr == VFW_E_VMR_NOT_IN_MIXER_MODE, "Got hr %#lx.\n", hr);
3362
3363 hr = IVMRFilterConfig9_SetNumberOfStreams(config, 1);
3364 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3365
3366 hr = IVMRFilterConfig9_GetNumberOfStreams(config, &stream_count);
3367 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3368 ok(stream_count == 1, "Got %lu streams.\n", stream_count);
3369
3370 hr = IBaseFilter_QueryInterface(filter, &IID_IVMRMixerControl9, (void **)&mixer_control);
3371 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3372 IVMRMixerControl9_Release(mixer_control);
3373
3374 hr = IVMRFilterConfig9_SetNumberOfStreams(config, 2);
3375 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
3376
3377 hr = IVMRFilterConfig9_GetNumberOfStreams(config, &stream_count);
3378 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3379 ok(stream_count == 1, "Got %lu streams.\n", stream_count);
3380
3381 IVMRFilterConfig9_Release(config);
3382 ref = IBaseFilter_Release(filter);
3383 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3384 }
3385
3387 IBaseFilter_QueryInterface(filter, &IID_IVMRFilterConfig9, (void **)&config);
3388 IBaseFilter_QueryInterface(filter, &IID_IVMRWindowlessControl9, (void **)&windowless_control);
3389
3390 window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
3391 ok(!!window, "Failed to create a window.\n");
3392 hr = IVMRWindowlessControl9_SetVideoClippingWindow(windowless_control, window);
3393 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3394
3395 hr = IVMRFilterConfig9_GetNumberOfStreams(config, &stream_count);
3396 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3397 ok(stream_count == 4, "Got %lu streams.\n", stream_count);
3398
3399 hr = IBaseFilter_QueryInterface(filter, &IID_IVMRMixerControl9, (void **)&mixer_control);
3400 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3401 IVMRMixerControl9_Release(mixer_control);
3402
3403 hr = IVMRFilterConfig9_SetNumberOfStreams(config, 2);
3404 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
3405
3406 hr = IVMRFilterConfig9_GetNumberOfStreams(config, &stream_count);
3407 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3408 ok(stream_count == 4, "Got %lu streams.\n", stream_count);
3409
3410 IVMRWindowlessControl9_Release(windowless_control);
3411 IVMRFilterConfig9_Release(config);
3412 ref = IBaseFilter_Release(filter);
3413 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3415}
3416
3417static void test_clipping_window(void)
3418{
3419 VIDEOINFOHEADER vih =
3420 {
3422 .bmiHeader.biWidth = 32,
3423 .bmiHeader.biHeight = 16,
3424 .bmiHeader.biBitCount = 32,
3425 };
3427 {
3428 .majortype = MEDIATYPE_Video,
3429 .subtype = MEDIASUBTYPE_RGB32,
3430 .formattype = FORMAT_VideoInfo,
3431 .cbFormat = sizeof(vih),
3432 .pbFormat = (BYTE *)&vih,
3433 };
3435 IVMRWindowlessControl9 *windowless_control;
3437 struct testfilter source;
3438 HWND window;
3439 HRESULT hr;
3440 ULONG ref;
3441 IPin *pin;
3442
3443 IBaseFilter_QueryInterface(filter, &IID_IVMRWindowlessControl9, (void **)&windowless_control);
3444 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
3446 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
3447 IFilterGraph2_AddFilter(graph, filter, L"vmr9");
3448 window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
3449 ok(!!window, "Failed to create a window.\n");
3450
3451 hr = IVMRWindowlessControl9_SetVideoClippingWindow(windowless_control, NULL);
3452 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3453 hr = IVMRWindowlessControl9_SetVideoClippingWindow(windowless_control, (HWND)0xdeadbeef);
3454 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3455
3456 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3457 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3458
3459 hr = IVMRWindowlessControl9_SetVideoClippingWindow(windowless_control, window);
3460 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
3461
3462 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
3463 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3464 hr = IFilterGraph2_Disconnect(graph, pin);
3465 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3466
3467 hr = IVMRWindowlessControl9_SetVideoClippingWindow(windowless_control, window);
3468 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3469
3470 ref = IFilterGraph2_Release(graph);
3471 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3472 IPin_Release(pin);
3473 IVMRWindowlessControl9_Release(windowless_control);
3474 ref = IBaseFilter_Release(filter);
3475 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3477}
3478
3480{
3481 struct presenter presenter =
3482 {
3484 .IVMRImagePresenter9_iface.lpVtbl = &presenter_vtbl,
3485 .refcount = 1,
3486 };
3489 HRESULT hr;
3490 ULONG ref;
3491
3493
3494 IBaseFilter_QueryInterface(filter, &IID_IVMRSurfaceAllocatorNotify9, (void **)&notify);
3495
3496 hr = IVMRSurfaceAllocatorNotify9_AdviseSurfaceAllocator(notify, 0xabacab,
3498 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3499
3500 ref = IBaseFilter_Release(filter);
3501 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3502 ok(presenter.got_TerminateDevice == 1, "Got %u calls to TerminateDevice().\n",
3504 ok(presenter.refcount == 1, "Got outstanding refcount %ld.\n", presenter.refcount);
3505
3506 ref = IVMRSurfaceAllocatorNotify9_Release(notify);
3507 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3508}
3509
3510static void check_source_position_(int line, IBasicVideo *video,
3511 LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
3512{
3513 LONG left, top, width, height, l;
3514 HRESULT hr;
3515
3516 left = top = width = height = 0xdeadbeef;
3517 hr = IBasicVideo_GetSourcePosition(video, &left, &top, &width, &height);
3518 ok_(__FILE__,line)(hr == S_OK, "Got hr %#lx.\n", hr);
3519 ok_(__FILE__,line)(left == expect_left, "Got left %ld.\n", left);
3520 ok_(__FILE__,line)(top == expect_top, "Got top %ld.\n", top);
3521 ok_(__FILE__,line)(width == expect_width, "Got width %ld.\n", width);
3522 ok_(__FILE__,line)(height == expect_height, "Got height %ld.\n", height);
3523
3524 l = 0xdeadbeef;
3525 hr = IBasicVideo_get_SourceLeft(video, &l);
3526 ok_(__FILE__,line)(hr == S_OK, "Failed to get left, hr %#lx.\n", hr);
3527 ok_(__FILE__,line)(l == left, "Got left %ld.\n", l);
3528
3529 l = 0xdeadbeef;
3530 hr = IBasicVideo_get_SourceTop(video, &l);
3531 ok_(__FILE__,line)(hr == S_OK, "Failed to get top, hr %#lx.\n", hr);
3532 ok_(__FILE__,line)(l == top, "Got top %ld.\n", l);
3533
3534 l = 0xdeadbeef;
3535 hr = IBasicVideo_get_SourceWidth(video, &l);
3536 ok_(__FILE__,line)(hr == S_OK, "Failed to get width, hr %#lx.\n", hr);
3537 ok_(__FILE__,line)(l == width, "Got width %ld.\n", l);
3538
3539 l = 0xdeadbeef;
3540 hr = IBasicVideo_get_SourceHeight(video, &l);
3541 ok_(__FILE__,line)(hr == S_OK, "Failed to get height, hr %#lx.\n", hr);
3542 ok_(__FILE__,line)(l == height, "Got height %ld.\n", l);
3543}
3544#define check_source_position(a,b,c,d,e) check_source_position_(__LINE__,a,b,c,d,e)
3545
3546static void test_basic_video_source(IBasicVideo *video)
3547{
3548 HRESULT hr;
3549
3550 check_source_position(video, 0, 0, 600, 400);
3551 hr = IBasicVideo_IsUsingDefaultSource(video);
3552 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3553
3554 hr = IBasicVideo_put_SourceLeft(video, -10);
3555 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3556 hr = IBasicVideo_put_SourceLeft(video, 10);
3557 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3558
3559 hr = IBasicVideo_put_SourceTop(video, -10);
3560 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3561 hr = IBasicVideo_put_SourceTop(video, 10);
3562 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3563
3564 hr = IBasicVideo_put_SourceWidth(video, -500);
3565 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3566 hr = IBasicVideo_put_SourceWidth(video, 0);
3567 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3568 hr = IBasicVideo_put_SourceWidth(video, 700);
3569 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3570 hr = IBasicVideo_put_SourceWidth(video, 500);
3571 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3572 check_source_position(video, 0, 0, 500, 400);
3573 hr = IBasicVideo_IsUsingDefaultSource(video);
3574 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3575
3576 hr = IBasicVideo_put_SourceHeight(video, -300);
3577 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3578 hr = IBasicVideo_put_SourceHeight(video, 0);
3579 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3580 hr = IBasicVideo_put_SourceHeight(video, 600);
3581 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3582 hr = IBasicVideo_put_SourceHeight(video, 300);
3583 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3584 check_source_position(video, 0, 0, 500, 300);
3585 hr = IBasicVideo_IsUsingDefaultSource(video);
3586 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3587
3588 hr = IBasicVideo_put_SourceLeft(video, -10);
3589 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3590 hr = IBasicVideo_put_SourceLeft(video, 10);
3591 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3592 check_source_position(video, 10, 0, 500, 300);
3593 hr = IBasicVideo_IsUsingDefaultSource(video);
3594 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3595
3596 hr = IBasicVideo_put_SourceTop(video, -10);
3597 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3598 hr = IBasicVideo_put_SourceTop(video, 20);
3599 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3600 check_source_position(video, 10, 20, 500, 300);
3601 hr = IBasicVideo_IsUsingDefaultSource(video);
3602 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3603
3604 hr = IBasicVideo_SetSourcePosition(video, 4, 5, 60, 40);
3605 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3606 check_source_position(video, 4, 5, 60, 40);
3607 hr = IBasicVideo_IsUsingDefaultSource(video);
3608 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3609
3610 hr = IBasicVideo_SetSourcePosition(video, 0, 0, 600, 400);
3611 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3612 check_source_position(video, 0, 0, 600, 400);
3613 hr = IBasicVideo_IsUsingDefaultSource(video);
3614 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3615
3616 hr = IBasicVideo_SetSourcePosition(video, 4, 5, 60, 40);
3617 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3618 hr = IBasicVideo_SetDefaultSourcePosition(video);
3619 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3620 check_source_position(video, 0, 0, 600, 400);
3621 hr = IBasicVideo_IsUsingDefaultSource(video);
3622 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3623}
3624
3625static void check_destination_position_(int line, IBasicVideo *video,
3626 LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
3627{
3628 LONG left, top, width, height, l;
3629 HRESULT hr;
3630
3631 left = top = width = height = 0xdeadbeef;
3632 hr = IBasicVideo_GetDestinationPosition(video, &left, &top, &width, &height);
3633 ok_(__FILE__,line)(hr == S_OK, "Failed to get position, hr %#lx.\n", hr);
3634 ok_(__FILE__,line)(left == expect_left, "Got left %ld.\n", left);
3635 ok_(__FILE__,line)(top == expect_top, "Got top %ld.\n", top);
3636 ok_(__FILE__,line)(width == expect_width, "Got width %ld.\n", width);
3637 ok_(__FILE__,line)(height == expect_height, "Got height %ld.\n", height);
3638
3639 l = 0xdeadbeef;
3640 hr = IBasicVideo_get_DestinationLeft(video, &l);
3641 ok_(__FILE__,line)(hr == S_OK, "Failed to get left, hr %#lx.\n", hr);
3642 ok_(__FILE__,line)(l == left, "Got left %ld.\n", l);
3643
3644 l = 0xdeadbeef;
3645 hr = IBasicVideo_get_DestinationTop(video, &l);
3646 ok_(__FILE__,line)(hr == S_OK, "Failed to get top, hr %#lx.\n", hr);
3647 ok_(__FILE__,line)(l == top, "Got top %ld.\n", l);
3648
3649 l = 0xdeadbeef;
3650 hr = IBasicVideo_get_DestinationWidth(video, &l);
3651 ok_(__FILE__,line)(hr == S_OK, "Failed to get width, hr %#lx.\n", hr);
3652 ok_(__FILE__,line)(l == width, "Got width %ld.\n", l);
3653
3654 l = 0xdeadbeef;
3655 hr = IBasicVideo_get_DestinationHeight(video, &l);
3656 ok_(__FILE__,line)(hr == S_OK, "Failed to get height, hr %#lx.\n", hr);
3657 ok_(__FILE__,line)(l == height, "Got height %ld.\n", l);
3658}
3659#define check_destination_position(a,b,c,d,e) check_destination_position_(__LINE__,a,b,c,d,e)
3660
3661static void test_basic_video_destination(IBasicVideo *video)
3662{
3663 IVideoWindow *window;
3664 HRESULT hr;
3665 RECT rect;
3666
3667 IBasicVideo_QueryInterface(video, &IID_IVideoWindow, (void **)&window);
3668
3669 check_destination_position(video, 0, 0, 600, 400);
3670 hr = IBasicVideo_IsUsingDefaultDestination(video);
3671 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3672
3673 hr = IBasicVideo_put_DestinationLeft(video, -10);
3674 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3675 check_destination_position(video, -10, 0, 600, 400);
3676 hr = IBasicVideo_IsUsingDefaultDestination(video);
3677 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3678
3679 hr = IBasicVideo_put_DestinationLeft(video, 10);
3680 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3681 check_destination_position(video, 10, 0, 600, 400);
3682 hr = IBasicVideo_IsUsingDefaultDestination(video);
3683 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3684
3685 hr = IBasicVideo_put_DestinationTop(video, -20);
3686 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3687 check_destination_position(video, 10, -20, 600, 400);
3688 hr = IBasicVideo_IsUsingDefaultDestination(video);
3689 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3690
3691 hr = IBasicVideo_put_DestinationTop(video, 20);
3692 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3693 check_destination_position(video, 10, 20, 600, 400);
3694 hr = IBasicVideo_IsUsingDefaultDestination(video);
3695 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3696
3697 hr = IBasicVideo_put_DestinationWidth(video, -700);
3698 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3699 hr = IBasicVideo_put_DestinationWidth(video, 0);
3700 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3701 hr = IBasicVideo_put_DestinationWidth(video, 700);
3702 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3703 check_destination_position(video, 10, 20, 700, 400);
3704 hr = IBasicVideo_IsUsingDefaultDestination(video);
3705 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3706
3707 hr = IBasicVideo_put_DestinationWidth(video, 500);
3708 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3709 check_destination_position(video, 10, 20, 500, 400);
3710 hr = IBasicVideo_IsUsingDefaultDestination(video);
3711 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3712
3713 hr = IBasicVideo_put_DestinationHeight(video, -500);
3714 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3715 hr = IBasicVideo_put_DestinationHeight(video, 0);
3716 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
3717 hr = IBasicVideo_put_DestinationHeight(video, 500);
3718 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3719 check_destination_position(video, 10, 20, 500, 500);
3720 hr = IBasicVideo_IsUsingDefaultDestination(video);
3721 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3722
3723 hr = IBasicVideo_put_DestinationHeight(video, 300);
3724 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3725 check_destination_position(video, 10, 20, 500, 300);
3726 hr = IBasicVideo_IsUsingDefaultDestination(video);
3727 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3728
3729 hr = IBasicVideo_SetDestinationPosition(video, 4, 5, 60, 40);
3730 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3731 check_destination_position(video, 4, 5, 60, 40);
3732 hr = IBasicVideo_IsUsingDefaultDestination(video);
3733 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3734
3735 hr = IBasicVideo_SetDestinationPosition(video, 0, 0, 600, 400);
3736 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3737 check_destination_position(video, 0, 0, 600, 400);
3738 hr = IBasicVideo_IsUsingDefaultDestination(video);
3739 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3740
3741 hr = IBasicVideo_SetDestinationPosition(video, 4, 5, 60, 40);
3742 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3743 hr = IBasicVideo_SetDefaultDestinationPosition(video);
3744 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3745 check_destination_position(video, 0, 0, 600, 400);
3746 hr = IBasicVideo_IsUsingDefaultDestination(video);
3747 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3748
3749 SetRect(&rect, 100, 200, 500, 500);
3751 hr = IVideoWindow_SetWindowPosition(window, rect.left, rect.top,
3753 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3754 check_destination_position(video, 0, 0, 400, 300);
3755 hr = IBasicVideo_IsUsingDefaultDestination(video);
3756 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3757
3758 hr = IBasicVideo_SetDestinationPosition(video, 0, 0, 400, 300);
3759 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3760 check_destination_position(video, 0, 0, 400, 300);
3761 hr = IBasicVideo_IsUsingDefaultDestination(video);
3762 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3763
3764 SetRect(&rect, 100, 200, 600, 600);
3766 hr = IVideoWindow_SetWindowPosition(window, rect.left, rect.top,
3768 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3769 check_destination_position(video, 0, 0, 400, 300);
3770 hr = IBasicVideo_IsUsingDefaultDestination(video);
3771 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3772
3773 IVideoWindow_Release(window);
3774}
3775
3776static void test_basic_video(void)
3777{
3778 ALLOCATOR_PROPERTIES req_props = {1, 600 * 400 * 4, 1, 0}, ret_props;
3779 VIDEOINFOHEADER vih =
3780 {
3781 .AvgTimePerFrame = 200000,
3782 .rcSource = {4, 6, 16, 12},
3783 .rcTarget = {40, 60, 120, 160},
3784 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
3785 .bmiHeader.biBitCount = 32,
3786 .bmiHeader.biWidth = 600,
3787 .bmiHeader.biHeight = 400,
3788 .bmiHeader.biPlanes = 1,
3789 .bmiHeader.biCompression = BI_RGB,
3790 };
3791 AM_MEDIA_TYPE req_mt =
3792 {
3793 .majortype = MEDIATYPE_Video,
3794 .subtype = MEDIASUBTYPE_RGB32,
3795 .formattype = FORMAT_VideoInfo,
3796 .cbFormat = sizeof(vih),
3797 .pbFormat = (BYTE *)&vih,
3798 };
3801 LONG left, top, width, height, l;
3802 struct testfilter source;
3806 IBasicVideo *video;
3807 TYPEATTR *typeattr;
3808 REFTIME reftime;
3809 HRESULT hr;
3810 UINT count;
3811 ULONG ref;
3812 IPin *pin;
3813 RECT rect;
3814
3815 IBaseFilter_QueryInterface(filter, &IID_IBasicVideo, (void **)&video);
3816 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
3817 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
3818
3819 hr = IBasicVideo_GetTypeInfoCount(video, &count);
3820 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3821 ok(count == 1, "Got count %u.\n", count);
3822
3823 hr = IBasicVideo_GetTypeInfo(video, 0, 0, &typeinfo);
3824 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3825 hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
3826 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3827 ok(typeattr->typekind == TKIND_DISPATCH, "Got kind %u.\n", typeattr->typekind);
3828 ok(IsEqualGUID(&typeattr->guid, &IID_IBasicVideo), "Got IID %s.\n", wine_dbgstr_guid(&typeattr->guid));
3829 ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
3830 ITypeInfo_Release(typeinfo);
3831
3832 hr = IBasicVideo_get_AvgTimePerFrame(video, NULL);
3833 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3834 hr = IBasicVideo_get_AvgTimePerFrame(video, &reftime);
3835 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
3836
3837 hr = IBasicVideo_get_BitRate(video, NULL);
3838 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3839 hr = IBasicVideo_get_BitRate(video, &l);
3840 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
3841
3842 hr = IBasicVideo_get_BitErrorRate(video, NULL);
3843 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3844 hr = IBasicVideo_get_BitErrorRate(video, &l);
3845 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
3846
3847 hr = IBasicVideo_get_VideoWidth(video, NULL);
3848 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3849 hr = IBasicVideo_get_VideoHeight(video, NULL);
3850 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3851
3852 hr = IBasicVideo_get_SourceLeft(video, NULL);
3853 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3854 hr = IBasicVideo_get_SourceWidth(video, NULL);
3855 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3856 hr = IBasicVideo_get_SourceTop(video, NULL);
3857 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3858 hr = IBasicVideo_get_SourceHeight(video, NULL);
3859 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3860
3861 hr = IBasicVideo_get_DestinationLeft(video, NULL);
3862 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3863 hr = IBasicVideo_get_DestinationWidth(video, NULL);
3864 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3865 hr = IBasicVideo_get_DestinationTop(video, NULL);
3866 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3867 hr = IBasicVideo_get_DestinationHeight(video, NULL);
3868 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3869
3870 hr = IBasicVideo_GetSourcePosition(video, NULL, &top, &width, &height);
3871 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3872 hr = IBasicVideo_GetSourcePosition(video, &left, NULL, &width, &height);
3873 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3874 hr = IBasicVideo_GetSourcePosition(video, &left, &top, NULL, &height);
3875 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3876 hr = IBasicVideo_GetSourcePosition(video, &left, &top, &width, NULL);
3877 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3878
3879 hr = IBasicVideo_GetDestinationPosition(video, NULL, &top, &width, &height);
3880 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3881 hr = IBasicVideo_GetDestinationPosition(video, &left, NULL, &width, &height);
3882 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3883 hr = IBasicVideo_GetDestinationPosition(video, &left, &top, NULL, &height);
3884 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3885 hr = IBasicVideo_GetDestinationPosition(video, &left, &top, &width, NULL);
3886 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3887
3888 hr = IBasicVideo_GetVideoSize(video, &width, NULL);
3889 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3890 hr = IBasicVideo_GetVideoSize(video, NULL, &height);
3891 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3892 hr = IBasicVideo_GetVideoSize(video, &width, &height);
3893 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
3894
3895 hr = IBasicVideo_GetVideoPaletteEntries(video, 0, 1, NULL, &l);
3896 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3897 hr = IBasicVideo_GetVideoPaletteEntries(video, 0, 1, &l, NULL);
3898 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
3899
3901 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, L"vmr9");
3902 IFilterGraph2_AddFilter(graph, filter, L"source");
3903 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
3904 if (hr == E_FAIL)
3905 {
3906 skip("Got E_FAIL when connecting.\n");
3907 goto out;
3908 }
3909 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3910
3911 hr = IMemInputPin_GetAllocator(input, &allocator);
3912 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
3913 if (hr == S_OK)
3914 {
3915 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
3916 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3917 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
3918 hr = IMemAllocator_Commit(allocator);
3919 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3920 IMemAllocator_Release(allocator);
3921 }
3922
3923 reftime = 0.0;
3924 hr = IBasicVideo_get_AvgTimePerFrame(video, &reftime);
3925 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3926 ok(compare_double(reftime, 0.02, 1 << 28), "Got frame rate %.16e.\n", reftime);
3927
3928 l = 0xdeadbeef;
3929 hr = IBasicVideo_get_BitRate(video, &l);
3930 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3931 ok(!l, "Got bit rate %ld.\n", l);
3932
3933 l = 0xdeadbeef;
3934 hr = IBasicVideo_get_BitErrorRate(video, &l);
3935 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3936 ok(!l, "Got bit rate %ld.\n", l);
3937
3938 hr = IBasicVideo_GetVideoPaletteEntries(video, 0, 1, &l, NULL);
3939 todo_wine ok(hr == VFW_E_NO_PALETTE_AVAILABLE, "Got hr %#lx.\n", hr);
3940
3941 width = height = 0xdeadbeef;
3942 hr = IBasicVideo_GetVideoSize(video, &width, &height);
3943 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3944 ok(width == 600, "Got width %ld.\n", width);
3945 ok(height == 400, "Got height %ld.\n", height);
3946
3949
3950 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
3951 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3952 hr = IFilterGraph2_Disconnect(graph, pin);
3953 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3954
3955 vih.bmiHeader.biWidth = 16;
3956 vih.bmiHeader.biHeight = 16;
3957 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
3958 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3959
3960 hr = IMemInputPin_GetAllocator(input, &allocator);
3961 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
3962 if (hr == S_OK)
3963 {
3964 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
3965 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3966 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
3967 hr = IMemAllocator_Commit(allocator);
3968 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3969 IMemAllocator_Release(allocator);
3970 }
3971
3972 check_source_position(video, 0, 0, 16, 16);
3973
3974 SetRect(&rect, 0, 0, 0, 0);
3978
3979out:
3980 ref = IFilterGraph2_Release(graph);
3981 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3982 IBasicVideo_Release(video);
3983 IMemInputPin_Release(input);
3984 IPin_Release(pin);
3985 ref = IBaseFilter_Release(filter);
3986 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3987 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
3988 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3989}
3990
3991static void test_windowless_size(void)
3992{
3993 ALLOCATOR_PROPERTIES req_props = {1, 32 * 16 * 4, 1, 0}, ret_props;
3994 VIDEOINFOHEADER vih =
3995 {
3997 .bmiHeader.biWidth = 32,
3998 .bmiHeader.biHeight = 16,
3999 .bmiHeader.biBitCount = 32,
4000 .bmiHeader.biPlanes = 1,
4001 };
4003 {
4004 .majortype = MEDIATYPE_Video,
4005 .subtype = MEDIASUBTYPE_RGB32,
4006 .formattype = FORMAT_VideoInfo,
4007 .cbFormat = sizeof(vih),
4008 .pbFormat = (BYTE *)&vih,
4009 };
4011 LONG width, height, aspect_width, aspect_height;
4012 IVMRAspectRatioControl9 *aspect_ratio_control;
4013 IVMRWindowlessControl9 *windowless_control;
4015 struct testfilter source;
4017 RECT src, dst, expect;
4019 DWORD aspect_mode;
4020 HWND window;
4021 HRESULT hr;
4022 ULONG ref;
4023 IPin *pin;
4024
4025 IBaseFilter_QueryInterface(filter, &IID_IVMRWindowlessControl9, (void **)&windowless_control);
4026 IBaseFilter_QueryInterface(filter, &IID_IVMRAspectRatioControl9, (void **)&aspect_ratio_control);
4027 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
4028 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
4030 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
4031 IFilterGraph2_AddFilter(graph, filter, L"vmr9");
4032 window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
4033 ok(!!window, "Failed to create a window.\n");
4034
4035 hr = IVMRWindowlessControl9_SetVideoClippingWindow(windowless_control, window);
4036 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4037
4038 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
4039 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4040 hr = IMemInputPin_GetAllocator(input, &allocator);
4041 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
4042 if (hr == S_OK)
4043 {
4044 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
4045 IMemAllocator_Release(allocator);
4046 if (hr == E_FAIL)
4047 {
4048 skip("Got E_FAIL when setting allocator properties.\n");
4049 goto out;
4050 }
4051 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4052 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
4053 }
4054
4055 hr = IVMRWindowlessControl9_GetNativeVideoSize(windowless_control, NULL, &height, &aspect_width, &aspect_height);
4056 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
4057 hr = IVMRWindowlessControl9_GetNativeVideoSize(windowless_control, &width, NULL, &aspect_width, &aspect_height);
4058 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
4059
4060 aspect_mode = 0xdeadbeef;
4061 hr = IVMRWindowlessControl9_GetAspectRatioMode(windowless_control, &aspect_mode);
4062 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4063 ok(aspect_mode == VMR9ARMode_None, "Got mode %lu.\n", aspect_mode);
4064
4065 aspect_mode = 0xdeadbeef;
4066 hr = IVMRAspectRatioControl9_GetAspectRatioMode(aspect_ratio_control, &aspect_mode);
4067 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4068 ok(aspect_mode == VMR9ARMode_None, "Got mode %lu.\n", aspect_mode);
4069
4070 width = height = 0xdeadbeef;
4071 hr = IVMRWindowlessControl9_GetNativeVideoSize(windowless_control, &width, &height, NULL, NULL);
4072 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4073 ok(width == 32, "Got width %ld.\n", width);
4074 ok(height == 16, "Got height %ld.\n", height);
4075
4076 aspect_width = aspect_height = 0xdeadbeef;
4077 hr = IVMRWindowlessControl9_GetNativeVideoSize(windowless_control, &width, &height, &aspect_width, &aspect_height);
4078 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4079 ok(aspect_width == 32, "Got width %ld.\n", aspect_width);
4080 ok(aspect_height == 16, "Got height %ld.\n", aspect_height);
4081
4082 memset(&src, 0xcc, sizeof(src));
4083 hr = IVMRWindowlessControl9_GetVideoPosition(windowless_control, &src, NULL);
4084 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4085 SetRect(&expect, 0, 0, 32, 16);
4086 ok(EqualRect(&src, &expect), "Got source rect %s.\n", wine_dbgstr_rect(&src));
4087
4088 memset(&dst, 0xcc, sizeof(dst));
4089 hr = IVMRWindowlessControl9_GetVideoPosition(windowless_control, NULL, &dst);
4090 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4091 SetRect(&expect, 0, 0, 0, 0);
4092 ok(EqualRect(&dst, &expect), "Got dest rect %s.\n", wine_dbgstr_rect(&dst));
4093
4094 SetRect(&src, 4, 6, 16, 12);
4095 hr = IVMRWindowlessControl9_SetVideoPosition(windowless_control, &src, NULL);
4096 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4097
4098 memset(&src, 0xcc, sizeof(src));
4099 memset(&dst, 0xcc, sizeof(dst));
4100 hr = IVMRWindowlessControl9_GetVideoPosition(windowless_control, &src, &dst);
4101 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4102 SetRect(&expect, 4, 6, 16, 12);
4103 ok(EqualRect(&src, &expect), "Got source rect %s.\n", wine_dbgstr_rect(&src));
4104 SetRect(&expect, 0, 0, 0, 0);
4105 ok(EqualRect(&dst, &expect), "Got dest rect %s.\n", wine_dbgstr_rect(&dst));
4106
4107 SetRect(&dst, 40, 60, 120, 160);
4108 hr = IVMRWindowlessControl9_SetVideoPosition(windowless_control, NULL, &dst);
4109 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4110
4111 memset(&src, 0xcc, sizeof(src));
4112 memset(&dst, 0xcc, sizeof(dst));
4113 hr = IVMRWindowlessControl9_GetVideoPosition(windowless_control, &src, &dst);
4114 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4115 SetRect(&expect, 4, 6, 16, 12);
4116 ok(EqualRect(&src, &expect), "Got source rect %s.\n", wine_dbgstr_rect(&src));
4117 SetRect(&expect, 40, 60, 120, 160);
4118 ok(EqualRect(&dst, &expect), "Got dest rect %s.\n", wine_dbgstr_rect(&dst));
4119
4121 SetRect(&expect, 0, 0, 640, 480);
4122 ok(EqualRect(&src, &expect), "Got window rect %s.\n", wine_dbgstr_rect(&src));
4123
4124 hr = IVMRAspectRatioControl9_SetAspectRatioMode(aspect_ratio_control, VMR9ARMode_LetterBox);
4125 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4126
4127 aspect_mode = 0xdeadbeef;
4128 hr = IVMRWindowlessControl9_GetAspectRatioMode(windowless_control, &aspect_mode);
4129 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4130 ok(aspect_mode == VMR9ARMode_LetterBox, "Got mode %lu.\n", aspect_mode);
4131
4132 hr = IVMRWindowlessControl9_SetAspectRatioMode(windowless_control, VMR9ARMode_None);
4133 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4134
4135 aspect_mode = 0xdeadbeef;
4136 hr = IVMRAspectRatioControl9_GetAspectRatioMode(aspect_ratio_control, &aspect_mode);
4137 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4138 ok(aspect_mode == VMR9ARMode_None, "Got mode %lu.\n", aspect_mode);
4139
4140 hr = IVMRWindowlessControl9_SetAspectRatioMode(windowless_control, VMR9ARMode_LetterBox);
4141 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4142
4143 memset(&src, 0xcc, sizeof(src));
4144 memset(&dst, 0xcc, sizeof(dst));
4145 hr = IVMRWindowlessControl9_GetVideoPosition(windowless_control, &src, &dst);
4146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4147 SetRect(&expect, 4, 6, 16, 12);
4148 ok(EqualRect(&src, &expect), "Got source rect %s.\n", wine_dbgstr_rect(&src));
4149 SetRect(&expect, 40, 60, 120, 160);
4150 ok(EqualRect(&dst, &expect), "Got dest rect %s.\n", wine_dbgstr_rect(&dst));
4151
4152 SetRect(&src, 0, 0, 32, 16);
4153 SetRect(&dst, 0, 0, 640, 480);
4154 hr = IVMRWindowlessControl9_SetVideoPosition(windowless_control, &src, &dst);
4155 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4156
4157 memset(&src, 0xcc, sizeof(src));
4158 memset(&dst, 0xcc, sizeof(dst));
4159 hr = IVMRWindowlessControl9_GetVideoPosition(windowless_control, &src, &dst);
4160 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4161 SetRect(&expect, 0, 0, 32, 16);
4162 ok(EqualRect(&src, &expect), "Got source rect %s.\n", wine_dbgstr_rect(&src));
4163 SetRect(&expect, 0, 0, 640, 480);
4164 ok(EqualRect(&dst, &expect), "Got dest rect %s.\n", wine_dbgstr_rect(&dst));
4165
4166out:
4167 ref = IFilterGraph2_Release(graph);
4168 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4169 IMemInputPin_Release(input);
4170 IPin_Release(pin);
4171 IVMRWindowlessControl9_Release(windowless_control);
4172 IVMRAspectRatioControl9_Release(aspect_ratio_control);
4173 ref = IBaseFilter_Release(filter);
4174 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4176}
4177
4178static void test_mixing_prefs(void)
4179{
4181 IVMRMixerControl9 *mixer_control;
4182 DWORD flags;
4183 HRESULT hr;
4184 ULONG ref;
4185
4187
4188 hr = IBaseFilter_QueryInterface(filter, &IID_IVMRMixerControl9, (void **)&mixer_control);
4189 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4190
4191 hr = IVMRMixerControl9_GetMixingPrefs(mixer_control, &flags);
4192 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4194 | MixerPref9_RenderTargetRGB), "Got flags %#lx.\n", flags);
4195
4196 hr = IVMRMixerControl9_SetMixingPrefs(mixer_control, MixerPref9_NoDecimation
4198 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4199
4200 hr = IVMRMixerControl9_GetMixingPrefs(mixer_control, &flags);
4201 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4203 | MixerPref9_RenderTargetRGB), "Got flags %#lx.\n", flags);
4204
4205 IVMRMixerControl9_Release(mixer_control);
4206 ref = IBaseFilter_Release(filter);
4207 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4208}
4209
4210static void test_unconnected_eos(void)
4211{
4214 IMediaControl *control;
4215 IMediaEvent *eventsrc;
4216 unsigned int ret;
4217 HRESULT hr;
4218 ULONG ref;
4219
4220 hr = IFilterGraph2_AddFilter(graph, filter, L"renderer");
4221 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4222
4223 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
4224 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4225
4226 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&eventsrc);
4227 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4228
4229 ret = check_ec_complete(eventsrc, 0);
4230 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
4231
4232 hr = IMediaControl_Pause(control);
4233 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4234
4235 ret = check_ec_complete(eventsrc, 0);
4236 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
4237
4238 hr = IMediaControl_Run(control);
4239 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4240
4241 ret = check_ec_complete(eventsrc, 0);
4242 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
4243
4244 hr = IMediaControl_Pause(control);
4245 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4246
4247 ret = check_ec_complete(eventsrc, 0);
4248 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
4249
4250 hr = IMediaControl_Run(control);
4251 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4252
4253 ret = check_ec_complete(eventsrc, 0);
4254 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
4255
4256 hr = IMediaControl_Stop(control);
4257 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4258
4259 ret = check_ec_complete(eventsrc, 0);
4260 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
4261
4262 hr = IMediaControl_Run(control);
4263 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4264
4265 ret = check_ec_complete(eventsrc, 0);
4266 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
4267
4268 IMediaControl_Release(control);
4269 IMediaEvent_Release(eventsrc);
4270 ref = IFilterGraph2_Release(graph);
4271 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4272 ref = IBaseFilter_Release(filter);
4273 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4274}
4275
4276static void test_notifyevent(void)
4277{
4281 IMediaEvent *eventsrc;
4282 unsigned int ret;
4283 HRESULT hr;
4284 ULONG ref;
4285
4286 hr = IFilterGraph2_AddFilter(graph, filter, NULL);
4287 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4288
4289 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&eventsrc);
4290 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4291
4292 ret = check_event_code(eventsrc, 0, 0x12345678, 0x9ABC, 0xDEF0);
4293 ok(ret == 0, "Got %u custom events.\n", ret);
4294
4295 hr = IBaseFilter_QueryInterface(filter, &IID_IVMRSurfaceAllocatorNotify9, (void **)&notify);
4296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4297 hr = IVMRSurfaceAllocatorNotify9_NotifyEvent(notify, 0x12345678, 0x9ABC, 0xDEF0);
4298 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4299
4300 ret = check_event_code(eventsrc, 0, 0x12345678, 0x9ABC, 0xDEF0);
4301 ok(ret == 1, "Got %u custom events.\n", ret);
4302
4303 IMediaEvent_Release(eventsrc);
4304 ref = IFilterGraph2_Release(graph);
4305 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4306 ref = IBaseFilter_Release(filter);
4307 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4308 ref = IVMRSurfaceAllocatorNotify9_Release(notify);
4309 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4310}
4311
4312static void test_changed3ddevice(void)
4313{
4314 VIDEOINFOHEADER vih =
4315 {
4316 .rcSource = {4, 6, 16, 12},
4317 .rcTarget = {40, 60, 160, 120},
4318 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
4319 .bmiHeader.biWidth = 32,
4320 .bmiHeader.biHeight = 16,
4321 };
4322 AM_MEDIA_TYPE req_mt =
4323 {
4324 .majortype = MEDIATYPE_Video,
4325 .subtype = MEDIASUBTYPE_RGB32,
4326 .formattype = FORMAT_VideoInfo,
4327 .cbFormat = sizeof(vih),
4328 .pbFormat = (BYTE *)&vih,
4329 };
4330 struct presenter presenter =
4331 {
4333 .IVMRImagePresenter9_iface.lpVtbl = &presenter_vtbl,
4334 .refcount = 1,
4335 .accept_flags = VMR9AllocFlag_TextureSurface,
4336 };
4337 ALLOCATOR_PROPERTIES req_props = {5, 32 * 16 * 4, 1, 0}, ret_props;
4341 RECT rect = {0, 0, 640, 480};
4343 struct testfilter source;
4345 IMediaControl *control;
4347 OAFilterState state;
4348 IPin *pin = NULL;
4349 HWND window;
4350 HRESULT hr;
4351 ULONG ref;
4352
4354
4356 window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0,
4358 if (!(device = create_device(window)))
4359 {
4360 IBaseFilter_Release(filter);
4362 return;
4363 }
4364
4365 IBaseFilter_QueryInterface(filter, &IID_IVMRSurfaceAllocatorNotify9, (void **)&notify);
4367
4368 hr = IVMRSurfaceAllocatorNotify9_AdviseSurfaceAllocator(notify, 0xabacab,
4370 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4371
4372 hr = IVMRSurfaceAllocatorNotify9_SetD3DDevice(notify, device, MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY));
4373 if (hr == E_NOINTERFACE)
4374 {
4375 win_skip("Direct3D does not support video rendering.\n");
4376 goto out;
4377 }
4378 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4379
4381
4383 ok(device != NULL, "Couldn't create device\n");
4384
4385 hr = IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(notify, device, MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY));
4386 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4389
4390 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
4391 IFilterGraph2_AddFilter(graph, filter, NULL);
4392
4393 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
4394 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
4395 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4396
4397 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
4398
4399 hr = IMemInputPin_GetAllocator(input, &allocator);
4400 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
4401 if (hr == VFW_E_NO_ALLOCATOR)
4402 {
4403 CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
4404 &IID_IMemAllocator, (void **)&allocator);
4405
4406 hr = IMemInputPin_NotifyAllocator(input, allocator, TRUE);
4407 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4408 }
4409 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
4410 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4411 hr = IMemAllocator_Commit(allocator);
4412 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4413
4414 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
4415 hr = IMediaControl_Run(control);
4416 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
4417
4419
4420 hr = IMediaControl_GetState(control, 100, &state);
4421 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4422
4423 ok(presenter.got_PresentImage >= 1, "Got %u calls to PresentImage().\n", presenter.got_PresentImage);
4424 IMediaControl_Release(control);
4425
4426 hr = IMediaControl_Stop(control);
4427 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4428
4429 IMemAllocator_Release(allocator);
4430 IMemInputPin_Release(input);
4431 IPin_Release(pin);
4432
4433out:
4434 ref = IFilterGraph2_Release(graph);
4435 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4436 IVMRSurfaceAllocatorNotify9_Release(notify);
4437 ref = IBaseFilter_Release(filter);
4438 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4440 ok(!ref, "Got outstanding refcount %ld.\n", ref);
4442}
4443
4445{
4447 HRESULT hr;
4448
4450
4451 if (FAILED(hr = CoCreateInstance(&CLSID_VideoMixingRenderer9, NULL,
4452 CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void **)&filter)))
4453 {
4454 skip("Failed to create VMR9, hr %#lx.\n", hr);
4455 return;
4456 }
4457 IBaseFilter_Release(filter);
4458
4463 test_find_pin();
4464 test_pin_info();
4469 test_overlay();
4482
4484}
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define msg(x)
Definition: auth_time.c:54
DOUBLE REFTIME
Definition: axcore.idl:57
enum _PinDirection PIN_DIRECTION
@ PINDIR_INPUT
Definition: axcore.idl:41
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
static HANDLE thread
Definition: service.c:33
const GUID IID_IUnknown
r l[0]
Definition: byte_order.h:168
RECT rect
Definition: combotst.c:67
const GUID IID_IKsPropertySet
Definition: controlnode.cpp:13
#define D3DERR_INVALIDCALL
Definition: d3d10_private.h:42
@ D3DMULTISAMPLE_NONE
Definition: d3d8types.h:672
@ D3DFMT_A1R5G5B5
Definition: d3d8types.h:608
@ D3DFMT_UYVY
Definition: d3d8types.h:632
@ D3DFMT_YUY2
Definition: d3d8types.h:633
@ D3DFMT_X1R5G5B5
Definition: d3d8types.h:607
@ D3DFMT_R8G8B8
Definition: d3d8types.h:603
@ D3DFMT_A8R8G8B8
Definition: d3d8types.h:604
@ D3DFMT_R5G6B5
Definition: d3d8types.h:606
@ D3DFMT_A4R4G4B4
Definition: d3d8types.h:609
@ D3DFMT_X8R8G8B8
Definition: d3d8types.h:605
#define D3DUSAGE_DYNAMIC
Definition: d3d8types.h:99
@ D3DRTYPE_SURFACE
Definition: d3d8types.h:810
@ D3DSWAPEFFECT_DISCARD
Definition: d3d8types.h:851
@ D3DDEVTYPE_HAL
Definition: d3d8types.h:576
#define D3DUSAGE_RENDERTARGET
Definition: d3d8types.h:91
@ D3DPOOL_DEFAULT
Definition: d3d8types.h:709
enum _D3DFORMAT D3DFORMAT
IDirect3D9 *WINAPI Direct3DCreate9(UINT SDKVersion)
Definition: d3d9.c:57
#define IDirect3DSurface9_GetDevice(p, a)
Definition: d3d9.h:452
#define IDirect3D9_CreateDevice(p, a, b, c, d, e, f)
Definition: d3d9.h:224
#define IDirect3D9_Release(p)
Definition: d3d9.h:209
#define IDirect3DSurface9_GetContainer(p, a, b)
Definition: d3d9.h:461
#define IDirect3DSurface9_GetDesc(p, a)
Definition: d3d9.h:462
#define IDirect3DDevice9_Release(p)
Definition: d3d9.h:1336
#define IDirect3DSurface9_Release(p)
Definition: d3d9.h:450
#define IDirect3DTexture9_Release(p)
Definition: d3d9.h:842
#define D3D_OK
Definition: d3d.h:106
HRESULT expected_hr
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
struct config_s config
HRESULT hr
Definition: delayimp.cpp:582
const GUID IID_IBaseFilter
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT64 uint64_t
Definition: types.h:77
static struct default_presenter * impl_from_IVMRImagePresenter9(IVMRImagePresenter9 *iface)
Definition: vmr9.c:167
static struct default_presenter * impl_from_IVMRSurfaceAllocator9(IVMRSurfaceAllocator9 *iface)
Definition: vmr9.c:172
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1674
#define CloseHandle
Definition: compat.h:739
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
OLECHAR * BSTR
Definition: compat.h:2293
HANDLE HWND
Definition: compat.h:19
#define CALLBACK
Definition: compat.h:35
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:541
ULONG WINAPI DECLSPEC_HOTPATCH GetTickCount(void)
Definition: sync.c:182
const WCHAR * text
Definition: package.c:1826
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
#define MAKEFOURCC(ch0, ch1, ch2, ch3)
Definition: ddsformat.c:45
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
#define OAFALSE
Definition: dshow.h:53
#define OATRUE
Definition: dshow.h:49
struct tagVIDEOINFOHEADER VIDEOINFOHEADER
@ VMRMode_Windowed
Definition: vmrender.idl:105
DWORD IDirect3DSurface9
Definition: dxva2api.idl:23
DWORD IDirect3DDevice9
Definition: dxva2api.idl:22
#define EC_COMPLETE
Definition: evcode.h:17
#define EC_USERABORT
Definition: evcode.h:50
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLuint color
Definition: glext.h:6243
GLuint index
Definition: glext.h:6031
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum mode
Definition: glext.h:6217
GLenum const GLfloat * params
Definition: glext.h:5645
const GLvdpauSurfaceNV * surfaces
Definition: glext.h:11586
GLint left
Definition: glext.h:7726
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
GLboolean GLboolean g
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLenum GLenum GLenum input
Definition: glext.h:9031
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
unsigned int UINT
Definition: sysinfo.c:13
static ID3D11Device * create_device(void)
Definition: hlsl_d3d11.c:102
REFIID riid
Definition: atlbase.h:39
static TfClientId tid
Definition: axcore.idl:92
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define wine_dbgstr_w
Definition: kernel32.h:34
#define GUID_NULL
Definition: ks.h:106
int winetest_debug
#define win_skip
Definition: minitest.h:67
#define todo_wine
Definition: minitest.h:80
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
__u16 time
Definition: mkdosfs.c:8
static struct test_info tests[]
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
unsigned int ulps
Definition: effect.c:4467
static IHTMLWindow2 * window
Definition: events.c:77
static void test_filter_state(void)
Definition: filtergraph.c:3441
static void test_sample_time(void)
Definition: memallocator.c:174
static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, IMemInputPin *peer, IMemAllocator **allocator)
Definition: vmr9.c:897
static BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b)
Definition: vmr9.c:68
static void testfilter_destroy(struct strmbase_filter *iface)
Definition: vmr9.c:884
static HRESULT join_thread_(int line, HANDLE thread)
Definition: vmr9.c:1032
#define join_thread(a)
Definition: vmr9.c:1040
static const IUnknownVtbl outer_vtbl
Definition: vmr9.c:378
static void test_video_window_messages(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
Definition: vmr9.c:2361
static HRESULT WINAPI allocator_QueryInterface(IVMRSurfaceAllocator9 *iface, REFIID iid, void **out)
Definition: vmr9.c:3020
static void test_video_window_owner(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
Definition: vmr9.c:2282
static void test_aggregation(void)
Definition: vmr9.c:387
static void test_windowless_size(void)
Definition: vmr9.c:3991
static void test_basic_video(void)
Definition: vmr9.c:3776
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: vmr9.c:368
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
Definition: vmr9.c:355
static void test_video_window_caption(IVideoWindow *window, HWND hwnd)
Definition: vmr9.c:1889
#define check_interface_broken(a, b, c)
Definition: vmr9.c:204
static void test_video_window_position(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
Definition: vmr9.c:2154
static struct testfilter * impl_from_strmbase_filter(struct strmbase_filter *iface)
Definition: vmr9.c:871
static ULONG get_refcount(void *iface)
Definition: vmr9.c:100
static HRESULT WINAPI allocator_InitializeDevice(IVMRSurfaceAllocator9 *iface, DWORD_PTR cookie, VMR9AllocationInfo *info, DWORD *buffer_count)
Definition: vmr9.c:3049
static HRESULT WINAPI presenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID iid, void **out)
Definition: vmr9.c:2948
static ULONG WINAPI allocator_AddRef(IVMRSurfaceAllocator9 *iface)
Definition: vmr9.c:3037
static HRESULT WINAPI presenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR cookie)
Definition: vmr9.c:2973
static void test_pin_info(void)
Definition: vmr9.c:632
static IUnknown test_outer
Definition: vmr9.c:385
static HRESULT WINAPI allocator_GetSurface(IVMRSurfaceAllocator9 *iface, DWORD_PTR cookie, DWORD index, DWORD flags, IDirect3DSurface9 **surface)
Definition: vmr9.c:3086
static void test_current_image(IBaseFilter *filter, IMemInputPin *input, IMediaControl *control, const BITMAPINFOHEADER *req_bih)
Definition: vmr9.c:1468
static void test_find_pin(void)
Definition: vmr9.c:574
static void test_mixing_mode(void)
Definition: vmr9.c:3332
static void test_basic_video_destination(IBasicVideo *video)
Definition: vmr9.c:3661
static void test_notifyevent(void)
Definition: vmr9.c:4276
static void test_video_window_style(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
Definition: vmr9.c:1917
static void test_flushing(IPin *pin, IMemInputPin *input, IMediaControl *control)
Definition: vmr9.c:1192
static const struct strmbase_source_ops testsource_ops
Definition: vmr9.c:903
static HRESULT WINAPI presenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR cookie)
Definition: vmr9.c:2966
static void test_basic_video_source(IBasicVideo *video)
Definition: vmr9.c:3546
static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: vmr9.c:1878
static void test_enum_media_types(void)
Definition: vmr9.c:764
static BOOL compare_double(double f, double g, unsigned int ulps)
Definition: vmr9.c:74
static void test_allocate_surface_helper(void)
Definition: vmr9.c:2744
static IBaseFilter * create_vmr9(DWORD mode)
Definition: vmr9.c:35
static BOOL CALLBACK top_window_cb(HWND hwnd, LPARAM ctx)
Definition: vmr9.c:1973
static void test_interfaces(void)
Definition: vmr9.c:281
static void test_video_window_autoshow(IVideoWindow *window, IFilterGraph2 *graph, HWND hwnd)
Definition: vmr9.c:2487
static void test_eos(IPin *pin, IMemInputPin *input, IMediaControl *control)
Definition: vmr9.c:1285
static unsigned int check_ec_userabort(IMediaEvent *eventsrc, DWORD timeout)
Definition: vmr9.c:1553
static void test_video_window(void)
Definition: vmr9.c:2535
static void test_surface_allocator_notify_refcount(void)
Definition: vmr9.c:3479
static void test_connect_pin(void)
Definition: vmr9.c:1639
static DWORD WINAPI frame_thread(void *arg)
Definition: vmr9.c:972
static void flush_events(void)
Definition: vmr9.c:1861
static void test_media_types(void)
Definition: vmr9.c:694
static void test_changed3ddevice(void)
Definition: vmr9.c:4312
static struct strmbase_pin * testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
Definition: vmr9.c:876
static void test_allocator(IMemInputPin *input)
Definition: vmr9.c:916
static void commit_allocator(IMemInputPin *input)
Definition: vmr9.c:1042
static void test_enum_pins(void)
Definition: vmr9.c:446
static IFilterGraph2 * create_graph(void)
Definition: vmr9.c:91
static void test_overlay(void)
Definition: vmr9.c:1803
static void test_renderless_present(struct presenter *presenter, IFilterGraph2 *graph, IMemInputPin *input)
Definition: vmr9.c:3118
static const IVMRSurfaceAllocator9Vtbl allocator_vtbl
Definition: vmr9.c:3107
static HWND get_top_window(void)
Definition: vmr9.c:1985
static HRESULT WINAPI allocator_TerminateDevice(IVMRSurfaceAllocator9 *iface, DWORD_PTR cookie)
Definition: vmr9.c:3075
static void check_destination_position_(int line, IBasicVideo *video, LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
Definition: vmr9.c:3625
static HANDLE send_frame(IMemInputPin *sink)
Definition: vmr9.c:1027
#define check_destination_position(a, b, c, d, e)
Definition: vmr9.c:3659
static void test_window_close(IPin *pin, IMemInputPin *input, IMediaControl *control)
Definition: vmr9.c:1558
static ULONG WINAPI allocator_Release(IVMRSurfaceAllocator9 *iface)
Definition: vmr9.c:3043
static DWORD CALLBACK notify_message_proc(void *arg)
Definition: vmr9.c:2353
static void test_clipping_window(void)
Definition: vmr9.c:3417
#define check_source_position(a, b, c, d, e)
Definition: vmr9.c:3544
static void test_unconnected_eos(void)
Definition: vmr9.c:4210
static HRESULT WINAPI presenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR cookie, VMR9PresentationInfo *info)
Definition: vmr9.c:2980
static unsigned int check_ec_complete(IMediaEvent *eventsrc, DWORD timeout)
Definition: vmr9.c:1280
#define check_interface(a, b, c)
Definition: vmr9.c:205
static ULONG WINAPI presenter_AddRef(IVMRImagePresenter9 *iface)
Definition: vmr9.c:2954
static const IVMRImagePresenter9Vtbl presenter_vtbl
Definition: vmr9.c:3005
static void test_filter_config(void)
Definition: vmr9.c:107
static HANDLE send_frame_time(IMemInputPin *sink, REFERENCE_TIME start_time, DWORD color)
Definition: vmr9.c:985
static void test_common_interfaces(IBaseFilter *filter)
Definition: vmr9.c:230
static void test_renderless_formats(void)
Definition: vmr9.c:3153
static HRESULT set_mixing_mode(IBaseFilter *filter, DWORD count)
Definition: vmr9.c:53
static LONG outer_ref
Definition: vmr9.c:353
static void test_mixing_prefs(void)
Definition: vmr9.c:4178
static HRESULT WINAPI allocator_AdviseNotify(IVMRSurfaceAllocator9 *iface, IVMRSurfaceAllocatorNotify9 *notify)
Definition: vmr9.c:3101
static unsigned int check_event_code(IMediaEvent *eventsrc, DWORD timeout, LONG expected_code, LONG_PTR expected1, LONG_PTR expected2)
Definition: vmr9.c:1257
static const struct strmbase_filter_ops testfilter_ops
Definition: vmr9.c:891
static HRESULT check_interface_(unsigned int line, void *iface, REFIID riid, BOOL supported, BOOL is_broken)
Definition: vmr9.c:206
static void test_video_window_state(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
Definition: vmr9.c:1992
static void check_source_position_(int line, IBasicVideo *video, LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
Definition: vmr9.c:3510
static void test_unconnected_filter_state(void)
Definition: vmr9.c:808
static const GUID test_iid
Definition: vmr9.c:352
static ULONG WINAPI presenter_Release(IVMRImagePresenter9 *iface)
Definition: vmr9.c:2960
static void testfilter_init(struct testfilter *filter)
Definition: vmr9.c:909
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: vmr9.c:373
const GUID * subtype
Definition: mpegvideo.c:120
int notify
Definition: msacm.c:1366
const CLSID * clsid
Definition: msctf.cpp:50
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
HMONITOR WINAPI MonitorFromWindow(HWND, DWORD)
#define DWORD
Definition: nt_native.h:44
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:240
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:273
#define WS_CHILD
Definition: pedump.c:617
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define WS_MAXIMIZE
Definition: pedump.c:623
short WCHAR
Definition: pedump.c:58
#define WS_VSCROLL
Definition: pedump.c:627
#define WS_MINIMIZE
Definition: pedump.c:622
#define WS_VISIBLE
Definition: pedump.c:620
long LONG
Definition: pedump.c:60
#define WS_DISABLED
Definition: pedump.c:621
#define WS_EX_TRANSPARENT
Definition: pedump.c:649
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define WS_HSCROLL
Definition: pedump.c:628
#define WS_CLIPCHILDREN
Definition: pedump.c:619
const GUID IID_IPin
Definition: pincontrol.cpp:15
const GUID IID_IPersist
Definition: proxy.cpp:14
const GUID IID_IPersistPropertyBag
Definition: proxy.cpp:11
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
HWND WINAPI GetFocus(void)
Definition: window.c:1887
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
BOOL WINAPI IsWindow(_In_opt_ HWND)
HWND WINAPI GetActiveWindow(void)
Definition: winpos.c:138
#define SW_HIDE
Definition: winuser.h:779
#define WM_CLOSE
Definition: winuser.h:1649
#define WM_KEYUP
Definition: winuser.h:1744
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
BOOL WINAPI AdjustWindowRect(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4469
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define SW_MINIMIZE
Definition: winuser.h:787
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1806
#define SWP_NOMOVE
Definition: winuser.h:1255
#define WM_RBUTTONUP
Definition: winuser.h:1808
BOOL WINAPI AdjustWindowRectEx(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL, _In_ DWORD)
#define WM_NCRBUTTONDBLCLK
Definition: winuser.h:1725
#define WM_RBUTTONDBLCLK
Definition: winuser.h:1809
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define GA_PARENT
Definition: winuser.h:2892
#define QS_ALLINPUT
Definition: winuser.h:914
#define SWP_NOSIZE
Definition: winuser.h:1256
#define WM_MOUSEMOVE
Definition: winuser.h:1803
#define WM_NCMBUTTONUP
Definition: winuser.h:1727
#define WM_LBUTTONDOWN
Definition: winuser.h:1804
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1654
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
#define WM_NCLBUTTONDBLCLK
Definition: winuser.h:1722
BOOL WINAPI IsIconic(_In_ HWND)
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
#define WM_RBUTTONDOWN
Definition: winuser.h:1807
BOOL WINAPI IsZoomed(_In_ HWND)
#define SM_CXMIN
Definition: winuser.h:1000
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define SM_CYMIN
Definition: winuser.h:1001
#define HWND_TOP
Definition: winuser.h:1218
#define SW_SHOWNA
Definition: winuser.h:789
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
#define WM_NCMBUTTONDOWN
Definition: winuser.h:1726
#define PM_REMOVE
Definition: winuser.h:1207
#define WM_MBUTTONDBLCLK
Definition: winuser.h:1812
#define WS_EX_WINDOWEDGE
Definition: winuser.h:407
#define WM_MOUSEACTIVATE
Definition: winuser.h:1665
#define WM_LBUTTONUP
Definition: winuser.h:1805
#define WM_NCLBUTTONUP
Definition: winuser.h:1721
#define SW_RESTORE
Definition: winuser.h:790
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define SW_SHOW
Definition: winuser.h:786
#define WM_NCRBUTTONUP
Definition: winuser.h:1724
#define WM_FONTCHANGE
Definition: winuser.h:1661
#define WM_KEYDOWN
Definition: winuser.h:1743
BOOL WINAPI GetMonitorInfoW(_In_ HMONITOR, _Inout_ LPMONITORINFO)
#define SW_MAXIMIZE
Definition: winuser.h:783
#define WM_NCMBUTTONDBLCLK
Definition: winuser.h:1728
#define WM_MBUTTONUP
Definition: winuser.h:1811
#define GWL_STYLE
Definition: winuser.h:863
BOOL WINAPI IsWindowVisible(_In_ HWND)
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
int WINAPI GetSystemMetrics(_In_ int)
HWND WINAPI GetAncestor(_In_ HWND, _In_ UINT)
Definition: window.c:929
#define WM_NCLBUTTONDOWN
Definition: winuser.h:1720
#define WM_MBUTTONDOWN
Definition: winuser.h:1810
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define WM_NCRBUTTONDOWN
Definition: winuser.h:1723
#define GWL_EXSTYLE
Definition: winuser.h:862
#define offsetof(TYPE, MEMBER)
#define D3DADAPTER_DEFAULT
Definition: d3d8.h:53
#define D3DCREATE_HARDWARE_VERTEXPROCESSING
Definition: d3d8.h:41
#define D3D_SDK_VERSION
Definition: d3d8.h:52
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
#define flaky_wine
Definition: test.h:167
#define memset(x, y, z)
Definition: compat.h:39
void strmbase_source_init(struct strmbase_source *pin, struct strmbase_filter *filter, const WCHAR *name, const struct strmbase_source_ops *func_table)
Definition: pin.c:765
void strmbase_filter_cleanup(struct strmbase_filter *filter)
Definition: filter.c:540
void strmbase_source_cleanup(struct strmbase_source *pin)
Definition: pin.c:778
void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer, const CLSID *clsid, const struct strmbase_filter_ops *func_table)
Definition: filter.c:517
HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(struct strmbase_source *pin, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: pin.c:710
DWORD biSizeImage
Definition: amvideo.idl:36
Definition: dcommon.idl:28
long bottom
Definition: dcommon.idl:29
long right
Definition: dcommon.idl:29
long left
Definition: dcommon.idl:29
long top
Definition: dcommon.idl:29
LPCSTR lpszClassName
Definition: winuser.h:3280
WNDPROC lpfnWndProc
Definition: winuser.h:3272
Definition: inflate.c:139
Definition: dialog.c:52
Definition: cookie.c:34
Definition: devices.h:37
Definition: filter.c:165
IBaseFilter * filter
Definition: filtergraph.c:75
IMemInputPin * sink
Definition: nullrenderer.c:529
IMediaSample * sample
Definition: nullrenderer.c:530
Definition: graph.c:32
Definition: parser.c:49
IVideoWindow * window
unsigned int got_PresentImage
Definition: vmr7.c:3198
IDirect3DDevice9 * device
Definition: vmr9.c:2937
LONG refcount
Definition: vmr7.c:3190
D3DFORMAT format
Definition: vmr9.c:2935
IDirectDrawSurface7 * surfaces[6]
Definition: vmr7.c:3193
IVMRSurfaceAllocator9 IVMRSurfaceAllocator9_iface
Definition: vmr9.c:2931
IVMRImagePresenter9 IVMRImagePresenter9_iface
Definition: vmr9.c:2932
IVMRSurfaceAllocatorNotify * notify
Definition: vmr7.c:3197
BITMAPINFOHEADER format
Definition: vmr7.c:3196
IVMRSurfaceAllocatorNotify9 * notify
Definition: vmr9.c:2939
unsigned int got_TerminateDevice
Definition: vmr9.c:2940
DWORD accept_flags
Definition: vmr9.c:2936
Definition: send.c:48
Definition: wave.c:25
Definition: style.c:91
RECT rcMonitor
Definition: winuser.h:3893
DWORD cbSize
Definition: winuser.h:3892
BITMAPINFOHEADER bmiHeader
Definition: amvideo.idl:189
REFERENCE_TIME AvgTimePerFrame
Definition: amvideo.idl:187
const AM_MEDIA_TYPE * mt
Definition: avidec.c:799
IFilterGraph * graph
Definition: filtergraph.c:850
struct strmbase_filter filter
Definition: amstream.c:1019
Definition: dhcpd.h:248
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint64_t ULONGLONG
Definition: typedefs.h:67
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define BI_RGB
Definition: uefivid.c:46
#define MEDIASUBTYPE_NULL
Definition: uuids.h:25
#define MEDIATYPE_NULL
Definition: uuids.h:24
#define VFW_E_VMR_NOT_IN_MIXER_MODE
Definition: vfwmsgs.h:155
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81
#define VFW_E_NOT_COMMITTED
Definition: vfwmsgs.h:56
#define VFW_E_NOT_STOPPED
Definition: vfwmsgs.h:75
#define VFW_E_WRONG_STATE
Definition: vfwmsgs.h:78
#define VFW_E_NO_PALETTE_AVAILABLE
Definition: vfwmsgs.h:71
#define VFW_S_STATE_INTERMEDIATE
Definition: vfwmsgs.h:21
#define VFW_E_NO_ALLOCATOR
Definition: vfwmsgs.h:49
#define VFW_E_NOT_FOUND
Definition: vfwmsgs.h:61
#define VFW_E_NOT_CONNECTED
Definition: vfwmsgs.h:48
@ VMR9Sample_TimeValid
Definition: vmr9.idl:52
@ VMR9AllocFlag_3DRenderTarget
Definition: vmr9.idl:85
@ VMR9AllocFlag_TextureSurface
Definition: vmr9.idl:87
@ VMR9AllocFlag_OffscreenSurface
Definition: vmr9.idl:88
@ MixerPref9_NoDecimation
Definition: vmr9.idl:182
@ MixerPref9_RenderTargetRGB
Definition: vmr9.idl:198
@ MixerPref9_PointFiltering
Definition: vmr9.idl:190
@ MixerPref9_BiLinearFiltering
Definition: vmr9.idl:189
@ MixerPref9_ARAdjustXorY
Definition: vmr9.idl:184
@ VMR9ARMode_None
Definition: vmr9.idl:151
@ VMR9ARMode_LetterBox
Definition: vmr9.idl:152
@ VMR9Mode_Renderless
Definition: vmr9.idl:356
@ VMR9Mode_Windowless
Definition: vmr9.idl:355
@ VMR9Mode_Windowed
Definition: vmr9.idl:354
enum _VMR9Mode VMR9Mode
static const WCHAR props[]
Definition: wbemdisp.c:288
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
@ TKIND_DISPATCH
Definition: widltypes.h:238
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1382
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1205
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
#define WAIT_OBJECT_0
Definition: winbase.h:383
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_UNEXPECTED
Definition: winerror.h:3528
#define E_POINTER
Definition: winerror.h:3480
#define E_ABORT
Definition: winerror.h:3481
size_t const buffer_count
Definition: xtoa.cpp:36
unsigned char BYTE
Definition: xxhash.c:193