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 %#x.\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 %#x.\n", hr
);
91 ok(outer_ref
== 1, "Got unexpected refcount %d.\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 %d.\n", ref
);
96 ref
= IUnknown_AddRef(unk
);
97 ok(ref
== 2, "Got unexpected refcount %d.\n", ref
);
98 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
100 ref
= IUnknown_Release(unk
);
101 ok(ref
== 1, "Got unexpected refcount %d.\n", ref
);
102 ok(outer_ref
== 1, "Got unexpected refcount %d.\n", outer_ref
);
104 hr
= IUnknown_QueryInterface(unk
, &IID_IUnknown
, (void **)&unk2
);
105 ok(hr
== S_OK
, "Got hr %#x.\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 %#x.\n", hr
);
112 hr
= IMediaDet_QueryInterface(detector
, &IID_IUnknown
, (void **)&unk2
);
113 ok(hr
== S_OK
, "Got hr %#x.\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 %#x.\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 %#x.\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 %#x.\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 %d.\n", ref
);
131 ok(outer_ref
== 1, "Got unexpected refcount %d.\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 IEnumMediaTypes
*type
;
452 IMediaDet
*pM
= NULL
;
453 BSTR filename
= NULL
;
466 /* test.avi has one video stream. */
467 hr
= CoCreateInstance(&CLSID_MediaDet
, NULL
, CLSCTX_INPROC_SERVER
,
468 &IID_IMediaDet
, (LPVOID
*)&pM
);
469 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
470 ok(pM
!= NULL
, "pM is NULL\n");
473 hr
= IMediaDet_get_Filename(pM
, &filename
);
474 /* Despite what MSDN claims, this returns S_OK. */
475 ok(hr
== S_OK
, "IMediaDet_get_Filename failed: %08x\n", hr
);
476 ok(filename
== NULL
, "IMediaDet_get_Filename\n");
478 filename
= (BSTR
) -1;
479 hr
= IMediaDet_get_Filename(pM
, &filename
);
480 /* Despite what MSDN claims, this returns S_OK. */
481 ok(hr
== S_OK
, "IMediaDet_get_Filename failed: %08x\n", hr
);
482 ok(filename
== NULL
, "IMediaDet_get_Filename\n");
485 hr
= IMediaDet_get_OutputStreams(pM
, &nstrms
);
486 ok(hr
== E_INVALIDARG
, "IMediaDet_get_OutputStreams failed: %08x\n", hr
);
487 ok(nstrms
== -1, "IMediaDet_get_OutputStreams: nstrms is %i\n", nstrms
);
490 /* The stream defaults to 0, even without a file! */
491 hr
= IMediaDet_get_CurrentStream(pM
, &strm
);
492 ok(hr
== S_OK
, "IMediaDet_get_CurrentStream failed: %08x\n", hr
);
493 ok(strm
== 0, "IMediaDet_get_CurrentStream: strm is %i\n", strm
);
495 hr
= IMediaDet_get_CurrentStream(pM
, NULL
);
496 ok(hr
== E_POINTER
, "IMediaDet_get_CurrentStream failed: %08x\n", hr
);
498 /* But put_CurrentStream doesn't. */
499 hr
= IMediaDet_put_CurrentStream(pM
, 0);
500 ok(hr
== E_INVALIDARG
, "IMediaDet_put_CurrentStream failed: %08x\n", hr
);
502 hr
= IMediaDet_put_CurrentStream(pM
, -1);
503 ok(hr
== E_INVALIDARG
, "IMediaDet_put_CurrentStream failed: %08x\n", hr
);
505 hr
= IMediaDet_get_StreamMediaType(pM
, &mt
);
506 ok(hr
== E_INVALIDARG
, "IMediaDet_get_StreamMediaType failed: %08x\n", hr
);
508 hr
= IMediaDet_get_StreamMediaType(pM
, NULL
);
509 ok(hr
== E_POINTER
, "IMediaDet_get_StreamMediaType failed: %08x\n", hr
);
511 hr
= IMediaDet_get_StreamType(pM
, &guid
);
512 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
514 hr
= IMediaDet_get_StreamType(pM
, NULL
);
515 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
517 hr
= IMediaDet_get_StreamTypeB(pM
, &bstr
);
518 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
520 hr
= IMediaDet_get_StreamTypeB(pM
, NULL
);
521 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
523 hr
= IMediaDet_get_Filter(pM
, NULL
);
524 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
526 unk
= (IUnknown
*)0xdeadbeef;
527 hr
= IMediaDet_get_Filter(pM
, &unk
);
528 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
529 ok(!unk
, "Got filter %p.\n", unk
);
531 filename
= SysAllocString(test_avi_filename
);
532 hr
= IMediaDet_put_Filename(pM
, filename
);
533 ok(hr
== S_OK
, "IMediaDet_put_Filename failed: %08x\n", hr
);
534 SysFreeString(filename
);
537 /* The stream defaults to 0. */
538 hr
= IMediaDet_get_CurrentStream(pM
, &strm
);
539 ok(hr
== S_OK
, "IMediaDet_get_CurrentStream failed: %08x\n", hr
);
540 ok(strm
== 0, "IMediaDet_get_CurrentStream: strm is %i\n", strm
);
542 ZeroMemory(&mt
, sizeof mt
);
543 hr
= IMediaDet_get_StreamMediaType(pM
, &mt
);
544 ok(hr
== S_OK
, "IMediaDet_get_StreamMediaType failed: %08x\n", hr
);
545 CoTaskMemFree(mt
.pbFormat
);
547 hr
= IMediaDet_get_StreamType(pM
, &guid
);
548 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
549 ok(IsEqualGUID(&guid
, &MEDIATYPE_Video
), "Got major type %s.\n", debugstr_guid(&guid
));
551 hr
= IMediaDet_get_StreamTypeB(pM
, &bstr
);
552 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
553 ok(!wcscmp(bstr
, L
"{73646976-0000-0010-8000-00AA00389B71}"),
554 "Got major type %s.\n", debugstr_w(bstr
));
557 /* Even before get_OutputStreams. */
558 hr
= IMediaDet_put_CurrentStream(pM
, 1);
559 ok(hr
== E_INVALIDARG
, "IMediaDet_put_CurrentStream failed: %08x\n", hr
);
561 hr
= IMediaDet_get_OutputStreams(pM
, &nstrms
);
562 ok(hr
== S_OK
, "IMediaDet_get_OutputStreams failed: %08x\n", hr
);
563 ok(nstrms
== 1, "IMediaDet_get_OutputStreams: nstrms is %i\n", nstrms
);
566 hr
= IMediaDet_get_Filename(pM
, &filename
);
567 ok(hr
== S_OK
, "IMediaDet_get_Filename failed: %08x\n", hr
);
568 ok(!wcscmp(filename
, test_avi_filename
), "Expected filename %s, got %s.\n",
569 debugstr_w(test_avi_filename
), debugstr_w(filename
));
570 SysFreeString(filename
);
572 hr
= IMediaDet_get_Filename(pM
, NULL
);
573 ok(hr
== E_POINTER
, "IMediaDet_get_Filename failed: %08x\n", hr
);
576 hr
= IMediaDet_get_CurrentStream(pM
, &strm
);
577 ok(hr
== S_OK
, "IMediaDet_get_CurrentStream failed: %08x\n", hr
);
578 ok(strm
== 0, "IMediaDet_get_CurrentStream: strm is %i\n", strm
);
580 hr
= IMediaDet_get_CurrentStream(pM
, NULL
);
581 ok(hr
== E_POINTER
, "IMediaDet_get_CurrentStream failed: %08x\n", hr
);
583 hr
= IMediaDet_put_CurrentStream(pM
, -1);
584 ok(hr
== E_INVALIDARG
, "IMediaDet_put_CurrentStream failed: %08x\n", hr
);
586 hr
= IMediaDet_put_CurrentStream(pM
, 1);
587 ok(hr
== E_INVALIDARG
, "IMediaDet_put_CurrentStream failed: %08x\n", hr
);
591 hr
= IMediaDet_get_CurrentStream(pM
, &strm
);
592 ok(hr
== S_OK
, "IMediaDet_get_CurrentStream failed: %08x\n", hr
);
593 ok(strm
== 0, "IMediaDet_get_CurrentStream: strm is %i\n", strm
);
595 hr
= IMediaDet_put_CurrentStream(pM
, 0);
596 ok(hr
== S_OK
, "IMediaDet_put_CurrentStream failed: %08x\n", hr
);
599 hr
= IMediaDet_get_CurrentStream(pM
, &strm
);
600 ok(hr
== S_OK
, "IMediaDet_get_CurrentStream failed: %08x\n", hr
);
601 ok(strm
== 0, "IMediaDet_get_CurrentStream: strm is %i\n", strm
);
603 ZeroMemory(&mt
, sizeof mt
);
604 hr
= IMediaDet_get_StreamMediaType(pM
, &mt
);
605 ok(hr
== S_OK
, "IMediaDet_get_StreamMediaType failed: %08x\n", hr
);
606 ok(IsEqualGUID(&mt
.majortype
, &MEDIATYPE_Video
),
607 "IMediaDet_get_StreamMediaType\n");
608 CoTaskMemFree(mt
.pbFormat
);
610 hr
= IMediaDet_get_StreamType(pM
, &guid
);
611 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
612 ok(IsEqualGUID(&guid
, &MEDIATYPE_Video
), "Got major type %s.\n", debugstr_guid(&guid
));
614 hr
= IMediaDet_get_StreamTypeB(pM
, &bstr
);
615 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
616 ok(!wcscmp(bstr
, L
"{73646976-0000-0010-8000-00AA00389B71}"),
617 "Got major type %s.\n", debugstr_w(bstr
));
620 hr
= IMediaDet_get_FrameRate(pM
, NULL
);
621 ok(hr
== E_POINTER
, "IMediaDet_get_FrameRate failed: %08x\n", hr
);
623 hr
= IMediaDet_get_FrameRate(pM
, &fps
);
624 ok(hr
== S_OK
, "IMediaDet_get_FrameRate failed: %08x\n", hr
);
625 ok(fps
== 10.0, "IMediaDet_get_FrameRate: fps is %f\n", fps
);
627 hr
= IMediaDet_Release(pM
);
628 ok(hr
== 0, "IMediaDet_Release returned: %x\n", hr
);
630 /* test_sound.avi has one video stream and one audio stream. */
631 hr
= CoCreateInstance(&CLSID_MediaDet
, NULL
, CLSCTX_INPROC_SERVER
,
632 &IID_IMediaDet
, (LPVOID
*)&pM
);
633 ok(hr
== S_OK
, "CoCreateInstance failed with %x\n", hr
);
634 ok(pM
!= NULL
, "pM is NULL\n");
636 filename
= SysAllocString(test_sound_avi_filename
);
637 hr
= IMediaDet_put_Filename(pM
, filename
);
638 ok(hr
== S_OK
, "IMediaDet_put_Filename failed: %08x\n", hr
);
639 SysFreeString(filename
);
641 hr
= IMediaDet_get_OutputStreams(pM
, &nstrms
);
642 ok(hr
== S_OK
, "IMediaDet_get_OutputStreams failed: %08x\n", hr
);
643 ok(nstrms
== 2, "IMediaDet_get_OutputStreams: nstrms is %i\n", nstrms
);
646 hr
= IMediaDet_get_Filename(pM
, &filename
);
647 ok(hr
== S_OK
, "IMediaDet_get_Filename failed: %08x\n", hr
);
648 ok(!wcscmp(filename
, test_sound_avi_filename
), "Expected filename %s, got %s.\n",
649 debugstr_w(test_sound_avi_filename
), debugstr_w(filename
));
650 SysFreeString(filename
);
652 /* I don't know if the stream order is deterministic. Just check
653 for both an audio and video stream. */
656 for (i
= 0; i
< 2; ++i
)
658 hr
= IMediaDet_put_CurrentStream(pM
, i
);
659 ok(hr
== S_OK
, "IMediaDet_put_CurrentStream failed: %08x\n", hr
);
662 hr
= IMediaDet_get_CurrentStream(pM
, &strm
);
663 ok(hr
== S_OK
, "IMediaDet_get_CurrentStream failed: %08x\n", hr
);
664 ok(strm
== i
, "IMediaDet_get_CurrentStream: strm is %i\n", strm
);
666 ZeroMemory(&mt
, sizeof mt
);
667 hr
= IMediaDet_get_StreamMediaType(pM
, &mt
);
668 ok(hr
== S_OK
, "IMediaDet_get_StreamMediaType failed: %08x\n", hr
);
669 flags
+= (IsEqualGUID(&mt
.majortype
, &MEDIATYPE_Video
)
671 : (IsEqualGUID(&mt
.majortype
, &MEDIATYPE_Audio
)
675 if (IsEqualGUID(&mt
.majortype
, &MEDIATYPE_Audio
))
677 hr
= IMediaDet_get_StreamType(pM
, &guid
);
678 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
679 ok(IsEqualGUID(&guid
, &MEDIATYPE_Audio
), "Got major type %s.\n", debugstr_guid(&guid
));
681 hr
= IMediaDet_get_StreamTypeB(pM
, &bstr
);
682 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
683 ok(!wcscmp(bstr
, L
"{73647561-0000-0010-8000-00AA00389B71}"),
684 "Got major type %s.\n", debugstr_w(bstr
));
687 hr
= IMediaDet_get_FrameRate(pM
, &fps
);
688 ok(hr
== VFW_E_INVALIDMEDIATYPE
, "IMediaDet_get_FrameRate failed: %08x\n", hr
);
691 CoTaskMemFree(mt
.pbFormat
);
693 ok(flags
== 3, "IMediaDet_get_StreamMediaType: flags are %i\n", flags
);
695 hr
= IMediaDet_put_CurrentStream(pM
, 2);
696 ok(hr
== E_INVALIDARG
, "IMediaDet_put_CurrentStream failed: %08x\n", hr
);
699 hr
= IMediaDet_get_CurrentStream(pM
, &strm
);
700 ok(hr
== S_OK
, "IMediaDet_get_CurrentStream failed: %08x\n", hr
);
701 ok(strm
== 1, "IMediaDet_get_CurrentStream: strm is %i\n", strm
);
704 hr
= IMediaDet_get_Filter(pM
, &unk
);
705 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
706 ok(!!unk
, "Expected a non-NULL filter.\n");
707 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void**)&filter
);
708 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
709 IUnknown_Release(unk
);
711 hr
= IBaseFilter_EnumPins(filter
, &enumpins
);
712 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
713 hr
= IEnumPins_Next(enumpins
, 1, &pin
, NULL
);
714 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
715 hr
= IPin_EnumMediaTypes(pin
, &type
);
716 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
717 hr
= IEnumMediaTypes_Next(type
, 1, &pmt
, NULL
);
718 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
719 ok(IsEqualGUID(&pmt
->majortype
, &MEDIATYPE_Stream
), "Got major type %s.\n",
720 debugstr_guid(&pmt
->majortype
));
721 IEnumMediaTypes_Release(type
);
722 CoTaskMemFree(pmt
->pbFormat
);
726 hr
= IEnumPins_Next(enumpins
, 1, &pin
, NULL
);
727 ok(hr
== S_FALSE
, "Got hr %#x.\n", hr
);
728 IEnumPins_Release(enumpins
);
730 hr
= IBaseFilter_QueryFilterInfo(filter
, &filter_info
);
731 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
732 ok(!wcscmp(filter_info
.achName
, L
"Source"), "Got name %s.\n", debugstr_w(filter_info
.achName
));
733 IFilterGraph_Release(filter_info
.pGraph
);
734 IBaseFilter_Release(filter
);
736 hr
= IMediaDet_Release(pM
);
737 ok(hr
== 0, "IMediaDet_Release returned: %x\n", hr
);
740 static void test_put_filter(void)
742 struct testfilter testfilter
, testfilter2
;
754 hr
= CoCreateInstance(&CLSID_MediaDet
, NULL
, CLSCTX_INPROC_SERVER
,
755 &IID_IMediaDet
, (void **)&detector
);
756 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
758 hr
= IMediaDet_put_Filter(detector
, NULL
);
759 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
761 hr
= IMediaDet_get_Filter(detector
, NULL
);
762 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
764 hr
= IMediaDet_get_StreamLength(detector
, NULL
);
765 ok(hr
== E_POINTER
, "Got hr %#x.\n", hr
);
767 hr
= IMediaDet_get_StreamLength(detector
, &duration
);
768 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
770 testfilter_init(&testfilter
);
771 hr
= IMediaDet_put_Filter(detector
, &testfilter
.filter
.IUnknown_inner
);
772 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
774 hr
= IMediaDet_get_Filter(detector
, &unk
);
775 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
776 ok(!!unk
, "Expected a non-NULL interface.\n");
777 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void **)&filter
);
778 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
779 ok(filter
== &testfilter
.filter
.IBaseFilter_iface
, "Expected the same filter.\n");
780 IBaseFilter_Release(filter
);
781 IUnknown_Release(unk
);
783 ok(!wcscmp(testfilter
.filter
.name
, L
"Source"), "Got name %s.\n",
784 debugstr_w(testfilter
.filter
.name
));
785 graph
= testfilter
.filter
.graph
;
786 IFilterGraph_AddRef(graph
);
788 testfilter_init(&testfilter2
);
789 hr
= IMediaDet_put_Filter(detector
, &testfilter2
.filter
.IUnknown_inner
);
790 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
792 hr
= IMediaDet_get_Filter(detector
, &unk
);
793 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
794 ok(!!unk
, "Expected a non-NULL interface.\n");
795 hr
= IUnknown_QueryInterface(unk
, &IID_IBaseFilter
, (void **)&filter
);
796 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
797 ok(filter
== &testfilter2
.filter
.IBaseFilter_iface
, "Expected the same filter.\n");
798 IBaseFilter_Release(filter
);
799 IUnknown_Release(unk
);
801 ok(testfilter2
.filter
.graph
!= graph
, "Expected a different graph.\n");
803 ref
= IFilterGraph_Release(graph
);
804 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
805 ref
= IBaseFilter_Release(&testfilter
.filter
.IBaseFilter_iface
);
806 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
809 hr
= IMediaDet_get_OutputStreams(detector
, &count
);
810 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
811 ok(count
== 1, "Got %d streams.\n", count
);
814 hr
= IMediaDet_get_CurrentStream(detector
, &index
);
815 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
816 ok(index
== 0, "Got stream %d.\n", index
);
818 filename
= (BSTR
)0xdeadbeef;
819 hr
= IMediaDet_get_Filename(detector
, &filename
);
820 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
821 ok(!filename
, "Got filename %s.\n", debugstr_w(filename
));
823 hr
= IMediaDet_get_StreamLength(detector
, &duration
);
824 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
825 ok(duration
== 4.2, "Got duration %.16e.\n", duration
);
827 ref
= IMediaDet_Release(detector
);
828 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
829 ref
= IBaseFilter_Release(&testfilter2
.filter
.IBaseFilter_iface
);
830 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
832 hr
= CoCreateInstance(&CLSID_MediaDet
, NULL
, CLSCTX_INPROC_SERVER
,
833 &IID_IMediaDet
, (void **)&detector
);
834 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
836 filename
= SysAllocString(test_sound_avi_filename
);
837 hr
= IMediaDet_put_Filename(detector
, filename
);
838 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
839 SysFreeString(filename
);
841 hr
= IMediaDet_get_StreamMediaType(detector
, &mt
);
842 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
845 hr
= IMediaDet_get_Filter(detector
, &unk
);
846 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
847 hr
= IMediaDet_put_Filter(detector
, unk
);
848 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
849 IUnknown_Release(unk
);
851 filename
= (BSTR
)0xdeadbeef;
852 hr
= IMediaDet_get_Filename(detector
, &filename
);
853 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
854 ok(!filename
, "Got filename %s.\n", debugstr_w(filename
));
857 hr
= IMediaDet_get_OutputStreams(detector
, &count
);
858 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
859 ok(count
== 2, "Got %d streams.\n", count
);
862 hr
= IMediaDet_get_CurrentStream(detector
, &index
);
863 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
864 ok(index
== 0, "Got stream %d.\n", index
);
866 ref
= IMediaDet_Release(detector
);
867 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
870 static HRESULT WINAPI
ms_QueryInterface(IMediaSample
*iface
, REFIID riid
,
876 static ULONG WINAPI
ms_AddRef(IMediaSample
*iface
)
881 static ULONG WINAPI
ms_Release(IMediaSample
*iface
)
886 static HRESULT WINAPI
ms_GetPointer(IMediaSample
*iface
, BYTE
**ppBuffer
)
891 static LONG WINAPI
ms_GetSize(IMediaSample
*iface
)
896 static HRESULT WINAPI
ms_GetTime(IMediaSample
*iface
, REFERENCE_TIME
*pTimeStart
,
897 REFERENCE_TIME
*pTimeEnd
)
902 static HRESULT WINAPI
ms_SetTime(IMediaSample
*iface
, REFERENCE_TIME
*pTimeStart
,
903 REFERENCE_TIME
*pTimeEnd
)
908 static HRESULT WINAPI
ms_IsSyncPoint(IMediaSample
*iface
)
913 static HRESULT WINAPI
ms_SetSyncPoint(IMediaSample
*iface
, BOOL bIsSyncPoint
)
918 static HRESULT WINAPI
ms_IsPreroll(IMediaSample
*iface
)
923 static HRESULT WINAPI
ms_SetPreroll(IMediaSample
*iface
, BOOL bIsPreroll
)
928 static LONG WINAPI
ms_GetActualDataLength(IMediaSample
*iface
)
933 static HRESULT WINAPI
ms_SetActualDataLength(IMediaSample
*iface
, LONG length
)
938 static HRESULT WINAPI
ms_GetMediaType(IMediaSample
*iface
, AM_MEDIA_TYPE
944 static HRESULT WINAPI
ms_SetMediaType(IMediaSample
*iface
, AM_MEDIA_TYPE
*pMediaType
)
949 static HRESULT WINAPI
ms_IsDiscontinuity(IMediaSample
*iface
)
954 static HRESULT WINAPI
ms_SetDiscontinuity(IMediaSample
*iface
, BOOL bDiscontinuity
)
959 static HRESULT WINAPI
ms_GetMediaTime(IMediaSample
*iface
, LONGLONG
*pTimeStart
,
965 static HRESULT WINAPI
ms_SetMediaTime(IMediaSample
*iface
, LONGLONG
*pTimeStart
,
971 static const IMediaSampleVtbl my_sample_vt
= {
983 ms_GetActualDataLength
,
984 ms_SetActualDataLength
,
993 static IMediaSample my_sample
= { &my_sample_vt
};
995 static BOOL samplecb_called
= FALSE
;
997 static HRESULT WINAPI
sgcb_QueryInterface(ISampleGrabberCB
*iface
, REFIID riid
,
1003 static ULONG WINAPI
sgcb_AddRef(ISampleGrabberCB
*iface
)
1008 static ULONG WINAPI
sgcb_Release(ISampleGrabberCB
*iface
)
1013 static HRESULT WINAPI
sgcb_SampleCB(ISampleGrabberCB
*iface
, double SampleTime
,
1014 IMediaSample
*pSample
)
1016 ok(pSample
== &my_sample
, "Got wrong IMediaSample: %p, expected %p\n", pSample
, &my_sample
);
1017 samplecb_called
= TRUE
;
1021 static HRESULT WINAPI
sgcb_BufferCB(ISampleGrabberCB
*iface
, double SampleTime
,
1022 BYTE
*pBuffer
, LONG BufferLen
)
1024 ok(0, "BufferCB should not have been called\n");
1028 static const ISampleGrabberCBVtbl sgcb_vt
= {
1029 sgcb_QueryInterface
,
1036 static ISampleGrabberCB my_sg_cb
= { &sgcb_vt
};
1038 static void test_samplegrabber(void)
1043 IMemInputPin
*inpin
;
1046 FILTER_STATE fstate
;
1049 hr
= CoCreateInstance(&CLSID_SampleGrabber
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IClassFactory
,
1051 ok(hr
== E_NOINTERFACE
, "SampleGrabber create failed: %08x, expected E_NOINTERFACE\n", hr
);
1053 hr
= CoCreateInstance(&CLSID_SampleGrabber
, NULL
, CLSCTX_INPROC_SERVER
, &IID_ISampleGrabber
,
1055 ok(hr
== S_OK
, "SampleGrabber create failed: %08x, expected S_OK\n", hr
);
1057 hr
= ISampleGrabber_QueryInterface(sg
, &IID_IBaseFilter
, (void**)&bf
);
1058 ok(hr
== S_OK
, "QueryInterface for IID_IBaseFilter failed: %08x\n", hr
);
1060 hr
= ISampleGrabber_SetCallback(sg
, &my_sg_cb
, 0);
1061 ok(hr
== S_OK
, "SetCallback failed: %08x\n", hr
);
1063 hr
= IBaseFilter_GetState(bf
, 100, &fstate
);
1064 ok(hr
== S_OK
, "Failed to get filter state: %08x\n", hr
);
1065 ok(fstate
== State_Stopped
, "Got wrong filter state: %u\n", fstate
);
1067 hr
= IBaseFilter_EnumPins(bf
, &pins
);
1068 ok(hr
== S_OK
, "EnumPins create failed: %08x, expected S_OK\n", hr
);
1070 hr
= IEnumPins_Next(pins
, 1, &pin
, NULL
);
1071 ok(hr
== S_OK
, "Next failed: %08x\n", hr
);
1073 IEnumPins_Release(pins
);
1075 hr
= IPin_QueryInterface(pin
, &IID_IMemInputPin
, (void**)&inpin
);
1076 ok(hr
== S_OK
, "QueryInterface(IMemInputPin) failed: %08x\n", hr
);
1078 hr
= IMemInputPin_Receive(inpin
, &my_sample
);
1079 ok(hr
== S_OK
, "Receive failed: %08x\n", hr
);
1080 ok(samplecb_called
== TRUE
, "SampleCB should have been called\n");
1082 IMemInputPin_Release(inpin
);
1085 while (ISampleGrabber_Release(sg
));
1088 static void test_COM_sg_enumpins(void)
1091 IEnumPins
*pins
, *pins2
;
1096 hr
= CoCreateInstance(&CLSID_SampleGrabber
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IBaseFilter
,
1098 ok(hr
== S_OK
, "SampleGrabber create failed: %08x, expected S_OK\n", hr
);
1099 hr
= IBaseFilter_EnumPins(bf
, &pins
);
1100 ok(hr
== S_OK
, "EnumPins create failed: %08x, expected S_OK\n", hr
);
1102 /* Same refcount for all EnumPins interfaces */
1103 refcount
= IEnumPins_AddRef(pins
);
1104 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
1105 hr
= IEnumPins_QueryInterface(pins
, &IID_IEnumPins
, (void**)&pins2
);
1106 ok(hr
== S_OK
, "QueryInterface for IID_IEnumPins failed: %08x\n", hr
);
1107 ok(pins
== pins2
, "QueryInterface for self failed (%p != %p)\n", pins
, pins2
);
1108 IEnumPins_Release(pins2
);
1110 hr
= IEnumPins_QueryInterface(pins
, &IID_IUnknown
, (void**)&unk
);
1111 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
1112 refcount
= IUnknown_AddRef(unk
);
1113 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
1114 refcount
= IUnknown_Release(unk
);
1116 while (IEnumPins_Release(pins
));
1117 IBaseFilter_Release(bf
);
1120 START_TEST(mediadet
)
1122 IMediaDet
*detector
;
1128 skip("Couldn't initialize tests!\n");
1134 if (FAILED(hr
= CoCreateInstance(&CLSID_MediaDet
, NULL
, CLSCTX_INPROC_SERVER
,
1135 &IID_IMediaDet
, (void **)&detector
)))
1137 /* qedit.dll does not exist on 2003. */
1138 win_skip("Failed to create media detector object, hr %#x.\n", hr
);
1141 IMediaDet_Release(detector
);
1146 test_samplegrabber();
1147 test_COM_sg_enumpins();
1149 ret
= DeleteFileW(test_avi_filename
);
1150 todo_wine
ok(ret
, "Failed to delete file, error %u.\n", GetLastError());
1151 ret
= DeleteFileW(test_sound_avi_filename
);
1152 todo_wine
ok(ret
, "Failed to delete file, error %u.\n", GetLastError());