ReactOS 0.4.17-dev-934-g091855f
mpegvideo.c
Go to the documentation of this file.
1/*
2 * MPEG video decoder filter unit tests
3 *
4 * Copyright 2022 Anton Baskanov
5 * Copyright 2018 Zebediah Figura
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#define COBJMACROS
23#include "dshow.h"
24#include "mmreg.h"
25#include "ks.h"
26#include "ksmedia.h"
27#include "wine/strmbase.h"
28#include "wine/test.h"
29
30/* same as normal MPEG1VIDEOINFO, except bSequenceHeader is 12 bytes */
31typedef struct tagMPEG1VIDEOINFO_12 {
37
39{
40 .hdr.rcSource = { 0, 0, 32, 24 },
41 .hdr.rcTarget = { 0, 0, 0, 0 },
42 .hdr.dwBitRate = 0,
43 .hdr.dwBitErrorRate = 0,
44 .hdr.AvgTimePerFrame = 400000, /* 25fps, 40ms */
45 .hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
46 .hdr.bmiHeader.biWidth = 32,
47 .hdr.bmiHeader.biHeight = 24,
48 .hdr.bmiHeader.biPlanes = 0,
49 .hdr.bmiHeader.biBitCount = 0,
50 .hdr.bmiHeader.biCompression = 0,
51 .hdr.bmiHeader.biSizeImage = 0,
52 .hdr.bmiHeader.biXPelsPerMeter = 2000,
53 .hdr.bmiHeader.biYPelsPerMeter = 2000,
54 .hdr.bmiHeader.biClrUsed = 0,
55 .hdr.bmiHeader.biClrImportant = 0,
56 .dwStartTimeCode = 4096,
57 .cbSequenceHeader = 12,
58 .bSequenceHeader = { 0x00, 0x00, 0x01, 0xb3, 0x02, 0x00, 0x18, 0x13, 0xff, 0xff, 0xe0, 0x18 },
59};
60
61static const AM_MEDIA_TYPE mpeg_mt =
62{
63 /* MEDIATYPE_Video, MEDIASUBTYPE_MPEG1Payload, FORMAT_MPEGVideo */
64 .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
65 .subtype = {0xe436eb81, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}},
66 .bFixedSizeSamples = TRUE,
67 .lSampleSize = 1,
68 .formattype = {0x05589f82, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
69 .cbFormat = sizeof(MPEG1VIDEOINFO_12),
70 .pbFormat = (BYTE *)&mpg_format,
71};
72
74{
75 .rcSource = { 0, 0, 32, 24 },
76 .rcTarget = { 0, 0, 0, 0 },
77 .dwBitRate = 32 * 24 * 16 * 25,
78 .dwBitErrorRate = 0,
79 .AvgTimePerFrame = 400000,
80 .bmiHeader.biSize = sizeof(BITMAPINFOHEADER),
81 .bmiHeader.biWidth = 32,
82 .bmiHeader.biHeight = 24,
83 .bmiHeader.biPlanes = 1,
84 .bmiHeader.biBitCount = 16,
85 .bmiHeader.biCompression = MAKEFOURCC('Y','U','Y','2'),
86 .bmiHeader.biSizeImage = 32 * 24 * 16 / 8,
87 .bmiHeader.biXPelsPerMeter = 2000,
88 .bmiHeader.biYPelsPerMeter = 2000,
89};
90
91static const AM_MEDIA_TYPE yuy2_mt =
92{
93 /* MEDIATYPE_Video, MEDIASUBTYPE_YUY2, FORMAT_VideoInfo */
94 .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
95 .subtype = {0x32595559, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}},
96 .bFixedSizeSamples = TRUE,
97 .lSampleSize = 32 * 24 * 16 / 8,
98 .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}},
99 .cbFormat = sizeof(VIDEOINFOHEADER),
100 .pbFormat = (BYTE *)&yuy2_format,
101};
102
104{
106 HRESULT hr = CoCreateInstance(&CLSID_CMpegVideoCodec, NULL, CLSCTX_INPROC_SERVER,
107 &IID_IBaseFilter, (void **)&filter);
108 ok(hr == S_OK, "Got hr %#lx.\n", hr);
109 return filter;
110}
111
113{
114 return !memcmp(a, b, offsetof(AM_MEDIA_TYPE, pbFormat))
115 && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat);
116}
117
118static const struct
119{
120 const GUID *subtype;
125}
126video_types[] =
127{
128 /* native's EnumMediaTypes offers YV12, but that media type refuses to connect */
129 /* Wine doesn't enumerate unsupported ones (Y41P and RGB8) at all */
130 { &MEDIASUBTYPE_YV12, 12, MAKEFOURCC('Y','V','1','2'), FALSE, TRUE },
131 { &MEDIASUBTYPE_Y41P, 12, MAKEFOURCC('Y','4','1','P'), TRUE, FALSE },
132 { &MEDIASUBTYPE_YUY2, 16, MAKEFOURCC('Y','U','Y','2'), TRUE, TRUE },
133 { &MEDIASUBTYPE_UYVY, 16, MAKEFOURCC('U','Y','V','Y'), TRUE, TRUE },
134 { &MEDIASUBTYPE_RGB24, 24, BI_RGB, TRUE, TRUE },
135 { &MEDIASUBTYPE_RGB32, 32, BI_RGB, TRUE, TRUE },
136 { &MEDIASUBTYPE_RGB565, 16, BI_BITFIELDS, TRUE, TRUE },
137 { &MEDIASUBTYPE_RGB555, 16, BI_RGB, TRUE, TRUE },
138 { &MEDIASUBTYPE_RGB8, 8, BI_RGB, TRUE, FALSE },
140
141static void init_video_mt(AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format, unsigned type_idx)
142{
143 memcpy(mt, &yuy2_mt, sizeof(AM_MEDIA_TYPE));
145 mt->subtype = *video_types[type_idx].subtype;
146 mt->pbFormat = (BYTE*)format;
147 format->bmiHeader.biBitCount = video_types[type_idx].bits_per_pixel;
148 format->bmiHeader.biCompression = video_types[type_idx].compression;
149 format->bmiHeader.biSizeImage = format->bmiHeader.biBitCount * format->bmiHeader.biWidth * format->bmiHeader.biHeight / 8;
150 format->dwBitRate = format->bmiHeader.biSizeImage*8 * 25;
151 mt->lSampleSize = format->bmiHeader.biSizeImage;
152 if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_RGB8))
153 format->bmiHeader.biClrUsed = 0x100;
154}
155
156static ULONG get_refcount(void *iface)
157{
158 IUnknown *unknown = iface;
159 IUnknown_AddRef(unknown);
160 return IUnknown_Release(unknown);
161}
162
163#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
164static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
165{
166 IUnknown *iface = iface_ptr;
168 IUnknown *unk;
169
170 expected_hr = supported ? S_OK : E_NOINTERFACE;
171
172 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
173 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
174 if (SUCCEEDED(hr))
175 IUnknown_Release(unk);
176}
177
178static void test_interfaces(void)
179{
181 IPin *pin;
182
184 check_interface(filter, &IID_IMediaFilter, TRUE);
187
188 check_interface(filter, &IID_IAMFilterMiscFlags, FALSE);
189 check_interface(filter, &IID_IBasicAudio, FALSE);
190 check_interface(filter, &IID_IBasicVideo, FALSE);
192 check_interface(filter, &IID_IMediaPosition, FALSE);
193 check_interface(filter, &IID_IMediaSeeking, FALSE);
195 check_interface(filter, &IID_IQualityControl, FALSE);
196 check_interface(filter, &IID_IQualProp, FALSE);
197 check_interface(filter, &IID_IReferenceClock, FALSE);
198 check_interface(filter, &IID_IVideoWindow, FALSE);
200
201 IBaseFilter_FindPin(filter, L"In", &pin);
202
203 check_interface(pin, &IID_IMemInputPin, TRUE);
205 check_interface(pin, &IID_IQualityControl, TRUE);
207
208 check_interface(pin, &IID_IMediaPosition, FALSE);
209 check_interface(pin, &IID_IMediaSeeking, FALSE);
210
211 IPin_Release(pin);
212
213 IBaseFilter_FindPin(filter, L"Out", &pin);
214
216 check_interface(pin, &IID_IMediaPosition, TRUE);
217 check_interface(pin, &IID_IMediaSeeking, TRUE);
218 check_interface(pin, &IID_IQualityControl, TRUE);
220
222
223 IPin_Release(pin);
224
225 IBaseFilter_Release(filter);
226}
227
228static const GUID test_iid = {0x33333333};
229static LONG outer_ref = 1;
230
232{
233 if (IsEqualGUID(iid, &IID_IUnknown)
235 || IsEqualGUID(iid, &test_iid))
236 {
237 *out = (IUnknown *)0xdeadbeef;
238 return S_OK;
239 }
240 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
241 return E_NOINTERFACE;
242}
243
245{
247}
248
250{
252}
253
254static const IUnknownVtbl outer_vtbl =
255{
259};
260
262
263static void test_aggregation(void)
264{
265 IBaseFilter *filter, *filter2;
266 IUnknown *unk, *unk2;
267 HRESULT hr;
268 ULONG ref;
269
270 filter = (IBaseFilter *)0xdeadbeef;
271 hr = CoCreateInstance(&CLSID_CMpegVideoCodec, &test_outer, CLSCTX_INPROC_SERVER,
272 &IID_IBaseFilter, (void **)&filter);
273 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
274 ok(!filter, "Got interface %p.\n", filter);
275
276 hr = CoCreateInstance(&CLSID_CMpegVideoCodec, &test_outer, CLSCTX_INPROC_SERVER,
277 &IID_IUnknown, (void **)&unk);
278 ok(hr == S_OK, "Got hr %#lx.\n", hr);
279 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
280 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
281 ref = get_refcount(unk);
282 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
283
284 ref = IUnknown_AddRef(unk);
285 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
286 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
287
288 ref = IUnknown_Release(unk);
289 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
290 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
291
292 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
293 ok(hr == S_OK, "Got hr %#lx.\n", hr);
294 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
295 IUnknown_Release(unk2);
296
297 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
298 ok(hr == S_OK, "Got hr %#lx.\n", hr);
299
300 hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
301 ok(hr == S_OK, "Got hr %#lx.\n", hr);
302 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
303
304 hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
305 ok(hr == S_OK, "Got hr %#lx.\n", hr);
306 ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
307
308 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
309 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
310 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
311
312 hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
313 ok(hr == S_OK, "Got hr %#lx.\n", hr);
314 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
315
316 IBaseFilter_Release(filter);
317 ref = IUnknown_Release(unk);
318 ok(!ref, "Got unexpected refcount %ld.\n", ref);
319 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
320}
321
323{
325 FILTER_STATE state;
326 HRESULT hr;
327 ULONG ref;
328
329 hr = IBaseFilter_GetState(filter, 0, &state);
330 ok(hr == S_OK, "Got hr %#lx.\n", hr);
331 ok(state == State_Stopped, "Got state %u.\n", state);
332
333 hr = IBaseFilter_Pause(filter);
334 ok(hr == S_OK, "Got hr %#lx.\n", hr);
335
336 hr = IBaseFilter_GetState(filter, 0, &state);
337 ok(hr == S_OK, "Got hr %#lx.\n", hr);
338 ok(state == State_Paused, "Got state %u.\n", state);
339
340 hr = IBaseFilter_Run(filter, 0);
341 ok(hr == S_OK, "Got hr %#lx.\n", hr);
342
343 hr = IBaseFilter_GetState(filter, 0, &state);
344 ok(hr == S_OK, "Got hr %#lx.\n", hr);
345 ok(state == State_Running, "Got state %u.\n", state);
346
347 hr = IBaseFilter_Pause(filter);
348 ok(hr == S_OK, "Got hr %#lx.\n", hr);
349
350 hr = IBaseFilter_GetState(filter, 0, &state);
351 ok(hr == S_OK, "Got hr %#lx.\n", hr);
352 ok(state == State_Paused, "Got state %u.\n", state);
353
354 hr = IBaseFilter_Stop(filter);
355 ok(hr == S_OK, "Got hr %#lx.\n", hr);
356
357 hr = IBaseFilter_GetState(filter, 0, &state);
358 ok(hr == S_OK, "Got hr %#lx.\n", hr);
359 ok(state == State_Stopped, "Got state %u.\n", state);
360
361 hr = IBaseFilter_Run(filter, 0);
362 ok(hr == S_OK, "Got hr %#lx.\n", hr);
363
364 hr = IBaseFilter_GetState(filter, 0, &state);
365 ok(hr == S_OK, "Got hr %#lx.\n", hr);
366 ok(state == State_Running, "Got state %u.\n", state);
367
368 hr = IBaseFilter_Stop(filter);
369 ok(hr == S_OK, "Got hr %#lx.\n", hr);
370
371 hr = IBaseFilter_GetState(filter, 0, &state);
372 ok(hr == S_OK, "Got hr %#lx.\n", hr);
373 ok(state == State_Stopped, "Got state %u.\n", state);
374
375 ref = IBaseFilter_Release(filter);
376 ok(!ref, "Got outstanding refcount %ld.\n", ref);
377}
378
379static void test_enum_pins(void)
380{
382 IEnumPins *enum1, *enum2;
383 ULONG count, ref;
384 IPin *pins[3];
385 HRESULT hr;
386
388 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
389
390 hr = IBaseFilter_EnumPins(filter, NULL);
391 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
392
393 hr = IBaseFilter_EnumPins(filter, &enum1);
394 ok(hr == S_OK, "Got hr %#lx.\n", hr);
396 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
397 ref = get_refcount(enum1);
398 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
399
400 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
401 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
402
403 hr = IEnumPins_Next(enum1, 1, pins, NULL);
404 ok(hr == S_OK, "Got hr %#lx.\n", hr);
406 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
407 ref = get_refcount(pins[0]);
408 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
409 ref = get_refcount(enum1);
410 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
411 IPin_Release(pins[0]);
413 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
414
415 hr = IEnumPins_Next(enum1, 1, pins, NULL);
416 ok(hr == S_OK, "Got hr %#lx.\n", hr);
418 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
419 ref = get_refcount(pins[0]);
420 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
421 ref = get_refcount(enum1);
422 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
423 IPin_Release(pins[0]);
425 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
426
427 hr = IEnumPins_Next(enum1, 1, pins, NULL);
428 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
429
430 hr = IEnumPins_Reset(enum1);
431 ok(hr == S_OK, "Got hr %#lx.\n", hr);
432
433 hr = IEnumPins_Next(enum1, 1, pins, &count);
434 ok(hr == S_OK, "Got hr %#lx.\n", hr);
435 ok(count == 1, "Got count %lu.\n", count);
436 IPin_Release(pins[0]);
437
438 hr = IEnumPins_Next(enum1, 1, pins, &count);
439 ok(hr == S_OK, "Got hr %#lx.\n", hr);
440 ok(count == 1, "Got count %lu.\n", count);
441 IPin_Release(pins[0]);
442
443 hr = IEnumPins_Next(enum1, 1, pins, &count);
444 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
445 ok(!count, "Got count %lu.\n", count);
446
447 hr = IEnumPins_Reset(enum1);
448 ok(hr == S_OK, "Got hr %#lx.\n", hr);
449
450 hr = IEnumPins_Next(enum1, 2, pins, NULL);
451 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
452
453 hr = IEnumPins_Next(enum1, 2, pins, &count);
454 ok(hr == S_OK, "Got hr %#lx.\n", hr);
455 ok(count == 2, "Got count %lu.\n", count);
456 IPin_Release(pins[0]);
457 IPin_Release(pins[1]);
458
459 hr = IEnumPins_Next(enum1, 2, pins, &count);
460 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
461 ok(!count, "Got count %lu.\n", count);
462
463 hr = IEnumPins_Reset(enum1);
464 ok(hr == S_OK, "Got hr %#lx.\n", hr);
465
466 hr = IEnumPins_Next(enum1, 3, pins, &count);
467 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
468 ok(count == 2, "Got count %lu.\n", count);
469 IPin_Release(pins[0]);
470 IPin_Release(pins[1]);
471
472 hr = IEnumPins_Reset(enum1);
473 ok(hr == S_OK, "Got hr %#lx.\n", hr);
474
475 hr = IEnumPins_Clone(enum1, &enum2);
476 ok(hr == S_OK, "Got hr %#lx.\n", hr);
477
478 hr = IEnumPins_Skip(enum1, 3);
479 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
480
481 hr = IEnumPins_Skip(enum1, 2);
482 ok(hr == S_OK, "Got hr %#lx.\n", hr);
483
484 hr = IEnumPins_Skip(enum1, 1);
485 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
486
487 hr = IEnumPins_Next(enum1, 1, pins, NULL);
488 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
489
490 hr = IEnumPins_Next(enum2, 1, pins, NULL);
491 ok(hr == S_OK, "Got hr %#lx.\n", hr);
492 IPin_Release(pins[0]);
493
494 IEnumPins_Release(enum2);
495 IEnumPins_Release(enum1);
496 ref = IBaseFilter_Release(filter);
497 ok(!ref, "Got outstanding refcount %ld.\n", ref);
498}
499
500static void test_find_pin(void)
501{
504 IPin *pin, *pin2;
505 HRESULT hr;
506 ULONG ref;
507
508 hr = IBaseFilter_EnumPins(filter, &enum_pins);
509 ok(hr == S_OK, "Got hr %#lx.\n", hr);
510
511 hr = IBaseFilter_FindPin(filter, L"In", &pin);
512 ok(hr == S_OK, "Got hr %#lx.\n", hr);
513 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
514 ok(hr == S_OK, "Got hr %#lx.\n", hr);
515 ok(pin == pin2, "Pins didn't match.\n");
516 IPin_Release(pin);
517 IPin_Release(pin2);
518
519 hr = IBaseFilter_FindPin(filter, L"Out", &pin);
520 ok(hr == S_OK, "Got hr %#lx.\n", hr);
521 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
522 ok(hr == S_OK, "Got hr %#lx.\n", hr);
523 ok(pin == pin2, "Pins didn't match.\n");
524 IPin_Release(pin);
525 IPin_Release(pin2);
526
527 hr = IBaseFilter_FindPin(filter, L"XForm In", &pin);
528 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
529 hr = IBaseFilter_FindPin(filter, L"XForm Out", &pin);
530 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
531 hr = IBaseFilter_FindPin(filter, L"input pin", &pin);
532 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
533 hr = IBaseFilter_FindPin(filter, L"output pin", &pin);
534 ok(hr == VFW_E_NOT_FOUND, "Got hr %#lx.\n", hr);
535
536 IEnumPins_Release(enum_pins);
537 ref = IBaseFilter_Release(filter);
538 ok(!ref, "Got outstanding refcount %ld.\n", ref);
539}
540
541static void test_pin_info(void)
542{
546 HRESULT hr;
547 WCHAR *id;
548 ULONG ref;
549 IPin *pin;
550
551 hr = IBaseFilter_FindPin(filter, L"In", &pin);
552 ok(hr == S_OK, "Got hr %#lx.\n", hr);
554 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
555 ref = get_refcount(pin);
556 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
557
558 hr = IPin_QueryPinInfo(pin, &info);
559 ok(hr == S_OK, "Got hr %#lx.\n", hr);
560 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
561 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
562 ok(!wcscmp(info.achName, L"Input"), "Got name %s.\n", debugstr_w(info.achName));
564 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
565 ref = get_refcount(pin);
566 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
567 IBaseFilter_Release(info.pFilter);
568
569 hr = IPin_QueryDirection(pin, &dir);
570 ok(hr == S_OK, "Got hr %#lx.\n", hr);
571 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
572
573 hr = IPin_QueryId(pin, &id);
574 ok(hr == S_OK, "Got hr %#lx.\n", hr);
575 ok(!wcscmp(id, L"In"), "Got id %s.\n", wine_dbgstr_w(id));
576 CoTaskMemFree(id);
577
578 hr = IPin_QueryInternalConnections(pin, NULL, NULL);
579 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
580
581 IPin_Release(pin);
582
583 hr = IBaseFilter_FindPin(filter, L"Out", &pin);
584 ok(hr == S_OK, "Got hr %#lx.\n", hr);
585 hr = IPin_QueryPinInfo(pin, &info);
586 ok(hr == S_OK, "Got hr %#lx.\n", hr);
587 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
588 ok(info.dir == PINDIR_OUTPUT, "Got direction %d.\n", info.dir);
589 ok(!wcscmp(info.achName, L"Output"), "Got name %s.\n", debugstr_w(info.achName));
590 IBaseFilter_Release(info.pFilter);
591
592 hr = IPin_QueryDirection(pin, &dir);
593 ok(hr == S_OK, "Got hr %#lx.\n", hr);
594 ok(dir == PINDIR_OUTPUT, "Got direction %d.\n", dir);
595
596 hr = IPin_QueryId(pin, &id);
597 ok(hr == S_OK, "Got hr %#lx.\n", hr);
598 ok(!wcscmp(id, L"Out"), "Got id %s.\n", wine_dbgstr_w(id));
599 CoTaskMemFree(id);
600
601 hr = IPin_QueryInternalConnections(pin, NULL, NULL);
602 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
603
604 IPin_Release(pin);
605
606 ref = IBaseFilter_Release(filter);
607 ok(!ref, "Got outstanding refcount %ld.\n", ref);
608}
609
610static void test_enum_media_types(void)
611{
613 IEnumMediaTypes *enum1, *enum2;
614 AM_MEDIA_TYPE *mts[1];
615 ULONG ref, count;
616 HRESULT hr;
617 IPin *pin;
618
619 IBaseFilter_FindPin(filter, L"In", &pin);
620
621 hr = IPin_EnumMediaTypes(pin, &enum1);
622 ok(hr == S_OK, "Got hr %#lx.\n", hr);
623
624 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
625 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
626
627 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
628 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
629 ok(!count, "Got count %lu.\n", count);
630
631 hr = IEnumMediaTypes_Reset(enum1);
632 ok(hr == S_OK, "Got hr %#lx.\n", hr);
633
634 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
635 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
636
637 hr = IEnumMediaTypes_Clone(enum1, &enum2);
638 ok(hr == S_OK, "Got hr %#lx.\n", hr);
639
640 hr = IEnumMediaTypes_Skip(enum1, 1);
641 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
642
643 hr = IEnumMediaTypes_Next(enum2, 1, mts, NULL);
644 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
645
646 IEnumMediaTypes_Release(enum1);
647 IEnumMediaTypes_Release(enum2);
648 IPin_Release(pin);
649
650 IBaseFilter_FindPin(filter, L"Out", &pin);
651
652 hr = IPin_EnumMediaTypes(pin, &enum1);
653 ok(hr == S_OK, "Got hr %#lx.\n", hr);
654
655 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
656 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
657
658 hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
659 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
660 ok(!count, "Got count %lu.\n", count);
661
662 hr = IEnumMediaTypes_Reset(enum1);
663 ok(hr == S_OK, "Got hr %#lx.\n", hr);
664
665 hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
666 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
667
668 hr = IEnumMediaTypes_Clone(enum1, &enum2);
669 ok(hr == S_OK, "Got hr %#lx.\n", hr);
670
671 hr = IEnumMediaTypes_Skip(enum1, 1);
672 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
673
674 hr = IEnumMediaTypes_Next(enum2, 1, mts, NULL);
675 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
676
677 IEnumMediaTypes_Release(enum1);
678 IEnumMediaTypes_Release(enum2);
679 IPin_Release(pin);
680
681 ref = IBaseFilter_Release(filter);
682 ok(!ref, "Got outstanding refcount %ld.\n", ref);
683}
684
685static void test_media_types(void)
686{
688 AM_MEDIA_TYPE mt;
689 HRESULT hr;
690 ULONG ref;
691 IPin *pin;
692
693 IBaseFilter_FindPin(filter, L"In", &pin);
694
695 hr = IPin_QueryAccept(pin, &mpeg_mt);
696 ok(hr == S_OK, "Got hr %#lx.\n", hr);
697
698 mt = mpeg_mt;
699 mt.subtype = MEDIASUBTYPE_MPEG1Packet;
700 hr = IPin_QueryAccept(pin, &mt);
701 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
702
703 mt = mpeg_mt;
704 mt.subtype = GUID_NULL;
705 hr = IPin_QueryAccept(pin, &mt);
706 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
707
708 IPin_Release(pin);
709
710 IBaseFilter_FindPin(filter, L"Out", &pin);
711
712 hr = IPin_QueryAccept(pin, &yuy2_mt);
713 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
714
715 IPin_Release(pin);
716
717 ref = IBaseFilter_Release(filter);
718 ok(!ref, "Got outstanding refcount %ld.\n", ref);
719}
720
721struct testqc
722{
730};
731
733{
734 return CONTAINING_RECORD(iface, struct testqc, IQualityControl_iface);
735}
736
738{
739 struct testqc *qc = impl_from_IQualityControl(iface);
740 return IUnknown_QueryInterface(qc->outer_unk, iid, out);
741}
742
744{
745 struct testqc *qc = impl_from_IQualityControl(iface);
746 return IUnknown_AddRef(qc->outer_unk);
747}
748
750{
751 struct testqc *qc = impl_from_IQualityControl(iface);
752 return IUnknown_Release(qc->outer_unk);
753}
754
756{
757 struct testqc *qc = impl_from_IQualityControl(iface);
758
759 qc->notify_sender = sender;
760 qc->notify_quality = q;
761
762 return qc->notify_hr;
763}
764
766{
767 ok(0, "Unexpected call.\n");
768 return E_NOTIMPL;
769}
770
771static const IQualityControlVtbl testqc_vtbl =
772{
778};
779
781{
782 return CONTAINING_RECORD(iface, struct testqc, IUnknown_inner);
783}
784
786{
787 struct testqc *qc = impl_from_qc_IUnknown(iface);
788
789 if (IsEqualIID(iid, &IID_IUnknown))
790 *out = iface;
791 else if (IsEqualIID(iid, &IID_IQualityControl))
793 else
794 return E_NOINTERFACE;
795
796 IUnknown_AddRef((IUnknown *)*out);
797 return S_OK;
798}
799
801{
802 struct testqc *qc = impl_from_qc_IUnknown(iface);
803 return InterlockedIncrement(&qc->refcount);
804}
805
807{
808 struct testqc *qc = impl_from_qc_IUnknown(iface);
809 return InterlockedDecrement(&qc->refcount);
810}
811
812static const IUnknownVtbl testqc_inner_vtbl =
813{
817};
818
819static void testqc_init(struct testqc *qc, IUnknown *outer)
820{
821 memset(qc, 0, sizeof(*qc));
823 qc->IUnknown_inner.lpVtbl = &testqc_inner_vtbl;
824 qc->outer_unk = outer ? outer : &qc->IUnknown_inner;
825}
826
827struct testfilter
828{
829 struct strmbase_filter filter;
830 struct strmbase_source source;
831 struct strmbase_sink sink;
832 struct testqc *qc;
833 const AM_MEDIA_TYPE *mt;
837};
838
839static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
840{
841 return CONTAINING_RECORD(iface, struct testfilter, filter);
842}
843
844static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
845{
847 if (!index)
848 return &filter->source.pin;
849 return NULL;
850}
851
852static void testfilter_destroy(struct strmbase_filter *iface)
853{
858}
859
861{
862 .filter_get_pin = testfilter_get_pin,
863 .filter_destroy = testfilter_destroy,
864};
865
866static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
867{
868 return E_NOINTERFACE;
869}
870
873{
874 return S_OK;
875}
876
878{
879 .base.pin_query_interface = testsource_query_interface,
880 .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
881 .pfnDecideAllocator = testsource_DecideAllocator,
882};
883
884static HRESULT testsink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
885{
887
888 if (IsEqualGUID(iid, &IID_IMemInputPin))
889 *out = &filter->sink.IMemInputPin_iface;
890 else
891 return E_NOINTERFACE;
892
893 IUnknown_AddRef((IUnknown *)*out);
894 return S_OK;
895}
896
898{
900 if (!index && filter->mt)
901 {
902 CopyMediaType(mt, filter->mt);
903 return S_OK;
904 }
905 return VFW_S_NO_MORE_ITEMS;
906}
907
908static HRESULT testsink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
909{
910 struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
911 if (filter->mt && !IsEqualGUID(&mt->majortype, &filter->mt->majortype))
913 return S_OK;
914}
915
917{
918 struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
919 REFERENCE_TIME start, stop;
920 AM_MEDIA_TYPE *mt = (AM_MEDIA_TYPE *)0xdeadbeef;
921 HRESULT hr;
922 LONG size;
923
924 size = IMediaSample_GetSize(sample);
925 ok(size == filter->sink.pin.mt.lSampleSize, "Got size %lu, expected %lu.\n", size, filter->sink.pin.mt.lSampleSize);
926 size = IMediaSample_GetActualDataLength(sample);
927 ok(size == filter->sink.pin.mt.lSampleSize, "Got actual size %lu, expected %lu.\n", size, filter->sink.pin.mt.lSampleSize);
928 ok(IMediaSample_GetActualDataLength(sample) <= IMediaSample_GetSize(sample), "Buffer overflow");
929
930 start = 0xdeadbeef;
931 stop = 0xdeadbeef;
932 hr = IMediaSample_GetTime(sample, &start, &stop);
933 ok(hr == S_OK, "Got hr %#lx.\n", hr);
934
935 hr = IMediaSample_GetMediaType(sample, &mt);
936 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
937 if (mt)
939
940 if (filter->got_sample == 0 && filter->expected_start_time != (REFERENCE_TIME)-1)
941 {
942 ok(start == filter->expected_start_time, "Got start time %s, expected %s.\n",
943 wine_dbgstr_longlong(start), wine_dbgstr_longlong(filter->expected_start_time));
945 ok(stop == filter->expected_stop_time, "Got stop time %s, expected %s.\n",
946 wine_dbgstr_longlong(stop), wine_dbgstr_longlong(filter->expected_stop_time));
947 }
948
949 ++filter->got_sample;
950
951 return S_OK;
952}
953
956{
957 struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
958 ++filter->got_new_segment;
959 ok(start == 10000, "Got start %s.\n", wine_dbgstr_longlong(start));
960 ok(stop == 20000, "Got stop %s.\n", wine_dbgstr_longlong(stop));
961 ok(rate == 1.0, "Got rate %.16e.\n", rate);
962 return S_OK;
963}
964
965static HRESULT testsink_eos(struct strmbase_sink *iface)
966{
967 struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
968 ++filter->got_eos;
969 return S_OK;
970}
971
973{
974 struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
975 ++filter->got_begin_flush;
976 return S_OK;
977}
978
980{
981 struct testfilter *filter = impl_from_strmbase_filter(iface->pin.filter);
982 ++filter->got_end_flush;
983 return S_OK;
984}
985
986static const struct strmbase_sink_ops testsink_ops =
987{
988 .base.pin_query_interface = testsink_query_interface,
989 .base.pin_get_media_type = testsink_get_media_type,
990 .sink_connect = testsink_connect,
991 .pfnReceive = testsink_Receive,
992 .sink_new_segment = testsink_new_segment,
993 .sink_eos = testsink_eos,
994 .sink_begin_flush = testsink_begin_flush,
995 .sink_end_flush = testsink_end_flush,
996};
997
999{
1000 static const GUID clsid = {0xabacab};
1001 memset(filter, 0, sizeof(*filter));
1003 strmbase_source_init(&filter->source, &filter->filter, L"source", &testsource_ops);
1005}
1006
1008{
1009 IMemAllocator *req_allocator, *ret_allocator;
1010 ALLOCATOR_PROPERTIES props, ret_props;
1011 HRESULT hr;
1012
1013 hr = IMemInputPin_GetAllocatorRequirements(input, &props);
1014 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
1015
1016 hr = IMemInputPin_GetAllocator(input, &ret_allocator);
1017 todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
1018
1019 if (hr == S_OK)
1020 {
1021 hr = IMemAllocator_GetProperties(ret_allocator, &props);
1022 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1023 ok(!props.cBuffers, "Got %ld buffers.\n", props.cBuffers);
1024 ok(!props.cbBuffer, "Got size %ld.\n", props.cbBuffer);
1025 ok(!props.cbAlign, "Got alignment %ld.\n", props.cbAlign);
1026 ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
1027
1028 hr = IMemInputPin_NotifyAllocator(input, ret_allocator, TRUE);
1029 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1030 IMemAllocator_Release(ret_allocator);
1031 }
1032
1033 hr = IMemInputPin_NotifyAllocator(input, NULL, TRUE);
1034 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
1035
1036 CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
1037 &IID_IMemAllocator, (void **)&req_allocator);
1038
1039 props.cBuffers = 1;
1040 props.cbBuffer = 256;
1041 props.cbAlign = 1;
1042 props.cbPrefix = 0;
1043 hr = IMemAllocator_SetProperties(req_allocator, &props, &ret_props);
1044 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1045
1046 hr = IMemInputPin_NotifyAllocator(input, req_allocator, TRUE);
1047 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1048
1049 hr = IMemInputPin_GetAllocator(input, &ret_allocator);
1050 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1051 ok(ret_allocator == req_allocator, "Allocators didn't match.\n");
1052
1053 IMemAllocator_Release(req_allocator);
1054 IMemAllocator_Release(ret_allocator);
1055}
1056
1058 IPin *sink, IPin *source, struct testfilter *testsource, struct testfilter *testsink,
1059 unsigned type_idx, BOOL should_work)
1060{
1061 ALLOCATOR_PROPERTIES props, req_props = {2, 30000, 32, 0};
1065 AM_MEDIA_TYPE mt;
1066 HRESULT hr;
1067
1068 hr = IFilterGraph2_ConnectDirect(graph, &testsource->source.pin.IPin_iface, sink, &mpeg_mt);
1069 ok(hr == S_OK, "(%u) Got hr %#lx.\n", type_idx, hr);
1070
1071 init_video_mt(&mt, &format, type_idx);
1072 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink->sink.pin.IPin_iface, &mt);
1073 if (!should_work)
1074 {
1075 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "(%u) Got hr %#lx.\n", type_idx, hr);
1076 IFilterGraph2_Disconnect(graph, sink);
1077 IFilterGraph2_Disconnect(graph, &testsource->source.pin.IPin_iface);
1078 return;
1079 }
1080 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1081
1082 ok(!!testsink->sink.pAllocator, "Expected an allocator.\n");
1083 hr = IMemAllocator_GetProperties(testsink->sink.pAllocator, &props);
1084 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1085 ok(props.cBuffers == 1, "Got %ld buffers.\n", props.cBuffers);
1086 ok(props.cbBuffer == mt.lSampleSize, "Got size %ld.\n", props.cbBuffer);
1087 ok(props.cbAlign == 1, "Got alignment %ld.\n", props.cbAlign);
1088 ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
1089
1090 hr = IMemAllocator_GetBuffer(testsink->sink.pAllocator, &sample, NULL, NULL, 0);
1091 ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#lx.\n", hr);
1092
1093 hr = IMediaControl_Pause(control);
1094 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1095
1096 hr = IMemAllocator_GetBuffer(testsink->sink.pAllocator, &sample, NULL, NULL, 0);
1097 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1098 if (hr == S_OK)
1099 IMediaSample_Release(sample);
1100
1101 hr = IMediaControl_Stop(control);
1102 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1103
1104 hr = IMemAllocator_GetBuffer(testsink->sink.pAllocator, &sample, NULL, NULL, 0);
1105 ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#lx.\n", hr);
1106
1107 IFilterGraph2_Disconnect(graph, source);
1108 IFilterGraph2_Disconnect(graph, &testsink->sink.pin.IPin_iface);
1109
1110 init_video_mt(&mt, &format, type_idx);
1111 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink->sink.pin.IPin_iface, &mt);
1112 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1113
1114 ok(!!testsink->sink.pAllocator, "Expected an allocator.\n");
1115 hr = IMemAllocator_GetProperties(testsink->sink.pAllocator, &props);
1116 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1117 ok(props.cBuffers == 1, "Got %ld buffers.\n", props.cBuffers);
1118 ok(props.cbBuffer == mt.lSampleSize, "Got size %ld.\n", props.cbBuffer);
1119 ok(props.cbAlign == 1, "Got alignment %ld.\n", props.cbAlign);
1120 ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
1121
1122 IFilterGraph2_Disconnect(graph, source);
1123 IFilterGraph2_Disconnect(graph, &testsink->sink.pin.IPin_iface);
1124
1125 CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
1126 &IID_IMemAllocator, (void **)&allocator);
1127 testsink->sink.pAllocator = allocator;
1128
1129 hr = IMemAllocator_SetProperties(allocator, &req_props, &props);
1130 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1131
1132 init_video_mt(&mt, &format, type_idx);
1133 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink->sink.pin.IPin_iface, &mt);
1134 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1135
1136 ok(testsink->sink.pAllocator == allocator, "Expected an allocator.\n");
1137 hr = IMemAllocator_GetProperties(testsink->sink.pAllocator, &props);
1138 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1139 ok(props.cBuffers == 1, "Got %ld buffers.\n", props.cBuffers);
1140 ok(props.cbBuffer == mt.lSampleSize, "Got size %ld.\n", props.cbBuffer);
1141 ok(props.cbAlign == 1, "Got alignment %ld.\n", props.cbAlign);
1142 ok(!props.cbPrefix, "Got prefix %ld.\n", props.cbPrefix);
1143
1144 IFilterGraph2_Disconnect(graph, source);
1145 IFilterGraph2_Disconnect(graph, &testsink->sink.pin.IPin_iface);
1146
1147 IFilterGraph2_Disconnect(graph, sink);
1148 IFilterGraph2_Disconnect(graph, &testsource->source.pin.IPin_iface);
1149}
1150
1152 IPin *sink, IPin *source, struct testfilter *testsource, struct testfilter *testsink)
1153{
1154 struct testqc testsource_qc;
1155 IQualityControl *source_qc;
1156 IQualityControl *sink_qc;
1157 Quality quality = {0};
1158 struct testqc qc;
1159 HRESULT hr;
1160
1161 testqc_init(&testsource_qc, testsource->filter.outer_unk);
1162 testqc_init(&qc, NULL);
1163
1164 testsource->qc = &testsource_qc;
1165
1166 hr = IPin_QueryInterface(sink, &IID_IQualityControl, (void **)&sink_qc);
1167 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1168 hr = IPin_QueryInterface(source, &IID_IQualityControl, (void **)&source_qc);
1169 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1170
1171 hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
1172 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1173
1174 hr = IFilterGraph2_ConnectDirect(graph, &testsource->source.pin.IPin_iface, sink, &mpeg_mt);
1175 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1176
1177 testsource_qc.notify_sender = (IBaseFilter *)0xdeadbeef;
1178 hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
1179 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1180 ok(testsource_qc.notify_sender == (IBaseFilter *)0xdeadbeef, "Got sender %p.\n",
1181 testsource_qc.notify_sender);
1182
1183 hr = IQualityControl_SetSink(sink_qc, &qc.IQualityControl_iface);
1184 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1185 qc.notify_sender = (IBaseFilter *)0xdeadbeef;
1186 hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
1187 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1188 ok(qc.notify_sender == (IBaseFilter *)0xdeadbeef, "Got sender %p.\n", qc.notify_sender);
1189
1190 qc.notify_hr = E_FAIL;
1191 hr = IQualityControl_Notify(source_qc, &testsink->filter.IBaseFilter_iface, quality);
1192 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1193 qc.notify_hr = S_OK;
1194
1195 IFilterGraph2_Disconnect(graph, sink);
1196 IFilterGraph2_Disconnect(graph, &testsource->source.pin.IPin_iface);
1197
1198 IQualityControl_Release(source_qc);
1199 IQualityControl_Release(sink_qc);
1200
1201 testsource->qc = NULL;
1202}
1203
1205{
1206 BYTE *target_data;
1207 HRESULT hr;
1208 LONG size;
1209 hr = IMediaSample_GetPointer(sample, &target_data);
1210 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1211 size = IMediaSample_GetSize(sample);
1212 ok(size >= len, "Got size %ld, expected at least %ld.\n", size, len);
1213
1214 memcpy(target_data, data, len);
1215 hr = IMediaSample_SetActualDataLength(sample, len);
1216 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1217
1218 hr = IMemInputPin_Receive(input, sample);
1219 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1220}
1221
1223{
1224 /* gst-launch-1.0 -v videotestsrc pattern=black num-buffers=10 ! video/x-raw,width=32,height=24 ! mpeg2enc ! filesink location=empty-es2.mpg */
1225 /* then truncate to taste */
1226 /* each 00 00 01 b3 or 00 00 01 00 starts a new frame, except the first 00 00 01 00 after a 00 00 01 b3 */
1227 static const BYTE empty_mpg_frames[] = {
1228 0x00, 0x00, 0x01, 0xb3, 0x02, 0x00, 0x18, 0x15, 0x02, 0xbf, 0x60, 0x9c,
1229 0x00, 0x00, 0x01, 0xb8, 0x00, 0x08, 0x00, 0x40,
1230 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0xff, 0xf8,
1231 0x00, 0x00, 0x01, 0x01, 0x0b, 0xf8, 0x7d, 0x29, 0x48, 0x8b, 0x94, 0xa5, 0x22, 0x20,
1232 0x00, 0x00, 0x01, 0x02, 0x0b, 0xf8, 0x7d, 0x2e, 0x7d, 0x2f, 0xcf, 0xc1, 0x04, 0x03, 0xa0, 0x11, 0xb1,
1233 0x41, 0x28, 0x88, 0x13, 0xb9, 0x6f, 0xcf, 0xc1, 0x04, 0x03, 0xa0, 0x11, 0xb1, 0x41, 0x28, 0x88,
1234 0x13, 0xb9, 0x6f, 0xa1, 0x4b, 0x9f, 0x48, 0x04, 0x10, 0x0e, 0x80, 0x46, 0xc5, 0x04, 0xa2,
1235 0x20, 0x4e, 0xe5, 0x80, 0x41, 0x00, 0xe8, 0x04, 0x6c, 0x50, 0x4a, 0x22, 0x04, 0xee, 0x58,
1236 0x00, 0x00, 0x01, 0x00, 0x00, 0x57, 0xff, 0xf9, 0x80,
1237 0x00, 0x00, 0x01, 0x01, 0x0a, 0x79, 0xc0,
1238 0x00, 0x00, 0x01, 0x02, 0x0a, 0x79, 0xc0,
1239 0x00, 0x00, 0x01, 0x00, 0x00, 0x97, 0xff, 0xf9, 0x80,
1240 0x00, 0x00, 0x01, 0x01, 0x0a, 0x79, 0xc0,
1241 0x00, 0x00, 0x01, 0x02, 0x0a, 0x79, 0xc0,
1242 };
1243 static const BYTE empty_mpg_eos[] = {
1244 0x00, 0x00, 0x01, 0xb7,
1245 };
1246 HRESULT hr;
1247 IPin *pin;
1248
1249 /* native won't emit anything until an unknown-sized internal buffer is filled, or EOS is announced */
1250 test_send_sample(input, sample, empty_mpg_frames, ARRAY_SIZE(empty_mpg_frames));
1251 test_send_sample(input, sample, empty_mpg_eos, ARRAY_SIZE(empty_mpg_eos));
1252
1253 hr = IMemInputPin_QueryInterface(input, &IID_IPin, (void **)&pin);
1254 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1255 hr = IPin_EndOfStream(pin);
1256 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1257 IPin_Release(pin);
1258}
1259
1260static void test_sample_processing(IMediaControl *control, IMemInputPin *input, struct testfilter *sink)
1261{
1262 REFERENCE_TIME start, stop;
1265 HRESULT hr;
1266 IPin *pin;
1267 LONG size;
1268
1269 sink->got_sample = 0;
1270 sink->got_eos = 0;
1271
1272 hr = IMemInputPin_QueryInterface(input, &IID_IPin, (void **)&pin);
1273 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1274
1275 hr = IMemInputPin_ReceiveCanBlock(input);
1276 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1277
1278 hr = IMemInputPin_GetAllocator(input, &allocator);
1279 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1280
1281 hr = IMediaControl_Pause(control);
1282 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1283
1284 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
1285 ok(hr == VFW_E_NOT_COMMITTED, "Got hr %#lx.\n", hr);
1286
1287 hr = IMemAllocator_Commit(allocator);
1288 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1289 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
1290 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1291
1292 size = IMediaSample_GetSize(sample);
1293 ok(size == 256, "Got size %ld.\n", size);
1294
1295 hr = IMediaSample_SetTime(sample, NULL, NULL);
1296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1297
1298 sink->expected_start_time = 0;
1299 sink->expected_stop_time = 0;
1300 hr = IMediaSample_SetTime(sample, &sink->expected_start_time, &sink->expected_stop_time);
1301 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1302
1304 ok(sink->got_sample >= 1, "Got %u calls to Receive().\n", sink->got_sample);
1305 ok(sink->got_eos == 1, "Got %u calls to EndOfStream().\n", sink->got_eos);
1306 sink->got_sample = 0;
1307 sink->got_eos = 0;
1308
1309 hr = IMediaControl_Stop(control);
1310 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1311 hr = IMediaControl_Pause(control);
1312 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1313
1314 start = 22222;
1315 hr = IMediaSample_SetTime(sample, &start, NULL);
1316 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1317
1318 sink->expected_start_time = -1; /* native returns start and stop 0xff80000000000001 */
1320 ok(sink->got_sample >= 1, "Got %u calls to Receive().\n", sink->got_sample);
1321 ok(sink->got_eos == 1, "Got %u calls to EndOfStream().\n", sink->got_eos);
1322 sink->got_sample = 0;
1323 sink->got_eos = 0;
1324
1325 hr = IMediaControl_Stop(control);
1326 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1327 hr = IMediaControl_Pause(control);
1328 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1329
1330 start = 22222;
1331 stop = 33333;
1332 hr = IMediaSample_SetTime(sample, &start, &stop);
1333 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1334
1335 sink->expected_start_time = 22222;
1336 sink->expected_stop_time = 22222;
1338 ok(sink->got_sample >= 1, "Got %u calls to Receive().\n", sink->got_sample);
1339 ok(sink->got_eos == 1, "Got %u calls to EndOfStream().\n", sink->got_eos);
1340 sink->got_sample = 0;
1341 sink->got_eos = 0;
1342
1343 hr = IMediaControl_Stop(control);
1344 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1345
1346 hr = IMemInputPin_Receive(input, sample);
1347 ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
1348
1349 hr=IMemAllocator_Decommit(allocator);
1350 IPin_Release(pin);
1351 IMediaSample_Release(sample);
1352 IMemAllocator_Release(allocator);
1353}
1354
1355static void test_streaming_events(IMediaControl *control, IPin *sink,
1357{
1358 REFERENCE_TIME start, stop;
1361 HRESULT hr;
1362 IPin *pin;
1363
1364 testsink->got_new_segment = 0;
1365 testsink->got_sample = 0;
1366 testsink->got_eos = 0;
1367 testsink->got_begin_flush = 0;
1368 testsink->got_end_flush = 0;
1369
1370 hr = IMemInputPin_QueryInterface(input, &IID_IPin, (void **)&pin);
1371 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1372
1373 hr = IMediaControl_Pause(control);
1374 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1375
1376 hr = IMemInputPin_GetAllocator(input, &allocator);
1377 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1378 hr = IMemAllocator_Commit(allocator);
1379 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1380 hr = IMemAllocator_GetBuffer(allocator, &sample, NULL, NULL, 0);
1381 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1382
1383 start = 0;
1384 stop = 120000;
1385 hr = IMediaSample_SetTime(sample, &start, &stop);
1386 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1387
1388 ok(!testsink->got_new_segment, "Got %u calls to IPin::NewSegment().\n", testsink->got_new_segment);
1389 hr = IPin_NewSegment(sink, 10000, 20000, 1.0);
1390 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1391 ok(testsink->got_new_segment == 1, "Got %u calls to IPin::NewSegment().\n", testsink->got_new_segment);
1392
1393 ok(!testsink->got_eos, "Got %u calls to IPin::EndOfStream().\n", testsink->got_eos);
1394 hr = IPin_EndOfStream(sink);
1395 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1396 ok(!testsink->got_sample, "Got %u calls to Receive().\n", testsink->got_sample);
1397 ok(testsink->got_eos == 1, "Got %u calls to IPin::EndOfStream().\n", testsink->got_eos);
1398 testsink->got_eos = 0;
1399
1400 hr = IPin_EndOfStream(sink);
1401 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1402 ok(testsink->got_eos == 1, "Got %u calls to IPin::EndOfStream().\n", testsink->got_eos);
1403
1404 testsink->expected_start_time = 0;
1405 testsink->expected_stop_time = 0;
1407 ok(testsink->got_sample >= 1, "Got %u calls to Receive().\n", testsink->got_sample);
1408 testsink->got_sample = 0;
1409
1410 ok(!testsink->got_begin_flush, "Got %u calls to IPin::BeginFlush().\n", testsink->got_begin_flush);
1411 hr = IPin_BeginFlush(sink);
1412 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1413 ok(testsink->got_begin_flush == 1, "Got %u calls to IPin::BeginFlush().\n", testsink->got_begin_flush);
1414
1415 hr = IMemInputPin_Receive(input, sample);
1416 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1417
1418 hr = IPin_EndOfStream(sink);
1419 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1420
1421 ok(!testsink->got_end_flush, "Got %u calls to IPin::EndFlush().\n", testsink->got_end_flush);
1422 hr = IPin_EndFlush(sink);
1423 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1424 ok(testsink->got_end_flush == 1, "Got %u calls to IPin::EndFlush().\n", testsink->got_end_flush);
1425
1426 hr = IMediaControl_Stop(control);
1427 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1428 hr = IMediaControl_Pause(control);
1429 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1430
1431 testsink->expected_start_time = 0;
1432 testsink->expected_stop_time = 0;
1434 ok(testsink->got_sample >= 1, "Got %u calls to Receive().\n", testsink->got_sample);
1435 testsink->got_sample = 0;
1436
1437 hr = IMediaControl_Stop(control);
1438 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1439
1440 IMemAllocator_Decommit(allocator);
1441 IPin_Release(pin);
1442 IMediaSample_Release(sample);
1443 IMemAllocator_Release(allocator);
1444}
1445
1446static void test_connect_pin(void)
1447{
1449 struct testfilter testsource, testsink;
1450 AM_MEDIA_TYPE mt, source_mt, *pmt;
1451 IPin *sink, *source, *peer;
1452 VIDEOINFOHEADER req_format;
1453 IEnumMediaTypes *enummt;
1454 IMediaControl *control;
1455 IMemInputPin *meminput;
1456 AM_MEDIA_TYPE req_mt;
1458 unsigned int i;
1459 HRESULT hr;
1460 ULONG ref;
1461
1462 CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
1463 &IID_IFilterGraph2, (void **)&graph);
1464 testfilter_init(&testsource);
1466 IFilterGraph2_AddFilter(graph, &testsink.filter.IBaseFilter_iface, L"sink");
1467 IFilterGraph2_AddFilter(graph, &testsource.filter.IBaseFilter_iface, L"source");
1468 IFilterGraph2_AddFilter(graph, filter, L"MPEG video decoder");
1469 IBaseFilter_FindPin(filter, L"In", &sink);
1470 IBaseFilter_FindPin(filter, L"Out", &source);
1471 IPin_QueryInterface(sink, &IID_IMemInputPin, (void **)&meminput);
1472 IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
1473
1475
1476 for (i=0;i<ARRAY_SIZE(video_types);++i)
1477 {
1478 BOOL should_work;
1479 if (winetest_platform_is_wine) should_work = video_types[i].works_wine;
1480 else should_work = video_types[i].works_native;
1481 test_source_allocator(graph, control, sink, source, &testsource, &testsink, i, should_work);
1482 }
1483
1484 /* Test sink connection. */
1485
1486 peer = (IPin *)0xdeadbeef;
1487 hr = IPin_ConnectedTo(sink, &peer);
1488 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1489 ok(!peer, "Got peer %p.\n", peer);
1490
1491 hr = IPin_ConnectionMediaType(sink, &mt);
1492 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1493
1494 hr = IMediaControl_Pause(control);
1495 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1496 hr = IFilterGraph2_ConnectDirect(graph, &testsource.source.pin.IPin_iface, sink, &mpeg_mt);
1497 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
1498 hr = IMediaControl_Stop(control);
1499 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1500
1501 req_mt = mpeg_mt;
1502 req_mt.subtype = MEDIASUBTYPE_RGB24;
1503 hr = IFilterGraph2_ConnectDirect(graph, &testsource.source.pin.IPin_iface, sink, &req_mt);
1504 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1505
1506 hr = IFilterGraph2_ConnectDirect(graph, &testsource.source.pin.IPin_iface, sink, &mpeg_mt);
1507 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1508
1509 hr = IPin_ConnectedTo(sink, &peer);
1510 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1511 ok(peer == &testsource.source.pin.IPin_iface, "Got peer %p.\n", peer);
1512 IPin_Release(peer);
1513
1514 hr = IPin_ConnectionMediaType(sink, &mt);
1515 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1516 ok(compare_media_types(&mt, &mpeg_mt), "Media types didn't match.\n");
1517 ok(compare_media_types(&testsource.source.pin.mt, &mpeg_mt), "Media types didn't match.\n");
1518 FreeMediaType(&mt);
1519
1520 hr = IPin_QueryAccept(source, &yuy2_mt);
1521 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1522
1523 req_mt = yuy2_mt;
1524 req_mt.majortype = GUID_NULL;
1525 hr = IPin_QueryAccept(source, &req_mt);
1526 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1527
1528 req_mt = yuy2_mt;
1529 req_mt.subtype = GUID_NULL;
1530 hr = IPin_QueryAccept(source, &req_mt);
1531 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1532
1533 for (i=0;i<ARRAY_SIZE(video_types);++i)
1534 {
1535 init_video_mt(&req_mt, &req_format, i);
1536 hr = IPin_QueryAccept(source, &req_mt);
1538 continue;
1540 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1541 }
1542
1543 req_mt = yuy2_mt;
1544 req_mt.formattype = GUID_NULL;
1545 hr = IPin_QueryAccept(source, &req_mt);
1546 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1547
1548 hr = IMediaControl_Pause(control);
1549 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1550 hr = IFilterGraph2_Disconnect(graph, sink);
1551 ok(hr == VFW_E_NOT_STOPPED, "Got hr %#lx.\n", hr);
1552 hr = IMediaControl_Stop(control);
1553 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1554
1555 test_sink_allocator(meminput);
1556
1557 hr = IPin_EnumMediaTypes(source, &enummt);
1558 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1559
1560 i = 0;
1561 while (i < ARRAY_SIZE(video_types))
1562 {
1563 VIDEOINFOHEADER expect_format;
1564 AM_MEDIA_TYPE expect_mt;
1565
1566 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
1567 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1568 while (IsEqualGUID(&pmt->formattype, &FORMAT_VideoInfo2))
1569 {
1570 DeleteMediaType(pmt);
1571 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
1572 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1573 }
1574
1575 init_video_mt(&expect_mt, &expect_format, i);
1576
1577 ok(!memcmp(pmt, &expect_mt, offsetof(AM_MEDIA_TYPE, cbFormat)),
1578 "%u: Media types didn't match.\n", i);
1579 ok(!memcmp(pmt->pbFormat, &expect_format, sizeof(VIDEOINFOHEADER)),
1580 "%u: Format blocks didn't match.\n", i);
1581 DeleteMediaType(pmt);
1582
1583 ++i;
1585 ++i;
1586 }
1587
1588 hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
1589 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1590 IEnumMediaTypes_Release(enummt);
1591
1592 /* Test source connection. */
1593
1594 peer = (IPin *)0xdeadbeef;
1595 hr = IPin_ConnectedTo(source, &peer);
1596 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1597 ok(!peer, "Got peer %p.\n", peer);
1598
1599 hr = IPin_ConnectionMediaType(source, &mt);
1600 ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#lx.\n", hr);
1601
1602 /* Exact connection. */
1603
1604 for (i=0;i<ARRAY_SIZE(video_types);i++)
1605 {
1607 continue;
1608
1609 hr = IMediaControl_Pause(control);
1610 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1611 init_video_mt(&req_mt, &req_format, i);
1612 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1613 ok(hr == VFW_E_NOT_STOPPED, "%u: Got hr %#lx.\n", i, hr);
1614 hr = IMediaControl_Stop(control);
1615 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1616
1617 init_video_mt(&req_mt, &req_format, i);
1618 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1620 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1621 if (hr != S_OK)
1622 continue;
1623
1624 hr = IPin_ConnectedTo(source, &peer);
1625 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1626 ok(peer == &testsink.sink.pin.IPin_iface, "%u: Got peer %p.\n", i, peer);
1627 IPin_Release(peer);
1628
1629 hr = IPin_ConnectionMediaType(source, &mt);
1630 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1631 ok(compare_media_types(&mt, &req_mt), "%u: Media types didn't match.\n", i);
1632 ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "%u: Media types didn't match.\n", i);
1633 FreeMediaType(&mt);
1634
1635 hr = IMediaControl_Pause(control);
1636 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1637 hr = IFilterGraph2_Disconnect(graph, source);
1638 ok(hr == VFW_E_NOT_STOPPED, "%u: Got hr %#lx.\n", i, hr);
1639 hr = IMediaControl_Stop(control);
1640 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1641
1644
1645 hr = IFilterGraph2_Disconnect(graph, source);
1646 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1647 hr = IFilterGraph2_Disconnect(graph, source);
1648 ok(hr == S_FALSE, "%u: Got hr %#lx.\n", i, hr);
1649 ok(testsink.sink.pin.peer == source, "%u: Got peer %p.\n", i, testsink.sink.pin.peer);
1650 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1651
1652 init_video_mt(&req_mt, &req_format, i);
1653 req_mt.lSampleSize = 999;
1654 req_mt.bTemporalCompression = TRUE;
1655 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1656 ok(hr == S_OK, "%u: Got hr %#lx.\n", i, hr);
1657 ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "%u: Media types didn't match.\n", i);
1658 IFilterGraph2_Disconnect(graph, source);
1659 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1660 }
1661
1662 req_mt = yuy2_mt;
1663 req_mt.formattype = FORMAT_None;
1664 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1665 ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#lx.\n", hr);
1666
1667 /* Connection with wildcards. */
1668
1670
1671 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, NULL);
1672 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1673 ok(IsEqualGUID(&testsink.sink.pin.mt.majortype, &source_mt.majortype), "Media types didn't match.\n");
1674 /* don't worry too much about sub/format type */
1675 IFilterGraph2_Disconnect(graph, source);
1676 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1677
1678 req_mt = yuy2_mt;
1679 req_format = yuy2_format;
1680 req_mt.pbFormat = (BYTE *)&req_format;
1681 req_mt.majortype = GUID_NULL;
1682 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1683 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1684 ok(IsEqualGUID(&testsink.sink.pin.mt.majortype, &MEDIATYPE_Video), "Media types didn't match.\n");
1685 IFilterGraph2_Disconnect(graph, source);
1686 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1687
1688 req_mt = yuy2_mt;
1689 req_format = yuy2_format;
1690 req_mt.pbFormat = (BYTE *)&req_format;
1691 req_mt.majortype = GUID_NULL;
1692 req_format.dwBitRate = 0; /* native looks at this specific field if the major type is GUID_NULL */
1693 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1694 todo_wine ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#lx.\n", hr);
1695 if (hr == S_OK)
1696 {
1697 IFilterGraph2_Disconnect(graph, source);
1698 IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
1699 }
1700
1701 req_mt = yuy2_mt;
1702 req_mt.majortype = MEDIATYPE_Audio;
1703 req_mt.subtype = GUID_NULL;
1704 req_mt.formattype = GUID_NULL;
1705 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
1706 ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#lx.\n", hr);
1707
1708 /* Test enumeration of sink media types. */
1709
1710 req_mt = yuy2_mt;
1711 req_mt.majortype = MEDIATYPE_Audio;
1712 req_mt.subtype = GUID_NULL;
1713 req_mt.formattype = GUID_NULL;
1714 testsink.mt = &req_mt;
1715 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, NULL);
1716 ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#lx.\n", hr);
1717
1718 req_mt = yuy2_mt;
1719 req_mt.lSampleSize = 444;
1720 testsink.mt = &req_mt;
1721 hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, NULL);
1722 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1723 ok(compare_media_types(&testsink.sink.pin.mt, &req_mt), "Media types didn't match.\n");
1724
1725 hr = IFilterGraph2_Disconnect(graph, sink);
1726 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1727 hr = IFilterGraph2_Disconnect(graph, sink);
1728 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
1729 ok(testsource.source.pin.peer == sink, "Got peer %p.\n", testsource.source.pin.peer);
1730 IFilterGraph2_Disconnect(graph, &testsource.source.pin.IPin_iface);
1731
1732 IMemInputPin_Release(meminput);
1733 IPin_Release(sink);
1734 IPin_Release(source);
1735 IMediaControl_Release(control);
1736 ref = IFilterGraph2_Release(graph);
1737 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1738 ref = IBaseFilter_Release(filter);
1739 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1740 ref = IBaseFilter_Release(&testsource.filter.IBaseFilter_iface);
1741 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1742 ref = IBaseFilter_Release(&testsink.filter.IBaseFilter_iface);
1743 ok(!ref, "Got outstanding refcount %ld.\n", ref);
1744}
1745
1746START_TEST(mpegvideo)
1747{
1749
1751
1752 if (FAILED(CoCreateInstance(&CLSID_CMpegVideoCodec, NULL, CLSCTX_INPROC_SERVER,
1753 &IID_IBaseFilter, (void **)&filter)))
1754 {
1755 skip("Failed to create MPEG video decoder instance.\n");
1756 return;
1757 }
1758 IBaseFilter_Release(filter);
1759
1764 test_find_pin();
1765 test_pin_info();
1769
1771}
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 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
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 E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
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 unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1674
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
_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
#define MAKEFOURCC(ch0, ch1, ch2, ch3)
Definition: ddsformat.c:45
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
#define L(x)
Definition: resources.c:13
struct tagVIDEOINFOHEADER VIDEOINFOHEADER
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLenum GLenum GLenum input
Definition: glext.h:9031
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
char hdr[14]
Definition: iptest.cpp:33
int quality
Definition: jpeglib.h:994
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
#define GUID_NULL
Definition: ks.h:106
#define todo_wine_if(is_todo)
Definition: minitest.h:81
#define todo_wine
Definition: minitest.h:80
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define BI_BITFIELDS
Definition: mmreg.h:507
static IUnknown * outer
Definition: compobj.c:82
static void testqc_init(struct testqc *qc, IUnknown *outer)
Definition: mpegvideo.c:819
static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, IMemInputPin *peer, IMemAllocator **allocator)
Definition: mpegvideo.c:871
BOOL works_native
Definition: mpegvideo.c:123
static BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b)
Definition: mpegvideo.c:112
static HRESULT testsink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
Definition: mpegvideo.c:884
static void testfilter_destroy(struct strmbase_filter *iface)
Definition: mpegvideo.c:852
static ULONG WINAPI testqc_inner_AddRef(IUnknown *iface)
Definition: mpegvideo.c:800
const GUID * subtype
Definition: mpegvideo.c:120
static const IUnknownVtbl outer_vtbl
Definition: mpegvideo.c:254
static const struct strmbase_sink_ops testsink_ops
Definition: mpegvideo.c:986
static const VIDEOINFOHEADER yuy2_format
Definition: mpegvideo.c:73
static HRESULT testsink_begin_flush(struct strmbase_sink *iface)
Definition: mpegvideo.c:972
static ULONG WINAPI testqc_Release(IQualityControl *iface)
Definition: mpegvideo.c:749
static void test_aggregation(void)
Definition: mpegvideo.c:263
static HRESULT testsink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: mpegvideo.c:908
static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
Definition: mpegvideo.c:164
static ULONG WINAPI outer_AddRef(IUnknown *iface)
Definition: mpegvideo.c:244
static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
Definition: mpegvideo.c:231
static const MPEG1VIDEOINFO_12 mpg_format
Definition: mpegvideo.c:38
static void test_send_sample(IMemInputPin *input, IMediaSample *sample, const BYTE *data, LONG len)
Definition: mpegvideo.c:1204
static struct testfilter * impl_from_strmbase_filter(struct strmbase_filter *iface)
Definition: mpegvideo.c:839
static ULONG get_refcount(void *iface)
Definition: mpegvideo.c:156
DWORD compression
Definition: mpegvideo.c:122
static void test_pin_info(void)
Definition: mpegvideo.c:541
static HRESULT testsource_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
Definition: mpegvideo.c:866
static IUnknown test_outer
Definition: mpegvideo.c:261
static struct testqc * impl_from_qc_IUnknown(IUnknown *iface)
Definition: mpegvideo.c:780
static const AM_MEDIA_TYPE mpeg_mt
Definition: mpegvideo.c:61
static void test_source_allocator(IFilterGraph2 *graph, IMediaControl *control, IPin *sink, IPin *source, struct testfilter *testsource, struct testfilter *testsink, unsigned type_idx, BOOL should_work)
Definition: mpegvideo.c:1057
static const IUnknownVtbl testqc_inner_vtbl
Definition: mpegvideo.c:812
static void test_find_pin(void)
Definition: mpegvideo.c:500
static HRESULT testsink_eos(struct strmbase_sink *iface)
Definition: mpegvideo.c:965
static IBaseFilter * create_mpeg_video_codec(void)
Definition: mpegvideo.c:103
static const struct strmbase_source_ops testsource_ops
Definition: mpegvideo.c:877
static void test_enum_media_types(void)
Definition: mpegvideo.c:610
BOOL works_wine
Definition: mpegvideo.c:124
static void test_quality_control(IFilterGraph2 *graph, IBaseFilter *filter, IPin *sink, IPin *source, struct testfilter *testsource, struct testfilter *testsink)
Definition: mpegvideo.c:1151
static void test_interfaces(void)
Definition: mpegvideo.c:178
static void test_streaming_events(IMediaControl *control, IPin *sink, IMemInputPin *input, struct testfilter *testsink)
Definition: mpegvideo.c:1355
static void test_connect_pin(void)
Definition: mpegvideo.c:1446
static HRESULT WINAPI testqc_SetSink(IQualityControl *iface, IQualityControl *sink)
Definition: mpegvideo.c:765
static void test_media_types(void)
Definition: mpegvideo.c:685
static struct strmbase_pin * testfilter_get_pin(struct strmbase_filter *iface, unsigned int index)
Definition: mpegvideo.c:844
static void test_enum_pins(void)
Definition: mpegvideo.c:379
static HRESULT WINAPI testqc_QueryInterface(IQualityControl *iface, REFIID iid, void **out)
Definition: mpegvideo.c:737
static ULONG WINAPI testqc_inner_Release(IUnknown *iface)
Definition: mpegvideo.c:806
static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample *sample)
Definition: mpegvideo.c:916
static HRESULT WINAPI testqc_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out)
Definition: mpegvideo.c:785
struct tagMPEG1VIDEOINFO_12 MPEG1VIDEOINFO_12
static void init_video_mt(AM_MEDIA_TYPE *mt, VIDEOINFOHEADER *format, unsigned type_idx)
Definition: mpegvideo.c:141
static void test_sink_allocator(IMemInputPin *input)
Definition: mpegvideo.c:1007
#define check_interface(a, b, c)
Definition: mpegvideo.c:163
static struct testqc * impl_from_IQualityControl(IQualityControl *iface)
Definition: mpegvideo.c:732
static ULONG WINAPI testqc_AddRef(IQualityControl *iface)
Definition: mpegvideo.c:743
static const struct @1969 video_types[]
int bits_per_pixel
Definition: mpegvideo.c:121
static LONG outer_ref
Definition: mpegvideo.c:229
static const IQualityControlVtbl testqc_vtbl
Definition: mpegvideo.c:771
static void test_send_video(IMemInputPin *input, IMediaSample *sample)
Definition: mpegvideo.c:1222
static const struct strmbase_filter_ops testfilter_ops
Definition: mpegvideo.c:860
static HRESULT testsink_new_segment(struct strmbase_sink *iface, REFERENCE_TIME start, REFERENCE_TIME stop, double rate)
Definition: mpegvideo.c:954
static void test_unconnected_filter_state(void)
Definition: mpegvideo.c:322
static const GUID test_iid
Definition: mpegvideo.c:228
static void test_sample_processing(IMediaControl *control, IMemInputPin *input, struct testfilter *sink)
Definition: mpegvideo.c:1260
static HRESULT testsink_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt)
Definition: mpegvideo.c:897
static HRESULT testsink_end_flush(struct strmbase_sink *iface)
Definition: mpegvideo.c:979
static void testfilter_init(struct testfilter *filter)
Definition: mpegvideo.c:998
static const AM_MEDIA_TYPE yuy2_mt
Definition: mpegvideo.c:91
static ULONG WINAPI outer_Release(IUnknown *iface)
Definition: mpegvideo.c:249
static HRESULT WINAPI testqc_Notify(IQualityControl *iface, IBaseFilter *sender, Quality q)
Definition: mpegvideo.c:755
const CLSID * clsid
Definition: msctf.cpp:50
short WCHAR
Definition: pedump.c:58
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 IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define offsetof(TYPE, MEMBER)
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
int winetest_platform_is_wine
#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
HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(struct strmbase_source *pin, IPin *peer, const AM_MEDIA_TYPE *mt)
Definition: pin.c:710
void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: mediatype.c:193
Definition: dialog.c:52
Definition: filter.c:165
IBaseFilter * filter
Definition: filtergraph.c:75
Definition: graph.c:32
Definition: parser.c:49
Definition: send.c:48
Definition: wave.c:25
struct strmbase_filter * filter
Definition: strmbase.h:58
struct strmbase_pin pin
Definition: strmbase.h:106
BYTE bSequenceHeader[12]
Definition: mpegvideo.c:35
VIDEOINFOHEADER hdr
Definition: mpegvideo.c:32
unsigned int got_end_flush
REFERENCE_TIME expected_stop_time
Definition: mpegaudio.c:907
REFERENCE_TIME expected_start_time
Definition: mpegaudio.c:906
unsigned int got_sample
AM_MEDIA_TYPE source_mt
unsigned int got_begin_flush
const AM_MEDIA_TYPE * mt
Definition: avidec.c:799
unsigned int got_eos
IFilterGraph * graph
Definition: filtergraph.c:850
struct testqc * qc
Definition: mpegaudio.c:903
struct strmbase_source source
Definition: amstream.c:1020
struct strmbase_filter filter
Definition: amstream.c:1019
unsigned int got_new_segment
IUnknown IUnknown_inner
Definition: mpegaudio.c:795
IUnknown * outer_unk
Definition: mpegaudio.c:796
LONG refcount
Definition: mpegaudio.c:797
HRESULT notify_hr
Definition: mpegaudio.c:800
Quality notify_quality
Definition: mpegaudio.c:799
IQualityControl IQualityControl_iface
Definition: mpegaudio.c:794
IBaseFilter * notify_sender
Definition: mpegaudio.c:798
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
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define BI_RGB
Definition: uefivid.c:46
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81
#define VFW_E_NOT_COMMITTED
Definition: vfwmsgs.h:56
#define VFW_E_NOT_STOPPED
Definition: vfwmsgs.h:75
#define VFW_E_NO_ACCEPTABLE_TYPES
Definition: vfwmsgs.h:46
#define VFW_E_WRONG_STATE
Definition: vfwmsgs.h:78
#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
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480
unsigned char BYTE
Definition: xxhash.c:193