2 * WDM video capture filter unit tests
4 * Copyright 2019 Damjan Jovanovic
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
23 #include "wine/test.h"
24 #include "wine/strmbase.h"
26 static BOOL
compare_media_types(const AM_MEDIA_TYPE
*a
, const AM_MEDIA_TYPE
*b
)
28 return !memcmp(a
, b
, offsetof(AM_MEDIA_TYPE
, pbFormat
))
29 && !memcmp(a
->pbFormat
, b
->pbFormat
, a
->cbFormat
);
32 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
33 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
35 IUnknown
*iface
= iface_ptr
;
36 HRESULT hr
, expected_hr
;
39 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
41 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
42 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
44 IUnknown_Release(unk
);
47 static void test_media_types(IPin
*pin
)
49 IEnumMediaTypes
*enum_media_types
;
50 AM_MEDIA_TYPE mt
, *pmt
;
53 hr
= IPin_EnumMediaTypes(pin
, &enum_media_types
);
54 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
56 while (IEnumMediaTypes_Next(enum_media_types
, 1, &pmt
, NULL
) == S_OK
)
58 hr
= IPin_QueryAccept(pin
, pmt
);
59 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
62 IEnumMediaTypes_Release(enum_media_types
);
64 hr
= IPin_QueryAccept(pin
, NULL
);
65 todo_wine
ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
67 memset(&mt
, 0, sizeof(mt
));
68 hr
= IPin_QueryAccept(pin
, &mt
);
69 ok(hr
!= S_OK
, "Got hr %#x.\n", hr
);
71 mt
.majortype
= MEDIATYPE_Video
;
72 hr
= IPin_QueryAccept(pin
, &mt
);
73 ok(hr
!= S_OK
, "Got hr %#x.\n", hr
);
75 mt
.formattype
= FORMAT_VideoInfo
;
76 hr
= IPin_QueryAccept(pin
, &mt
);
77 ok(hr
!= S_OK
, "Got hr %#x.\n", hr
);
79 mt
.formattype
= FORMAT_None
;
80 hr
= IPin_QueryAccept(pin
, &mt
);
81 ok(hr
!= S_OK
, "Got hr %#x.\n", hr
);
84 static void test_stream_config(IPin
*pin
)
86 VIDEOINFOHEADER
*video_info
, *video_info2
;
87 LONG depth
, compression
, count
, size
, i
;
88 IEnumMediaTypes
*enum_media_types
;
89 AM_MEDIA_TYPE
*format
, *format2
;
90 IAMStreamConfig
*stream_config
;
91 VIDEO_STREAM_CONFIG_CAPS vscc
;
94 hr
= IPin_QueryInterface(pin
, &IID_IAMStreamConfig
, (void **)&stream_config
);
95 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
97 hr
= IAMStreamConfig_GetFormat(stream_config
, &format
);
98 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
99 ok(IsEqualGUID(&format
->majortype
, &MEDIATYPE_Video
), "Got wrong majortype: %s.\n",
100 debugstr_guid(&format
->majortype
));
102 hr
= IAMStreamConfig_SetFormat(stream_config
, format
);
103 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
105 /* After setting the format, a single media type is enumerated.
106 * This persists until the filter is released. */
107 IPin_EnumMediaTypes(pin
, &enum_media_types
);
108 hr
= IEnumMediaTypes_Next(enum_media_types
, 1, &format2
, NULL
);
109 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
110 DeleteMediaType(format2
);
111 hr
= IEnumMediaTypes_Next(enum_media_types
, 1, &format2
, NULL
);
112 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
113 IEnumMediaTypes_Release(enum_media_types
);
115 format
->majortype
= MEDIATYPE_Audio
;
116 hr
= IAMStreamConfig_SetFormat(stream_config
, format
);
117 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
119 format
->majortype
= MEDIATYPE_Video
;
120 video_info
= (VIDEOINFOHEADER
*)format
->pbFormat
;
121 video_info
->bmiHeader
.biWidth
--;
122 video_info
->bmiHeader
.biHeight
--;
123 hr
= IAMStreamConfig_SetFormat(stream_config
, format
);
124 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
126 depth
= video_info
->bmiHeader
.biBitCount
;
127 compression
= video_info
->bmiHeader
.biCompression
;
128 video_info
->bmiHeader
.biWidth
++;
129 video_info
->bmiHeader
.biHeight
++;
130 video_info
->bmiHeader
.biBitCount
= 0;
131 video_info
->bmiHeader
.biCompression
= 0;
132 hr
= IAMStreamConfig_SetFormat(stream_config
, format
);
133 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
135 hr
= IAMStreamConfig_GetFormat(stream_config
, &format2
);
136 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
137 ok(IsEqualGUID(&format2
->majortype
, &MEDIATYPE_Video
), "Got wrong majortype: %s.\n",
138 debugstr_guid(&format2
->majortype
));
139 video_info2
= (VIDEOINFOHEADER
*)format2
->pbFormat
;
140 ok(video_info2
->bmiHeader
.biBitCount
== depth
, "Got wrong depth: %d.\n",
141 video_info2
->bmiHeader
.biBitCount
);
142 ok(video_info2
->bmiHeader
.biCompression
== compression
,
143 "Got wrong compression: %d.\n", video_info2
->bmiHeader
.biCompression
);
144 FreeMediaType(format2
);
146 video_info
->bmiHeader
.biWidth
= 10000000;
147 video_info
->bmiHeader
.biHeight
= 10000000;
148 hr
= IAMStreamConfig_SetFormat(stream_config
, format
);
149 ok(hr
== E_FAIL
, "Got hr %#x.\n", hr
);
150 FreeMediaType(format
);
154 /* Crash on Windows */
157 hr
= IAMStreamConfig_GetNumberOfCapabilities(stream_config
, &count
, NULL
);
158 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
160 hr
= IAMStreamConfig_GetNumberOfCapabilities(stream_config
, NULL
, &size
);
161 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
163 hr
= IAMStreamConfig_GetStreamCaps(stream_config
, 0, NULL
, (BYTE
*)&vscc
);
164 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
166 hr
= IAMStreamConfig_GetStreamCaps(stream_config
, 0, &format
, NULL
);
167 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
170 hr
= IAMStreamConfig_GetNumberOfCapabilities(stream_config
, &count
, &size
);
171 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
172 ok(count
!= 0xdeadbeef, "Got wrong count: %d.\n", count
);
173 ok(size
== sizeof(VIDEO_STREAM_CONFIG_CAPS
), "Got wrong size: %d.\n", size
);
175 hr
= IAMStreamConfig_GetStreamCaps(stream_config
, 100000, NULL
, NULL
);
176 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
178 hr
= IAMStreamConfig_GetStreamCaps(stream_config
, 100000, &format
, (BYTE
*)&vscc
);
179 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
181 for (i
= 0; i
< count
; ++i
)
183 hr
= IAMStreamConfig_GetStreamCaps(stream_config
, i
, &format
, (BYTE
*)&vscc
);
184 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
185 ok(IsEqualGUID(&format
->majortype
, &MEDIATYPE_Video
), "Got wrong majortype: %s.\n",
186 debugstr_guid(&MEDIATYPE_Video
));
187 ok(IsEqualGUID(&vscc
.guid
, &FORMAT_VideoInfo
)
188 || IsEqualGUID(&vscc
.guid
, &FORMAT_VideoInfo2
), "Got wrong guid: %s.\n",
189 debugstr_guid(&vscc
.guid
));
191 hr
= IAMStreamConfig_SetFormat(stream_config
, format
);
192 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
194 hr
= IAMStreamConfig_GetFormat(stream_config
, &format2
);
195 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
196 ok(compare_media_types(format
, format2
), "Media types didn't match.\n");
197 DeleteMediaType(format2
);
199 hr
= IPin_EnumMediaTypes(pin
, &enum_media_types
);
200 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
201 hr
= IEnumMediaTypes_Next(enum_media_types
, 1, &format2
, NULL
);
202 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
203 ok(compare_media_types(format
, format2
), "Media types didn't match.\n");
204 DeleteMediaType(format2
);
205 IEnumMediaTypes_Release(enum_media_types
);
207 DeleteMediaType(format
);
210 IAMStreamConfig_Release(stream_config
);
213 static void test_pin_interfaces(IPin
*pin
)
215 todo_wine
check_interface(pin
, &IID_IAMBufferNegotiation
, TRUE
);
216 check_interface(pin
, &IID_IAMStreamConfig
, TRUE
);
217 todo_wine
check_interface(pin
, &IID_IAMStreamControl
, TRUE
);
218 todo_wine
check_interface(pin
, &IID_IKsPin
, TRUE
);
219 check_interface(pin
, &IID_IKsPropertySet
, TRUE
);
220 todo_wine
check_interface(pin
, &IID_IMediaSeeking
, TRUE
);
221 check_interface(pin
, &IID_IPin
, TRUE
);
222 todo_wine
check_interface(pin
, &IID_IQualityControl
, TRUE
);
223 todo_wine
check_interface(pin
, &IID_ISpecifyPropertyPages
, TRUE
);
225 check_interface(pin
, &IID_IAMCrossbar
, FALSE
);
226 check_interface(pin
, &IID_IAMDroppedFrames
, FALSE
);
227 check_interface(pin
, &IID_IAMFilterMiscFlags
, FALSE
);
228 check_interface(pin
, &IID_IAMPushSource
, FALSE
);
229 check_interface(pin
, &IID_IAMTVTuner
, FALSE
);
230 check_interface(pin
, &IID_IAMVideoCompression
, FALSE
);
231 check_interface(pin
, &IID_IAMVideoProcAmp
, FALSE
);
232 check_interface(pin
, &IID_IPersistPropertyBag
, FALSE
);
233 check_interface(pin
, &IID_IStreamBuilder
, FALSE
);
236 static void test_pins(IBaseFilter
*filter
)
238 IEnumPins
*enum_pins
;
242 hr
= IBaseFilter_EnumPins(filter
, &enum_pins
);
243 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
245 while ((hr
= IEnumPins_Next(enum_pins
, 1, &pin
, NULL
)) == S_OK
)
247 PIN_DIRECTION pin_direction
;
248 IPin_QueryDirection(pin
, &pin_direction
);
249 if (pin_direction
== PINDIR_OUTPUT
)
251 test_pin_interfaces(pin
);
252 test_media_types(pin
);
253 test_stream_config(pin
);
258 IEnumPins_Release(enum_pins
);
261 static void test_filter_interfaces(IBaseFilter
*filter
)
263 check_interface(filter
, &IID_IAMFilterMiscFlags
, TRUE
);
264 check_interface(filter
, &IID_IAMVideoControl
, TRUE
);
265 check_interface(filter
, &IID_IAMVideoProcAmp
, TRUE
);
266 check_interface(filter
, &IID_IBaseFilter
, TRUE
);
267 todo_wine
check_interface(filter
, &IID_IKsPropertySet
, TRUE
);
268 todo_wine
check_interface(filter
, &IID_IMediaSeeking
, TRUE
);
269 check_interface(filter
, &IID_IPersistPropertyBag
, TRUE
);
270 todo_wine
check_interface(filter
, &IID_ISpecifyPropertyPages
, TRUE
);
272 check_interface(filter
, &IID_IAMCrossbar
, FALSE
);
273 check_interface(filter
, &IID_IAMPushSource
, FALSE
);
274 check_interface(filter
, &IID_IAMStreamConfig
, FALSE
);
275 check_interface(filter
, &IID_IAMTVTuner
, FALSE
);
276 check_interface(filter
, &IID_IAMVideoCompression
, FALSE
);
277 check_interface(filter
, &IID_IAMVfwCaptureDialogs
, FALSE
);
278 check_interface(filter
, &IID_IPin
, FALSE
);
279 check_interface(filter
, &IID_IReferenceClock
, FALSE
);
280 check_interface(filter
, &IID_IOverlayNotify
, FALSE
);
283 static void test_misc_flags(IBaseFilter
*filter
)
285 IAMFilterMiscFlags
*misc_flags
;
289 hr
= IBaseFilter_QueryInterface(filter
, &IID_IAMFilterMiscFlags
, (void **)&misc_flags
);
290 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
292 flags
= IAMFilterMiscFlags_GetMiscFlags(misc_flags
);
293 ok(flags
== AM_FILTER_MISC_FLAGS_IS_SOURCE
294 || broken(!flags
) /* win7 */, "Got wrong flags: %#x.\n", flags
);
296 IAMFilterMiscFlags_Release(misc_flags
);
301 struct strmbase_filter filter
;
302 struct strmbase_sink sink
;
305 static inline struct testfilter
*impl_from_strmbase_filter(struct strmbase_filter
*iface
)
307 return CONTAINING_RECORD(iface
, struct testfilter
, filter
);
310 static struct strmbase_pin
*testfilter_get_pin(struct strmbase_filter
*iface
, unsigned int index
)
312 struct testfilter
*filter
= impl_from_strmbase_filter(iface
);
314 return &filter
->sink
.pin
;
318 static void testfilter_destroy(struct strmbase_filter
*iface
)
320 struct testfilter
*filter
= impl_from_strmbase_filter(iface
);
321 strmbase_sink_cleanup(&filter
->sink
);
322 strmbase_filter_cleanup(&filter
->filter
);
325 static const struct strmbase_filter_ops testfilter_ops
=
327 .filter_get_pin
= testfilter_get_pin
,
328 .filter_destroy
= testfilter_destroy
,
331 static HRESULT
testsink_query_interface(struct strmbase_pin
*iface
, REFIID iid
, void **out
)
333 struct testfilter
*filter
= impl_from_strmbase_filter(iface
->filter
);
335 if (IsEqualGUID(iid
, &IID_IMemInputPin
))
336 *out
= &filter
->sink
.IMemInputPin_iface
;
338 return E_NOINTERFACE
;
340 IUnknown_AddRef((IUnknown
*)*out
);
344 static HRESULT WINAPI
testsink_Receive(struct strmbase_sink
*iface
, IMediaSample
*sample
)
349 static const struct strmbase_sink_ops testsink_ops
=
351 .base
.pin_query_interface
= testsink_query_interface
,
352 .pfnReceive
= testsink_Receive
,
355 static void testfilter_init(struct testfilter
*filter
)
357 static const GUID clsid
= {0xabacab};
358 memset(filter
, 0, sizeof(*filter
));
359 strmbase_filter_init(&filter
->filter
, NULL
, &clsid
, &testfilter_ops
);
360 strmbase_sink_init(&filter
->sink
, &filter
->filter
, L
"sink", &testsink_ops
, NULL
);
363 static void test_connect_pin(IBaseFilter
*filter
, IPin
*source
)
365 AM_MEDIA_TYPE req_mt
, default_mt
, mt
, *mts
[2];
366 IAMStreamConfig
*stream_config
;
367 struct testfilter testsink
;
368 IEnumMediaTypes
*enummt
;
369 IFilterGraph2
*graph
;
374 CoCreateInstance(&CLSID_FilterGraph
, NULL
, CLSCTX_INPROC_SERVER
,
375 &IID_IFilterGraph2
, (void **)&graph
);
376 testfilter_init(&testsink
);
377 IFilterGraph2_AddFilter(graph
, &testsink
.filter
.IBaseFilter_iface
, L
"sink");
378 IFilterGraph2_AddFilter(graph
, filter
, L
"source");
379 hr
= IPin_QueryInterface(source
, &IID_IAMStreamConfig
, (void **)&stream_config
);
380 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
382 peer
= (IPin
*)0xdeadbeef;
383 hr
= IPin_ConnectedTo(source
, &peer
);
384 ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
385 ok(!peer
, "Got peer %p.\n", peer
);
387 hr
= IPin_ConnectionMediaType(source
, &mt
);
388 ok(hr
== VFW_E_NOT_CONNECTED
, "Got hr %#x.\n", hr
);
390 hr
= IPin_EnumMediaTypes(source
, &enummt
);
391 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
392 hr
= IEnumMediaTypes_Next(enummt
, 2, mts
, &count
);
393 ok(SUCCEEDED(hr
), "Got hr %#x.\n", hr
);
394 CopyMediaType(&req_mt
, mts
[count
- 1]);
395 CopyMediaType(&default_mt
, mts
[0]);
396 DeleteMediaType(mts
[0]);
398 DeleteMediaType(mts
[1]);
399 IEnumMediaTypes_Release(enummt
);
401 hr
= IAMStreamConfig_GetFormat(stream_config
, &mts
[0]);
402 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
403 ok(compare_media_types(mts
[0], &default_mt
), "Media types didn't match.\n");
404 DeleteMediaType(mts
[0]);
406 hr
= IFilterGraph2_ConnectDirect(graph
, source
, &testsink
.sink
.pin
.IPin_iface
, &req_mt
);
407 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
409 hr
= IPin_ConnectedTo(source
, &peer
);
410 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
411 ok(peer
== &testsink
.sink
.pin
.IPin_iface
, "Got peer %p.\n", peer
);
414 hr
= IPin_ConnectionMediaType(source
, &mt
);
415 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
416 ok(compare_media_types(&mt
, &req_mt
), "Media types didn't match.\n");
417 ok(compare_media_types(&testsink
.sink
.pin
.mt
, &req_mt
), "Media types didn't match.\n");
420 hr
= IAMStreamConfig_GetFormat(stream_config
, &mts
[0]);
421 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
422 ok(compare_media_types(mts
[0], &req_mt
), "Media types didn't match.\n");
423 DeleteMediaType(mts
[0]);
425 hr
= IPin_EnumMediaTypes(source
, &enummt
);
426 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
427 hr
= IEnumMediaTypes_Next(enummt
, 1, mts
, NULL
);
428 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
429 ok(compare_media_types(mts
[0], &default_mt
), "Media types didn't match.\n");
430 DeleteMediaType(mts
[0]);
431 IEnumMediaTypes_Release(enummt
);
433 hr
= IFilterGraph2_Disconnect(graph
, source
);
434 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
435 hr
= IFilterGraph2_Disconnect(graph
, source
);
436 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
437 ok(testsink
.sink
.pin
.peer
== source
, "Got peer %p.\n", testsink
.sink
.pin
.peer
);
438 IFilterGraph2_Disconnect(graph
, &testsink
.sink
.pin
.IPin_iface
);
440 hr
= IAMStreamConfig_GetFormat(stream_config
, &mts
[0]);
441 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
442 ok(compare_media_types(mts
[0], &default_mt
), "Media types didn't match.\n");
443 DeleteMediaType(mts
[0]);
445 FreeMediaType(&req_mt
);
446 FreeMediaType(&default_mt
);
447 IAMStreamConfig_Release(stream_config
);
448 ref
= IFilterGraph2_Release(graph
);
449 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
450 ref
= IBaseFilter_Release(&testsink
.filter
.IBaseFilter_iface
);
451 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
454 static void test_connection(IMoniker
*moniker
)
456 IEnumPins
*enum_pins
;
462 hr
= IMoniker_BindToObject(moniker
, NULL
, NULL
, &IID_IBaseFilter
, (void **)&filter
);
463 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
465 hr
= IBaseFilter_EnumPins(filter
, &enum_pins
);
466 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
468 while (IEnumPins_Next(enum_pins
, 1, &pin
, NULL
) == S_OK
)
471 IPin_QueryDirection(pin
, &dir
);
472 if (dir
== PINDIR_OUTPUT
)
474 test_connect_pin(filter
, pin
);
479 IEnumPins_Release(enum_pins
);
480 ref
= IBaseFilter_Release(filter
);
481 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
484 START_TEST(videocapture
)
486 ICreateDevEnum
*dev_enum
;
487 IEnumMoniker
*class_enum
;
496 hr
= CoCreateInstance(&CLSID_SystemDeviceEnum
, NULL
, CLSCTX_INPROC
,
497 &IID_ICreateDevEnum
, (void **)&dev_enum
);
498 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
500 hr
= ICreateDevEnum_CreateClassEnumerator(dev_enum
, &CLSID_VideoInputDeviceCategory
, &class_enum
, 0);
503 skip("No video capture devices present.\n");
504 ICreateDevEnum_Release(dev_enum
);
508 ok(hr
== S_OK
, "Got hr=%#x.\n", hr
);
510 while (IEnumMoniker_Next(class_enum
, 1, &moniker
, NULL
) == S_OK
)
512 hr
= IMoniker_GetDisplayName(moniker
, NULL
, NULL
, &name
);
513 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
514 trace("Testing device %s.\n", wine_dbgstr_w(name
));
517 if (FAILED(hr
= IMoniker_BindToObject(moniker
, NULL
, NULL
, &IID_IBaseFilter
, (void **)&filter
)))
519 skip("Failed to open device %s, hr %#x.\n", debugstr_w(name
), hr
);
520 IMoniker_Release(moniker
);
524 test_filter_interfaces(filter
);
526 test_misc_flags(filter
);
528 ref
= IBaseFilter_Release(filter
);
529 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
531 test_connection(moniker
);
533 IMoniker_Release(moniker
);
536 ICreateDevEnum_Release(dev_enum
);
537 IEnumMoniker_Release(class_enum
);