2 * AVI muxer 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
24 #include "wine/test.h"
26 static const GUID testguid
= {0xfacade};
28 static IBaseFilter
*create_avi_mux(void)
30 IBaseFilter
*filter
= NULL
;
31 HRESULT hr
= CoCreateInstance(&CLSID_AviDest
, NULL
, CLSCTX_INPROC_SERVER
,
32 &IID_IBaseFilter
, (void **)&filter
);
33 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
37 static ULONG
get_refcount(void *iface
)
39 IUnknown
*unknown
= iface
;
40 IUnknown_AddRef(unknown
);
41 return IUnknown_Release(unknown
);
44 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
45 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
47 IUnknown
*iface
= iface_ptr
;
48 HRESULT hr
, expected_hr
;
51 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
53 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
54 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
56 IUnknown_Release(unk
);
59 static void test_interfaces(void)
61 IBaseFilter
*filter
= create_avi_mux();
64 check_interface(filter
, &IID_IBaseFilter
, TRUE
);
65 check_interface(filter
, &IID_IConfigAviMux
, TRUE
);
66 check_interface(filter
, &IID_IConfigInterleaving
, TRUE
);
67 check_interface(filter
, &IID_IMediaFilter
, TRUE
);
68 check_interface(filter
, &IID_IMediaSeeking
, TRUE
);
69 check_interface(filter
, &IID_IPersist
, TRUE
);
70 check_interface(filter
, &IID_IPersistMediaPropertyBag
, TRUE
);
71 check_interface(filter
, &IID_ISpecifyPropertyPages
, TRUE
);
72 check_interface(filter
, &IID_IUnknown
, TRUE
);
74 check_interface(filter
, &IID_IAMFilterMiscFlags
, FALSE
);
75 check_interface(filter
, &IID_IBasicAudio
, FALSE
);
76 check_interface(filter
, &IID_IBasicVideo
, FALSE
);
77 check_interface(filter
, &IID_IKsPropertySet
, FALSE
);
78 check_interface(filter
, &IID_IMediaPosition
, FALSE
);
79 check_interface(filter
, &IID_IPersistPropertyBag
, FALSE
);
80 check_interface(filter
, &IID_IPin
, FALSE
);
81 check_interface(filter
, &IID_IQualityControl
, FALSE
);
82 check_interface(filter
, &IID_IQualProp
, FALSE
);
83 check_interface(filter
, &IID_IReferenceClock
, FALSE
);
84 check_interface(filter
, &IID_IVideoWindow
, FALSE
);
86 IBaseFilter_FindPin(filter
, L
"AVI Out", &pin
);
88 check_interface(pin
, &IID_IPin
, TRUE
);
89 check_interface(pin
, &IID_IQualityControl
, TRUE
);
90 check_interface(pin
, &IID_IUnknown
, TRUE
);
92 check_interface(pin
, &IID_IAsyncReader
, FALSE
);
93 check_interface(pin
, &IID_IKsPropertySet
, FALSE
);
94 check_interface(pin
, &IID_IMediaSeeking
, FALSE
);
95 check_interface(pin
, &IID_IMediaPosition
, FALSE
);
99 IBaseFilter_FindPin(filter
, L
"Input 01", &pin
);
101 check_interface(pin
, &IID_IAMStreamControl
, TRUE
);
102 check_interface(pin
, &IID_IMemInputPin
, TRUE
);
103 check_interface(pin
, &IID_IPin
, TRUE
);
104 check_interface(pin
, &IID_IPropertyBag
, TRUE
);
105 check_interface(pin
, &IID_IQualityControl
, TRUE
);
106 check_interface(pin
, &IID_IUnknown
, TRUE
);
108 check_interface(pin
, &IID_IKsPropertySet
, FALSE
);
109 check_interface(pin
, &IID_IMediaSeeking
, FALSE
);
110 check_interface(pin
, &IID_IMediaPosition
, FALSE
);
114 IBaseFilter_Release(filter
);
117 static const GUID test_iid
= {0x33333333};
118 static LONG outer_ref
= 1;
120 static HRESULT WINAPI
outer_QueryInterface(IUnknown
*iface
, REFIID iid
, void **out
)
122 if (IsEqualGUID(iid
, &IID_IUnknown
)
123 || IsEqualGUID(iid
, &IID_IBaseFilter
)
124 || IsEqualGUID(iid
, &test_iid
))
126 *out
= (IUnknown
*)0xdeadbeef;
129 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid
));
130 return E_NOINTERFACE
;
133 static ULONG WINAPI
outer_AddRef(IUnknown
*iface
)
135 return InterlockedIncrement(&outer_ref
);
138 static ULONG WINAPI
outer_Release(IUnknown
*iface
)
140 return InterlockedDecrement(&outer_ref
);
143 static const IUnknownVtbl outer_vtbl
=
145 outer_QueryInterface
,
150 static IUnknown test_outer
= {&outer_vtbl
};
152 static void test_aggregation(void)
154 IBaseFilter
*filter
, *filter2
;
155 IUnknown
*unk
, *unk2
;
159 filter
= (IBaseFilter
*)0xdeadbeef;
160 hr
= CoCreateInstance(&CLSID_AviDest
, &test_outer
, CLSCTX_INPROC_SERVER
,
161 &IID_IBaseFilter
, (void **)&filter
);
162 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
163 ok(!filter
, "Got interface %p.\n", filter
);
165 hr
= CoCreateInstance(&CLSID_AviDest
, &test_outer
, CLSCTX_INPROC_SERVER
,
166 &IID_IUnknown
, (void **)&unk
);
167 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
168 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
169 ok(unk
!= &test_outer
, "Returned IUnknown should not be outer IUnknown.\n");
170 ref
= get_refcount(unk
);
171 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
173 ref
= IUnknown_AddRef(unk
);
174 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
175 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
177 ref
= IUnknown_Release(unk
);
178 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
179 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
181 hr
= IUnknown_QueryInterface(unk
, &IID_IUnknown
, (void **)&unk2
);
182 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
183 ok(unk2
== unk
, "Got unexpected IUnknown %p.\n", unk2
);
184 IUnknown_Release(unk2
);
186 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void **)&filter
);
187 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
189 hr
= IBaseFilter_QueryInterface(filter
, &IID_IUnknown
, (void **)&unk2
);
190 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
191 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
193 hr
= IBaseFilter_QueryInterface(filter
, &IID_IBaseFilter
, (void **)&filter2
);
194 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
195 ok(filter2
== (IBaseFilter
*)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2
);
197 hr
= IUnknown_QueryInterface(unk
, &test_iid
, (void **)&unk2
);
198 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
199 ok(!unk2
, "Got unexpected IUnknown %p.\n", unk2
);
201 hr
= IBaseFilter_QueryInterface(filter
, &test_iid
, (void **)&unk2
);
202 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
203 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
205 IBaseFilter_Release(filter
);
206 ref
= IUnknown_Release(unk
);
207 ok(!ref
, "Got unexpected refcount %d.\n", ref
);
208 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
211 static void test_enum_pins(void)
213 IBaseFilter
*filter
= create_avi_mux();
214 IEnumPins
*enum1
, *enum2
;
219 ref
= get_refcount(filter
);
220 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
222 hr
= IBaseFilter_EnumPins(filter
, NULL
);
223 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
225 hr
= IBaseFilter_EnumPins(filter
, &enum1
);
226 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
227 ref
= get_refcount(filter
);
228 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
229 ref
= get_refcount(enum1
);
230 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
232 hr
= IEnumPins_Next(enum1
, 1, NULL
, NULL
);
233 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
235 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
236 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
237 ref
= get_refcount(filter
);
238 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
239 ref
= get_refcount(pins
[0]);
240 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
241 ref
= get_refcount(enum1
);
242 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
243 IPin_Release(pins
[0]);
244 ref
= get_refcount(filter
);
245 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
247 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
248 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
249 ref
= get_refcount(filter
);
250 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
251 ref
= get_refcount(pins
[0]);
252 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
253 ref
= get_refcount(enum1
);
254 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
255 IPin_Release(pins
[0]);
256 ref
= get_refcount(filter
);
257 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
259 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
260 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
262 hr
= IEnumPins_Reset(enum1
);
263 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
265 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
266 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
267 ok(count
== 1, "Got count %u.\n", count
);
268 IPin_Release(pins
[0]);
270 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
271 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
272 ok(count
== 1, "Got count %u.\n", count
);
273 IPin_Release(pins
[0]);
275 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
276 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
277 ok(!count
, "Got count %u.\n", count
);
279 hr
= IEnumPins_Reset(enum1
);
280 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
282 hr
= IEnumPins_Next(enum1
, 2, pins
, NULL
);
283 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
285 hr
= IEnumPins_Next(enum1
, 2, pins
, &count
);
286 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
287 ok(count
== 2, "Got count %u.\n", count
);
288 IPin_Release(pins
[0]);
289 IPin_Release(pins
[1]);
291 hr
= IEnumPins_Next(enum1
, 2, pins
, &count
);
292 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
293 ok(!count
, "Got count %u.\n", count
);
295 hr
= IEnumPins_Reset(enum1
);
296 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
298 hr
= IEnumPins_Next(enum1
, 3, pins
, &count
);
299 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
300 ok(count
== 2, "Got count %u.\n", count
);
301 IPin_Release(pins
[0]);
302 IPin_Release(pins
[1]);
304 hr
= IEnumPins_Reset(enum1
);
305 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
307 hr
= IEnumPins_Clone(enum1
, &enum2
);
308 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
310 hr
= IEnumPins_Skip(enum1
, 3);
311 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
313 hr
= IEnumPins_Skip(enum1
, 2);
314 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
316 hr
= IEnumPins_Skip(enum1
, 1);
317 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
319 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
320 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
322 hr
= IEnumPins_Next(enum2
, 1, pins
, NULL
);
323 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
324 IPin_Release(pins
[0]);
326 IEnumPins_Release(enum2
);
327 IEnumPins_Release(enum1
);
328 ref
= IBaseFilter_Release(filter
);
329 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
332 static void test_find_pin(void)
334 IBaseFilter
*filter
= create_avi_mux();
335 IEnumPins
*enum_pins
;
340 hr
= IBaseFilter_EnumPins(filter
, &enum_pins
);
341 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
343 hr
= IBaseFilter_FindPin(filter
, L
"AVI Out", &pin
);
344 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
345 hr
= IEnumPins_Next(enum_pins
, 1, &pin2
, NULL
);
346 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
347 ok(pin
== pin2
, "Pins didn't match.\n");
351 hr
= IBaseFilter_FindPin(filter
, L
"Input 01", &pin
);
352 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
353 hr
= IEnumPins_Next(enum_pins
, 1, &pin2
, NULL
);
354 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
355 ok(pin
== pin2
, "Pins didn't match.\n");
359 IEnumPins_Release(enum_pins
);
360 ref
= IBaseFilter_Release(filter
);
361 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
364 static void test_pin_info(void)
366 IBaseFilter
*filter
= create_avi_mux();
374 hr
= IBaseFilter_FindPin(filter
, L
"AVI Out", &pin
);
375 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
376 ref
= get_refcount(filter
);
377 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
378 ref
= get_refcount(pin
);
379 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
381 hr
= IPin_QueryPinInfo(pin
, &info
);
382 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
383 ok(info
.pFilter
== filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
384 ok(info
.dir
== PINDIR_OUTPUT
, "Got direction %d.\n", info
.dir
);
385 ok(!lstrcmpW(info
.achName
, L
"AVI Out"), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
386 ref
= get_refcount(filter
);
387 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
388 ref
= get_refcount(pin
);
389 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
390 IBaseFilter_Release(info
.pFilter
);
392 hr
= IPin_QueryDirection(pin
, &dir
);
393 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
394 ok(dir
== PINDIR_OUTPUT
, "Got direction %d.\n", dir
);
396 hr
= IPin_QueryId(pin
, &id
);
397 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
398 ok(!lstrcmpW(id
, L
"AVI Out"), "Got id %s.\n", wine_dbgstr_w(id
));
401 hr
= IPin_QueryInternalConnections(pin
, NULL
, NULL
);
402 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
406 hr
= IBaseFilter_FindPin(filter
, L
"Input 01", &pin
);
407 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
409 hr
= IPin_QueryPinInfo(pin
, &info
);
410 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
411 ok(info
.pFilter
== filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
412 ok(info
.dir
== PINDIR_INPUT
, "Got direction %d.\n", info
.dir
);
413 ok(!lstrcmpW(info
.achName
, L
"Input 01"), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
414 IBaseFilter_Release(info
.pFilter
);
416 hr
= IPin_QueryDirection(pin
, &dir
);
417 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
418 ok(dir
== PINDIR_INPUT
, "Got direction %d.\n", dir
);
420 hr
= IPin_QueryId(pin
, &id
);
421 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
422 ok(!lstrcmpW(id
, L
"Input 01"), "Got id %s.\n", wine_dbgstr_w(id
));
425 hr
= IPin_QueryInternalConnections(pin
, NULL
, NULL
);
426 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
430 ref
= IBaseFilter_Release(filter
);
431 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
434 static void test_media_types(void)
436 IBaseFilter
*filter
= create_avi_mux();
437 AM_MEDIA_TYPE mt
= {}, *pmt
;
438 VIDEOINFOHEADER vih
= {};
439 IEnumMediaTypes
*enummt
;
440 WAVEFORMATEX wfx
= {};
445 IBaseFilter_FindPin(filter
, L
"AVI Out", &pin
);
447 hr
= IPin_EnumMediaTypes(pin
, &enummt
);
448 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
450 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, NULL
);
451 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
452 ok(IsEqualGUID(&pmt
->majortype
, &MEDIATYPE_Stream
), "Got major type %s\n",
453 wine_dbgstr_guid(&pmt
->majortype
));
454 ok(IsEqualGUID(&pmt
->subtype
, &MEDIASUBTYPE_Avi
), "Got subtype %s\n",
455 wine_dbgstr_guid(&pmt
->subtype
));
456 ok(pmt
->bFixedSizeSamples
== TRUE
, "Got fixed size %d.\n", pmt
->bFixedSizeSamples
);
457 ok(!pmt
->bTemporalCompression
, "Got temporal compression %d.\n", pmt
->bTemporalCompression
);
458 ok(pmt
->lSampleSize
== 1, "Got sample size %u.\n", pmt
->lSampleSize
);
459 ok(IsEqualGUID(&pmt
->formattype
, &GUID_NULL
), "Got format type %s.\n",
460 wine_dbgstr_guid(&pmt
->formattype
));
461 ok(!pmt
->pUnk
, "Got pUnk %p.\n", pmt
->pUnk
);
462 ok(!pmt
->cbFormat
, "Got format size %u.\n", pmt
->cbFormat
);
463 ok(!pmt
->pbFormat
, "Got format block %u.\n", pmt
->cbFormat
);
465 hr
= IPin_QueryAccept(pin
, pmt
);
466 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
468 pmt
->bFixedSizeSamples
= FALSE
;
469 pmt
->bTemporalCompression
= TRUE
;
470 pmt
->lSampleSize
= 123;
471 hr
= IPin_QueryAccept(pin
, pmt
);
472 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
474 pmt
->majortype
= GUID_NULL
;
475 hr
= IPin_QueryAccept(pin
, pmt
);
476 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
477 pmt
->majortype
= MEDIATYPE_Video
;
478 hr
= IPin_QueryAccept(pin
, pmt
);
479 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
480 pmt
->majortype
= MEDIATYPE_Stream
;
482 pmt
->subtype
= GUID_NULL
;
483 hr
= IPin_QueryAccept(pin
, pmt
);
484 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
485 pmt
->subtype
= MEDIASUBTYPE_RGB8
;
486 hr
= IPin_QueryAccept(pin
, pmt
);
487 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
488 pmt
->subtype
= MEDIASUBTYPE_Avi
;
492 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, NULL
);
493 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
495 IEnumMediaTypes_Release(enummt
);
498 IBaseFilter_FindPin(filter
, L
"Input 01", &pin
);
500 hr
= IPin_EnumMediaTypes(pin
, &enummt
);
501 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
503 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, NULL
);
504 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
506 IEnumMediaTypes_Release(enummt
);
508 mt
.majortype
= MEDIATYPE_Audio
;
509 mt
.formattype
= FORMAT_WaveFormatEx
;
510 mt
.cbFormat
= sizeof(wfx
);
511 mt
.pbFormat
= (BYTE
*)&wfx
;
513 hr
= IPin_QueryAccept(pin
, &mt
);
514 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
516 mt
.subtype
= MEDIASUBTYPE_RGB8
;
517 mt
.bFixedSizeSamples
= TRUE
;
518 mt
.bTemporalCompression
= TRUE
;
519 mt
.lSampleSize
= 123;
520 hr
= IPin_QueryAccept(pin
, &mt
);
521 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
523 mt
.majortype
= MEDIATYPE_Video
;
524 hr
= IPin_QueryAccept(pin
, &mt
);
525 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
526 mt
.majortype
= GUID_NULL
;
527 hr
= IPin_QueryAccept(pin
, &mt
);
528 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
529 mt
.majortype
= MEDIATYPE_Interleaved
;
530 hr
= IPin_QueryAccept(pin
, &mt
);
531 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
533 mt
.majortype
= MEDIATYPE_Video
;
534 mt
.formattype
= FORMAT_VideoInfo
;
535 mt
.cbFormat
= sizeof(vih
);
536 mt
.pbFormat
= (BYTE
*)&vih
;
537 hr
= IPin_QueryAccept(pin
, &mt
);
538 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
540 mt
.majortype
= MEDIATYPE_Audio
;
541 hr
= IPin_QueryAccept(pin
, &mt
);
542 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
543 mt
.majortype
= GUID_NULL
;
544 hr
= IPin_QueryAccept(pin
, &mt
);
545 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
546 mt
.majortype
= MEDIATYPE_Interleaved
;
547 hr
= IPin_QueryAccept(pin
, &mt
);
548 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
552 ref
= IBaseFilter_Release(filter
);
553 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
556 static void test_enum_media_types(void)
558 IBaseFilter
*filter
= create_avi_mux();
559 IEnumMediaTypes
*enum1
, *enum2
;
560 AM_MEDIA_TYPE
*mts
[2];
565 IBaseFilter_FindPin(filter
, L
"AVI Out", &pin
);
567 hr
= IPin_EnumMediaTypes(pin
, &enum1
);
568 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
570 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
571 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
572 CoTaskMemFree(mts
[0]);
574 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
575 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
577 hr
= IEnumMediaTypes_Reset(enum1
);
578 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
580 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
581 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
582 ok(count
== 1, "Got count %u.\n", count
);
583 CoTaskMemFree(mts
[0]);
585 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
586 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
587 ok(!count
, "Got count %u.\n", count
);
589 hr
= IEnumMediaTypes_Reset(enum1
);
590 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
592 hr
= IEnumMediaTypes_Next(enum1
, 2, mts
, &count
);
593 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
594 ok(count
== 1, "Got count %u.\n", count
);
595 CoTaskMemFree(mts
[0]);
597 hr
= IEnumMediaTypes_Reset(enum1
);
598 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
600 hr
= IEnumMediaTypes_Clone(enum1
, &enum2
);
601 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
603 hr
= IEnumMediaTypes_Skip(enum1
, 2);
604 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
606 hr
= IEnumMediaTypes_Skip(enum1
, 1);
607 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
609 hr
= IEnumMediaTypes_Reset(enum1
);
610 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
612 hr
= IEnumMediaTypes_Skip(enum1
, 1);
613 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
615 hr
= IEnumMediaTypes_Skip(enum1
, 1);
616 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
618 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
619 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
621 hr
= IEnumMediaTypes_Next(enum2
, 1, mts
, NULL
);
622 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
623 CoTaskMemFree(mts
[0]);
625 IEnumMediaTypes_Release(enum1
);
626 IEnumMediaTypes_Release(enum2
);
629 IBaseFilter_FindPin(filter
, L
"Input 01", &pin
);
631 hr
= IPin_EnumMediaTypes(pin
, &enum1
);
632 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
634 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
635 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
637 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
638 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
639 ok(!count
, "Got count %u.\n", count
);
641 hr
= IEnumMediaTypes_Reset(enum1
);
642 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
644 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
645 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
647 hr
= IEnumMediaTypes_Clone(enum1
, &enum2
);
648 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
650 hr
= IEnumMediaTypes_Skip(enum1
, 1);
651 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
653 hr
= IEnumMediaTypes_Next(enum2
, 1, mts
, NULL
);
654 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
656 IEnumMediaTypes_Release(enum1
);
657 IEnumMediaTypes_Release(enum2
);
660 ref
= IBaseFilter_Release(filter
);
661 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
664 static void test_seeking(void)
666 IBaseFilter
*filter
= create_avi_mux();
667 LONGLONG time
, current
, stop
;
668 IMediaSeeking
*seeking
;
682 {&TIME_FORMAT_MEDIA_TIME
, S_OK
},
683 {&TIME_FORMAT_BYTE
, S_OK
},
685 {&TIME_FORMAT_NONE
, S_FALSE
},
686 {&TIME_FORMAT_FRAME
, S_FALSE
},
687 {&TIME_FORMAT_SAMPLE
, S_FALSE
},
688 {&TIME_FORMAT_FIELD
, S_FALSE
},
689 {&testguid
, S_FALSE
},
692 IBaseFilter_QueryInterface(filter
, &IID_IMediaSeeking
, (void **)&seeking
);
694 hr
= IMediaSeeking_GetCapabilities(seeking
, &caps
);
695 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
696 todo_wine
ok(caps
== (AM_SEEKING_CanGetCurrentPos
| AM_SEEKING_CanGetDuration
), "Got caps %#x.\n", caps
);
698 caps
= AM_SEEKING_CanGetCurrentPos
;
699 hr
= IMediaSeeking_CheckCapabilities(seeking
, &caps
);
700 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
701 ok(caps
== AM_SEEKING_CanGetCurrentPos
, "Got caps %#x.\n", caps
);
703 caps
= AM_SEEKING_CanDoSegments
| AM_SEEKING_CanGetCurrentPos
;
704 hr
= IMediaSeeking_CheckCapabilities(seeking
, &caps
);
705 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
706 todo_wine
ok(caps
== AM_SEEKING_CanGetCurrentPos
, "Got caps %#x.\n", caps
);
708 caps
= AM_SEEKING_CanDoSegments
;
709 hr
= IMediaSeeking_CheckCapabilities(seeking
, &caps
);
710 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
711 todo_wine
ok(!caps
, "Got caps %#x.\n", caps
);
713 for (i
= 0; i
< ARRAY_SIZE(format_tests
); ++i
)
715 hr
= IMediaSeeking_IsFormatSupported(seeking
, format_tests
[i
].guid
);
716 todo_wine
ok(hr
== format_tests
[i
].hr
, "Got hr %#x for format %s.\n", hr
, wine_dbgstr_guid(format_tests
[i
].guid
));
719 hr
= IMediaSeeking_QueryPreferredFormat(seeking
, &format
);
720 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
721 todo_wine
ok(IsEqualGUID(&format
, &TIME_FORMAT_MEDIA_TIME
), "Got format %s.\n", wine_dbgstr_guid(&format
));
723 hr
= IMediaSeeking_GetTimeFormat(seeking
, &format
);
724 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
725 todo_wine
ok(IsEqualGUID(&format
, &TIME_FORMAT_MEDIA_TIME
), "Got format %s.\n", wine_dbgstr_guid(&format
));
727 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_MEDIA_TIME
);
728 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
729 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_BYTE
);
730 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
732 hr
= IMediaSeeking_SetTimeFormat(seeking
, &TIME_FORMAT_SAMPLE
);
733 todo_wine
ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
735 hr
= IMediaSeeking_SetTimeFormat(seeking
, &TIME_FORMAT_BYTE
);
736 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
738 hr
= IMediaSeeking_QueryPreferredFormat(seeking
, &format
);
739 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
740 todo_wine
ok(IsEqualGUID(&format
, &TIME_FORMAT_MEDIA_TIME
), "Got format %s.\n", wine_dbgstr_guid(&format
));
742 hr
= IMediaSeeking_GetTimeFormat(seeking
, &format
);
743 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
744 todo_wine
ok(IsEqualGUID(&format
, &TIME_FORMAT_BYTE
), "Got format %s.\n", wine_dbgstr_guid(&format
));
746 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_MEDIA_TIME
);
747 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
748 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_BYTE
);
749 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
751 hr
= IMediaSeeking_SetTimeFormat(seeking
, &TIME_FORMAT_MEDIA_TIME
);
752 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
754 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_MEDIA_TIME
);
755 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
756 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_BYTE
);
757 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
759 hr
= IMediaSeeking_ConvertTimeFormat(seeking
, &time
, NULL
, 0x123456789a, NULL
);
760 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
761 hr
= IMediaSeeking_ConvertTimeFormat(seeking
, &time
, &TIME_FORMAT_MEDIA_TIME
, 0x123456789a, &TIME_FORMAT_BYTE
);
762 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
766 hr
= IMediaSeeking_SetPositions(seeking
, ¤t
, AM_SEEKING_AbsolutePositioning
,
767 &stop
, AM_SEEKING_AbsolutePositioning
);
768 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
769 hr
= IMediaSeeking_SetPositions(seeking
, ¤t
, AM_SEEKING_NoPositioning
,
770 &stop
, AM_SEEKING_NoPositioning
);
771 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
773 hr
= IMediaSeeking_GetPositions(seeking
, NULL
, NULL
);
774 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
775 hr
= IMediaSeeking_GetPositions(seeking
, NULL
, &stop
);
776 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
777 hr
= IMediaSeeking_GetPositions(seeking
, ¤t
, &stop
);
778 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
779 hr
= IMediaSeeking_GetPositions(seeking
, ¤t
, NULL
);
780 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
782 hr
= IMediaSeeking_GetDuration(seeking
, &time
);
783 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
785 ok(!time
, "Got duration %s.\n", wine_dbgstr_longlong(time
));
787 hr
= IMediaSeeking_GetCurrentPosition(seeking
, &time
);
788 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
790 ok(!time
, "Got duration %s.\n", wine_dbgstr_longlong(time
));
792 hr
= IMediaSeeking_GetStopPosition(seeking
, &time
);
793 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
795 IMediaSeeking_Release(seeking
);
796 ref
= IBaseFilter_Release(filter
);
797 ok(!ref
, "Got unexpected refcount %d.\n", ref
);
800 static void test_unconnected_filter_state(void)
802 IBaseFilter
*filter
= create_avi_mux();
807 hr
= IBaseFilter_GetState(filter
, 0, &state
);
808 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
809 ok(state
== State_Stopped
, "Got state %u.\n", state
);
811 hr
= IBaseFilter_Pause(filter
);
812 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
814 hr
= IBaseFilter_GetState(filter
, 0, &state
);
815 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
816 todo_wine
ok(state
== State_Paused
, "Got state %u.\n", state
);
818 hr
= IBaseFilter_Run(filter
, 0);
819 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
821 hr
= IBaseFilter_GetState(filter
, 0, &state
);
822 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
823 todo_wine
ok(state
== State_Running
, "Got state %u.\n", state
);
825 hr
= IBaseFilter_Pause(filter
);
826 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
828 hr
= IBaseFilter_GetState(filter
, 0, &state
);
829 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
830 todo_wine
ok(state
== State_Paused
, "Got state %u.\n", state
);
832 hr
= IBaseFilter_Stop(filter
);
833 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
835 hr
= IBaseFilter_GetState(filter
, 0, &state
);
836 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
837 ok(state
== State_Stopped
, "Got state %u.\n", state
);
839 hr
= IBaseFilter_Run(filter
, 0);
840 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
842 hr
= IBaseFilter_GetState(filter
, 0, &state
);
843 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
844 todo_wine
ok(state
== State_Running
, "Got state %u.\n", state
);
846 hr
= IBaseFilter_Stop(filter
);
847 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
849 hr
= IBaseFilter_GetState(filter
, 0, &state
);
850 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
851 ok(state
== State_Stopped
, "Got state %u.\n", state
);
853 ref
= IBaseFilter_Release(filter
);
854 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
867 test_enum_media_types();
869 test_unconnected_filter_state();