ReactOS 0.4.17-dev-966-gf06eace
videorenderer.c
Go to the documentation of this file.
1/*
2 * Unit tests for Video Renderer functions
3 *
4 * Copyright (C) 2007 Google (Lei Zhang)
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#define COBJMACROS
22#include "dshow.h"
23#include "videoacc.h"
24#include "wine/strmbase.h"
25#include "wine/test.h"
26
28{
30 HRESULT hr = CoCreateInstance(&CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER,
31 &IID_IBaseFilter, (void **)&filter);
32 ok(hr == S_OK, "Got hr %#lx.\n", hr);
33 return filter;
34}
35
37{
38 return !memcmp(a, b, offsetof(AM_MEDIA_TYPE, pbFormat))
39 && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat);
40}
41
43{
45 HRESULT hr;
46 hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph2, (void **)&ret);
47 ok(hr == S_OK, "Got hr %#lx.\n", hr);
48 return ret;
49}
50
51static ULONG get_refcount(void *iface)
52{
53 IUnknown *unknown = iface;
54 IUnknown_AddRef(unknown);
55 return IUnknown_Release(unknown);
56}
57
58#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
59static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
60{
61 IUnknown *iface = iface_ptr;
63 IUnknown *unk;
64
65 expected_hr = supported ? S_OK : E_NOINTERFACE;
66
67 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
68 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
69 if (SUCCEEDED(hr))
70 IUnknown_Release(unk);
71}
72
73static void test_interfaces(void)
74{
76 IPin *pin;
77
79 check_interface(filter, &IID_IBasicVideo, TRUE);
80 todo_wine check_interface(filter, &IID_IBasicVideo2, TRUE);
81 todo_wine check_interface(filter, &IID_IDirectDrawVideo, TRUE);
83 check_interface(filter, &IID_IMediaFilter, TRUE);
84 check_interface(filter, &IID_IMediaPosition, TRUE);
85 check_interface(filter, &IID_IMediaSeeking, TRUE);
87 check_interface(filter, &IID_IQualityControl, TRUE);
88 todo_wine check_interface(filter, &IID_IQualProp, TRUE);
90 check_interface(filter, &IID_IVideoWindow, TRUE);
91
92 check_interface(filter, &IID_IAMFilterMiscFlags, FALSE);
93 check_interface(filter, &IID_IAMVideoAccelerator, FALSE);
94 check_interface(filter, &IID_IBasicAudio, FALSE);
96 check_interface(filter, &IID_IOverlay, FALSE);
99 check_interface(filter, &IID_IReferenceClock, FALSE);
100
101 IBaseFilter_FindPin(filter, L"In", &pin);
102
103 check_interface(pin, &IID_IMemInputPin, TRUE);
104 check_interface(pin, &IID_IOverlay, TRUE);
106 todo_wine check_interface(pin, &IID_IPinConnection, TRUE);
107 todo_wine check_interface(pin, &IID_IQualityControl, TRUE);
109
110 check_interface(pin, &IID_IAMVideoAccelerator, FALSE);
112 check_interface(pin, &IID_IMediaPosition, FALSE);
113 check_interface(pin, &IID_IMediaSeeking, FALSE);
114
115 IPin_Release(pin);
116 IBaseFilter_Release(filter);
117}
118
119static const GUID test_iid = {0x33333333};
120static LONG outer_ref = 1;
121
123{
124 if (IsEqualGUID(iid, &IID_IUnknown)
126 || IsEqualGUID(iid, &test_iid))
127 {
128 *out = (IUnknown *)0xdeadbeef;
129 return S_OK;
130 }
131 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
132 return E_NOINTERFACE;
133}
134
136{
138}
139
141{
143}
144
145static const IUnknownVtbl outer_vtbl =
146{
150};
151
153
154static void test_aggregation(void)
155{
156 IBaseFilter *filter, *filter2;
157 IUnknown *unk, *unk2;
158 HRESULT hr;
159 ULONG ref;
160
161 filter = (IBaseFilter *)0xdeadbeef;
162 hr = CoCreateInstance(&CLSID_VideoRenderer, &test_outer, CLSCTX_INPROC_SERVER,
163 &IID_IBaseFilter, (void **)&filter);
164 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
165 ok(!filter, "Got interface %p.\n", filter);
166
167 hr = CoCreateInstance(&CLSID_VideoRenderer, &test_outer, CLSCTX_INPROC_SERVER,
168 &IID_IUnknown, (void **)&unk);
169 ok(hr == S_OK, "Got hr %#lx.\n", hr);
170 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
171 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
172 ref = get_refcount(unk);
173 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
174
175 ref = IUnknown_AddRef(unk);
176 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
177 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
178
179 ref = IUnknown_Release(unk);
180 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
181 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
182
183 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
184 ok(hr == S_OK, "Got hr %#lx.\n", hr);
185 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
186 IUnknown_Release(unk2);
187
188 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
189 ok(hr == S_OK, "Got hr %#lx.\n", hr);
190
191 hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
192 ok(hr == S_OK, "Got hr %#lx.\n", hr);
193 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
194
195 hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
196 ok(hr == S_OK, "Got hr %#lx.\n", hr);
197 ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
198
199 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
200 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
201 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
202
203 hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
204 ok(hr == S_OK, "Got hr %#lx.\n", hr);
205 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
206
207 IBaseFilter_Release(filter);
208 ref = IUnknown_Release(unk);
209 ok(!ref, "Got unexpected refcount %ld.\n", ref);
210 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
211}
212
213static void test_enum_pins(void)
214{
216 IEnumPins *enum1, *enum2;
217 IPin *pins[2];
218 ULONG count;
219 HRESULT hr;
220 ULONG ref;
221
223 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
224
225 hr = IBaseFilter_EnumPins(filter, NULL);
226 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
227
228 hr = IBaseFilter_EnumPins(filter, &enum1);
229 ok(hr == S_OK, "Got hr %#lx.\n", hr);
231 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
232 ref = get_refcount(enum1);
233 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
234
235 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
236 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
237
238 hr = IEnumPins_Next(enum1, 1, pins, NULL);
239 ok(hr == S_OK, "Got hr %#lx.\n", hr);
241 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
242 ref = get_refcount(pins[0]);
243 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
244 ref = get_refcount(enum1);
245 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
246 IPin_Release(pins[0]);
248 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
249
250 hr = IEnumPins_Next(enum1, 1, pins, NULL);
251 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
252
253 hr = IEnumPins_Reset(enum1);
254 ok(hr == S_OK, "Got hr %#lx.\n", hr);
255
256 hr = IEnumPins_Next(enum1, 1, pins, &count);
257 ok(hr == S_OK, "Got hr %#lx.\n", hr);
258 ok(count == 1, "Got count %lu.\n", count);
259 IPin_Release(pins[0]);
260
261 hr = IEnumPins_Next(enum1, 1, pins, &count);
262 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
263 ok(!count, "Got count %lu.\n", count);
264
265 hr = IEnumPins_Reset(enum1);
266 ok(hr == S_OK, "Got hr %#lx.\n", hr);
267
268 hr = IEnumPins_Next(enum1, 2, pins, NULL);
269 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
270
271 hr = IEnumPins_Next(enum1, 2, pins, &count);
272 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
273 ok(count == 1, "Got count %lu.\n", count);
274 IPin_Release(pins[0]);
275
276 hr = IEnumPins_Reset(enum1);
277 ok(hr == S_OK, "Got hr %#lx.\n", hr);
278
279 hr = IEnumPins_Clone(enum1, &enum2);
280 ok(hr == S_OK, "Got hr %#lx.\n", hr);
281
282 hr = IEnumPins_Skip(enum1, 2);
283 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
284
285 hr = IEnumPins_Skip(enum1, 1);
286 ok(hr == S_OK, "Got hr %#lx.\n", hr);
287
288 hr = IEnumPins_Skip(enum1, 1);
289 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
290
291 hr = IEnumPins_Next(enum1, 1, pins, NULL);
292 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
293
294 hr = IEnumPins_Next(enum2, 1, pins, NULL);
295 ok(hr == S_OK, "Got hr %#lx.\n", hr);
296 IPin_Release(pins[0]);
297
298 IEnumPins_Release(enum2);
299 IEnumPins_Release(enum1);
300 ref = IBaseFilter_Release(filter);
301 ok(!ref, "Got outstanding refcount %ld.\n", ref);
302}
303
304static void test_find_pin(void)
305{
308 IPin *pin, *pin2;
309 HRESULT hr;
310 ULONG ref;
311
312 hr = IBaseFilter_FindPin(filter, L"input pin", &pin);
313 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
314
315 hr = IBaseFilter_FindPin(filter, L"In", &pin);
316 ok(hr == S_OK, "Got hr %#lx.\n", hr);
317
318 hr = IBaseFilter_EnumPins(filter, &enum_pins);
319 ok(hr == S_OK, "Got hr %#lx.\n", hr);
320
321 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
322 ok(hr == S_OK, "Got hr %#lx.\n", hr);
323 ok(pin == pin2, "Expected pin %p, got %p.\n", pin2, pin);
324 IPin_Release(pin);
325 IPin_Release(pin2);
326
327 IEnumPins_Release(enum_pins);
328 ref = IBaseFilter_Release(filter);
329 ok(!ref, "Got outstanding refcount %ld.\n", ref);
330}
331
332static void test_pin_info(void)
333{
337 HRESULT hr;
338 WCHAR *id;
339 ULONG ref;
340 IPin *pin;
341
342 hr = IBaseFilter_FindPin(filter, L"In", &pin);
343 ok(hr == S_OK, "Got hr %#lx.\n", hr);
345 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
346 ref = get_refcount(pin);
347 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
348
349 hr = IPin_QueryPinInfo(pin, &info);
350 ok(hr == S_OK, "Got hr %#lx.\n", hr);
351 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
352 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
353 ok(!wcscmp(info.achName, L"Input"), "Got name %s.\n", debugstr_w(info.achName));
355 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
356 ref = get_refcount(pin);
357 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
358 IBaseFilter_Release(info.pFilter);
359
360 hr = IPin_QueryDirection(pin, &dir);
361 ok(hr == S_OK, "Got hr %#lx.\n", hr);
362 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
363
364 hr = IPin_QueryId(pin, &id);
365 ok(hr == S_OK, "Got hr %#lx.\n", hr);
366 ok(!wcscmp(id, L"In"), "Got id %s.\n", wine_dbgstr_w(id));
367 CoTaskMemFree(id);
368
369 hr = IPin_QueryInternalConnections(pin, NULL, NULL);
370 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
371
372 IPin_Release(pin);
373 ref = IBaseFilter_Release(filter);
374 ok(!ref, "Got outstanding refcount %ld.\n", ref);
375}
376
377static void test_media_types(void)
378{
380 AM_MEDIA_TYPE *mt, req_mt = {{0}};
381 VIDEOINFOHEADER vih =
382 {
383 {0}, {0}, 0, 0, 0,
384 {sizeof(BITMAPINFOHEADER), 32, 24, 1, 0, BI_RGB}
385 };
386 IEnumMediaTypes *enummt;
387 unsigned int i;
388 HRESULT hr;
389 ULONG ref;
390 IPin *pin;
391
392 static const GUID *subtype_tests[] =
393 {
394 &MEDIASUBTYPE_RGB8,
395 &MEDIASUBTYPE_RGB565,
396 &MEDIASUBTYPE_RGB24,
397 &MEDIASUBTYPE_RGB32,
398 };
399
400 IBaseFilter_FindPin(filter, L"In", &pin);
401
402 hr = IPin_EnumMediaTypes(pin, &enummt);
403 ok(hr == S_OK, "Got hr %#lx.\n", hr);
404
405 hr = IEnumMediaTypes_Next(enummt, 1, &mt, NULL);
406 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
407
408 IEnumMediaTypes_Release(enummt);
409
410 req_mt.majortype = MEDIATYPE_Video;
411 req_mt.formattype = FORMAT_VideoInfo;
412 req_mt.cbFormat = sizeof(VIDEOINFOHEADER);
413 req_mt.pbFormat = (BYTE *)&vih;
414
415 for (i = 0; i < ARRAY_SIZE(subtype_tests); ++i)
416 {
417 req_mt.subtype = *subtype_tests[i];
418 hr = IPin_QueryAccept(pin, &req_mt);
419 ok(hr == S_OK, "Got hr %#lx for subtype %s.\n", hr, wine_dbgstr_guid(subtype_tests[i]));
420 }
421
422 req_mt.subtype = MEDIASUBTYPE_NULL;
423 hr = IPin_QueryAccept(pin, &req_mt);
424 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
425 req_mt.subtype = MEDIASUBTYPE_RGB24;
426
427 req_mt.majortype = MEDIATYPE_NULL;
428 hr = IPin_QueryAccept(pin, &req_mt);
429 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
430 req_mt.majortype = MEDIATYPE_Video;
431
432 req_mt.formattype = FORMAT_None;
433 hr = IPin_QueryAccept(pin, &req_mt);
434 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
435
436 req_mt.formattype = GUID_NULL;
437 hr = IPin_QueryAccept(pin, &req_mt);
438 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
439
440 IPin_Release(pin);
441 ref = IBaseFilter_Release(filter);
442 ok(!ref, "Got outstanding refcount %ld.\n", ref);
443}
444
445static void test_enum_media_types(void)
446{
448 IEnumMediaTypes *enum1, *enum2;
449 AM_MEDIA_TYPE *mts[2];
450 ULONG ref, count;
451 HRESULT hr;
452 IPin *pin;
453
454 IBaseFilter_FindPin(filter, L"In", &pin);
455
456 hr = IPin_EnumMediaTypes(pin, &enum1);
457 ok(hr == S_OK, "Got hr %#lx.\n", hr);
458
459 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
460 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
461
462 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
463 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
464 ok(!count, "Got count %lu.\n", count);
465
466 hr = IEnumMediaTypes_Reset(enum1);
467 ok(hr == S_OK, "Got hr %#lx.\n", hr);
468
469 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
470 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
471
472 hr = IEnumMediaTypes_Clone(enum1, &enum2);
473 ok(hr == S_OK, "Got hr %#lx.\n", hr);
474
475 hr = IEnumMediaTypes_Skip(enum1, 1);
476 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
477
478 hr = IEnumMediaTypes_Next(enum2, 1, mts, NULL);
479 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
480
481 IEnumMediaTypes_Release(enum1);
482 IEnumMediaTypes_Release(enum2);
483 IPin_Release(pin);
484
485 ref = IBaseFilter_Release(filter);
486 ok(!ref, "Got outstanding refcount %ld.\n", ref);
487}
488
489struct testfilter
490{
491 struct strmbase_filter filter;
492 struct strmbase_source source;
494};
495
496static inline struct testfilter *impl_from_BaseFilter(struct strmbase_filter *iface)
497{
498 return CONTAINING_RECORD(iface, struct testfilter, filter);
499}
500
501static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
502{
503 struct testfilter *filter = impl_from_BaseFilter(iface);
504 if (!index)
505 return &filter->source.pin;
506 return NULL;
507}
508
509static void testfilter_destroy(struct strmbase_filter *iface)
510{
511 struct testfilter *filter = impl_from_BaseFilter(iface);
514}
515
517{
518 .filter_get_pin = testfilter_get_pin,
519 .filter_destroy = testfilter_destroy,
520};
521
522static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
523{
525
526 if (IsEqualGUID(iid, &IID_IMediaSeeking))
528 else
529 return E_NOINTERFACE;
530
531 IUnknown_AddRef((IUnknown *)*out);
532 return S_OK;
533}
534
537{
538 return S_OK;
539}
540
542{
543 .base.pin_query_interface = testsource_query_interface,
544 .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
545 .pfnDecideAllocator = testsource_DecideAllocator,
546};
547
549{
550 return CONTAINING_RECORD(iface, struct testfilter, IMediaSeeking_iface);
551}
552
554{
556 return IUnknown_QueryInterface(filter->filter.outer_unk, iid, out);
557}
558
560{
562 return IUnknown_AddRef(filter->filter.outer_unk);
563}
564
566{
568 return IUnknown_Release(filter->filter.outer_unk);
569}
570
572{
573 ok(0, "Unexpected call.\n");
574 return E_NOTIMPL;
575}
576
578{
579 ok(0, "Unexpected call.\n");
580 return E_NOTIMPL;
581}
582
584{
585 if (winetest_debug > 1) trace("IsFormatSupported()\n");
586 return E_NOTIMPL;
587}
588
590{
591 if (winetest_debug > 1) trace("%p->QueryPreferredFormat()\n", iface);
592 return E_NOTIMPL;
593}
594
596{
597 if (winetest_debug > 1) trace("%p->GetTimeFormat()\n", iface);
598 return E_NOTIMPL;
599}
600
602{
603 ok(0, "Unexpected call.\n");
604 return E_NOTIMPL;
605}
606
608{
609 ok(0, "Unexpected call.\n");
610 return E_NOTIMPL;
611}
612
614{
615 ok(0, "Unexpected call.\n");
616 return E_NOTIMPL;
617}
618
620{
621 if (winetest_debug > 1) trace("GetStopPosition()\n");
622 return E_NOTIMPL;
623}
624
626{
627 if (winetest_debug > 1) trace("GetCurrentPosition()\n");
628 return 0xdeadbeef;
629}
630
632 const GUID *target_format, LONGLONG source, const GUID *source_format)
633{
634 if (winetest_debug > 1) trace("ConvertTimeFormat()\n");
635 ok(IsEqualGUID(source_format, &TIME_FORMAT_MEDIA_TIME),
636 "Got source format %s.\n", debugstr_guid(source_format));
637 ok(!target_format, "Got target format %s.\n", debugstr_guid(target_format));
638 *target = source;
639 return S_OK;
640}
641
643 DWORD current_flags, LONGLONG *stop, DWORD stop_flags )
644{
645 if (winetest_debug > 1) trace("SetPositions()\n");
646 return E_NOTIMPL;
647}
648
650{
651 ok(0, "Unexpected call.\n");
652 return E_NOTIMPL;
653}
654
656{
657 ok(0, "Unexpected call.\n");
658 return E_NOTIMPL;
659}
660
662{
663 ok(0, "Unexpected call.\n");
664 return E_NOTIMPL;
665}
666
668{
669 ok(0, "Unexpected call.\n");
670 return E_NOTIMPL;
671}
672
674{
675 if (winetest_debug > 1) trace("%p->GetPreroll()\n", iface);
676 return E_NOTIMPL;
677}
678
679static const IMediaSeekingVtbl testseek_vtbl =
680{
701};
702
704{
705 static const GUID clsid = {0xabacab};
709}
710
712{
713 IMemAllocator *req_allocator, *ret_allocator;
715 HRESULT hr;
716
717 hr = IMemInputPin_GetAllocatorRequirements(input, &props);
718 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
719
720 hr = IMemInputPin_GetAllocator(input, &ret_allocator);
721 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
722
723 if (hr == S_OK)
724 {
725 hr = IMemAllocator_GetProperties(ret_allocator, &props);
726 ok(hr == S_OK, "Got hr %#lx.\n", hr);
727 ok(!props.cBuffers, "Got %ld buffers.\n", props.cBuffers);
728 ok(!props.cbBuffer, "Got size %ld.\n", props.cbBuffer);
729 ok(!props.cbAlign, "Got alignment %ld.\n", props.cbAlign);
730 ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
731
732 hr = IMemInputPin_NotifyAllocator(input, ret_allocator, TRUE);
733 ok(hr == S_OK, "Got hr %#lx.\n", hr);
734 IMemAllocator_Release(ret_allocator);
735 }
736
737 hr = IMemInputPin_NotifyAllocator(input, NULL, TRUE);
738 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
739
740 CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
741 &IID_IMemAllocator, (void **)&req_allocator);
742
743 hr = IMemInputPin_NotifyAllocator(input, req_allocator, TRUE);
744 ok(hr == S_OK, "Got hr %#lx.\n", hr);
745
746 hr = IMemInputPin_GetAllocator(input, &ret_allocator);
747 ok(hr == S_OK, "Got hr %#lx.\n", hr);
748 ok(ret_allocator == req_allocator, "Allocators didn't match.\n");
749
750 IMemAllocator_Release(req_allocator);
751 IMemAllocator_Release(ret_allocator);
752}
753
755{
758};
759
761{
763 HRESULT hr;
764
765 if (winetest_debug > 1) trace("%04lx: Sending frame.\n", GetCurrentThreadId());
766 hr = IMemInputPin_Receive(params->sink, params->sample);
767 if (winetest_debug > 1) trace("%04lx: Returned %#lx.\n", GetCurrentThreadId(), hr);
768 IMediaSample_Release(params->sample);
769 free(params);
770 return hr;
771}
772
773static HANDLE send_frame_time(IMemInputPin *sink, REFERENCE_TIME start_time, unsigned char color)
774{
775 struct frame_thread_params *params = malloc(sizeof(*params));
777 REFERENCE_TIME end_time;
780 HRESULT hr;
781 BYTE *data;
782
783 hr = IMemInputPin_GetAllocator(sink, &allocator);
784 ok(hr == S_OK, "Got hr %#lx.\n", hr);
785
786 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
787 ok(hr == S_OK, "Got hr %#lx.\n", hr);
788
789 hr = IMediaSample_GetPointer(sample, &data);
790 ok(hr == S_OK, "Got hr %#lx.\n", hr);
791 memset(data, color, 32 * 16 * 2);
792
793 hr = IMediaSample_SetActualDataLength(sample, 32 * 16 * 2);
794 ok(hr == S_OK, "Got hr %#lx.\n", hr);
795
796 start_time *= 10000000;
797 end_time = start_time + 10000000;
798 hr = IMediaSample_SetTime(sample, &start_time, &end_time);
799 ok(hr == S_OK, "Got hr %#lx.\n", hr);
800
801 hr = IMediaSample_SetPreroll(sample, TRUE);
802 ok(hr == S_OK, "Got hr %#lx.\n", hr);
803
804 params->sink = sink;
805 params->sample = sample;
807
808 IMemAllocator_Release(allocator);
809 return thread;
810}
811
813{
814 return send_frame_time(sink, 0, 0x55); /* purple */
815}
816
818{
819 DWORD ret;
820 ok_(__FILE__, line)(!WaitForSingleObject(thread, 1000), "Wait failed.\n");
823 return ret;
824}
825#define join_thread(a) join_thread_(__LINE__, a)
826
827static void test_filter_state(IMemInputPin *input, IMediaControl *control)
828{
831 OAFilterState state;
833 HRESULT hr;
834
837 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
838
839 /* The renderer is not fully paused until it receives a sample. The thread
840 * sending the sample blocks in IMemInputPin_Receive() until the filter is
841 * stopped or run. */
842
843 hr = IMediaControl_Pause(control);
844 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
845
846 hr = IMediaControl_GetState(control, 0, &state);
847 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
848
850
851 hr = IMediaControl_GetState(control, 1000, &state);
852 ok(hr == S_OK, "Got hr %#lx.\n", hr);
853
854 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
855
856 hr = IMediaControl_Stop(control);
857 ok(hr == S_OK, "Got hr %#lx.\n", hr);
858
860 ok(hr == S_OK, "Got hr %#lx.\n", hr);
861
862 /* The sink will decommit our allocator for us when stopping, and recommit
863 * it when pausing. */
864 hr = IMemInputPin_GetAllocator(input, &allocator);
865 ok(hr == S_OK, "Got hr %#lx.\n", hr);
866 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
867 todo_wine ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#lx.\n", hr);
868 if (hr == S_OK) IMediaSample_Release(sample);
869
870 hr = IMemAllocator_Commit(allocator);
871 ok(hr == S_OK, "Got hr %#lx.\n", hr);
874 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
875
876 hr = IMediaControl_Pause(control);
877 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
878
879 hr = IMediaControl_GetState(control, 0, &state);
880 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
881
883
884 hr = IMediaControl_GetState(control, 1000, &state);
885 ok(hr == S_OK, "Got hr %#lx.\n", hr);
886
887 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
888
889 hr = IMediaControl_Run(control);
890 ok(hr == S_OK, "Got hr %#lx.\n", hr);
891
892 hr = IMediaControl_GetState(control, 0, &state);
893 ok(hr == S_OK, "Got hr %#lx.\n", hr);
894
896 ok(hr == S_OK, "Got hr %#lx.\n", hr);
897
900 ok(hr == S_OK, "Got hr %#lx.\n", hr);
901
902 hr = IMediaControl_Pause(control);
903 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
904
905 hr = IMediaControl_GetState(control, 0, &state);
906 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
907
909
910 hr = IMediaControl_GetState(control, 1000, &state);
911 ok(hr == S_OK, "Got hr %#lx.\n", hr);
912
913 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
914
915 hr = IMediaControl_Run(control);
916 ok(hr == S_OK, "Got hr %#lx.\n", hr);
917
918 hr = IMediaControl_GetState(control, 0, &state);
919 ok(hr == S_OK, "Got hr %#lx.\n", hr);
920
922 ok(hr == S_OK, "Got hr %#lx.\n", hr);
923
924 hr = IMediaControl_Pause(control);
925 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
926
927 hr = IMediaControl_GetState(control, 0, &state);
928 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
929
930 hr = IMediaControl_Stop(control);
931 ok(hr == S_OK, "Got hr %#lx.\n", hr);
932
933 hr = IMediaControl_GetState(control, 0, &state);
934 ok(hr == S_OK, "Got hr %#lx.\n", hr);
935
936 hr = IMediaControl_Pause(control);
937 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
938
939 hr = IMediaControl_GetState(control, 0, &state);
940 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
941
942 hr = IMediaControl_Run(control);
943 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
944
945 hr = IMediaControl_GetState(control, 0, &state);
946 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
947
950 ok(hr == S_OK, "Got hr %#lx.\n", hr);
951
952 hr = IMediaControl_GetState(control, 0, &state);
953 ok(hr == S_OK, "Got hr %#lx.\n", hr);
954
955 hr = IMediaControl_Stop(control);
956 ok(hr == S_OK, "Got hr %#lx.\n", hr);
957
958 hr = IMediaControl_GetState(control, 0, &state);
959 ok(hr == S_OK, "Got hr %#lx.\n", hr);
960
961 IMemAllocator_Release(allocator);
962}
963
964static void test_flushing(IPin *pin, IMemInputPin *input, IMediaControl *control)
965{
966 OAFilterState state;
968 HRESULT hr;
969
970 hr = IMediaControl_Pause(control);
971 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
972
974 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
975
976 hr = IMediaControl_GetState(control, 1000, &state);
977 ok(hr == S_OK, "Got hr %#lx.\n", hr);
978
979 hr = IPin_BeginFlush(pin);
980 ok(hr == S_OK, "Got hr %#lx.\n", hr);
981
983 ok(hr == S_OK, "Got hr %#lx.\n", hr);
984
987 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
988
989 hr = IPin_EndFlush(pin);
990 ok(hr == S_OK, "Got hr %#lx.\n", hr);
991
992 /* We dropped the sample we were holding, so now we need a new one... */
993
994 hr = IMediaControl_GetState(control, 0, &state);
995 todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
996
998 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
999
1000 hr = IMediaControl_Run(control);
1001 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1003 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1004
1005 hr = IPin_BeginFlush(pin);
1006 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1007
1009 todo_wine ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
1010
1011 hr = IPin_EndFlush(pin);
1012 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1013
1015 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1016
1017 hr = IMediaControl_Stop(control);
1018 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1019}
1020
1021static void test_sample_time(IBaseFilter *filter, IPin *pin, IMemInputPin *input, IMediaControl *control)
1022{
1023 IMediaSeeking *seeking;
1025 OAFilterState state;
1026 HANDLE thread;
1027 HRESULT hr;
1028
1029 IBaseFilter_QueryInterface(filter, &IID_IMediaSeeking, (void **)&seeking);
1030
1031 hr = IMediaControl_Pause(control);
1032 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1033
1034 hr = IMediaControl_GetState(control, 0, &state);
1035 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1036
1037 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
1038 ok(hr == 0xdeadbeef, "Got hr %#lx.\n", hr);
1039
1040 thread = send_frame_time(input, 1, 0x11); /* dark blue */
1041
1042 hr = IMediaControl_GetState(control, 1000, &state);
1043 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1044
1045 hr = IMediaSeeking_GetCurrentPosition(seeking, &time);
1046 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1047 ok(time == 10000000, "Got time %s.\n", wine_dbgstr_longlong(time));
1048
1049 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1050
1051 hr = IMediaControl_Run(control);
1052 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1053
1054 ok(WaitForSingleObject(thread, 500) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1055
1057 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1058
1059 /* Sample time is relative to the time passed to Run(). Thus a sample
1060 * stamped at or earlier than 1s will now be displayed immediately, because
1061 * that time has already passed.
1062 * One may manually verify that all of the frames in this function are
1063 * rendered, including (by adding a Sleep() after sending the frame) the
1064 * dark and light green frames. Thus the video renderer does not attempt to
1065 * drop any frames that it considers late. This remains true if the frames
1066 * are marked as discontinuous. */
1067
1068 hr = join_thread(send_frame_time(input, 1, 0x22)); /* dark green */
1069 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1070
1071 hr = join_thread(send_frame_time(input, 0, 0x33)); /* light green */
1072 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1073
1074 hr = join_thread(send_frame_time(input, -2, 0x44)); /* dark red */
1075 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1076
1077 thread = send_frame_time(input, 2, 0x66); /* orange */
1078 ok(WaitForSingleObject(thread, 500) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1080 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1081
1082 thread = send_frame_time(input, 1000000, 0xff); /* white */
1083 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1084
1085 hr = IPin_BeginFlush(pin);
1086 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1088 /* If the frame makes it to Receive() in time to be rendered, we get S_OK. */
1089 ok(hr == S_OK || hr == E_FAIL, "Got hr %#lx.\n", hr);
1090 hr = IPin_EndFlush(pin);
1091 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1092
1093 thread = send_frame_time(input, 1000000, 0xff);
1094 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
1095
1096 hr = IMediaControl_Stop(control);
1097 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1099 /* If the frame makes it to Receive() in time to be rendered, we get S_OK. */
1100 ok(hr == S_OK || hr == E_FAIL, "Got hr %#lx.\n", hr);
1101
1102 IMediaSeeking_Release(seeking);
1103}
1104
1105static unsigned int check_event_code(IMediaEvent *eventsrc, DWORD timeout, LONG expected_code, LONG_PTR expected1, LONG_PTR expected2)
1106{
1107 LONG_PTR param1, param2;
1108 unsigned int ret = 0;
1109 HRESULT hr;
1110 LONG code;
1111
1112 while ((hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, timeout)) == S_OK)
1113 {
1114 if (code == expected_code)
1115 {
1116 ok(param1 == expected1, "Got param1 %#Ix.\n", param1);
1117 ok(param2 == expected2, "Got param2 %#Ix.\n", param2);
1118 ret++;
1119 }
1120 IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
1121 timeout = 0;
1122 }
1123 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
1124
1125 return ret;
1126}
1127
1128static inline unsigned int check_ec_complete(IMediaEvent *eventsrc, DWORD timeout)
1129{
1130 return check_event_code(eventsrc, timeout, EC_COMPLETE, S_OK, 0);
1131}
1132
1133static void test_eos(IPin *pin, IMemInputPin *input, IMediaControl *control)
1134{
1135 IMediaEvent *eventsrc;
1136 OAFilterState state;
1137 HRESULT hr;
1138 BOOL ret;
1139
1140 IMediaControl_QueryInterface(control, &IID_IMediaEvent, (void **)&eventsrc);
1141
1142 hr = IMediaControl_Pause(control);
1143 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1144 ret = check_ec_complete(eventsrc, 0);
1145 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1146
1147 hr = IPin_EndOfStream(pin);
1148 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1149
1150 hr = IMediaControl_GetState(control, 1000, &state);
1151 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1152 ret = check_ec_complete(eventsrc, 0);
1153 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1154
1156 todo_wine ok(hr == E_UNEXPECTED, "Got hr %#lx.\n", hr);
1157
1158 hr = IMediaControl_Run(control);
1159 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1160 ret = check_ec_complete(eventsrc, 0);
1161 ok(ret == 1, "Expected EC_COMPLETE.\n");
1162
1163 hr = IMediaControl_Stop(control);
1164 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1165 ret = check_ec_complete(eventsrc, 0);
1166 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1167
1168 /* We do not receive an EC_COMPLETE notification until the last sample is
1169 * done rendering. */
1170
1171 hr = IMediaControl_Run(control);
1172 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1174 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1175 hr = IMediaControl_GetState(control, 1000, &state);
1176 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1177 ret = check_ec_complete(eventsrc, 0);
1178 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1179
1180 hr = IPin_EndOfStream(pin);
1181 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1182 ret = check_ec_complete(eventsrc, 0);
1183 todo_wine ok(!ret, "Got unexpected EC_COMPLETE.\n");
1184 ret = check_ec_complete(eventsrc, 1600);
1185 todo_wine ok(ret == 1, "Expected EC_COMPLETE.\n");
1186
1187 hr = IMediaControl_Stop(control);
1188 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1189 ret = check_ec_complete(eventsrc, 0);
1190 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1191
1192 /* Test sending EOS while flushing. */
1193
1194 hr = IMediaControl_Run(control);
1195 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1197 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1198
1199 hr = IPin_BeginFlush(pin);
1200 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1201 hr = IPin_EndOfStream(pin);
1202 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1203 hr = IPin_EndFlush(pin);
1204 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1205
1206 hr = IMediaControl_Stop(control);
1207 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1208 ret = check_ec_complete(eventsrc, 0);
1209 todo_wine ok(!ret, "Got unexpected EC_COMPLETE.\n");
1210
1211 /* Test sending EOS and then flushing or stopping. */
1212
1213 hr = IMediaControl_Run(control);
1214 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1216 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1217 hr = IMediaControl_GetState(control, 1000, &state);
1218 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1219
1220 hr = IPin_EndOfStream(pin);
1221 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1222 ret = check_ec_complete(eventsrc, 0);
1223 todo_wine ok(!ret, "Got unexpected EC_COMPLETE.\n");
1224
1225 hr = IPin_BeginFlush(pin);
1226 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1227 hr = IPin_EndFlush(pin);
1228 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1229
1231 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1232 hr = IPin_EndOfStream(pin);
1233 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1234 ret = check_ec_complete(eventsrc, 0);
1235 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1236
1237 hr = IMediaControl_Stop(control);
1238 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1239 ret = check_ec_complete(eventsrc, 0);
1240 ok(!ret, "Got unexpected EC_COMPLETE.\n");
1241
1242 IMediaEvent_Release(eventsrc);
1243}
1244
1246 IMediaControl *control, const BITMAPINFOHEADER *expect_bih)
1247{
1248 LONG buffer[(sizeof(BITMAPINFOHEADER) + 32 * 16 * 2) / 4];
1250 OAFilterState state;
1251 IBasicVideo *video;
1252 unsigned int i;
1253 HANDLE thread;
1254 HRESULT hr;
1255 LONG size;
1256
1257 IBaseFilter_QueryInterface(filter, &IID_IBasicVideo, (void **)&video);
1258
1259 hr = IBasicVideo_GetCurrentImage(video, NULL, NULL);
1260 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1261
1262 hr = IBasicVideo_GetCurrentImage(video, NULL, buffer);
1263 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1264
1265 size = 0xdeadbeef;
1266 hr = IBasicVideo_GetCurrentImage(video, &size, NULL);
1267 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
1268 todo_wine ok(size == sizeof(BITMAPINFOHEADER) + 32 * 16 * 2, "Got size %ld.\n", size);
1269
1270 size = 0xdeadbeef;
1271 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1272 ok(hr == VFW_E_NOT_PAUSED, "Got hr %#lx.\n", hr);
1273 ok(size == 0xdeadbeef, "Got size %ld.\n", size);
1274
1275 hr = IMediaControl_Pause(control);
1276 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1277
1278 size = 0xdeadbeef;
1279 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1280 ok(hr == E_UNEXPECTED, "Got hr %#lx.\n", hr);
1281 ok(size == 0xdeadbeef, "Got size %ld.\n", size);
1282
1284 hr = IMediaControl_GetState(control, 1000, &state);
1285 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1286
1287 size = sizeof(BITMAPINFOHEADER) + 32 * 16 * 2 - 1;
1288 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1289 ok(hr == E_OUTOFMEMORY, "Got hr %#lx.\n", hr);
1290 ok(size == sizeof(BITMAPINFOHEADER) + 32 * 16 * 2 - 1, "Got size %ld.\n", size);
1291
1292 size = sizeof(BITMAPINFOHEADER) + 32 * 16 * 2;
1293 memset(buffer, 0xcc, sizeof(buffer));
1294 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1295 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1296 ok(size == sizeof(BITMAPINFOHEADER) + 32 * 16 * 2, "Got size %ld.\n", size);
1297 ok(!memcmp(bih, expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
1298 for (i = 0; i < 32 * 16 * 2; ++i)
1299 {
1300 const unsigned char *data = (unsigned char *)buffer + sizeof(BITMAPINFOHEADER);
1301 ok(data[i] == 0x55, "Got unexpected byte %02x at %u.\n", data[i], i);
1302 }
1303
1304 hr = IMediaControl_Run(control);
1305 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1307
1308 hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
1309 ok(hr == VFW_E_NOT_PAUSED, "Got hr %#lx.\n", hr);
1310
1311 hr = IMediaControl_Stop(control);
1312 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1313
1314 IBasicVideo_Release(video);
1315}
1316
1317static inline unsigned int check_ec_userabort(IMediaEvent *eventsrc, DWORD timeout)
1318{
1319 return check_event_code(eventsrc, timeout, EC_USERABORT, 0, 0);
1320}
1321
1322static void test_window_close(IPin *pin, IMemInputPin *input, IMediaControl *control)
1323{
1324 IMediaEvent *eventsrc;
1325 OAFilterState state;
1326 IOverlay *overlay;
1327 HANDLE thread;
1328 HRESULT hr;
1329 HWND hwnd;
1330 BOOL ret;
1331
1332 IMediaControl_QueryInterface(control, &IID_IMediaEvent, (void **)&eventsrc);
1333 IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
1334
1335 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
1336 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1337 IOverlay_Release(overlay);
1338
1339 hr = IMediaControl_Pause(control);
1340 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1341 ret = check_ec_userabort(eventsrc, 0);
1342 ok(!ret, "Got unexpected EC_USERABORT.\n");
1343
1344 SendMessageW(hwnd, WM_CLOSE, 0, 0);
1345
1346 hr = IMediaControl_GetState(control, 1000, &state);
1347 ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#lx.\n", hr);
1348 ret = check_ec_userabort(eventsrc, 0);
1349 ok(ret == 1, "Expected EC_USERABORT.\n");
1350
1351 ok(IsWindow(hwnd), "Window should exist.\n");
1352 ok(!IsWindowVisible(hwnd), "Window should be visible.\n");
1353
1356 todo_wine ok(ret == WAIT_OBJECT_0, "Wait failed\n");
1357 if (ret == WAIT_OBJECT_0)
1358 {
1360 ok(hr == E_UNEXPECTED, "Got hr %#lx.\n", hr);
1361 }
1363
1364 hr = IMediaControl_Run(control);
1365 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1366 ret = check_ec_userabort(eventsrc, 0);
1367 ok(!ret, "Got unexpected EC_USERABORT.\n");
1368
1369 hr = IMediaControl_Stop(control);
1370 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1371 ret = check_ec_userabort(eventsrc, 0);
1372 ok(!ret, "Got unexpected EC_USERABORT.\n");
1373
1374 /* We receive an EC_USERABORT notification immediately. */
1375
1376 hr = IMediaControl_Run(control);
1377 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1379 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1380 hr = IMediaControl_GetState(control, 1000, &state);
1381 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1382 ret = check_ec_userabort(eventsrc, 0);
1383 ok(!ret, "Got unexpected EC_USERABORT.\n");
1384
1385 SendMessageW(hwnd, WM_CLOSE, 0, 0);
1386
1387 ret = check_ec_userabort(eventsrc, 0);
1388 ok(ret == 1, "Expected EC_USERABORT.\n");
1389
1390 ok(IsWindow(hwnd), "Window should exist.\n");
1391 ok(!IsWindowVisible(hwnd), "Window should be visible.\n");
1392
1393 hr = IMediaControl_Stop(control);
1394 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1395 ret = check_ec_userabort(eventsrc, 0);
1396 ok(!ret, "Got unexpected EC_USERABORT.\n");
1397
1398 IMediaEvent_Release(eventsrc);
1399}
1400
1401static void test_connect_pin(void)
1402{
1403 VIDEOINFOHEADER vih =
1404 {
1406 .bmiHeader.biBitCount = 16,
1407 .bmiHeader.biWidth = 32,
1408 .bmiHeader.biHeight = 16,
1409 .bmiHeader.biPlanes = 1,
1410 .bmiHeader.biCompression = BI_RGB,
1411 };
1412 AM_MEDIA_TYPE req_mt =
1413 {
1414 .majortype = MEDIATYPE_Video,
1415 .formattype = FORMAT_VideoInfo,
1416 .cbFormat = sizeof(vih),
1417 .pbFormat = (BYTE *)&vih,
1418 };
1419 ALLOCATOR_PROPERTIES req_props = {1, 32 * 16 * 2, 1, 0}, ret_props;
1422 struct testfilter source;
1424 IMediaControl *control;
1427 IPin *pin, *peer;
1428 unsigned int i;
1429 HRESULT hr;
1430 ULONG ref;
1431
1432 static const GUID *subtype_tests[] =
1433 {
1434 &MEDIASUBTYPE_RGB8,
1435 &MEDIASUBTYPE_RGB565,
1436 &MEDIASUBTYPE_RGB24,
1437 &MEDIASUBTYPE_RGB32,
1438 };
1439
1441
1442 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
1443 IFilterGraph2_AddFilter(graph, filter, NULL);
1444 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
1445
1446 IBaseFilter_FindPin(filter, L"In", &pin);
1447
1448 for (i = 0; i < ARRAY_SIZE(subtype_tests); ++i)
1449 {
1450 req_mt.subtype = *subtype_tests[i];
1451 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1452 ok(hr == S_OK, "Got hr %#lx for subtype %s.\n", hr, wine_dbgstr_guid(subtype_tests[i]));
1453
1454 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
1455 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1456 hr = IFilterGraph2_Disconnect(graph, pin);
1457 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1458 }
1459
1460 req_mt.formattype = FORMAT_None;
1461 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1462 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1463 req_mt.formattype = FORMAT_VideoInfo;
1464
1465 peer = (IPin *)0xdeadbeef;
1466 hr = IPin_ConnectedTo(pin, &peer);
1467 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1468 ok(!peer, "Got peer %p.\n", peer);
1469
1470 hr = IPin_ConnectionMediaType(pin, &mt);
1471 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1472
1473 hr = IMediaControl_Pause(control);
1474 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1475 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1476 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
1477 hr = IMediaControl_Stop(control);
1478 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1479
1480 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
1481 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1482
1483 hr = IPin_ConnectedTo(pin, &peer);
1484 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1485 ok(peer == &source.source.pin.IPin_iface, "Got peer %p.\n", peer);
1486 IPin_Release(peer);
1487
1488 hr = IPin_ConnectionMediaType(pin, &mt);
1489 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1490 ok(compare_media_types(&mt, &req_mt), "Media types didn't match.\n");
1491
1492 hr = IMediaControl_Pause(control);
1493 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1494 hr = IFilterGraph2_Disconnect(graph, pin);
1495 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
1496 hr = IMediaControl_Stop(control);
1497 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1498
1499 IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input);
1500
1502
1503 hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
1504 &IID_IMemAllocator, (void **)&allocator);
1505 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1506 hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props);
1507 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1508 ok(!memcmp(&ret_props, &req_props, sizeof(req_props)), "Properties did not match.\n");
1509 hr = IMemInputPin_NotifyAllocator(input, allocator, TRUE);
1510 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1511 hr = IMemAllocator_Commit(allocator);
1512 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1513
1514 hr = IMemInputPin_ReceiveCanBlock(input);
1515 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1516
1520 test_eos(pin, input, control);
1523
1524 hr = IFilterGraph2_Disconnect(graph, pin);
1525 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1526 hr = IFilterGraph2_Disconnect(graph, pin);
1527 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1528 ok(source.source.pin.peer == pin, "Got peer %p.\n", peer);
1529 IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
1530
1531 peer = (IPin *)0xdeadbeef;
1532 hr = IPin_ConnectedTo(pin, &peer);
1533 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1534 ok(!peer, "Got peer %p.\n", peer);
1535
1536 hr = IPin_ConnectionMediaType(pin, &mt);
1537 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1538
1539 ref = IMemAllocator_Release(allocator);
1540 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1541 IMemInputPin_Release(input);
1542 IPin_Release(pin);
1543 IMediaControl_Release(control);
1544 ref = IFilterGraph2_Release(graph);
1545 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1546 ref = IBaseFilter_Release(filter);
1547 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1548 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
1549 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1550}
1551
1553{
1555 FILTER_STATE state;
1556 HRESULT hr;
1557 ULONG ref;
1558
1559 hr = IBaseFilter_GetState(filter, 0, &state);
1560 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1561 ok(state == State_Stopped, "Got state %u.\n", state);
1562
1563 hr = IBaseFilter_Pause(filter);
1564 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1565
1566 hr = IBaseFilter_GetState(filter, 0, &state);
1567 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1568 ok(state == State_Paused, "Got state %u.\n", state);
1569
1570 hr = IBaseFilter_Run(filter, 0);
1571 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1572
1573 hr = IBaseFilter_GetState(filter, 0, &state);
1574 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1575 ok(state == State_Running, "Got state %u.\n", state);
1576
1577 hr = IBaseFilter_Pause(filter);
1578 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1579
1580 hr = IBaseFilter_GetState(filter, 0, &state);
1581 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1582 ok(state == State_Paused, "Got state %u.\n", state);
1583
1584 hr = IBaseFilter_Stop(filter);
1585 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1586
1587 hr = IBaseFilter_GetState(filter, 0, &state);
1588 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1589 ok(state == State_Stopped, "Got state %u.\n", state);
1590
1591 hr = IBaseFilter_Run(filter, 0);
1592 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1593
1594 hr = IBaseFilter_GetState(filter, 0, &state);
1595 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1596 ok(state == State_Running, "Got state %u.\n", state);
1597
1598 hr = IBaseFilter_Stop(filter);
1599 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1600
1601 hr = IBaseFilter_GetState(filter, 0, &state);
1602 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1603 ok(state == State_Stopped, "Got state %u.\n", state);
1604
1605 ref = IBaseFilter_Release(filter);
1606 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1607}
1608
1609static void test_overlay(void)
1610{
1612 IOverlay *overlay;
1613 HRESULT hr;
1614 ULONG ref;
1615 IPin *pin;
1616 HWND hwnd;
1617
1618 IBaseFilter_FindPin(filter, L"In", &pin);
1619
1620 hr = IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
1621 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1622
1623 hwnd = (HWND)0xdeadbeef;
1624 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
1625 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1626 ok(hwnd && hwnd != (HWND)0xdeadbeef, "Got invalid window %p.\n", hwnd);
1627
1628 IOverlay_Release(overlay);
1629 IPin_Release(pin);
1630 ref = IBaseFilter_Release(filter);
1631 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1632}
1633
1634/* try to make sure pending X events have been processed before continuing */
1635static void flush_events(void)
1636{
1637 int diff = 200;
1638 DWORD time;
1639 MSG msg;
1640
1641 time = GetTickCount() + diff;
1642 while (diff > 0)
1643 {
1645 break;
1646 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
1648 diff = time - GetTickCount();
1649 }
1650}
1651
1653{
1654 if (winetest_debug > 1)
1655 trace("hwnd %p, msg %#x, wparam %#Ix, lparam %#Ix.\n", hwnd, msg, wparam, lparam);
1656
1657 if (wparam == 0xdeadbeef)
1658 return 0;
1659
1660 return DefWindowProcA(hwnd, msg, wparam, lparam);
1661}
1662
1663static void test_video_window_caption(IVideoWindow *window, HWND hwnd)
1664{
1665 WCHAR text[50];
1666 BSTR caption;
1667 HRESULT hr;
1668
1669 hr = IVideoWindow_get_Caption(window, &caption);
1670 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1671 ok(!wcscmp(caption, L"ActiveMovie Window"), "Got caption %s.\n", wine_dbgstr_w(caption));
1672 SysFreeString(caption);
1673
1675 ok(!wcscmp(text, L"ActiveMovie Window"), "Got caption %s.\n", wine_dbgstr_w(text));
1676
1677 caption = SysAllocString(L"foo");
1678 hr = IVideoWindow_put_Caption(window, caption);
1679 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1680 SysFreeString(caption);
1681
1682 hr = IVideoWindow_get_Caption(window, &caption);
1683 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1684 ok(!wcscmp(caption, L"foo"), "Got caption %s.\n", wine_dbgstr_w(caption));
1685 SysFreeString(caption);
1686
1688 ok(!wcscmp(text, L"foo"), "Got caption %s.\n", wine_dbgstr_w(text));
1689}
1690
1691static void test_video_window_style(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
1692{
1693 HRESULT hr;
1694 LONG style;
1695
1696 hr = IVideoWindow_get_WindowStyle(window, &style);
1697 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1699 "Got style %#lx.\n", style);
1700
1703 "Got style %#lx.\n", style);
1704
1705 hr = IVideoWindow_put_WindowStyle(window, style | WS_DISABLED);
1706 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1707 hr = IVideoWindow_put_WindowStyle(window, style | WS_HSCROLL);
1708 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1709 hr = IVideoWindow_put_WindowStyle(window, style | WS_VSCROLL);
1710 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1711 hr = IVideoWindow_put_WindowStyle(window, style | WS_MAXIMIZE);
1712 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1713 hr = IVideoWindow_put_WindowStyle(window, style | WS_MINIMIZE);
1714 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1715
1716 hr = IVideoWindow_put_WindowStyle(window, style & ~WS_CLIPCHILDREN);
1717 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1718
1719 hr = IVideoWindow_get_WindowStyle(window, &style);
1720 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1721 ok(style == (WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW), "Got style %#lx.\n", style);
1722
1724 ok(style == (WS_CLIPSIBLINGS | WS_OVERLAPPEDWINDOW), "Got style %#lx.\n", style);
1725
1727 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1728
1729 hr = IVideoWindow_get_WindowStyleEx(window, &style);
1730 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1731 ok(style == WS_EX_WINDOWEDGE, "Got style %#lx.\n", style);
1732
1734 ok(style == WS_EX_WINDOWEDGE, "Got style %#lx.\n", style);
1735
1736 hr = IVideoWindow_put_WindowStyleEx(window, style | WS_EX_TRANSPARENT);
1737 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1738
1739 hr = IVideoWindow_get_WindowStyleEx(window, &style);
1740 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1741 ok(style == (WS_EX_WINDOWEDGE | WS_EX_TRANSPARENT), "Got style %#lx.\n", style);
1742
1744 ok(style == (WS_EX_WINDOWEDGE | WS_EX_TRANSPARENT), "Got style %#lx.\n", style);
1745}
1746
1748{
1749 DWORD pid;
1752 {
1753 *(HWND *)ctx = hwnd;
1754 return FALSE;
1755 }
1756 return TRUE;
1757}
1758
1760{
1761 HWND hwnd;
1763 return hwnd;
1764}
1765
1766static void test_video_window_state(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
1767{
1768 HRESULT hr;
1769 LONG state;
1770 HWND top;
1771
1772 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1773
1774 hr = IVideoWindow_get_WindowState(window, &state);
1775 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1776 ok(state == SW_HIDE, "Got state %ld.\n", state);
1777
1778 hr = IVideoWindow_get_Visible(window, &state);
1779 ok(state == OAFALSE, "Got state %ld.\n", state);
1780
1781 ok(!IsWindowVisible(hwnd), "Window should not be visible.\n");
1782 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
1783 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1784
1785 hr = IVideoWindow_put_WindowState(window, SW_SHOWNA);
1786 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1787
1788 hr = IVideoWindow_get_WindowState(window, &state);
1789 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1790 ok(state == SW_SHOW, "Got state %ld.\n", state);
1791
1792 hr = IVideoWindow_get_Visible(window, &state);
1793 ok(state == OATRUE, "Got state %ld.\n", state);
1794
1795 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
1796 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
1797 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1798 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1799 top = get_top_window();
1800 ok(top == hwnd, "Got top window %p.\n", top);
1801
1802 hr = IVideoWindow_put_WindowState(window, SW_MINIMIZE);
1803 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1804
1805 hr = IVideoWindow_get_WindowState(window, &state);
1806 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1807 ok(state == SW_MINIMIZE, "Got state %ld.\n", state);
1808
1809 hr = IVideoWindow_get_Visible(window, &state);
1810 ok(state == OATRUE, "Got state %ld.\n", state);
1811
1812 ok(IsWindowVisible(hwnd), "Window should be visible.\n");
1813 ok(IsIconic(hwnd), "Window should be minimized.\n");
1814 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1815 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1816
1817 hr = IVideoWindow_put_WindowState(window, SW_RESTORE);
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_SHOW, "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 not be minimized.\n");
1829 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1830 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
1831
1832 hr = IVideoWindow_put_WindowState(window, SW_MAXIMIZE);
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_MAXIMIZE, "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 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_RESTORE);
1848 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1849
1850 hr = IVideoWindow_put_WindowState(window, SW_HIDE);
1851 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1852
1853 hr = IVideoWindow_get_WindowState(window, &state);
1854 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1855 ok(state == SW_HIDE, "Got state %ld.\n", state);
1856
1857 hr = IVideoWindow_get_Visible(window, &state);
1858 ok(state == OAFALSE, "Got state %ld.\n", state);
1859
1860 ok(!IsWindowVisible(hwnd), "Window should not be visible.\n");
1861 ok(!IsIconic(hwnd), "Window should not be minimized.\n");
1862 ok(!IsZoomed(hwnd), "Window should not be maximized.\n");
1863 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1864
1865 hr = IVideoWindow_put_Visible(window, OATRUE);
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_SHOW, "Got state %ld.\n", state);
1871
1872 hr = IVideoWindow_get_Visible(window, &state);
1873 ok(state == OATRUE, "Got state %ld.\n", state);
1874
1875 ok(IsWindowVisible(hwnd), "Window should 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() == hwnd, "Got active window %p.\n", GetActiveWindow());
1879
1880 hr = IVideoWindow_put_Visible(window, OAFALSE);
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_HIDE, "Got state %ld.\n", state);
1886
1887 hr = IVideoWindow_get_Visible(window, &state);
1888 ok(state == OAFALSE, "Got state %ld.\n", state);
1889
1890 ok(!IsWindowVisible(hwnd), "Window should not 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() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1894
1895 hr = IVideoWindow_put_WindowState(window, SW_SHOWNA);
1896 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1897
1898 hr = IVideoWindow_SetWindowForeground(window, TRUE);
1899 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1900
1901 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1902 hr = IVideoWindow_SetWindowForeground(window, OATRUE);
1903 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1904 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
1905 ok(GetFocus() == hwnd, "Got focus window %p.\n", GetFocus());
1906 ok(GetForegroundWindow() == hwnd, "Got foreground window %p.\n", GetForegroundWindow());
1907 top = get_top_window();
1908 ok(top == hwnd, "Got top window %p.\n", top);
1909
1910 hr = IVideoWindow_SetWindowForeground(window, OAFALSE);
1911 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1912 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
1913 ok(GetFocus() == hwnd, "Got focus window %p.\n", GetFocus());
1914 ok(GetForegroundWindow() == hwnd, "Got foreground window %p.\n", GetForegroundWindow());
1915 top = get_top_window();
1916 ok(top == hwnd, "Got top window %p.\n", top);
1917
1918 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1919 hr = IVideoWindow_SetWindowForeground(window, OAFALSE);
1920 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1921 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
1922 ok(GetFocus() == our_hwnd, "Got focus window %p.\n", GetFocus());
1923 ok(GetForegroundWindow() == our_hwnd, "Got foreground window %p.\n", GetForegroundWindow());
1924 top = get_top_window();
1925 ok(top == hwnd, "Got top window %p.\n", top);
1926}
1927
1928static void test_video_window_position(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
1929{
1930 LONG left, width, top, height, expect_width, expect_height;
1931 RECT rect = {0, 0, 640, 480};
1932 HWND top_hwnd;
1933 HRESULT hr;
1934
1935 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1936
1938 expect_width = rect.right - rect.left;
1939 expect_height = rect.bottom - rect.top;
1940
1941 hr = IVideoWindow_put_Left(window, 0);
1942 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1943 hr = IVideoWindow_put_Top(window, 0);
1944 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1945
1946 hr = IVideoWindow_get_Left(window, &left);
1947 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1948 ok(left == 0, "Got left %ld.\n", left);
1949 hr = IVideoWindow_get_Top(window, &top);
1950 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1951 ok(top == 0, "Got top %ld.\n", top);
1952 hr = IVideoWindow_get_Width(window, &width);
1953 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1954 ok(width == expect_width, "Got width %ld.\n", width);
1955 hr = IVideoWindow_get_Height(window, &height);
1956 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1957 ok(height == expect_height, "Got height %ld.\n", height);
1958 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
1959 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1960 ok(left == 0, "Got left %ld.\n", left);
1961 ok(top == 0, "Got top %ld.\n", top);
1962 ok(width == expect_width, "Got width %ld.\n", width);
1963 ok(height == expect_height, "Got height %ld.\n", height);
1965 ok(rect.left == 0, "Got window left %ld.\n", rect.left);
1966 ok(rect.top == 0, "Got window top %ld.\n", rect.top);
1967 ok(rect.right == expect_width, "Got window right %ld.\n", rect.right);
1968 ok(rect.bottom == expect_height, "Got window bottom %ld.\n", rect.bottom);
1969
1970 hr = IVideoWindow_put_Left(window, 10);
1971 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1972
1973 hr = IVideoWindow_get_Left(window, &left);
1974 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1975 ok(left == 10, "Got left %ld.\n", left);
1976 hr = IVideoWindow_get_Top(window, &top);
1977 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1978 ok(top == 0, "Got top %ld.\n", top);
1979 hr = IVideoWindow_get_Width(window, &width);
1980 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1981 ok(width == expect_width, "Got width %ld.\n", width);
1982 hr = IVideoWindow_get_Height(window, &height);
1983 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1984 ok(height == expect_height, "Got height %ld.\n", height);
1985 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
1986 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1987 ok(left == 10, "Got left %ld.\n", left);
1988 ok(top == 0, "Got top %ld.\n", top);
1989 ok(width == expect_width, "Got width %ld.\n", width);
1990 ok(height == expect_height, "Got height %ld.\n", height);
1992 ok(rect.left == 10, "Got window left %ld.\n", rect.left);
1993 ok(rect.top == 0, "Got window top %ld.\n", rect.top);
1994 ok(rect.right == 10 + expect_width, "Got window right %ld.\n", rect.right);
1995 ok(rect.bottom == expect_height, "Got window bottom %ld.\n", rect.bottom);
1996
1997 hr = IVideoWindow_put_Height(window, 200);
1998 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1999
2000 hr = IVideoWindow_get_Left(window, &left);
2001 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2002 ok(left == 10, "Got left %ld.\n", left);
2003 hr = IVideoWindow_get_Top(window, &top);
2004 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2005 ok(top == 0, "Got top %ld.\n", top);
2006 hr = IVideoWindow_get_Width(window, &width);
2007 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2008 ok(width == expect_width, "Got width %ld.\n", width);
2009 hr = IVideoWindow_get_Height(window, &height);
2010 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2011 ok(height == 200, "Got height %ld.\n", height);
2012 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
2013 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2014 ok(left == 10, "Got left %ld.\n", left);
2015 ok(top == 0, "Got top %ld.\n", top);
2016 ok(width == expect_width, "Got width %ld.\n", width);
2017 ok(height == 200, "Got height %ld.\n", height);
2019 ok(rect.left == 10, "Got window left %ld.\n", rect.left);
2020 ok(rect.top == 0, "Got window top %ld.\n", rect.top);
2021 ok(rect.right == 10 + expect_width, "Got window right %ld.\n", rect.right);
2022 ok(rect.bottom == 200, "Got window bottom %ld.\n", rect.bottom);
2023
2024 hr = IVideoWindow_SetWindowPosition(window, 100, 200, 300, 400);
2025 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2026
2027 hr = IVideoWindow_get_Left(window, &left);
2028 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2029 ok(left == 100, "Got left %ld.\n", left);
2030 hr = IVideoWindow_get_Top(window, &top);
2031 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2032 ok(top == 200, "Got top %ld.\n", top);
2033 hr = IVideoWindow_get_Width(window, &width);
2034 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2035 ok(width == 300, "Got width %ld.\n", width);
2036 hr = IVideoWindow_get_Height(window, &height);
2037 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2038 ok(height == 400, "Got height %ld.\n", height);
2039 hr = IVideoWindow_GetWindowPosition(window, &left, &top, &width, &height);
2040 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2041 ok(left == 100, "Got left %ld.\n", left);
2042 ok(top == 200, "Got top %ld.\n", top);
2043 ok(width == 300, "Got width %ld.\n", width);
2044 ok(height == 400, "Got height %ld.\n", height);
2046 ok(rect.left == 100, "Got window left %ld.\n", rect.left);
2047 ok(rect.top == 200, "Got window top %ld.\n", rect.top);
2048 ok(rect.right == 400, "Got window right %ld.\n", rect.right);
2049 ok(rect.bottom == 600, "Got window bottom %ld.\n", rect.bottom);
2050
2051 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2052 top_hwnd = get_top_window();
2053 ok(top_hwnd == our_hwnd, "Got top window %p.\n", top_hwnd);
2054}
2055
2056static void test_video_window_owner(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
2057{
2058 HWND parent, top_hwnd;
2059 LONG style, state;
2060 OAHWND oahwnd;
2061 HRESULT hr;
2062
2063 SetWindowPos(our_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
2064
2065 hr = IVideoWindow_get_Owner(window, &oahwnd);
2066 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2067 ok(!oahwnd, "Got owner %#Ix.\n", oahwnd);
2068
2070 ok(parent == GetDesktopWindow(), "Got parent %p.\n", parent);
2072 ok(!(style & WS_CHILD), "Got style %#lx.\n", style);
2073
2074 hr = IVideoWindow_put_Owner(window, (OAHWND)our_hwnd);
2075 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2076
2077 hr = IVideoWindow_get_Owner(window, &oahwnd);
2078 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2079 ok(oahwnd == (OAHWND)our_hwnd, "Got owner %#Ix.\n", oahwnd);
2080
2082 ok(parent == our_hwnd, "Got parent %p.\n", parent);
2084 ok((style & WS_CHILD), "Got style %#lx.\n", style);
2085
2086 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2087 top_hwnd = get_top_window();
2088 ok(top_hwnd == our_hwnd, "Got top window %p.\n", top_hwnd);
2089
2090 ShowWindow(our_hwnd, SW_HIDE);
2091
2092 hr = IVideoWindow_put_Visible(window, OATRUE);
2093 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2094
2095 hr = IVideoWindow_get_Visible(window, &state);
2096 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2097 ok(state == OAFALSE, "Got state %ld.\n", state);
2098
2099 hr = IVideoWindow_put_Owner(window, 0);
2100 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2101
2102 hr = IVideoWindow_get_Owner(window, &oahwnd);
2103 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2104 ok(!oahwnd, "Got owner %#Ix.\n", oahwnd);
2105
2107 ok(parent == GetDesktopWindow(), "Got parent %p.\n", parent);
2109 ok(!(style & WS_CHILD), "Got style %#lx.\n", style);
2110
2111 ok(GetActiveWindow() == hwnd, "Got active window %p.\n", GetActiveWindow());
2112 top_hwnd = get_top_window();
2113 ok(top_hwnd == hwnd, "Got top window %p.\n", top_hwnd);
2114
2115 hr = IVideoWindow_get_Visible(window, &state);
2116 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2117 ok(state == OATRUE, "Got state %ld.\n", state);
2118}
2119
2121{
2122 IVideoWindow *window;
2125};
2126
2128{
2129 const struct notify_message_params *params = arg;
2130 HRESULT hr = IVideoWindow_NotifyOwnerMessage(params->window, (OAHWND)params->hwnd, params->message, 0, 0);
2131 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2132 return 0;
2133}
2134
2135static void test_video_window_messages(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
2136{
2138 unsigned int i;
2139 OAHWND oahwnd;
2140 HANDLE thread;
2141 HRESULT hr;
2142 BOOL ret;
2143 MSG msg;
2144
2145 static UINT drain_tests[] =
2146 {
2157 WM_KEYDOWN,
2158 WM_KEYUP,
2169 };
2170
2171 flush_events();
2172
2173 hr = IVideoWindow_get_MessageDrain(window, &oahwnd);
2174 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2175 ok(!oahwnd, "Got window %#Ix.\n", oahwnd);
2176
2177 hr = IVideoWindow_put_MessageDrain(window, (OAHWND)our_hwnd);
2178 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2179
2180 hr = IVideoWindow_get_MessageDrain(window, &oahwnd);
2181 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2182 ok(oahwnd == (OAHWND)our_hwnd, "Got window %#Ix.\n", oahwnd);
2183
2184 for (i = 0; i < ARRAY_SIZE(drain_tests); ++i)
2185 {
2186 SendMessageA(hwnd, drain_tests[i], 0xdeadbeef, 0);
2187 ret = PeekMessageA(&msg, 0, drain_tests[i], drain_tests[i], PM_REMOVE);
2188 ok(ret, "Expected a message.\n");
2189 ok(msg.hwnd == our_hwnd, "Got hwnd %p.\n", msg.hwnd);
2190 ok(msg.message == drain_tests[i], "Got message %#x.\n", msg.message);
2191 ok(msg.wParam == 0xdeadbeef, "Got wparam %#Ix.\n", msg.wParam);
2192 ok(!msg.lParam, "Got lparam %#Ix.\n", msg.lParam);
2194
2195 ret = PeekMessageA(&msg, 0, drain_tests[i], drain_tests[i], PM_REMOVE);
2196 ok(!ret, "Got unexpected message %#x.\n", msg.message);
2197 }
2198
2199 hr = IVideoWindow_put_MessageDrain(window, 0);
2200 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2201
2202 hr = IVideoWindow_put_Owner(window, (OAHWND)our_hwnd);
2203 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2204
2205 flush_events();
2206
2207 /* Demonstrate that messages should be sent, not posted, and that only some
2208 * messages should be forwarded. A previous implementation unconditionally
2209 * posted all messages. */
2210
2211 hr = IVideoWindow_NotifyOwnerMessage(window, (OAHWND)our_hwnd, WM_SYSCOLORCHANGE, 0, 0);
2212 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2213
2214 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2215 {
2216 ok(msg.message != WM_SYSCOLORCHANGE, "WM_SYSCOLORCHANGE should not be posted.\n");
2218 }
2219
2220 hr = IVideoWindow_NotifyOwnerMessage(window, (OAHWND)our_hwnd, WM_FONTCHANGE, 0, 0);
2221 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2222
2223 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2224 {
2225 ok(msg.message != WM_FONTCHANGE, "WM_FONTCHANGE should not be posted.\n");
2227 }
2228
2229 params.window = window;
2230 params.hwnd = our_hwnd;
2231 params.message = WM_SYSCOLORCHANGE;
2233 ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block.\n");
2234
2235 while ((ret = MsgWaitForMultipleObjects(1, &thread, FALSE, 1000, QS_ALLINPUT)) == 1)
2236 {
2237 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2238 {
2239 ok(msg.message != WM_SYSCOLORCHANGE, "WM_SYSCOLORCHANGE should not be posted.\n");
2241 }
2242 }
2243 ok(!ret, "Wait timed out.\n");
2245
2246 params.message = WM_FONTCHANGE;
2248 ok(!WaitForSingleObject(thread, 1000), "Thread should not block.\n");
2250
2251 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
2252 {
2253 ok(msg.message != WM_FONTCHANGE, "WM_FONTCHANGE should not be posted.\n");
2255 }
2256
2257 hr = IVideoWindow_put_Owner(window, 0);
2258 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2259}
2260
2262{
2263 IMediaControl *control;
2264 HRESULT hr;
2265 LONG l;
2266
2267 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
2268
2269 hr = IVideoWindow_get_AutoShow(window, &l);
2270 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2271 ok(l == OATRUE, "Got %ld.\n", l);
2272
2273 hr = IVideoWindow_put_Visible(window, OAFALSE);
2274 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2275
2276 hr = IMediaControl_Pause(control);
2277 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2278
2279 hr = IVideoWindow_get_Visible(window, &l);
2280 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2281 ok(l == OATRUE, "Got %ld.\n", l);
2282
2283 hr = IMediaControl_Stop(control);
2284 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2285
2286 hr = IVideoWindow_get_Visible(window, &l);
2287 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2288 ok(l == OATRUE, "Got %ld.\n", l);
2289
2290 hr = IVideoWindow_put_AutoShow(window, OAFALSE);
2291 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2292
2293 hr = IVideoWindow_put_Visible(window, OAFALSE);
2294 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2295
2296 hr = IMediaControl_Pause(control);
2297 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2298
2299 hr = IVideoWindow_get_Visible(window, &l);
2300 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2301 ok(l == OAFALSE, "Got %ld.\n", l);
2302
2303 hr = IMediaControl_Stop(control);
2304 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2305
2306 IMediaControl_Release(control);
2307}
2308
2309static void test_video_window(void)
2310{
2311 VIDEOINFOHEADER vih =
2312 {
2314 .bmiHeader.biBitCount = 24,
2315 .bmiHeader.biWidth = 640,
2316 .bmiHeader.biHeight = 480,
2317 .bmiHeader.biPlanes = 1,
2318 .bmiHeader.biCompression = BI_RGB,
2319 };
2320 AM_MEDIA_TYPE req_mt =
2321 {
2322 .majortype = MEDIATYPE_Video,
2323 .subtype = MEDIASUBTYPE_RGB24,
2324 .formattype = FORMAT_VideoInfo,
2325 .cbFormat = sizeof(vih),
2326 .pbFormat = (BYTE *)&vih,
2327 };
2329 WNDCLASSA window_class = {0};
2330 struct testfilter source;
2331 LONG width, height, l;
2332 ULONG_PTR background;
2333 IVideoWindow *window;
2335 HWND hwnd, our_hwnd;
2336 IOverlay *overlay;
2337 BSTR caption;
2338 HRESULT hr;
2339 DWORD tid;
2340 ULONG ref;
2341 IPin *pin;
2342 RECT rect;
2343
2344 window_class.lpszClassName = "wine_test_class";
2345 window_class.lpfnWndProc = window_proc;
2346 RegisterClassA(&window_class);
2347 our_hwnd = CreateWindowA("wine_test_class", "test window", WS_VISIBLE | WS_OVERLAPPEDWINDOW,
2348 100, 200, 300, 400, NULL, NULL, NULL, NULL);
2349 flush_events();
2350
2352 flush_events();
2353
2355 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2356
2357 IBaseFilter_FindPin(filter, L"In", &pin);
2358
2359 hr = IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay);
2360 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2361
2362 hr = IOverlay_GetWindowHandle(overlay, &hwnd);
2363 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2364 if (winetest_debug > 1) trace("ours %p, theirs %p\n", our_hwnd, hwnd);
2366
2368 ok(tid == GetCurrentThreadId(), "Expected tid %#lx, got %#lx.\n", GetCurrentThreadId(), tid);
2369
2371 ok(!background, "Expected NULL brush, got %#Ix\n", background);
2372
2373 hr = IBaseFilter_QueryInterface(filter, &IID_IVideoWindow, (void **)&window);
2374 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2375
2376 hr = IVideoWindow_get_Visible(window, NULL);
2377 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2378
2379 hr = IVideoWindow_get_Caption(window, &caption);
2380 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2381
2382 caption = SysAllocString(L"foo");
2383 hr = IVideoWindow_put_Caption(window, caption);
2384 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2385 SysFreeString(caption);
2386
2387 hr = IVideoWindow_get_WindowStyle(window, &l);
2388 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2389
2390 hr = IVideoWindow_put_WindowStyle(window, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
2391 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2392
2393 hr = IVideoWindow_get_AutoShow(window, &l);
2394 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2395
2396 hr = IVideoWindow_put_AutoShow(window, OAFALSE);
2397 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2398
2399 hr = IVideoWindow_put_Owner(window, (OAHWND)our_hwnd);
2400 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2401
2402 hr = IVideoWindow_put_MessageDrain(window, (OAHWND)our_hwnd);
2403 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2404
2405 hr = IVideoWindow_put_Visible(window, OATRUE);
2406 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2407
2408 hr = IVideoWindow_SetWindowPosition(window, 100, 200, 300, 400);
2409 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2410
2412 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, NULL);
2413 IFilterGraph2_AddFilter(graph, filter, NULL);
2414 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
2415 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2416
2418 ok(GetActiveWindow() == our_hwnd, "Got active window %p.\n", GetActiveWindow());
2419
2427
2428 hr = IVideoWindow_put_FullScreenMode(window, OATRUE);
2429 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2430
2431 hr = IVideoWindow_get_FullScreenMode(window, &l);
2432 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
2433
2434 hr = IVideoWindow_GetMinIdealImageSize(window, &width, &height);
2435 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2436 ok(width == 640, "Got width %ld.\n", width);
2437 ok(height == 480, "Got height %ld.\n", height);
2438
2439 hr = IVideoWindow_GetMaxIdealImageSize(window, &width, &height);
2440 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2441 ok(width == 640, "Got width %ld.\n", width);
2442 ok(height == 480, "Got height %ld.\n", height);
2443
2444 IFilterGraph2_Release(graph);
2445 IVideoWindow_Release(window);
2446 IOverlay_Release(overlay);
2447 IPin_Release(pin);
2448 ref = IBaseFilter_Release(filter);
2449 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2450 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
2451 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2452 DestroyWindow(our_hwnd);
2453}
2454
2455static void check_source_position_(int line, IBasicVideo *video,
2456 LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
2457{
2458 LONG left, top, width, height, l;
2459 HRESULT hr;
2460
2461 left = top = width = height = 0xdeadbeef;
2462 hr = IBasicVideo_GetSourcePosition(video, &left, &top, &width, &height);
2463 ok_(__FILE__,line)(hr == S_OK, "Got hr %#lx.\n", hr);
2464 ok_(__FILE__,line)(left == expect_left, "Got left %ld.\n", left);
2465 ok_(__FILE__,line)(top == expect_top, "Got top %ld.\n", top);
2466 ok_(__FILE__,line)(width == expect_width, "Got width %ld.\n", width);
2467 ok_(__FILE__,line)(height == expect_height, "Got height %ld.\n", height);
2468
2469 l = 0xdeadbeef;
2470 hr = IBasicVideo_get_SourceLeft(video, &l);
2471 ok_(__FILE__,line)(hr == S_OK, "Failed to get left, hr %#lx.\n", hr);
2472 ok_(__FILE__,line)(l == left, "Got left %ld.\n", l);
2473
2474 l = 0xdeadbeef;
2475 hr = IBasicVideo_get_SourceTop(video, &l);
2476 ok_(__FILE__,line)(hr == S_OK, "Failed to get top, hr %#lx.\n", hr);
2477 ok_(__FILE__,line)(l == top, "Got top %ld.\n", l);
2478
2479 l = 0xdeadbeef;
2480 hr = IBasicVideo_get_SourceWidth(video, &l);
2481 ok_(__FILE__,line)(hr == S_OK, "Failed to get width, hr %#lx.\n", hr);
2482 ok_(__FILE__,line)(l == width, "Got width %ld.\n", l);
2483
2484 l = 0xdeadbeef;
2485 hr = IBasicVideo_get_SourceHeight(video, &l);
2486 ok_(__FILE__,line)(hr == S_OK, "Failed to get height, hr %#lx.\n", hr);
2487 ok_(__FILE__,line)(l == height, "Got height %ld.\n", l);
2488}
2489#define check_source_position(a,b,c,d,e) check_source_position_(__LINE__,a,b,c,d,e)
2490
2491static void test_basic_video_source(IBasicVideo *video)
2492{
2493 HRESULT hr;
2494
2495 check_source_position(video, 0, 0, 600, 400);
2496 hr = IBasicVideo_IsUsingDefaultSource(video);
2497 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2498
2499 hr = IBasicVideo_put_SourceLeft(video, -10);
2500 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2501 hr = IBasicVideo_put_SourceLeft(video, 10);
2502 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2503
2504 hr = IBasicVideo_put_SourceTop(video, -10);
2505 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2506 hr = IBasicVideo_put_SourceTop(video, 10);
2507 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2508
2509 hr = IBasicVideo_put_SourceWidth(video, -500);
2510 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2511 hr = IBasicVideo_put_SourceWidth(video, 0);
2512 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2513 hr = IBasicVideo_put_SourceWidth(video, 700);
2514 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2515 hr = IBasicVideo_put_SourceWidth(video, 500);
2516 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2517 check_source_position(video, 0, 0, 500, 400);
2518 hr = IBasicVideo_IsUsingDefaultSource(video);
2519 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2520
2521 hr = IBasicVideo_put_SourceHeight(video, -300);
2522 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2523 hr = IBasicVideo_put_SourceHeight(video, 0);
2524 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2525 hr = IBasicVideo_put_SourceHeight(video, 600);
2526 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2527 hr = IBasicVideo_put_SourceHeight(video, 300);
2528 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2529 check_source_position(video, 0, 0, 500, 300);
2530 hr = IBasicVideo_IsUsingDefaultSource(video);
2531 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2532
2533 hr = IBasicVideo_put_SourceLeft(video, -10);
2534 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2535 hr = IBasicVideo_put_SourceLeft(video, 10);
2536 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2537 check_source_position(video, 10, 0, 500, 300);
2538 hr = IBasicVideo_IsUsingDefaultSource(video);
2539 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2540
2541 hr = IBasicVideo_put_SourceTop(video, -10);
2542 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2543 hr = IBasicVideo_put_SourceTop(video, 20);
2544 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2545 check_source_position(video, 10, 20, 500, 300);
2546 hr = IBasicVideo_IsUsingDefaultSource(video);
2547 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2548
2549 hr = IBasicVideo_SetSourcePosition(video, 4, 5, 60, 40);
2550 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2551 check_source_position(video, 4, 5, 60, 40);
2552 hr = IBasicVideo_IsUsingDefaultSource(video);
2553 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2554
2555 hr = IBasicVideo_SetSourcePosition(video, 0, 0, 600, 400);
2556 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2557 check_source_position(video, 0, 0, 600, 400);
2558 hr = IBasicVideo_IsUsingDefaultSource(video);
2559 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2560
2561 hr = IBasicVideo_SetSourcePosition(video, 4, 5, 60, 40);
2562 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2563 hr = IBasicVideo_SetDefaultSourcePosition(video);
2564 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2565 check_source_position(video, 0, 0, 600, 400);
2566 hr = IBasicVideo_IsUsingDefaultSource(video);
2567 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2568}
2569
2570static void check_destination_position_(int line, IBasicVideo *video,
2571 LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
2572{
2573 LONG left, top, width, height, l;
2574 HRESULT hr;
2575
2576 left = top = width = height = 0xdeadbeef;
2577 hr = IBasicVideo_GetDestinationPosition(video, &left, &top, &width, &height);
2578 ok_(__FILE__,line)(hr == S_OK, "Failed to get position, hr %#lx.\n", hr);
2579 ok_(__FILE__,line)(left == expect_left, "Got left %ld.\n", left);
2580 ok_(__FILE__,line)(top == expect_top, "Got top %ld.\n", top);
2581 ok_(__FILE__,line)(width == expect_width, "Got width %ld.\n", width);
2582 ok_(__FILE__,line)(height == expect_height, "Got height %ld.\n", height);
2583
2584 l = 0xdeadbeef;
2585 hr = IBasicVideo_get_DestinationLeft(video, &l);
2586 ok_(__FILE__,line)(hr == S_OK, "Failed to get left, hr %#lx.\n", hr);
2587 ok_(__FILE__,line)(l == left, "Got left %ld.\n", l);
2588
2589 l = 0xdeadbeef;
2590 hr = IBasicVideo_get_DestinationTop(video, &l);
2591 ok_(__FILE__,line)(hr == S_OK, "Failed to get top, hr %#lx.\n", hr);
2592 ok_(__FILE__,line)(l == top, "Got top %ld.\n", l);
2593
2594 l = 0xdeadbeef;
2595 hr = IBasicVideo_get_DestinationWidth(video, &l);
2596 ok_(__FILE__,line)(hr == S_OK, "Failed to get width, hr %#lx.\n", hr);
2597 ok_(__FILE__,line)(l == width, "Got width %ld.\n", l);
2598
2599 l = 0xdeadbeef;
2600 hr = IBasicVideo_get_DestinationHeight(video, &l);
2601 ok_(__FILE__,line)(hr == S_OK, "Failed to get height, hr %#lx.\n", hr);
2602 ok_(__FILE__,line)(l == height, "Got height %ld.\n", l);
2603}
2604#define check_destination_position(a,b,c,d,e) check_destination_position_(__LINE__,a,b,c,d,e)
2605
2606static void test_basic_video_destination(IBasicVideo *video)
2607{
2608 IVideoWindow *window;
2609 HRESULT hr;
2610 RECT rect;
2611
2612 IBasicVideo_QueryInterface(video, &IID_IVideoWindow, (void **)&window);
2613
2614 check_destination_position(video, 0, 0, 600, 400);
2615 hr = IBasicVideo_IsUsingDefaultDestination(video);
2616 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2617
2618 hr = IBasicVideo_put_DestinationLeft(video, -10);
2619 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2620 check_destination_position(video, -10, 0, 600, 400);
2621 hr = IBasicVideo_IsUsingDefaultDestination(video);
2622 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2623
2624 hr = IBasicVideo_put_DestinationLeft(video, 10);
2625 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2626 check_destination_position(video, 10, 0, 600, 400);
2627 hr = IBasicVideo_IsUsingDefaultDestination(video);
2628 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2629
2630 hr = IBasicVideo_put_DestinationTop(video, -20);
2631 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2632 check_destination_position(video, 10, -20, 600, 400);
2633 hr = IBasicVideo_IsUsingDefaultDestination(video);
2634 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2635
2636 hr = IBasicVideo_put_DestinationTop(video, 20);
2637 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2638 check_destination_position(video, 10, 20, 600, 400);
2639 hr = IBasicVideo_IsUsingDefaultDestination(video);
2640 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2641
2642 hr = IBasicVideo_put_DestinationWidth(video, -700);
2643 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2644 hr = IBasicVideo_put_DestinationWidth(video, 0);
2645 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2646 hr = IBasicVideo_put_DestinationWidth(video, 700);
2647 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2648 check_destination_position(video, 10, 20, 700, 400);
2649 hr = IBasicVideo_IsUsingDefaultDestination(video);
2650 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2651
2652 hr = IBasicVideo_put_DestinationWidth(video, 500);
2653 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2654 check_destination_position(video, 10, 20, 500, 400);
2655 hr = IBasicVideo_IsUsingDefaultDestination(video);
2656 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2657
2658 hr = IBasicVideo_put_DestinationHeight(video, -500);
2659 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2660 hr = IBasicVideo_put_DestinationHeight(video, 0);
2661 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
2662 hr = IBasicVideo_put_DestinationHeight(video, 500);
2663 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2664 check_destination_position(video, 10, 20, 500, 500);
2665 hr = IBasicVideo_IsUsingDefaultDestination(video);
2666 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2667
2668 hr = IBasicVideo_put_DestinationHeight(video, 300);
2669 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2670 check_destination_position(video, 10, 20, 500, 300);
2671 hr = IBasicVideo_IsUsingDefaultDestination(video);
2672 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2673
2674 hr = IBasicVideo_SetDestinationPosition(video, 4, 5, 60, 40);
2675 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2676 check_destination_position(video, 4, 5, 60, 40);
2677 hr = IBasicVideo_IsUsingDefaultDestination(video);
2678 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2679
2680 hr = IBasicVideo_SetDestinationPosition(video, 0, 0, 600, 400);
2681 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2682 check_destination_position(video, 0, 0, 600, 400);
2683 hr = IBasicVideo_IsUsingDefaultDestination(video);
2684 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2685
2686 hr = IBasicVideo_SetDestinationPosition(video, 4, 5, 60, 40);
2687 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2688 hr = IBasicVideo_SetDefaultDestinationPosition(video);
2689 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2690 check_destination_position(video, 0, 0, 600, 400);
2691 hr = IBasicVideo_IsUsingDefaultDestination(video);
2692 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2693
2694 SetRect(&rect, 100, 200, 500, 500);
2696 hr = IVideoWindow_SetWindowPosition(window, rect.left, rect.top,
2698 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2699 check_destination_position(video, 0, 0, 400, 300);
2700 hr = IBasicVideo_IsUsingDefaultDestination(video);
2701 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2702
2703 hr = IBasicVideo_SetDestinationPosition(video, 0, 0, 400, 300);
2704 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2705 check_destination_position(video, 0, 0, 400, 300);
2706 hr = IBasicVideo_IsUsingDefaultDestination(video);
2707 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2708
2709 SetRect(&rect, 100, 200, 600, 600);
2711 hr = IVideoWindow_SetWindowPosition(window, rect.left, rect.top,
2713 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2714 check_destination_position(video, 0, 0, 400, 300);
2715 hr = IBasicVideo_IsUsingDefaultDestination(video);
2716 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2717
2718 IVideoWindow_Release(window);
2719}
2720
2721static void test_basic_video(void)
2722{
2723 VIDEOINFOHEADER vih =
2724 {
2725 .AvgTimePerFrame = 200000,
2726 .rcSource = {4, 6, 16, 12},
2727 .rcTarget = {40, 60, 120, 160},
2728 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
2729 .bmiHeader.biBitCount = 32,
2730 .bmiHeader.biWidth = 600,
2731 .bmiHeader.biHeight = 400,
2732 .bmiHeader.biPlanes = 1,
2733 .bmiHeader.biCompression = BI_RGB,
2734 };
2735 AM_MEDIA_TYPE req_mt =
2736 {
2737 .majortype = MEDIATYPE_Video,
2738 .subtype = MEDIASUBTYPE_RGB32,
2739 .formattype = FORMAT_VideoInfo,
2740 .cbFormat = sizeof(vih),
2741 .pbFormat = (BYTE *)&vih,
2742 };
2745 LONG left, top, width, height, l;
2746 struct testfilter source;
2748 IBasicVideo *video;
2749 TYPEATTR *typeattr;
2750 REFTIME reftime;
2751 HRESULT hr;
2752 UINT count;
2753 ULONG ref;
2754 IPin *pin;
2755 RECT rect;
2756
2757 IBaseFilter_QueryInterface(filter, &IID_IBasicVideo, (void **)&video);
2758 IBaseFilter_FindPin(filter, L"In", &pin);
2759
2760 hr = IBasicVideo_GetTypeInfoCount(video, &count);
2761 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2762 ok(count == 1, "Got count %u.\n", count);
2763
2764 hr = IBasicVideo_GetTypeInfo(video, 0, 0, &typeinfo);
2765 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2766 hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
2767 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2768 ok(typeattr->typekind == TKIND_DISPATCH, "Got kind %u.\n", typeattr->typekind);
2769 ok(IsEqualGUID(&typeattr->guid, &IID_IBasicVideo), "Got IID %s.\n", wine_dbgstr_guid(&typeattr->guid));
2770 ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
2771 ITypeInfo_Release(typeinfo);
2772
2773 hr = IBasicVideo_get_AvgTimePerFrame(video, NULL);
2774 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2775 hr = IBasicVideo_get_AvgTimePerFrame(video, &reftime);
2776 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2777
2778 hr = IBasicVideo_get_BitRate(video, NULL);
2779 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2780 hr = IBasicVideo_get_BitRate(video, &l);
2781 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2782
2783 hr = IBasicVideo_get_BitErrorRate(video, NULL);
2784 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2785 hr = IBasicVideo_get_BitErrorRate(video, &l);
2786 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2787
2788 hr = IBasicVideo_get_VideoWidth(video, NULL);
2789 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2790 hr = IBasicVideo_get_VideoHeight(video, NULL);
2791 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2792
2793 hr = IBasicVideo_get_SourceLeft(video, NULL);
2794 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2795 hr = IBasicVideo_get_SourceWidth(video, NULL);
2796 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2797 hr = IBasicVideo_get_SourceTop(video, NULL);
2798 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2799 hr = IBasicVideo_get_SourceHeight(video, NULL);
2800 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2801
2802 hr = IBasicVideo_get_DestinationLeft(video, NULL);
2803 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2804 hr = IBasicVideo_get_DestinationWidth(video, NULL);
2805 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2806 hr = IBasicVideo_get_DestinationTop(video, NULL);
2807 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2808 hr = IBasicVideo_get_DestinationHeight(video, NULL);
2809 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2810
2811 hr = IBasicVideo_GetSourcePosition(video, NULL, &top, &width, &height);
2812 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2813 hr = IBasicVideo_GetSourcePosition(video, &left, NULL, &width, &height);
2814 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2815 hr = IBasicVideo_GetSourcePosition(video, &left, &top, NULL, &height);
2816 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2817 hr = IBasicVideo_GetSourcePosition(video, &left, &top, &width, NULL);
2818 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2819
2820 hr = IBasicVideo_GetDestinationPosition(video, NULL, &top, &width, &height);
2821 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2822 hr = IBasicVideo_GetDestinationPosition(video, &left, NULL, &width, &height);
2823 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2824 hr = IBasicVideo_GetDestinationPosition(video, &left, &top, NULL, &height);
2825 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2826 hr = IBasicVideo_GetDestinationPosition(video, &left, &top, &width, NULL);
2827 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2828
2829 hr = IBasicVideo_GetVideoSize(video, &width, NULL);
2830 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2831 hr = IBasicVideo_GetVideoSize(video, NULL, &height);
2832 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2833 hr = IBasicVideo_GetVideoSize(video, &width, &height);
2834 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2835
2836 hr = IBasicVideo_GetVideoPaletteEntries(video, 0, 1, NULL, &l);
2837 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
2838 hr = IBasicVideo_GetVideoPaletteEntries(video, 0, 1, &l, NULL);
2839 todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
2840
2842 IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, L"vmr9");
2843 IFilterGraph2_AddFilter(graph, filter, L"source");
2844 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
2845 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2846
2847 reftime = 0.0;
2848 hr = IBasicVideo_get_AvgTimePerFrame(video, &reftime);
2849 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2850 ok(reftime == 0.02, "Got frame rate %.16e.\n", reftime);
2851
2852 l = 0xdeadbeef;
2853 hr = IBasicVideo_get_BitRate(video, &l);
2854 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2855 ok(!l, "Got bit rate %ld.\n", l);
2856
2857 l = 0xdeadbeef;
2858 hr = IBasicVideo_get_BitErrorRate(video, &l);
2859 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2860 ok(!l, "Got bit rate %ld.\n", l);
2861
2862 hr = IBasicVideo_GetVideoPaletteEntries(video, 0, 1, &l, NULL);
2863 todo_wine ok(hr == VFW_E_NO_PALETTE_AVAILABLE, "Got hr %#lx.\n", hr);
2864
2865 width = height = 0xdeadbeef;
2866 hr = IBasicVideo_GetVideoSize(video, &width, &height);
2867 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2868 ok(width == 600, "Got width %ld.\n", width);
2869 ok(height == 400, "Got height %ld.\n", height);
2870
2873
2874 hr = IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface);
2875 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2876 hr = IFilterGraph2_Disconnect(graph, pin);
2877 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2878
2879 vih.bmiHeader.biWidth = 16;
2880 vih.bmiHeader.biHeight = 16;
2881 vih.bmiHeader.biSizeImage = 0;
2882 hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
2883 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2884
2885 check_source_position(video, 0, 0, 16, 16);
2886
2887 SetRect(&rect, 0, 0, 0, 0);
2891
2892 ref = IFilterGraph2_Release(graph);
2893 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2894 IBasicVideo_Release(video);
2895 IPin_Release(pin);
2896 ref = IBaseFilter_Release(filter);
2897 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2898 ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface);
2899 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2900}
2901
2902static void test_unconnected_eos(void)
2903{
2906 IMediaControl *control;
2907 IMediaEvent *eventsrc;
2908 unsigned int ret;
2909 HRESULT hr;
2910 ULONG ref;
2911
2912 hr = IFilterGraph2_AddFilter(graph, filter, L"renderer");
2913 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2914
2915 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
2916 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2917
2918 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&eventsrc);
2919 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2920
2921 ret = check_ec_complete(eventsrc, 0);
2922 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
2923
2924 hr = IMediaControl_Pause(control);
2925 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2926
2927 ret = check_ec_complete(eventsrc, 0);
2928 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
2929
2930 hr = IMediaControl_Run(control);
2931 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2932
2933 ret = check_ec_complete(eventsrc, 0);
2934 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
2935
2936 hr = IMediaControl_Pause(control);
2937 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2938
2939 ret = check_ec_complete(eventsrc, 0);
2940 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
2941
2942 hr = IMediaControl_Run(control);
2943 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2944
2945 ret = check_ec_complete(eventsrc, 0);
2946 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
2947
2948 hr = IMediaControl_Stop(control);
2949 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2950
2951 ret = check_ec_complete(eventsrc, 0);
2952 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
2953
2954 hr = IMediaControl_Run(control);
2955 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2956
2957 ret = check_ec_complete(eventsrc, 0);
2958 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
2959
2960 IMediaControl_Release(control);
2961 IMediaEvent_Release(eventsrc);
2962 ref = IFilterGraph2_Release(graph);
2963 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2964 ref = IBaseFilter_Release(filter);
2965 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2966}
2967
2968START_TEST(videorenderer)
2969{
2971
2975 test_find_pin();
2976 test_pin_info();
2981 test_overlay();
2985
2987}
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
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 START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
unsigned int rate
Definition: audiorecord.c:87
#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
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_OUTOFMEMORY
Definition: ddrawi.h:100
#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
HRESULT hr
Definition: delayimp.cpp:582
const GUID IID_IBaseFilter
const GUID IID_IAsyncReader
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
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
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
#define EC_COMPLETE
Definition: evcode.h:17
#define EC_USERABORT
Definition: evcode.h:50
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLuint color
Definition: glext.h:6243
GLuint index
Definition: glext.h:6031
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum const GLfloat * params
Definition: glext.h:5645
GLint left
Definition: glext.h:7726
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
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 debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
#define GUID_NULL
Definition: ks.h:106
int winetest_debug
#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
struct task_struct * current
Definition: linux.c:32
static IHTMLWindow2 * window
Definition: events.c:77
static void test_filter_state(void)
Definition: filtergraph.c:3441
static void test_sample_time(void)
Definition: memallocator.c:174
static void test_current_image(IBaseFilter *filter, IMemInputPin *input, IMediaControl *control, const BITMAPINFOHEADER *expect_bih)
static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, IMemInputPin *peer, IMemAllocator **allocator)
static HRESULT WINAPI testseek_CheckCapabilities(IMediaSeeking *iface, DWORD *caps)
static BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b)
Definition: videorenderer.c:36
static void testfilter_destroy(struct strmbase_filter *iface)
static HRESULT join_thread_(int line, HANDLE thread)
#define join_thread(a)
static const IUnknownVtbl outer_vtbl
static void test_video_window_messages(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
static ULONG WINAPI testseek_Release(IMediaSeeking *iface)
static ULONG WINAPI testseek_AddRef(IMediaSeeking *iface)
static void test_video_window_owner(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
static HRESULT WINAPI testseek_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
static HANDLE send_frame_time(IMemInputPin *sink, REFERENCE_TIME start_time, unsigned char color)
static HRESULT WINAPI testseek_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop)
static void test_aggregation(void)
static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
Definition: videorenderer.c:59
static void test_basic_video(void)
static ULONG WINAPI outer_AddRef(IUnknown *iface)
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
static void test_video_window_caption(IVideoWindow *window, HWND hwnd)
static HRESULT WINAPI testseek_IsFormatSupported(IMediaSeeking *iface, const GUID *format)
static void test_video_window_position(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
static ULONG get_refcount(void *iface)
Definition: videorenderer.c:51
static HRESULT WINAPI testseek_SetRate(IMediaSeeking *iface, double rate)
static void test_pin_info(void)
static const IMediaSeekingVtbl testseek_vtbl
static struct testfilter * impl_from_IMediaSeeking(IMediaSeeking *iface)
static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
static IUnknown test_outer
static void test_find_pin(void)
static void test_basic_video_destination(IBasicVideo *video)
static void test_video_window_style(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
static void test_flushing(IPin *pin, IMemInputPin *input, IMediaControl *control)
static const struct strmbase_source_ops testsource_ops
static struct testfilter * impl_from_BaseFilter(struct strmbase_filter *iface)
static void test_basic_video_source(IBasicVideo *video)
static LRESULT CALLBACK window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
static HRESULT WINAPI testseek_GetDuration(IMediaSeeking *iface, LONGLONG *duration)
static void test_enum_media_types(void)
static BOOL CALLBACK top_window_cb(HWND hwnd, LPARAM ctx)
static void test_interfaces(void)
Definition: videorenderer.c:73
static void test_video_window_autoshow(IVideoWindow *window, IFilterGraph2 *graph, HWND hwnd)
static void test_eos(IPin *pin, IMemInputPin *input, IMediaControl *control)
static unsigned int check_ec_userabort(IMediaEvent *eventsrc, DWORD timeout)
static void test_video_window(void)
static void test_connect_pin(void)
static DWORD WINAPI frame_thread(void *arg)
static void flush_events(void)
static void test_media_types(void)
static HRESULT WINAPI testseek_SetPositions(IMediaSeeking *iface, LONGLONG *current, DWORD current_flags, LONGLONG *stop, DWORD stop_flags)
static HRESULT WINAPI testseek_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target, const GUID *target_format, LONGLONG source, const GUID *source_format)
static HRESULT WINAPI testseek_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format)
static struct strmbase_pin * testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
static void test_allocator(IMemInputPin *input)
static void test_enum_pins(void)
static IFilterGraph2 * create_graph(void)
Definition: videorenderer.c:42
static void test_overlay(void)
static HWND get_top_window(void)
static HRESULT WINAPI testseek_QueryPreferredFormat(IMediaSeeking *iface, GUID *format)
static void check_destination_position_(int line, IBasicVideo *video, LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
static HANDLE send_frame(IMemInputPin *sink)
#define check_destination_position(a, b, c, d, e)
static HRESULT WINAPI testseek_GetCapabilities(IMediaSeeking *iface, DWORD *caps)
static void test_window_close(IPin *pin, IMemInputPin *input, IMediaControl *control)
static DWORD CALLBACK notify_message_proc(void *arg)
static HRESULT WINAPI testseek_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest)
#define check_source_position(a, b, c, d, e)
static void test_unconnected_eos(void)
static unsigned int check_ec_complete(IMediaEvent *eventsrc, DWORD timeout)
#define check_interface(a, b, c)
Definition: videorenderer.c:58
static HRESULT WINAPI testseek_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current)
static HRESULT WINAPI testseek_SetTimeFormat(IMediaSeeking *iface, const GUID *format)
static HRESULT WINAPI testseek_GetTimeFormat(IMediaSeeking *iface, GUID *format)
static IBaseFilter * create_video_renderer(void)
Definition: videorenderer.c:27
static HRESULT WINAPI testseek_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll)
static LONG outer_ref
static HRESULT WINAPI testseek_GetRate(IMediaSeeking *iface, double *rate)
static unsigned int check_event_code(IMediaEvent *eventsrc, DWORD timeout, LONG expected_code, LONG_PTR expected1, LONG_PTR expected2)
static const struct strmbase_filter_ops testfilter_ops
static void test_video_window_state(IVideoWindow *window, HWND hwnd, HWND our_hwnd)
static void check_source_position_(int line, IBasicVideo *video, LONG expect_left, LONG expect_top, LONG expect_width, LONG expect_height)
static void test_unconnected_filter_state(void)
static HRESULT WINAPI testseek_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop)
static const GUID test_iid
static void testfilter_init(struct testfilter *filter)
static ULONG WINAPI outer_Release(IUnknown *iface)
const CLSID * clsid
Definition: msctf.cpp:50
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:240
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:273
const GUID IID_IDispatch
#define WS_CHILD
Definition: pedump.c:617
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define WS_MAXIMIZE
Definition: pedump.c:623
short WCHAR
Definition: pedump.c:58
#define WS_VSCROLL
Definition: pedump.c:627
#define WS_MINIMIZE
Definition: pedump.c:622
#define WS_VISIBLE
Definition: pedump.c:620
long LONG
Definition: pedump.c:60
#define WS_DISABLED
Definition: pedump.c:621
#define WS_EX_TRANSPARENT
Definition: pedump.c:649
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define WS_HSCROLL
Definition: pedump.c:628
#define WS_CLIPCHILDREN
Definition: pedump.c:619
const GUID IID_IPin
Definition: pincontrol.cpp:15
const GUID IID_IPersist
Definition: proxy.cpp:14
const GUID IID_IPersistPropertyBag
Definition: proxy.cpp:11
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
HWND WINAPI GetFocus(void)
Definition: window.c:1887
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
BOOL WINAPI IsWindow(_In_opt_ HWND)
HWND WINAPI GetActiveWindow(void)
Definition: winpos.c:138
#define SW_HIDE
Definition: winuser.h:779
#define WM_CLOSE
Definition: winuser.h:1649
#define WM_KEYUP
Definition: winuser.h:1744
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
BOOL WINAPI AdjustWindowRect(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL)
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4469
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define SW_MINIMIZE
Definition: winuser.h:787
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1806
#define SWP_NOMOVE
Definition: winuser.h:1255
#define WM_RBUTTONUP
Definition: winuser.h:1808
BOOL WINAPI AdjustWindowRectEx(_Inout_ LPRECT, _In_ DWORD, _In_ BOOL, _In_ DWORD)
#define WM_NCRBUTTONDBLCLK
Definition: winuser.h:1725
#define WM_RBUTTONDBLCLK
Definition: winuser.h:1809
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define GA_PARENT
Definition: winuser.h:2892
#define QS_ALLINPUT
Definition: winuser.h:914
#define SWP_NOSIZE
Definition: winuser.h:1256
#define WM_MOUSEMOVE
Definition: winuser.h:1803
#define WM_NCMBUTTONUP
Definition: winuser.h:1727
#define WM_LBUTTONDOWN
Definition: winuser.h:1804
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1654
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
#define WM_NCLBUTTONDBLCLK
Definition: winuser.h:1722
BOOL WINAPI IsIconic(_In_ HWND)
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
#define WM_RBUTTONDOWN
Definition: winuser.h:1807
BOOL WINAPI IsZoomed(_In_ HWND)
#define SM_CXMIN
Definition: winuser.h:1000
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define SM_CYMIN
Definition: winuser.h:1001
#define HWND_TOP
Definition: winuser.h:1218
#define SW_SHOWNA
Definition: winuser.h:789
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)
#define WM_NCMBUTTONDOWN
Definition: winuser.h:1726
#define PM_REMOVE
Definition: winuser.h:1207
#define WM_MBUTTONDBLCLK
Definition: winuser.h:1812
#define WS_EX_WINDOWEDGE
Definition: winuser.h:407
#define WM_MOUSEACTIVATE
Definition: winuser.h:1665
#define WM_LBUTTONUP
Definition: winuser.h:1805
#define GetClassLongPtrW
Definition: winuser.h:4718
#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)
#define GCLP_HBRBACKGROUND
Definition: winuser.h:680
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)
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
#define flaky_wine
Definition: test.h:167
#define memset(x, y, z)
Definition: compat.h:39
void strmbase_source_init(struct strmbase_source *pin, struct strmbase_filter *filter, const WCHAR *name, const struct strmbase_source_ops *func_table)
Definition: pin.c:765
void strmbase_filter_cleanup(struct strmbase_filter *filter)
Definition: filter.c:540
void strmbase_source_cleanup(struct strmbase_source *pin)
Definition: pin.c:778
void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer, const CLSID *clsid, const struct strmbase_filter_ops *func_table)
Definition: filter.c:517
HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(struct strmbase_source *pin, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: pin.c:710
DWORD biSizeImage
Definition: amvideo.idl:36
Definition: dcommon.idl:28
long bottom
Definition: dcommon.idl:29
long right
Definition: dcommon.idl:29
long left
Definition: dcommon.idl:29
long top
Definition: dcommon.idl:29
LPCSTR lpszClassName
Definition: winuser.h:3280
WNDPROC lpfnWndProc
Definition: winuser.h:3272
Definition: inflate.c:139
Definition: dialog.c:52
Definition: filter.c:165
IBaseFilter * filter
Definition: filtergraph.c:75
IMediaSeeking IMediaSeeking_iface
Definition: filter.c:167
IMemInputPin * sink
Definition: nullrenderer.c:529
IMediaSample * sample
Definition: nullrenderer.c:530
Definition: graph.c:32
Definition: parser.c:49
IVideoWindow * window
Definition: send.c:48
Definition: wave.c:25
struct strmbase_filter * filter
Definition: strmbase.h:58
Definition: style.c:91
BITMAPINFOHEADER bmiHeader
Definition: amvideo.idl:189
REFERENCE_TIME AvgTimePerFrame
Definition: amvideo.idl:187
Definition: tools.h:99
IMediaSeeking IMediaSeeking_iface
Definition: amstream.c:1021
const AM_MEDIA_TYPE * mt
Definition: avidec.c:799
struct strmbase_source source
Definition: amstream.c:1020
struct strmbase_filter filter
Definition: amstream.c:1019
Definition: dhcpd.h:248
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int64_t LONGLONG
Definition: typedefs.h:68
uint32_t ULONG_PTR
Definition: typedefs.h:65
#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_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81
#define VFW_E_NOT_COMMITTED
Definition: vfwmsgs.h:56
#define VFW_E_NOT_STOPPED
Definition: vfwmsgs.h:75
#define VFW_E_NOT_PAUSED
Definition: vfwmsgs.h:76
#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
unsigned char BYTE
Definition: xxhash.c:193