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 WCHAR source_id
[] = {'A','V','I',' ','O','u','t',0};
27 static const WCHAR sink0_id
[] = {'I','n','p','u','t',' ','0','1',0};
29 static const GUID testguid
= {0xfacade};
31 static IBaseFilter
*create_avi_mux(void)
33 IBaseFilter
*filter
= NULL
;
34 HRESULT hr
= CoCreateInstance(&CLSID_AviDest
, NULL
, CLSCTX_INPROC_SERVER
,
35 &IID_IBaseFilter
, (void **)&filter
);
36 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
40 static ULONG
get_refcount(void *iface
)
42 IUnknown
*unknown
= iface
;
43 IUnknown_AddRef(unknown
);
44 return IUnknown_Release(unknown
);
47 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
48 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
50 IUnknown
*iface
= iface_ptr
;
51 HRESULT hr
, expected_hr
;
54 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
56 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
57 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
59 IUnknown_Release(unk
);
62 static void test_interfaces(void)
64 IBaseFilter
*filter
= create_avi_mux();
67 check_interface(filter
, &IID_IBaseFilter
, TRUE
);
68 check_interface(filter
, &IID_IConfigAviMux
, TRUE
);
69 check_interface(filter
, &IID_IConfigInterleaving
, TRUE
);
70 check_interface(filter
, &IID_IMediaFilter
, TRUE
);
71 check_interface(filter
, &IID_IMediaSeeking
, TRUE
);
72 check_interface(filter
, &IID_IPersist
, TRUE
);
73 check_interface(filter
, &IID_IPersistMediaPropertyBag
, TRUE
);
74 check_interface(filter
, &IID_ISpecifyPropertyPages
, TRUE
);
75 check_interface(filter
, &IID_IUnknown
, TRUE
);
77 check_interface(filter
, &IID_IAMFilterMiscFlags
, FALSE
);
78 check_interface(filter
, &IID_IBasicAudio
, FALSE
);
79 check_interface(filter
, &IID_IBasicVideo
, FALSE
);
80 check_interface(filter
, &IID_IKsPropertySet
, FALSE
);
81 check_interface(filter
, &IID_IMediaPosition
, FALSE
);
82 check_interface(filter
, &IID_IPersistPropertyBag
, FALSE
);
83 check_interface(filter
, &IID_IPin
, FALSE
);
84 check_interface(filter
, &IID_IQualityControl
, FALSE
);
85 check_interface(filter
, &IID_IQualProp
, FALSE
);
86 check_interface(filter
, &IID_IReferenceClock
, FALSE
);
87 check_interface(filter
, &IID_IVideoWindow
, FALSE
);
89 IBaseFilter_FindPin(filter
, source_id
, &pin
);
91 check_interface(pin
, &IID_IPin
, TRUE
);
92 check_interface(pin
, &IID_IQualityControl
, TRUE
);
93 check_interface(pin
, &IID_IUnknown
, TRUE
);
95 check_interface(pin
, &IID_IAsyncReader
, FALSE
);
96 check_interface(pin
, &IID_IKsPropertySet
, FALSE
);
97 check_interface(pin
, &IID_IMediaSeeking
, FALSE
);
98 check_interface(pin
, &IID_IMediaPosition
, FALSE
);
102 IBaseFilter_FindPin(filter
, sink0_id
, &pin
);
104 check_interface(pin
, &IID_IAMStreamControl
, TRUE
);
105 check_interface(pin
, &IID_IMemInputPin
, TRUE
);
106 check_interface(pin
, &IID_IPin
, TRUE
);
107 check_interface(pin
, &IID_IPropertyBag
, TRUE
);
108 check_interface(pin
, &IID_IQualityControl
, TRUE
);
109 check_interface(pin
, &IID_IUnknown
, TRUE
);
111 check_interface(pin
, &IID_IKsPropertySet
, FALSE
);
112 check_interface(pin
, &IID_IMediaSeeking
, FALSE
);
113 check_interface(pin
, &IID_IMediaPosition
, FALSE
);
117 IBaseFilter_Release(filter
);
120 static const GUID test_iid
= {0x33333333};
121 static LONG outer_ref
= 1;
123 static HRESULT WINAPI
outer_QueryInterface(IUnknown
*iface
, REFIID iid
, void **out
)
125 if (IsEqualGUID(iid
, &IID_IUnknown
)
126 || IsEqualGUID(iid
, &IID_IBaseFilter
)
127 || IsEqualGUID(iid
, &test_iid
))
129 *out
= (IUnknown
*)0xdeadbeef;
132 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid
));
133 return E_NOINTERFACE
;
136 static ULONG WINAPI
outer_AddRef(IUnknown
*iface
)
138 return InterlockedIncrement(&outer_ref
);
141 static ULONG WINAPI
outer_Release(IUnknown
*iface
)
143 return InterlockedDecrement(&outer_ref
);
146 static const IUnknownVtbl outer_vtbl
=
148 outer_QueryInterface
,
153 static IUnknown test_outer
= {&outer_vtbl
};
155 static void test_aggregation(void)
157 IBaseFilter
*filter
, *filter2
;
158 IUnknown
*unk
, *unk2
;
162 filter
= (IBaseFilter
*)0xdeadbeef;
163 hr
= CoCreateInstance(&CLSID_AviDest
, &test_outer
, CLSCTX_INPROC_SERVER
,
164 &IID_IBaseFilter
, (void **)&filter
);
165 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
166 ok(!filter
, "Got interface %p.\n", filter
);
168 hr
= CoCreateInstance(&CLSID_AviDest
, &test_outer
, CLSCTX_INPROC_SERVER
,
169 &IID_IUnknown
, (void **)&unk
);
170 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
171 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
172 ok(unk
!= &test_outer
, "Returned IUnknown should not be outer IUnknown.\n");
173 ref
= get_refcount(unk
);
174 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
176 ref
= IUnknown_AddRef(unk
);
177 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
178 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
180 ref
= IUnknown_Release(unk
);
181 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
182 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
184 hr
= IUnknown_QueryInterface(unk
, &IID_IUnknown
, (void **)&unk2
);
185 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
186 ok(unk2
== unk
, "Got unexpected IUnknown %p.\n", unk2
);
187 IUnknown_Release(unk2
);
189 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void **)&filter
);
190 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
192 hr
= IBaseFilter_QueryInterface(filter
, &IID_IUnknown
, (void **)&unk2
);
193 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
194 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
196 hr
= IBaseFilter_QueryInterface(filter
, &IID_IBaseFilter
, (void **)&filter2
);
197 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
198 ok(filter2
== (IBaseFilter
*)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2
);
200 hr
= IUnknown_QueryInterface(unk
, &test_iid
, (void **)&unk2
);
201 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
202 ok(!unk2
, "Got unexpected IUnknown %p.\n", unk2
);
204 hr
= IBaseFilter_QueryInterface(filter
, &test_iid
, (void **)&unk2
);
205 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
206 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
208 IBaseFilter_Release(filter
);
209 ref
= IUnknown_Release(unk
);
210 ok(!ref
, "Got unexpected refcount %d.\n", ref
);
211 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
214 static void test_enum_pins(void)
216 IBaseFilter
*filter
= create_avi_mux();
217 IEnumPins
*enum1
, *enum2
;
222 ref
= get_refcount(filter
);
223 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
225 hr
= IBaseFilter_EnumPins(filter
, NULL
);
226 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
228 hr
= IBaseFilter_EnumPins(filter
, &enum1
);
229 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
230 ref
= get_refcount(filter
);
231 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
232 ref
= get_refcount(enum1
);
233 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
235 hr
= IEnumPins_Next(enum1
, 1, NULL
, NULL
);
236 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
238 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
239 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
240 ref
= get_refcount(filter
);
241 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
242 ref
= get_refcount(pins
[0]);
243 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
244 ref
= get_refcount(enum1
);
245 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
246 IPin_Release(pins
[0]);
247 ref
= get_refcount(filter
);
248 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
250 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
251 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
252 ref
= get_refcount(filter
);
253 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
254 ref
= get_refcount(pins
[0]);
255 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
256 ref
= get_refcount(enum1
);
257 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
258 IPin_Release(pins
[0]);
259 ref
= get_refcount(filter
);
260 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
262 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
263 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
265 hr
= IEnumPins_Reset(enum1
);
266 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
268 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
269 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
270 ok(count
== 1, "Got count %u.\n", count
);
271 IPin_Release(pins
[0]);
273 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
274 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
275 ok(count
== 1, "Got count %u.\n", count
);
276 IPin_Release(pins
[0]);
278 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
279 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
280 ok(!count
, "Got count %u.\n", count
);
282 hr
= IEnumPins_Reset(enum1
);
283 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
285 hr
= IEnumPins_Next(enum1
, 2, pins
, NULL
);
286 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
288 hr
= IEnumPins_Next(enum1
, 2, pins
, &count
);
289 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
290 ok(count
== 2, "Got count %u.\n", count
);
291 IPin_Release(pins
[0]);
292 IPin_Release(pins
[1]);
294 hr
= IEnumPins_Next(enum1
, 2, pins
, &count
);
295 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
296 ok(!count
, "Got count %u.\n", count
);
298 hr
= IEnumPins_Reset(enum1
);
299 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
301 hr
= IEnumPins_Next(enum1
, 3, pins
, &count
);
302 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
303 ok(count
== 2, "Got count %u.\n", count
);
304 IPin_Release(pins
[0]);
305 IPin_Release(pins
[1]);
307 hr
= IEnumPins_Reset(enum1
);
308 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
310 hr
= IEnumPins_Clone(enum1
, &enum2
);
311 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
313 hr
= IEnumPins_Skip(enum1
, 3);
314 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
316 hr
= IEnumPins_Skip(enum1
, 2);
317 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
319 hr
= IEnumPins_Skip(enum1
, 1);
320 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
322 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
323 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
325 hr
= IEnumPins_Next(enum2
, 1, pins
, NULL
);
326 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
327 IPin_Release(pins
[0]);
329 IEnumPins_Release(enum2
);
330 IEnumPins_Release(enum1
);
331 ref
= IBaseFilter_Release(filter
);
332 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
335 static void test_find_pin(void)
337 IBaseFilter
*filter
= create_avi_mux();
338 IEnumPins
*enum_pins
;
343 hr
= IBaseFilter_EnumPins(filter
, &enum_pins
);
344 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
346 hr
= IBaseFilter_FindPin(filter
, source_id
, &pin
);
347 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
348 hr
= IEnumPins_Next(enum_pins
, 1, &pin2
, NULL
);
349 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
350 ok(pin
== pin2
, "Pins didn't match.\n");
354 hr
= IBaseFilter_FindPin(filter
, sink0_id
, &pin
);
355 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
356 hr
= IEnumPins_Next(enum_pins
, 1, &pin2
, NULL
);
357 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
358 ok(pin
== pin2
, "Pins didn't match.\n");
362 IEnumPins_Release(enum_pins
);
363 ref
= IBaseFilter_Release(filter
);
364 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
367 static void test_pin_info(void)
369 IBaseFilter
*filter
= create_avi_mux();
377 hr
= IBaseFilter_FindPin(filter
, source_id
, &pin
);
378 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
379 ref
= get_refcount(filter
);
380 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
381 ref
= get_refcount(pin
);
382 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
384 hr
= IPin_QueryPinInfo(pin
, &info
);
385 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
386 ok(info
.pFilter
== filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
387 ok(info
.dir
== PINDIR_OUTPUT
, "Got direction %d.\n", info
.dir
);
388 ok(!lstrcmpW(info
.achName
, source_id
), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
389 ref
= get_refcount(filter
);
390 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
391 ref
= get_refcount(pin
);
392 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
393 IBaseFilter_Release(info
.pFilter
);
395 hr
= IPin_QueryDirection(pin
, &dir
);
396 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
397 ok(dir
== PINDIR_OUTPUT
, "Got direction %d.\n", dir
);
399 hr
= IPin_QueryId(pin
, &id
);
400 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
401 ok(!lstrcmpW(id
, source_id
), "Got id %s.\n", wine_dbgstr_w(id
));
404 hr
= IPin_QueryInternalConnections(pin
, NULL
, NULL
);
405 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
409 hr
= IBaseFilter_FindPin(filter
, sink0_id
, &pin
);
410 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
412 hr
= IPin_QueryPinInfo(pin
, &info
);
413 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
414 ok(info
.pFilter
== filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
415 ok(info
.dir
== PINDIR_INPUT
, "Got direction %d.\n", info
.dir
);
416 ok(!lstrcmpW(info
.achName
, sink0_id
), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
417 IBaseFilter_Release(info
.pFilter
);
419 hr
= IPin_QueryDirection(pin
, &dir
);
420 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
421 ok(dir
== PINDIR_INPUT
, "Got direction %d.\n", dir
);
423 hr
= IPin_QueryId(pin
, &id
);
424 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
425 ok(!lstrcmpW(id
, sink0_id
), "Got id %s.\n", wine_dbgstr_w(id
));
428 hr
= IPin_QueryInternalConnections(pin
, NULL
, NULL
);
429 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
433 ref
= IBaseFilter_Release(filter
);
434 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
437 static void test_media_types(void)
439 IBaseFilter
*filter
= create_avi_mux();
440 AM_MEDIA_TYPE mt
= {}, *pmt
;
441 VIDEOINFOHEADER vih
= {};
442 IEnumMediaTypes
*enummt
;
443 WAVEFORMATEX wfx
= {};
448 IBaseFilter_FindPin(filter
, source_id
, &pin
);
450 hr
= IPin_EnumMediaTypes(pin
, &enummt
);
451 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
453 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, NULL
);
454 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
455 ok(IsEqualGUID(&pmt
->majortype
, &MEDIATYPE_Stream
), "Got major type %s\n",
456 wine_dbgstr_guid(&pmt
->majortype
));
457 ok(IsEqualGUID(&pmt
->subtype
, &MEDIASUBTYPE_Avi
), "Got subtype %s\n",
458 wine_dbgstr_guid(&pmt
->subtype
));
459 ok(pmt
->bFixedSizeSamples
== TRUE
, "Got fixed size %d.\n", pmt
->bFixedSizeSamples
);
460 ok(!pmt
->bTemporalCompression
, "Got temporal compression %d.\n", pmt
->bTemporalCompression
);
461 ok(pmt
->lSampleSize
== 1, "Got sample size %u.\n", pmt
->lSampleSize
);
462 ok(IsEqualGUID(&pmt
->formattype
, &GUID_NULL
), "Got format type %s.\n",
463 wine_dbgstr_guid(&pmt
->formattype
));
464 ok(!pmt
->pUnk
, "Got pUnk %p.\n", pmt
->pUnk
);
465 ok(!pmt
->cbFormat
, "Got format size %u.\n", pmt
->cbFormat
);
466 ok(!pmt
->pbFormat
, "Got format block %u.\n", pmt
->cbFormat
);
468 hr
= IPin_QueryAccept(pin
, pmt
);
469 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
471 pmt
->bFixedSizeSamples
= FALSE
;
472 pmt
->bTemporalCompression
= TRUE
;
473 pmt
->lSampleSize
= 123;
474 hr
= IPin_QueryAccept(pin
, pmt
);
475 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
477 pmt
->majortype
= GUID_NULL
;
478 hr
= IPin_QueryAccept(pin
, pmt
);
479 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
480 pmt
->majortype
= MEDIATYPE_Video
;
481 hr
= IPin_QueryAccept(pin
, pmt
);
482 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
483 pmt
->majortype
= MEDIATYPE_Stream
;
485 pmt
->subtype
= GUID_NULL
;
486 hr
= IPin_QueryAccept(pin
, pmt
);
487 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
488 pmt
->subtype
= MEDIASUBTYPE_RGB8
;
489 hr
= IPin_QueryAccept(pin
, pmt
);
490 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
491 pmt
->subtype
= MEDIASUBTYPE_Avi
;
495 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, NULL
);
496 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
498 IEnumMediaTypes_Release(enummt
);
501 IBaseFilter_FindPin(filter
, sink0_id
, &pin
);
503 hr
= IPin_EnumMediaTypes(pin
, &enummt
);
504 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
506 hr
= IEnumMediaTypes_Next(enummt
, 1, &pmt
, NULL
);
507 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
509 IEnumMediaTypes_Release(enummt
);
511 mt
.majortype
= MEDIATYPE_Audio
;
512 mt
.formattype
= FORMAT_WaveFormatEx
;
513 mt
.cbFormat
= sizeof(wfx
);
514 mt
.pbFormat
= (BYTE
*)&wfx
;
516 hr
= IPin_QueryAccept(pin
, &mt
);
517 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
519 mt
.subtype
= MEDIASUBTYPE_RGB8
;
520 mt
.bFixedSizeSamples
= TRUE
;
521 mt
.bTemporalCompression
= TRUE
;
522 mt
.lSampleSize
= 123;
523 hr
= IPin_QueryAccept(pin
, &mt
);
524 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
526 mt
.majortype
= MEDIATYPE_Video
;
527 hr
= IPin_QueryAccept(pin
, &mt
);
528 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
529 mt
.majortype
= GUID_NULL
;
530 hr
= IPin_QueryAccept(pin
, &mt
);
531 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
532 mt
.majortype
= MEDIATYPE_Interleaved
;
533 hr
= IPin_QueryAccept(pin
, &mt
);
534 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
536 mt
.majortype
= MEDIATYPE_Video
;
537 mt
.formattype
= FORMAT_VideoInfo
;
538 mt
.cbFormat
= sizeof(vih
);
539 mt
.pbFormat
= (BYTE
*)&vih
;
540 hr
= IPin_QueryAccept(pin
, &mt
);
541 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
543 mt
.majortype
= MEDIATYPE_Audio
;
544 hr
= IPin_QueryAccept(pin
, &mt
);
545 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
546 mt
.majortype
= GUID_NULL
;
547 hr
= IPin_QueryAccept(pin
, &mt
);
548 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
549 mt
.majortype
= MEDIATYPE_Interleaved
;
550 hr
= IPin_QueryAccept(pin
, &mt
);
551 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
555 ref
= IBaseFilter_Release(filter
);
556 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
559 static void test_enum_media_types(void)
561 IBaseFilter
*filter
= create_avi_mux();
562 IEnumMediaTypes
*enum1
, *enum2
;
563 AM_MEDIA_TYPE
*mts
[2];
568 IBaseFilter_FindPin(filter
, source_id
, &pin
);
570 hr
= IPin_EnumMediaTypes(pin
, &enum1
);
571 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
573 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
574 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
575 CoTaskMemFree(mts
[0]);
577 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
578 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
580 hr
= IEnumMediaTypes_Reset(enum1
);
581 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
583 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
584 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
585 ok(count
== 1, "Got count %u.\n", count
);
586 CoTaskMemFree(mts
[0]);
588 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
589 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
590 ok(!count
, "Got count %u.\n", count
);
592 hr
= IEnumMediaTypes_Reset(enum1
);
593 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
595 hr
= IEnumMediaTypes_Next(enum1
, 2, mts
, &count
);
596 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
597 ok(count
== 1, "Got count %u.\n", count
);
598 CoTaskMemFree(mts
[0]);
600 hr
= IEnumMediaTypes_Reset(enum1
);
601 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
603 hr
= IEnumMediaTypes_Clone(enum1
, &enum2
);
604 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
606 hr
= IEnumMediaTypes_Skip(enum1
, 2);
607 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
609 hr
= IEnumMediaTypes_Skip(enum1
, 1);
610 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
612 hr
= IEnumMediaTypes_Reset(enum1
);
613 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
615 hr
= IEnumMediaTypes_Skip(enum1
, 1);
616 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
618 hr
= IEnumMediaTypes_Skip(enum1
, 1);
619 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
621 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
622 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
624 hr
= IEnumMediaTypes_Next(enum2
, 1, mts
, NULL
);
625 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
626 CoTaskMemFree(mts
[0]);
628 IEnumMediaTypes_Release(enum1
);
629 IEnumMediaTypes_Release(enum2
);
632 IBaseFilter_FindPin(filter
, sink0_id
, &pin
);
634 hr
= IPin_EnumMediaTypes(pin
, &enum1
);
635 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
637 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
638 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
640 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
641 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
642 ok(!count
, "Got count %u.\n", count
);
644 hr
= IEnumMediaTypes_Reset(enum1
);
645 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
647 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
648 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
650 hr
= IEnumMediaTypes_Clone(enum1
, &enum2
);
651 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
653 hr
= IEnumMediaTypes_Skip(enum1
, 1);
654 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
656 hr
= IEnumMediaTypes_Next(enum2
, 1, mts
, NULL
);
657 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
659 IEnumMediaTypes_Release(enum1
);
660 IEnumMediaTypes_Release(enum2
);
663 ref
= IBaseFilter_Release(filter
);
664 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
667 static void test_seeking(void)
669 IBaseFilter
*filter
= create_avi_mux();
670 LONGLONG time
, current
, stop
;
671 IMediaSeeking
*seeking
;
685 {&TIME_FORMAT_MEDIA_TIME
, S_OK
},
686 {&TIME_FORMAT_BYTE
, S_OK
},
688 {&TIME_FORMAT_NONE
, S_FALSE
},
689 {&TIME_FORMAT_FRAME
, S_FALSE
},
690 {&TIME_FORMAT_SAMPLE
, S_FALSE
},
691 {&TIME_FORMAT_FIELD
, S_FALSE
},
692 {&testguid
, S_FALSE
},
695 IBaseFilter_QueryInterface(filter
, &IID_IMediaSeeking
, (void **)&seeking
);
697 hr
= IMediaSeeking_GetCapabilities(seeking
, &caps
);
698 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
699 todo_wine
ok(caps
== (AM_SEEKING_CanGetCurrentPos
| AM_SEEKING_CanGetDuration
), "Got caps %#x.\n", caps
);
701 caps
= AM_SEEKING_CanGetCurrentPos
;
702 hr
= IMediaSeeking_CheckCapabilities(seeking
, &caps
);
703 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
704 ok(caps
== AM_SEEKING_CanGetCurrentPos
, "Got caps %#x.\n", caps
);
706 caps
= AM_SEEKING_CanDoSegments
| AM_SEEKING_CanGetCurrentPos
;
707 hr
= IMediaSeeking_CheckCapabilities(seeking
, &caps
);
708 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
709 todo_wine
ok(caps
== AM_SEEKING_CanGetCurrentPos
, "Got caps %#x.\n", caps
);
711 caps
= AM_SEEKING_CanDoSegments
;
712 hr
= IMediaSeeking_CheckCapabilities(seeking
, &caps
);
713 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
714 todo_wine
ok(!caps
, "Got caps %#x.\n", caps
);
716 for (i
= 0; i
< ARRAY_SIZE(format_tests
); ++i
)
718 hr
= IMediaSeeking_IsFormatSupported(seeking
, format_tests
[i
].guid
);
719 todo_wine
ok(hr
== format_tests
[i
].hr
, "Got hr %#x for format %s.\n", hr
, wine_dbgstr_guid(format_tests
[i
].guid
));
722 hr
= IMediaSeeking_QueryPreferredFormat(seeking
, &format
);
723 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
724 todo_wine
ok(IsEqualGUID(&format
, &TIME_FORMAT_MEDIA_TIME
), "Got format %s.\n", wine_dbgstr_guid(&format
));
726 hr
= IMediaSeeking_GetTimeFormat(seeking
, &format
);
727 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
728 todo_wine
ok(IsEqualGUID(&format
, &TIME_FORMAT_MEDIA_TIME
), "Got format %s.\n", wine_dbgstr_guid(&format
));
730 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_MEDIA_TIME
);
731 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
732 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_BYTE
);
733 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
735 hr
= IMediaSeeking_SetTimeFormat(seeking
, &TIME_FORMAT_SAMPLE
);
736 todo_wine
ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
738 hr
= IMediaSeeking_SetTimeFormat(seeking
, &TIME_FORMAT_BYTE
);
739 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
741 hr
= IMediaSeeking_QueryPreferredFormat(seeking
, &format
);
742 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
743 todo_wine
ok(IsEqualGUID(&format
, &TIME_FORMAT_MEDIA_TIME
), "Got format %s.\n", wine_dbgstr_guid(&format
));
745 hr
= IMediaSeeking_GetTimeFormat(seeking
, &format
);
746 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
747 todo_wine
ok(IsEqualGUID(&format
, &TIME_FORMAT_BYTE
), "Got format %s.\n", wine_dbgstr_guid(&format
));
749 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_MEDIA_TIME
);
750 todo_wine
ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
751 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_BYTE
);
752 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
754 hr
= IMediaSeeking_SetTimeFormat(seeking
, &TIME_FORMAT_MEDIA_TIME
);
755 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
757 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_MEDIA_TIME
);
758 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
759 hr
= IMediaSeeking_IsUsingTimeFormat(seeking
, &TIME_FORMAT_BYTE
);
760 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
762 hr
= IMediaSeeking_ConvertTimeFormat(seeking
, &time
, NULL
, 0x123456789a, NULL
);
763 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
764 hr
= IMediaSeeking_ConvertTimeFormat(seeking
, &time
, &TIME_FORMAT_MEDIA_TIME
, 0x123456789a, &TIME_FORMAT_BYTE
);
765 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
769 hr
= IMediaSeeking_SetPositions(seeking
, ¤t
, AM_SEEKING_AbsolutePositioning
,
770 &stop
, AM_SEEKING_AbsolutePositioning
);
771 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
772 hr
= IMediaSeeking_SetPositions(seeking
, ¤t
, AM_SEEKING_NoPositioning
,
773 &stop
, AM_SEEKING_NoPositioning
);
774 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
776 hr
= IMediaSeeking_GetPositions(seeking
, NULL
, NULL
);
777 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
778 hr
= IMediaSeeking_GetPositions(seeking
, NULL
, &stop
);
779 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
780 hr
= IMediaSeeking_GetPositions(seeking
, ¤t
, &stop
);
781 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
782 hr
= IMediaSeeking_GetPositions(seeking
, ¤t
, NULL
);
783 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
785 hr
= IMediaSeeking_GetDuration(seeking
, &time
);
786 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
788 ok(!time
, "Got duration %s.\n", wine_dbgstr_longlong(time
));
790 hr
= IMediaSeeking_GetCurrentPosition(seeking
, &time
);
791 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
793 ok(!time
, "Got duration %s.\n", wine_dbgstr_longlong(time
));
795 hr
= IMediaSeeking_GetStopPosition(seeking
, &time
);
796 ok(hr
== E_NOTIMPL
, "Got hr %#x.\n", hr
);
798 IMediaSeeking_Release(seeking
);
799 ref
= IBaseFilter_Release(filter
);
800 ok(!ref
, "Got unexpected refcount %d.\n", ref
);
803 static void test_unconnected_filter_state(void)
805 IBaseFilter
*filter
= create_avi_mux();
810 hr
= IBaseFilter_GetState(filter
, 0, &state
);
811 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
812 ok(state
== State_Stopped
, "Got state %u.\n", state
);
814 hr
= IBaseFilter_Pause(filter
);
815 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
817 hr
= IBaseFilter_GetState(filter
, 0, &state
);
818 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
819 todo_wine
ok(state
== State_Paused
, "Got state %u.\n", state
);
821 hr
= IBaseFilter_Run(filter
, 0);
822 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
824 hr
= IBaseFilter_GetState(filter
, 0, &state
);
825 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
826 todo_wine
ok(state
== State_Running
, "Got state %u.\n", state
);
828 hr
= IBaseFilter_Pause(filter
);
829 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
831 hr
= IBaseFilter_GetState(filter
, 0, &state
);
832 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
833 todo_wine
ok(state
== State_Paused
, "Got state %u.\n", state
);
835 hr
= IBaseFilter_Stop(filter
);
836 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
838 hr
= IBaseFilter_GetState(filter
, 0, &state
);
839 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
840 ok(state
== State_Stopped
, "Got state %u.\n", state
);
842 hr
= IBaseFilter_Run(filter
, 0);
843 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
845 hr
= IBaseFilter_GetState(filter
, 0, &state
);
846 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
847 todo_wine
ok(state
== State_Running
, "Got state %u.\n", state
);
849 hr
= IBaseFilter_Stop(filter
);
850 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
852 hr
= IBaseFilter_GetState(filter
, 0, &state
);
853 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
854 ok(state
== State_Stopped
, "Got state %u.\n", state
);
856 ref
= IBaseFilter_Release(filter
);
857 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
870 test_enum_media_types();
872 test_unconnected_filter_state();