mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / qcap / tests / avico.c
blob332ca5a8e7de6fd27125c394ff221f67e7d6a8c4
1 /*
2 * AVI compressor filter unit tests
4 * Copyright 2018 Zebediah Figura
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
22 #include "dshow.h"
23 #include "vfw.h"
24 #include "wine/test.h"
26 static const DWORD test_fourcc = mmioFOURCC('w','t','s','t');
28 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
29 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
31 IUnknown *iface = iface_ptr;
32 HRESULT hr, expected_hr;
33 IUnknown *unk;
35 expected_hr = supported ? S_OK : E_NOINTERFACE;
37 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
38 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
39 if (SUCCEEDED(hr))
40 IUnknown_Release(unk);
43 static ULONG get_refcount(void *iface)
45 IUnknown *unknown = iface;
46 IUnknown_AddRef(unknown);
47 return IUnknown_Release(unknown);
50 static void test_interfaces(IBaseFilter *filter)
52 IPin *pin;
54 check_interface(filter, &IID_IBaseFilter, TRUE);
55 check_interface(filter, &IID_IMediaFilter, TRUE);
56 check_interface(filter, &IID_IPersist, TRUE);
57 check_interface(filter, &IID_IPersistPropertyBag, TRUE);
58 check_interface(filter, &IID_IUnknown, TRUE);
60 check_interface(filter, &IID_IAMFilterMiscFlags, FALSE);
61 check_interface(filter, &IID_IBasicAudio, FALSE);
62 check_interface(filter, &IID_IBasicVideo, FALSE);
63 check_interface(filter, &IID_IKsPropertySet, FALSE);
64 check_interface(filter, &IID_IMediaPosition, FALSE);
65 check_interface(filter, &IID_IMediaSeeking, FALSE);
66 check_interface(filter, &IID_IPin, FALSE);
67 check_interface(filter, &IID_IQualityControl, FALSE);
68 check_interface(filter, &IID_IQualProp, FALSE);
69 check_interface(filter, &IID_IReferenceClock, FALSE);
70 check_interface(filter, &IID_IVideoWindow, FALSE);
72 IBaseFilter_FindPin(filter, L"In", &pin);
74 check_interface(pin, &IID_IMemInputPin, TRUE);
75 check_interface(pin, &IID_IPin, TRUE);
76 todo_wine check_interface(pin, &IID_IQualityControl, TRUE);
77 check_interface(pin, &IID_IUnknown, TRUE);
79 check_interface(pin, &IID_IMediaPosition, FALSE);
80 check_interface(pin, &IID_IMediaSeeking, FALSE);
82 IPin_Release(pin);
83 IBaseFilter_FindPin(filter, L"Out", &pin);
85 todo_wine check_interface(pin, &IID_IMediaPosition, TRUE);
86 todo_wine check_interface(pin, &IID_IMediaSeeking, TRUE);
87 check_interface(pin, &IID_IPin, TRUE);
88 todo_wine check_interface(pin, &IID_IQualityControl, TRUE);
89 check_interface(pin, &IID_IUnknown, TRUE);
91 check_interface(pin, &IID_IAsyncReader, FALSE);
93 IPin_Release(pin);
96 static const GUID test_iid = {0x33333333};
97 static LONG outer_ref = 1;
99 static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
101 if (IsEqualGUID(iid, &IID_IUnknown)
102 || IsEqualGUID(iid, &IID_IBaseFilter)
103 || IsEqualGUID(iid, &test_iid))
105 *out = (IUnknown *)0xdeadbeef;
106 return S_OK;
108 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
109 return E_NOINTERFACE;
112 static ULONG WINAPI outer_AddRef(IUnknown *iface)
114 return InterlockedIncrement(&outer_ref);
117 static ULONG WINAPI outer_Release(IUnknown *iface)
119 return InterlockedDecrement(&outer_ref);
122 static const IUnknownVtbl outer_vtbl =
124 outer_QueryInterface,
125 outer_AddRef,
126 outer_Release,
129 static IUnknown test_outer = {&outer_vtbl};
131 static void test_aggregation(void)
133 IBaseFilter *filter, *filter2;
134 IUnknown *unk, *unk2;
135 HRESULT hr;
136 ULONG ref;
138 filter = (IBaseFilter *)0xdeadbeef;
139 hr = CoCreateInstance(&CLSID_AVICo, &test_outer, CLSCTX_INPROC_SERVER,
140 &IID_IBaseFilter, (void **)&filter);
141 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
142 ok(!filter, "Got interface %p.\n", filter);
144 hr = CoCreateInstance(&CLSID_AVICo, &test_outer, CLSCTX_INPROC_SERVER,
145 &IID_IUnknown, (void **)&unk);
146 ok(hr == S_OK, "Got hr %#x.\n", hr);
147 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
148 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
149 ref = get_refcount(unk);
150 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
152 ref = IUnknown_AddRef(unk);
153 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
154 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
156 ref = IUnknown_Release(unk);
157 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
158 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
160 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
161 ok(hr == S_OK, "Got hr %#x.\n", hr);
162 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
163 IUnknown_Release(unk2);
165 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
166 ok(hr == S_OK, "Got hr %#x.\n", hr);
168 hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
169 ok(hr == S_OK, "Got hr %#x.\n", hr);
170 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
172 hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
173 ok(hr == S_OK, "Got hr %#x.\n", hr);
174 ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
176 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
177 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
178 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
180 hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
181 ok(hr == S_OK, "Got hr %#x.\n", hr);
182 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
184 IBaseFilter_Release(filter);
185 ref = IUnknown_Release(unk);
186 ok(!ref, "Got unexpected refcount %d.\n", ref);
187 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
190 static void test_enum_pins(IBaseFilter *filter)
192 IEnumPins *enum1, *enum2;
193 ULONG ref, count;
194 IPin *pins[3];
195 HRESULT hr;
197 ref = get_refcount(filter);
198 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
200 hr = IBaseFilter_EnumPins(filter, NULL);
201 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
203 hr = IBaseFilter_EnumPins(filter, &enum1);
204 ok(hr == S_OK, "Got hr %#x.\n", hr);
205 ref = get_refcount(filter);
206 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
207 ref = get_refcount(enum1);
208 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
210 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
211 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
213 hr = IEnumPins_Next(enum1, 1, pins, NULL);
214 ok(hr == S_OK, "Got hr %#x.\n", hr);
215 ref = get_refcount(filter);
216 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
217 ref = get_refcount(pins[0]);
218 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
219 ref = get_refcount(enum1);
220 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
221 IPin_Release(pins[0]);
222 ref = get_refcount(filter);
223 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
225 hr = IEnumPins_Next(enum1, 1, pins, NULL);
226 ok(hr == S_OK, "Got hr %#x.\n", hr);
227 ref = get_refcount(filter);
228 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
229 ref = get_refcount(pins[0]);
230 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
231 ref = get_refcount(enum1);
232 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
233 IPin_Release(pins[0]);
234 ref = get_refcount(filter);
235 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
237 hr = IEnumPins_Next(enum1, 1, pins, NULL);
238 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
240 hr = IEnumPins_Reset(enum1);
241 ok(hr == S_OK, "Got hr %#x.\n", hr);
243 hr = IEnumPins_Next(enum1, 1, pins, &count);
244 ok(hr == S_OK, "Got hr %#x.\n", hr);
245 ok(count == 1, "Got count %u.\n", count);
246 IPin_Release(pins[0]);
248 hr = IEnumPins_Next(enum1, 1, pins, &count);
249 ok(hr == S_OK, "Got hr %#x.\n", hr);
250 ok(count == 1, "Got count %u.\n", count);
251 IPin_Release(pins[0]);
253 hr = IEnumPins_Next(enum1, 1, pins, &count);
254 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
255 ok(!count, "Got count %u.\n", count);
257 hr = IEnumPins_Reset(enum1);
258 ok(hr == S_OK, "Got hr %#x.\n", hr);
260 hr = IEnumPins_Next(enum1, 2, pins, NULL);
261 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
263 hr = IEnumPins_Next(enum1, 2, pins, &count);
264 ok(hr == S_OK, "Got hr %#x.\n", hr);
265 ok(count == 2, "Got count %u.\n", count);
266 IPin_Release(pins[0]);
267 IPin_Release(pins[1]);
269 hr = IEnumPins_Next(enum1, 2, pins, &count);
270 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
271 ok(!count, "Got count %u.\n", count);
273 hr = IEnumPins_Reset(enum1);
274 ok(hr == S_OK, "Got hr %#x.\n", hr);
276 hr = IEnumPins_Next(enum1, 3, pins, &count);
277 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
278 ok(count == 2, "Got count %u.\n", count);
279 IPin_Release(pins[0]);
280 IPin_Release(pins[1]);
282 hr = IEnumPins_Reset(enum1);
283 ok(hr == S_OK, "Got hr %#x.\n", hr);
285 hr = IEnumPins_Clone(enum1, &enum2);
286 ok(hr == S_OK, "Got hr %#x.\n", hr);
288 hr = IEnumPins_Skip(enum1, 3);
289 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
291 hr = IEnumPins_Skip(enum1, 2);
292 ok(hr == S_OK, "Got hr %#x.\n", hr);
294 hr = IEnumPins_Skip(enum1, 1);
295 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
297 hr = IEnumPins_Next(enum1, 1, pins, NULL);
298 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
300 hr = IEnumPins_Next(enum2, 1, pins, NULL);
301 ok(hr == S_OK, "Got hr %#x.\n", hr);
302 IPin_Release(pins[0]);
304 IEnumPins_Release(enum2);
305 IEnumPins_Release(enum1);
308 static void test_find_pin(IBaseFilter *filter)
310 IEnumPins *enum_pins;
311 IPin *pin, *pin2;
312 HRESULT hr;
314 hr = IBaseFilter_EnumPins(filter, &enum_pins);
315 ok(hr == S_OK, "Got hr %#x.\n", hr);
317 hr = IBaseFilter_FindPin(filter, L"In", &pin);
318 ok(hr == S_OK, "Got hr %#x.\n", hr);
319 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
320 ok(hr == S_OK, "Got hr %#x.\n", hr);
321 ok(pin == pin2, "Pins didn't match.\n");
322 IPin_Release(pin);
323 IPin_Release(pin2);
325 hr = IBaseFilter_FindPin(filter, L"Out", &pin);
326 ok(hr == S_OK, "Got hr %#x.\n", hr);
327 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
328 ok(hr == S_OK, "Got hr %#x.\n", hr);
329 ok(pin == pin2, "Pins didn't match.\n");
330 IPin_Release(pin);
331 IPin_Release(pin2);
333 hr = IBaseFilter_FindPin(filter, L"Input", &pin);
334 ok(hr == VFW_E_NOT_FOUND, "Got hr %#x.\n", hr);
335 hr = IBaseFilter_FindPin(filter, L"Output", &pin);
336 ok(hr == VFW_E_NOT_FOUND, "Got hr %#x.\n", hr);
338 IEnumPins_Release(enum_pins);
341 static void test_pin_info(IBaseFilter *filter)
343 PIN_DIRECTION dir;
344 PIN_INFO info;
345 HRESULT hr;
346 WCHAR *id;
347 IPin *pin;
349 hr = IBaseFilter_FindPin(filter, L"In", &pin);
350 ok(hr == S_OK, "Got hr %#x.\n", hr);
352 hr = IPin_QueryPinInfo(pin, &info);
353 ok(hr == S_OK, "Got hr %#x.\n", hr);
354 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
355 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
356 todo_wine ok(!lstrcmpW(info.achName, L"Input"), "Got name %s.\n", wine_dbgstr_w(info.achName));
357 IBaseFilter_Release(info.pFilter);
359 hr = IPin_QueryDirection(pin, &dir);
360 ok(hr == S_OK, "Got hr %#x.\n", hr);
361 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
363 hr = IPin_QueryId(pin, &id);
364 ok(hr == S_OK, "Got hr %#x.\n", hr);
365 ok(!lstrcmpW(id, L"In"), "Got id %s.\n", wine_dbgstr_w(id));
366 CoTaskMemFree(id);
368 IPin_Release(pin);
370 hr = IBaseFilter_FindPin(filter, L"Out", &pin);
371 ok(hr == S_OK, "Got hr %#x.\n", hr);
373 hr = IPin_QueryPinInfo(pin, &info);
374 ok(hr == S_OK, "Got hr %#x.\n", hr);
375 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
376 ok(info.dir == PINDIR_OUTPUT, "Got direction %d.\n", info.dir);
377 todo_wine ok(!lstrcmpW(info.achName, L"Output"), "Got name %s.\n", wine_dbgstr_w(info.achName));
378 IBaseFilter_Release(info.pFilter);
380 hr = IPin_QueryDirection(pin, &dir);
381 ok(hr == S_OK, "Got hr %#x.\n", hr);
382 ok(dir == PINDIR_OUTPUT, "Got direction %d.\n", dir);
384 hr = IPin_QueryId(pin, &id);
385 ok(hr == S_OK, "Got hr %#x.\n", hr);
386 ok(!lstrcmpW(id, L"Out"), "Got id %s.\n", wine_dbgstr_w(id));
387 CoTaskMemFree(id);
389 IPin_Release(pin);
392 static LRESULT CALLBACK driver_proc(DWORD_PTR id, HDRVR driver, UINT msg,
393 LPARAM lparam1, LPARAM lparam2)
395 if (winetest_debug > 1) trace("msg %#x, lparam1 %#lx, lparam2 %#lx.\n", msg, lparam1, lparam2);
397 switch (msg)
399 case DRV_LOAD:
400 case DRV_OPEN:
401 case DRV_CLOSE:
402 case DRV_FREE:
403 return 1;
404 case ICM_GETINFO:
406 ICINFO *info = (ICINFO *)lparam1;
407 info->fccType = ICTYPE_VIDEO;
408 info->fccHandler = test_fourcc;
409 info->dwFlags = VIDCF_TEMPORAL;
410 info->dwVersion = 0x10101;
411 info->dwVersionICM = ICVERSION;
412 lstrcpyW(info->szName, L"foo");
413 lstrcpyW(info->szDescription, L"foo");
414 return sizeof(ICINFO);
416 case ICM_COMPRESS_QUERY:
418 BITMAPINFO *in = (BITMAPINFO *)lparam1;
419 return in->bmiHeader.biBitCount == 16 ? ICERR_OK : ICERR_BADFORMAT;
423 return 0;
426 static HRESULT WINAPI property_bag_QueryInterface(IPropertyBag *iface, REFIID iid, void **out)
428 ok(0, "Unexpected call (iid %s).\n", wine_dbgstr_guid(iid));
429 return E_NOINTERFACE;
432 static ULONG WINAPI property_bag_AddRef(IPropertyBag *iface)
434 ok(0, "Unexpected call.\n");
435 return 2;
438 static ULONG WINAPI property_bag_Release(IPropertyBag *iface)
440 ok(0, "Unexpected call.\n");
441 return 1;
443 static BSTR ppb_handler;
444 static unsigned int ppb_got_read;
446 static HRESULT WINAPI property_bag_Read(IPropertyBag *iface, const WCHAR *name, VARIANT *var, IErrorLog *log)
448 ok(!lstrcmpW(name, L"FccHandler"), "Got unexpected name %s.\n", wine_dbgstr_w(name));
449 ok(V_VT(var) == VT_BSTR, "Got unexpected type %u.\n", V_VT(var));
450 ok(!log, "Got unexpected error log %p.\n", log);
451 V_BSTR(var) = SysAllocString(ppb_handler);
452 ppb_got_read++;
453 return S_OK;
456 static HRESULT WINAPI property_bag_Write(IPropertyBag *iface, const WCHAR *name, VARIANT *var)
458 ok(0, "Unexpected call (name %s).\n", wine_dbgstr_w(name));
459 return E_FAIL;
462 static const IPropertyBagVtbl property_bag_vtbl =
464 property_bag_QueryInterface,
465 property_bag_AddRef,
466 property_bag_Release,
467 property_bag_Read,
468 property_bag_Write,
471 static void test_property_bag(IMoniker *mon)
473 IPropertyBag property_bag = {&property_bag_vtbl};
474 IPropertyBag *devenum_bag;
475 IPersistPropertyBag *ppb;
476 VARIANT var;
477 HRESULT hr;
478 ULONG ref;
480 hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&devenum_bag);
481 ok(hr == S_OK, "Got hr %#x.\n", hr);
483 VariantInit(&var);
484 hr = IPropertyBag_Read(devenum_bag, L"FccHandler", &var, NULL);
485 ok(hr == S_OK, "Got hr %#x.\n", hr);
486 ppb_handler = V_BSTR(&var);
488 hr = CoCreateInstance(&CLSID_AVICo, NULL, CLSCTX_INPROC_SERVER,
489 &IID_IPersistPropertyBag, (void **)&ppb);
490 ok(hr == S_OK, "Got hr %#x.\n", hr);
492 hr = IPersistPropertyBag_InitNew(ppb);
493 todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
495 ppb_got_read = 0;
496 hr = IPersistPropertyBag_Load(ppb, &property_bag, NULL);
497 ok(hr == S_OK, "Got hr %#x.\n", hr);
498 ok(ppb_got_read == 1, "Got %u calls to Read().\n", ppb_got_read);
500 ref = IPersistPropertyBag_Release(ppb);
501 ok(!ref, "Got unexpected refcount %d.\n", ref);
503 VariantClear(&var);
504 IPropertyBag_Release(devenum_bag);
507 static void test_media_types(IBaseFilter *filter)
509 VIDEOINFOHEADER vih =
511 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
512 .bmiHeader.biBitCount = 16,
513 .bmiHeader.biCompression = BI_RGB,
515 AM_MEDIA_TYPE mt = {}, *pmt;
516 IEnumMediaTypes *enummt;
517 HRESULT hr;
518 IPin *pin;
520 IBaseFilter_FindPin(filter, L"In", &pin);
522 hr = IPin_EnumMediaTypes(pin, &enummt);
523 ok(hr == S_OK, "Got hr %#x.\n", hr);
525 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
526 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
528 IEnumMediaTypes_Release(enummt);
530 mt.majortype = MEDIATYPE_Video;
531 mt.formattype = FORMAT_VideoInfo;
532 mt.cbFormat = sizeof(VIDEOINFOHEADER);
533 mt.pbFormat = (BYTE *)&vih;
534 hr = IPin_QueryAccept(pin, &mt);
535 ok(hr == S_OK, "Got hr %#x.\n", hr);
537 vih.bmiHeader.biBitCount = 32;
538 hr = IPin_QueryAccept(pin, &mt);
539 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
540 vih.bmiHeader.biBitCount = 16;
542 mt.bFixedSizeSamples = TRUE;
543 mt.bTemporalCompression = TRUE;
544 mt.lSampleSize = 123;
545 mt.subtype = MEDIASUBTYPE_RGB565;
546 hr = IPin_QueryAccept(pin, &mt);
547 ok(hr == S_OK, "Got hr %#x.\n", hr);
548 mt.subtype = MEDIASUBTYPE_WAVE;
549 hr = IPin_QueryAccept(pin, &mt);
550 ok(hr == S_OK, "Got hr %#x.\n", hr);
552 mt.formattype = GUID_NULL;
553 hr = IPin_QueryAccept(pin, &mt);
554 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
555 mt.formattype = FORMAT_None;
556 hr = IPin_QueryAccept(pin, &mt);
557 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
558 mt.formattype = FORMAT_VideoInfo;
560 mt.majortype = MEDIATYPE_NULL;
561 hr = IPin_QueryAccept(pin, &mt);
562 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
563 mt.majortype = MEDIATYPE_Video;
565 IPin_Release(pin);
567 IBaseFilter_FindPin(filter, L"Out", &pin);
569 hr = IPin_EnumMediaTypes(pin, &enummt);
570 ok(hr == S_OK, "Got hr %#x.\n", hr);
572 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
573 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
575 IEnumMediaTypes_Release(enummt);
576 IPin_Release(pin);
579 static void test_enum_media_types(IBaseFilter *filter)
581 IEnumMediaTypes *enum1, *enum2;
582 AM_MEDIA_TYPE *mts[2];
583 ULONG count;
584 HRESULT hr;
585 IPin *pin;
587 IBaseFilter_FindPin(filter, L"In", &pin);
589 hr = IPin_EnumMediaTypes(pin, &enum1);
590 ok(hr == S_OK, "Got hr %#x.\n", hr);
592 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
593 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
595 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
596 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
597 ok(!count, "Got count %u.\n", count);
599 hr = IEnumMediaTypes_Reset(enum1);
600 ok(hr == S_OK, "Got hr %#x.\n", hr);
602 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
603 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
605 hr = IEnumMediaTypes_Clone(enum1, &enum2);
606 ok(hr == S_OK, "Got hr %#x.\n", hr);
608 hr = IEnumMediaTypes_Skip(enum1, 1);
609 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
611 hr = IEnumMediaTypes_Next(enum2, 1, mts, NULL);
612 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
614 IEnumMediaTypes_Release(enum1);
615 IEnumMediaTypes_Release(enum2);
616 IPin_Release(pin);
618 IBaseFilter_FindPin(filter, L"Out", &pin);
620 hr = IPin_EnumMediaTypes(pin, &enum1);
621 ok(hr == S_OK, "Got hr %#x.\n", hr);
623 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
624 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
626 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
627 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
628 ok(!count, "Got count %u.\n", count);
630 hr = IEnumMediaTypes_Reset(enum1);
631 ok(hr == S_OK, "Got hr %#x.\n", hr);
633 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
634 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
636 hr = IEnumMediaTypes_Clone(enum1, &enum2);
637 ok(hr == S_OK, "Got hr %#x.\n", hr);
639 hr = IEnumMediaTypes_Skip(enum1, 1);
640 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
642 hr = IEnumMediaTypes_Next(enum2, 1, mts, NULL);
643 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
645 IEnumMediaTypes_Release(enum1);
646 IEnumMediaTypes_Release(enum2);
647 IPin_Release(pin);
650 static void test_unconnected_filter_state(IBaseFilter *filter)
652 FILTER_STATE state;
653 HRESULT hr;
655 hr = IBaseFilter_GetState(filter, 0, &state);
656 ok(hr == S_OK, "Got hr %#x.\n", hr);
657 ok(state == State_Stopped, "Got state %u.\n", state);
659 hr = IBaseFilter_Pause(filter);
660 ok(hr == S_OK, "Got hr %#x.\n", hr);
662 hr = IBaseFilter_GetState(filter, 0, &state);
663 ok(hr == S_OK, "Got hr %#x.\n", hr);
664 ok(state == State_Paused, "Got state %u.\n", state);
666 hr = IBaseFilter_Run(filter, 0);
667 ok(hr == S_OK, "Got hr %#x.\n", hr);
669 hr = IBaseFilter_GetState(filter, 0, &state);
670 ok(hr == S_OK, "Got hr %#x.\n", hr);
671 ok(state == State_Running, "Got state %u.\n", state);
673 hr = IBaseFilter_Pause(filter);
674 ok(hr == S_OK, "Got hr %#x.\n", hr);
676 hr = IBaseFilter_GetState(filter, 0, &state);
677 ok(hr == S_OK, "Got hr %#x.\n", hr);
678 ok(state == State_Paused, "Got state %u.\n", state);
680 hr = IBaseFilter_Stop(filter);
681 ok(hr == S_OK, "Got hr %#x.\n", hr);
683 hr = IBaseFilter_GetState(filter, 0, &state);
684 ok(hr == S_OK, "Got hr %#x.\n", hr);
685 ok(state == State_Stopped, "Got state %u.\n", state);
687 hr = IBaseFilter_Run(filter, 0);
688 ok(hr == S_OK, "Got hr %#x.\n", hr);
690 hr = IBaseFilter_GetState(filter, 0, &state);
691 ok(hr == S_OK, "Got hr %#x.\n", hr);
692 ok(state == State_Running, "Got state %u.\n", state);
694 hr = IBaseFilter_Stop(filter);
695 ok(hr == S_OK, "Got hr %#x.\n", hr);
697 hr = IBaseFilter_GetState(filter, 0, &state);
698 ok(hr == S_OK, "Got hr %#x.\n", hr);
699 ok(state == State_Stopped, "Got state %u.\n", state);
702 START_TEST(avico)
704 static const WCHAR test_display_name[] =
705 L"@device:cm:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\wtst";
706 ICreateDevEnum *devenum;
707 IEnumMoniker *enummon;
708 IBaseFilter *filter;
709 IMoniker *mon;
710 WCHAR *name;
711 HRESULT hr;
712 ULONG ref;
713 BOOL ret;
715 ret = ICInstall(ICTYPE_VIDEO, test_fourcc, (LPARAM)driver_proc, NULL, ICINSTALL_FUNCTION);
716 ok(ret, "Failed to install test VFW driver.\n");
718 CoInitialize(NULL);
720 hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
721 &IID_ICreateDevEnum, (void **)&devenum);
722 ok(hr == S_OK, "Got hr %#x.\n", hr);
723 hr = ICreateDevEnum_CreateClassEnumerator(devenum, &CLSID_VideoCompressorCategory, &enummon, 0);
724 ok(hr == S_OK, "Got hr %#x.\n", hr);
726 while (IEnumMoniker_Next(enummon, 1, &mon, NULL) == S_OK)
728 hr = IMoniker_GetDisplayName(mon, NULL, NULL, &name);
729 ok(hr == S_OK, "Got hr %#x.\n", hr);
730 if (!lstrcmpW(name, test_display_name))
732 hr = IMoniker_BindToObject(mon, NULL, NULL, &IID_IBaseFilter, (void **)&filter);
733 ok(hr == S_OK, "Got hr %#x.\n", hr);
735 test_aggregation();
736 test_interfaces(filter);
737 test_enum_pins(filter);
738 test_find_pin(filter);
739 test_pin_info(filter);
740 test_media_types(filter);
741 test_enum_media_types(filter);
742 test_unconnected_filter_state(filter);
744 ref = IBaseFilter_Release(filter);
745 ok(!ref, "Got outstanding refcount %d.\n", ref);
748 if (!memcmp(name, test_display_name, 11 * sizeof(WCHAR)))
749 test_property_bag(mon);
751 CoTaskMemFree(name);
752 IMoniker_Release(mon);
755 IEnumMoniker_Release(enummon);
756 ICreateDevEnum_Release(devenum);
758 ret = ICRemove(ICTYPE_VIDEO, test_fourcc, 0);
759 ok(ret, "Failed to remove test driver.\n");
761 CoUninitialize();