quartz/filesource: Use a completion port to handle asynchronous requests.
[wine.git] / dlls / quartz / tests / filesource.c
blobdf0db1b3b53474245148d850e1c0f2f6ca9afb2c
1 /*
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
22 #define COBJMACROS
23 #include "dshow.h"
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);
32 return filter;
35 static WCHAR *load_resource(const WCHAR *name)
37 static WCHAR pathW[MAX_PATH];
38 DWORD written;
39 HANDLE file;
40 HRSRC res;
41 void *ptr;
43 GetTempPathW(ARRAY_SIZE(pathW), pathW);
44 wcscat(pathW, name);
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");
55 CloseHandle(file);
57 return pathW;
60 static void load_file(IBaseFilter *filter, const WCHAR *filename)
62 IFileSourceFilter *filesource;
63 HRESULT hr;
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;
84 IUnknown *unk;
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);
90 if (SUCCEEDED(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();
98 IPin *pin;
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);
128 IPin_Release(pin);
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;
142 return S_OK;
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,
161 outer_AddRef,
162 outer_Release,
165 static IUnknown test_outer = {&outer_vtbl};
167 static void test_aggregation(void)
169 IBaseFilter *filter, *filter2;
170 IUnknown *unk, *unk2;
171 HRESULT hr;
172 ULONG ref;
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)
228 static const struct
230 const char *label;
231 const char *data;
232 DWORD size;
233 const GUID *subtype;
235 tests[] =
238 "AVI",
239 "\x52\x49\x46\x46xxxx\x41\x56\x49\x20",
241 &MEDIASUBTYPE_Avi,
244 "MPEG1 System",
245 "\x00\x00\x01\xBA\x21\x00\x01\x00\x01\x80\x00\x01\x00\x00\x01\xBB",
247 &MEDIASUBTYPE_MPEG1System,
250 "MPEG1 Video",
251 "\x00\x00\x01\xB3",
253 &MEDIASUBTYPE_MPEG1Video,
256 "MPEG1 Audio",
257 "\xFF\xE0",
259 &MEDIASUBTYPE_MPEG1Audio,
262 "MPEG2 Program",
263 "\x00\x00\x01\xBA\x40",
265 &MEDIASUBTYPE_MPEG2_PROGRAM,
268 "WAVE",
269 "\x52\x49\x46\x46xxxx\x57\x41\x56\x45",
271 &MEDIASUBTYPE_WAVE,
274 "unknown format",
275 "Hello World",
277 &MEDIASUBTYPE_NULL,
280 WCHAR path[MAX_PATH], temp[MAX_PATH], *filename;
281 AM_MEDIA_TYPE mt, file_mt, *pmt;
282 IFileSourceFilter *filesource;
283 IEnumMediaTypes *enum_mt;
284 IBaseFilter *filter;
285 OLECHAR *olepath;
286 DWORD written;
287 HANDLE file;
288 HRESULT hr;
289 ULONG ref;
290 IPin *pin;
291 BOOL ret;
292 int i;
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());
305 CloseHandle(file);
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);
324 olepath = NULL;
325 hr = IFileSourceFilter_GetCurFile(filesource, &olepath, NULL);
326 ok(hr == S_OK, "Got hr %#x.\n", hr);
327 CoTaskMemFree(olepath);
329 olepath = NULL;
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");
361 CoTaskMemFree(pmt);
363 hr = IEnumMediaTypes_Next(enum_mt, 1, &pmt, NULL);
364 ok(hr == S_OK, "Got hr %#x.\n", hr);
365 mt = file_mt;
366 mt.subtype = GUID_NULL;
367 ok(!memcmp(pmt, &mt, sizeof(*pmt)), "Media types did not match.\n");
368 CoTaskMemFree(pmt);
370 hr = IEnumMediaTypes_Next(enum_mt, 1, &pmt, NULL);
371 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
373 IEnumMediaTypes_Release(enum_mt);
375 mt = file_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);
398 IPin_Release(pin);
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;
418 mt.pUnk = NULL;
419 mt.cbFormat = 0;
420 mt.pbFormat = NULL;
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");
439 CoTaskMemFree(pmt);
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);
458 CoTaskMemFree(pmt);
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);
484 IPin_Release(pin);
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;
497 IPin *pins[2];
498 ULONG count;
499 HRESULT hr;
500 ULONG ref;
501 BOOL ret;
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();
606 IEnumPins *enumpins;
607 IPin *pin, *pin2;
608 HRESULT hr;
609 ULONG ref;
610 BOOL ret;
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);
631 IPin_Release(pin2);
632 IPin_Release(pin);
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();
644 PIN_DIRECTION dir;
645 PIN_INFO info;
646 HRESULT hr;
647 WCHAR *id;
648 ULONG ref;
649 IPin *pin;
650 BOOL ret;
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));
679 CoTaskMemFree(id);
681 IPin_Release(pin);
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();
691 FILTER_STATE state;
692 HRESULT hr;
693 ULONG ref;
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;
749 HRESULT hr;
750 BYTE *data;
751 LONG len;
752 int i;
754 IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
755 IMediaSample_GetPointer(sample, &data);
757 start_time = 0;
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);
810 return 0;
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;
818 BYTE *data, *data2;
819 DWORD_PTR cookie;
820 HANDLE thread;
821 HRESULT hr;
822 LONG len;
823 int i;
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);
833 start_time = 0;
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);
860 start_time = 0;
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);
878 if (cookie == 123)
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);
887 else
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, &params, 0, NULL);
907 ok(!WaitForSingleObject(thread, 1000), "Wait timed out.\n");
908 CloseHandle(thread);
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;
923 DWORD_PTR cookie;
924 HRESULT hr = IAsyncReader_WaitForNext(reader, 2000, &sample, &cookie);
925 ok(hr == VFW_E_WRONG_STATE, "Got hr %#x.\n", hr);
926 return 0;
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;
934 DWORD_PTR cookie;
935 HANDLE thread;
936 HRESULT hr;
937 int i;
939 IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
940 IMediaSample_GetPointer(sample, &data);
942 start_time = 0;
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);
955 start_time = 0;
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);
974 start_time = 0;
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");
993 CloseHandle(thread);
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;
1010 BYTE buffer[20];
1011 DWORD written;
1012 HANDLE file;
1013 HRESULT hr;
1014 ULONG ref;
1015 IPin *pin;
1016 BOOL ret;
1017 int i;
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++)
1025 BYTE b = i % 111;
1026 WriteFile(file, &b, 1, &written, NULL);
1028 CloseHandle(file);
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);
1062 for (; i < 20; 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);
1086 IPin_Release(pin);
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];
1100 ULONG ref, count;
1101 HRESULT hr;
1102 IPin *pin;
1103 BOOL ret;
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);
1192 IPin_Release(pin);
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)
1202 CoInitialize(NULL);
1204 test_interfaces();
1205 test_aggregation();
1206 test_enum_pins();
1207 test_find_pin();
1208 test_pin_info();
1209 test_unconnected_filter_state();
1210 test_file_source_filter();
1211 test_async_reader();
1212 test_enum_media_types();
1214 CoUninitialize();