ReactOS 0.4.17-dev-923-g4c9a150
mpegsplit.c
Go to the documentation of this file.
1/*
2 * MPEG-1 splitter filter unit tests
3 *
4 * Copyright 2015 Anton Baskanov
5 *
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.
10 *
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.
15 *
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
19 */
20
21#define COBJMACROS
22#include "dshow.h"
23#include "mmreg.h"
24#include "wine/strmbase.h"
25#include "wine/test.h"
26
27static const GUID testguid = {0xfacade};
28static const GUID MEDIASUBTYPE_mp3 = {0x00000055,0x0000,0x0010,{0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71}};
29
31{
33 HRESULT hr = CoCreateInstance(&CLSID_MPEG1Splitter, NULL, CLSCTX_INPROC_SERVER,
34 &IID_IBaseFilter, (void **)&filter);
35 ok(hr == S_OK, "Got hr %#lx.\n", hr);
36 return filter;
37}
38
40{
41 return !memcmp(a, b, offsetof(AM_MEDIA_TYPE, pbFormat))
42 && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat);
43}
44
46{
47 static WCHAR pathW[MAX_PATH];
48 DWORD written;
50 HRSRC res;
51 void *ptr;
52
55
57 ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s, error %lu.\n",
59
61 ok(!!res, "Failed to load resource, error %lu.\n", GetLastError());
64 ok(written == SizeofResource(GetModuleHandleA(NULL), res), "Failed to write resource.\n");
66
67 return pathW;
68}
69
70static ULONG get_refcount(void *iface)
71{
72 IUnknown *unknown = iface;
73 IUnknown_AddRef(unknown);
74 return IUnknown_Release(unknown);
75}
76
78{
79 IFileSourceFilter *filesource;
82 IPin *source, *sink;
83 HRESULT hr;
84
85 CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
86 &IID_IBaseFilter, (void **)&reader);
87 IBaseFilter_QueryInterface(reader, &IID_IFileSourceFilter, (void **)&filesource);
88 IFileSourceFilter_Load(filesource, filename, NULL);
89
90 CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
91 &IID_IFilterGraph2, (void **)&graph);
92 IFilterGraph2_AddFilter(graph, reader, NULL);
93 IFilterGraph2_AddFilter(graph, splitter, NULL);
94
95 IBaseFilter_FindPin(splitter, L"Input", &sink);
96 IBaseFilter_FindPin(reader, L"Output", &source);
97
98 hr = IFilterGraph2_ConnectDirect(graph, source, sink, NULL);
99 ok(hr == S_OK, "Got hr %#lx.\n", hr);
100
101 IPin_Release(source);
102 IPin_Release(sink);
103 IBaseFilter_Release(reader);
104 IFileSourceFilter_Release(filesource);
105 return graph;
106}
107
108#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
109static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
110{
111 IUnknown *iface = iface_ptr;
113 IUnknown *unk;
114
115 expected_hr = supported ? S_OK : E_NOINTERFACE;
116
117 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
118 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
119 if (SUCCEEDED(hr))
120 IUnknown_Release(unk);
121}
122
123static void test_interfaces(void)
124{
125 const WCHAR *filename = load_resource(L"test.mp3");
128 IPin *pin;
129
130 check_interface(filter, &IID_IAMStreamSelect, TRUE);
133 check_interface(filter, &IID_IMediaFilter, TRUE);
135
136 check_interface(filter, &IID_IAMFilterMiscFlags, FALSE);
137 check_interface(filter, &IID_IBasicAudio, FALSE);
138 check_interface(filter, &IID_IBasicVideo, FALSE);
140 check_interface(filter, &IID_IMediaPosition, FALSE);
141 check_interface(filter, &IID_IMediaSeeking, FALSE);
144 check_interface(filter, &IID_IQualityControl, FALSE);
145 check_interface(filter, &IID_IQualProp, FALSE);
146 check_interface(filter, &IID_IReferenceClock, FALSE);
147 check_interface(filter, &IID_IVideoWindow, FALSE);
148
149 IBaseFilter_FindPin(filter, L"Input", &pin);
150
151 todo_wine check_interface(pin, &IID_IMemInputPin, TRUE);
153 todo_wine check_interface(pin, &IID_IQualityControl, TRUE);
155
157 check_interface(pin, &IID_IMediaPosition, FALSE);
158 check_interface(pin, &IID_IMediaSeeking, FALSE);
159
160 IPin_Release(pin);
161
162 IBaseFilter_FindPin(filter, L"Audio", &pin);
163
164 check_interface(pin, &IID_IMediaSeeking, TRUE);
166 check_interface(pin, &IID_IQualityControl, TRUE);
168
171 check_interface(pin, &IID_IMediaPosition, FALSE);
172
173 IPin_Release(pin);
174
175 IBaseFilter_Release(filter);
176 IFilterGraph2_Release(graph);
178}
179
180static const GUID test_iid = {0x33333333};
181static LONG outer_ref = 1;
182
184{
185 if (IsEqualGUID(iid, &IID_IUnknown)
187 || IsEqualGUID(iid, &test_iid))
188 {
189 *out = (IUnknown *)0xdeadbeef;
190 return S_OK;
191 }
192 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
193 return E_NOINTERFACE;
194}
195
197{
199}
200
202{
204}
205
206static const IUnknownVtbl outer_vtbl =
207{
211};
212
214
215static void test_aggregation(void)
216{
217 IBaseFilter *filter, *filter2;
218 IUnknown *unk, *unk2;
219 HRESULT hr;
220 ULONG ref;
221
222 filter = (IBaseFilter *)0xdeadbeef;
223 hr = CoCreateInstance(&CLSID_MPEG1Splitter, &test_outer, CLSCTX_INPROC_SERVER,
224 &IID_IBaseFilter, (void **)&filter);
225 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
226 ok(!filter, "Got interface %p.\n", filter);
227
228 hr = CoCreateInstance(&CLSID_MPEG1Splitter, &test_outer, CLSCTX_INPROC_SERVER,
229 &IID_IUnknown, (void **)&unk);
230 ok(hr == S_OK, "Got hr %#lx.\n", hr);
231 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
232 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
233 ref = get_refcount(unk);
234 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
235
236 ref = IUnknown_AddRef(unk);
237 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
238 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
239
240 ref = IUnknown_Release(unk);
241 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
242 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
243
244 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
245 ok(hr == S_OK, "Got hr %#lx.\n", hr);
246 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
247 IUnknown_Release(unk2);
248
249 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
250 ok(hr == S_OK, "Got hr %#lx.\n", hr);
251
252 hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
253 ok(hr == S_OK, "Got hr %#lx.\n", hr);
254 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
255
256 hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
257 ok(hr == S_OK, "Got hr %#lx.\n", hr);
258 ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
259
260 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
261 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
262 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
263
264 hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
265 ok(hr == S_OK, "Got hr %#lx.\n", hr);
266 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
267
268 IBaseFilter_Release(filter);
269 ref = IUnknown_Release(unk);
270 ok(!ref, "Got unexpected refcount %ld.\n", ref);
271 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
272}
273
274static void test_enum_pins(void)
275{
276 const WCHAR *filename = load_resource(L"test.mp3");
278 IEnumPins *enum1, *enum2;
280 ULONG count, ref;
281 IPin *pins[3];
282 HRESULT hr;
283 BOOL ret;
284
286 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
287
288 hr = IBaseFilter_EnumPins(filter, &enum1);
289 ok(hr == S_OK, "Got hr %#lx.\n", hr);
291 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
292 ref = get_refcount(enum1);
293 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
294
295 hr = IEnumPins_Next(enum1, 1, pins, NULL);
296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
298 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
299 ref = get_refcount(pins[0]);
300 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
301 ref = get_refcount(enum1);
302 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
303 IPin_Release(pins[0]);
304
305 hr = IEnumPins_Next(enum1, 1, pins, NULL);
306 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
307
308 hr = IEnumPins_Reset(enum1);
309 ok(hr == S_OK, "Got hr %#lx.\n", hr);
310
311 hr = IEnumPins_Next(enum1, 1, pins, &count);
312 ok(hr == S_OK, "Got hr %#lx.\n", hr);
313 ok(count == 1, "Got count %lu.\n", count);
314 IPin_Release(pins[0]);
315
316 hr = IEnumPins_Next(enum1, 1, pins, &count);
317 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
318 ok(!count, "Got count %lu.\n", count);
319
320 hr = IEnumPins_Reset(enum1);
321 ok(hr == S_OK, "Got hr %#lx.\n", hr);
322
323 hr = IEnumPins_Next(enum1, 2, pins, NULL);
324 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
325
326 hr = IEnumPins_Next(enum1, 2, pins, &count);
327 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
328 ok(count == 1, "Got count %lu.\n", count);
329 IPin_Release(pins[0]);
330
331 hr = IEnumPins_Reset(enum1);
332 ok(hr == S_OK, "Got hr %#lx.\n", hr);
333
334 hr = IEnumPins_Clone(enum1, &enum2);
335 ok(hr == S_OK, "Got hr %#lx.\n", hr);
336
337 hr = IEnumPins_Skip(enum1, 2);
338 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
339
340 hr = IEnumPins_Skip(enum1, 1);
341 ok(hr == S_OK, "Got hr %#lx.\n", hr);
342
343 hr = IEnumPins_Skip(enum1, 1);
344 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
345
346 hr = IEnumPins_Next(enum1, 1, pins, NULL);
347 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
348
349 hr = IEnumPins_Next(enum2, 1, pins, NULL);
350 ok(hr == S_OK, "Got hr %#lx.\n", hr);
351 IPin_Release(pins[0]);
352
353 IEnumPins_Release(enum2);
354
356
357 hr = IEnumPins_Next(enum1, 1, pins, NULL);
358 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
359
360 hr = IEnumPins_Reset(enum1);
361 ok(hr == S_OK, "Got hr %#lx.\n", hr);
362
363 hr = IEnumPins_Next(enum1, 1, pins, NULL);
364 ok(hr == S_OK, "Got hr %#lx.\n", hr);
365 IPin_Release(pins[0]);
366
367 hr = IEnumPins_Next(enum1, 1, pins, NULL);
368 ok(hr == S_OK, "Got hr %#lx.\n", hr);
369 IPin_Release(pins[0]);
370
371 hr = IEnumPins_Next(enum1, 1, pins, NULL);
372 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
373
374 hr = IEnumPins_Reset(enum1);
375 ok(hr == S_OK, "Got hr %#lx.\n", hr);
376
377 hr = IEnumPins_Next(enum1, 2, pins, &count);
378 ok(hr == S_OK, "Got hr %#lx.\n", hr);
379 ok(count == 2, "Got count %lu.\n", count);
380 IPin_Release(pins[0]);
381 IPin_Release(pins[1]);
382
383 hr = IEnumPins_Reset(enum1);
384 ok(hr == S_OK, "Got hr %#lx.\n", hr);
385
386 hr = IEnumPins_Next(enum1, 3, pins, &count);
387 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
388 ok(count == 2, "Got count %lu.\n", count);
389 IPin_Release(pins[0]);
390 IPin_Release(pins[1]);
391
392 IEnumPins_Release(enum1);
393 IFilterGraph2_Release(graph);
394 ref = IBaseFilter_Release(filter);
395 ok(!ref, "Got outstanding refcount %ld.\n", ref);
397 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
398}
399
400static void test_find_pin(void)
401{
402 const WCHAR *filename = load_resource(L"test.mp3");
406 IPin *pin, *pin2;
407 HRESULT hr;
408 ULONG ref;
409 BOOL ret;
410
411 hr = IBaseFilter_FindPin(filter, L"input pin", &pin);
412 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
413
414 hr = IBaseFilter_FindPin(filter, L"Input", &pin);
415 ok(hr == S_OK, "Got hr %#lx.\n", hr);
416 IPin_Release(pin);
417
418 hr = IBaseFilter_FindPin(filter, L"Audio", &pin);
419 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
420
422
423 hr = IBaseFilter_EnumPins(filter, &enum_pins);
424 ok(hr == S_OK, "Got hr %#lx.\n", hr);
425
426 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
427 ok(hr == S_OK, "Got hr %#lx.\n", hr);
428
429 hr = IBaseFilter_FindPin(filter, L"Input", &pin);
430 ok(hr == S_OK, "Got hr %#lx.\n", hr);
431 ok(pin == pin2, "Expected pin %p, got %p.\n", pin2, pin);
432 IPin_Release(pin);
433 IPin_Release(pin2);
434
435 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
436 ok(hr == S_OK, "Got hr %#lx.\n", hr);
437
438 hr = IBaseFilter_FindPin(filter, L"Audio", &pin);
439 ok(hr == S_OK, "Got hr %#lx.\n", hr);
440 ok(pin == pin2, "Expected pin %p, got %p.\n", pin2, pin);
441 IPin_Release(pin);
442 IPin_Release(pin2);
443
444 IEnumPins_Release(enum_pins);
445 IFilterGraph2_Release(graph);
446 ref = IBaseFilter_Release(filter);
447 ok(!ref, "Got outstanding refcount %ld.\n", ref);
449 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
450}
451
452static void test_pin_info(void)
453{
454 const WCHAR *filename = load_resource(L"test.mp3");
460 HRESULT hr;
461 WCHAR *id;
462 IPin *pin;
463 BOOL ret;
464
466
467 hr = IBaseFilter_FindPin(filter, L"Input", &pin);
468 ok(hr == S_OK, "Got hr %#lx.\n", hr);
470 ref = get_refcount(pin);
471 ok(ref == expect_ref, "Got unexpected refcount %ld.\n", ref);
472
473 hr = IPin_QueryPinInfo(pin, &info);
474 ok(hr == S_OK, "Got hr %#lx.\n", hr);
475 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
476 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
477 ok(!wcscmp(info.achName, L"Input"), "Got name %s.\n", wine_dbgstr_w(info.achName));
479 ok(ref == expect_ref + 1, "Got unexpected refcount %ld.\n", ref);
480 ref = get_refcount(pin);
481 ok(ref == expect_ref + 1, "Got unexpected refcount %ld.\n", ref);
482 IBaseFilter_Release(info.pFilter);
483
484 hr = IPin_QueryDirection(pin, &dir);
485 ok(hr == S_OK, "Got hr %#lx.\n", hr);
486 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
487
488 hr = IPin_QueryId(pin, &id);
489 ok(hr == S_OK, "Got hr %#lx.\n", hr);
490 ok(!wcscmp(id, L"Input"), "Got id %s.\n", wine_dbgstr_w(id));
491 CoTaskMemFree(id);
492
493 IPin_Release(pin);
494
495 hr = IBaseFilter_FindPin(filter, L"Audio", &pin);
496 ok(hr == S_OK, "Got hr %#lx.\n", hr);
497
498 hr = IPin_QueryPinInfo(pin, &info);
499 ok(hr == S_OK, "Got hr %#lx.\n", hr);
500 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
501 ok(info.dir == PINDIR_OUTPUT, "Got direction %d.\n", info.dir);
502 ok(!wcscmp(info.achName, L"Audio"), "Got name %s.\n", wine_dbgstr_w(info.achName));
503 IBaseFilter_Release(info.pFilter);
504
505 hr = IPin_QueryDirection(pin, &dir);
506 ok(hr == S_OK, "Got hr %#lx.\n", hr);
507 ok(dir == PINDIR_OUTPUT, "Got direction %d.\n", dir);
508
509 hr = IPin_QueryId(pin, &id);
510 ok(hr == S_OK, "Got hr %#lx.\n", hr);
511 ok(!wcscmp(id, L"Audio"), "Got id %s.\n", wine_dbgstr_w(id));
512 CoTaskMemFree(id);
513
514 IPin_Release(pin);
515
516 IFilterGraph2_Release(graph);
517 ref = IBaseFilter_Release(filter);
518 ok(!ref, "Got outstanding refcount %ld.\n", ref);
520 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
521}
522
523static void test_media_types(void)
524{
525 MPEG1WAVEFORMAT expect_wfx =
526 {
527 {WAVE_FORMAT_MPEG, 1, 48000, 4000, 96, 0, sizeof(MPEG1WAVEFORMAT) - sizeof(WAVEFORMATEX)},
529 };
530 static const MPEGLAYER3WAVEFORMAT expect_mp3_wfx =
531 {
532 {WAVE_FORMAT_MPEGLAYER3, 1, 48000, 4000, 1, 0, sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX)},
533 MPEGLAYER3_ID_MPEG, 0, 96, 1, 0
534 };
535
536 const WCHAR *filename = load_resource(L"test.mp3");
537 AM_MEDIA_TYPE mt = {{0}}, *pmt, expect_mt = {{0}};
539 MPEGLAYER3WAVEFORMAT *mp3wfx;
540 IEnumMediaTypes *enummt;
541 MPEG1WAVEFORMAT *wfx;
543 HRESULT hr;
544 ULONG ref;
545 IPin *pin;
546 BOOL ret;
547
548 IBaseFilter_FindPin(filter, L"Input", &pin);
549
550 hr = IPin_EnumMediaTypes(pin, &enummt);
551 ok(hr == S_OK, "Got hr %#lx.\n", hr);
552
553 expect_mt.majortype = MEDIATYPE_Stream;
554 expect_mt.bFixedSizeSamples = TRUE;
555 expect_mt.bTemporalCompression = TRUE;
556 expect_mt.lSampleSize = 1;
557
558 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
559 ok(hr == S_OK, "Got hr %#lx.\n", hr);
560 expect_mt.subtype = MEDIASUBTYPE_MPEG1System;
561 ok(!memcmp(pmt, &expect_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n");
562 CoTaskMemFree(pmt);
563
564 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
565 ok(hr == S_OK, "Got hr %#lx.\n", hr);
566 expect_mt.subtype = MEDIASUBTYPE_MPEG1VideoCD;
567 ok(!memcmp(pmt, &expect_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n");
568 CoTaskMemFree(pmt);
569
570 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
571 ok(hr == S_OK, "Got hr %#lx.\n", hr);
572 expect_mt.subtype = MEDIASUBTYPE_MPEG1Video;
573 ok(!memcmp(pmt, &expect_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n");
574 CoTaskMemFree(pmt);
575
576 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
577 ok(hr == S_OK, "Got hr %#lx.\n", hr);
578 expect_mt.subtype = MEDIASUBTYPE_MPEG1Audio;
579 ok(!memcmp(pmt, &expect_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n");
580 CoTaskMemFree(pmt);
581
582 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
583 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
584
585 IEnumMediaTypes_Release(enummt);
586
587 mt.majortype = MEDIATYPE_Stream;
588 mt.subtype = MEDIASUBTYPE_MPEG1Audio;
589 hr = IPin_QueryAccept(pin, &mt);
590 ok(hr == S_OK, "Got hr %#lx.\n", hr);
591
592 mt.subtype = MEDIASUBTYPE_MPEG1Video;
593 hr = IPin_QueryAccept(pin, &mt);
594 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
595 mt.subtype = MEDIASUBTYPE_MPEG1VideoCD;
596 hr = IPin_QueryAccept(pin, &mt);
597 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
598 mt.subtype = MEDIASUBTYPE_MPEG1System;
599 hr = IPin_QueryAccept(pin, &mt);
600 ok(hr == S_OK, "Got hr %#lx.\n", hr);
601 mt.subtype = MEDIASUBTYPE_MPEG1AudioPayload;
602 hr = IPin_QueryAccept(pin, &mt);
603 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
604 mt.subtype = MEDIASUBTYPE_MPEG1Payload;
605 hr = IPin_QueryAccept(pin, &mt);
606 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
607 mt.subtype = MEDIASUBTYPE_MPEG1Packet;
608 hr = IPin_QueryAccept(pin, &mt);
609 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
610 mt.subtype = GUID_NULL;
611 hr = IPin_QueryAccept(pin, &mt);
612 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
613 mt.subtype = MEDIASUBTYPE_MPEG1Audio;
614
615 mt.majortype = MEDIATYPE_Audio;
616 hr = IPin_QueryAccept(pin, &mt);
617 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
618 mt.majortype = GUID_NULL;
619 hr = IPin_QueryAccept(pin, &mt);
620 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
621 mt.majortype = MEDIATYPE_Stream;
622
623 mt.formattype = FORMAT_None;
624 hr = IPin_QueryAccept(pin, &mt);
625 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
626 mt.formattype = FORMAT_VideoInfo;
627 hr = IPin_QueryAccept(pin, &mt);
628 todo_wine ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
629 mt.formattype = FORMAT_WaveFormatEx;
630 hr = IPin_QueryAccept(pin, &mt);
631 ok(hr == S_OK, "Got hr %#lx.\n", hr);
632
633 mt.bFixedSizeSamples = TRUE;
634 mt.bTemporalCompression = TRUE;
635 mt.lSampleSize = 123;
636 hr = IPin_QueryAccept(pin, &mt);
637 ok(hr == S_OK, "Got hr %#lx.\n", hr);
638
640
641 /* Connecting input doesn't change the reported media types. */
642 hr = IPin_EnumMediaTypes(pin, &enummt);
643 ok(hr == S_OK, "Got hr %#lx.\n", hr);
644
645 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
646 ok(hr == S_OK, "Got hr %#lx.\n", hr);
647 expect_mt.subtype = MEDIASUBTYPE_MPEG1System;
648 ok(!memcmp(pmt, &expect_mt, sizeof(AM_MEDIA_TYPE)), "Media types didn't match.\n");
649 CoTaskMemFree(pmt);
650
651 IEnumMediaTypes_Release(enummt);
652 IPin_Release(pin);
653
654 IBaseFilter_FindPin(filter, L"Audio", &pin);
655
656 hr = IPin_EnumMediaTypes(pin, &enummt);
657 ok(hr == S_OK, "Got hr %#lx.\n", hr);
658
659 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
660 ok(hr == S_OK, "Got hr %#lx.\n", hr);
661 ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s.\n",
662 wine_dbgstr_guid(&pmt->majortype));
663 todo_wine ok(IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_MPEG1AudioPayload), "Got subtype %s.\n",
664 wine_dbgstr_guid(&pmt->subtype));
665 todo_wine ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
666 ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
667 todo_wine ok(pmt->lSampleSize == 1, "Got sample size %lu.\n", pmt->lSampleSize);
668 ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n",
669 wine_dbgstr_guid(&pmt->formattype));
670 ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
671 todo_wine ok(pmt->cbFormat == sizeof(MPEG1WAVEFORMAT), "Got format size %lu.\n", pmt->cbFormat);
672 if (pmt->cbFormat == sizeof(MPEG1WAVEFORMAT))
673 {
674 /* Native will sometimes leave junk in the joint stereo flags. */
675 expect_wfx.fwHeadModeExt = ((MPEG1WAVEFORMAT *)pmt->pbFormat)->fwHeadModeExt;
676 ok(!memcmp(pmt->pbFormat, &expect_wfx, sizeof(MPEG1WAVEFORMAT)), "Format blocks didn't match.\n");
677 }
678
679 hr = IPin_QueryAccept(pin, pmt);
680 ok(hr == S_OK, "Got hr %#lx.\n", hr);
681
682 pmt->bFixedSizeSamples = FALSE;
683 pmt->bTemporalCompression = TRUE;
684 pmt->lSampleSize = 123;
685 hr = IPin_QueryAccept(pin, pmt);
686 ok(hr == S_OK, "Got hr %#lx.\n", hr);
687
688 pmt->majortype = MEDIATYPE_Video;
689 hr = IPin_QueryAccept(pin, pmt);
690 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
691 pmt->majortype = GUID_NULL;
692 hr = IPin_QueryAccept(pin, pmt);
693 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
694 pmt->majortype = MEDIATYPE_Audio;
695
696 pmt->subtype = MEDIASUBTYPE_MPEG1Audio;
697 hr = IPin_QueryAccept(pin, pmt);
698 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
699 pmt->subtype = MEDIASUBTYPE_MPEG1Packet;
700 hr = IPin_QueryAccept(pin, pmt);
701 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
702 pmt->subtype = MEDIASUBTYPE_MPEG1Video;
703 hr = IPin_QueryAccept(pin, pmt);
704 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
705 pmt->subtype = MEDIASUBTYPE_MPEG1AudioPayload;
706
707 pmt->formattype = FORMAT_None;
708 hr = IPin_QueryAccept(pin, pmt);
709 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
710 pmt->formattype = GUID_NULL;
711 hr = IPin_QueryAccept(pin, pmt);
712 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
713 pmt->formattype = FORMAT_WaveFormatEx;
714
715 wfx = (MPEG1WAVEFORMAT *)pmt->pbFormat;
716
718 hr = IPin_QueryAccept(pin, pmt);
719 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
721
723 hr = IPin_QueryAccept(pin, pmt);
724 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
726
727 CoTaskMemFree(pmt->pbFormat);
728 CoTaskMemFree(pmt);
729
730 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
731 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
732 if (hr != S_OK)
733 goto done;
734 ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s.\n",
735 wine_dbgstr_guid(&pmt->majortype));
736 ok(IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_MPEG1Payload), "Got subtype %s.\n",
737 wine_dbgstr_guid(&pmt->subtype));
738 ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
739 ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
740 ok(pmt->lSampleSize == 1, "Got sample size %lu.\n", pmt->lSampleSize);
741 ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n",
742 wine_dbgstr_guid(&pmt->formattype));
743 ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
744 ok(pmt->cbFormat == sizeof(MPEG1WAVEFORMAT), "Got format size %lu.\n", pmt->cbFormat);
745 /* Native will sometimes leave junk in the joint stereo flags. */
746 expect_wfx.fwHeadModeExt = ((MPEG1WAVEFORMAT *)pmt->pbFormat)->fwHeadModeExt;
747 ok(!memcmp(pmt->pbFormat, &expect_wfx, sizeof(MPEG1WAVEFORMAT)), "Format blocks didn't match.\n");
748
749 hr = IPin_QueryAccept(pin, pmt);
750 ok(hr == S_OK, "Got hr %#lx.\n", hr);
751
752 CoTaskMemFree(pmt->pbFormat);
753 CoTaskMemFree(pmt);
754
755 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
756 ok(hr == S_OK, "Got hr %#lx.\n", hr);
757 ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s.\n",
758 wine_dbgstr_guid(&pmt->majortype));
759 ok(IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_mp3), "Got subtype %s.\n",
760 wine_dbgstr_guid(&pmt->subtype));
761 ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
762 ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
763 ok(pmt->lSampleSize == 1, "Got sample size %lu.\n", pmt->lSampleSize);
764 ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n",
765 wine_dbgstr_guid(&pmt->formattype));
766 ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
767 ok(pmt->cbFormat == sizeof(MPEGLAYER3WAVEFORMAT), "Got format size %lu.\n", pmt->cbFormat);
768 ok(!memcmp(pmt->pbFormat, &expect_mp3_wfx, sizeof(MPEGLAYER3WAVEFORMAT)),
769 "Format blocks didn't match.\n");
770
771 hr = IPin_QueryAccept(pin, pmt);
772 ok(hr == S_OK, "Got hr %#lx.\n", hr);
773
774 pmt->bFixedSizeSamples = FALSE;
775 pmt->bTemporalCompression = TRUE;
776 pmt->lSampleSize = 123;
777 hr = IPin_QueryAccept(pin, pmt);
778 ok(hr == S_OK, "Got hr %#lx.\n", hr);
779
780 pmt->majortype = MEDIATYPE_Video;
781 hr = IPin_QueryAccept(pin, pmt);
782 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
783 pmt->majortype = MEDIATYPE_Audio;
784
785 pmt->subtype = MEDIASUBTYPE_MPEG1Audio;
786 hr = IPin_QueryAccept(pin, pmt);
787 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
788 pmt->subtype = MEDIASUBTYPE_MPEG1Packet;
789 hr = IPin_QueryAccept(pin, pmt);
790 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
791 pmt->subtype = MEDIASUBTYPE_MPEG1Video;
792 hr = IPin_QueryAccept(pin, pmt);
793 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
794 pmt->subtype = MEDIASUBTYPE_MPEG1AudioPayload;
795
796 pmt->formattype = FORMAT_None;
797 hr = IPin_QueryAccept(pin, pmt);
798 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
799 pmt->formattype = GUID_NULL;
800 hr = IPin_QueryAccept(pin, pmt);
801 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
802 pmt->formattype = FORMAT_WaveFormatEx;
803
804 mp3wfx = (MPEGLAYER3WAVEFORMAT *)pmt->pbFormat;
805
807 hr = IPin_QueryAccept(pin, pmt);
808 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
810
812 hr = IPin_QueryAccept(pin, pmt);
813 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
815
816 CoTaskMemFree(pmt->pbFormat);
817 CoTaskMemFree(pmt);
818
819done:
820 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
821 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
822
823 IEnumMediaTypes_Release(enummt);
824 IPin_Release(pin);
825
826 IFilterGraph2_Release(graph);
827 ref = IBaseFilter_Release(filter);
828 ok(!ref, "Got outstanding refcount %ld.\n", ref);
830 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
831}
832
833static void test_enum_media_types(void)
834{
835 const WCHAR *filename = load_resource(L"test.mp3");
838 IEnumMediaTypes *enum1, *enum2;
839 AM_MEDIA_TYPE *mts[5];
840 ULONG ref, count;
841 unsigned int i;
842 HRESULT hr;
843 IPin *pin;
844 BOOL ret;
845
846 IBaseFilter_FindPin(filter, L"Input", &pin);
847
848 hr = IPin_EnumMediaTypes(pin, &enum1);
849 ok(hr == S_OK, "Got hr %#lx.\n", hr);
850
851 for (i = 0; i < 4; ++i)
852 {
853 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
854 ok(hr == S_OK, "Got hr %#lx.\n", hr);
855 CoTaskMemFree(mts[0]);
856 }
857
858 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
859 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
860
861 hr = IEnumMediaTypes_Reset(enum1);
862 ok(hr == S_OK, "Got hr %#lx.\n", hr);
863
864 for (i = 0; i < 4; ++i)
865 {
866 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
867 ok(hr == S_OK, "Got hr %#lx.\n", hr);
868 ok(count == 1, "Got count %lu.\n", count);
869 CoTaskMemFree(mts[0]);
870 }
871
872 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
873 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
874 ok(!count, "Got count %lu.\n", count);
875
876 hr = IEnumMediaTypes_Reset(enum1);
877 ok(hr == S_OK, "Got hr %#lx.\n", hr);
878
879 hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
880 ok(hr == S_OK, "Got hr %#lx.\n", hr);
881 ok(count == 2, "Got count %lu.\n", count);
882 CoTaskMemFree(mts[0]);
883 CoTaskMemFree(mts[1]);
884
885 hr = IEnumMediaTypes_Next(enum1, 3, mts, &count);
886 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
887 ok(count == 2, "Got count %lu.\n", count);
888 CoTaskMemFree(mts[0]);
889 CoTaskMemFree(mts[1]);
890
891 hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
892 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
893 ok(!count, "Got count %lu.\n", count);
894
895 hr = IEnumMediaTypes_Reset(enum1);
896 ok(hr == S_OK, "Got hr %#lx.\n", hr);
897
898 hr = IEnumMediaTypes_Clone(enum1, &enum2);
899 ok(hr == S_OK, "Got hr %#lx.\n", hr);
900
901 hr = IEnumMediaTypes_Skip(enum1, 5);
902 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
903
904 hr = IEnumMediaTypes_Skip(enum1, 1);
905 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
906
907 hr = IEnumMediaTypes_Reset(enum1);
908 ok(hr == S_OK, "Got hr %#lx.\n", hr);
909
910 hr = IEnumMediaTypes_Skip(enum1, 4);
911 ok(hr == S_OK, "Got hr %#lx.\n", hr);
912
913 hr = IEnumMediaTypes_Skip(enum1, 1);
914 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
915
916 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
917 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
918
919 hr = IEnumMediaTypes_Next(enum2, 1, mts, NULL);
920 ok(hr == S_OK, "Got hr %#lx.\n", hr);
921 CoTaskMemFree(mts[0]);
922
923 IEnumMediaTypes_Release(enum1);
924 IEnumMediaTypes_Release(enum2);
925 IPin_Release(pin);
926
927 IBaseFilter_FindPin(filter, L"Audio", &pin);
928
929 hr = IPin_EnumMediaTypes(pin, &enum1);
930 ok(hr == S_OK, "Got hr %#lx.\n", hr);
931
932 for (i = 0; i < 3; ++i)
933 {
934 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
935 todo_wine_if(i) ok(hr == S_OK, "Got hr %#lx.\n", hr);
936 if (hr == S_OK) CoTaskMemFree(mts[0]->pbFormat);
937 if (hr == S_OK) CoTaskMemFree(mts[0]);
938 }
939
940 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
941 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
942
943 hr = IEnumMediaTypes_Reset(enum1);
944 ok(hr == S_OK, "Got hr %#lx.\n", hr);
945
946 for (i = 0; i < 3; ++i)
947 {
948 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
949 todo_wine_if(i) ok(hr == S_OK, "Got hr %#lx.\n", hr);
950 todo_wine_if(i) ok(count == 1, "Got count %lu.\n", count);
951 if (hr == S_OK) CoTaskMemFree(mts[0]->pbFormat);
952 if (hr == S_OK) CoTaskMemFree(mts[0]);
953 }
954
955 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
956 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
957 ok(!count, "Got count %lu.\n", count);
958
959 hr = IEnumMediaTypes_Reset(enum1);
960 ok(hr == S_OK, "Got hr %#lx.\n", hr);
961
962 hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
963 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
964 todo_wine ok(count == 2, "Got count %lu.\n", count);
965 CoTaskMemFree(mts[0]->pbFormat);
966 CoTaskMemFree(mts[0]);
967 if (count > 1) CoTaskMemFree(mts[1]->pbFormat);
968 if (count > 1) CoTaskMemFree(mts[1]);
969
970 hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
971 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
972 todo_wine ok(count == 1, "Got count %lu.\n", count);
973 if (count) CoTaskMemFree(mts[0]->pbFormat);
974 if (count) CoTaskMemFree(mts[0]);
975
976 hr = IEnumMediaTypes_Next(enum1, 2, mts, &count);
977 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
978 ok(!count, "Got count %lu.\n", count);
979
980 hr = IEnumMediaTypes_Reset(enum1);
981 ok(hr == S_OK, "Got hr %#lx.\n", hr);
982
983 hr = IEnumMediaTypes_Clone(enum1, &enum2);
984 ok(hr == S_OK, "Got hr %#lx.\n", hr);
985
986 hr = IEnumMediaTypes_Skip(enum1, 4);
987 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
988
989 hr = IEnumMediaTypes_Skip(enum1, 1);
990 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
991
992 hr = IEnumMediaTypes_Reset(enum1);
993 ok(hr == S_OK, "Got hr %#lx.\n", hr);
994
995 hr = IEnumMediaTypes_Skip(enum1, 3);
996 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
997
998 hr = IEnumMediaTypes_Skip(enum1, 1);
999 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1000
1001 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
1002 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1003
1004 hr = IEnumMediaTypes_Next(enum2, 1, mts, NULL);
1005 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1006 CoTaskMemFree(mts[0]->pbFormat);
1007 CoTaskMemFree(mts[0]);
1008
1009 IEnumMediaTypes_Release(enum1);
1010 IEnumMediaTypes_Release(enum2);
1011 IPin_Release(pin);
1012
1013 IFilterGraph2_Release(graph);
1014 ref = IBaseFilter_Release(filter);
1015 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1017 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
1018}
1019
1021{
1023 FILTER_STATE state;
1024 HRESULT hr;
1025 ULONG ref;
1026
1027 hr = IBaseFilter_GetState(filter, 0, &state);
1028 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1029 ok(state == State_Stopped, "Got state %u.\n", state);
1030
1031 hr = IBaseFilter_Pause(filter);
1032 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1033
1034 hr = IBaseFilter_GetState(filter, 0, &state);
1035 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1036 ok(state == State_Paused, "Got state %u.\n", state);
1037
1038 hr = IBaseFilter_Run(filter, 0);
1039 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1040
1041 hr = IBaseFilter_GetState(filter, 0, &state);
1042 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1043 ok(state == State_Running, "Got state %u.\n", state);
1044
1045 hr = IBaseFilter_Pause(filter);
1046 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1047
1048 hr = IBaseFilter_GetState(filter, 0, &state);
1049 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1050 ok(state == State_Paused, "Got state %u.\n", state);
1051
1052 hr = IBaseFilter_Stop(filter);
1053 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1054
1055 hr = IBaseFilter_GetState(filter, 0, &state);
1056 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1057 ok(state == State_Stopped, "Got state %u.\n", state);
1058
1059 hr = IBaseFilter_Run(filter, 0);
1060 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1061
1062 hr = IBaseFilter_GetState(filter, 0, &state);
1063 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1064 ok(state == State_Running, "Got state %u.\n", state);
1065
1066 hr = IBaseFilter_Stop(filter);
1067 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1068
1069 hr = IBaseFilter_GetState(filter, 0, &state);
1070 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1071 ok(state == State_Stopped, "Got state %u.\n", state);
1072
1073 ref = IBaseFilter_Release(filter);
1074 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1075}
1076
1077struct testfilter
1078{
1079 struct strmbase_filter filter;
1080 struct strmbase_source source;
1081 struct strmbase_sink sink;
1083 const AM_MEDIA_TYPE *mt;
1088};
1089
1090static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
1091{
1092 return CONTAINING_RECORD(iface, struct testfilter, filter);
1093}
1094
1095static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
1096{
1098 if (!index)
1099 return &filter->source.pin;
1100 else if (index == 1)
1101 return &filter->sink.pin;
1102 return NULL;
1103}
1104
1105static void testfilter_destroy(struct strmbase_filter *iface)
1106{
1111 CloseHandle(filter->eos_event);
1112}
1113
1115{
1117
1118 filter->new_segment_count = 0;
1119 filter->eos_count = 0;
1120 filter->sample_count = 0;
1121 return S_OK;
1122}
1123
1125{
1126 .filter_get_pin = testfilter_get_pin,
1127 .filter_destroy = testfilter_destroy,
1128 .filter_init_stream = testfilter_init_stream,
1129};
1130
1132{
1134
1135 if (IsEqualGUID(iid, &IID_IAsyncReader))
1136 *out = &filter->IAsyncReader_iface;
1137 else
1138 return E_NOINTERFACE;
1139
1140 IUnknown_AddRef((IUnknown *)*out);
1141 return S_OK;
1142}
1143
1145 IPin *peer, const AM_MEDIA_TYPE *mt)
1146{
1147 HRESULT hr;
1148
1149 iface->pin.peer = peer;
1150 IPin_AddRef(peer);
1151 CopyMediaType(&iface->pin.mt, mt);
1152
1153 if (FAILED(hr = IPin_ReceiveConnection(peer, &iface->pin.IPin_iface, mt)))
1154 {
1155 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1156 IPin_Release(peer);
1157 iface->pin.peer = NULL;
1158 FreeMediaType(&iface->pin.mt);
1159 }
1160
1161 return hr;
1162}
1163
1165{
1166 .base.pin_query_interface = testsource_query_interface,
1167 .pfnAttemptConnection = testsource_AttemptConnection,
1168};
1169
1170static HRESULT testsink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
1171{
1173
1174 if (IsEqualGUID(iid, &IID_IMemInputPin))
1175 *out = &filter->sink.IMemInputPin_iface;
1176 else
1177 return E_NOINTERFACE;
1178
1179 IUnknown_AddRef((IUnknown *)*out);
1180 return S_OK;
1181}
1182
1184{
1186 if (!index && filter->mt)
1187 {
1188 CopyMediaType(mt, filter->mt);
1189 return S_OK;
1190 }
1191 return VFW_S_NO_MORE_ITEMS;
1192}
1193
1194static HRESULT testsink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
1195{
1196 struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
1197 if (filter->mt && !IsEqualGUID(&mt->majortype, &filter->mt->majortype))
1199 return S_OK;
1200}
1201
1203{
1204 struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
1206 IMediaSeeking *seeking;
1207 HRESULT hr;
1208
1209 hr = IMediaSample_GetTime(sample, &start, &end);
1210 ok(hr == S_OK || (filter->sample_count > 0 && hr == VFW_E_SAMPLE_TIME_NOT_SET), "Got hr %#lx.\n", hr);
1211
1212 if (winetest_debug > 1)
1213 trace("%04lx: Got sample with timestamps %I64d-%I64d.\n", GetCurrentThreadId(), start, end);
1214
1215 ok(filter->new_segment_count, "Expected NewSegment() before Receive().\n");
1216
1217 IPin_QueryInterface(iface->pin.peer, &IID_IMediaSeeking, (void **)&seeking);
1218 hr = IMediaSeeking_GetPositions(seeking, &start, &end);
1219 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1220 ok(start == filter->seek_start, "Expected start position %I64u, got %I64u.\n", filter->seek_start, start);
1221 ok(end == filter->seek_end, "Expected end position %I64u, got %I64u.\n", filter->seek_end, end);
1222 IMediaSeeking_Release(seeking);
1223
1224 ok(!filter->eos_count, "Got a sample after EOS.\n");
1225 ++filter->sample_count;
1226 filter->byte_count += IMediaSample_GetActualDataLength(sample);
1227 return S_OK;
1228}
1229
1231{
1232 struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
1233
1234 if (winetest_debug > 1)
1235 trace("%04lx: Got EOS.\n", GetCurrentThreadId());
1236
1237 ok(!filter->eos_count, "Got %u EOS events.\n", filter->eos_count + 1);
1238 ++filter->eos_count;
1239 SetEvent(filter->eos_event);
1240 return S_OK;
1241}
1242
1245{
1246 struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
1247 IMediaSeeking *seeking;
1248 HRESULT hr;
1249
1250 if (winetest_debug > 1)
1251 trace("%04lx: Got segment with timestamps %I64d-%I64d.\n", GetCurrentThreadId(), start, end);
1252
1253 ++filter->new_segment_count;
1254
1255 IPin_QueryInterface(iface->pin.peer, &IID_IMediaSeeking, (void **)&seeking);
1256 hr = IMediaSeeking_GetPositions(seeking, &filter->seek_start, &filter->seek_end);
1257 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1258 IMediaSeeking_Release(seeking);
1259
1260 ok(start == filter->segment_start, "Expected start %I64d, got %I64d.\n", filter->segment_start, start);
1261 ok(end >= filter->segment_end_min && end <= filter->segment_end_max,
1262 "Expected end %I64d to %I64d, got %I64d.\n", filter->segment_end_min, filter->segment_end_max, end);
1263 ok(rate == 1.0, "Got rate %.16e.\n", rate);
1264
1265 return S_OK;
1266}
1267
1268static const struct strmbase_sink_ops testsink_ops =
1269{
1270 .base.pin_query_interface = testsink_query_interface,
1271 .base.pin_get_media_type = testsink_get_media_type,
1272 .sink_connect = testsink_connect,
1273 .pfnReceive = testsink_Receive,
1274 .sink_eos = testsink_eos,
1275 .sink_new_segment = testsink_new_segment,
1276};
1277
1279{
1280 return CONTAINING_RECORD(iface, struct testfilter, IAsyncReader_iface);
1281}
1282
1284{
1285 return IPin_QueryInterface(&impl_from_IAsyncReader(iface)->source.pin.IPin_iface, iid, out);
1286}
1287
1289{
1290 return IPin_AddRef(&impl_from_IAsyncReader(iface)->source.pin.IPin_iface);
1291}
1292
1294{
1295 return IPin_Release(&impl_from_IAsyncReader(iface)->source.pin.IPin_iface);
1296}
1297
1300{
1301 return IAsyncReader_RequestAllocator(impl_from_IAsyncReader(iface)->reader, preferred, props, allocator);
1302}
1303
1305{
1306 return IAsyncReader_Request(impl_from_IAsyncReader(iface)->reader, sample, cookie);
1307}
1308
1311{
1312 return IAsyncReader_WaitForNext(impl_from_IAsyncReader(iface)->reader, timeout, sample, cookie);
1313}
1314
1316{
1317 return IAsyncReader_SyncReadAligned(impl_from_IAsyncReader(iface)->reader, sample);
1318}
1319
1321{
1322 struct testfilter *filter = impl_from_IAsyncReader(iface);
1323 filter->read_position = position + length;
1324 return IAsyncReader_SyncRead(filter->reader, position, length, buffer);
1325}
1326
1328{
1329 return IAsyncReader_Length(impl_from_IAsyncReader(iface)->reader, total, available);
1330}
1331
1333{
1334 return IAsyncReader_BeginFlush(impl_from_IAsyncReader(iface)->reader);
1335}
1336
1338{
1339 return IAsyncReader_EndFlush(impl_from_IAsyncReader(iface)->reader);
1340}
1341
1342static const struct IAsyncReaderVtbl async_reader_vtbl =
1343{
1355};
1356
1358{
1359 static const GUID clsid = {0xabacab};
1360 memset(filter, 0, sizeof(*filter));
1362 strmbase_source_init(&filter->source, &filter->filter, L"source", &testsource_ops);
1364 filter->IAsyncReader_iface.lpVtbl = &async_reader_vtbl;
1365 filter->eos_event = CreateEventW(NULL, FALSE, FALSE, NULL);
1366 filter->segment_end_min = 5000000; /* 5392500 on native */
1367 filter->segment_end_max = 5500000;
1368}
1369
1370static void test_connect_pin(void)
1371{
1372 AM_MEDIA_TYPE req_mt =
1373 {
1374 .majortype = MEDIATYPE_Stream,
1375 .subtype = MEDIASUBTYPE_MPEG1Audio,
1376 .formattype = FORMAT_WaveFormatEx,
1377 .lSampleSize = 888,
1378 };
1380 const WCHAR *filename = load_resource(L"test.mp3");
1381 struct testfilter testsource, testsink;
1382 IFileSourceFilter *filesource;
1384 IPin *sink, *source, *peer;
1385 IEnumMediaTypes *enummt;
1386 IMediaControl *control;
1388 HRESULT hr;
1389 ULONG ref;
1390 BOOL ret;
1391
1392 CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
1393 &IID_IFilterGraph2, (void **)&graph);
1394 testfilter_init(&testsource);
1396 IFilterGraph2_AddFilter(graph, &testsink.filter.IBaseFilter_iface, L"sink");
1397 IFilterGraph2_AddFilter(graph, &testsource.filter.IBaseFilter_iface, L"source");
1398 IFilterGraph2_AddFilter(graph, filter, L"splitter");
1399 IBaseFilter_FindPin(filter, L"Input", &sink);
1400 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
1401
1402 CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
1403 &IID_IBaseFilter, (void **)&reader);
1404 IBaseFilter_QueryInterface(reader, &IID_IFileSourceFilter, (void **)&filesource);
1405 IFileSourceFilter_Load(filesource, filename, NULL);
1406 IFileSourceFilter_Release(filesource);
1407 IBaseFilter_FindPin(reader, L"Output", &source);
1408 IPin_QueryInterface(source, &IID_IAsyncReader, (void **)&testsource.reader);
1409 IPin_Release(source);
1410
1411 /* Test sink connection. */
1412
1413 peer = (IPin *)0xdeadbeef;
1414 hr = IPin_ConnectedTo(sink, &peer);
1415 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1416 ok(!peer, "Got peer %p.\n", peer);
1417
1418 hr = IPin_ConnectionMediaType(sink, &mt);
1419 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1420
1421 hr = IMediaControl_Pause(control);
1422 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1423 hr = IFilterGraph2_ConnectDirect(graph, &testsource.source.pin.IPin_iface, sink, &req_mt);
1424 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
1425 hr = IMediaControl_Stop(control);
1426 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1427
1428 req_mt.majortype = MEDIATYPE_Video;
1429 hr = IFilterGraph2_ConnectDirect(graph, &testsource.source.pin.IPin_iface, sink, &req_mt);
1430 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1431 req_mt.majortype = MEDIATYPE_Stream;
1432
1433 req_mt.subtype = MEDIASUBTYPE_RGB8;
1434 hr = IFilterGraph2_ConnectDirect(graph, &testsource.source.pin.IPin_iface, sink, &req_mt);
1435 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1436 req_mt.subtype = MEDIASUBTYPE_MPEG1Audio;
1437
1438 hr = IFilterGraph2_ConnectDirect(graph, &testsource.source.pin.IPin_iface, sink, &req_mt);
1439 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1440
1441 hr = IPin_ConnectedTo(sink, &peer);
1442 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1443 ok(peer == &testsource.source.pin.IPin_iface, "Got peer %p.\n", peer);
1444 IPin_Release(peer);
1445
1446 hr = IPin_ConnectionMediaType(sink, &mt);
1447 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1448 ok(compare_media_types(&mt, &req_mt), "Media types didn't match.\n");
1449 ok(compare_media_types(&testsource.source.pin.mt, &req_mt), "Media types didn't match.\n");
1450
1451 hr = IMediaControl_Pause(control);
1452 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1453 hr = IFilterGraph2_Disconnect(graph, sink);
1454 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
1455 hr = IMediaControl_Stop(control);
1456 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1457
1458 /* Test source connection. */
1459
1460 IBaseFilter_FindPin(filter, L"Audio", &source);
1461
1462 peer = (IPin *)0xdeadbeef;
1463 hr = IPin_ConnectedTo(source, &peer);
1464 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1465 ok(!peer, "Got peer %p.\n", peer);
1466
1467 hr = IPin_ConnectionMediaType(source, &mt);
1468 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1469
1470 /* Exact connection. */
1471
1472 IPin_EnumMediaTypes(source, &enummt);
1473 IEnumMediaTypes_Next(enummt, 1, &source_mt, NULL);
1474 IEnumMediaTypes_Release(enummt);
1475 CopyMediaType(&req_mt, source_mt);
1476
1477 hr = IMediaControl_Pause(control);
1478 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1479 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1480 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
1481 hr = IMediaControl_Stop(control);
1482 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1483
1484 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1485 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1486
1487 hr = IPin_ConnectedTo(source, &peer);
1488 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1489 ok(peer == &testsink.sink.pin.IPin_iface, "Got peer %p.\n", peer);
1490 IPin_Release(peer);
1491
1492 hr = IPin_ConnectionMediaType(source, &mt);
1493 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1494 ok(compare_media_types(&mt, &req_mt), "Media types didn't match.\n");
1495 ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "Media types didn't match.\n");
1496
1497 hr = IMediaControl_Pause(control);
1498 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1499 hr = IFilterGraph2_Disconnect(graph, source);
1500 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
1501 hr = IMediaControl_Stop(control);
1502 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1503
1504 hr = IFilterGraph2_Disconnect(graph, source);
1505 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1506 hr = IFilterGraph2_Disconnect(graph, source);
1507 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1508 ok(testsink.sink.pin.peer == source, "Got peer %p.\n", testsink.sink.pin.peer);
1509 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1510
1511 req_mt.lSampleSize = 999;
1512 req_mt.bTemporalCompression = req_mt.bFixedSizeSamples = TRUE;
1513 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1514 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1515 ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "Media types didn't match.\n");
1516 IFilterGraph2_Disconnect(graph, source);
1517 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1518
1519 req_mt.majortype = MEDIATYPE_Stream;
1520 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1521 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1522 req_mt.majortype = MEDIATYPE_Audio;
1523
1524 req_mt.subtype = MEDIASUBTYPE_PCM;
1525 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1526 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1527 req_mt.subtype = GUID_NULL;
1528 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1529 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1530 req_mt.subtype = MEDIASUBTYPE_MPEG1AudioPayload;
1531
1532 /* Connection with wildcards. */
1533
1534 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, NULL);
1535 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1536 ok(compare_media_types(&testsink.sink.pin.mt, source_mt), "Media types didn't match.\n");
1537 IFilterGraph2_Disconnect(graph, source);
1538 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1539
1540 req_mt.majortype = GUID_NULL;
1541 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1542 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
1543 if (hr == S_OK)
1544 ok(compare_media_types(&testsink.sink.pin.mt, source_mt), "Media types didn't match.\n");
1545 IFilterGraph2_Disconnect(graph, source);
1546 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1547
1548 req_mt.subtype = MEDIASUBTYPE_PCM;
1549 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1550 ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#lx.\n", hr);
1551
1552 req_mt.subtype = GUID_NULL;
1553 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1554 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1555 ok(compare_media_types(&testsink.sink.pin.mt, source_mt), "Media types didn't match.\n");
1556 IFilterGraph2_Disconnect(graph, source);
1557 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1558
1559 req_mt.formattype = FORMAT_None;
1560 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1561 ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#lx.\n", hr);
1562
1563 req_mt.majortype = MEDIATYPE_Audio;
1564 req_mt.subtype = MEDIASUBTYPE_MPEG1AudioPayload;
1565 req_mt.formattype = GUID_NULL;
1566 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1567 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
1568 if (hr == S_OK)
1569 ok(compare_media_types(&testsink.sink.pin.mt, source_mt), "Media types didn't match.\n");
1570 IFilterGraph2_Disconnect(graph, source);
1571 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1572
1573 req_mt.subtype = MEDIASUBTYPE_PCM;
1574 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1575 ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#lx.\n", hr);
1576
1577 req_mt.subtype = GUID_NULL;
1578 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1579 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1580 ok(compare_media_types(&testsink.sink.pin.mt, source_mt), "Media types didn't match.\n");
1581 IFilterGraph2_Disconnect(graph, source);
1582 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1583
1584 req_mt.majortype = MEDIATYPE_Stream;
1585 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1586 ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#lx.\n", hr);
1587
1588 /* Test enumeration of sink media types. */
1589
1590 testsink.mt = &req_mt;
1591 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, NULL);
1592 ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#lx.\n", hr);
1593
1594 req_mt.majortype = MEDIATYPE_Audio;
1595 req_mt.subtype = MEDIASUBTYPE_MPEG1AudioPayload;
1596 req_mt.formattype = FORMAT_WaveFormatEx;
1597 req_mt.lSampleSize = 444;
1598 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, NULL);
1599 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1600 todo_wine ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "Media types didn't match.\n");
1601
1602 IPin_Release(source);
1603 hr = IFilterGraph2_Disconnect(graph, sink);
1604 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1605 hr = IFilterGraph2_Disconnect(graph, sink);
1606 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1607 ok(testsource.source.pin.peer == sink, "Got peer %p.\n", testsource.source.pin.peer);
1608 IFilterGraph2_Disconnect(graph, &testsource.source.pin.IPin_iface);
1609
1610 CoTaskMemFree(req_mt.pbFormat);
1611 CoTaskMemFree(source_mt->pbFormat);
1613
1614 IAsyncReader_Release(testsource.reader);
1615 IPin_Release(sink);
1616 IMediaControl_Release(control);
1617 ref = IFilterGraph2_Release(graph);
1618 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1619 ref = IBaseFilter_Release(reader);
1620 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1621 ref = IBaseFilter_Release(filter);
1622 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1623 ref = IBaseFilter_Release(&testsource.filter.IBaseFilter_iface);
1624 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1625 ref = IBaseFilter_Release(&testsink.filter.IBaseFilter_iface);
1626 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1628 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
1629}
1630
1631static void test_seeking(void)
1632{
1633 LONGLONG time, current, stop, earliest, latest, duration;
1634 const WCHAR *filename = load_resource(L"test.mp3");
1637 IMediaSeeking *seeking;
1638 unsigned int i;
1639 double rate;
1640 GUID format;
1641 HRESULT hr;
1642 DWORD caps;
1643 ULONG ref;
1644 IPin *pin;
1645 BOOL ret;
1646
1647 static const struct
1648 {
1649 const GUID *guid;
1650 HRESULT hr;
1651 }
1652 format_tests[] =
1653 {
1654 {&TIME_FORMAT_MEDIA_TIME, S_OK},
1655
1656 {&TIME_FORMAT_SAMPLE, S_FALSE},
1657 {&TIME_FORMAT_BYTE, S_FALSE},
1658 {&TIME_FORMAT_NONE, S_FALSE},
1659 {&TIME_FORMAT_FRAME, S_FALSE},
1660 {&TIME_FORMAT_FIELD, S_FALSE},
1661 {&testguid, S_FALSE},
1662 };
1663
1664 IBaseFilter_FindPin(filter, L"Audio", &pin);
1665 IPin_QueryInterface(pin, &IID_IMediaSeeking, (void **)&seeking);
1666
1667 hr = IMediaSeeking_GetCapabilities(seeking, &caps);
1668 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1671 | AM_SEEKING_CanGetDuration), "Got caps %#lx.\n", caps);
1672
1674 hr = IMediaSeeking_CheckCapabilities(seeking, &caps);
1675 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1676 ok(caps == (AM_SEEKING_CanSeekAbsolute | AM_SEEKING_CanSeekForwards), "Got caps %#lx.\n", caps);
1677
1679 hr = IMediaSeeking_CheckCapabilities(seeking, &caps);
1680 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1681 ok(caps == AM_SEEKING_CanSeekAbsolute, "Got caps %#lx.\n", caps);
1682
1684 hr = IMediaSeeking_CheckCapabilities(seeking, &caps);
1685 ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
1686 ok(!caps, "Got caps %#lx.\n", caps);
1687
1688 caps = 0;
1689 hr = IMediaSeeking_CheckCapabilities(seeking, &caps);
1690 ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
1691 ok(!caps, "Got caps %#lx.\n", caps);
1692
1693 for (i = 0; i < ARRAY_SIZE(format_tests); ++i)
1694 {
1695 hr = IMediaSeeking_IsFormatSupported(seeking, format_tests[i].guid);
1696 ok(hr == format_tests[i].hr, "Got hr %#lx for format %s.\n",
1697 hr, wine_dbgstr_guid(format_tests[i].guid));
1698 }
1699
1700 hr = IMediaSeeking_QueryPreferredFormat(seeking, &format);
1701 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1702 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
1703
1704 hr = IMediaSeeking_GetTimeFormat(seeking, &format);
1705 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1706 ok(IsEqualGUID(&format, &TIME_FORMAT_MEDIA_TIME), "Got format %s.\n", wine_dbgstr_guid(&format));
1707
1708 hr = IMediaSeeking_IsUsingTimeFormat(seeking, &TIME_FORMAT_MEDIA_TIME);
1709 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1710 hr = IMediaSeeking_IsUsingTimeFormat(seeking, &TIME_FORMAT_SAMPLE);
1711 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1712
1713 hr = IMediaSeeking_SetTimeFormat(seeking, &TIME_FORMAT_FRAME);
1714 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1715 hr = IMediaSeeking_SetTimeFormat(seeking, &TIME_FORMAT_MEDIA_TIME);
1716 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1717
1718 duration = 0;
1719 hr = IMediaSeeking_GetDuration(seeking, &duration);
1720 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1721 ok(duration >= 5000000 && duration <= 5500000, "Got duration %I64d.\n", duration);
1722
1723 stop = current = 0xdeadbeef;
1724 hr = IMediaSeeking_GetStopPosition(seeking, &stop);
1725 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1726 ok(stop == duration, "Expected time %s, got %s.\n",
1728 hr = IMediaSeeking_GetCurrentPosition(seeking, &current);
1729 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1730 ok(!current, "Got time %s.\n", wine_dbgstr_longlong(current));
1731 stop = current = 0xdeadbeef;
1732 hr = IMediaSeeking_GetPositions(seeking, &current, &stop);
1733 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1734 ok(!current, "Got time %s.\n", wine_dbgstr_longlong(current));
1735 ok(stop == duration, "Expected time %s, got %s.\n",
1737
1738 time = 0xdeadbeef;
1739 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, &TIME_FORMAT_MEDIA_TIME, 0x123456789a, NULL);
1740 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1741 ok(time == 0x123456789a, "Got time %s.\n", wine_dbgstr_longlong(time));
1742 time = 0xdeadbeef;
1743 hr = IMediaSeeking_ConvertTimeFormat(seeking, &time, NULL, 0x123456789a, &TIME_FORMAT_MEDIA_TIME);
1744 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1745 ok(time == 0x123456789a, "Got time %s.\n", wine_dbgstr_longlong(time));
1746
1747 earliest = latest = 0xdeadbeef;
1748 hr = IMediaSeeking_GetAvailable(seeking, &earliest, &latest);
1749 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1750 ok(!earliest, "Got time %s.\n", wine_dbgstr_longlong(earliest));
1751 ok(latest == duration, "Expected time %s, got %s.\n",
1752 wine_dbgstr_longlong(duration), wine_dbgstr_longlong(latest));
1753
1754 rate = 0;
1755 hr = IMediaSeeking_GetRate(seeking, &rate);
1756 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1757 ok(rate == 1.0, "Got rate %.16e.\n", rate);
1758
1759 hr = IMediaSeeking_SetRate(seeking, 200.0);
1760 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
1761 rate = 0;
1762 hr = IMediaSeeking_GetRate(seeking, &rate);
1763 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1764 todo_wine ok(rate == 200.0, "Got rate %.16e.\n", rate);
1765
1766 hr = IMediaSeeking_SetRate(seeking, -1.0);
1767 todo_wine ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
1768
1769 hr = IMediaSeeking_GetPreroll(seeking, &time);
1770 todo_wine ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
1771
1772 current = 200 * 10000;
1773 stop = 400 * 10000;
1774 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning,
1776 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1777 ok(current == 200 * 10000, "Got time %s.\n", wine_dbgstr_longlong(current));
1778 ok(stop == 400 * 10000, "Got time %s.\n", wine_dbgstr_longlong(stop));
1779
1780 stop = current = 0xdeadbeef;
1781 hr = IMediaSeeking_GetPositions(seeking, &current, &stop);
1782 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1783 ok(current == 200 * 10000, "Got time %s.\n", wine_dbgstr_longlong(current));
1784 ok(stop == 400 * 10000, "Got time %s.\n", wine_dbgstr_longlong(stop));
1785
1786 current = 200 * 10000;
1787 stop = 400 * 10000;
1788 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning | AM_SEEKING_ReturnTime,
1790 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1791 ok(current == 200 * 10000, "Got time %s.\n", wine_dbgstr_longlong(current));
1792 ok(stop == 400 * 10000, "Got time %s.\n", wine_dbgstr_longlong(stop));
1793
1794 current = 100 * 10000;
1795 stop = 200 * 10000;
1796 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning | AM_SEEKING_ReturnTime,
1798 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1799 ok(current == 100 * 10000, "Got time %s.\n", wine_dbgstr_longlong(current));
1800 ok(stop == 200 * 10000, "Got time %s.\n", wine_dbgstr_longlong(stop));
1801
1802 current = 50 * 10000;
1803 hr = IMediaSeeking_SetPositions(seeking, &current, AM_SEEKING_AbsolutePositioning,
1805 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1806
1807 stop = current = 0xdeadbeef;
1808 hr = IMediaSeeking_GetPositions(seeking, &current, &stop);
1809 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1810 ok(current == 50 * 10000, "Got time %s.\n", wine_dbgstr_longlong(current));
1811 ok(stop == 200 * 10000, "Got time %s.\n", wine_dbgstr_longlong(stop));
1812
1813 IMediaSeeking_Release(seeking);
1814 IPin_Release(pin);
1815 IFilterGraph2_Release(graph);
1816 ref = IBaseFilter_Release(filter);
1817 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1819 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
1820}
1821
1822static void test_streaming(void)
1823{
1824 const WCHAR *filename = load_resource(L"test.mp3");
1827 struct testfilter testsink;
1829 IMediaSeeking *seeking;
1830 IMediaControl *control;
1831 IPin *source;
1832 HRESULT hr;
1833 ULONG ref;
1834 DWORD ret;
1835
1837 IFilterGraph2_AddFilter(graph, &testsink.filter.IBaseFilter_iface, L"sink");
1838 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
1839 IBaseFilter_FindPin(filter, L"Audio", &source);
1840 IPin_QueryInterface(source, &IID_IMediaSeeking, (void **)&seeking);
1841
1842 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, NULL);
1843 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1844
1845 ok(WaitForSingleObject(testsink.eos_event, 100) == WAIT_TIMEOUT, "Expected timeout.\n");
1846
1847 hr = IMediaControl_Pause(control);
1848 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1849
1850 ok(!WaitForSingleObject(testsink.eos_event, 1000), "Did not receive EOS.\n");
1851 ok(WaitForSingleObject(testsink.eos_event, 100) == WAIT_TIMEOUT, "Got more than one EOS.\n");
1852 ok(testsink.sample_count, "Expected at least one sample.\n");
1853
1854 hr = IMediaControl_Stop(control);
1855 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1856 hr = IMediaControl_Pause(control);
1857 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1858
1859 ok(!WaitForSingleObject(testsink.eos_event, 1000), "Did not receive EOS.\n");
1860 ok(WaitForSingleObject(testsink.eos_event, 100) == WAIT_TIMEOUT, "Got more than one EOS.\n");
1861 ok(testsink.sample_count, "Expected at least one sample.\n");
1862
1863 testsink.new_segment_count = testsink.sample_count = testsink.eos_count = 0;
1864 testsink.segment_start = 100 * 10000;
1865 testsink.segment_end_min = 300 * 10000;
1866 testsink.segment_end_max = 300 * 10000;
1867 hr = IMediaSeeking_SetPositions(seeking, &testsink.segment_start, AM_SEEKING_AbsolutePositioning,
1868 &testsink.segment_end_min, AM_SEEKING_AbsolutePositioning);
1869 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1870
1871 ok(!WaitForSingleObject(testsink.eos_event, 1000), "Did not receive EOS.\n");
1872 ok(WaitForSingleObject(testsink.eos_event, 100) == WAIT_TIMEOUT, "Got more than one EOS.\n");
1873 ok(testsink.sample_count, "Expected at least one sample.\n");
1874
1875 start = end = 0xdeadbeef;
1876 hr = IMediaSeeking_GetPositions(seeking, &start, &end);
1877 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1878 ok(start == testsink.seek_start, "Expected start position %I64u, got %I64u.\n", testsink.seek_start, start);
1879 ok(end == testsink.seek_end, "Expected end position %I64u, got %I64u.\n", testsink.seek_end, end);
1880
1881 hr = IMediaControl_Stop(control);
1882 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1883 hr = IMediaControl_Pause(control);
1884 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1885
1886 ok(!WaitForSingleObject(testsink.eos_event, 1000), "Did not receive EOS.\n");
1887 ok(WaitForSingleObject(testsink.eos_event, 100) == WAIT_TIMEOUT, "Got more than one EOS.\n");
1888 ok(testsink.sample_count, "Expected at least one sample.\n");
1889
1890 start = end = 0xdeadbeef;
1891 hr = IMediaSeeking_GetPositions(seeking, &start, &end);
1892 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1893 ok(start == testsink.seek_start, "Expected start position %I64u, got %I64u.\n", testsink.seek_start, start);
1894 ok(end == testsink.seek_end, "Expected end position %I64u, got %I64u.\n", testsink.seek_end, end);
1895
1896 IMediaSeeking_Release(seeking);
1897 IPin_Release(source);
1898 IMediaControl_Release(control);
1899 ref = IFilterGraph2_Release(graph);
1900 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1901 ref = IBaseFilter_Release(filter);
1902 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1903 ref = IBaseFilter_Release(&testsink.filter.IBaseFilter_iface);
1904 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1906 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
1907}
1908
1909static void test_large_file(void)
1910{
1911 static const BYTE frame[96] = {0xff, 0xfb, 0x14, 0xc4};
1913 static WCHAR path[MAX_PATH];
1914 REFERENCE_TIME duration;
1915 IMediaSeeking *seeking;
1917 unsigned int i;
1918 IPin *source;
1919 BYTE *buffer;
1920 HRESULT hr;
1921 ULONG ref;
1922 DWORD ret;
1923 FILE *f;
1924
1926 wcscat(path, L"big_test.mp3");
1927
1928 /* allocate a larger buffer so I/O is faster on the testbot */
1929 buffer = malloc(1000 * sizeof(frame));
1930 for (i = 0; i < 1000; ++i)
1931 memcpy(buffer + i * 96, frame, sizeof(frame));
1932 f = _wfopen(path, L"w");
1933 for (i = 0; i < 100; ++i)
1934 fwrite(buffer, 1000 * sizeof(frame), 1, f);
1935 fclose(f);
1936 free(buffer);
1937
1939 IBaseFilter_FindPin(filter, L"Audio", &source);
1940 IPin_QueryInterface(source, &IID_IMediaSeeking, (void **)&seeking);
1941
1942 duration = 0xdeadbeef;
1943 hr = IMediaSeeking_GetDuration(seeking, &duration);
1944 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1945 ok(duration == 2400 * 10000000ull, "Got duration %I64d.\n", duration);
1946
1947 IMediaSeeking_Release(seeking);
1948 IPin_Release(source);
1949 ref = IFilterGraph2_Release(graph);
1950 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1951 ref = IBaseFilter_Release(filter);
1952 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1953 ret = DeleteFileW(path);
1954 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
1955}
1956
1958{
1959 AM_MEDIA_TYPE mt_pin, *mt;
1961 IUnknown *unk_video;
1962 IUnknown *unk_audio;
1963 DWORD stream_count;
1965 IPin *pin_video;
1966 IPin *pin_audio;
1967 IUnknown *unk;
1968 DWORD flags;
1969 DWORD group;
1970 LPWSTR name;
1971 HRESULT hr;
1972 LCID lcid;
1973
1974 IAMStreamSelect_QueryInterface(sel, &IID_IBaseFilter, (void **)&filter);
1975 IBaseFilter_FindPin(filter, L"Video", &pin_video);
1976 IBaseFilter_FindPin(filter, L"Audio", &pin_audio);
1977 IPin_QueryInterface(pin_video, &IID_IUnknown, (void **)&unk_video);
1978 IPin_QueryInterface(pin_audio, &IID_IUnknown, (void **)&unk_audio);
1979
1980 hr = IAMStreamSelect_Count(sel, &stream_count);
1981 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1982 ok(stream_count == 2, "Got %lu streams.\n", stream_count);
1983
1984 hr = IAMStreamSelect_Info(sel, 0, &mt, &flags, &lcid, &group, &name, &object, &unk);
1985 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1986 IPin_ConnectionMediaType(pin_video, &mt_pin);
1987 ok(compare_media_types(mt, &mt_pin), "Media types don't match\n");
1988 FreeMediaType(&mt_pin);
1989 todo_wine ok(flags == AMSTREAMSELECTINFO_ENABLED, "Got flags %lx.\n", flags);
1990 ok(lcid == 0, "Got LCID %lx.\n", lcid);
1991 ok(group == 0, "Got group %lx.\n", group);
1992 todo_wine ok(name && !wcscmp(name, L"Stream(E0)"), "Got name %ls.\n", name ? name : L"(null)");
1993 todo_wine ok(object == unk_video, "Got object %p, expected %p.\n", object, unk_video);
1994 ok(unk == NULL, "Got unknown %p.\n", unk);
1996 if (mt)
1998 if (object)
1999 IUnknown_Release(object);
2000
2001 hr = IAMStreamSelect_Info(sel, 1, &mt, &flags, &lcid, &group, &name, &object, &unk);
2002 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2003 IPin_ConnectionMediaType(pin_audio, &mt_pin);
2004 ok(compare_media_types(mt, &mt_pin), "Media types don't match\n");
2005 FreeMediaType(&mt_pin);
2006 todo_wine ok(flags == AMSTREAMSELECTINFO_ENABLED, "Got flags %lx.\n", flags);
2007 ok(lcid == 0, "Got LCID %lx.\n", lcid);
2008 todo_wine ok(group == 1, "Got group %lx.\n", group);
2009 todo_wine ok(name && !wcscmp(name, L"Stream(C0)"), "Got name %ls.\n", name ? name : L"(null)");
2010 todo_wine ok(object == unk_audio, "Got object %p, expected %p.\n", object, unk_audio);
2011 ok(unk == NULL, "Got unknown %p.\n", unk);
2013 if (mt)
2015 if (object)
2016 IUnknown_Release(object);
2017
2018 hr = IAMStreamSelect_Info(sel, 2, &mt, &flags, &lcid, &group, &name, &object, &unk);
2019 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
2020
2021 IBaseFilter_Release(filter);
2022 IUnknown_Release(pin_video);
2023 IUnknown_Release(pin_audio);
2024 IUnknown_Release(unk_video);
2025 IUnknown_Release(unk_audio);
2026}
2027
2028static void test_video_file(void)
2029{
2030 const WCHAR *filename = load_resource(L"test.mpg");
2032 struct testfilter testsink_video;
2033 struct testfilter testsink_audio;
2034 IPin *source_video = NULL;
2035 IPin *source_audio = NULL;
2036 IMediaControl *control;
2038 IAMStreamSelect *sel;
2039 DWORD stream_count;
2040 HRESULT hr;
2041 ULONG ref;
2042 DWORD ret;
2043
2044 IBaseFilter_QueryInterface(filter, &IID_IAMStreamSelect, (void **)&sel);
2045 hr = IAMStreamSelect_Count(sel, &stream_count);
2046 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2047 ok(stream_count == 0, "Got %lu streams.\n", stream_count);
2048
2050 hr = IBaseFilter_FindPin(filter, L"Video", &source_video);
2051 ok(source_video != NULL, "No video pin, hr %#lx.\n", hr);
2052 hr = IBaseFilter_FindPin(filter, L"Audio", &source_audio);
2053 ok(source_audio != NULL, "No audio pin, hr %#lx.\n", hr);
2054
2055 testfilter_init(&testsink_video);
2056 testfilter_init(&testsink_audio);
2057 testsink_video.segment_end_min = 1000000; /* 11232612 on native, 1197000 in Wine */
2058 testsink_video.segment_end_max = 20000000;
2059 testsink_audio.segment_end_min = 1000000;
2060 testsink_audio.segment_end_max = 20000000;
2061
2062 hr = IFilterGraph2_AddFilter(graph, &testsink_video.filter.IBaseFilter_iface, L"sink_video");
2063 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2064 hr = IFilterGraph2_AddFilter(graph, &testsink_audio.filter.IBaseFilter_iface, L"sink_audio");
2065 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2066
2067 hr = IFilterGraph2_ConnectDirect(graph, source_video, &testsink_video.sink.pin.IPin_iface, NULL);
2068 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2069 hr = IFilterGraph2_ConnectDirect(graph, source_audio, &testsink_audio.sink.pin.IPin_iface, NULL);
2070 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2071
2072 test_streamselect(sel);
2073
2074 ok(IsEqualGUID(&testsink_video.sink.pin.mt.majortype, &MEDIATYPE_Video), "Media types didn't match.\n");
2075 ok(IsEqualGUID(&testsink_video.sink.pin.mt.subtype, &MEDIASUBTYPE_MPEG1Payload), "Media types didn't match.\n");
2076 ok(IsEqualGUID(&testsink_video.sink.pin.mt.formattype, &FORMAT_MPEGVideo), "Media types didn't match.\n");
2077
2078 ok(IsEqualGUID(&testsink_audio.sink.pin.mt.majortype, &MEDIATYPE_Audio), "Media types didn't match.\n");
2079 ok(IsEqualGUID(&testsink_audio.sink.pin.mt.subtype, &MEDIASUBTYPE_MPEG1AudioPayload), "Media types didn't match.\n");
2080 ok(IsEqualGUID(&testsink_audio.sink.pin.mt.formattype, &FORMAT_WaveFormatEx), "Media types didn't match.\n");
2081
2082 testsink_video.new_segment_count = 0;
2083 testsink_audio.new_segment_count = 0;
2084 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
2085 hr = IMediaControl_Stop(control);
2086 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2087 hr = IMediaControl_Run(control);
2088 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2089
2090 ok(!WaitForSingleObject(testsink_video.eos_event, 1000), "Video sink did not receive EOS.\n");
2091 ok(!WaitForSingleObject(testsink_audio.eos_event, 1000), "Audio sink did not receive EOS.\n");
2092 ok(testsink_video.new_segment_count == 1, "Video sink got %u segments.\n", testsink_video.new_segment_count);
2093 ok(testsink_audio.new_segment_count == 1, "Audio sink got %u segments.\n", testsink_audio.new_segment_count);
2094
2095 /* Native also supports subtype MEDIASUBTYPE_MPEG1Packet, yielding 1230 and 8828 bytes, respectively */
2096 ok(testsink_video.byte_count == 1214, "Video sink got %u bytes.\n", testsink_video.byte_count);
2097 ok(testsink_audio.byte_count == 8777, "Audio sink got %u bytes.\n", testsink_audio.byte_count);
2098
2099 IAMStreamSelect_Release(sel);
2100 IPin_Release(source_video);
2101 IPin_Release(source_audio);
2102 IMediaControl_Release(control);
2103 ref = IFilterGraph2_Release(graph);
2104 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2105 ref = IBaseFilter_Release(filter);
2106 ok(!ref, "Got outstanding refcount %ld.\n", ref);
2108 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
2109}
2110
2112{
2113 const WCHAR *filename = load_resource(L"test.wav");
2114 IBaseFilter *splitter = create_mpeg_splitter();
2115 IFileSourceFilter *filesource;
2118 IPin *source, *sink;
2119 HRESULT hr;
2120
2121 hr = CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
2122 &IID_IBaseFilter, (void **)&reader);
2123 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2124 hr = IBaseFilter_QueryInterface(reader, &IID_IFileSourceFilter, (void **)&filesource);
2125 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2126 hr = IFileSourceFilter_Load(filesource, filename, NULL);
2127 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2128
2129 hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
2130 &IID_IFilterGraph2, (void **)&graph);
2131 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2132 hr = IFilterGraph2_AddFilter(graph, reader, NULL);
2133 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2134 hr = IFilterGraph2_AddFilter(graph, splitter, NULL);
2135 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2136
2137 hr = IBaseFilter_FindPin(splitter, L"Input", &sink);
2138 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2139 hr = IBaseFilter_FindPin(reader, L"Output", &source);
2140 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2141
2142 hr = IFilterGraph2_ConnectDirect(graph, source, sink, NULL);
2143 ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#lx.\n", hr);
2144
2145 IPin_Release(source);
2146 IPin_Release(sink);
2147 IBaseFilter_Release(reader);
2148 IBaseFilter_Release(splitter);
2149 IFileSourceFilter_Release(filesource);
2150 IFilterGraph2_Release(graph);
2152}
2153
2155{
2157 const WCHAR *filename = load_resource(L"test2.mpg");
2158 struct IFileSourceFilter *filesource;
2159 struct testfilter testsource;
2162 IPin *sink, *source;
2163 HRESULT hr;
2164 BOOL ret;
2165
2166 CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
2167 &IID_IFilterGraph2, (void **)&graph);
2168 testfilter_init(&testsource);
2169 IFilterGraph2_AddFilter(graph, &testsource.filter.IBaseFilter_iface, L"source");
2170 IFilterGraph2_AddFilter(graph, filter, L"splitter");
2171 hr = IBaseFilter_FindPin(filter, L"Input", &sink);
2172 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2173
2174 CoCreateInstance(&CLSID_AsyncReader, NULL, CLSCTX_INPROC_SERVER,
2175 &IID_IBaseFilter, (void **)&reader);
2176 IBaseFilter_QueryInterface(reader, &IID_IFileSourceFilter, (void **)&filesource);
2177 IFileSourceFilter_Load(filesource, filename, NULL);
2178 IFileSourceFilter_Release(filesource);
2179 IBaseFilter_FindPin(reader, L"Output", &source);
2180 IPin_QueryInterface(source, &IID_IAsyncReader, (void **)&testsource.reader);
2181 IAsyncReader_Length(testsource.reader, &total, &avail);
2182 IPin_Release(source);
2183
2184 hr = IFilterGraph2_ConnectDirect(graph, &testsource.source.pin.IPin_iface, sink, NULL);
2185 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2186 ok(testsource.read_position == total, "Got 0x%s, expected 0x%s.\n", wine_dbgstr_longlong(testsource.read_position), wine_dbgstr_longlong(total));
2187
2188 IAsyncReader_Release(testsource.reader);
2189 IPin_Release(sink);
2190 IFilterGraph2_Release(graph);
2191 IBaseFilter_Release(reader);
2192 IBaseFilter_Release(filter);
2193 IBaseFilter_Release(&testsource.filter.IBaseFilter_iface);
2195 ok(ret, "Failed to delete file, error %lu.\n", GetLastError());
2196}
2197
2198START_TEST(mpegsplit)
2199{
2201
2203
2204 if (FAILED(CoCreateInstance(&CLSID_MPEG1Splitter, NULL, CLSCTX_INPROC_SERVER,
2205 &IID_IBaseFilter, (void **)&filter)))
2206 {
2207 skip("Failed to create MPEG-1 splitter.\n");
2208 return;
2209 }
2210 IBaseFilter_Release(filter);
2211
2215 test_find_pin();
2216 test_pin_info();
2221 test_seeking();
2227
2229}
static int avail
Definition: adh-main.c:39
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
unsigned int rate
Definition: audiorecord.c:87
@ AM_SEEKING_CanGetDuration
Definition: axcore.idl:609
@ AM_SEEKING_CanGetCurrentPos
Definition: axcore.idl:607
@ AM_SEEKING_CanSeekBackwards
Definition: axcore.idl:606
@ AM_SEEKING_CanSeekForwards
Definition: axcore.idl:605
@ AM_SEEKING_CanSeekAbsolute
Definition: axcore.idl:604
@ AM_SEEKING_CanGetStopPos
Definition: axcore.idl:608
@ AM_SEEKING_NoPositioning
Definition: axcore.idl:591
@ AM_SEEKING_AbsolutePositioning
Definition: axcore.idl:592
@ AM_SEEKING_ReturnTime
Definition: axcore.idl:597
@ AMSTREAMSELECTINFO_ENABLED
Definition: axcore.idl:675
enum _PinDirection PIN_DIRECTION
@ PINDIR_OUTPUT
Definition: axcore.idl:42
@ PINDIR_INPUT
Definition: axcore.idl:41
#define ARRAY_SIZE(A)
Definition: main.h:20
const GUID IID_IUnknown
const GUID IID_IKsPropertySet
Definition: controlnode.cpp:13
HRESULT expected_hr
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
const GUID IID_IBaseFilter
const GUID IID_IAsyncReader
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
static WCHAR available[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2402
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1674
#define CloseHandle
Definition: compat.h:739
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI WriteFile(_In_ HANDLE hFile, _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer, _In_ DWORD nNumberOfBytesToWrite, _Out_opt_ LPDWORD lpNumberOfBytesWritten, _Inout_opt_ LPOVERLAPPED lpOverlapped)
Definition: rw.c:25
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2098
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
Definition: res.c:176
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
LCID lcid
Definition: locale.c:5660
GUID guid
Definition: version.c:147
int CDECL fclose(FILE *file)
Definition: file.c:3757
FILE *CDECL _wfopen(const wchar_t *path, const wchar_t *mode)
Definition: file.c:4335
size_t CDECL fwrite(const void *ptr, size_t size, size_t nmemb, FILE *file)
Definition: file.c:4129
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
size_t total
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLuint index
Definition: glext.h:6031
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLboolean GLuint group
Definition: glext.h:11120
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: axcore.idl:92
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
#define f
Definition: ke_i.h:83
#define wine_dbgstr_w
Definition: kernel32.h:34
#define GUID_NULL
Definition: ks.h:106
int winetest_debug
#define todo_wine_if(is_todo)
Definition: minitest.h:81
#define todo_wine
Definition: minitest.h:80
__u16 time
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define MPEGLAYER3_FLAG_PADDING_OFF
Definition: mmreg.h:447
#define MPEGLAYER3_FLAG_PADDING_ISO
Definition: mmreg.h:445
#define ACM_MPEG_PROTECTIONBIT
Definition: mmreg.h:427
#define MPEGLAYER3_ID_MPEG
Definition: mmreg.h:442
#define WAVE_FORMAT_MPEG
Definition: mmreg.h:126
#define WAVE_FORMAT_MPEGLAYER3
Definition: mmreg.h:127
#define ACM_MPEG_SINGLECHANNEL
Definition: mmreg.h:423
#define ACM_MPEG_LAYER3
Definition: mmreg.h:418
struct mpeglayer3waveformat_tag MPEGLAYER3WAVEFORMAT
#define ACM_MPEG_LAYER2
Definition: mmreg.h:417
struct mpeg1waveformat_tag MPEG1WAVEFORMAT
#define ACM_MPEG_ID_MPEG1
Definition: mmreg.h:428
#define ACM_MPEG_ORIGINALHOME
Definition: mmreg.h:426
struct task_struct * current
Definition: linux.c:32
#define CREATE_ALWAYS
Definition: disk.h:72
static PVOID ptr
Definition: dispmode.c:27
#define load_resource(a, b, c)
Definition: font.c:46
static const WCHAR pathW[]
Definition: path.c:2368
#define expect_ref(obj, ref)
Definition: metadata.c:40
static void test_video_file(void)
Definition: mpegsplit.c:2028
static void test_no_acceptable_type(void)
Definition: mpegsplit.c:2111
static IBaseFilter * create_mpeg_splitter(void)
Definition: mpegsplit.c:30
static HRESULT WINAPI async_reader_WaitForNext(IAsyncReader *iface, DWORD timeout, IMediaSample **sample, DWORD_PTR *cookie)
Definition: mpegsplit.c:1309
static void test_video_read_position(void)
Definition: mpegsplit.c:2154
static HRESULT WINAPI async_reader_SyncRead(IAsyncReader *iface, LONGLONG position, LONG length, BYTE *buffer)
Definition: mpegsplit.c:1320
static BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b)
Definition: mpegsplit.c:39
static HRESULT testsink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
Definition: mpegsplit.c:1170
static void testfilter_destroy(struct strmbase_filter *iface)
Definition: mpegsplit.c:1105
static const IUnknownVtbl outer_vtbl
Definition: mpegsplit.c:206
static HRESULT WINAPI async_reader_SyncReadAligned(IAsyncReader *iface, IMediaSample *sample)
Definition: mpegsplit.c:1315
static const struct strmbase_sink_ops testsink_ops
Definition: mpegsplit.c:1268
static const GUID MEDIASUBTYPE_mp3
Definition: mpegsplit.c:28
static void test_aggregation(void)
Definition: mpegsplit.c:215
static HRESULT testsink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: mpegsplit.c:1194
static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
Definition: mpegsplit.c:109
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: mpegsplit.c:196
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
Definition: mpegsplit.c:183
static HRESULT WINAPI async_reader_Length(IAsyncReader *iface, LONGLONG *total, LONGLONG *available)
Definition: mpegsplit.c:1327
static struct testfilter * impl_from_strmbase_filter(struct strmbase_filter *iface)
Definition: mpegsplit.c:1090
static ULONG get_refcount(void *iface)
Definition: mpegsplit.c:70
static const struct IAsyncReaderVtbl async_reader_vtbl
Definition: mpegsplit.c:1342
static HRESULT WINAPI async_reader_BeginFlush(IAsyncReader *iface)
Definition: mpegsplit.c:1332
static void test_large_file(void)
Definition: mpegsplit.c:1909
static void test_pin_info(void)
Definition: mpegsplit.c:452
static HRESULT WINAPI async_reader_EndFlush(IAsyncReader *iface)
Definition: mpegsplit.c:1337
static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
Definition: mpegsplit.c:1131
static IUnknown test_outer
Definition: mpegsplit.c:213
static HRESULT WINAPI async_reader_RequestAllocator(IAsyncReader *iface, IMemAllocator *preferred, ALLOCATOR_PROPERTIES *props, IMemAllocator **allocator)
Definition: mpegsplit.c:1298
static void test_find_pin(void)
Definition: mpegsplit.c:400
static IFilterGraph2 * connect_input(IBaseFilter *splitter, const WCHAR *filename)
Definition: mpegsplit.c:77
static HRESULT testsink_new_segment(struct strmbase_sink *iface, REFERENCE_TIME start, REFERENCE_TIME end, double rate)
Definition: mpegsplit.c:1243
static ULONG WINAPI async_reader_Release(IAsyncReader *iface)
Definition: mpegsplit.c:1293
static HRESULT testsink_eos(struct strmbase_sink *iface)
Definition: mpegsplit.c:1230
static const struct strmbase_source_ops testsource_ops
Definition: mpegsplit.c:1164
static void test_enum_media_types(void)
Definition: mpegsplit.c:833
static HRESULT WINAPI async_reader_Request(IAsyncReader *iface, IMediaSample *sample, DWORD_PTR cookie)
Definition: mpegsplit.c:1304
static void test_interfaces(void)
Definition: mpegsplit.c:123
static void test_connect_pin(void)
Definition: mpegsplit.c:1370
static void test_media_types(void)
Definition: mpegsplit.c:523
static HRESULT WINAPI testsource_AttemptConnection(struct strmbase_source *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: mpegsplit.c:1144
static struct strmbase_pin * testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
Definition: mpegsplit.c:1095
static void test_enum_pins(void)
Definition: mpegsplit.c:274
static HRESULT testfilter_init_stream(struct strmbase_filter *iface)
Definition: mpegsplit.c:1114
static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample *sample)
Definition: mpegsplit.c:1202
static ULONG WINAPI async_reader_AddRef(IAsyncReader *iface)
Definition: mpegsplit.c:1288
static void test_seeking(void)
Definition: mpegsplit.c:1631
static void test_streamselect(IAMStreamSelect *sel)
Definition: mpegsplit.c:1957
static HRESULT WINAPI async_reader_QueryInterface(IAsyncReader *iface, REFIID iid, void **out)
Definition: mpegsplit.c:1283
static const GUID testguid
Definition: mpegsplit.c:27
static void test_streaming(void)
Definition: mpegsplit.c:1822
#define check_interface(a, b, c)
Definition: mpegsplit.c:108
static LONG outer_ref
Definition: mpegsplit.c:181
static const struct strmbase_filter_ops testfilter_ops
Definition: mpegsplit.c:1124
static void test_unconnected_filter_state(void)
Definition: mpegsplit.c:1020
static const GUID test_iid
Definition: mpegsplit.c:180
static struct testfilter * impl_from_IAsyncReader(IAsyncReader *iface)
Definition: mpegsplit.c:1278
static HRESULT testsink_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt)
Definition: mpegsplit.c:1183
static void testfilter_init(struct testfilter *filter)
Definition: mpegsplit.c:1357
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: mpegsplit.c:201
const CLSID * clsid
Definition: msctf.cpp:50
#define GENERIC_WRITE
Definition: nt_native.h:90
short WCHAR
Definition: pedump.c:58
#define RT_RCDATA
Definition: pedump.c:372
long LONG
Definition: pedump.c:60
const GUID IID_IPin
Definition: pincontrol.cpp:15
const GUID IID_IPersist
Definition: proxy.cpp:14
const GUID IID_IPersistPropertyBag
Definition: proxy.cpp:11
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define offsetof(TYPE, MEMBER)
DWORD LCID
Definition: nls.h:13
wcscat
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
#define memset(x, y, z)
Definition: compat.h:39
HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
Definition: mediatype.c:150
void WINAPI FreeMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: mediatype.c:165
void strmbase_source_init(struct strmbase_source *pin, struct strmbase_filter *filter, const WCHAR *name, const struct strmbase_source_ops *func_table)
Definition: pin.c:765
void strmbase_sink_cleanup(struct strmbase_sink *pin)
Definition: pin.c:1185
void strmbase_sink_init(struct strmbase_sink *pin, struct strmbase_filter *filter, const WCHAR *name, const struct strmbase_sink_ops *ops, IMemAllocator *allocator)
Definition: pin.c:1168
void strmbase_filter_cleanup(struct strmbase_filter *filter)
Definition: filter.c:540
void strmbase_source_cleanup(struct strmbase_source *pin)
Definition: pin.c:778
void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer, const CLSID *clsid, const struct strmbase_filter_ops *func_table)
Definition: filter.c:517
void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: mediatype.c:193
WORD wFormatTag
Definition: mmreg.h:78
Definition: dialog.c:52
Definition: cookie.c:34
Definition: fci.c:123
Definition: filter.c:165
IBaseFilter * filter
Definition: filtergraph.c:75
LONG eos_count
Definition: filter.c:181
Definition: graph.c:32
Definition: parser.c:49
WORD fwHeadModeExt
Definition: mmreg.h:409
WAVEFORMATEX wfx
Definition: mmreg.h:405
WAVEFORMATEX wfx
Definition: mmreg.h:431
Definition: name.c:39
Definition: reader.h:84
Definition: send.c:48
Definition: wave.c:25
struct strmbase_filter * filter
Definition: strmbase.h:58
struct strmbase_pin pin
Definition: strmbase.h:106
struct strmbase_pin pin
Definition: strmbase.h:79
LONGLONG read_position
Definition: mpegsplit.c:1087
IAsyncReader IAsyncReader_iface
Definition: avisplit.c:808
REFERENCE_TIME seek_end
Definition: avisplit.c:812
struct strmbase_sink sink
REFERENCE_TIME seek_start
Definition: avisplit.c:812
unsigned int eos_count
Definition: avisplit.c:811
IAsyncReader * reader
Definition: avisplit.c:808
REFERENCE_TIME segment_start
Definition: avisplit.c:812
AM_MEDIA_TYPE source_mt
REFERENCE_TIME segment_end_max
Definition: mpegsplit.c:1086
WCHAR * name
Definition: filtergraph.c:851
HANDLE eos_event
Definition: avisplit.c:810
const AM_MEDIA_TYPE * mt
Definition: avidec.c:799
IFilterGraph * graph
Definition: filtergraph.c:850
unsigned int new_segment_count
Definition: avisplit.c:811
unsigned int byte_count
Definition: mpegsplit.c:1085
struct strmbase_source source
Definition: amstream.c:1020
REFERENCE_TIME segment_end_min
Definition: mpegsplit.c:1086
struct strmbase_filter filter
Definition: amstream.c:1019
unsigned int sample_count
Definition: avisplit.c:811
struct strmbase_sink pin
Definition: filesource.c:1211
struct strmbase_filter filter
Definition: filesource.c:1210
const AM_MEDIA_TYPE * mt
Definition: filesource.c:1214
Definition: dhcpd.h:248
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint16_t * LPWSTR
Definition: typedefs.h:56
int64_t LONGLONG
Definition: typedefs.h:68
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define VFW_E_SAMPLE_TIME_NOT_SET
Definition: vfwmsgs.h:104
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81
#define VFW_E_NOT_STOPPED
Definition: vfwmsgs.h:75
#define VFW_E_NO_ACCEPTABLE_TYPES
Definition: vfwmsgs.h:46
#define VFW_S_NO_MORE_ITEMS
Definition: vfwmsgs.h:19
#define VFW_E_NOT_FOUND
Definition: vfwmsgs.h:61
#define VFW_E_NOT_CONNECTED
Definition: vfwmsgs.h:48
static const WCHAR props[]
Definition: wbemdisp.c:288
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
unsigned char BYTE
Definition: xxhash.c:193