ReactOS 0.4.17-dev-923-g4c9a150
vmr7.c
Go to the documentation of this file.
1/*
2 * Video Mixing Renderer 7 unit tests
3 *
4 * Copyright 2018 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 "dshow.h"
24#include "d3d9.h"
25#include "vmr9.h"
26#include "videoacc.h"
27#include "wine/strmbase.h"
28#include "wine/test.h"
29
31{
34 HRESULT hr = CoCreateInstance(&CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER,
35 &IID_IBaseFilter, (void **)&filter);
36 ok(hr == S_OK, "Got hr %#lx.\n", hr);
37 if (mode)
38 {
39 hr = IBaseFilter_QueryInterface(filter, &IID_IVMRFilterConfig, (void **)&config);
40 ok(hr == S_OK, "Got hr %#lx.\n", hr);
41 hr = IVMRFilterConfig_SetRenderingMode(config, mode);
42 ok(hr == S_OK, "Got hr %#lx.\n", hr);
43 IVMRFilterConfig_Release(config);
44 }
45 return filter;
46}
47
49{
51 HRESULT hr;
52
53 hr = IBaseFilter_QueryInterface(filter, &IID_IVMRFilterConfig, (void **)&config);
54 ok(hr == S_OK, "Got hr %#lx.\n", hr);
55
56 hr = IVMRFilterConfig_SetNumberOfStreams(config, 2);
57 ok(hr == VFW_E_DDRAW_CAPS_NOT_SUITABLE || hr == S_OK, "Got hr %#lx.\n", hr);
58
59 IVMRFilterConfig_Release(config);
60 return hr;
61}
62
64{
65 return !memcmp(a, b, offsetof(AM_MEDIA_TYPE, pbFormat))
66 && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat);
67}
68
69static BOOL compare_double(double f, double g, unsigned int ulps)
70{
71 uint64_t x = *(ULONGLONG *)&f;
72 uint64_t y = *(ULONGLONG *)&g;
73
74 if (f < 0)
75 x = ~x + 1;
76 else
77 x |= ((ULONGLONG)1)<<63;
78 if (g < 0)
79 y = ~y + 1;
80 else
81 y |= ((ULONGLONG)1)<<63;
82
83 return (x>y ? x-y : y-x) <= ulps;
84}
85
87{
89 HRESULT hr;
90 hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph2, (void **)&ret);
91 ok(hr == S_OK, "Got hr %#lx.\n", hr);
92 return ret;
93}
94
95static ULONG get_refcount(void *iface)
96{
97 IUnknown *unknown = iface;
98 IUnknown_AddRef(unknown);
99 return IUnknown_Release(unknown);
100}
101
102static void test_filter_config(void)
103{
106 HRESULT hr;
107 ULONG ref;
108
109 hr = CoCreateInstance(&CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER,
110 &IID_IVMRFilterConfig, (void **)&config);
111 ok(hr == S_OK, "Got hr %#lx.\n", hr);
112
113 hr = IVMRFilterConfig_GetRenderingMode(config, &mode);
114 ok(hr == S_OK, "Got hr %#lx.\n", hr);
115 ok(mode == VMRMode_Windowed, "Got mode %#lx.\n", mode);
116
117 hr = IVMRFilterConfig_SetRenderingMode(config, VMRMode_Windowed);
118 ok(hr == S_OK, "Got hr %#lx.\n", hr);
119
120 hr = IVMRFilterConfig_GetRenderingMode(config, &mode);
121 ok(hr == S_OK, "Got hr %#lx.\n", hr);
122 ok(mode == VMRMode_Windowed, "Got mode %#lx.\n", mode);
123
124 hr = IVMRFilterConfig_SetRenderingMode(config, VMRMode_Windowed);
125 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
126
127 ref = IVMRFilterConfig_Release(config);
128 ok(!ref, "Got outstanding refcount %ld.\n", ref);
129
130 hr = CoCreateInstance(&CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER,
131 &IID_IVMRFilterConfig, (void **)&config);
132 ok(hr == S_OK, "Got hr %#lx.\n", hr);
133
134 hr = IVMRFilterConfig_SetRenderingMode(config, VMRMode_Windowless);
135 ok(hr == S_OK, "Got hr %#lx.\n", hr);
136
137 hr = IVMRFilterConfig_GetRenderingMode(config, &mode);
138 ok(hr == S_OK, "Got hr %#lx.\n", hr);
139 ok(mode == VMRMode_Windowless, "Got mode %#lx.\n", mode);
140
141 hr = IVMRFilterConfig_SetRenderingMode(config, VMRMode_Windowed);
142 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
143
144 ref = IVMRFilterConfig_Release(config);
145 ok(!ref, "Got outstanding refcount %ld.\n", ref);
146
147 hr = CoCreateInstance(&CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER,
148 &IID_IVMRFilterConfig, (void **)&config);
149 ok(hr == S_OK, "Got hr %#lx.\n", hr);
150
151 hr = IVMRFilterConfig_SetRenderingMode(config, VMRMode_Renderless);
152 ok(hr == S_OK, "Got hr %#lx.\n", hr);
153
154 hr = IVMRFilterConfig_GetRenderingMode(config, &mode);
155 ok(hr == S_OK, "Got hr %#lx.\n", hr);
156 ok(mode == VMRMode_Renderless, "Got mode %#lx.\n", mode);
157
158 hr = IVMRFilterConfig_SetRenderingMode(config, VMRMode_Windowless);
159 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
160
161 ref = IVMRFilterConfig_Release(config);
162 ok(!ref, "Got outstanding refcount %ld.\n", ref);
163
164 hr = CoCreateInstance(&CLSID_VideoMixingRenderer, NULL, CLSCTX_INPROC_SERVER,
165 &IID_IVMRFilterConfig, (void **)&config);
166 ok(hr == S_OK, "Got hr %#lx.\n", hr);
167
168 hr = IVMRFilterConfig_GetNumberOfStreams(config, &count);
169 todo_wine ok(hr == VFW_E_VMR_NOT_IN_MIXER_MODE, "Got hr %#lx.\n", hr);
170
171 hr = IVMRFilterConfig_SetNumberOfStreams(config, 3);
173 {
174 ok(hr == S_OK, "Got hr %#lx.\n", hr);
175
176 hr = IVMRFilterConfig_GetNumberOfStreams(config, &count);
177 todo_wine {
178 ok(hr == S_OK, "Got hr %#lx.\n", hr);
179 ok(count == 3, "Got count %lu.\n", count);
180 }
181
182 hr = IVMRFilterConfig_GetRenderingMode(config, &mode);
183 ok(hr == S_OK, "Got hr %#lx.\n", hr);
184 ok(mode == VMRMode_Windowed, "Got mode %#lx.\n", mode);
185
186 /* Despite MSDN, you can still change the rendering mode after setting the
187 * stream count. */
188 hr = IVMRFilterConfig_SetRenderingMode(config, VMRMode_Windowless);
189 ok(hr == S_OK, "Got hr %#lx.\n", hr);
190
191 hr = IVMRFilterConfig_GetRenderingMode(config, &mode);
192 ok(hr == S_OK, "Got hr %#lx.\n", hr);
193 ok(mode == VMRMode_Windowless, "Got mode %#lx.\n", mode);
194
195 hr = IVMRFilterConfig_GetNumberOfStreams(config, &count);
196 todo_wine {
197 ok(hr == S_OK, "Got hr %#lx.\n", hr);
198 ok(count == 3, "Got count %lu.\n", count);
199 }
200 }
201 else
202 skip("Mixing mode is not supported.\n");
203
204 ref = IVMRFilterConfig_Release(config);
205 ok(!ref, "Got outstanding refcount %ld.\n", ref);
206}
207
208#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
209static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
210{
211 IUnknown *iface = iface_ptr;
213 IUnknown *unk;
214
215 expected_hr = supported ? S_OK : E_NOINTERFACE;
216
217 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
218 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
219 if (SUCCEEDED(hr))
220 IUnknown_Release(unk);
221}
222
224{
225 IPin *pin;
226
227 check_interface(filter, &IID_IAMCertifiedOutputProtection, TRUE);
228 check_interface(filter, &IID_IAMFilterMiscFlags, TRUE);
231 check_interface(filter, &IID_IMediaFilter, TRUE);
232 check_interface(filter, &IID_IMediaPosition, TRUE);
233 check_interface(filter, &IID_IMediaSeeking, TRUE);
235 check_interface(filter, &IID_IQualityControl, TRUE);
236 todo_wine check_interface(filter, &IID_IQualProp, TRUE);
238 todo_wine check_interface(filter, &IID_IVMRAspectRatioControl, TRUE);
239 todo_wine check_interface(filter, &IID_IVMRDeinterlaceControl, TRUE);
240 check_interface(filter, &IID_IVMRFilterConfig, TRUE);
241 todo_wine check_interface(filter, &IID_IVMRMixerBitmap, TRUE);
242
243 check_interface(filter, &IID_IAMVideoAccelerator, FALSE);
244 check_interface(filter, &IID_IBasicAudio, FALSE);
245 check_interface(filter, &IID_IDirectDrawVideo, FALSE);
248 check_interface(filter, &IID_IReferenceClock, FALSE);
249 check_interface(filter, &IID_IVMRAspectRatioControl9, FALSE);
250 check_interface(filter, &IID_IVMRDeinterlaceControl9, FALSE);
251 check_interface(filter, &IID_IVMRFilterConfig9, FALSE);
252 check_interface(filter, &IID_IVMRMixerBitmap9, FALSE);
253 check_interface(filter, &IID_IVMRMixerControl9, FALSE);
254 check_interface(filter, &IID_IVMRMonitorConfig9, FALSE);
255 check_interface(filter, &IID_IVMRSurfaceAllocatorNotify9, FALSE);
256 check_interface(filter, &IID_IVMRWindowlessControl9, FALSE);
257
258 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
259
260 check_interface(pin, &IID_IAMVideoAccelerator, TRUE);
261 check_interface(pin, &IID_IMemInputPin, TRUE);
262 check_interface(pin, &IID_IOverlay, TRUE);
264 todo_wine check_interface(pin, &IID_IQualityControl, TRUE);
266
268 check_interface(pin, &IID_IMediaPosition, FALSE);
269 check_interface(pin, &IID_IMediaSeeking, FALSE);
270
271 IPin_Release(pin);
272}
273
274static void test_interfaces(void)
275{
277 ULONG ref;
278
280
281 check_interface(filter, &IID_IBasicVideo, TRUE);
282 todo_wine check_interface(filter, &IID_IBasicVideo2, TRUE);
283 check_interface(filter, &IID_IVideoWindow, TRUE);
284 check_interface(filter, &IID_IVMRMonitorConfig, TRUE);
285
286 check_interface(filter, &IID_IVMRMixerControl, FALSE);
287 check_interface(filter, &IID_IVMRSurfaceAllocatorNotify, FALSE);
288 check_interface(filter, &IID_IVMRWindowlessControl, FALSE);
289
290 ref = IBaseFilter_Release(filter);
291 ok(!ref, "Got outstanding refcount %ld.\n", ref);
292
294
295 check_interface(filter, &IID_IVMRMonitorConfig, TRUE);
296 check_interface(filter, &IID_IVMRWindowlessControl, TRUE);
297
298 todo_wine check_interface(filter, &IID_IBasicVideo, FALSE);
299 check_interface(filter, &IID_IBasicVideo2, FALSE);
300 todo_wine check_interface(filter, &IID_IVideoWindow, FALSE);
301 check_interface(filter, &IID_IVMRMixerControl, FALSE);
302 check_interface(filter, &IID_IVMRSurfaceAllocatorNotify, FALSE);
303
304 ref = IBaseFilter_Release(filter);
305 ok(!ref, "Got outstanding refcount %ld.\n", ref);
306
308
309 check_interface(filter, &IID_IVMRSurfaceAllocatorNotify, TRUE);
310
311 todo_wine check_interface(filter, &IID_IBasicVideo, FALSE);
312 check_interface(filter, &IID_IBasicVideo2, FALSE);
313 todo_wine check_interface(filter, &IID_IVideoWindow, FALSE);
314 check_interface(filter, &IID_IVMRMixerControl, FALSE);
315 todo_wine check_interface(filter, &IID_IVMRMonitorConfig, FALSE);
316 check_interface(filter, &IID_IVMRWindowlessControl, FALSE);
317
318 ref = IBaseFilter_Release(filter);
319 ok(!ref, "Got outstanding refcount %ld.\n", ref);
320}
321
322static const GUID test_iid = {0x33333333};
323static LONG outer_ref = 1;
324
326{
327 if (IsEqualGUID(iid, &IID_IUnknown)
329 || IsEqualGUID(iid, &test_iid))
330 {
331 *out = (IUnknown *)0xdeadbeef;
332 return S_OK;
333 }
334 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
335 return E_NOINTERFACE;
336}
337
339{
341}
342
344{
346}
347
348static const IUnknownVtbl outer_vtbl =
349{
353};
354
356
357static void test_aggregation(void)
358{
359 IBaseFilter *filter, *filter2;
360 IUnknown *unk, *unk2;
361 HRESULT hr;
362 ULONG ref;
363
364 filter = (IBaseFilter *)0xdeadbeef;
365 hr = CoCreateInstance(&CLSID_VideoMixingRenderer, &test_outer, CLSCTX_INPROC_SERVER,
366 &IID_IBaseFilter, (void **)&filter);
367 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
368 ok(!filter, "Got interface %p.\n", filter);
369
370 hr = CoCreateInstance(&CLSID_VideoMixingRenderer, &test_outer, CLSCTX_INPROC_SERVER,
371 &IID_IUnknown, (void **)&unk);
372 ok(hr == S_OK, "Got hr %#lx.\n", hr);
373 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
374 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
375 ref = get_refcount(unk);
376 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
377
378 ref = IUnknown_AddRef(unk);
379 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
380 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
381
382 ref = IUnknown_Release(unk);
383 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
384 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
385
386 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
387 ok(hr == S_OK, "Got hr %#lx.\n", hr);
388 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
389 IUnknown_Release(unk2);
390
391 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
392 ok(hr == S_OK, "Got hr %#lx.\n", hr);
393
394 hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
395 ok(hr == S_OK, "Got hr %#lx.\n", hr);
396 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
397
398 hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
399 ok(hr == S_OK, "Got hr %#lx.\n", hr);
400 ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
401
402 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
403 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
404 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
405
406 hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
407 ok(hr == S_OK, "Got hr %#lx.\n", hr);
408 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
409
410 IBaseFilter_Release(filter);
411 ref = IUnknown_Release(unk);
412 ok(!ref, "Got unexpected refcount %ld.\n", ref);
413 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
414}
415
416static void test_enum_pins(void)
417{
419 IEnumPins *enum1, *enum2;
420 ULONG count, ref;
421 IPin *pins[3];
422 HRESULT hr;
423
425 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
426
427 hr = IBaseFilter_EnumPins(filter, NULL);
428 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
429
430 hr = IBaseFilter_EnumPins(filter, &enum1);
431 ok(hr == S_OK, "Got hr %#lx.\n", hr);
433 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
434 ref = get_refcount(enum1);
435 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
436
437 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
438 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
439
440 hr = IEnumPins_Next(enum1, 1, pins, NULL);
441 ok(hr == S_OK, "Got hr %#lx.\n", hr);
443 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
444 ref = get_refcount(pins[0]);
445 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
446 ref = get_refcount(enum1);
447 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
448 IPin_Release(pins[0]);
450 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
451
452 hr = IEnumPins_Next(enum1, 1, pins, NULL);
453 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
454
455 hr = IEnumPins_Reset(enum1);
456 ok(hr == S_OK, "Got hr %#lx.\n", hr);
457
458 hr = IEnumPins_Next(enum1, 1, pins, &count);
459 ok(hr == S_OK, "Got hr %#lx.\n", hr);
460 ok(count == 1, "Got count %lu.\n", count);
461 IPin_Release(pins[0]);
462
463 hr = IEnumPins_Next(enum1, 1, pins, &count);
464 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
465 ok(!count, "Got count %lu.\n", count);
466
467 hr = IEnumPins_Reset(enum1);
468 ok(hr == S_OK, "Got hr %#lx.\n", hr);
469
470 hr = IEnumPins_Next(enum1, 2, pins, NULL);
471 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
472
473 hr = IEnumPins_Next(enum1, 2, pins, &count);
474 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
475 ok(count == 1, "Got count %lu.\n", count);
476 IPin_Release(pins[0]);
477
478 hr = IEnumPins_Reset(enum1);
479 ok(hr == S_OK, "Got hr %#lx.\n", hr);
480
481 hr = IEnumPins_Clone(enum1, &enum2);
482 ok(hr == S_OK, "Got hr %#lx.\n", hr);
483
484 hr = IEnumPins_Skip(enum1, 2);
485 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
486
487 hr = IEnumPins_Skip(enum1, 1);
488 ok(hr == S_OK, "Got hr %#lx.\n", hr);
489
490 hr = IEnumPins_Skip(enum1, 1);
491 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
492
493 hr = IEnumPins_Next(enum1, 1, pins, NULL);
494 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
495
496 hr = IEnumPins_Next(enum2, 1, pins, NULL);
497 ok(hr == S_OK, "Got hr %#lx.\n", hr);
498 IPin_Release(pins[0]);
499
500 IEnumPins_Release(enum2);
501
503 {
504 hr = IEnumPins_Next(enum1, 1, pins, NULL);
505 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
506
507 hr = IEnumPins_Reset(enum1);
508 ok(hr == S_OK, "Got hr %#lx.\n", hr);
509
510 hr = IEnumPins_Next(enum1, 1, pins, NULL);
511 ok(hr == S_OK, "Got hr %#lx.\n", hr);
512 IPin_Release(pins[0]);
513
514 hr = IEnumPins_Next(enum1, 1, pins, NULL);
515 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
516 if (hr == S_OK)
517 IPin_Release(pins[0]);
518
519 hr = IEnumPins_Next(enum1, 1, pins, NULL);
520 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
521
522 hr = IEnumPins_Reset(enum1);
523 ok(hr == S_OK, "Got hr %#lx.\n", hr);
524
525 hr = IEnumPins_Next(enum1, 2, pins, &count);
526 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
527 todo_wine ok(count == 2, "Got count %lu.\n", count);
528 IPin_Release(pins[0]);
529 if (count == 2)
530 IPin_Release(pins[1]);
531
532 hr = IEnumPins_Reset(enum1);
533 ok(hr == S_OK, "Got hr %#lx.\n", hr);
534
535 hr = IEnumPins_Next(enum1, 3, pins, &count);
536 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
537 todo_wine ok(count == 2, "Got count %lu.\n", count);
538 IPin_Release(pins[0]);
539 if (count == 2)
540 IPin_Release(pins[1]);
541 }
542 else
543 skip("Mixing mode is not supported.\n");
544
545 IEnumPins_Release(enum1);
546 ref = IBaseFilter_Release(filter);
547 ok(!ref, "Got outstanding refcount %ld.\n", ref);
548}
549
550static void test_find_pin(void)
551{
554 IPin *pin, *pin2;
555 HRESULT hr;
556 ULONG ref;
557
558 IBaseFilter_EnumPins(filter, &enum_pins);
559
560 hr = IBaseFilter_FindPin(filter, L"input pin", &pin);
561 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
562
563 hr = IBaseFilter_FindPin(filter, L"In", &pin);
564 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
565
566 hr = IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
567 ok(hr == S_OK, "Got hr %#lx.\n", hr);
568 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
569 ok(hr == S_OK, "Got hr %#lx.\n", hr);
570 ok(pin == pin2, "Pins did not match.\n");
571 IPin_Release(pin);
572 IPin_Release(pin2);
573
574 hr = IBaseFilter_FindPin(filter, L"VMR input1", &pin);
575 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
576
578 {
579 IEnumPins_Reset(enum_pins);
580
581 hr = IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
582 ok(hr == S_OK, "Got hr %#lx.\n", hr);
583 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
584 ok(hr == S_OK, "Got hr %#lx.\n", hr);
585 ok(pin == pin2, "Pins did not match.\n");
586 IPin_Release(pin);
587 IPin_Release(pin2);
588
589 hr = IBaseFilter_FindPin(filter, L"VMR Input1", &pin);
590 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
591 if (hr == S_OK)
592 {
593 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
594 ok(hr == S_OK, "Got hr %#lx.\n", hr);
595 ok(pin == pin2, "Pins did not match.\n");
596 IPin_Release(pin);
597 IPin_Release(pin2);
598 }
599
600 hr = IBaseFilter_FindPin(filter, L"VMR Input2", &pin);
601 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
602 }
603 else
604 skip("Mixing mode is not supported.\n");
605
606 IEnumPins_Release(enum_pins);
607 ref = IBaseFilter_Release(filter);
608 ok(!ref, "Got outstanding refcount %ld.\n", ref);
609}
610
611static void test_pin_info(void)
612{
615 ULONG count, ref;
617 HRESULT hr;
618 WCHAR *id;
619 IPin *pin;
620
621 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
622 hr = IPin_QueryPinInfo(pin, &info);
623 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
624 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
625 ok(!wcscmp(info.achName, L"VMR Input0"), "Got name %s.\n", wine_dbgstr_w(info.achName));
626 IBaseFilter_Release(info.pFilter);
627
628 hr = IPin_QueryDirection(pin, &dir);
629 ok(hr == S_OK, "Got hr %#lx.\n", hr);
630 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
631
632 hr = IPin_QueryId(pin, &id);
633 ok(hr == S_OK, "Got hr %#lx.\n", hr);
634 ok(!wcscmp(id, L"VMR Input0"), "Got id %s.\n", wine_dbgstr_w(id));
635 CoTaskMemFree(id);
636
637 hr = IPin_QueryInternalConnections(pin, NULL, &count);
638 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
639
640 IPin_Release(pin);
641
643 {
644 hr = IBaseFilter_FindPin(filter, L"VMR Input1", &pin);
645 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
646 if (hr == S_OK)
647 {
648 hr = IPin_QueryPinInfo(pin, &info);
649 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
650 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
651 ok(!wcscmp(info.achName, L"VMR Input1"), "Got name %s.\n", wine_dbgstr_w(info.achName));
652 IBaseFilter_Release(info.pFilter);
653
654 hr = IPin_QueryDirection(pin, &dir);
655 ok(hr == S_OK, "Got hr %#lx.\n", hr);
656 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
657
658 hr = IPin_QueryId(pin, &id);
659 ok(hr == S_OK, "Got hr %#lx.\n", hr);
660 ok(!wcscmp(id, L"VMR Input1"), "Got id %s.\n", wine_dbgstr_w(id));
661 CoTaskMemFree(id);
662
663 hr = IPin_QueryInternalConnections(pin, NULL, &count);
664 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
665
666 IPin_Release(pin);
667 }
668 }
669 else
670 skip("Mixing mode is not supported.\n");
671
672 ref = IBaseFilter_Release(filter);
673 ok(!ref, "Got outstanding refcount %ld.\n", ref);
674}
675
676static void test_media_types(void)
677{
679 AM_MEDIA_TYPE *mt, req_mt = {{0}};
680 VIDEOINFOHEADER vih =
681 {
682 {0}, {0}, 0, 0, 0,
683 {sizeof(BITMAPINFOHEADER), 32, 24, 1, 0, BI_RGB}
684 };
685 IEnumMediaTypes *enummt;
686 unsigned int i;
687 HRESULT hr;
688 ULONG ref;
689 IPin *pin;
690
691 static const GUID *subtype_tests[] =
692 {
694 &MEDIASUBTYPE_RGB565,
695 &MEDIASUBTYPE_RGB24,
696 &MEDIASUBTYPE_RGB32,
697 };
698
699 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
700
701 hr = IPin_EnumMediaTypes(pin, &enummt);
702 ok(hr == S_OK, "Got hr %#lx.\n", hr);
703
704 hr = IEnumMediaTypes_Next(enummt, 1, &mt, NULL);
705 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
706
707 IEnumMediaTypes_Release(enummt);
708
709 req_mt.majortype = MEDIATYPE_Video;
710 req_mt.formattype = FORMAT_VideoInfo;
711 req_mt.cbFormat = sizeof(VIDEOINFOHEADER);
712 req_mt.pbFormat = (BYTE *)&vih;
713
714 for (i = 0; i < ARRAY_SIZE(subtype_tests); ++i)
715 {
716 req_mt.subtype = *subtype_tests[i];
717 hr = IPin_QueryAccept(pin, &req_mt);
718 ok(hr == S_OK, "Got hr %#lx for subtype %s.\n", hr, wine_dbgstr_guid(subtype_tests[i]));
719 }
720
721 req_mt.subtype = MEDIASUBTYPE_RGB8;
722 hr = IPin_QueryAccept(pin, &req_mt);
723 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
724 req_mt.subtype = MEDIASUBTYPE_RGB24;
725
726 req_mt.majortype = MEDIATYPE_NULL;
727 hr = IPin_QueryAccept(pin, &req_mt);
728 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
729 req_mt.majortype = MEDIATYPE_Video;
730
731 req_mt.formattype = FORMAT_None;
732 hr = IPin_QueryAccept(pin, &req_mt);
733 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
734
735 req_mt.formattype = GUID_NULL;
736 hr = IPin_QueryAccept(pin, &req_mt);
737 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
738
739 IPin_Release(pin);
740 ref = IBaseFilter_Release(filter);
741 ok(!ref, "Got outstanding refcount %ld.\n", ref);
742}
743
744static void test_enum_media_types(void)
745{
747 IEnumMediaTypes *enum1, *enum2;
748 AM_MEDIA_TYPE *mts[2];
749 ULONG ref, count;
750 HRESULT hr;
751 IPin *pin;
752
753 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
754
755 hr = IPin_EnumMediaTypes(pin, &enum1);
756 ok(hr == S_OK, "Got hr %#lx.\n", hr);
757
758 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
759 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
760
761 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
762 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
763 ok(!count, "Got count %lu.\n", count);
764
765 hr = IEnumMediaTypes_Reset(enum1);
766 ok(hr == S_OK, "Got hr %#lx.\n", hr);
767
768 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
769 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
770
771 hr = IEnumMediaTypes_Clone(enum1, &enum2);
772 ok(hr == S_OK, "Got hr %#lx.\n", hr);
773
774 hr = IEnumMediaTypes_Skip(enum1, 1);
775 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
776
777 hr = IEnumMediaTypes_Next(enum2, 1, mts, NULL);
778 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
779
780 IEnumMediaTypes_Release(enum1);
781 IEnumMediaTypes_Release(enum2);
782 IPin_Release(pin);
783
784 ref = IBaseFilter_Release(filter);
785 ok(!ref, "Got outstanding refcount %ld.\n", ref);
786}
787
789{
791 FILTER_STATE state;
792 HRESULT hr;
793 ULONG ref;
794
795 hr = IBaseFilter_GetState(filter, 0, &state);
796 ok(hr == S_OK, "Got hr %#lx.\n", hr);
797 ok(state == State_Stopped, "Got state %u.\n", state);
798
799 hr = IBaseFilter_Pause(filter);
800 ok(hr == S_OK, "Got hr %#lx.\n", hr);
801
802 hr = IBaseFilter_GetState(filter, 0, &state);
803 ok(hr == S_OK, "Got hr %#lx.\n", hr);
804 ok(state == State_Paused, "Got state %u.\n", state);
805
806 hr = IBaseFilter_Run(filter, 0);
807 ok(hr == S_OK, "Got hr %#lx.\n", hr);
808
809 hr = IBaseFilter_GetState(filter, 0, &state);
810 ok(hr == S_OK, "Got hr %#lx.\n", hr);
811 ok(state == State_Running, "Got state %u.\n", state);
812
813 hr = IBaseFilter_Pause(filter);
814 ok(hr == S_OK, "Got hr %#lx.\n", hr);
815
816 hr = IBaseFilter_GetState(filter, 0, &state);
817 ok(hr == S_OK, "Got hr %#lx.\n", hr);
818 ok(state == State_Paused, "Got state %u.\n", state);
819
820 hr = IBaseFilter_Stop(filter);
821 ok(hr == S_OK, "Got hr %#lx.\n", hr);
822
823 hr = IBaseFilter_GetState(filter, 0, &state);
824 ok(hr == S_OK, "Got hr %#lx.\n", hr);
825 ok(state == State_Stopped, "Got state %u.\n", state);
826
827 hr = IBaseFilter_Run(filter, 0);
828 ok(hr == S_OK, "Got hr %#lx.\n", hr);
829
830 hr = IBaseFilter_GetState(filter, 0, &state);
831 ok(hr == S_OK, "Got hr %#lx.\n", hr);
832 ok(state == State_Running, "Got state %u.\n", state);
833
834 hr = IBaseFilter_Stop(filter);
835 ok(hr == S_OK, "Got hr %#lx.\n", hr);
836
837 hr = IBaseFilter_GetState(filter, 0, &state);
838 ok(hr == S_OK, "Got hr %#lx.\n", hr);
839 ok(state == State_Stopped, "Got state %u.\n", state);
840
841 ref = IBaseFilter_Release(filter);
842 ok(!ref, "Got outstanding refcount %ld.\n", ref);
843}
844
845struct testfilter
846{
847 struct strmbase_filter filter;
848 struct strmbase_source source;
849};
850
851static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
852{
853 return CONTAINING_RECORD(iface, struct testfilter, filter);
854}
855
856static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
857{
859 if (!index)
860 return &filter->source.pin;
861 return NULL;
862}
863
864static void testfilter_destroy(struct strmbase_filter *iface)
865{
869}
870
872{
873 .filter_get_pin = testfilter_get_pin,
874 .filter_destroy = testfilter_destroy,
875};
876
879{
880 return S_OK;
881}
882
884{
885 .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
886 .pfnDecideAllocator = testsource_DecideAllocator,
887};
888
890{
891 static const GUID clsid = {0xabacab};
894}
895
897{
898 IMemAllocator *req_allocator, *ret_allocator;
899 ALLOCATOR_PROPERTIES props, req_props;
900 HRESULT hr;
901
902 hr = IMemInputPin_GetAllocatorRequirements(input, &props);
903 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
904
905 hr = IMemInputPin_GetAllocator(input, &ret_allocator);
906 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
907
908 if (hr == S_OK)
909 {
910 hr = IMemAllocator_GetProperties(ret_allocator, &props);
911 ok(hr == S_OK, "Got hr %#lx.\n", hr);
912 ok(!props.cBuffers, "Got %ld buffers.\n", props.cBuffers);
913 ok(!props.cbBuffer, "Got size %ld.\n", props.cbBuffer);
914 ok(!props.cbAlign, "Got alignment %ld.\n", props.cbAlign);
915 ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
916
917 hr = IMemInputPin_NotifyAllocator(input, ret_allocator, TRUE);
918 ok(hr == S_OK, "Got hr %#lx.\n", hr);
919
920 req_props.cBuffers = 1;
921 req_props.cbBuffer = 32 * 16 * 4;
922 req_props.cbAlign = 1;
923 req_props.cbPrefix = 0;
924 hr = IMemAllocator_SetProperties(ret_allocator, &req_props, &props);
925 ok(hr == S_OK, "Got hr %#lx.\n", hr);
926 ok(props.cBuffers == 1, "Got %ld buffers.\n", props.cBuffers);
927 ok(props.cbBuffer == 32 * 16 * 4, "Got size %ld.\n", props.cbBuffer);
928 ok(props.cbAlign == 1, "Got alignment %ld.\n", props.cbAlign);
929 ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
930
931 IMemAllocator_Release(ret_allocator);
932 }
933
934 hr = IMemInputPin_NotifyAllocator(input, NULL, TRUE);
935 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
936
937 CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
938 &IID_IMemAllocator, (void **)&req_allocator);
939
940 hr = IMemInputPin_NotifyAllocator(input, req_allocator, TRUE);
941 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
942
943 IMemAllocator_Release(req_allocator);
944}
945
947{
950};
951
953{
955 HRESULT hr;
956
957 if (winetest_debug > 1) trace("%04lx: Sending frame.\n", GetCurrentThreadId());
958 hr = IMemInputPin_Receive(params->sink, params->sample);
959 if (winetest_debug > 1) trace("%04lx: Returned %#lx.\n", GetCurrentThreadId(), hr);
960 IMediaSample_Release(params->sample);
961 free(params);
962 return hr;
963}
964
966{
967 struct frame_thread_params *params = malloc(sizeof(*params));
968 REFERENCE_TIME start_time, end_time;
972 HRESULT hr;
973 BYTE *data;
974
975 hr = IMemInputPin_GetAllocator(sink, &allocator);
976 ok(hr == S_OK, "Got hr %#lx.\n", hr);
977
978 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
979 ok(hr == S_OK, "Got hr %#lx.\n", hr);
980
981 hr = IMediaSample_GetPointer(sample, &data);
982 ok(hr == S_OK, "Got hr %#lx.\n", hr);
983 memset(data, 0x55, IMediaSample_GetSize(sample));
984
985 hr = IMediaSample_SetActualDataLength(sample, IMediaSample_GetSize(sample));
986 ok(hr == S_OK, "Got hr %#lx.\n", hr);
987
988 start_time = 0;
989 end_time = start_time + 10000000;
990 hr = IMediaSample_SetTime(sample, &start_time, &end_time);
991 ok(hr == S_OK, "Got hr %#lx.\n", hr);
992
993 hr = IMediaSample_SetPreroll(sample, TRUE);
994 ok(hr == S_OK, "Got hr %#lx.\n", hr);
995
996 params->sink = sink;
997 params->sample = sample;
999
1000 IMemAllocator_Release(allocator);
1001 return thread;
1002}
1003
1005{
1006 DWORD ret;
1007 ok_(__FILE__, line)(!WaitForSingleObject(thread, 1000), "Wait failed.\n");
1010 return ret;
1011}
1012#define join_thread(a) join_thread_(__LINE__, a)
1013
1015{
1017 HRESULT hr;
1018
1019 hr = IMemInputPin_GetAllocator(input, &allocator);
1020 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1021 hr = IMemAllocator_Commit(allocator);
1022 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1023 IMemAllocator_Release(allocator);
1024}
1025
1026static void test_filter_state(IMemInputPin *input, IMediaControl *control)
1027{
1030 OAFilterState state;
1031 HANDLE thread;
1032 HRESULT hr;
1033
1036 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
1037
1038 /* The renderer is not fully paused until it receives a sample. The thread
1039 * sending the sample blocks in IMemInputPin_Receive() until the filter is
1040 * stopped or run. */
1041
1042 hr = IMediaControl_Pause(control);
1043 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1044
1045 hr = IMediaControl_GetState(control, 0, &state);
1046 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1047
1049
1050 hr = IMediaControl_GetState(control, 1000, &state);
1051 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1052
1053 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1054
1055 hr = IMediaControl_Stop(control);
1056 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1057
1059 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1060
1061 /* The sink will decommit our allocator for us when stopping, however it
1062 * will not recommit it when pausing. */
1063 hr = IMemInputPin_GetAllocator(input, &allocator);
1064 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1065 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
1066 todo_wine ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#lx.\n", hr);
1067 if (hr == S_OK) IMediaSample_Release(sample);
1068
1069 hr = IMemAllocator_Commit(allocator);
1070 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1073 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
1074
1075 hr = IMediaControl_Pause(control);
1076 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1077
1078 hr = IMediaControl_GetState(control, 0, &state);
1079 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1080
1082
1083 hr = IMediaControl_GetState(control, 1000, &state);
1084 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1085
1086 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1087
1088 hr = IMediaControl_Run(control);
1089 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1090
1091 hr = IMediaControl_GetState(control, 0, &state);
1092 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1093
1095 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1096
1099 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1100
1101 hr = IMediaControl_Pause(control);
1102 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1103
1104 hr = IMediaControl_GetState(control, 0, &state);
1105 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1106
1108
1109 hr = IMediaControl_GetState(control, 1000, &state);
1110 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1111
1112 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1113
1114 hr = IMediaControl_Run(control);
1115 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1116
1117 hr = IMediaControl_GetState(control, 0, &state);
1118 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1119
1121 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1122
1123 hr = IMediaControl_Pause(control);
1124 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1125
1126 hr = IMediaControl_GetState(control, 0, &state);
1127 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1128
1129 hr = IMediaControl_Stop(control);
1130 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1131
1132 hr = IMediaControl_GetState(control, 0, &state);
1133 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1134
1136 hr = IMediaControl_Pause(control);
1137 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1138
1139 hr = IMediaControl_GetState(control, 0, &state);
1140 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1141
1142 hr = IMediaControl_Run(control);
1143 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1144
1145 hr = IMediaControl_GetState(control, 0, &state);
1146 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1147
1150 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1151
1152 hr = IMediaControl_GetState(control, 0, &state);
1153 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1154
1155 hr = IMediaControl_Stop(control);
1156 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1157
1158 hr = IMediaControl_GetState(control, 0, &state);
1159 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1160
1161 IMemAllocator_Release(allocator);
1162}
1163
1164static void test_flushing(IPin *pin, IMemInputPin *input, IMediaControl *control)
1165{
1166 OAFilterState state;
1167 HANDLE thread;
1168 HRESULT hr;
1169
1171 hr = IMediaControl_Pause(control);
1172 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1173
1175 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1176
1177 hr = IMediaControl_GetState(control, 1000, &state);
1178 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1179
1180 hr = IPin_BeginFlush(pin);
1181 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1182
1184 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1185
1188 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1189
1190 hr = IPin_EndFlush(pin);
1191 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1192
1193 /* We dropped the sample we were holding, so now we need a new one... */
1194
1195 hr = IMediaControl_GetState(control, 0, &state);
1196 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1197 ok(state == State_Paused, "Got state %#lx.\n", state);
1198
1200 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1201
1202 hr = IMediaControl_GetState(control, 1000, &state);
1203 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1204 ok(state == State_Paused, "Got state %#lx.\n", state);
1205
1206 hr = IMediaControl_Run(control);
1207 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1209 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1210
1211 hr = IPin_BeginFlush(pin);
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
1223 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1224
1225 hr = IMediaControl_Stop(control);
1226 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1227}
1228
1229static unsigned int check_event_code(IMediaEvent *eventsrc, DWORD timeout, LONG expected_code, LONG_PTR expected1, LONG_PTR expected2)
1230{
1231 LONG_PTR param1, param2;
1232 unsigned int ret = 0;
1233 HRESULT hr;
1234 LONG code;
1235
1236 while ((hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, timeout)) == S_OK)
1237 {
1238 if (code == expected_code)
1239 {
1240 ok(param1 == expected1, "Got param1 %#Ix.\n", param1);
1241 ok(param2 == expected2, "Got param2 %#Ix.\n", param2);
1242 ret++;
1243 }
1244 IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
1245 timeout = 0;
1246 }
1247 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
1248
1249 return ret;
1250}
1251
1252static unsigned int check_ec_complete(IMediaEvent *eventsrc, DWORD timeout)
1253{
1254 return check_event_code(eventsrc, timeout, EC_COMPLETE, S_OK, 0);
1255}
1256
1258 IMediaControl *control, const BITMAPINFOHEADER *req_bih)
1259{
1260 LONG buffer[(sizeof(BITMAPINFOHEADER) + 32 * 16 * 4) / 4];
1262 const DWORD *data = (DWORD *)((char *)buffer + sizeof(BITMAPINFOHEADER));
1263 BITMAPINFOHEADER expect_bih = *req_bih;
1264 OAFilterState state;
1265 IBasicVideo *video;
1266 unsigned int i;
1267 HANDLE thread;
1268 HRESULT hr;
1269 LONG size;
1270
1271 /* Note that the bitmap returned by GetCurrentImage() has a bit depth of
1272 * 32 regardless of the format used for pin connection. */
1273 expect_bih.biBitCount = 32;
1274 expect_bih.biSizeImage = 32 * 16 * 4;
1275
1276 IBaseFilter_QueryInterface(filter, &IID_IBasicVideo, (void **)&video);
1277
1278 hr = IBasicVideo_GetCurrentImage(video, NULL, NULL);
1279 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1280
1281 hr = IBasicVideo_GetCurrentImage(video, NULL, buffer);
1282 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1283
1284 size = 0xdeadbeef;
1285 hr = IBasicVideo_GetCurrentImage(video, &size, NULL);
1286 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
1287 todo_wine ok(size == sizeof(BITMAPINFOHEADER) + 32 * 16 * 4, "Got size %ld.\n", size);
1288
1289 size = sizeof(buffer);
1290 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1291 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
1292 if (hr != S_OK)
1293 goto out;
1294 ok(size == sizeof(buffer), "Got size %ld.\n", size);
1295 ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
1296 /* The contents seem to reflect the last frame rendered. */
1297
1299 hr = IMediaControl_Pause(control);
1300 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1301
1302 size = sizeof(buffer);
1303 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1304 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1305 ok(size == sizeof(buffer), "Got size %ld.\n", size);
1306 ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
1307 /* The contents seem to reflect the last frame rendered. */
1308
1310 hr = IMediaControl_GetState(control, 1000, &state);
1311 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1312
1313 size = 1;
1314 memset(buffer, 0xcc, sizeof(buffer));
1315 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1316 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1317 ok(size == 1, "Got size %ld.\n", size);
1318
1319 size = sizeof(buffer);
1320 memset(buffer, 0xcc, sizeof(buffer));
1321 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1322 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1323 ok(size == sizeof(buffer), "Got size %ld.\n", size);
1324 ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
1325 for (i = 0; i < 32 * 16; ++i)
1326 ok((data[i] & 0xffffff) == 0x555555, "Got unexpected color %08lx at %u.\n", data[i], i);
1327
1328 hr = IMediaControl_Run(control);
1329 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1331
1332 size = sizeof(buffer);
1333 memset(buffer, 0xcc, sizeof(buffer));
1334 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1335 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1336 ok(size == sizeof(buffer), "Got size %ld.\n", size);
1337 ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
1338 for (i = 0; i < 32 * 16; ++i)
1339 ok((data[i] & 0xffffff) == 0x555555, "Got unexpected color %08lx at %u.\n", data[i], i);
1340
1341 hr = IMediaControl_Stop(control);
1342 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1343
1344out:
1345 IBasicVideo_Release(video);
1346}
1347
1348static unsigned int check_ec_userabort(IMediaEvent *eventsrc, DWORD timeout)
1349{
1350 LONG_PTR param1, param2;
1351 unsigned int ret = 0;
1352 HRESULT hr;
1353 LONG code;
1354
1355 while ((hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, timeout)) == S_OK)
1356 {
1357 if (code == EC_USERABORT)
1358 {
1359 ok(!param1, "Got param1 %#Ix.\n", param1);
1360 ok(!param2, "Got param2 %#Ix.\n", param2);
1361 ret++;
1362 }
1363 IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
1364 timeout = 0;
1365 }
1366 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
1367
1368 return ret;
1369}
1370
1371static void test_window_close(IPin *pin, IMemInputPin *input, IMediaControl *control)
1372{
1373 IMediaEvent *eventsrc;
1374 OAFilterState state;
1375 IOverlay *overlay;
1376 HANDLE thread;
1377 HRESULT hr;
1378 HWND hwnd;
1379 BOOL ret;
1380
1381 IMediaControl_QueryInterface(control, &IID_IMediaEvent, (void **)&eventsrc);
1382 IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
1383
1384 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
1385 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1386 IOverlay_Release(overlay);
1387
1389 hr = IMediaControl_Pause(control);
1390 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1391 ret = check_ec_userabort(eventsrc, 0);
1392 ok(!ret, "Got unexpected EC_USERABORT.\n");
1393
1394 SendMessageW(hwnd, WM_CLOSE, 0, 0);
1395
1396 hr = IMediaControl_GetState(control, 1000, &state);
1397 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1398 ret = check_ec_userabort(eventsrc, 0);
1399 ok(ret == 1, "Expected EC_USERABORT.\n");
1400
1401 ok(IsWindow(hwnd), "Window should exist.\n");
1402 ok(!IsWindowVisible(hwnd), "Window should be visible.\n");
1403
1406 todo_wine ok(ret == WAIT_OBJECT_0, "Wait failed\n");
1407 if (ret == WAIT_OBJECT_0)
1408 {
1410 ok(hr == E_UNEXPECTED, "Got hr %#lx.\n", hr);
1411 }
1413
1414 hr = IMediaControl_Run(control);
1415 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1416 ret = check_ec_userabort(eventsrc, 0);
1417 ok(!ret, "Got unexpected EC_USERABORT.\n");
1418
1419 hr = IMediaControl_Stop(control);
1420 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1421 ret = check_ec_userabort(eventsrc, 0);
1422 ok(!ret, "Got unexpected EC_USERABORT.\n");
1423
1424 /* We receive an EC_USERABORT notification immediately. */
1425
1427 hr = IMediaControl_Run(control);
1428 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1430 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1431 hr = IMediaControl_GetState(control, 1000, &state);
1432 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1433 ret = check_ec_userabort(eventsrc, 0);
1434 ok(!ret, "Got unexpected EC_USERABORT.\n");
1435
1436 SendMessageW(hwnd, WM_CLOSE, 0, 0);
1437
1438 ret = check_ec_userabort(eventsrc, 0);
1439 ok(ret == 1, "Expected EC_USERABORT.\n");
1440
1441 ok(IsWindow(hwnd), "Window should exist.\n");
1442 ok(!IsWindowVisible(hwnd), "Window should be visible.\n");
1443
1444 hr = IMediaControl_Stop(control);
1445 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1446 ret = check_ec_userabort(eventsrc, 0);
1447 ok(!ret, "Got unexpected EC_USERABORT.\n");
1448
1449 IMediaEvent_Release(eventsrc);
1450}
1451
1452static void test_connect_pin(void)
1453{
1454 VIDEOINFOHEADER vih =
1455 {
1457 .bmiHeader.biWidth = 32,
1458 .bmiHeader.biHeight = 16,
1459 .bmiHeader.biPlanes = 1,
1460 .bmiHeader.biCompression = BI_RGB,
1461 };
1462 AM_MEDIA_TYPE req_mt =
1463 {
1464 .majortype = MEDIATYPE_Video,
1465 .subtype = MEDIASUBTYPE_WAVE,
1466 .formattype = FORMAT_VideoInfo,
1467 .cbFormat = sizeof(vih),
1468 .pbFormat = (BYTE *)&vih,
1469 };
1470 ALLOCATOR_PROPERTIES req_props = {1, 32 * 16 * 4, 1, 0}, ret_props;
1473 struct testfilter source;
1475 IMediaControl *control;
1478 IPin *pin, *peer;
1479 unsigned int i;
1480 HRESULT hr;
1481 ULONG ref;
1482
1483 static const GUID *subtype_tests[] =
1484 {
1485 &MEDIASUBTYPE_RGB565,
1486 &MEDIASUBTYPE_RGB24,
1487 &MEDIASUBTYPE_RGB32,
1488 &MEDIASUBTYPE_WAVE,
1489 };
1490
1492
1493 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
1494 IFilterGraph2_AddFilter(graph, filter, NULL);
1495 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
1496
1497 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
1498
1499 vih.bmiHeader.biBitCount = 16;
1500 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1501 todo_wine ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1502
1503 vih.bmiHeader.biBitCount = 32;
1504 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1505 if (hr == VFW_E_TYPE_NOT_ACCEPTED) /* w7u */
1506 {
1507 vih.bmiHeader.biBitCount = 24;
1508 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1509 /* w7u is also rather buggy with its allocator. Requesting a size of
1510 * 32 * 16 * 4 succeeds and returns that size from SetProperties(), but
1511 * the actual samples only have a size of 32 * 16 * 3. */
1512 req_props.cbBuffer = 32 * 16 * 3;
1513 }
1514 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1515 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
1516 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1517 hr = IFilterGraph2_Disconnect(graph, pin);
1518 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1519
1520 for (i = 0; i < ARRAY_SIZE(subtype_tests); ++i)
1521 {
1522 req_mt.subtype = *subtype_tests[i];
1523 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1524 ok(hr == S_OK, "Got hr %#lx for subtype %s.\n", hr, wine_dbgstr_guid(subtype_tests[i]));
1525
1526 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
1527 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1528 hr = IFilterGraph2_Disconnect(graph, pin);
1529 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1530 }
1531
1532 req_mt.formattype = FORMAT_None;
1533 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1534 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1535 req_mt.formattype = FORMAT_VideoInfo;
1536
1537 req_mt.subtype = MEDIASUBTYPE_RGB8;
1538 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1539 todo_wine ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1540 if (hr == S_OK)
1541 {
1542 IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
1543 IFilterGraph2_Disconnect(graph, pin);
1544 }
1545 req_mt.subtype = MEDIASUBTYPE_RGB32;
1546
1547 peer = (IPin *)0xdeadbeef;
1548 hr = IPin_ConnectedTo(pin, &peer);
1549 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1550 ok(!peer, "Got peer %p.\n", peer);
1551
1552 hr = IPin_ConnectionMediaType(pin, &mt);
1553 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1554
1555 hr = IMediaControl_Pause(control);
1556 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1557 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1558 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
1559 hr = IMediaControl_Stop(control);
1560 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1561
1562 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1563 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1564
1565 hr = IPin_ConnectedTo(pin, &peer);
1566 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1567 ok(peer == &source.source.pin.IPin_iface, "Got peer %p.\n", peer);
1568 IPin_Release(peer);
1569
1570 hr = IPin_ConnectionMediaType(pin, &mt);
1571 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1572 ok(compare_media_types(&mt, &req_mt), "Media types didn't match.\n");
1573
1574 /* Disconnecting while not stopped is broken: it returns S_OK, but
1575 * subsequent attempts to connect return VFW_E_ALREADY_CONNECTED. */
1576
1577 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
1578
1580
1581 hr = IMemInputPin_GetAllocator(input, &allocator);
1582 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1583 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
1584 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1585 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
1586 hr = IMemAllocator_Commit(allocator);
1587 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1588 IMemAllocator_Release(allocator);
1589
1590 hr = IMemInputPin_ReceiveCanBlock(input);
1591 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1592
1597
1598 hr = IFilterGraph2_Disconnect(graph, pin);
1599 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1600 hr = IFilterGraph2_Disconnect(graph, pin);
1601 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1602 ok(source.source.pin.peer == pin, "Got peer %p.\n", peer);
1603 IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
1604
1605 peer = (IPin *)0xdeadbeef;
1606 hr = IPin_ConnectedTo(pin, &peer);
1607 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1608 ok(!peer, "Got peer %p.\n", peer);
1609
1610 hr = IPin_ConnectionMediaType(pin, &mt);
1611 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1612
1613 IMemInputPin_Release(input);
1614 IPin_Release(pin);
1615 IMediaControl_Release(control);
1616 ref = IFilterGraph2_Release(graph);
1617 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1618 ref = IBaseFilter_Release(filter);
1619 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1620 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
1621 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1622}
1623
1624static void test_overlay(void)
1625{
1627 IOverlay *overlay;
1628 HRESULT hr;
1629 ULONG ref;
1630 IPin *pin;
1631 HWND hwnd;
1632
1633 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
1634
1635 hr = IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
1636 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1637
1638 hwnd = (HWND)0xdeadbeef;
1639 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
1640 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1641 ok(hwnd && hwnd != (HWND)0xdeadbeef, "Got invalid window %p.\n", hwnd);
1642
1643 IOverlay_Release(overlay);
1644 IPin_Release(pin);
1645 ref = IBaseFilter_Release(filter);
1646 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1647}
1648
1649/* try to make sure pending X events have been processed before continuing */
1650static void flush_events(void)
1651{
1652 int diff = 200;
1653 DWORD time;
1654 MSG msg;
1655
1656 time = GetTickCount() + diff;
1657 while (diff > 0)
1658 {
1660 break;
1661 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
1663 diff = time - GetTickCount();
1664 }
1665}
1666
1668{
1669 if (winetest_debug > 1)
1670 trace("hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix.\n", hwnd, msg, wparam, lparam);
1671
1672 if (wparam == 0xdeadbeef)
1673 return 0;
1674
1675 return DefWindowProcA(hwnd, msg, wparam, lparam);
1676}
1677
1678static void test_video_window_caption(IVideoWindow *window, HWND hwnd)
1679{
1680 WCHAR text[50];
1681 BSTR caption;
1682 HRESULT hr;
1683
1684 hr = IVideoWindow_get_Caption(window, &caption);
1685 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1686 ok(!wcscmp(caption, L"ActiveMovie Window"), "Got caption %s.\n", wine_dbgstr_w(caption));
1687 SysFreeString(caption);
1688
1690 ok(!wcscmp(text, L"ActiveMovie Window"), "Got caption %s.\n", wine_dbgstr_w(text));
1691
1692 caption = SysAllocString(L"foo");
1693 hr = IVideoWindow_put_Caption(window, caption);
1694 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1695 SysFreeString(caption);
1696
1697 hr = IVideoWindow_get_Caption(window, &caption);
1698 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1699 ok(!wcscmp(caption, L"foo"), "Got caption %s.\n", wine_dbgstr_w(caption));
1700 SysFreeString(caption);
1701
1703 ok(!wcscmp(text, L"foo"), "Got caption %s.\n", wine_dbgstr_w(text));
1704}
1705
1706static void test_video_window_style(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
1707{
1708 HRESULT hr;
1709 LONG style;
1710
1711 hr = IVideoWindow_get_WindowStyle(window, &style);
1712 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1714 "Got style %#lx.\n", style);
1715
1718 "Got style %#lx.\n", style);
1719
1720 hr = IVideoWindow_put_WindowStyle(window, style | WS_DISABLED);
1721 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1722 hr = IVideoWindow_put_WindowStyle(window, style | WS_HSCROLL);
1723 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1724 hr = IVideoWindow_put_WindowStyle(window, style | WS_VSCROLL);
1725 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1726 hr = IVideoWindow_put_WindowStyle(window, style | WS_MAXIMIZE);
1727 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1728 hr = IVideoWindow_put_WindowStyle(window, style | WS_MINIMIZE);
1729 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1730
1731 hr = IVideoWindow_put_WindowStyle(window, style & ~WS_CLIPCHILDREN);
1732 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1733
1734 hr = IVideoWindow_get_WindowStyle(window, &style);
1735 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1736 ok(style == (WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW), "Got style %#lx.\n", style);
1737
1739 ok(style == (WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW), "Got style %#lx.\n", style);
1740
1742 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1743
1744 hr = IVideoWindow_get_WindowStyleEx(window, &style);
1745 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1746 ok(style == WS_EX_WINDOWEDGE, "Got style %#lx.\n", style);
1747
1749 ok(style == WS_EX_WINDOWEDGE, "Got style %#lx.\n", style);
1750
1751 hr = IVideoWindow_put_WindowStyleEx(window, style | WS_EX_TRANSPARENT);
1752 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1753
1754 hr = IVideoWindow_get_WindowStyleEx(window, &style);
1755 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1756 ok(style == (WS_EX_WINDOWEDGE | WS_EX_TRANSPARENT), "Got style %#lx.\n", style);
1757
1759 ok(style == (WS_EX_WINDOWEDGE | WS_EX_TRANSPARENT), "Got style %#lx.\n", style);
1760}
1761
1763{
1764 DWORD pid;
1767 {
1768 *(HWND *)ctx = hwnd;
1769 return FALSE;
1770 }
1771 return TRUE;
1772}
1773
1775{
1776 HWND hwnd;
1778 return hwnd;
1779}
1780
1781static void test_video_window_state(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
1782{
1783 HRESULT hr;
1784 LONG state;
1785 HWND top;
1786
1787 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1788
1789 hr = IVideoWindow_get_WindowState(window, &state);
1790 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1791 ok(state == SW_HIDE, "Got state %ld.\n", state);
1792
1793 hr = IVideoWindow_get_Visible(window, &state);
1794 ok(state == OAFALSE, "Got state %ld.\n", state);
1795
1796 ok(!IsWindowVisible(hwnd), "Window should not be visible.\n");
1797 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
1798 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1799
1800 hr = IVideoWindow_put_WindowState(window, SW_SHOWNA);
1801 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1802
1803 hr = IVideoWindow_get_WindowState(window, &state);
1804 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1805 ok(state == SW_SHOW, "Got state %ld.\n", state);
1806
1807 hr = IVideoWindow_get_Visible(window, &state);
1808 ok(state == OATRUE, "Got state %ld.\n", state);
1809
1810 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
1811 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
1812 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1813 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1814 top = get_top_window();
1815 ok(top == hwnd, "Got top window %p.\n", top);
1816
1817 hr = IVideoWindow_put_WindowState(window, SW_MINIMIZE);
1818 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1819
1820 hr = IVideoWindow_get_WindowState(window, &state);
1821 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1822 ok(state == SW_MINIMIZE, "Got state %ld.\n", state);
1823
1824 hr = IVideoWindow_get_Visible(window, &state);
1825 ok(state == OATRUE, "Got state %ld.\n", state);
1826
1827 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
1828 ok(IsIconic(hwnd), "Window should be minimized.\n");
1829 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1830 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1831
1832 hr = IVideoWindow_put_WindowState(window, SW_RESTORE);
1833 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1834
1835 hr = IVideoWindow_get_WindowState(window, &state);
1836 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1837 ok(state == SW_SHOW, "Got state %ld.\n", state);
1838
1839 hr = IVideoWindow_get_Visible(window, &state);
1840 ok(state == OATRUE, "Got state %ld.\n", state);
1841
1842 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
1843 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
1844 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1845 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
1846
1847 hr = IVideoWindow_put_WindowState(window, SW_MAXIMIZE);
1848 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1849
1850 hr = IVideoWindow_get_WindowState(window, &state);
1851 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1852 ok(state == SW_MAXIMIZE, "Got state %ld.\n", state);
1853
1854 hr = IVideoWindow_get_Visible(window, &state);
1855 ok(state == OATRUE, "Got state %ld.\n", state);
1856
1857 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
1858 ok(!IsIconic(hwnd), "Window should be minimized.\n");
1859 ok(IsZoomed(hwnd), "Window should not be maximized.\n");
1860 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
1861
1862 hr = IVideoWindow_put_WindowState(window, SW_RESTORE);
1863 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1864
1865 hr = IVideoWindow_put_WindowState(window, SW_HIDE);
1866 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1867
1868 hr = IVideoWindow_get_WindowState(window, &state);
1869 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1870 ok(state == SW_HIDE, "Got state %ld.\n", state);
1871
1872 hr = IVideoWindow_get_Visible(window, &state);
1873 ok(state == OAFALSE, "Got state %ld.\n", state);
1874
1875 ok(!IsWindowVisible(hwnd), "Window should not be visible.\n");
1876 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
1877 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1878 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1879
1880 hr = IVideoWindow_put_Visible(window, OATRUE);
1881 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1882
1883 hr = IVideoWindow_get_WindowState(window, &state);
1884 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1885 ok(state == SW_SHOW, "Got state %ld.\n", state);
1886
1887 hr = IVideoWindow_get_Visible(window, &state);
1888 ok(state == OATRUE, "Got state %ld.\n", state);
1889
1890 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
1891 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
1892 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1893 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
1894
1895 hr = IVideoWindow_put_Visible(window, OAFALSE);
1896 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1897
1898 hr = IVideoWindow_get_WindowState(window, &state);
1899 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1900 ok(state == SW_HIDE, "Got state %ld.\n", state);
1901
1902 hr = IVideoWindow_get_Visible(window, &state);
1903 ok(state == OAFALSE, "Got state %ld.\n", state);
1904
1905 ok(!IsWindowVisible(hwnd), "Window should not be visible.\n");
1906 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
1907 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1908 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1909
1910 hr = IVideoWindow_put_WindowState(window, SW_SHOWNA);
1911 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1912
1913 hr = IVideoWindow_SetWindowForeground(window, TRUE);
1914 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1915
1916 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1917 hr = IVideoWindow_SetWindowForeground(window, OATRUE);
1918 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1919 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
1920 ok(GetFocus() == hwnd, "Got focus window %p.\n", GetFocus());
1921 ok(GetForegroundWindow() == hwnd, "Got foreground window %p.\n", GetForegroundWindow());
1922 top = get_top_window();
1923 ok(top == hwnd, "Got top window %p.\n", top);
1924
1925 hr = IVideoWindow_SetWindowForeground(window, OAFALSE);
1926 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1927 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
1928 ok(GetFocus() == hwnd, "Got focus window %p.\n", GetFocus());
1929 ok(GetForegroundWindow() == hwnd, "Got foreground window %p.\n", GetForegroundWindow());
1930 top = get_top_window();
1931 ok(top == hwnd, "Got top window %p.\n", top);
1932
1933 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1934 hr = IVideoWindow_SetWindowForeground(window, OAFALSE);
1935 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1936 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1937 ok(GetFocus() == our_hwnd, "Got focus window %p.\n", GetFocus());
1938 ok(GetForegroundWindow() == our_hwnd, "Got foreground window %p.\n", GetForegroundWindow());
1939 top = get_top_window();
1940 ok(top == hwnd, "Got top window %p.\n", top);
1941}
1942
1943static void test_video_window_position(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
1944{
1945 LONG left, width, top, height, expect_width, expect_height;
1946 RECT rect = {0, 0, 600, 400};
1947 HWND top_hwnd;
1948 HRESULT hr;
1949
1950 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1951
1953 expect_width = rect.right - rect.left;
1954 expect_height = rect.bottom - rect.top;
1955
1956 hr = IVideoWindow_put_Left(window, 0);
1957 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1958 hr = IVideoWindow_put_Top(window, 0);
1959 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1960
1961 hr = IVideoWindow_get_Left(window, &left);
1962 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1963 ok(left == 0, "Got left %ld.\n", left);
1964 hr = IVideoWindow_get_Top(window, &top);
1965 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1966 ok(top == 0, "Got top %ld.\n", top);
1967 hr = IVideoWindow_get_Width(window, &width);
1968 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1969 ok(width == expect_width, "Got width %ld.\n", width);
1970 hr = IVideoWindow_get_Height(window, &height);
1971 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1972 ok(height == expect_height, "Got height %ld.\n", height);
1973 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
1974 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1975 ok(left == 0, "Got left %ld.\n", left);
1976 ok(top == 0, "Got top %ld.\n", top);
1977 ok(width == expect_width, "Got width %ld.\n", width);
1978 ok(height == expect_height, "Got height %ld.\n", height);
1980 ok(rect.left == 0, "Got window left %ld.\n", rect.left);
1981 ok(rect.top == 0, "Got window top %ld.\n", rect.top);
1982 ok(rect.right == expect_width, "Got window right %ld.\n", rect.right);
1983 ok(rect.bottom == expect_height, "Got window bottom %ld.\n", rect.bottom);
1984
1985 hr = IVideoWindow_put_Left(window, 10);
1986 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1987
1988 hr = IVideoWindow_get_Left(window, &left);
1989 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1990 ok(left == 10, "Got left %ld.\n", left);
1991 hr = IVideoWindow_get_Top(window, &top);
1992 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1993 ok(top == 0, "Got top %ld.\n", top);
1994 hr = IVideoWindow_get_Width(window, &width);
1995 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1996 ok(width == expect_width, "Got width %ld.\n", width);
1997 hr = IVideoWindow_get_Height(window, &height);
1998 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1999 ok(height == expect_height, "Got height %ld.\n", height);
2000 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
2001 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2002 ok(left == 10, "Got left %ld.\n", left);
2003 ok(top == 0, "Got top %ld.\n", top);
2004 ok(width == expect_width, "Got width %ld.\n", width);
2005 ok(height == expect_height, "Got height %ld.\n", height);
2007 ok(rect.left == 10, "Got window left %ld.\n", rect.left);
2008 ok(rect.top == 0, "Got window top %ld.\n", rect.top);
2009 ok(rect.right == 10 + expect_width, "Got window right %ld.\n", rect.right);
2010 ok(rect.bottom == expect_height, "Got window bottom %ld.\n", rect.bottom);
2011
2012 hr = IVideoWindow_put_Height(window, 200);
2013 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2014
2015 hr = IVideoWindow_get_Left(window, &left);
2016 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2017 ok(left == 10, "Got left %ld.\n", left);
2018 hr = IVideoWindow_get_Top(window, &top);
2019 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2020 ok(top == 0, "Got top %ld.\n", top);
2021 hr = IVideoWindow_get_Width(window, &width);
2022 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2023 ok(width == expect_width, "Got width %ld.\n", width);
2024 hr = IVideoWindow_get_Height(window, &height);
2025 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2026 ok(height == 200, "Got height %ld.\n", height);
2027 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
2028 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2029 ok(left == 10, "Got left %ld.\n", left);
2030 ok(top == 0, "Got top %ld.\n", top);
2031 ok(width == expect_width, "Got width %ld.\n", width);
2032 ok(height == 200, "Got height %ld.\n", height);
2034 ok(rect.left == 10, "Got window left %ld.\n", rect.left);
2035 ok(rect.top == 0, "Got window top %ld.\n", rect.top);
2036 ok(rect.right == 10 + expect_width, "Got window right %ld.\n", rect.right);
2037 ok(rect.bottom == 200, "Got window bottom %ld.\n", rect.bottom);
2038
2039 hr = IVideoWindow_SetWindowPosition(window, 100, 200, 300, 400);
2040 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2041
2042 hr = IVideoWindow_get_Left(window, &left);
2043 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2044 ok(left == 100, "Got left %ld.\n", left);
2045 hr = IVideoWindow_get_Top(window, &top);
2046 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2047 ok(top == 200, "Got top %ld.\n", top);
2048 hr = IVideoWindow_get_Width(window, &width);
2049 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2050 ok(width == 300, "Got width %ld.\n", width);
2051 hr = IVideoWindow_get_Height(window, &height);
2052 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2053 ok(height == 400, "Got height %ld.\n", height);
2054 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
2055 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2056 ok(left == 100, "Got left %ld.\n", left);
2057 ok(top == 200, "Got top %ld.\n", top);
2058 ok(width == 300, "Got width %ld.\n", width);
2059 ok(height == 400, "Got height %ld.\n", height);
2061 ok(rect.left == 100, "Got window left %ld.\n", rect.left);
2062 ok(rect.top == 200, "Got window top %ld.\n", rect.top);
2063 ok(rect.right == 400, "Got window right %ld.\n", rect.right);
2064 ok(rect.bottom == 600, "Got window bottom %ld.\n", rect.bottom);
2065
2066 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2067 top_hwnd = get_top_window();
2068 ok(top_hwnd == our_hwnd, "Got top window %p.\n", top_hwnd);
2069}
2070
2071static void test_video_window_owner(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
2072{
2073 HWND parent, top_hwnd;
2074 LONG style, state;
2075 OAHWND oahwnd;
2076 HRESULT hr;
2077
2078 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
2079
2080 hr = IVideoWindow_get_Owner(window, &oahwnd);
2081 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2082 ok(!oahwnd, "Got owner %#Ix.\n", oahwnd);
2083
2085 ok(parent == GetDesktopWindow(), "Got parent %p.\n", parent);
2087 ok(!(style & WS_CHILD), "Got style %#lx.\n", style);
2088
2089 hr = IVideoWindow_put_Owner(window, (OAHWND)our_hwnd);
2090 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2091
2092 hr = IVideoWindow_get_Owner(window, &oahwnd);
2093 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2094 ok(oahwnd == (OAHWND)our_hwnd, "Got owner %#Ix.\n", oahwnd);
2095
2097 ok(parent == our_hwnd, "Got parent %p.\n", parent);
2099 ok((style & WS_CHILD), "Got style %#lx.\n", style);
2100
2101 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2102 top_hwnd = get_top_window();
2103 ok(top_hwnd == our_hwnd, "Got top window %p.\n", top_hwnd);
2104
2105 ShowWindow(our_hwnd, SW_HIDE);
2106
2107 hr = IVideoWindow_put_Visible(window, OATRUE);
2108 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2109
2110 hr = IVideoWindow_get_Visible(window, &state);
2111 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2112 ok(state == OAFALSE, "Got state %ld.\n", state);
2113
2114 hr = IVideoWindow_put_Owner(window, 0);
2115 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2116
2117 hr = IVideoWindow_get_Owner(window, &oahwnd);
2118 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2119 ok(!oahwnd, "Got owner %#Ix.\n", oahwnd);
2120
2122 ok(parent == GetDesktopWindow(), "Got parent %p.\n", parent);
2124 ok(!(style & WS_CHILD), "Got style %#lx.\n", style);
2125
2126 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
2127 top_hwnd = get_top_window();
2128 ok(top_hwnd == hwnd, "Got top window %p.\n", top_hwnd);
2129
2130 hr = IVideoWindow_get_Visible(window, &state);
2131 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2132 ok(state == OATRUE, "Got state %ld.\n", state);
2133}
2134
2136{
2137 IVideoWindow *window;
2138 HWND hwnd;
2139 UINT message;
2140};
2141
2143{
2144 const struct notify_message_params *params = arg;
2145 HRESULT hr = IVideoWindow_NotifyOwnerMessage(params->window, (OAHWND)params->hwnd, params->message, 0, 0);
2146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2147 return 0;
2148}
2149
2150static void test_video_window_messages(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
2151{
2153 unsigned int i;
2154 OAHWND oahwnd;
2155 HANDLE thread;
2156 HRESULT hr;
2157 BOOL ret;
2158 MSG msg;
2159
2160 static UINT drain_tests[] =
2161 {
2172 WM_KEYDOWN,
2173 WM_KEYUP,
2184 };
2185
2186 flush_events();
2187
2188 hr = IVideoWindow_get_MessageDrain(window, &oahwnd);
2189 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2190 ok(!oahwnd, "Got window %#Ix.\n", oahwnd);
2191
2192 hr = IVideoWindow_put_MessageDrain(window, (OAHWND)our_hwnd);
2193 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2194
2195 hr = IVideoWindow_get_MessageDrain(window, &oahwnd);
2196 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2197 ok(oahwnd == (OAHWND)our_hwnd, "Got window %#Ix.\n", oahwnd);
2198
2199 for (i = 0; i < ARRAY_SIZE(drain_tests); ++i)
2200 {
2201 SendMessageA(hwnd, drain_tests[i], 0xdeadbeef, 0);
2202 ret = PeekMessageA(&msg, 0, drain_tests[i], drain_tests[i], PM_REMOVE);
2203 ok(ret, "Expected a message.\n");
2204 ok(msg.hwnd == our_hwnd, "Got hwnd %p.\n", msg.hwnd);
2205 ok(msg.message == drain_tests[i], "Got message %#x.\n", msg.message);
2206 ok(msg.wParam == 0xdeadbeef, "Got wparam %#Ix.\n", msg.wParam);
2207 ok(!msg.lParam, "Got lparam %#Ix.\n", msg.lParam);
2209
2210 ret = PeekMessageA(&msg, 0, drain_tests[i], drain_tests[i], PM_REMOVE);
2211 ok(!ret, "Got unexpected message %#x.\n", msg.message);
2212 }
2213
2214 hr = IVideoWindow_put_MessageDrain(window, 0);
2215 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2216
2217 hr = IVideoWindow_put_Owner(window, (OAHWND)our_hwnd);
2218 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2219
2220 flush_events();
2221
2222 /* Demonstrate that messages should be sent, not posted, and that only some
2223 * messages should be forwarded. A previous implementation unconditionally
2224 * posted all messages. */
2225
2226 hr = IVideoWindow_NotifyOwnerMessage(window, (OAHWND)our_hwnd, WM_SYSCOLORCHANGE, 0, 0);
2227 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2228
2229 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2230 {
2231 ok(msg.message != WM_SYSCOLORCHANGE, "WM_SYSCOLORCHANGE should not be posted.\n");
2233 }
2234
2235 hr = IVideoWindow_NotifyOwnerMessage(window, (OAHWND)our_hwnd, WM_FONTCHANGE, 0, 0);
2236 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2237
2238 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2239 {
2240 ok(msg.message != WM_FONTCHANGE, "WM_FONTCHANGE should not be posted.\n");
2242 }
2243
2244 params.window = window;
2245 params.hwnd = our_hwnd;
2246 params.message = WM_SYSCOLORCHANGE;
2248 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block.\n");
2249
2250 while ((ret = MsgWaitForMultipleObjects(1, &thread, FALSE, 1000, QS_ALLINPUT)) == 1)
2251 {
2252 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2253 {
2254 ok(msg.message != WM_SYSCOLORCHANGE, "WM_SYSCOLORCHANGE should not be posted.\n");
2256 }
2257 }
2258 ok(!ret, "Wait timed out.\n");
2260
2261 params.message = WM_FONTCHANGE;
2263 ok(!WaitForSingleObject(thread, 1000), "Thread should not block.\n");
2265
2266 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2267 {
2268 ok(msg.message != WM_FONTCHANGE, "WM_FONTCHANGE should not be posted.\n");
2270 }
2271
2272 hr = IVideoWindow_put_Owner(window, 0);
2273 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2274}
2275
2277{
2278 IMediaControl *control;
2279 HRESULT hr;
2280 LONG l;
2281
2282 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
2283
2284 hr = IVideoWindow_get_AutoShow(window, &l);
2285 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2286 ok(l == OATRUE, "Got %ld.\n", l);
2287
2288 hr = IVideoWindow_put_Visible(window, OAFALSE);
2289 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2290
2291 hr = IMediaControl_Pause(control);
2292 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2293
2294 hr = IVideoWindow_get_Visible(window, &l);
2295 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2296 ok(l == OATRUE, "Got %ld.\n", l);
2297
2298 hr = IMediaControl_Stop(control);
2299 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2300
2301 hr = IVideoWindow_get_Visible(window, &l);
2302 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2303 ok(l == OATRUE, "Got %ld.\n", l);
2304
2305 hr = IVideoWindow_put_AutoShow(window, OAFALSE);
2306 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2307
2308 hr = IVideoWindow_put_Visible(window, OAFALSE);
2309 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2310
2311 hr = IMediaControl_Pause(control);
2312 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2313
2314 hr = IVideoWindow_get_Visible(window, &l);
2315 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2316 ok(l == OAFALSE, "Got %ld.\n", l);
2317
2318 hr = IMediaControl_Stop(control);
2319 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2320
2321 IMediaControl_Release(control);
2322}
2323
2324static void test_video_window(void)
2325{
2326 ALLOCATOR_PROPERTIES req_props = {1, 600 * 400 * 4, 1, 0}, ret_props;
2327 VIDEOINFOHEADER vih =
2328 {
2330 .bmiHeader.biBitCount = 32,
2331 .bmiHeader.biWidth = 600,
2332 .bmiHeader.biHeight = 400,
2333 .bmiHeader.biPlanes = 1,
2334 .bmiHeader.biCompression = BI_RGB,
2335 };
2336 AM_MEDIA_TYPE req_mt =
2337 {
2338 .majortype = MEDIATYPE_Video,
2339 .subtype = MEDIASUBTYPE_RGB32,
2340 .formattype = FORMAT_VideoInfo,
2341 .cbFormat = sizeof(vih),
2342 .pbFormat = (BYTE *)&vih,
2343 };
2345 WNDCLASSA window_class = {0};
2346 struct testfilter source;
2348 LONG width, height, l;
2349 IVideoWindow *window;
2352 HWND hwnd, our_hwnd;
2353 IOverlay *overlay;
2354 BSTR caption;
2355 HRESULT hr;
2356 DWORD tid;
2357 ULONG ref;
2358 IPin *pin;
2359 RECT rect;
2360
2361 window_class.lpszClassName = "wine_test_class";
2362 window_class.lpfnWndProc = window_proc;
2363 RegisterClassA(&window_class);
2364 our_hwnd = CreateWindowA("wine_test_class", "test window", WS_VISIBLE | WS_OVERLAPPEDWINDOW,
2365 100, 200, 300, 400, NULL, NULL, NULL, NULL);
2366 flush_events();
2367
2368 filter = create_vmr7(0);
2369 flush_events();
2370
2372 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2373
2374 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
2375 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
2376
2377 hr = IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
2378 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2379
2380 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
2381 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2382 if (winetest_debug > 1) trace("ours %p, theirs %p\n", our_hwnd, hwnd);
2384
2386 ok(tid == GetCurrentThreadId(), "Expected tid %#lx, got %#lx.\n", GetCurrentThreadId(), tid);
2387
2388 hr = IBaseFilter_QueryInterface(filter, &IID_IVideoWindow, (void **)&window);
2389 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2390
2391 hr = IVideoWindow_get_Caption(window, &caption);
2392 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2393
2394 caption = SysAllocString(L"foo");
2395 hr = IVideoWindow_put_Caption(window, caption);
2396 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2397 SysFreeString(caption);
2398
2399 hr = IVideoWindow_get_WindowStyle(window, &l);
2400 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2401
2402 hr = IVideoWindow_put_WindowStyle(window, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
2403 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2404
2405 hr = IVideoWindow_get_AutoShow(window, &l);
2406 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2407
2408 hr = IVideoWindow_put_AutoShow(window, OAFALSE);
2409 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2410
2411 hr = IVideoWindow_put_Owner(window, (OAHWND)our_hwnd);
2412 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2413
2414 hr = IVideoWindow_put_MessageDrain(window, (OAHWND)our_hwnd);
2415 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2416
2417 hr = IVideoWindow_put_Visible(window, OATRUE);
2418 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2419
2420 hr = IVideoWindow_SetWindowPosition(window, 100, 200, 300, 400);
2421 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2422
2424 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
2425 IFilterGraph2_AddFilter(graph, filter, NULL);
2426 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
2427 if (hr == VFW_E_TYPE_NOT_ACCEPTED) /* w7u */
2428 {
2429 req_mt.subtype = MEDIASUBTYPE_RGB24;
2430 vih.bmiHeader.biBitCount = 24;
2431 req_props.cbBuffer = 32 * 16 * 3;
2432 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
2433 }
2434 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2435
2436 hr = IMemInputPin_GetAllocator(input, &allocator);
2437 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
2438 if (hr == S_OK)
2439 {
2440 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
2441 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2442 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
2443 hr = IMemAllocator_Commit(allocator);
2444 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2445 IMemAllocator_Release(allocator);
2446 }
2447
2449 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2450
2458
2459 hr = IVideoWindow_put_FullScreenMode(window, OATRUE);
2460 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2461 hr = IVideoWindow_get_FullScreenMode(window, &l);
2462 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2463
2464 hr = IVideoWindow_GetMinIdealImageSize(window, &width, &height);
2465 todo_wine ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
2466 hr = IVideoWindow_GetMaxIdealImageSize(window, &width, &height);
2467 todo_wine ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
2468
2469 IVideoWindow_Release(window);
2470
2471 hr = IFilterGraph2_QueryInterface(graph, &IID_IVideoWindow, (void **)&window);
2472 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2473
2474 l = 0xdeadbeef;
2475 hr = IVideoWindow_get_FullScreenMode(window, &l);
2476 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2477 ok(l == OAFALSE, "Got fullscreenmode %ld.\n", l);
2478 hr = IVideoWindow_put_FullScreenMode(window, l);
2479 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2480
2481 IFilterGraph2_Release(graph);
2482 IVideoWindow_Release(window);
2483 IOverlay_Release(overlay);
2484 IMemInputPin_Release(input);
2485 IPin_Release(pin);
2486 ref = IBaseFilter_Release(filter);
2487 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2488 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
2489 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2490 DestroyWindow(our_hwnd);
2491}
2492
2493static void check_source_position_(int line, IBasicVideo *video,
2494 LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
2495{
2496 LONG left, top, width, height, l;
2497 HRESULT hr;
2498
2499 left = top = width = height = 0xdeadbeef;
2500 hr = IBasicVideo_GetSourcePosition(video, &left, &top, &width, &height);
2501 ok_(__FILE__,line)(hr == S_OK, "Got hr %#lx.\n", hr);
2502 ok_(__FILE__,line)(left == expect_left, "Got left %ld.\n", left);
2503 ok_(__FILE__,line)(top == expect_top, "Got top %ld.\n", top);
2504 ok_(__FILE__,line)(width == expect_width, "Got width %ld.\n", width);
2505 ok_(__FILE__,line)(height == expect_height, "Got height %ld.\n", height);
2506
2507 l = 0xdeadbeef;
2508 hr = IBasicVideo_get_SourceLeft(video, &l);
2509 ok_(__FILE__,line)(hr == S_OK, "Failed to get left, hr %#lx.\n", hr);
2510 ok_(__FILE__,line)(l == left, "Got left %ld.\n", l);
2511
2512 l = 0xdeadbeef;
2513 hr = IBasicVideo_get_SourceTop(video, &l);
2514 ok_(__FILE__,line)(hr == S_OK, "Failed to get top, hr %#lx.\n", hr);
2515 ok_(__FILE__,line)(l == top, "Got top %ld.\n", l);
2516
2517 l = 0xdeadbeef;
2518 hr = IBasicVideo_get_SourceWidth(video, &l);
2519 ok_(__FILE__,line)(hr == S_OK, "Failed to get width, hr %#lx.\n", hr);
2520 ok_(__FILE__,line)(l == width, "Got width %ld.\n", l);
2521
2522 l = 0xdeadbeef;
2523 hr = IBasicVideo_get_SourceHeight(video, &l);
2524 ok_(__FILE__,line)(hr == S_OK, "Failed to get height, hr %#lx.\n", hr);
2525 ok_(__FILE__,line)(l == height, "Got height %ld.\n", l);
2526}
2527#define check_source_position(a,b,c,d,e) check_source_position_(__LINE__,a,b,c,d,e)
2528
2529static void test_basic_video_source(IBasicVideo *video)
2530{
2531 HRESULT hr;
2532
2533 check_source_position(video, 0, 0, 600, 400);
2534 hr = IBasicVideo_IsUsingDefaultSource(video);
2535 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2536
2537 hr = IBasicVideo_put_SourceLeft(video, -10);
2538 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2539 hr = IBasicVideo_put_SourceLeft(video, 10);
2540 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2541
2542 hr = IBasicVideo_put_SourceTop(video, -10);
2543 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2544 hr = IBasicVideo_put_SourceTop(video, 10);
2545 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2546
2547 hr = IBasicVideo_put_SourceWidth(video, -500);
2548 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2549 hr = IBasicVideo_put_SourceWidth(video, 0);
2550 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2551 hr = IBasicVideo_put_SourceWidth(video, 700);
2552 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2553 hr = IBasicVideo_put_SourceWidth(video, 500);
2554 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2555 check_source_position(video, 0, 0, 500, 400);
2556 hr = IBasicVideo_IsUsingDefaultSource(video);
2557 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2558
2559 hr = IBasicVideo_put_SourceHeight(video, -300);
2560 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2561 hr = IBasicVideo_put_SourceHeight(video, 0);
2562 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2563 hr = IBasicVideo_put_SourceHeight(video, 600);
2564 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2565 hr = IBasicVideo_put_SourceHeight(video, 300);
2566 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2567 check_source_position(video, 0, 0, 500, 300);
2568 hr = IBasicVideo_IsUsingDefaultSource(video);
2569 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2570
2571 hr = IBasicVideo_put_SourceLeft(video, -10);
2572 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2573 hr = IBasicVideo_put_SourceLeft(video, 10);
2574 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2575 check_source_position(video, 10, 0, 500, 300);
2576 hr = IBasicVideo_IsUsingDefaultSource(video);
2577 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2578
2579 hr = IBasicVideo_put_SourceTop(video, -10);
2580 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2581 hr = IBasicVideo_put_SourceTop(video, 20);
2582 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2583 check_source_position(video, 10, 20, 500, 300);
2584 hr = IBasicVideo_IsUsingDefaultSource(video);
2585 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2586
2587 hr = IBasicVideo_SetSourcePosition(video, 4, 5, 60, 40);
2588 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2589 check_source_position(video, 4, 5, 60, 40);
2590 hr = IBasicVideo_IsUsingDefaultSource(video);
2591 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2592
2593 hr = IBasicVideo_SetSourcePosition(video, 0, 0, 600, 400);
2594 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2595 check_source_position(video, 0, 0, 600, 400);
2596 hr = IBasicVideo_IsUsingDefaultSource(video);
2597 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2598
2599 hr = IBasicVideo_SetSourcePosition(video, 4, 5, 60, 40);
2600 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2601 hr = IBasicVideo_SetDefaultSourcePosition(video);
2602 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2603 check_source_position(video, 0, 0, 600, 400);
2604 hr = IBasicVideo_IsUsingDefaultSource(video);
2605 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2606}
2607
2608static void check_destination_position_(int line, IBasicVideo *video,
2609 LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
2610{
2611 LONG left, top, width, height, l;
2612 HRESULT hr;
2613
2614 left = top = width = height = 0xdeadbeef;
2615 hr = IBasicVideo_GetDestinationPosition(video, &left, &top, &width, &height);
2616 ok_(__FILE__,line)(hr == S_OK, "Failed to get position, hr %#lx.\n", hr);
2617 ok_(__FILE__,line)(left == expect_left, "Got left %ld.\n", left);
2618 ok_(__FILE__,line)(top == expect_top, "Got top %ld.\n", top);
2619 ok_(__FILE__,line)(width == expect_width, "Got width %ld.\n", width);
2620 ok_(__FILE__,line)(height == expect_height, "Got height %ld.\n", height);
2621
2622 l = 0xdeadbeef;
2623 hr = IBasicVideo_get_DestinationLeft(video, &l);
2624 ok_(__FILE__,line)(hr == S_OK, "Failed to get left, hr %#lx.\n", hr);
2625 ok_(__FILE__,line)(l == left, "Got left %ld.\n", l);
2626
2627 l = 0xdeadbeef;
2628 hr = IBasicVideo_get_DestinationTop(video, &l);
2629 ok_(__FILE__,line)(hr == S_OK, "Failed to get top, hr %#lx.\n", hr);
2630 ok_(__FILE__,line)(l == top, "Got top %ld.\n", l);
2631
2632 l = 0xdeadbeef;
2633 hr = IBasicVideo_get_DestinationWidth(video, &l);
2634 ok_(__FILE__,line)(hr == S_OK, "Failed to get width, hr %#lx.\n", hr);
2635 ok_(__FILE__,line)(l == width, "Got width %ld.\n", l);
2636
2637 l = 0xdeadbeef;
2638 hr = IBasicVideo_get_DestinationHeight(video, &l);
2639 ok_(__FILE__,line)(hr == S_OK, "Failed to get height, hr %#lx.\n", hr);
2640 ok_(__FILE__,line)(l == height, "Got height %ld.\n", l);
2641}
2642#define check_destination_position(a,b,c,d,e) check_destination_position_(__LINE__,a,b,c,d,e)
2643
2644static void test_basic_video_destination(IBasicVideo *video)
2645{
2646 IVideoWindow *window;
2647 HRESULT hr;
2648 RECT rect;
2649
2650 IBasicVideo_QueryInterface(video, &IID_IVideoWindow, (void **)&window);
2651
2652 check_destination_position(video, 0, 0, 600, 400);
2653 hr = IBasicVideo_IsUsingDefaultDestination(video);
2654 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2655
2656 hr = IBasicVideo_put_DestinationLeft(video, -10);
2657 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2658 check_destination_position(video, -10, 0, 600, 400);
2659 hr = IBasicVideo_IsUsingDefaultDestination(video);
2660 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2661
2662 hr = IBasicVideo_put_DestinationLeft(video, 10);
2663 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2664 check_destination_position(video, 10, 0, 600, 400);
2665 hr = IBasicVideo_IsUsingDefaultDestination(video);
2666 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2667
2668 hr = IBasicVideo_put_DestinationTop(video, -20);
2669 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2670 check_destination_position(video, 10, -20, 600, 400);
2671 hr = IBasicVideo_IsUsingDefaultDestination(video);
2672 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2673
2674 hr = IBasicVideo_put_DestinationTop(video, 20);
2675 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2676 check_destination_position(video, 10, 20, 600, 400);
2677 hr = IBasicVideo_IsUsingDefaultDestination(video);
2678 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2679
2680 hr = IBasicVideo_put_DestinationWidth(video, -700);
2681 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2682 hr = IBasicVideo_put_DestinationWidth(video, 0);
2683 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2684 hr = IBasicVideo_put_DestinationWidth(video, 700);
2685 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2686 check_destination_position(video, 10, 20, 700, 400);
2687 hr = IBasicVideo_IsUsingDefaultDestination(video);
2688 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2689
2690 hr = IBasicVideo_put_DestinationWidth(video, 500);
2691 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2692 check_destination_position(video, 10, 20, 500, 400);
2693 hr = IBasicVideo_IsUsingDefaultDestination(video);
2694 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2695
2696 hr = IBasicVideo_put_DestinationHeight(video, -500);
2697 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2698 hr = IBasicVideo_put_DestinationHeight(video, 0);
2699 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2700 hr = IBasicVideo_put_DestinationHeight(video, 500);
2701 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2702 check_destination_position(video, 10, 20, 500, 500);
2703 hr = IBasicVideo_IsUsingDefaultDestination(video);
2704 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2705
2706 hr = IBasicVideo_put_DestinationHeight(video, 300);
2707 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2708 check_destination_position(video, 10, 20, 500, 300);
2709 hr = IBasicVideo_IsUsingDefaultDestination(video);
2710 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2711
2712 hr = IBasicVideo_SetDestinationPosition(video, 4, 5, 60, 40);
2713 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2714 check_destination_position(video, 4, 5, 60, 40);
2715 hr = IBasicVideo_IsUsingDefaultDestination(video);
2716 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2717
2718 hr = IBasicVideo_SetDestinationPosition(video, 0, 0, 600, 400);
2719 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2720 check_destination_position(video, 0, 0, 600, 400);
2721 hr = IBasicVideo_IsUsingDefaultDestination(video);
2722 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2723
2724 hr = IBasicVideo_SetDestinationPosition(video, 4, 5, 60, 40);
2725 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2726 hr = IBasicVideo_SetDefaultDestinationPosition(video);
2727 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2728 check_destination_position(video, 0, 0, 600, 400);
2729 hr = IBasicVideo_IsUsingDefaultDestination(video);
2730 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2731
2732 SetRect(&rect, 100, 200, 500, 500);
2734 hr = IVideoWindow_SetWindowPosition(window, rect.left, rect.top,
2736 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2737 check_destination_position(video, 0, 0, 400, 300);
2738 hr = IBasicVideo_IsUsingDefaultDestination(video);
2739 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2740
2741 hr = IBasicVideo_SetDestinationPosition(video, 0, 0, 400, 300);
2742 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2743 check_destination_position(video, 0, 0, 400, 300);
2744 hr = IBasicVideo_IsUsingDefaultDestination(video);
2745 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2746
2747 SetRect(&rect, 100, 200, 600, 600);
2749 hr = IVideoWindow_SetWindowPosition(window, rect.left, rect.top,
2751 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2752 check_destination_position(video, 0, 0, 400, 300);
2753 hr = IBasicVideo_IsUsingDefaultDestination(video);
2754 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2755
2756 IVideoWindow_Release(window);
2757}
2758
2759static void test_basic_video(void)
2760{
2761 ALLOCATOR_PROPERTIES req_props = {1, 600 * 400 * 4, 1, 0}, ret_props;
2762 VIDEOINFOHEADER vih =
2763 {
2764 .AvgTimePerFrame = 200000,
2765 .rcSource = {4, 6, 16, 12},
2766 .rcTarget = {40, 60, 120, 160},
2767 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
2768 .bmiHeader.biBitCount = 32,
2769 .bmiHeader.biWidth = 600,
2770 .bmiHeader.biHeight = 400,
2771 .bmiHeader.biPlanes = 1,
2772 .bmiHeader.biCompression = BI_RGB,
2773 };
2774 AM_MEDIA_TYPE req_mt =
2775 {
2776 .majortype = MEDIATYPE_Video,
2777 .subtype = MEDIASUBTYPE_RGB32,
2778 .formattype = FORMAT_VideoInfo,
2779 .cbFormat = sizeof(vih),
2780 .pbFormat = (BYTE *)&vih,
2781 };
2784 LONG left, top, width, height, l;
2785 struct testfilter source;
2789 IBasicVideo *video;
2790 TYPEATTR *typeattr;
2791 REFTIME reftime;
2792 HRESULT hr;
2793 UINT count;
2794 ULONG ref;
2795 IPin *pin;
2796 RECT rect;
2797
2798 IBaseFilter_QueryInterface(filter, &IID_IBasicVideo, (void **)&video);
2799 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
2800 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
2801
2802 hr = IBasicVideo_GetTypeInfoCount(video, &count);
2803 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2804 ok(count == 1, "Got count %u.\n", count);
2805
2806 hr = IBasicVideo_GetTypeInfo(video, 0, 0, &typeinfo);
2807 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2808 hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
2809 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2810 ok(typeattr->typekind == TKIND_DISPATCH, "Got kind %u.\n", typeattr->typekind);
2811 ok(IsEqualGUID(&typeattr->guid, &IID_IBasicVideo), "Got IID %s.\n", wine_dbgstr_guid(&typeattr->guid));
2812 ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
2813 ITypeInfo_Release(typeinfo);
2814
2815 hr = IBasicVideo_get_AvgTimePerFrame(video, NULL);
2816 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2817 hr = IBasicVideo_get_AvgTimePerFrame(video, &reftime);
2818 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2819
2820 hr = IBasicVideo_get_BitRate(video, NULL);
2821 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2822 hr = IBasicVideo_get_BitRate(video, &l);
2823 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2824
2825 hr = IBasicVideo_get_BitErrorRate(video, NULL);
2826 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2827 hr = IBasicVideo_get_BitErrorRate(video, &l);
2828 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2829
2830 hr = IBasicVideo_get_VideoWidth(video, NULL);
2831 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2832 hr = IBasicVideo_get_VideoHeight(video, NULL);
2833 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2834
2835 hr = IBasicVideo_get_SourceLeft(video, NULL);
2836 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2837 hr = IBasicVideo_get_SourceWidth(video, NULL);
2838 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2839 hr = IBasicVideo_get_SourceTop(video, NULL);
2840 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2841 hr = IBasicVideo_get_SourceHeight(video, NULL);
2842 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2843
2844 hr = IBasicVideo_get_DestinationLeft(video, NULL);
2845 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2846 hr = IBasicVideo_get_DestinationWidth(video, NULL);
2847 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2848 hr = IBasicVideo_get_DestinationTop(video, NULL);
2849 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2850 hr = IBasicVideo_get_DestinationHeight(video, NULL);
2851 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2852
2853 hr = IBasicVideo_GetSourcePosition(video, NULL, &top, &width, &height);
2854 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2855 hr = IBasicVideo_GetSourcePosition(video, &left, NULL, &width, &height);
2856 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2857 hr = IBasicVideo_GetSourcePosition(video, &left, &top, NULL, &height);
2858 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2859 hr = IBasicVideo_GetSourcePosition(video, &left, &top, &width, NULL);
2860 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2861
2862 hr = IBasicVideo_GetDestinationPosition(video, NULL, &top, &width, &height);
2863 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2864 hr = IBasicVideo_GetDestinationPosition(video, &left, NULL, &width, &height);
2865 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2866 hr = IBasicVideo_GetDestinationPosition(video, &left, &top, NULL, &height);
2867 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2868 hr = IBasicVideo_GetDestinationPosition(video, &left, &top, &width, NULL);
2869 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2870
2871 hr = IBasicVideo_GetVideoSize(video, &width, NULL);
2872 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2873 hr = IBasicVideo_GetVideoSize(video, NULL, &height);
2874 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2875 hr = IBasicVideo_GetVideoSize(video, &width, &height);
2876 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2877
2878 hr = IBasicVideo_GetVideoPaletteEntries(video, 0, 1, NULL, &l);
2879 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2880 hr = IBasicVideo_GetVideoPaletteEntries(video, 0, 1, &l, NULL);
2881 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2882
2884 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, L"vmr9");
2885 IFilterGraph2_AddFilter(graph, filter, L"source");
2886 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
2887 if (hr == E_FAIL)
2888 {
2889 skip("Got E_FAIL when connecting.\n");
2890 goto out;
2891 }
2892 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2893
2894 hr = IMemInputPin_GetAllocator(input, &allocator);
2895 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
2896 if (hr == S_OK)
2897 {
2898 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
2899 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2900 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
2901 hr = IMemAllocator_Commit(allocator);
2902 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2903 IMemAllocator_Release(allocator);
2904 }
2905
2906 reftime = 0.0;
2907 hr = IBasicVideo_get_AvgTimePerFrame(video, &reftime);
2908 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2909 ok(compare_double(reftime, 0.02, 1 << 28), "Got frame rate %.16e.\n", reftime);
2910
2911 l = 0xdeadbeef;
2912 hr = IBasicVideo_get_BitRate(video, &l);
2913 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2914 ok(!l, "Got bit rate %ld.\n", l);
2915
2916 l = 0xdeadbeef;
2917 hr = IBasicVideo_get_BitErrorRate(video, &l);
2918 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2919 ok(!l, "Got bit rate %ld.\n", l);
2920
2921 hr = IBasicVideo_GetVideoPaletteEntries(video, 0, 1, &l, NULL);
2922 todo_wine ok(hr == VFW_E_NO_PALETTE_AVAILABLE, "Got hr %#lx.\n", hr);
2923
2924 width = height = 0xdeadbeef;
2925 hr = IBasicVideo_GetVideoSize(video, &width, &height);
2926 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2927 ok(width == 600, "Got width %ld.\n", width);
2928 ok(height == 400, "Got height %ld.\n", height);
2929
2932
2933 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
2934 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2935 hr = IFilterGraph2_Disconnect(graph, pin);
2936 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2937
2938 vih.bmiHeader.biWidth = 16;
2939 vih.bmiHeader.biHeight = 16;
2940 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
2941 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2942
2943 hr = IMemInputPin_GetAllocator(input, &allocator);
2944 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
2945 if (hr == S_OK)
2946 {
2947 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
2948 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2949 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
2950 hr = IMemAllocator_Commit(allocator);
2951 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2952 IMemAllocator_Release(allocator);
2953 }
2954
2955 check_source_position(video, 0, 0, 16, 16);
2956
2957 SetRect(&rect, 0, 0, 0, 0);
2961
2962out:
2963 ref = IFilterGraph2_Release(graph);
2964 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2965 IBasicVideo_Release(video);
2966 IMemInputPin_Release(input);
2967 IPin_Release(pin);
2968 ref = IBaseFilter_Release(filter);
2969 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2970 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
2971 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2972}
2973
2974static void test_windowless_size(void)
2975{
2976 ALLOCATOR_PROPERTIES req_props = {1, 32 * 16 * 4, 1, 0}, ret_props;
2977 VIDEOINFOHEADER vih =
2978 {
2980 .bmiHeader.biWidth = 32,
2981 .bmiHeader.biHeight = 16,
2982 .bmiHeader.biBitCount = 32,
2983 .bmiHeader.biPlanes = 1,
2984 };
2986 {
2987 .majortype = MEDIATYPE_Video,
2988 .subtype = MEDIASUBTYPE_RGB32,
2989 .formattype = FORMAT_VideoInfo,
2990 .cbFormat = sizeof(vih),
2991 .pbFormat = (BYTE *)&vih,
2992 };
2994 LONG width, height, aspect_width, aspect_height;
2995 IVMRWindowlessControl *windowless_control;
2997 struct testfilter source;
2999 RECT src, dst, expect;
3001 HWND window;
3002 HRESULT hr;
3003 ULONG ref;
3004 IPin *pin;
3005
3006 IBaseFilter_QueryInterface(filter, &IID_IVMRWindowlessControl, (void **)&windowless_control);
3007 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
3008 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
3010 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source");
3011 IFilterGraph2_AddFilter(graph, filter, L"vmr7");
3012 window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0);
3013 ok(!!window, "Failed to create a window.\n");
3014
3015 hr = IVMRWindowlessControl_SetVideoClippingWindow(windowless_control, window);
3016 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3017
3018 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &mt);
3019 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3020 hr = IMemInputPin_GetAllocator(input, &allocator);
3021 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
3022 if (hr == S_OK)
3023 {
3024 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
3025 IMemAllocator_Release(allocator);
3026 if (hr == E_FAIL)
3027 {
3028 skip("Got E_FAIL when setting allocator properties.\n");
3029 goto out;
3030 }
3031 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3032 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
3033 }
3034
3035 hr = IVMRWindowlessControl_GetNativeVideoSize(windowless_control, NULL, &height, &aspect_width, &aspect_height);
3036 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3037 hr = IVMRWindowlessControl_GetNativeVideoSize(windowless_control, &width, NULL, &aspect_width, &aspect_height);
3038 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
3039
3040 width = height = 0xdeadbeef;
3041 hr = IVMRWindowlessControl_GetNativeVideoSize(windowless_control, &width, &height, NULL, NULL);
3042 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3043 ok(width == 32, "Got width %ld.\n", width);
3044 ok(height == 16, "Got height %ld.\n", height);
3045
3046 aspect_width = aspect_height = 0xdeadbeef;
3047 hr = IVMRWindowlessControl_GetNativeVideoSize(windowless_control, &width, &height, &aspect_width, &aspect_height);
3048 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3049 ok(aspect_width == 32, "Got width %ld.\n", aspect_width);
3050 ok(aspect_height == 16, "Got height %ld.\n", aspect_height);
3051
3052 memset(&src, 0xcc, sizeof(src));
3053 hr = IVMRWindowlessControl_GetVideoPosition(windowless_control, &src, NULL);
3054 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3055 SetRect(&expect, 0, 0, 32, 16);
3056 ok(EqualRect(&src, &expect), "Got source rect %s.\n", wine_dbgstr_rect(&src));
3057
3058 memset(&dst, 0xcc, sizeof(dst));
3059 hr = IVMRWindowlessControl_GetVideoPosition(windowless_control, NULL, &dst);
3060 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3061 SetRect(&expect, 0, 0, 0, 0);
3062 ok(EqualRect(&dst, &expect), "Got dest rect %s.\n", wine_dbgstr_rect(&dst));
3063
3064 SetRect(&src, 4, 6, 16, 12);
3065 hr = IVMRWindowlessControl_SetVideoPosition(windowless_control, &src, NULL);
3066 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3067
3068 memset(&src, 0xcc, sizeof(src));
3069 memset(&dst, 0xcc, sizeof(dst));
3070 hr = IVMRWindowlessControl_GetVideoPosition(windowless_control, &src, &dst);
3071 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3072 SetRect(&expect, 4, 6, 16, 12);
3073 ok(EqualRect(&src, &expect), "Got source rect %s.\n", wine_dbgstr_rect(&src));
3074 SetRect(&expect, 0, 0, 0, 0);
3075 ok(EqualRect(&dst, &expect), "Got dest rect %s.\n", wine_dbgstr_rect(&dst));
3076
3077 SetRect(&dst, 40, 60, 120, 160);
3078 hr = IVMRWindowlessControl_SetVideoPosition(windowless_control, NULL, &dst);
3079 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3080
3081 memset(&src, 0xcc, sizeof(src));
3082 memset(&dst, 0xcc, sizeof(dst));
3083 hr = IVMRWindowlessControl_GetVideoPosition(windowless_control, &src, &dst);
3084 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3085 SetRect(&expect, 4, 6, 16, 12);
3086 ok(EqualRect(&src, &expect), "Got source rect %s.\n", wine_dbgstr_rect(&src));
3087 SetRect(&expect, 40, 60, 120, 160);
3088 ok(EqualRect(&dst, &expect), "Got dest rect %s.\n", wine_dbgstr_rect(&dst));
3089
3091 SetRect(&expect, 0, 0, 640, 480);
3092 ok(EqualRect(&src, &expect), "Got window rect %s.\n", wine_dbgstr_rect(&src));
3093
3094out:
3095 ref = IFilterGraph2_Release(graph);
3096 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3097 IMemInputPin_Release(input);
3098 IPin_Release(pin);
3099 IVMRWindowlessControl_Release(windowless_control);
3100 ref = IBaseFilter_Release(filter);
3101 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3103}
3104
3105static void test_unconnected_eos(void)
3106{
3109 IMediaControl *control;
3110 IMediaEvent *eventsrc;
3111 unsigned int ret;
3112 HRESULT hr;
3113 ULONG ref;
3114
3115 hr = IFilterGraph2_AddFilter(graph, filter, L"renderer");
3116 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3117
3118 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
3119 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3120
3121 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&eventsrc);
3122 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3123
3124 ret = check_ec_complete(eventsrc, 0);
3125 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
3126
3127 hr = IMediaControl_Pause(control);
3128 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3129
3130 ret = check_ec_complete(eventsrc, 0);
3131 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
3132
3133 hr = IMediaControl_Run(control);
3134 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3135
3136 ret = check_ec_complete(eventsrc, 0);
3137 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
3138
3139 hr = IMediaControl_Pause(control);
3140 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3141
3142 ret = check_ec_complete(eventsrc, 0);
3143 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
3144
3145 hr = IMediaControl_Run(control);
3146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3147
3148 ret = check_ec_complete(eventsrc, 0);
3149 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
3150
3151 hr = IMediaControl_Stop(control);
3152 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3153
3154 ret = check_ec_complete(eventsrc, 0);
3155 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
3156
3157 hr = IMediaControl_Run(control);
3158 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3159
3160 ret = check_ec_complete(eventsrc, 0);
3161 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
3162
3163 IMediaControl_Release(control);
3164 IMediaEvent_Release(eventsrc);
3165 ref = IFilterGraph2_Release(graph);
3166 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3167 ref = IBaseFilter_Release(filter);
3168 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3169}
3170
3172{
3173 DDSURFACEDESC2 desc = {.dwSize = sizeof(desc)};
3175 HRESULT hr;
3176
3177 if (FAILED(DirectDrawCreateEx(NULL, (void **)&ddraw, &IID_IDirectDraw7, NULL)))
3178 return NULL;
3179
3180 hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL);
3181 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3182
3183 return ddraw;
3184}
3185
3187{
3191
3195
3199};
3200
3202{
3204}
3205
3207{
3209 return IVMRSurfaceAllocator_QueryInterface(&presenter->IVMRSurfaceAllocator_iface, iid, out);
3210}
3211
3213{
3215 return IVMRSurfaceAllocator_AddRef(&presenter->IVMRSurfaceAllocator_iface);
3216}
3217
3219{
3221 return IVMRSurfaceAllocator_Release(&presenter->IVMRSurfaceAllocator_iface);
3222}
3223
3225{
3226 if (winetest_debug > 1) trace("StartPresenting()\n");
3227 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
3228 return E_NOTIMPL;
3229}
3230
3232{
3233 if (winetest_debug > 1) trace("StopPresenting()\n");
3234 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
3235 return E_NOTIMPL;
3236}
3237
3239{
3241 static const RECT rect;
3242
3243 if (winetest_debug > 1) trace("PresentImage(surface %p)\n", info->lpSurf);
3244
3245 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
3246 ok(info->dwFlags == VMRSample_TimeValid, "Got flags %#lx.\n", info->dwFlags);
3247 todo_wine ok(info->lpSurf == presenter->surfaces[5 - presenter->got_PresentImage], "Got unexpected surface.\n");
3248 ok(!info->rtStart, "Got start time %s.\n", wine_dbgstr_longlong(info->rtStart));
3249 ok(info->rtEnd == 10000000, "Got end time %s.\n", wine_dbgstr_longlong(info->rtEnd));
3250 todo_wine ok(info->szAspectRatio.cx == 120, "Got aspect ratio width %ld.\n", info->szAspectRatio.cx);
3251 todo_wine ok(info->szAspectRatio.cy == 60, "Got aspect ratio height %ld.\n", info->szAspectRatio.cy);
3252 ok(EqualRect(&info->rcSrc, &rect), "Got source rect %s.\n", wine_dbgstr_rect(&info->rcSrc));
3253 ok(EqualRect(&info->rcDst, &rect), "Got dest rect %s.\n", wine_dbgstr_rect(&info->rcDst));
3254 ok(!info->dwTypeSpecificFlags, "Got type-specific flags %#lx.\n", info->dwTypeSpecificFlags);
3255 ok(!info->dwInterlaceFlags, "Got interlace flags %#lx.\n", info->dwInterlaceFlags);
3256
3259 "Got %u calls to PrepareSurface(); %u calls to PresentImage().\n",
3261
3262 return S_OK;
3263}
3264
3265static const IVMRImagePresenterVtbl presenter_vtbl =
3266{
3273};
3274
3276{
3278}
3279
3281{
3283
3284 if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
3285
3286 if (IsEqualGUID(iid, &IID_IVMRImagePresenter))
3287 {
3289 IVMRImagePresenter_AddRef(&presenter->IVMRImagePresenter_iface);
3290 return S_OK;
3291 }
3292 ok(!IsEqualGUID(iid, &IID_IVMRSurfaceAllocatorEx9), "Unexpected query for IVMRSurfaceAllocatorEx9.\n");
3293 *out = NULL;
3294 return E_NOTIMPL;
3295}
3296
3298{
3301}
3302
3304{
3307}
3308
3311{
3313 DDSURFACEDESC2 surface_desc = {.dwSize = sizeof(surface_desc)};
3314 HRESULT hr;
3315
3316 if (winetest_debug > 1) trace("AllocateSurface()\n");
3317
3318 ok(!presenter->surfaces[0], "Surface should not already exist.\n");
3319
3320 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
3321 ok(info->dwFlags == (AMAP_DIRECTED_FLIP | AMAP_ALLOW_SYSMEM), "Got flags %#lx.\n", info->dwFlags);
3322 todo_wine ok(info->dwMinBuffers == 5, "Got minimum buffer count %lu.\n", info->dwMinBuffers);
3323 todo_wine ok(info->dwMaxBuffers == 5, "Got maximum buffer count %lu.\n", info->dwMaxBuffers);
3324 ok(!info->dwInterlaceFlags, "Got interlace flags %#lx.\n", info->dwInterlaceFlags);
3325 todo_wine ok(info->szAspectRatio.cx == 120, "Got aspect ratio width %ld.\n", info->szAspectRatio.cx);
3326 todo_wine ok(info->szAspectRatio.cy == 60, "Got aspect ratio height %ld.\n", info->szAspectRatio.cy);
3327 ok(info->szNativeSize.cx == 32, "Got native width %ld.\n", info->szNativeSize.cx);
3328 ok(info->szNativeSize.cy == 16, "Got native height %ld.\n", info->szNativeSize.cy);
3329 todo_wine ok(*buffer_count == 5, "Got buffer count %lu.\n", *buffer_count);
3330 ok(!info->lpPixFmt, "Got pixel format %p.\n", info->lpPixFmt);
3331
3332 presenter->format = *info->lpHdr;
3333
3335 surface_desc.dwWidth = presenter->format.biWidth;
3336 surface_desc.dwHeight = presenter->format.biHeight;
3337 surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
3339 surface_desc.dwBackBufferCount = *buffer_count;
3340
3342 {
3343 surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
3344 surface_desc.ddpfPixelFormat.dwRGBBitCount = 32;
3345 surface_desc.ddpfPixelFormat.dwRBitMask = 0x00ff0000;
3346 surface_desc.ddpfPixelFormat.dwGBitMask = 0x0000ff00;
3347 surface_desc.ddpfPixelFormat.dwBBitMask = 0x000000ff;
3348 }
3349 else
3350 {
3351 surface_desc.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
3353 }
3354
3355 hr = IDirectDraw7_CreateSurface(presenter->ddraw, &surface_desc, surface, NULL);
3356 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3357 presenter->surfaces[0] = *surface;
3359 for (unsigned int i = 0; i < *buffer_count; ++i)
3360 {
3361 DDSCAPS2 caps = {.dwCaps = DDSCAPS_FLIP};
3362
3363 hr = IDirectDrawSurface7_GetAttachedSurface(presenter->surfaces[i], &caps, &presenter->surfaces[i + 1]);
3364 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3365 }
3366
3367 ++*buffer_count;
3368 return S_OK;
3369}
3370
3372{
3374 LONG ref;
3375
3376 if (winetest_debug > 1) trace("FreeSurface()\n");
3377
3378 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
3379 ok(!!presenter->surfaces[0], "Surface should exist.\n");
3380
3381 for (unsigned int i = 0; i < presenter->surface_count; ++i)
3382 IDirectDrawSurface7_Release(presenter->surfaces[i + 1]);
3383 ref = IDirectDrawSurface7_Release(presenter->surfaces[0]);
3384 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3386
3387 return E_NOTIMPL;
3388}
3389
3392{
3394
3395 if (winetest_debug > 1) trace("PrepareSurface(surface %p)\n", surface);
3396 ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie);
3397 ok(!flags, "Got flags %#lx.\n", flags);
3398 todo_wine ok(surface == presenter->surfaces[5 - presenter->got_PrepareSurface], "Got unexpected surface.\n");
3400
3401 return S_OK;
3402}
3403
3405{
3406 ok(0, "Unexpected call.\n");
3407 return E_NOTIMPL;
3408}
3409
3410static const IVMRSurfaceAllocatorVtbl allocator_vtbl =
3411{
3419};
3420
3423{
3424 IMediaControl *control;
3425 OAFilterState state;
3426 HANDLE thread;
3427 HRESULT hr;
3428
3429 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
3430
3433
3434 hr = IMediaControl_Pause(control);
3435 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
3437 hr = IMediaControl_GetState(control, 1000, &state);
3438 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3439 ok(presenter->got_PrepareSurface == 1, "Got %u calls to PrepareSurface().\n", presenter->got_PrepareSurface);
3440 ok(presenter->got_PresentImage == 1, "Got %u calls to PresentImage().\n", presenter->got_PresentImage);
3441
3442 hr = IMediaControl_Run(control);
3443 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3445 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3446 ok(presenter->got_PrepareSurface == 1, "Got %u calls to PrepareSurface().\n", presenter->got_PrepareSurface);
3447 ok(presenter->got_PresentImage == 1, "Got %u calls to PresentImage().\n", presenter->got_PresentImage);
3448
3451 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3452 ok(presenter->got_PrepareSurface == 2, "Got %u calls to PrepareSurface().\n", presenter->got_PrepareSurface);
3453 ok(presenter->got_PresentImage == 2, "Got %u calls to PresentImage().\n", presenter->got_PresentImage);
3454
3455 hr = IMediaControl_Stop(control);
3456 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3457
3458 IMediaControl_Release(control);
3459}
3460
3462{
3463 VIDEOINFOHEADER vih =
3464 {
3465 .rcSource = {4, 6, 16, 12},
3466 .rcTarget = {40, 60, 160, 120},
3467 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
3468 .bmiHeader.biWidth = 32,
3469 .bmiHeader.biHeight = 16,
3470 .bmiHeader.biPlanes = 1,
3471 };
3472 AM_MEDIA_TYPE req_mt =
3473 {
3474 .majortype = MEDIATYPE_Video,
3475 .subtype = MEDIASUBTYPE_WAVE,
3476 .formattype = FORMAT_VideoInfo,
3477 .cbFormat = sizeof(vih),
3478 .pbFormat = (BYTE *)&vih,
3479 };
3480 ALLOCATOR_PROPERTIES req_props = {5, 32 * 16 * 4, 1, 0}, ret_props;
3481 struct presenter presenter =
3482 {
3484 .IVMRImagePresenter_iface.lpVtbl = &presenter_vtbl,
3485 .refcount = 1,
3486 };
3487 struct presenter presenter2 = presenter;
3489 RECT rect = {0, 0, 640, 480};
3490 struct testfilter source;
3496 unsigned int i;
3497 HWND window;
3498 HRESULT hr;
3499 ULONG ref;
3500 IPin *pin;
3501
3502 static const struct
3503 {
3504 const GUID *subtype;
3505 WORD depth;
3507 }
3508 tests[] =
3509 {
3510 {&MEDIASUBTYPE_RGB32, 32, BI_RGB},
3511 {&MEDIASUBTYPE_NV12, 12, mmioFOURCC('N','V','1','2')},
3512 {&MEDIASUBTYPE_YV12, 12, mmioFOURCC('Y','V','1','2')},
3513 {&MEDIASUBTYPE_UYVY, 16, mmioFOURCC('U','Y','V','Y')},
3514 {&MEDIASUBTYPE_YUY2, 16, mmioFOURCC('Y','U','Y','2')},
3515 };
3516
3518 window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0,
3520 if (!(ddraw = create_ddraw(window)))
3521 {
3523 return;
3524 }
3525
3527 IBaseFilter_QueryInterface(filter, &IID_IVMRSurfaceAllocatorNotify, (void **)&notify);
3528
3530 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
3531
3532 hr = IVMRSurfaceAllocatorNotify_SetDDrawDevice(notify, ddraw, MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY));
3534 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
3535
3537 todo_wine ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
3538
3539 hr = IVMRSurfaceAllocatorNotify_AdviseSurfaceAllocator(notify, 0xabacab,
3541 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3542
3544
3546 graph = create_graph();
3547 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
3548 IFilterGraph2_AddFilter(graph, filter, NULL);
3549 IBaseFilter_FindPin(filter, L"VMR Input0", &pin);
3550 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
3551
3552 for (i = 0; i < ARRAY_SIZE(tests); ++i)
3553 {
3554 winetest_push_context("Compression %#lx, depth %u", tests[i].compression, tests[i].depth);
3555
3556 req_mt.subtype = *tests[i].subtype;
3557 vih.bmiHeader.biBitCount = tests[i].depth;
3558 vih.bmiHeader.biCompression = tests[i].compression;
3559
3560 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
3561 /* Connection never fails on native, but Wine currently creates
3562 * surfaces during IPin::ReceiveConnection() instead of
3563 * IMemAllocator::SetProperties(), so let that fail here for now. */
3564 if (hr != S_OK)
3565 {
3566 skip("Format is not supported, hr %#lx.\n", hr);
3568 continue;
3569 }
3570 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3571
3572 hr = IMemInputPin_GetAllocator(input, &allocator);
3573 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
3574 if (hr != S_OK)
3575 {
3577 hr = IMemInputPin_GetAllocator(input, &allocator);
3578 }
3579
3580 req_props.cbBuffer = vih.bmiHeader.biWidth * vih.bmiHeader.biHeight * vih.bmiHeader.biBitCount / 8;
3581 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
3582 if (hr != S_OK)
3583 {
3584 skip("Format is not supported, hr %#lx.\n", hr);
3585 IMemAllocator_Release(allocator);
3586 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
3587 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3588 hr = IFilterGraph2_Disconnect(graph, pin);
3589 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3591 continue;
3592 }
3593 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3594 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
3595 hr = IMemAllocator_Commit(allocator);
3596 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3597
3598 hr = IVMRSurfaceAllocatorNotify_AdviseSurfaceAllocator(notify, 0xabacab,
3599 &presenter2.IVMRSurfaceAllocator_iface);
3600 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
3601
3603 "Bitmap header didn't match.\n");
3604
3606
3607 hr = IMemAllocator_Decommit(allocator);
3608 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3609 IMemAllocator_Release(allocator);
3610
3611 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
3612 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3613 hr = IFilterGraph2_Disconnect(graph, pin);
3614 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3616 }
3617
3618 hr = IVMRSurfaceAllocatorNotify_AdviseSurfaceAllocator(notify, 0xabacab,
3619 &presenter2.IVMRSurfaceAllocator_iface);
3620 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3621
3622 ref = IFilterGraph2_Release(graph);
3623 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3624 IMemInputPin_Release(input);
3625 IPin_Release(pin);
3626
3627 IVMRSurfaceAllocatorNotify_Release(notify);
3628 ref = IBaseFilter_Release(filter);
3629 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3630 ok(presenter.refcount == 1, "Got outstanding refcount %ld.\n", presenter.refcount);
3631 ok(presenter2.refcount == 1, "Got outstanding refcount %ld.\n", presenter2.refcount);
3632 ref = IDirectDraw7_Release(ddraw);
3633 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3635}
3636
3638{
3639 IDirectDrawSurface7 *frontbuffer, *backbuffer, *backbuffer2, *backbuffer3;
3640 IDirectDraw7 *ddraw, *prev_ddraw = NULL;
3644 HWND window;
3645 HRESULT hr;
3646 LONG ref;
3647
3648 BITMAPINFOHEADER bitmap_header =
3649 {
3650 .biSize = sizeof(BITMAPINFOHEADER),
3651 .biWidth = 32,
3652 .biHeight = 16,
3653 .biCompression = mmioFOURCC('Y','U','Y','2'),
3654 .biBitCount = 16,
3655 .biPlanes = 1,
3656 };
3657
3658 static const struct
3659 {
3660 WORD depth;
3663 }
3664 tests[] =
3665 {
3666 {32, BI_RGB},
3667 {12, mmioFOURCC('N','V','1','2')},
3668 {12, mmioFOURCC('Y','V','1','2')},
3669 {16, mmioFOURCC('U','Y','V','Y')},
3670 {16, mmioFOURCC('Y','U','Y','2')},
3671 };
3672
3673 window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0,
3674 100, 100, NULL, NULL, NULL, NULL);
3675
3676 hr = CoCreateInstance(&CLSID_AllocPresenter, NULL, CLSCTX_INPROC_SERVER,
3677 &IID_IVMRSurfaceAllocator, (void **)&allocator);
3678 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3679
3680 hr = IVMRSurfaceAllocator_FreeSurface(allocator, 0);
3681 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3682
3684 info.dwMinBuffers = 2;
3685 info.dwMaxBuffers = 2;
3686 info.dwInterlaceFlags = 0;
3687 info.szNativeSize.cx = info.szAspectRatio.cx = 640;
3688 info.szNativeSize.cy = info.szAspectRatio.cy = 480;
3689 info.lpHdr = &bitmap_header;
3690 info.lpPixFmt = NULL;
3691
3692 for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i)
3693 {
3694 DWORD expect_caps = 0;
3696 DWORD count = 2;
3697
3698 winetest_push_context("Compression %#lx, depth %u", tests[i].compression, tests[i].depth);
3699
3700 bitmap_header.biBitCount = tests[i].depth;
3701 bitmap_header.biCompression = tests[i].compression;
3702
3704
3705 /* Test whether we can create a surface directly, and how that will
3706 * be translated to the error message and caps. */
3707 memset(&desc, 0, sizeof(desc));
3708 desc.dwSize = sizeof(desc);
3711 desc.dwWidth = desc.dwHeight = 32;
3712 desc.dwBackBufferCount = 2;
3713 desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
3714 if (tests[i].compression)
3715 {
3716 desc.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
3717 desc.ddpfPixelFormat.dwFourCC = tests[i].compression;
3718 }
3719 else
3720 {
3721 desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
3722 desc.ddpfPixelFormat.dwRGBBitCount = 32;
3723 desc.ddpfPixelFormat.dwRBitMask = 0x00ff0000;
3724 desc.ddpfPixelFormat.dwGBitMask = 0x0000ff00;
3725 desc.ddpfPixelFormat.dwBBitMask = 0x000000ff;
3726 }
3727 hr = IDirectDraw7_CreateSurface(ddraw, &desc, &frontbuffer, NULL);
3728 ok(hr == S_OK || hr == DDERR_INVALIDPIXELFORMAT, "Got hr %#lx.\n", hr);
3730 if (hr == S_OK)
3731 {
3732 memset(&desc, 0, sizeof(desc));
3733 desc.dwSize = sizeof(desc);
3734 hr = IDirectDrawSurface7_GetSurfaceDesc(frontbuffer, &desc);
3735 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3736 expect_caps = desc.ddsCaps.dwCaps & ~(DDSCAPS_FRONTBUFFER | DDSCAPS_COMPLEX);
3737 IDirectDrawSurface7_Release(frontbuffer);
3738 }
3739
3740 IDirectDraw7_Release(ddraw);
3741
3742 hr = IVMRSurfaceAllocator_AllocateSurface(allocator, 0, &info, &count, &frontbuffer);
3743 ok(hr == expect_hr, "Got hr %#lx.\n", hr);
3745 {
3746 skip("Format is not supported.\n");
3748 continue;
3749 }
3750 ok(count == 3, "Got count %lu.\n", count);
3751
3752 memset(&desc, 0, sizeof(desc));
3753 desc.dwSize = sizeof(desc);
3754 hr = IDirectDrawSurface7_GetSurfaceDesc(frontbuffer, &desc);
3755 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3757 "Got flags %#lx.\n", desc.dwFlags);
3758 todo_wine ok(desc.ddsCaps.dwCaps == (expect_caps | DDSCAPS_FRONTBUFFER),
3759 "Expected caps %#lx, got %#lx.\n", (expect_caps | DDSCAPS_FRONTBUFFER), desc.ddsCaps.dwCaps);
3760 ok(!desc.ddsCaps.dwCaps2, "Got caps2 %#lx.\n", desc.ddsCaps.dwCaps2);
3761 ok(!desc.ddsCaps.dwCaps3, "Got caps2 %#lx.\n", desc.ddsCaps.dwCaps3);
3762 ok(!desc.ddsCaps.dwCaps4, "Got caps2 %#lx.\n", desc.ddsCaps.dwCaps4);
3763 ok(desc.dwWidth == 32, "Got width %lu.\n", desc.dwWidth);
3764 ok(desc.dwHeight == 16, "Got height %lu.\n", desc.dwHeight);
3765 ok(desc.ddpfPixelFormat.dwSize == sizeof(desc.ddpfPixelFormat),
3766 "Got size %lu.\n", desc.ddpfPixelFormat.dwSize);
3767 if (tests[i].compression)
3768 {
3769 ok(desc.ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Got flags %#lx.\n", desc.ddpfPixelFormat.dwFlags);
3770 ok(desc.ddpfPixelFormat.dwFourCC == bitmap_header.biCompression,
3771 "Got fourcc %08lx.\n", desc.ddpfPixelFormat.dwFourCC);
3772 }
3773 else
3774 {
3775 ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#lx.\n", desc.ddpfPixelFormat.dwFlags);
3776 ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got depth %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
3777 ok(desc.ddpfPixelFormat.dwRBitMask == 0x00ff0000, "Got red mask %#lx.\n", desc.ddpfPixelFormat.dwRBitMask);
3778 ok(desc.ddpfPixelFormat.dwGBitMask == 0x0000ff00, "Got green mask %#lx.\n", desc.ddpfPixelFormat.dwGBitMask);
3779 ok(desc.ddpfPixelFormat.dwBBitMask == 0x000000ff, "Got blue mask %#lx.\n", desc.ddpfPixelFormat.dwBBitMask);
3780 }
3781
3782 desc.ddsCaps.dwCaps = DDSCAPS_FLIP;
3783 hr = IDirectDrawSurface7_GetAttachedSurface(frontbuffer, &desc.ddsCaps, &backbuffer);
3784 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3785
3786 memset(&desc, 0, sizeof(desc));
3787 desc.dwSize = sizeof(desc);
3788 hr = IDirectDrawSurface7_GetSurfaceDesc(backbuffer, &desc);
3789 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3791 "Got flags %#lx.\n", desc.dwFlags);
3792 todo_wine ok(desc.ddsCaps.dwCaps == (expect_caps | DDSCAPS_BACKBUFFER),
3793 "Expected caps %#lx, got %#lx.\n", (expect_caps | DDSCAPS_BACKBUFFER), desc.ddsCaps.dwCaps);
3794
3795 desc.ddsCaps.dwCaps = DDSCAPS_FLIP;
3796 hr = IDirectDrawSurface7_GetAttachedSurface(backbuffer, &desc.ddsCaps, &backbuffer2);
3797 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3798
3799 memset(&desc, 0, sizeof(desc));
3800 desc.dwSize = sizeof(desc);
3801 hr = IDirectDrawSurface7_GetSurfaceDesc(backbuffer2, &desc);
3802 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3804 "Got flags %#lx.\n", desc.dwFlags);
3805 todo_wine ok(desc.ddsCaps.dwCaps == expect_caps,
3806 "Expected caps %#lx, got %#lx.\n", expect_caps, desc.ddsCaps.dwCaps);
3807
3808 desc.ddsCaps.dwCaps = DDSCAPS_FLIP;
3809 hr = IDirectDrawSurface7_GetAttachedSurface(backbuffer2, &desc.ddsCaps, &backbuffer3);
3810 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3811 if (hr == S_OK)
3812 {
3813 ok(backbuffer3 == frontbuffer, "Expected only 2 backbuffers.\n");
3814 IDirectDrawSurface7_Release(backbuffer3);
3815 }
3816
3817 IDirectDrawSurface7_Release(backbuffer2);
3818 IDirectDrawSurface7_Release(backbuffer);
3819
3820 hr = IDirectDrawSurface7_GetDDInterface(frontbuffer, (void **)&ddraw);
3821 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3822 if (prev_ddraw)
3823 {
3824 ok(ddraw == prev_ddraw, "Expected the same ddraw object.\n");
3825 IDirectDraw7_Release(ddraw);
3826 }
3827 else
3828 {
3829 prev_ddraw = ddraw;
3830 }
3831
3832 /* AllocateSurface does *not* give the application a reference to the
3833 * surface. */
3834
3835 IDirectDrawSurface7_AddRef(frontbuffer);
3836
3837 hr = IVMRSurfaceAllocator_FreeSurface(allocator, 0);
3838 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3839
3840 ref = IDirectDrawSurface7_Release(frontbuffer);
3841 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3842
3844 }
3845
3846 ref = IVMRSurfaceAllocator_Release(allocator);
3847 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3848 ref = IDirectDraw7_Release(prev_ddraw);
3849 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3851}
3852
3854{
3855 IDirectDrawSurface7 *frontbuffer;
3859 LONG width, height;
3860 DWORD count;
3861 HRESULT hr;
3862 LONG ref;
3863
3864 BITMAPINFOHEADER bitmap_header =
3865 {
3866 .biSize = sizeof(BITMAPINFOHEADER),
3867 .biWidth = 320,
3868 .biHeight = 240,
3869 .biCompression = BI_RGB,
3870 .biBitCount = 32,
3871 .biPlanes = 1,
3872 };
3873
3874 hr = CoCreateInstance(&CLSID_AllocPresenter, NULL, CLSCTX_INPROC_SERVER,
3875 &IID_IVMRSurfaceAllocator, (void **)&allocator);
3876 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3877
3878 count = 2;
3880 info.dwMinBuffers = count;
3881 info.dwMaxBuffers = count;
3882 info.dwInterlaceFlags = 0;
3883 info.szNativeSize.cx = 420;
3884 info.szAspectRatio.cx = 400;
3885 info.szNativeSize.cy = 180;
3886 info.szAspectRatio.cy = 200;
3887 info.lpHdr = &bitmap_header;
3888 info.lpPixFmt = NULL;
3889
3890 hr = IVMRSurfaceAllocator_AllocateSurface(allocator, 0, &info, &count, &frontbuffer);
3891 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3892
3893 hr = IVMRSurfaceAllocator_QueryInterface(allocator, &IID_IVMRWindowlessControl, (void **)&control);
3894 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3895
3896 width = height = 0xdeadbeef;
3897 hr = IVMRWindowlessControl_GetNativeVideoSize(control, &width, &height, NULL, NULL);
3898 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3899 ok(width == 420, "Got width %ld.\n", width);
3900 ok(height == 180, "Got height %ld.\n", height);
3901
3902 width = height = 0xdeadbeef;
3903 hr = IVMRWindowlessControl_GetNativeVideoSize(control, NULL, NULL, &width, &height);
3904 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3905 ok(width == 400, "Got width %ld.\n", width);
3906 ok(height == 200, "Got height %ld.\n", height);
3907
3908 hr = IVMRSurfaceAllocator_FreeSurface(allocator, 0);
3909 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3910
3911 IVMRWindowlessControl_Release(control);
3912 ref = IVMRSurfaceAllocator_Release(allocator);
3913 ok(!ref, "Got outstanding refcount %ld.\n", ref);
3914}
3915
3917{
3919
3924 test_find_pin();
3925 test_pin_info();
3930 test_overlay();
3938
3940}
@ 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 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 ARRAY_SIZE(A)
Definition: main.h:20
static HANDLE thread
Definition: service.c:33
const GUID IID_IUnknown
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY _In_ uint8_t compression
Definition: btrfs_drv.h:1365
r l[0]
Definition: byte_order.h:168
RECT rect
Definition: combotst.c:67
const GUID IID_IKsPropertySet
Definition: controlnode.cpp:13
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
HRESULT WINAPI DirectDrawCreateEx(LPGUID lpGUID, LPVOID *lplpDD, REFIID id, LPUNKNOWN pUnkOuter)
Definition: main.c:139
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 DDPF_FOURCC
Definition: ddsformat.c:58
#define DDPF_RGB
Definition: ddsformat.c:60
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
@ AMAP_ALLOW_SYSMEM
Definition: vmrender.idl:53
@ AMAP_DIRECTED_FLIP
Definition: vmrender.idl:55
@ VMRMode_Renderless
Definition: vmrender.idl:107
@ VMRMode_Windowless
Definition: vmrender.idl:106
@ VMRMode_Windowed
Definition: vmrender.idl:105
@ VMRSample_TimeValid
Definition: vmrender.idl:45
#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 GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
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 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
unsigned int UINT
Definition: sysinfo.c:13
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
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:539
#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
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
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 HRESULT WINAPI allocator_FreeSurface(IVMRSurfaceAllocator *iface, DWORD_PTR cookie)
Definition: vmr7.c:3371
static HRESULT WINAPI allocator_PrepareSurface(IVMRSurfaceAllocator *iface, DWORD_PTR cookie, IDirectDrawSurface7 *surface, DWORD flags)
Definition: vmr7.c:3390
static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, IMemInputPin *peer, IMemAllocator **allocator)
Definition: vmr7.c:877
static struct presenter * impl_from_IVMRSurfaceAllocator(IVMRSurfaceAllocator *iface)
Definition: vmr7.c:3275
static BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b)
Definition: vmr7.c:63
static void testfilter_destroy(struct strmbase_filter *iface)
Definition: vmr7.c:864
static HRESULT join_thread_(int line, HANDLE thread)
Definition: vmr7.c:1004
#define join_thread(a)
Definition: vmr7.c:1012
static ULONG WINAPI allocator_Release(IVMRSurfaceAllocator *iface)
Definition: vmr7.c:3303
static const IUnknownVtbl outer_vtbl
Definition: vmr7.c:348
static void test_video_window_messages(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
Definition: vmr7.c:2150
static void test_video_window_owner(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
Definition: vmr7.c:2071
static void test_default_presenter_window(void)
Definition: vmr7.c:3853
static void test_aggregation(void)
Definition: vmr7.c:357
static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
Definition: vmr7.c:209
static void test_windowless_size(void)
Definition: vmr7.c:2974
static void test_basic_video(void)
Definition: vmr7.c:2759
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: vmr7.c:338
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
Definition: vmr7.c:325
static HRESULT set_mixing_mode(IBaseFilter *filter)
Definition: vmr7.c:48
static void test_video_window_caption(IVideoWindow *window, HWND hwnd)
Definition: vmr7.c:1678
static const IVMRSurfaceAllocatorVtbl allocator_vtbl
Definition: vmr7.c:3410
static HRESULT WINAPI presenter_StartPresenting(IVMRImagePresenter *iface, DWORD_PTR cookie)
Definition: vmr7.c:3224
static void test_video_window_position(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
Definition: vmr7.c:1943
static struct testfilter * impl_from_strmbase_filter(struct strmbase_filter *iface)
Definition: vmr7.c:851
static HRESULT WINAPI presenter_QueryInterface(IVMRImagePresenter *iface, REFIID iid, void **out)
Definition: vmr7.c:3206
static ULONG get_refcount(void *iface)
Definition: vmr7.c:95
static const IVMRImagePresenterVtbl presenter_vtbl
Definition: vmr7.c:3265
static HRESULT WINAPI presenter_PresentImage(IVMRImagePresenter *iface, DWORD_PTR cookie, VMRPRESENTATIONINFO *info)
Definition: vmr7.c:3238
static void test_pin_info(void)
Definition: vmr7.c:611
static IUnknown test_outer
Definition: vmr7.c:355
static void test_current_image(IBaseFilter *filter, IMemInputPin *input, IMediaControl *control, const BITMAPINFOHEADER *req_bih)
Definition: vmr7.c:1257
static void test_find_pin(void)
Definition: vmr7.c:550
static void test_basic_video_destination(IBasicVideo *video)
Definition: vmr7.c:2644
static void test_video_window_style(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
Definition: vmr7.c:1706
static void test_flushing(IPin *pin, IMemInputPin *input, IMediaControl *control)
Definition: vmr7.c:1164
static const struct strmbase_source_ops testsource_ops
Definition: vmr7.c:883
static void test_basic_video_source(IBasicVideo *video)
Definition: vmr7.c:2529
static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
Definition: vmr7.c:1667
static HRESULT WINAPI allocator_AllocateSurface(IVMRSurfaceAllocator *iface, DWORD_PTR cookie, VMRALLOCATIONINFO *info, DWORD *buffer_count, IDirectDrawSurface7 **surface)
Definition: vmr7.c:3309
static void test_enum_media_types(void)
Definition: vmr7.c:744
static BOOL compare_double(double f, double g, unsigned int ulps)
Definition: vmr7.c:69
static HRESULT WINAPI allocator_AdviseNotify(IVMRSurfaceAllocator *iface, IVMRSurfaceAllocatorNotify *notify)
Definition: vmr7.c:3404
static BOOL CALLBACK top_window_cb(HWND hwnd, LPARAM ctx)
Definition: vmr7.c:1762
static void test_interfaces(void)
Definition: vmr7.c:274
static void test_video_window_autoshow(IVideoWindow *window, IFilterGraph2 *graph, HWND hwnd)
Definition: vmr7.c:2276
static unsigned int check_ec_userabort(IMediaEvent *eventsrc, DWORD timeout)
Definition: vmr7.c:1348
static void test_video_window(void)
Definition: vmr7.c:2324
static IBaseFilter * create_vmr7(DWORD mode)
Definition: vmr7.c:30
static void test_connect_pin(void)
Definition: vmr7.c:1452
static DWORD WINAPI frame_thread(void *arg)
Definition: vmr7.c:952
static ULONG WINAPI presenter_Release(IVMRImagePresenter *iface)
Definition: vmr7.c:3218
static void flush_events(void)
Definition: vmr7.c:1650
static void test_media_types(void)
Definition: vmr7.c:676
static struct presenter * impl_from_IVMRImagePresenter(IVMRImagePresenter *iface)
Definition: vmr7.c:3201
static ULONG WINAPI presenter_AddRef(IVMRImagePresenter *iface)
Definition: vmr7.c:3212
static struct strmbase_pin * testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
Definition: vmr7.c:856
static void test_allocator(IMemInputPin *input)
Definition: vmr7.c:896
static void commit_allocator(IMemInputPin *input)
Definition: vmr7.c:1014
static void test_enum_pins(void)
Definition: vmr7.c:416
static IFilterGraph2 * create_graph(void)
Definition: vmr7.c:86
static IDirectDraw7 * create_ddraw(HWND window)
Definition: vmr7.c:3171
static void test_overlay(void)
Definition: vmr7.c:1624
static void test_renderless_present(struct presenter *presenter, IFilterGraph2 *graph, IMemInputPin *input)
Definition: vmr7.c:3421
static HWND get_top_window(void)
Definition: vmr7.c:1774
static HRESULT WINAPI presenter_StopPresenting(IVMRImagePresenter *iface, DWORD_PTR cookie)
Definition: vmr7.c:3231
static void check_destination_position_(int line, IBasicVideo *video, LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
Definition: vmr7.c:2608
static HANDLE send_frame(IMemInputPin *sink)
Definition: vmr7.c:965
#define check_destination_position(a, b, c, d, e)
Definition: vmr7.c:2642
static void test_window_close(IPin *pin, IMemInputPin *input, IMediaControl *control)
Definition: vmr7.c:1371
static DWORD CALLBACK notify_message_proc(void *arg)
Definition: vmr7.c:2142
#define check_source_position(a, b, c, d, e)
Definition: vmr7.c:2527
static void test_unconnected_eos(void)
Definition: vmr7.c:3105
static void test_default_presenter_allocate(void)
Definition: vmr7.c:3637
static unsigned int check_ec_complete(IMediaEvent *eventsrc, DWORD timeout)
Definition: vmr7.c:1252
#define check_interface(a, b, c)
Definition: vmr7.c:208
static void test_filter_config(void)
Definition: vmr7.c:102
static void test_common_interfaces(IBaseFilter *filter)
Definition: vmr7.c:223
static void test_renderless_formats(void)
Definition: vmr7.c:3461
static LONG outer_ref
Definition: vmr7.c:323
static ULONG WINAPI allocator_AddRef(IVMRSurfaceAllocator *iface)
Definition: vmr7.c:3297
static unsigned int check_event_code(IMediaEvent *eventsrc, DWORD timeout, LONG expected_code, LONG_PTR expected1, LONG_PTR expected2)
Definition: vmr7.c:1229
static const struct strmbase_filter_ops testfilter_ops
Definition: vmr7.c:871
static void test_video_window_state(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
Definition: vmr7.c:1781
static void check_source_position_(int line, IBasicVideo *video, LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
Definition: vmr7.c:2493
static void test_unconnected_filter_state(void)
Definition: vmr7.c:788
static const GUID test_iid
Definition: vmr7.c:322
static HRESULT WINAPI allocator_QueryInterface(IVMRSurfaceAllocator *iface, REFIID iid, void **out)
Definition: vmr7.c:3280
static void testfilter_init(struct testfilter *filter)
Definition: vmr7.c:889
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: vmr7.c:343
#define expect_hr(expected, got)
Definition: assoc.c:27
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)
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
DWORD IDirectDrawSurface7
Definition: vmrender.idl:20
DWORD IDirectDraw7
Definition: vmrender.idl:21
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
#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 DDSD_WIDTH
Definition: ddraw.h:212
#define DDSCAPS_FRONTBUFFER
Definition: ddraw.h:256
#define DDSD_PIXELFORMAT
Definition: ddraw.h:218
#define DDSCL_NORMAL
Definition: ddraw.h:537
#define DDSD_PITCH
Definition: ddraw.h:213
#define DDERR_INVALIDPIXELFORMAT
Definition: ddraw.h:82
#define DDSD_HEIGHT
Definition: ddraw.h:211
#define DDSCAPS_OFFSCREENPLAIN
Definition: ddraw.h:257
#define DDSCAPS_FLIP
Definition: ddraw.h:255
#define DDSCAPS_BACKBUFFER
Definition: ddraw.h:253
#define DDSD_CAPS
Definition: ddraw.h:210
#define DDSD_BACKBUFFERCOUNT
Definition: ddraw.h:214
#define DDSCAPS_COMPLEX
Definition: ddraw.h:254
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 biCompression
Definition: amvideo.idl:35
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
DWORD dwBBitMask
Definition: ddraw.h:1108
DWORD dwSize
Definition: ddraw.h:1072
DWORD dwFourCC
Definition: ddraw.h:1074
DWORD dwRGBBitCount
Definition: ddraw.h:1077
DWORD dwRBitMask
Definition: ddraw.h:1087
DWORD dwGBitMask
Definition: ddraw.h:1096
DWORD dwFlags
Definition: ddraw.h:1073
DWORD dwCaps
Definition: ddraw.h:734
DWORD dwWidth
Definition: ddraw.h:1157
DWORD dwHeight
Definition: ddraw.h:1156
DDSCAPS2 ddsCaps
Definition: ddraw.h:1190
DDPIXELFORMAT ddpfPixelFormat
Definition: ddraw.h:1187
DWORD dwBackBufferCount
Definition: ddraw.h:1165
DWORD dwFlags
Definition: ddraw.h:1155
DWORD dwSize
Definition: ddraw.h:1154
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: 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
IVMRImagePresenter IVMRImagePresenter_iface
Definition: vmr7.c:3189
unsigned int got_PresentImage
Definition: vmr7.c:3198
IDirectDraw7 * ddraw
Definition: vmr7.c:3192
LONG refcount
Definition: vmr7.c:3190
IDirectDrawSurface7 * surfaces[6]
Definition: vmr7.c:3193
IVMRSurfaceAllocator IVMRSurfaceAllocator_iface
Definition: vmr7.c:3188
unsigned int got_PrepareSurface
Definition: vmr7.c:3198
IVMRSurfaceAllocatorNotify * notify
Definition: vmr7.c:3197
DWORD surface_count
Definition: vmr7.c:3194
BITMAPINFOHEADER format
Definition: vmr7.c:3196
Definition: send.c:48
Definition: wave.c:25
Definition: style.c:91
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
Definition: vmr7.c:52
#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_DDRAW_CAPS_NOT_SUITABLE
Definition: vfwmsgs.h:124
#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_NOT_FOUND
Definition: vfwmsgs.h:61
#define VFW_E_NOT_CONNECTED
Definition: vfwmsgs.h:48
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