2 * Unit tests for Media Detector
4 * Copyright (C) 2008 Google (Lei Zhang, Dan Hipschman)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/strmbase.h"
28 #include "wine/test.h"
33 static ULONG
get_refcount(void *iface
)
35 IUnknown
*unknown
= iface
;
36 IUnknown_AddRef(unknown
);
37 return IUnknown_Release(unknown
);
40 static const GUID test_iid
= {0x33333333};
41 static LONG outer_ref
= 1;
43 static HRESULT WINAPI
outer_QueryInterface(IUnknown
*iface
, REFIID iid
, void **out
)
45 if (IsEqualGUID(iid
, &IID_IUnknown
)
46 || IsEqualGUID(iid
, &IID_IMediaDet
)
47 || IsEqualGUID(iid
, &test_iid
))
49 *out
= (IUnknown
*)0xdeadbeef;
52 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid
));
56 static ULONG WINAPI
outer_AddRef(IUnknown
*iface
)
58 return InterlockedIncrement(&outer_ref
);
61 static ULONG WINAPI
outer_Release(IUnknown
*iface
)
63 return InterlockedDecrement(&outer_ref
);
66 static const IUnknownVtbl outer_vtbl
=
73 static IUnknown test_outer
= {&outer_vtbl
};
75 static void test_aggregation(void)
77 IMediaDet
*detector
, *detector2
;
82 detector
= (IMediaDet
*)0xdeadbeef;
83 hr
= CoCreateInstance(&CLSID_MediaDet
, &test_outer
, CLSCTX_INPROC_SERVER
,
84 &IID_IMediaDet
, (void **)&detector
);
85 ok(hr
== E_NOINTERFACE
, "Got hr %#lx.\n", hr
);
86 ok(!detector
, "Got interface %p.\n", detector
);
88 hr
= CoCreateInstance(&CLSID_MediaDet
, &test_outer
, CLSCTX_INPROC_SERVER
,
89 &IID_IUnknown
, (void **)&unk
);
90 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
91 ok(outer_ref
== 1, "Got unexpected refcount %ld.\n", outer_ref
);
92 ok(unk
!= &test_outer
, "Returned IUnknown should not be outer IUnknown.\n");
93 ref
= get_refcount(unk
);
94 ok(ref
== 1, "Got unexpected refcount %ld.\n", ref
);
96 ref
= IUnknown_AddRef(unk
);
97 ok(ref
== 2, "Got unexpected refcount %ld.\n", ref
);
98 ok(outer_ref
== 1, "Got unexpected refcount %ld.\n", outer_ref
);
100 ref
= IUnknown_Release(unk
);
101 ok(ref
== 1, "Got unexpected refcount %ld.\n", ref
);
102 ok(outer_ref
== 1, "Got unexpected refcount %ld.\n", outer_ref
);
104 hr
= IUnknown_QueryInterface(unk
, &IID_IUnknown
, (void **)&unk2
);
105 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
106 ok(unk2
== unk
, "Got unexpected IUnknown %p.\n", unk2
);
107 IUnknown_Release(unk2
);
109 hr
= IUnknown_QueryInterface(unk
, &IID_IMediaDet
, (void **)&detector
);
110 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
112 hr
= IMediaDet_QueryInterface(detector
, &IID_IUnknown
, (void **)&unk2
);
113 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
114 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
116 hr
= IMediaDet_QueryInterface(detector
, &IID_IMediaDet
, (void **)&detector2
);
117 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
118 ok(detector2
== (IMediaDet
*)0xdeadbeef, "Got unexpected IMediaDet %p.\n", detector2
);
120 hr
= IUnknown_QueryInterface(unk
, &test_iid
, (void **)&unk2
);
121 ok(hr
== E_NOINTERFACE
, "Got hr %#lx.\n", hr
);
122 ok(!unk2
, "Got unexpected IUnknown %p.\n", unk2
);
124 hr
= IMediaDet_QueryInterface(detector
, &test_iid
, (void **)&unk2
);
125 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
126 ok(unk2
== (IUnknown
*)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2
);
128 IMediaDet_Release(detector
);
129 ref
= IUnknown_Release(unk
);
130 ok(!ref
, "Got unexpected refcount %ld.\n", ref
);
131 ok(outer_ref
== 1, "Got unexpected refcount %ld.\n", outer_ref
);
136 struct strmbase_filter filter
;
137 struct strmbase_source source
;
138 IMediaSeeking IMediaSeeking_iface
;
141 static inline struct testfilter
*impl_from_strmbase_filter(struct strmbase_filter
*iface
)
143 return CONTAINING_RECORD(iface
, struct testfilter
, filter
);
146 static struct strmbase_pin
*testfilter_get_pin(struct strmbase_filter
*iface
, unsigned int index
)
148 struct testfilter
*filter
= impl_from_strmbase_filter(iface
);
150 return index
? NULL
: &filter
->source
.pin
;
153 static void testfilter_destroy(struct strmbase_filter
*iface
)
155 struct testfilter
*filter
= impl_from_strmbase_filter(iface
);
157 strmbase_source_cleanup(&filter
->source
);
158 strmbase_filter_cleanup(&filter
->filter
);
161 static const struct strmbase_filter_ops testfilter_ops
=
163 .filter_get_pin
= testfilter_get_pin
,
164 .filter_destroy
= testfilter_destroy
,
167 static inline struct testfilter
*impl_from_strmbase_pin(struct strmbase_pin
*iface
)
169 return CONTAINING_RECORD(iface
, struct testfilter
, source
.pin
);
172 static HRESULT
testsource_get_media_type(struct strmbase_pin
*iface
, unsigned int index
, AM_MEDIA_TYPE
*mt
)
174 static const VIDEOINFOHEADER source_format
=
176 .bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
),
177 .bmiHeader
.biWidth
= 640,
178 .bmiHeader
.biHeight
= 480,
179 .bmiHeader
.biPlanes
= 1,
180 .bmiHeader
.biBitCount
= 24,
181 .bmiHeader
.biCompression
= BI_RGB
,
182 .bmiHeader
.biSizeImage
= 640 * 480 * 3
188 mt
->majortype
= MEDIATYPE_Video
;
189 mt
->subtype
= MEDIASUBTYPE_RGB24
;
190 mt
->bFixedSizeSamples
= TRUE
;
191 mt
->bTemporalCompression
= FALSE
;
192 mt
->lSampleSize
= source_format
.bmiHeader
.biSizeImage
;
193 mt
->formattype
= FORMAT_VideoInfo
;
195 mt
->cbFormat
= sizeof(source_format
);
196 mt
->pbFormat
= CoTaskMemAlloc(mt
->cbFormat
);
197 memcpy(mt
->pbFormat
, &source_format
, mt
->cbFormat
);
201 static HRESULT
testsource_query_interface(struct strmbase_pin
*iface
, REFIID iid
, void **out
)
203 struct testfilter
*filter
= impl_from_strmbase_pin(iface
);
205 if (IsEqualGUID(iid
, &IID_IMediaSeeking
))
206 *out
= &filter
->IMediaSeeking_iface
;
208 return E_NOINTERFACE
;
210 IUnknown_AddRef((IUnknown
*)*out
);
214 static HRESULT WINAPI
testsource_DecideAllocator(struct strmbase_source
*iface
,
215 IMemInputPin
*peer
, IMemAllocator
**allocator
)
220 static const struct strmbase_source_ops testsource_ops
=
222 .base
.pin_get_media_type
= testsource_get_media_type
,
223 .base
.pin_query_interface
= testsource_query_interface
,
224 .pfnAttemptConnection
= BaseOutputPinImpl_AttemptConnection
,
225 .pfnDecideAllocator
= testsource_DecideAllocator
,
228 static inline struct testfilter
*impl_from_IMediaSeeking(IMediaSeeking
*iface
)
230 return CONTAINING_RECORD(iface
, struct testfilter
, IMediaSeeking_iface
);
233 static HRESULT WINAPI
testseek_QueryInterface(IMediaSeeking
*iface
, REFIID iid
, void **out
)
235 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
236 return IPin_QueryInterface(&filter
->source
.pin
.IPin_iface
, iid
, out
);
239 static ULONG WINAPI
testseek_AddRef(IMediaSeeking
*iface
)
241 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
242 return IPin_AddRef(&filter
->source
.pin
.IPin_iface
);
245 static ULONG WINAPI
testseek_Release(IMediaSeeking
*iface
)
247 struct testfilter
*filter
= impl_from_IMediaSeeking(iface
);
248 return IPin_Release(&filter
->source
.pin
.IPin_iface
);
251 static HRESULT WINAPI
testseek_GetCapabilities(IMediaSeeking
*iface
, DWORD
*caps
)
253 ok(0, "Unexpected call.\n");
257 static HRESULT WINAPI
testseek_CheckCapabilities(IMediaSeeking
*iface
, DWORD
*caps
)
259 ok(0, "Unexpected call.\n");
263 static HRESULT WINAPI
testseek_IsFormatSupported(IMediaSeeking
*iface
, const GUID
*format
)
265 ok(0, "Unexpected call.\n");
269 static HRESULT WINAPI
testseek_QueryPreferredFormat(IMediaSeeking
*iface
, GUID
*format
)
271 ok(0, "Unexpected call.\n");
275 static HRESULT WINAPI
testseek_GetTimeFormat(IMediaSeeking
*iface
, GUID
*format
)
277 ok(0, "Unexpected call.\n");
281 static HRESULT WINAPI
testseek_IsUsingTimeFormat(IMediaSeeking
*iface
, const GUID
*format
)
283 ok(0, "Unexpected call.\n");
287 static HRESULT WINAPI
testseek_SetTimeFormat(IMediaSeeking
*iface
, const GUID
*format
)
289 ok(0, "Unexpected call.\n");
293 static HRESULT WINAPI
testseek_GetDuration(IMediaSeeking
*iface
, LONGLONG
*duration
)
295 if (winetest_debug
> 1) trace("IMediaSeeking_GetDuration()\n");
297 *duration
= 42000000;
301 static HRESULT WINAPI
testseek_GetStopPosition(IMediaSeeking
*iface
, LONGLONG
*stop
)
303 ok(0, "Unexpected call.\n");
307 static HRESULT WINAPI
testseek_GetCurrentPosition(IMediaSeeking
*iface
, LONGLONG
*current
)
309 ok(0, "Unexpected call.\n");
313 static HRESULT WINAPI
testseek_ConvertTimeFormat(IMediaSeeking
*iface
, LONGLONG
*target
,
314 const GUID
*target_format
, LONGLONG source
, const GUID
*source_format
)
316 ok(0, "Unexpected call.\n");
320 static HRESULT WINAPI
testseek_SetPositions(IMediaSeeking
*iface
, LONGLONG
*current
,
321 DWORD current_flags
, LONGLONG
*stop
, DWORD stop_flags
)
323 ok(0, "Unexpected call.\n");
327 static HRESULT WINAPI
testseek_GetPositions(IMediaSeeking
*iface
, LONGLONG
*current
, LONGLONG
*stop
)
329 ok(0, "Unexpected call.\n");
333 static HRESULT WINAPI
testseek_GetAvailable(IMediaSeeking
*iface
, LONGLONG
*earliest
, LONGLONG
*latest
)
335 ok(0, "Unexpected call.\n");
339 static HRESULT WINAPI
testseek_SetRate(IMediaSeeking
*iface
, double rate
)
341 ok(0, "Unexpected call.\n");
345 static HRESULT WINAPI
testseek_GetRate(IMediaSeeking
*iface
, double *rate
)
347 ok(0, "Unexpected call.\n");
351 static HRESULT WINAPI
testseek_GetPreroll(IMediaSeeking
*iface
, LONGLONG
*preroll
)
353 ok(0, "Unexpected call.\n");
357 static const IMediaSeekingVtbl testseek_vtbl
=
359 testseek_QueryInterface
,
362 testseek_GetCapabilities
,
363 testseek_CheckCapabilities
,
364 testseek_IsFormatSupported
,
365 testseek_QueryPreferredFormat
,
366 testseek_GetTimeFormat
,
367 testseek_IsUsingTimeFormat
,
368 testseek_SetTimeFormat
,
369 testseek_GetDuration
,
370 testseek_GetStopPosition
,
371 testseek_GetCurrentPosition
,
372 testseek_ConvertTimeFormat
,
373 testseek_SetPositions
,
374 testseek_GetPositions
,
375 testseek_GetAvailable
,
381 static void testfilter_init(struct testfilter
*filter
)
383 static const GUID clsid
= {0xabacab};
385 memset(filter
, 0, sizeof(*filter
));
386 strmbase_filter_init(&filter
->filter
, NULL
, &clsid
, &testfilter_ops
);
387 strmbase_source_init(&filter
->source
, &filter
->filter
, L
"", &testsource_ops
);
388 filter
->IMediaSeeking_iface
.lpVtbl
= &testseek_vtbl
;
391 static WCHAR test_avi_filename
[MAX_PATH
];
392 static WCHAR test_sound_avi_filename
[MAX_PATH
];
394 static BOOL
unpack_avi_file(int id
, WCHAR name
[MAX_PATH
])
396 static WCHAR temp_path
[MAX_PATH
];
404 res
= FindResourceW(NULL
, MAKEINTRESOURCEW(id
), MAKEINTRESOURCEW(AVI_RES_TYPE
));
408 data
= LoadResource(NULL
, res
);
412 mem
= LockResource(data
);
416 size
= SizeofResource(NULL
, res
);
420 if (!GetTempPathW(MAX_PATH
, temp_path
))
423 /* We might end up relying on the extension here, so .TMP is no good. */
424 if (!GetTempFileNameW(temp_path
, L
"DES", 0, name
))
428 wcscpy(name
+ wcslen(name
) - 3, L
"avi");
430 fh
= CreateFileW(name
, GENERIC_WRITE
, 0, NULL
, CREATE_NEW
,
431 FILE_ATTRIBUTE_NORMAL
, NULL
);
432 if (fh
== INVALID_HANDLE_VALUE
)
435 ret
= WriteFile(fh
, mem
, size
, &written
, NULL
);
437 return ret
&& written
== size
;
440 static BOOL
init_tests(void)
442 return unpack_avi_file(TEST_AVI_RES
, test_avi_filename
)
443 && unpack_avi_file(TEST_SOUND_AVI_RES
, test_sound_avi_filename
);
446 static void test_mediadet(void)
449 FILTER_INFO filter_info
;
450 AM_MEDIA_TYPE mt
, *pmt
;
451 LONG index
, ref
, count
;
452 IEnumMediaTypes
*type
;
453 IMediaDet
*pM
= NULL
;
454 BSTR filename
= NULL
;
465 /* test.avi has one video stream. */
466 hr
= CoCreateInstance(&CLSID_MediaDet
, NULL
, CLSCTX_INPROC_SERVER
,
467 &IID_IMediaDet
, (LPVOID
*)&pM
);
468 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
469 ok(pM
!= NULL
, "pM is NULL\n");
472 hr
= IMediaDet_get_Filename(pM
, &filename
);
473 /* Despite what MSDN claims, this returns S_OK. */
474 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
475 ok(filename
== NULL
, "IMediaDet_get_Filename\n");
477 filename
= (BSTR
) -1;
478 hr
= IMediaDet_get_Filename(pM
, &filename
);
479 /* Despite what MSDN claims, this returns S_OK. */
480 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
481 ok(filename
== NULL
, "IMediaDet_get_Filename\n");
484 hr
= IMediaDet_get_OutputStreams(pM
, &count
);
485 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
486 ok(count
== -1, "Got %ld streams.\n", count
);
489 /* The stream defaults to 0, even without a file! */
490 hr
= IMediaDet_get_CurrentStream(pM
, &index
);
491 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
492 ok(index
== 0, "Got stream index %ld.\n", index
);
494 hr
= IMediaDet_get_CurrentStream(pM
, NULL
);
495 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
497 /* But put_CurrentStream doesn't. */
498 hr
= IMediaDet_put_CurrentStream(pM
, 0);
499 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
501 hr
= IMediaDet_put_CurrentStream(pM
, -1);
502 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
504 hr
= IMediaDet_get_StreamMediaType(pM
, &mt
);
505 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
507 hr
= IMediaDet_get_StreamMediaType(pM
, NULL
);
508 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
510 hr
= IMediaDet_get_StreamType(pM
, &guid
);
511 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
513 hr
= IMediaDet_get_StreamType(pM
, NULL
);
514 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
516 hr
= IMediaDet_get_StreamTypeB(pM
, &bstr
);
517 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
519 hr
= IMediaDet_get_StreamTypeB(pM
, NULL
);
520 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
522 hr
= IMediaDet_get_Filter(pM
, NULL
);
523 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
525 unk
= (IUnknown
*)0xdeadbeef;
526 hr
= IMediaDet_get_Filter(pM
, &unk
);
527 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
528 ok(!unk
, "Got filter %p.\n", unk
);
530 filename
= SysAllocString(test_avi_filename
);
531 hr
= IMediaDet_put_Filename(pM
, filename
);
532 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
533 SysFreeString(filename
);
536 /* The stream defaults to 0. */
537 hr
= IMediaDet_get_CurrentStream(pM
, &index
);
538 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
539 ok(index
== 0, "Got stream index %ld.\n", index
);
541 ZeroMemory(&mt
, sizeof mt
);
542 hr
= IMediaDet_get_StreamMediaType(pM
, &mt
);
543 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
544 CoTaskMemFree(mt
.pbFormat
);
546 hr
= IMediaDet_get_StreamType(pM
, &guid
);
547 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
548 ok(IsEqualGUID(&guid
, &MEDIATYPE_Video
), "Got major type %s.\n", debugstr_guid(&guid
));
550 hr
= IMediaDet_get_StreamTypeB(pM
, &bstr
);
551 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
552 ok(!wcscmp(bstr
, L
"{73646976-0000-0010-8000-00AA00389B71}"),
553 "Got major type %s.\n", debugstr_w(bstr
));
556 /* Even before get_OutputStreams. */
557 hr
= IMediaDet_put_CurrentStream(pM
, 1);
558 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
560 hr
= IMediaDet_get_OutputStreams(pM
, &count
);
561 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
562 ok(count
== 1, "Got %ld streams.\n", count
);
565 hr
= IMediaDet_get_Filename(pM
, &filename
);
566 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
567 ok(!wcscmp(filename
, test_avi_filename
), "Expected filename %s, got %s.\n",
568 debugstr_w(test_avi_filename
), debugstr_w(filename
));
569 SysFreeString(filename
);
571 hr
= IMediaDet_get_Filename(pM
, NULL
);
572 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
575 hr
= IMediaDet_get_CurrentStream(pM
, &index
);
576 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
577 ok(index
== 0, "Got stream index %ld.\n", index
);
579 hr
= IMediaDet_get_CurrentStream(pM
, NULL
);
580 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
582 hr
= IMediaDet_put_CurrentStream(pM
, -1);
583 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
585 hr
= IMediaDet_put_CurrentStream(pM
, 1);
586 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
590 hr
= IMediaDet_get_CurrentStream(pM
, &index
);
591 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
592 ok(index
== 0, "Got stream index %ld.\n", index
);
594 hr
= IMediaDet_put_CurrentStream(pM
, 0);
595 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
598 hr
= IMediaDet_get_CurrentStream(pM
, &index
);
599 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
600 ok(index
== 0, "Got stream index %ld.\n", index
);
602 ZeroMemory(&mt
, sizeof mt
);
603 hr
= IMediaDet_get_StreamMediaType(pM
, &mt
);
604 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
605 ok(IsEqualGUID(&mt
.majortype
, &MEDIATYPE_Video
),
606 "IMediaDet_get_StreamMediaType\n");
607 CoTaskMemFree(mt
.pbFormat
);
609 hr
= IMediaDet_get_StreamType(pM
, &guid
);
610 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
611 ok(IsEqualGUID(&guid
, &MEDIATYPE_Video
), "Got major type %s.\n", debugstr_guid(&guid
));
613 hr
= IMediaDet_get_StreamTypeB(pM
, &bstr
);
614 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
615 ok(!wcscmp(bstr
, L
"{73646976-0000-0010-8000-00AA00389B71}"),
616 "Got major type %s.\n", debugstr_w(bstr
));
619 hr
= IMediaDet_get_FrameRate(pM
, NULL
);
620 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
622 hr
= IMediaDet_get_FrameRate(pM
, &fps
);
623 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
624 ok(fps
== 10.0, "IMediaDet_get_FrameRate: fps is %f\n", fps
);
626 ref
= IMediaDet_Release(pM
);
627 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
629 /* test_sound.avi has one video stream and one audio stream. */
630 hr
= CoCreateInstance(&CLSID_MediaDet
, NULL
, CLSCTX_INPROC_SERVER
,
631 &IID_IMediaDet
, (LPVOID
*)&pM
);
632 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
633 ok(pM
!= NULL
, "pM is NULL\n");
635 filename
= SysAllocString(test_sound_avi_filename
);
636 hr
= IMediaDet_put_Filename(pM
, filename
);
637 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
638 SysFreeString(filename
);
640 hr
= IMediaDet_get_OutputStreams(pM
, &count
);
641 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
642 ok(count
== 2, "Got %ld streams.\n", count
);
645 hr
= IMediaDet_get_Filename(pM
, &filename
);
646 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
647 ok(!wcscmp(filename
, test_sound_avi_filename
), "Expected filename %s, got %s.\n",
648 debugstr_w(test_sound_avi_filename
), debugstr_w(filename
));
649 SysFreeString(filename
);
651 /* I don't know if the stream order is deterministic. Just check
652 for both an audio and video stream. */
655 for (i
= 0; i
< 2; ++i
)
657 hr
= IMediaDet_put_CurrentStream(pM
, i
);
658 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
661 hr
= IMediaDet_get_CurrentStream(pM
, &index
);
662 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
663 ok(index
== i
, "Got stream index %ld.\n", index
);
665 ZeroMemory(&mt
, sizeof mt
);
666 hr
= IMediaDet_get_StreamMediaType(pM
, &mt
);
667 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
668 flags
+= (IsEqualGUID(&mt
.majortype
, &MEDIATYPE_Video
)
670 : (IsEqualGUID(&mt
.majortype
, &MEDIATYPE_Audio
)
674 if (IsEqualGUID(&mt
.majortype
, &MEDIATYPE_Audio
))
676 hr
= IMediaDet_get_StreamType(pM
, &guid
);
677 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
678 ok(IsEqualGUID(&guid
, &MEDIATYPE_Audio
), "Got major type %s.\n", debugstr_guid(&guid
));
680 hr
= IMediaDet_get_StreamTypeB(pM
, &bstr
);
681 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
682 ok(!wcscmp(bstr
, L
"{73647561-0000-0010-8000-00AA00389B71}"),
683 "Got major type %s.\n", debugstr_w(bstr
));
686 hr
= IMediaDet_get_FrameRate(pM
, &fps
);
687 ok(hr
== VFW_E_INVALIDMEDIATYPE
, "Got hr %#lx.\n", hr
);
690 CoTaskMemFree(mt
.pbFormat
);
692 ok(flags
== 3, "IMediaDet_get_StreamMediaType: flags are %i\n", flags
);
694 hr
= IMediaDet_put_CurrentStream(pM
, 2);
695 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
698 hr
= IMediaDet_get_CurrentStream(pM
, &index
);
699 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
700 ok(index
== 1, "Got stream index %ld.\n", index
);
703 hr
= IMediaDet_get_Filter(pM
, &unk
);
704 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
705 ok(!!unk
, "Expected a non-NULL filter.\n");
706 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void**)&filter
);
707 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
708 IUnknown_Release(unk
);
710 hr
= IBaseFilter_EnumPins(filter
, &enumpins
);
711 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
712 hr
= IEnumPins_Next(enumpins
, 1, &pin
, NULL
);
713 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
714 hr
= IPin_EnumMediaTypes(pin
, &type
);
715 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
716 hr
= IEnumMediaTypes_Next(type
, 1, &pmt
, NULL
);
717 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
718 ok(IsEqualGUID(&pmt
->majortype
, &MEDIATYPE_Stream
), "Got major type %s.\n",
719 debugstr_guid(&pmt
->majortype
));
720 IEnumMediaTypes_Release(type
);
721 CoTaskMemFree(pmt
->pbFormat
);
725 hr
= IEnumPins_Next(enumpins
, 1, &pin
, NULL
);
726 ok(hr
== S_FALSE
, "Got hr %#lx.\n", hr
);
727 IEnumPins_Release(enumpins
);
729 hr
= IBaseFilter_QueryFilterInfo(filter
, &filter_info
);
730 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
731 ok(!wcscmp(filter_info
.achName
, L
"Source"), "Got name %s.\n", debugstr_w(filter_info
.achName
));
732 IFilterGraph_Release(filter_info
.pGraph
);
733 IBaseFilter_Release(filter
);
735 ref
= IMediaDet_Release(pM
);
736 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
739 static void test_put_filter(void)
741 struct testfilter testfilter
, testfilter2
;
753 hr
= CoCreateInstance(&CLSID_MediaDet
, NULL
, CLSCTX_INPROC_SERVER
,
754 &IID_IMediaDet
, (void **)&detector
);
755 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
757 hr
= IMediaDet_put_Filter(detector
, NULL
);
758 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
760 hr
= IMediaDet_get_Filter(detector
, NULL
);
761 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
763 hr
= IMediaDet_get_StreamLength(detector
, NULL
);
764 ok(hr
== E_POINTER
, "Got hr %#lx.\n", hr
);
766 hr
= IMediaDet_get_StreamLength(detector
, &duration
);
767 ok(hr
== E_INVALIDARG
, "Got hr %#lx.\n", hr
);
769 testfilter_init(&testfilter
);
770 hr
= IMediaDet_put_Filter(detector
, &testfilter
.filter
.IUnknown_inner
);
771 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
773 hr
= IMediaDet_get_Filter(detector
, &unk
);
774 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
775 ok(!!unk
, "Expected a non-NULL interface.\n");
776 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void **)&filter
);
777 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
778 ok(filter
== &testfilter
.filter
.IBaseFilter_iface
, "Expected the same filter.\n");
779 IBaseFilter_Release(filter
);
780 IUnknown_Release(unk
);
782 ok(!wcscmp(testfilter
.filter
.name
, L
"Source"), "Got name %s.\n",
783 debugstr_w(testfilter
.filter
.name
));
784 graph
= testfilter
.filter
.graph
;
785 IFilterGraph_AddRef(graph
);
787 testfilter_init(&testfilter2
);
788 hr
= IMediaDet_put_Filter(detector
, &testfilter2
.filter
.IUnknown_inner
);
789 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
791 hr
= IMediaDet_get_Filter(detector
, &unk
);
792 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
793 ok(!!unk
, "Expected a non-NULL interface.\n");
794 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void **)&filter
);
795 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
796 ok(filter
== &testfilter2
.filter
.IBaseFilter_iface
, "Expected the same filter.\n");
797 IBaseFilter_Release(filter
);
798 IUnknown_Release(unk
);
800 ok(testfilter2
.filter
.graph
!= graph
, "Expected a different graph.\n");
802 ref
= IFilterGraph_Release(graph
);
803 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
804 ref
= IBaseFilter_Release(&testfilter
.filter
.IBaseFilter_iface
);
805 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
808 hr
= IMediaDet_get_OutputStreams(detector
, &count
);
809 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
810 ok(count
== 1, "Got %ld streams.\n", count
);
813 hr
= IMediaDet_get_CurrentStream(detector
, &index
);
814 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
815 ok(index
== 0, "Got stream %ld.\n", index
);
817 filename
= (BSTR
)0xdeadbeef;
818 hr
= IMediaDet_get_Filename(detector
, &filename
);
819 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
820 ok(!filename
, "Got filename %s.\n", debugstr_w(filename
));
822 hr
= IMediaDet_get_StreamLength(detector
, &duration
);
823 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
824 ok(duration
== 4.2, "Got duration %.16e.\n", duration
);
826 ref
= IMediaDet_Release(detector
);
827 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
828 ref
= IBaseFilter_Release(&testfilter2
.filter
.IBaseFilter_iface
);
829 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
831 hr
= CoCreateInstance(&CLSID_MediaDet
, NULL
, CLSCTX_INPROC_SERVER
,
832 &IID_IMediaDet
, (void **)&detector
);
833 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
835 filename
= SysAllocString(test_sound_avi_filename
);
836 hr
= IMediaDet_put_Filename(detector
, filename
);
837 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
838 SysFreeString(filename
);
840 hr
= IMediaDet_get_StreamMediaType(detector
, &mt
);
841 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
844 hr
= IMediaDet_get_Filter(detector
, &unk
);
845 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
846 hr
= IMediaDet_put_Filter(detector
, unk
);
847 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
848 IUnknown_Release(unk
);
850 filename
= (BSTR
)0xdeadbeef;
851 hr
= IMediaDet_get_Filename(detector
, &filename
);
852 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
853 ok(!filename
, "Got filename %s.\n", debugstr_w(filename
));
856 hr
= IMediaDet_get_OutputStreams(detector
, &count
);
857 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
858 ok(count
== 2, "Got %ld streams.\n", count
);
861 hr
= IMediaDet_get_CurrentStream(detector
, &index
);
862 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
863 ok(index
== 0, "Got stream %ld.\n", index
);
865 ref
= IMediaDet_Release(detector
);
866 ok(!ref
, "Got outstanding refcount %ld.\n", ref
);
875 static struct test_sample
*impl_from_IMediaSample(IMediaSample
*iface
)
877 return CONTAINING_RECORD(iface
, struct test_sample
, sample
);
880 static HRESULT WINAPI
ms_QueryInterface(IMediaSample
*iface
, REFIID riid
,
886 static ULONG WINAPI
ms_AddRef(IMediaSample
*iface
)
888 struct test_sample
*sample
= impl_from_IMediaSample(iface
);
889 return InterlockedIncrement(&sample
->refcount
);
892 static ULONG WINAPI
ms_Release(IMediaSample
*iface
)
894 struct test_sample
*sample
= impl_from_IMediaSample(iface
);
895 return InterlockedDecrement(&sample
->refcount
);
898 static HRESULT WINAPI
ms_GetPointer(IMediaSample
*iface
, BYTE
**ppBuffer
)
903 static LONG WINAPI
ms_GetSize(IMediaSample
*iface
)
908 static HRESULT WINAPI
ms_GetTime(IMediaSample
*iface
, REFERENCE_TIME
*pTimeStart
,
909 REFERENCE_TIME
*pTimeEnd
)
914 static HRESULT WINAPI
ms_SetTime(IMediaSample
*iface
, REFERENCE_TIME
*pTimeStart
,
915 REFERENCE_TIME
*pTimeEnd
)
920 static HRESULT WINAPI
ms_IsSyncPoint(IMediaSample
*iface
)
925 static HRESULT WINAPI
ms_SetSyncPoint(IMediaSample
*iface
, BOOL bIsSyncPoint
)
930 static HRESULT WINAPI
ms_IsPreroll(IMediaSample
*iface
)
935 static HRESULT WINAPI
ms_SetPreroll(IMediaSample
*iface
, BOOL bIsPreroll
)
940 static LONG WINAPI
ms_GetActualDataLength(IMediaSample
*iface
)
945 static HRESULT WINAPI
ms_SetActualDataLength(IMediaSample
*iface
, LONG length
)
950 static HRESULT WINAPI
ms_GetMediaType(IMediaSample
*iface
, AM_MEDIA_TYPE
956 static HRESULT WINAPI
ms_SetMediaType(IMediaSample
*iface
, AM_MEDIA_TYPE
*pMediaType
)
961 static HRESULT WINAPI
ms_IsDiscontinuity(IMediaSample
*iface
)
966 static HRESULT WINAPI
ms_SetDiscontinuity(IMediaSample
*iface
, BOOL bDiscontinuity
)
971 static HRESULT WINAPI
ms_GetMediaTime(IMediaSample
*iface
, LONGLONG
*pTimeStart
,
977 static HRESULT WINAPI
ms_SetMediaTime(IMediaSample
*iface
, LONGLONG
*pTimeStart
,
983 static const IMediaSampleVtbl my_sample_vt
= {
995 ms_GetActualDataLength
,
996 ms_SetActualDataLength
,
1000 ms_SetDiscontinuity
,
1005 static struct test_sample my_sample
= { {&my_sample_vt
}, 0 };
1007 static BOOL samplecb_called
= FALSE
;
1009 static HRESULT WINAPI
sgcb_QueryInterface(ISampleGrabberCB
*iface
, REFIID riid
,
1015 static ULONG WINAPI
sgcb_AddRef(ISampleGrabberCB
*iface
)
1020 static ULONG WINAPI
sgcb_Release(ISampleGrabberCB
*iface
)
1025 static HRESULT WINAPI
sgcb_SampleCB(ISampleGrabberCB
*iface
, double SampleTime
,
1026 IMediaSample
*pSample
)
1028 ok(pSample
== &my_sample
.sample
, "Got wrong IMediaSample: %p, expected %p\n", pSample
, &my_sample
);
1029 samplecb_called
= TRUE
;
1030 IMediaSample_AddRef(pSample
);
1034 static HRESULT WINAPI
sgcb_BufferCB(ISampleGrabberCB
*iface
, double SampleTime
,
1035 BYTE
*pBuffer
, LONG BufferLen
)
1037 ok(0, "BufferCB should not have been called\n");
1041 static const ISampleGrabberCBVtbl sgcb_vt
= {
1042 sgcb_QueryInterface
,
1049 static ISampleGrabberCB my_sg_cb
= { &sgcb_vt
};
1051 static void test_samplegrabber(void)
1056 IMemInputPin
*inpin
;
1059 FILTER_STATE fstate
;
1063 hr
= CoCreateInstance(&CLSID_SampleGrabber
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IClassFactory
,
1065 ok(hr
== E_NOINTERFACE
, "Got hr %#lx.\n", hr
);
1067 hr
= CoCreateInstance(&CLSID_SampleGrabber
, NULL
, CLSCTX_INPROC_SERVER
, &IID_ISampleGrabber
,
1069 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1071 hr
= ISampleGrabber_QueryInterface(sg
, &IID_IBaseFilter
, (void**)&bf
);
1072 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1074 hr
= ISampleGrabber_SetCallback(sg
, &my_sg_cb
, 0);
1075 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1077 hr
= IBaseFilter_GetState(bf
, 100, &fstate
);
1078 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1079 ok(fstate
== State_Stopped
, "Got wrong filter state: %u\n", fstate
);
1081 hr
= IBaseFilter_EnumPins(bf
, &pins
);
1082 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1084 hr
= IEnumPins_Next(pins
, 1, &pin
, NULL
);
1085 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1087 IEnumPins_Release(pins
);
1089 hr
= IPin_QueryInterface(pin
, &IID_IMemInputPin
, (void**)&inpin
);
1090 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1092 hr
= IMemInputPin_Receive(inpin
, &my_sample
.sample
);
1093 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1094 ok(samplecb_called
== TRUE
, "SampleCB should have been called\n");
1096 refcount
= IUnknown_Release(&my_sample
.sample
);
1097 ok(!refcount
, "Got unexpected refcount %ld.\n", refcount
);
1099 IMemInputPin_Release(inpin
);
1102 while (ISampleGrabber_Release(sg
));
1105 static void test_COM_sg_enumpins(void)
1108 IEnumPins
*pins
, *pins2
;
1113 hr
= CoCreateInstance(&CLSID_SampleGrabber
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IBaseFilter
,
1115 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1116 hr
= IBaseFilter_EnumPins(bf
, &pins
);
1117 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1119 /* Same refcount for all EnumPins interfaces */
1120 refcount
= IEnumPins_AddRef(pins
);
1121 ok(refcount
== 2, "refcount == %lu, expected 2\n", refcount
);
1122 hr
= IEnumPins_QueryInterface(pins
, &IID_IEnumPins
, (void**)&pins2
);
1123 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1124 ok(pins
== pins2
, "QueryInterface for self failed (%p != %p)\n", pins
, pins2
);
1125 IEnumPins_Release(pins2
);
1127 hr
= IEnumPins_QueryInterface(pins
, &IID_IUnknown
, (void**)&unk
);
1128 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
1129 refcount
= IUnknown_AddRef(unk
);
1130 ok(refcount
== 4, "refcount == %lu, expected 4\n", refcount
);
1131 refcount
= IUnknown_Release(unk
);
1133 while (IEnumPins_Release(pins
));
1134 IBaseFilter_Release(bf
);
1137 START_TEST(mediadet
)
1139 IMediaDet
*detector
;
1145 skip("Couldn't initialize tests!\n");
1151 if (FAILED(hr
= CoCreateInstance(&CLSID_MediaDet
, NULL
, CLSCTX_INPROC_SERVER
,
1152 &IID_IMediaDet
, (void **)&detector
)))
1154 /* qedit.dll does not exist on 2003. */
1155 win_skip("Failed to create media detector object, hr %#lx.\n", hr
);
1158 IMediaDet_Release(detector
);
1163 test_samplegrabber();
1164 test_COM_sg_enumpins();
1166 ret
= DeleteFileW(test_avi_filename
);
1167 ok(ret
, "Failed to delete file, error %lu.\n", GetLastError());
1168 ret
= DeleteFileW(test_sound_avi_filename
);
1169 ok(ret
, "Failed to delete file, error %lu.\n", GetLastError());