2 * File source filter unit tests
4 * Copyright 2016 Sebastian Lackner
5 * Copyright 2018 Zebediah Figura
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/test.h"
26 static IBaseFilter
*create_file_source(void)
28 IBaseFilter
*filter
= NULL
;
29 HRESULT hr
= CoCreateInstance(&CLSID_AsyncReader
, NULL
, CLSCTX_INPROC_SERVER
,
30 &IID_IBaseFilter
, (void **)&filter
);
31 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
35 static WCHAR
*load_resource(const WCHAR
*name
)
37 static WCHAR pathW
[MAX_PATH
];
43 GetTempPathW(ARRAY_SIZE(pathW
), pathW
);
46 file
= CreateFileW(pathW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
47 ok(file
!= INVALID_HANDLE_VALUE
, "Failed to create file %s, error %u.\n",
48 wine_dbgstr_w(pathW
), GetLastError());
50 res
= FindResourceW(NULL
, name
, (LPCWSTR
)RT_RCDATA
);
51 ok(!!res
, "Failed to load resource, error %u.\n", GetLastError());
52 ptr
= LockResource(LoadResource(GetModuleHandleA(NULL
), res
));
53 WriteFile(file
, ptr
, SizeofResource( GetModuleHandleA(NULL
), res
), &written
, NULL
);
54 ok(written
== SizeofResource(GetModuleHandleA(NULL
), res
), "Failed to write resource.\n");
60 static void load_file(IBaseFilter
*filter
, const WCHAR
*filename
)
62 IFileSourceFilter
*filesource
;
65 hr
= IBaseFilter_QueryInterface(filter
, &IID_IFileSourceFilter
, (void **)&filesource
);
66 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
67 hr
= IFileSourceFilter_Load(filesource
, filename
, NULL
);
68 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
69 IFileSourceFilter_Release(filesource
);
72 static ULONG
get_refcount(void *iface
)
74 IUnknown
*unknown
= iface
;
75 IUnknown_AddRef(unknown
);
76 return IUnknown_Release(unknown
);
79 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
80 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
82 IUnknown
*iface
= iface_ptr
;
83 HRESULT hr
, expected_hr
;
86 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
88 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
89 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
91 IUnknown_Release(unk
);
94 static void test_interfaces(void)
96 const WCHAR
*filename
= load_resource(L
"test.avi");
97 IBaseFilter
*filter
= create_file_source();
100 check_interface(filter
, &IID_IBaseFilter
, TRUE
);
101 check_interface(filter
, &IID_IFileSourceFilter
, TRUE
);
103 check_interface(filter
, &IID_IAMFilterMiscFlags
, FALSE
);
104 check_interface(filter
, &IID_IBasicAudio
, FALSE
);
105 check_interface(filter
, &IID_IBasicVideo
, FALSE
);
106 check_interface(filter
, &IID_IKsPropertySet
, FALSE
);
107 check_interface(filter
, &IID_IMediaPosition
, FALSE
);
108 check_interface(filter
, &IID_IMediaSeeking
, FALSE
);
109 check_interface(filter
, &IID_IPersistPropertyBag
, FALSE
);
110 check_interface(filter
, &IID_IPin
, FALSE
);
111 check_interface(filter
, &IID_IQualityControl
, FALSE
);
112 check_interface(filter
, &IID_IQualProp
, FALSE
);
113 check_interface(filter
, &IID_IReferenceClock
, FALSE
);
114 check_interface(filter
, &IID_IVideoWindow
, FALSE
);
116 load_file(filter
, filename
);
117 IBaseFilter_FindPin(filter
, L
"Output", &pin
);
119 check_interface(pin
, &IID_IAsyncReader
, TRUE
);
120 check_interface(pin
, &IID_IPin
, TRUE
);
121 todo_wine
check_interface(pin
, &IID_IQualityControl
, TRUE
);
122 check_interface(pin
, &IID_IUnknown
, TRUE
);
124 check_interface(pin
, &IID_IKsPropertySet
, FALSE
);
125 check_interface(pin
, &IID_IMediaPosition
, FALSE
);
126 check_interface(pin
, &IID_IMediaSeeking
, FALSE
);
129 IBaseFilter_Release(filter
);
132 static const GUID test_iid
= {0x33333333};
133 static LONG outer_ref
= 1;
135 static HRESULT WINAPI
outer_QueryInterface(IUnknown
*iface
, REFIID iid
, void **out
)
137 if (IsEqualGUID(iid
, &IID_IUnknown
)
138 || IsEqualGUID(iid
, &IID_IBaseFilter
)
139 || IsEqualGUID(iid
, &test_iid
))
141 *out
= (IUnknown
*)0xdeadbeef;
144 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid
));
145 return E_NOINTERFACE
;
148 static ULONG WINAPI
outer_AddRef(IUnknown
*iface
)
150 return InterlockedIncrement(&outer_ref
);
153 static ULONG WINAPI
outer_Release(IUnknown
*iface
)
155 return InterlockedDecrement(&outer_ref
);
158 static const IUnknownVtbl outer_vtbl
=
160 outer_QueryInterface
,
165 static IUnknown test_outer
= {&outer_vtbl
};
167 static void test_aggregation(void)
169 IBaseFilter
*filter
, *filter2
;
170 IUnknown
*unk
, *unk2
;
174 filter
= (IBaseFilter
*)0xdeadbeef;
175 hr
= CoCreateInstance(&CLSID_AsyncReader
, &test_outer
, CLSCTX_INPROC_SERVER
,
176 &IID_IBaseFilter
, (void **)&filter
);
177 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
178 ok(!filter
, "Got interface %p.\n", filter
);
180 hr
= CoCreateInstance(&CLSID_AsyncReader
, &test_outer
, CLSCTX_INPROC_SERVER
,
181 &IID_IUnknown
, (void **)&unk
);
182 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
183 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
184 ok(unk
!= &test_outer
, "Returned IUnknown should not be outer IUnknown.\n");
185 ref
= get_refcount(unk
);
186 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
188 ref
= IUnknown_AddRef(unk
);
189 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
190 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
192 ref
= IUnknown_Release(unk
);
193 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
194 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
196 hr
= IUnknown_QueryInterface(unk
, &IID_IUnknown
, (void **)&unk2
);
197 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
198 ok(unk2
== unk
, "Got unexpected IUnknown %p.\n", unk2
);
199 IUnknown_Release(unk2
);
201 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void **)&filter
);
202 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
204 hr
= IBaseFilter_QueryInterface(filter
, &IID_IUnknown
, (void **)&unk2
);
205 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
206 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
208 hr
= IBaseFilter_QueryInterface(filter
, &IID_IBaseFilter
, (void **)&filter2
);
209 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
210 ok(filter2
== (IBaseFilter
*)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2
);
212 hr
= IUnknown_QueryInterface(unk
, &test_iid
, (void **)&unk2
);
213 ok(hr
== E_NOINTERFACE
, "Got hr %#x.\n", hr
);
214 ok(!unk2
, "Got unexpected IUnknown %p.\n", unk2
);
216 hr
= IBaseFilter_QueryInterface(filter
, &test_iid
, (void **)&unk2
);
217 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
218 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
220 IBaseFilter_Release(filter
);
221 ref
= IUnknown_Release(unk
);
222 ok(!ref
, "Got unexpected refcount %d.\n", ref
);
223 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
226 static void test_file_source_filter(void)
239 "\x52\x49\x46\x46xxxx\x41\x56\x49\x20",
245 "\x00\x00\x01\xBA\x21\x00\x01\x00\x01\x80\x00\x01\x00\x00\x01\xBB",
247 &MEDIASUBTYPE_MPEG1System
,
253 &MEDIASUBTYPE_MPEG1Video
,
259 &MEDIASUBTYPE_MPEG1Audio
,
263 "\x00\x00\x01\xBA\x40",
265 &MEDIASUBTYPE_MPEG2_PROGRAM
,
269 "\x52\x49\x46\x46xxxx\x57\x41\x56\x45",
280 WCHAR path
[MAX_PATH
], temp
[MAX_PATH
], *filename
;
281 AM_MEDIA_TYPE mt
, file_mt
, *pmt
;
282 IFileSourceFilter
*filesource
;
283 IEnumMediaTypes
*enum_mt
;
294 GetTempPathW(MAX_PATH
, temp
);
295 GetTempFileNameW(temp
, L
"win", 0, path
);
297 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
299 trace("Running test for %s.\n", tests
[i
].label
);
301 file
= CreateFileW(path
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
);
302 ok(file
!= INVALID_HANDLE_VALUE
, "Failed to create file, error %u.\n", GetLastError());
303 ret
= WriteFile(file
, tests
[i
].data
, tests
[i
].size
, &written
, NULL
);
304 ok(ret
, "Failed to write file, error %u.\n", GetLastError());
307 filter
= create_file_source();
308 IBaseFilter_QueryInterface(filter
, &IID_IFileSourceFilter
, (void **)&filesource
);
310 olepath
= (void *)0xdeadbeef;
311 hr
= IFileSourceFilter_GetCurFile(filesource
, &olepath
, NULL
);
312 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
313 ok(!olepath
, "Got path %s.\n", wine_dbgstr_w(olepath
));
315 hr
= IFileSourceFilter_Load(filesource
, NULL
, NULL
);
316 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
318 hr
= IFileSourceFilter_Load(filesource
, path
, NULL
);
319 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
321 hr
= IFileSourceFilter_GetCurFile(filesource
, NULL
, &mt
);
322 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
325 hr
= IFileSourceFilter_GetCurFile(filesource
, &olepath
, NULL
);
326 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
327 CoTaskMemFree(olepath
);
330 memset(&file_mt
, 0x11, sizeof(file_mt
));
331 hr
= IFileSourceFilter_GetCurFile(filesource
, &olepath
, &file_mt
);
332 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
333 ok(!wcscmp(olepath
, path
), "Expected path %s, got %s.\n",
334 wine_dbgstr_w(path
), wine_dbgstr_w(olepath
));
335 ok(IsEqualGUID(&file_mt
.majortype
, &MEDIATYPE_Stream
), "Got major type %s.\n",
336 wine_dbgstr_guid(&file_mt
.majortype
));
337 /* winegstreamer hijacks format type detection. */
338 if (!IsEqualGUID(tests
[i
].subtype
, &MEDIASUBTYPE_NULL
))
339 ok(IsEqualGUID(&file_mt
.subtype
, tests
[i
].subtype
), "Expected subtype %s, got %s.\n",
340 wine_dbgstr_guid(tests
[i
].subtype
), wine_dbgstr_guid(&file_mt
.subtype
));
341 ok(file_mt
.bFixedSizeSamples
== TRUE
, "Got fixed size %d.\n", file_mt
.bFixedSizeSamples
);
342 ok(file_mt
.bTemporalCompression
== FALSE
, "Got temporal compression %d.\n",
343 file_mt
.bTemporalCompression
);
344 ok(file_mt
.lSampleSize
== 1, "Got sample size %u.\n", file_mt
.lSampleSize
);
345 ok(IsEqualGUID(&file_mt
.formattype
, &GUID_NULL
), "Got format type %s.\n",
346 wine_dbgstr_guid(&file_mt
.formattype
));
347 ok(!file_mt
.pUnk
, "Got pUnk %p.\n", file_mt
.pUnk
);
348 ok(!file_mt
.cbFormat
, "Got format size %#x.\n", file_mt
.cbFormat
);
349 ok(!file_mt
.pbFormat
, "Got format %p.\n", file_mt
.pbFormat
);
350 CoTaskMemFree(olepath
);
352 hr
= IBaseFilter_FindPin(filter
, L
"Output", &pin
);
353 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
355 hr
= IPin_EnumMediaTypes(pin
, &enum_mt
);
356 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
358 hr
= IEnumMediaTypes_Next(enum_mt
, 1, &pmt
, NULL
);
359 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
360 ok(!memcmp(pmt
, &file_mt
, sizeof(*pmt
)), "Media types did not match.\n");
363 hr
= IEnumMediaTypes_Next(enum_mt
, 1, &pmt
, NULL
);
364 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
366 mt
.subtype
= GUID_NULL
;
367 ok(!memcmp(pmt
, &mt
, sizeof(*pmt
)), "Media types did not match.\n");
370 hr
= IEnumMediaTypes_Next(enum_mt
, 1, &pmt
, NULL
);
371 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
373 IEnumMediaTypes_Release(enum_mt
);
376 hr
= IPin_QueryAccept(pin
, &mt
);
377 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
379 mt
.bFixedSizeSamples
= FALSE
;
380 mt
.bTemporalCompression
= TRUE
;
381 mt
.lSampleSize
= 123;
382 mt
.formattype
= FORMAT_VideoInfo
;
383 hr
= IPin_QueryAccept(pin
, &mt
);
384 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
386 mt
.majortype
= MEDIATYPE_Video
;
387 hr
= IPin_QueryAccept(pin
, &mt
);
388 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
389 mt
.majortype
= MEDIATYPE_Stream
;
391 if (!IsEqualGUID(tests
[i
].subtype
, &GUID_NULL
))
393 mt
.subtype
= GUID_NULL
;
394 hr
= IPin_QueryAccept(pin
, &mt
);
395 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
399 IFileSourceFilter_Release(filesource
);
400 ref
= IBaseFilter_Release(filter
);
401 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
403 ret
= DeleteFileW(path
);
404 ok(ret
, "Failed to delete file, error %u\n", GetLastError());
407 /* test prescribed format */
408 filter
= create_file_source();
409 hr
= IBaseFilter_QueryInterface(filter
, &IID_IFileSourceFilter
, (void **)&filesource
);
410 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
412 mt
.majortype
= MEDIATYPE_Video
;
413 mt
.subtype
= MEDIASUBTYPE_RGB8
;
414 mt
.bFixedSizeSamples
= FALSE
;
415 mt
.bTemporalCompression
= TRUE
;
416 mt
.lSampleSize
= 123;
417 mt
.formattype
= FORMAT_None
;
421 filename
= load_resource(L
"test.avi");
422 hr
= IFileSourceFilter_Load(filesource
, filename
, &mt
);
423 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
425 hr
= IFileSourceFilter_GetCurFile(filesource
, &olepath
, &file_mt
);
426 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
427 ok(!memcmp(&file_mt
, &mt
, sizeof(mt
)), "Media types did not match.\n");
428 CoTaskMemFree(olepath
);
430 hr
= IBaseFilter_FindPin(filter
, L
"Output", &pin
);
431 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
433 hr
= IPin_EnumMediaTypes(pin
, &enum_mt
);
434 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
436 hr
= IEnumMediaTypes_Next(enum_mt
, 1, &pmt
, NULL
);
437 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
438 ok(!memcmp(pmt
, &file_mt
, sizeof(*pmt
)), "Media types did not match.\n");
441 hr
= IEnumMediaTypes_Next(enum_mt
, 1, &pmt
, NULL
);
442 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
443 ok(IsEqualGUID(&pmt
->majortype
, &MEDIATYPE_Stream
), "Got major type %s.\n",
444 wine_dbgstr_guid(&pmt
->majortype
));
445 ok(IsEqualGUID(&pmt
->subtype
, &GUID_NULL
), "Got subtype %s.\n",
446 wine_dbgstr_guid(&pmt
->subtype
));
447 ok(pmt
->bFixedSizeSamples
== TRUE
, "Got fixed size %d.\n", pmt
->bFixedSizeSamples
);
448 ok(!pmt
->bTemporalCompression
, "Got temporal compression %d.\n", pmt
->bTemporalCompression
);
449 ok(pmt
->lSampleSize
== 1, "Got sample size %u.\n", pmt
->lSampleSize
);
450 ok(IsEqualGUID(&pmt
->formattype
, &GUID_NULL
), "Got format type %s.\n",
451 wine_dbgstr_guid(&pmt
->formattype
));
452 ok(!pmt
->pUnk
, "Got pUnk %p.\n", pmt
->pUnk
);
453 ok(!pmt
->cbFormat
, "Got format size %#x.\n", pmt
->cbFormat
);
454 ok(!pmt
->pbFormat
, "Got format %p.\n", pmt
->pbFormat
);
456 hr
= IPin_QueryAccept(pin
, pmt
);
457 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
460 hr
= IEnumMediaTypes_Next(enum_mt
, 1, &pmt
, NULL
);
461 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
463 IEnumMediaTypes_Release(enum_mt
);
465 hr
= IPin_QueryAccept(pin
, &mt
);
466 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
468 mt
.bFixedSizeSamples
= TRUE
;
469 mt
.bTemporalCompression
= FALSE
;
470 mt
.lSampleSize
= 456;
471 mt
.formattype
= FORMAT_VideoInfo
;
472 hr
= IPin_QueryAccept(pin
, &mt
);
473 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
475 mt
.majortype
= MEDIATYPE_Stream
;
476 hr
= IPin_QueryAccept(pin
, &mt
);
477 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
478 mt
.majortype
= MEDIATYPE_Video
;
480 mt
.subtype
= MEDIASUBTYPE_NULL
;
481 hr
= IPin_QueryAccept(pin
, &mt
);
482 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
485 IFileSourceFilter_Release(filesource
);
486 ref
= IBaseFilter_Release(filter
);
487 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
488 ret
= DeleteFileW(filename
);
489 ok(ret
, "Failed to delete file, error %u.\n", GetLastError());
492 static void test_enum_pins(void)
494 const WCHAR
*filename
= load_resource(L
"test.avi");
495 IBaseFilter
*filter
= create_file_source();
496 IEnumPins
*enum1
, *enum2
;
503 ref
= get_refcount(filter
);
504 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
506 hr
= IBaseFilter_EnumPins(filter
, NULL
);
507 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
509 hr
= IBaseFilter_EnumPins(filter
, &enum1
);
510 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
512 ref
= get_refcount(filter
);
513 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
514 ref
= get_refcount(enum1
);
515 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
517 hr
= IEnumPins_Next(enum1
, 1, NULL
, NULL
);
518 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
520 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
521 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
523 hr
= IEnumPins_Skip(enum1
, 1);
524 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
526 load_file(filter
, filename
);
528 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
529 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
531 hr
= IEnumPins_Reset(enum1
);
532 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
534 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
535 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
536 ref
= get_refcount(filter
);
537 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
538 ref
= get_refcount(pins
[0]);
539 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
540 ref
= get_refcount(enum1
);
541 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
542 IPin_Release(pins
[0]);
543 ref
= get_refcount(filter
);
544 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
546 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
547 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
549 hr
= IEnumPins_Reset(enum1
);
550 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
552 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
553 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
554 ok(count
== 1, "Got count %u.\n", count
);
555 IPin_Release(pins
[0]);
557 hr
= IEnumPins_Next(enum1
, 1, pins
, &count
);
558 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
559 ok(!count
, "Got count %u.\n", count
);
561 hr
= IEnumPins_Reset(enum1
);
562 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
564 hr
= IEnumPins_Next(enum1
, 2, pins
, NULL
);
565 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
567 hr
= IEnumPins_Next(enum1
, 2, pins
, &count
);
568 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
569 ok(count
== 1, "Got count %u.\n", count
);
570 IPin_Release(pins
[0]);
572 hr
= IEnumPins_Reset(enum1
);
573 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
575 hr
= IEnumPins_Clone(enum1
, &enum2
);
576 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
578 hr
= IEnumPins_Skip(enum1
, 2);
579 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
581 hr
= IEnumPins_Skip(enum1
, 1);
582 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
584 hr
= IEnumPins_Skip(enum1
, 1);
585 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
587 hr
= IEnumPins_Next(enum1
, 1, pins
, NULL
);
588 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
590 hr
= IEnumPins_Next(enum2
, 1, pins
, NULL
);
591 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
592 IPin_Release(pins
[0]);
594 IEnumPins_Release(enum2
);
595 IEnumPins_Release(enum1
);
596 ref
= IBaseFilter_Release(filter
);
597 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
598 ret
= DeleteFileW(filename
);
599 ok(ret
, "Failed to delete file, error %u.\n", GetLastError());
602 static void test_find_pin(void)
604 const WCHAR
*filename
= load_resource(L
"test.avi");
605 IBaseFilter
*filter
= create_file_source();
612 hr
= IBaseFilter_FindPin(filter
, L
"Output", &pin
);
613 ok(hr
== VFW_E_NOT_FOUND
, "Got hr %#x.\n", hr
);
615 load_file(filter
, filename
);
617 hr
= IBaseFilter_FindPin(filter
, L
"Output", &pin
);
618 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
619 ref
= get_refcount(filter
);
620 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
621 ref
= get_refcount(pin
);
622 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
624 hr
= IBaseFilter_EnumPins(filter
, &enumpins
);
625 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
627 hr
= IEnumPins_Next(enumpins
, 1, &pin2
, NULL
);
628 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
629 ok(pin
== pin2
, "Expected pin %p, got %p.\n", pin
, pin2
);
633 IEnumPins_Release(enumpins
);
634 ref
= IBaseFilter_Release(filter
);
635 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
636 ret
= DeleteFileW(filename
);
637 ok(ret
, "Failed to delete file, error %u.\n", GetLastError());
640 static void test_pin_info(void)
642 const WCHAR
*filename
= load_resource(L
"test.avi");
643 IBaseFilter
*filter
= create_file_source();
652 load_file(filter
, filename
);
654 hr
= IBaseFilter_FindPin(filter
, L
"Output", &pin
);
655 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
656 ref
= get_refcount(filter
);
657 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
658 ref
= get_refcount(pin
);
659 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
661 hr
= IPin_QueryPinInfo(pin
, &info
);
662 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
663 ok(info
.pFilter
== filter
, "Expected filter %p, got %p.\n", filter
, info
.pFilter
);
664 ok(info
.dir
== PINDIR_OUTPUT
, "Got direction %d.\n", info
.dir
);
665 ok(!wcscmp(info
.achName
, L
"Output"), "Got name %s.\n", wine_dbgstr_w(info
.achName
));
666 ref
= get_refcount(filter
);
667 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
668 ref
= get_refcount(pin
);
669 ok(ref
== 3, "Got unexpected refcount %d.\n", ref
);
670 IBaseFilter_Release(info
.pFilter
);
672 hr
= IPin_QueryDirection(pin
, &dir
);
673 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
674 ok(dir
== PINDIR_OUTPUT
, "Got direction %d.\n", dir
);
676 hr
= IPin_QueryId(pin
, &id
);
677 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
678 ok(!wcscmp(id
, L
"Output"), "Got id %s.\n", wine_dbgstr_w(id
));
682 ref
= IBaseFilter_Release(filter
);
683 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
684 ret
= DeleteFileW(filename
);
685 ok(ret
, "Failed to delete file, error %u.\n", GetLastError());
688 static void test_unconnected_filter_state(void)
690 IBaseFilter
*filter
= create_file_source();
695 hr
= IBaseFilter_GetState(filter
, 0, &state
);
696 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
697 ok(state
== State_Stopped
, "Got state %u.\n", state
);
699 hr
= IBaseFilter_Pause(filter
);
700 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
702 hr
= IBaseFilter_GetState(filter
, 0, &state
);
703 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
704 ok(state
== State_Paused
, "Got state %u.\n", state
);
706 hr
= IBaseFilter_Run(filter
, 0);
707 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
709 hr
= IBaseFilter_GetState(filter
, 0, &state
);
710 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
711 ok(state
== State_Running
, "Got state %u.\n", state
);
713 hr
= IBaseFilter_Pause(filter
);
714 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
716 hr
= IBaseFilter_GetState(filter
, 0, &state
);
717 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
718 ok(state
== State_Paused
, "Got state %u.\n", state
);
720 hr
= IBaseFilter_Stop(filter
);
721 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
723 hr
= IBaseFilter_GetState(filter
, 0, &state
);
724 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
725 ok(state
== State_Stopped
, "Got state %u.\n", state
);
727 hr
= IBaseFilter_Run(filter
, 0);
728 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
730 hr
= IBaseFilter_GetState(filter
, 0, &state
);
731 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
732 ok(state
== State_Running
, "Got state %u.\n", state
);
734 hr
= IBaseFilter_Stop(filter
);
735 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
737 hr
= IBaseFilter_GetState(filter
, 0, &state
);
738 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
739 ok(state
== State_Stopped
, "Got state %u.\n", state
);
741 ref
= IBaseFilter_Release(filter
);
742 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
745 static void test_sync_read_aligned(IAsyncReader
*reader
, IMemAllocator
*allocator
)
747 REFERENCE_TIME start_time
, end_time
;
748 IMediaSample
*sample
;
754 IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
755 IMediaSample_GetPointer(sample
, &data
);
758 end_time
= 512 * (LONGLONG
)10000000;
759 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
760 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
762 hr
= IAsyncReader_SyncReadAligned(reader
, sample
);
763 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
765 len
= IMediaSample_GetActualDataLength(sample
);
766 ok(len
== 512, "Got length %d.\n", len
);
768 for (i
= 0; i
< 512; i
++)
769 ok(data
[i
] == i
% 111, "Got wrong byte %02x at %u.\n", data
[i
], i
);
771 start_time
= 512 * (LONGLONG
)10000000;
772 end_time
= 1024 * (LONGLONG
)10000000;
773 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
774 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
776 hr
= IAsyncReader_SyncReadAligned(reader
, sample
);
777 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
779 len
= IMediaSample_GetActualDataLength(sample
);
780 ok(len
== 88, "Got length %d.\n", len
);
782 for (i
= 0; i
< 88; i
++)
783 ok(data
[i
] == (512 + i
) % 111, "Got wrong byte %02x at %u.\n", data
[i
], i
);
785 start_time
= 1024 * (LONGLONG
)10000000;
786 end_time
= 1536 * (LONGLONG
)10000000;
787 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
788 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
790 hr
= IAsyncReader_SyncReadAligned(reader
, sample
);
791 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
793 len
= IMediaSample_GetActualDataLength(sample
);
794 ok(len
== 0, "Got length %d.\n", len
);
796 IMediaSample_Release(sample
);
799 struct request_thread_params
801 IAsyncReader
*reader
;
802 IMediaSample
*sample
;
805 static DWORD CALLBACK
request_thread(void *arg
)
807 struct request_thread_params
*params
= arg
;
808 HRESULT hr
= IAsyncReader_Request(params
->reader
, params
->sample
, 123);
809 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
813 static void test_request(IAsyncReader
*reader
, IMemAllocator
*allocator
)
815 IMediaSample
*sample
, *sample2
, *ret_sample
;
816 struct request_thread_params params
;
817 REFERENCE_TIME start_time
, end_time
;
825 IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
826 IMediaSample_GetPointer(sample
, &data
);
827 IMemAllocator_GetBuffer(allocator
, &sample2
, NULL
, NULL
, 0);
828 IMediaSample_GetPointer(sample2
, &data2
);
830 hr
= IAsyncReader_WaitForNext(reader
, 0, &ret_sample
, &cookie
);
831 ok(hr
== VFW_E_TIMEOUT
, "Got hr %#x.\n", hr
);
834 end_time
= 512 * (LONGLONG
)10000000;
835 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
836 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
838 hr
= IAsyncReader_Request(reader
, sample
, 123);
839 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
841 hr
= IAsyncReader_WaitForNext(reader
, 1000, &ret_sample
, &cookie
);
842 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
843 ok(ret_sample
== sample
, "Expected sample %p, got %p.\n", sample
, ret_sample
);
844 ok(cookie
== 123, "Got cookie %lu.\n", cookie
);
846 len
= IMediaSample_GetActualDataLength(sample
);
847 ok(len
== 512, "Got length %d.\n", hr
);
849 for (i
= 0; i
< 512; i
++)
850 ok(data
[i
] == i
% 111, "Got wrong byte %02x at %u.\n", data
[i
], i
);
852 start_time
= 1024 * (LONGLONG
)10000000;
853 end_time
= 1536 * (LONGLONG
)10000000;
854 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
855 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
857 hr
= IAsyncReader_Request(reader
, sample
, 123);
858 ok(hr
== HRESULT_FROM_WIN32(ERROR_HANDLE_EOF
), "Got hr %#x.\n", hr
);
861 end_time
= 512 * (LONGLONG
)10000000;
862 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
863 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
865 hr
= IAsyncReader_Request(reader
, sample
, 123);
866 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
868 start_time
= 512 * (LONGLONG
)10000000;
869 end_time
= 1024 * (LONGLONG
)10000000;
870 hr
= IMediaSample_SetTime(sample2
, &start_time
, &end_time
);
871 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
873 hr
= IAsyncReader_Request(reader
, sample2
, 456);
874 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
876 hr
= IAsyncReader_WaitForNext(reader
, 1000, &ret_sample
, &cookie
);
877 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
880 ok(ret_sample
== sample
, "Expected sample %p, got %p.\n", sample
, ret_sample
);
882 hr
= IAsyncReader_WaitForNext(reader
, 1000, &ret_sample
, &cookie
);
883 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
884 ok(ret_sample
== sample2
, "Expected sample %p, got %p.\n", sample2
, ret_sample
);
885 ok(cookie
== 456, "Got cookie %lu.\n", cookie
);
889 ok(cookie
== 456, "Got cookie %lu.\n", cookie
);
890 ok(ret_sample
== sample2
, "Expected sample %p, got %p.\n", sample2
, ret_sample
);
892 hr
= IAsyncReader_WaitForNext(reader
, 1000, &ret_sample
, &cookie
);
893 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
894 ok(ret_sample
== sample
, "Expected sample %p, got %p.\n", sample
, ret_sample
);
895 ok(cookie
== 123, "Got cookie %lu.\n", cookie
);
898 for (i
= 0; i
< 512; i
++)
899 ok(data
[i
] == i
% 111, "Got wrong byte %02x at %u.\n", data
[i
], i
);
901 for (i
= 0; i
< 88; i
++)
902 ok(data2
[i
] == (512 + i
) % 111, "Got wrong byte %02x at %u.\n", data2
[i
], i
);
904 params
.reader
= reader
;
905 params
.sample
= sample
;
906 thread
= CreateThread(NULL
, 0, request_thread
, ¶ms
, 0, NULL
);
907 ok(!WaitForSingleObject(thread
, 1000), "Wait timed out.\n");
910 hr
= IAsyncReader_WaitForNext(reader
, 1000, &ret_sample
, &cookie
);
911 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
912 ok(ret_sample
== sample
, "Samples didn't match.\n");
913 ok(cookie
== 123, "Got cookie %lu.\n", cookie
);
915 IMediaSample_Release(sample
);
916 IMediaSample_Release(sample2
);
919 static DWORD CALLBACK
wait_thread(void *arg
)
921 IAsyncReader
*reader
= arg
;
922 IMediaSample
*sample
;
924 HRESULT hr
= IAsyncReader_WaitForNext(reader
, 2000, &sample
, &cookie
);
925 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
929 static void test_flush(IAsyncReader
*reader
, IMemAllocator
*allocator
)
931 REFERENCE_TIME start_time
, end_time
;
932 IMediaSample
*sample
, *ret_sample
;
933 BYTE buffer
[20], *data
;
939 IMemAllocator_GetBuffer(allocator
, &sample
, NULL
, NULL
, 0);
940 IMediaSample_GetPointer(sample
, &data
);
943 end_time
= 512 * (LONGLONG
)10000000;
944 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
945 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
947 hr
= IAsyncReader_BeginFlush(reader
);
948 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
950 hr
= IAsyncReader_SyncRead(reader
, 0, 20, buffer
);
951 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
952 for (i
= 0; i
< 20; i
++)
953 ok(buffer
[i
] == i
% 111, "Got wrong byte %02x at %u.\n", buffer
[i
], i
);
956 end_time
= 512 * (LONGLONG
)10000000;
957 hr
= IMediaSample_SetTime(sample
, &start_time
, &end_time
);
958 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
960 hr
= IAsyncReader_SyncReadAligned(reader
, sample
);
961 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
962 for (i
= 0; i
< 512; i
++)
963 ok(data
[i
] == i
% 111, "Got wrong byte %02x at %u.\n", data
[i
], i
);
965 hr
= IAsyncReader_Request(reader
, sample
, 456);
966 ok(hr
== VFW_E_WRONG_STATE
, "Got hr %#x.\n", hr
);
968 hr
= IAsyncReader_EndFlush(reader
);
969 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
971 hr
= IAsyncReader_WaitForNext(reader
, 0, &ret_sample
, &cookie
);
972 ok(hr
== VFW_E_TIMEOUT
, "Got hr %#x.\n", hr
);
975 end_time
= 512 * (LONGLONG
)10000000;
976 hr
= IAsyncReader_Request(reader
, sample
, 123);
977 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
979 hr
= IAsyncReader_WaitForNext(reader
, 1000, &ret_sample
, &cookie
);
980 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
981 ok(ret_sample
== sample
, "Expected sample %p, got %p.\n", sample
, ret_sample
);
982 ok(cookie
== 123, "Got cookie %lu.\n", cookie
);
984 for (i
= 0; i
< 512; i
++)
985 ok(data
[i
] == i
% 111, "Got wrong byte %02x at %u.\n", data
[i
], i
);
987 thread
= CreateThread(NULL
, 0, wait_thread
, reader
, 0, NULL
);
988 ok(WaitForSingleObject(thread
, 100) == WAIT_TIMEOUT
, "Expected timeout.\n");
990 hr
= IAsyncReader_BeginFlush(reader
);
991 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
992 ok(!WaitForSingleObject(thread
, 1000), "Wait timed out.\n");
995 hr
= IAsyncReader_EndFlush(reader
);
996 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
998 IMediaSample_Release(sample
);
1001 static void test_async_reader(void)
1003 ALLOCATOR_PROPERTIES req_props
= {100, 1024, 512, 0}, ret_props
;
1004 IBaseFilter
*filter
= create_file_source();
1005 IFileSourceFilter
*filesource
;
1006 LONGLONG length
, available
;
1007 IMemAllocator
*allocator
;
1008 WCHAR filename
[MAX_PATH
];
1009 IAsyncReader
*reader
;
1019 GetTempPathW(ARRAY_SIZE(filename
), filename
);
1020 wcscat(filename
, L
"test.avi");
1021 file
= CreateFileW(filename
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
1022 ok(file
!= INVALID_HANDLE_VALUE
, "Failed to create file, error %u.\n", GetLastError());
1023 for (i
= 0; i
< 600; i
++)
1026 WriteFile(file
, &b
, 1, &written
, NULL
);
1030 IBaseFilter_QueryInterface(filter
, &IID_IFileSourceFilter
, (void **)&filesource
);
1031 IFileSourceFilter_Load(filesource
, filename
, NULL
);
1032 IBaseFilter_FindPin(filter
, L
"Output", &pin
);
1034 hr
= IPin_QueryInterface(pin
, &IID_IAsyncReader
, (void **)&reader
);
1035 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1037 hr
= IAsyncReader_Length(reader
, &length
, &available
);
1038 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1039 ok(length
== 600, "Got length %s.\n", wine_dbgstr_longlong(length
));
1040 ok(available
== 600, "Got available length %s.\n", wine_dbgstr_longlong(available
));
1042 memset(buffer
, 0xcc, sizeof(buffer
));
1043 hr
= IAsyncReader_SyncRead(reader
, 0, 10, buffer
);
1044 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1045 for (i
= 0; i
< 10; i
++)
1046 ok(buffer
[i
] == i
% 111, "Got wrong byte %02x at %u.\n", buffer
[i
], i
);
1048 hr
= IAsyncReader_SyncRead(reader
, 0, 10, buffer
);
1049 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1050 for (i
= 0; i
< 10; i
++)
1051 ok(buffer
[i
] == i
% 111, "Got wrong byte %02x at %u.\n", buffer
[i
], i
);
1053 hr
= IAsyncReader_SyncRead(reader
, 10, 10, buffer
);
1054 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1055 for (i
= 0; i
< 10; i
++)
1056 ok(buffer
[i
] == (10 + i
) % 111, "Got wrong byte %02x at %u.\n", buffer
[i
], i
);
1058 hr
= IAsyncReader_SyncRead(reader
, 590, 20, buffer
);
1059 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1060 for (i
= 0; i
< 10; i
++)
1061 ok(buffer
[i
] == (590 + i
) % 111, "Got wrong byte %02x at %u.\n", buffer
[i
], i
);
1063 ok(buffer
[i
] == 0xcc, "Got wrong byte %02x at %u.\n", buffer
[i
], i
);
1065 memset(buffer
, 0xcc, sizeof(buffer
));
1066 hr
= IAsyncReader_SyncRead(reader
, 600, 10, buffer
);
1067 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1068 ok(buffer
[0] == 0xcc, "Got wrong byte %02x.\n", buffer
[0]);
1070 ret_props
= req_props
;
1071 hr
= IAsyncReader_RequestAllocator(reader
, NULL
, &ret_props
, &allocator
);
1072 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1073 ok(ret_props
.cBuffers
== 100, "Got %d buffers.\n", ret_props
.cBuffers
);
1074 ok(ret_props
.cbBuffer
== 1024, "Got size %d.\n", ret_props
.cbBuffer
);
1075 ok(ret_props
.cbAlign
== 512, "Got alignment %d.\n", ret_props
.cbAlign
);
1076 ok(ret_props
.cbPrefix
== 0, "Got prefix %d.\n", ret_props
.cbPrefix
);
1078 IMemAllocator_Commit(allocator
);
1080 test_sync_read_aligned(reader
, allocator
);
1081 test_request(reader
, allocator
);
1082 test_flush(reader
, allocator
);
1084 IMemAllocator_Release(allocator
);
1085 IAsyncReader_Release(reader
);
1087 IFileSourceFilter_Release(filesource
);
1088 ref
= IBaseFilter_Release(filter
);
1089 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1090 ret
= DeleteFileW(filename
);
1091 ok(ret
, "Failed to delete file, error %u.\n", GetLastError());
1094 static void test_enum_media_types(void)
1096 const WCHAR
*filename
= load_resource(L
"test.avi");
1097 IBaseFilter
*filter
= create_file_source();
1098 IEnumMediaTypes
*enum1
, *enum2
;
1099 AM_MEDIA_TYPE
*mts
[3];
1105 load_file(filter
, filename
);
1107 IBaseFilter_FindPin(filter
, L
"Output", &pin
);
1109 hr
= IPin_EnumMediaTypes(pin
, &enum1
);
1110 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1112 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
1113 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1114 CoTaskMemFree(mts
[0]);
1116 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
1117 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1118 CoTaskMemFree(mts
[0]);
1120 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
1121 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1123 hr
= IEnumMediaTypes_Reset(enum1
);
1124 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1126 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
1127 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1128 ok(count
== 1, "Got count %u.\n", count
);
1129 CoTaskMemFree(mts
[0]);
1131 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
1132 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1133 ok(count
== 1, "Got count %u.\n", count
);
1134 CoTaskMemFree(mts
[0]);
1136 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, &count
);
1137 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1138 ok(!count
, "Got count %u.\n", count
);
1140 hr
= IEnumMediaTypes_Reset(enum1
);
1141 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1143 hr
= IEnumMediaTypes_Next(enum1
, 2, mts
, &count
);
1144 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1145 ok(count
== 2, "Got count %u.\n", count
);
1146 CoTaskMemFree(mts
[0]);
1147 CoTaskMemFree(mts
[1]);
1149 hr
= IEnumMediaTypes_Next(enum1
, 2, mts
, &count
);
1150 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1151 ok(!count
, "Got count %u.\n", count
);
1153 hr
= IEnumMediaTypes_Reset(enum1
);
1154 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1156 hr
= IEnumMediaTypes_Next(enum1
, 3, mts
, &count
);
1157 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1158 ok(count
== 2, "Got count %u.\n", count
);
1159 CoTaskMemFree(mts
[0]);
1160 CoTaskMemFree(mts
[1]);
1162 hr
= IEnumMediaTypes_Reset(enum1
);
1163 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1165 hr
= IEnumMediaTypes_Clone(enum1
, &enum2
);
1166 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1168 hr
= IEnumMediaTypes_Skip(enum1
, 3);
1169 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1171 hr
= IEnumMediaTypes_Skip(enum1
, 1);
1172 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1174 hr
= IEnumMediaTypes_Reset(enum1
);
1175 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1177 hr
= IEnumMediaTypes_Skip(enum1
, 2);
1178 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1180 hr
= IEnumMediaTypes_Skip(enum1
, 1);
1181 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1183 hr
= IEnumMediaTypes_Next(enum1
, 1, mts
, NULL
);
1184 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
1186 hr
= IEnumMediaTypes_Next(enum2
, 1, mts
, NULL
);
1187 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1188 CoTaskMemFree(mts
[0]);
1190 IEnumMediaTypes_Release(enum1
);
1191 IEnumMediaTypes_Release(enum2
);
1194 ref
= IBaseFilter_Release(filter
);
1195 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1196 ret
= DeleteFileW(filename
);
1197 ok(ret
, "Failed to delete file, error %u.\n", GetLastError());
1200 START_TEST(filesource
)
1209 test_unconnected_filter_state();
1210 test_file_source_filter();
1211 test_async_reader();
1212 test_enum_media_types();