2 * Copyright 2017 Alistair Leslie-Hughes
3 * Copyright 2019 Vijay Kiran Kamuju
4 * Copyright 2021 Zebediah Figura for CodeWeavers
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
23 #define WIN32_LEAN_AND_MEAN
29 #include "wmcodecdsp.h"
31 #include "wine/test.h"
33 HRESULT WINAPI
WMCreateWriterPriv(IWMWriter
**writer
);
35 static BOOL
compare_media_types(const WM_MEDIA_TYPE
*a
, const WM_MEDIA_TYPE
*b
)
37 /* We can't use memcmp(), because WM_MEDIA_TYPE has a hole, which sometimes
40 return IsEqualGUID(&a
->majortype
, &b
->majortype
)
41 && IsEqualGUID(&a
->subtype
, &b
->subtype
)
42 && a
->bFixedSizeSamples
== b
->bFixedSizeSamples
43 && a
->bTemporalCompression
== b
->bTemporalCompression
44 && a
->lSampleSize
== b
->lSampleSize
45 && IsEqualGUID(&a
->formattype
, &b
->formattype
)
47 && a
->cbFormat
== b
->cbFormat
48 && !memcmp(a
->pbFormat
, b
->pbFormat
, a
->cbFormat
);
51 static WCHAR
*load_resource(const WCHAR
*name
)
53 static WCHAR pathW
[MAX_PATH
];
59 GetTempPathW(ARRAY_SIZE(pathW
), pathW
);
62 file
= CreateFileW(pathW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
63 ok(file
!= INVALID_HANDLE_VALUE
, "Failed to create file %s, error %u.\n",
64 wine_dbgstr_w(pathW
), GetLastError());
66 res
= FindResourceW(NULL
, name
, (LPCWSTR
)RT_RCDATA
);
67 ok(!!res
, "Failed to load resource, error %u.\n", GetLastError());
68 ptr
= LockResource(LoadResource(GetModuleHandleA(NULL
), res
));
69 WriteFile(file
, ptr
, SizeofResource( GetModuleHandleA(NULL
), res
), &written
, NULL
);
70 ok(written
== SizeofResource(GetModuleHandleA(NULL
), res
), "Failed to write resource.\n");
76 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
77 static HRESULT
check_interface_(unsigned int line
, void *iface
, REFIID riid
, BOOL supported
)
79 HRESULT hr
, expected_hr
;
80 IUnknown
*unknown
= iface
, *out
;
82 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
84 hr
= IUnknown_QueryInterface(unknown
, riid
, (void **)&out
);
85 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
87 IUnknown_Release(out
);
91 static void test_wmwriter_interfaces(void)
96 hr
= WMCreateWriter( NULL
, &writer
);
97 ok(hr
== S_OK
, "WMCreateWriter failed 0x%08x\n", hr
);
100 win_skip("Failed to create IWMWriter\n");
104 check_interface(writer
, &IID_IWMWriterSink
, FALSE
);
106 check_interface(writer
, &IID_IWMWriter
, TRUE
);
107 check_interface(writer
, &IID_IWMWriterAdvanced
, TRUE
);
108 check_interface(writer
, &IID_IWMWriterAdvanced2
, TRUE
);
109 check_interface(writer
, &IID_IWMWriterAdvanced3
, TRUE
);
110 todo_wine
check_interface(writer
, &IID_IWMWriterPreprocess
, TRUE
);
111 todo_wine
check_interface(writer
, &IID_IWMHeaderInfo
, TRUE
);
112 todo_wine
check_interface(writer
, &IID_IWMHeaderInfo2
, TRUE
);
113 todo_wine
check_interface(writer
, &IID_IWMHeaderInfo3
, TRUE
);
115 IWMWriter_Release(writer
);
118 static void test_wmreader_interfaces(void)
123 hr
= WMCreateReader( NULL
, 0, &reader
);
124 ok(hr
== S_OK
, "WMCreateReader failed 0x%08x\n", hr
);
127 win_skip("Failed to create IWMReader\n");
131 check_interface(reader
, &IID_IWMDRMReader
, FALSE
);
132 check_interface(reader
, &IID_IWMDRMReader2
, FALSE
);
133 check_interface(reader
, &IID_IWMDRMReader3
, FALSE
);
134 check_interface(reader
, &IID_IWMSyncReader
, FALSE
);
135 check_interface(reader
, &IID_IWMSyncReader2
, FALSE
);
137 check_interface(reader
, &IID_IReferenceClock
, TRUE
);
138 check_interface(reader
, &IID_IWMHeaderInfo
, TRUE
);
139 check_interface(reader
, &IID_IWMHeaderInfo2
, TRUE
);
140 check_interface(reader
, &IID_IWMHeaderInfo3
, TRUE
);
141 check_interface(reader
, &IID_IWMLanguageList
, TRUE
);
142 check_interface(reader
, &IID_IWMPacketSize
, TRUE
);
143 check_interface(reader
, &IID_IWMPacketSize2
, TRUE
);
144 check_interface(reader
, &IID_IWMProfile
, TRUE
);
145 check_interface(reader
, &IID_IWMProfile2
, TRUE
);
146 check_interface(reader
, &IID_IWMProfile3
, TRUE
);
147 check_interface(reader
, &IID_IWMReader
, TRUE
);
148 check_interface(reader
, &IID_IWMReaderAccelerator
, TRUE
);
149 check_interface(reader
, &IID_IWMReaderAdvanced
, TRUE
);
150 check_interface(reader
, &IID_IWMReaderAdvanced2
, TRUE
);
151 check_interface(reader
, &IID_IWMReaderAdvanced3
, TRUE
);
152 check_interface(reader
, &IID_IWMReaderAdvanced4
, TRUE
);
153 check_interface(reader
, &IID_IWMReaderAdvanced5
, TRUE
);
154 check_interface(reader
, &IID_IWMReaderAdvanced6
, TRUE
);
155 check_interface(reader
, &IID_IWMReaderNetworkConfig
, TRUE
);
156 check_interface(reader
, &IID_IWMReaderNetworkConfig2
, TRUE
);
157 check_interface(reader
, &IID_IWMReaderPlaylistBurn
, TRUE
);
158 check_interface(reader
, &IID_IWMReaderStreamClock
, TRUE
);
159 check_interface(reader
, &IID_IWMReaderTimecode
, TRUE
);
160 check_interface(reader
, &IID_IWMReaderTypeNegotiation
, TRUE
);
162 IWMReader_Release(reader
);
165 static void test_wmsyncreader_interfaces(void)
168 IWMSyncReader
*reader
;
170 hr
= WMCreateSyncReader( NULL
, 0, &reader
);
171 ok(hr
== S_OK
, "WMCreateSyncReader failed 0x%08x\n", hr
);
174 win_skip("Failed to create IWMSyncReader\n");
178 check_interface(reader
, &IID_IReferenceClock
, FALSE
);
179 check_interface(reader
, &IID_IWMDRMReader
, FALSE
);
180 check_interface(reader
, &IID_IWMDRMReader2
, FALSE
);
181 check_interface(reader
, &IID_IWMDRMReader3
, FALSE
);
182 check_interface(reader
, &IID_IWMReader
, FALSE
);
183 check_interface(reader
, &IID_IWMReaderAccelerator
, FALSE
);
184 check_interface(reader
, &IID_IWMReaderAdvanced
, FALSE
);
185 check_interface(reader
, &IID_IWMReaderAdvanced2
, FALSE
);
186 check_interface(reader
, &IID_IWMReaderAdvanced3
, FALSE
);
187 check_interface(reader
, &IID_IWMReaderAdvanced4
, FALSE
);
188 check_interface(reader
, &IID_IWMReaderAdvanced5
, FALSE
);
189 check_interface(reader
, &IID_IWMReaderAdvanced6
, FALSE
);
190 check_interface(reader
, &IID_IWMReaderNetworkConfig
, FALSE
);
191 check_interface(reader
, &IID_IWMReaderNetworkConfig2
, FALSE
);
192 check_interface(reader
, &IID_IWMReaderStreamClock
, FALSE
);
193 check_interface(reader
, &IID_IWMReaderTypeNegotiation
, FALSE
);
195 check_interface(reader
, &IID_IWMHeaderInfo
, TRUE
);
196 check_interface(reader
, &IID_IWMHeaderInfo2
, TRUE
);
197 check_interface(reader
, &IID_IWMHeaderInfo3
, TRUE
);
198 check_interface(reader
, &IID_IWMLanguageList
, TRUE
);
199 check_interface(reader
, &IID_IWMPacketSize
, TRUE
);
200 check_interface(reader
, &IID_IWMPacketSize2
, TRUE
);
201 check_interface(reader
, &IID_IWMProfile
, TRUE
);
202 check_interface(reader
, &IID_IWMProfile2
, TRUE
);
203 check_interface(reader
, &IID_IWMProfile3
, TRUE
);
204 check_interface(reader
, &IID_IWMReaderPlaylistBurn
, TRUE
);
205 check_interface(reader
, &IID_IWMReaderTimecode
, TRUE
);
206 check_interface(reader
, &IID_IWMSyncReader
, TRUE
);
207 check_interface(reader
, &IID_IWMSyncReader2
, TRUE
);
209 IWMSyncReader_Release(reader
);
213 static void test_profile_manager_interfaces(void)
216 IWMProfileManager
*profile
;
218 hr
= WMCreateProfileManager(&profile
);
219 ok(hr
== S_OK
, "WMCreateProfileManager failed 0x%08x\n", hr
);
222 win_skip("Failed to create IWMProfileManager\n");
226 IWMProfileManager_Release(profile
);
229 static void test_WMCreateWriterPriv(void)
231 IWMWriter
*writer
, *writer2
;
234 hr
= WMCreateWriterPriv(&writer
);
235 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
237 hr
= IWMWriter_QueryInterface(writer
, &IID_IWMWriter
, (void**)&writer2
);
238 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
240 IWMWriter_Release(writer
);
241 IWMWriter_Release(writer2
);
244 static void test_urlextension(void)
248 hr
= WMCheckURLExtension(NULL
);
249 ok(hr
== E_INVALIDARG
, "WMCheckURLExtension failed 0x%08x\n", hr
);
250 hr
= WMCheckURLExtension(L
"test.mkv");
251 ok(hr
== NS_E_INVALID_NAME
, "WMCheckURLExtension failed 0x%08x\n", hr
);
252 hr
= WMCheckURLExtension(L
"test.mp3");
253 todo_wine
ok(hr
== S_OK
, "WMCheckURLExtension failed 0x%08x\n", hr
);
254 hr
= WMCheckURLExtension(L
"abcd://test/test.wmv");
255 todo_wine
ok(hr
== S_OK
, "WMCheckURLExtension failed 0x%08x\n", hr
);
256 hr
= WMCheckURLExtension(L
"http://test/t.asf?alt=t.mkv");
257 todo_wine
ok(hr
== S_OK
, "WMCheckURLExtension failed 0x%08x\n", hr
);
260 static void test_iscontentprotected(void)
265 hr
= WMIsContentProtected(NULL
, NULL
);
266 ok(hr
== E_INVALIDARG
, "WMIsContentProtected failed 0x%08x\n", hr
);
267 hr
= WMIsContentProtected(NULL
, &drm
);
268 ok(hr
== E_INVALIDARG
, "WMIsContentProtected failed 0x%08x\n", hr
);
269 hr
= WMIsContentProtected(L
"test.mp3", NULL
);
270 ok(hr
== E_INVALIDARG
, "WMIsContentProtected failed 0x%08x\n", hr
);
271 hr
= WMIsContentProtected(L
"test.mp3", &drm
);
272 ok(hr
== S_FALSE
, "WMIsContentProtected failed 0x%08x\n", hr
);
273 ok(drm
== FALSE
, "got %0dx\n", drm
);
278 IStream IStream_iface
;
283 static struct teststream
*impl_from_IStream(IStream
*iface
)
285 return CONTAINING_RECORD(iface
, struct teststream
, IStream_iface
);
288 static HRESULT WINAPI
stream_QueryInterface(IStream
*iface
, REFIID iid
, void **out
)
290 if (winetest_debug
> 1)
291 trace("%04x: IStream::QueryInterface(%s)\n", GetCurrentThreadId(), debugstr_guid(iid
));
293 if (!IsEqualGUID(iid
, &IID_IWMGetSecureChannel
) && !IsEqualGUID(iid
, &IID_IWMIStreamProps
))
294 ok(0, "Unexpected IID %s.\n", debugstr_guid(iid
));
296 return E_NOINTERFACE
;
299 static ULONG WINAPI
stream_AddRef(IStream
*iface
)
301 struct teststream
*stream
= impl_from_IStream(iface
);
303 return InterlockedIncrement(&stream
->refcount
);
306 static ULONG WINAPI
stream_Release(IStream
*iface
)
308 struct teststream
*stream
= impl_from_IStream(iface
);
310 return InterlockedDecrement(&stream
->refcount
);
313 static HRESULT WINAPI
stream_Read(IStream
*iface
, void *data
, ULONG size
, ULONG
*ret_size
)
315 struct teststream
*stream
= impl_from_IStream(iface
);
317 if (winetest_debug
> 2)
318 trace("%04x: IStream::Read(size %u)\n", GetCurrentThreadId(), size
);
320 ok(size
> 0, "Got zero size.\n");
321 ok(!!ret_size
, "Got NULL ret_size pointer.\n");
322 if (!ReadFile(stream
->file
, data
, size
, ret_size
, NULL
))
323 return HRESULT_FROM_WIN32(GetLastError());
327 static HRESULT WINAPI
stream_Write(IStream
*iface
, const void *data
, ULONG size
, ULONG
*ret_size
)
329 ok(0, "Unexpected call.\n");
333 static HRESULT WINAPI
stream_Seek(IStream
*iface
, LARGE_INTEGER offset
, DWORD method
, ULARGE_INTEGER
*ret_offset
)
335 struct teststream
*stream
= impl_from_IStream(iface
);
338 if (winetest_debug
> 2)
339 trace("%04x: IStream::Seek(offset %I64u, method %#x)\n", GetCurrentThreadId(), offset
.QuadPart
, method
);
341 GetFileSizeEx(stream
->file
, &size
);
342 ok(offset
.QuadPart
< size
.QuadPart
, "Expected offset less than size %I64u, got %I64u.\n",
343 size
.QuadPart
, offset
.QuadPart
);
345 ok(method
== STREAM_SEEK_SET
, "Got method %#x.\n", method
);
346 ok(!ret_offset
, "Got unexpected ret_offset pointer %p\n", ret_offset
);
348 if (!SetFilePointerEx(stream
->file
, offset
, &offset
, method
))
349 return HRESULT_FROM_WIN32(GetLastError());
353 static HRESULT WINAPI
stream_SetSize(IStream
*iface
, ULARGE_INTEGER size
)
355 ok(0, "Unexpected call.\n");
359 static HRESULT WINAPI
stream_CopyTo(IStream
*iface
, IStream
*dest
, ULARGE_INTEGER size
,
360 ULARGE_INTEGER
*read_size
, ULARGE_INTEGER
*write_size
)
362 ok(0, "Unexpected call.\n");
366 static HRESULT WINAPI
stream_Commit(IStream
*iface
, DWORD flags
)
368 ok(0, "Unexpected call.\n");
372 static HRESULT WINAPI
stream_Revert(IStream
*iface
)
374 ok(0, "Unexpected call.\n");
378 static HRESULT WINAPI
stream_LockRegion(IStream
*iface
, ULARGE_INTEGER offset
, ULARGE_INTEGER size
, DWORD type
)
380 ok(0, "Unexpected call.\n");
384 static HRESULT WINAPI
stream_UnlockRegion(IStream
*iface
, ULARGE_INTEGER offset
, ULARGE_INTEGER size
, DWORD type
)
386 ok(0, "Unexpected call.\n");
390 static HRESULT WINAPI
stream_Stat(IStream
*iface
, STATSTG
*stat
, DWORD flags
)
392 struct teststream
*stream
= impl_from_IStream(iface
);
395 if (winetest_debug
> 1)
396 trace("%04x: IStream::Stat(flags %#x)\n", GetCurrentThreadId(), flags
);
398 ok(flags
== STATFLAG_NONAME
, "Got flags %#x.\n", flags
);
400 stat
->type
= 0xdeadbeef;
401 GetFileSizeEx(stream
->file
, &size
);
402 stat
->cbSize
.QuadPart
= size
.QuadPart
;
404 stat
->grfLocksSupported
= TRUE
;
409 static HRESULT WINAPI
stream_Clone(IStream
*iface
, IStream
**out
)
411 ok(0, "Unexpected call.\n");
415 static const IStreamVtbl stream_vtbl
=
417 stream_QueryInterface
,
433 static void teststream_init(struct teststream
*stream
, HANDLE file
)
435 memset(stream
, 0, sizeof(*stream
));
436 stream
->IStream_iface
.lpVtbl
= &stream_vtbl
;
437 stream
->refcount
= 1;
441 static void test_reader_attributes(IWMProfile
*profile
)
443 WORD size
, stream_number
, ret_stream_number
;
444 IWMHeaderInfo
*header_info
;
445 IWMStreamConfig
*config
;
446 WMT_ATTR_DATATYPE type
;
452 IWMProfile_QueryInterface(profile
, &IID_IWMHeaderInfo
, (void **)&header_info
);
454 hr
= IWMProfile_GetStreamCount(profile
, &count
);
455 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
456 ok(count
== 2, "Got count %u.\n", count
);
458 for (i
= 0; i
< count
; ++i
)
460 hr
= IWMProfile_GetStream(profile
, i
, &config
);
461 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
462 hr
= IWMStreamConfig_GetStreamNumber(config
, &stream_number
);
463 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
464 ret_stream_number
= stream_number
;
466 size
= sizeof(DWORD
);
469 hr
= IWMHeaderInfo_GetAttributeByName(header_info
, &ret_stream_number
,
470 L
"WM/VideoFrameRate", &type
, (BYTE
*)&dword
, &size
);
471 ok(hr
== ASF_E_NOTFOUND
, "Got hr %#x.\n", hr
);
472 ok(type
== 0xdeadbeef, "Got type %#x.\n", type
);
473 ok(size
== sizeof(DWORD
), "Got size %u.\n", size
);
474 ok(dword
== 0xdeadbeef, "Got frame rate %u.\n", dword
);
475 ok(ret_stream_number
== stream_number
, "Expected stream number %u, got %u.\n",
476 stream_number
, ret_stream_number
);
478 size
= sizeof(QWORD
);
480 duration
= 0xdeadbeef;
481 hr
= IWMHeaderInfo_GetAttributeByName(header_info
, &ret_stream_number
,
482 L
"Duration", &type
, (BYTE
*)&duration
, &size
);
483 ok(hr
== ASF_E_NOTFOUND
, "Got hr %#x.\n", hr
);
484 ok(type
== 0xdeadbeef, "Got type %#x.\n", type
);
485 ok(size
== sizeof(QWORD
), "Got size %u.\n", size
);
486 ok(ret_stream_number
== stream_number
, "Expected stream number %u, got %u.\n",
487 stream_number
, ret_stream_number
);
489 size
= sizeof(DWORD
);
492 hr
= IWMHeaderInfo_GetAttributeByName(header_info
, &ret_stream_number
,
493 L
"Seekable", &type
, (BYTE
*)&dword
, &size
);
494 ok(hr
== ASF_E_NOTFOUND
, "Got hr %#x.\n", hr
);
495 ok(type
== 0xdeadbeef, "Got type %#x.\n", type
);
496 ok(size
== sizeof(DWORD
), "Got size %u.\n", size
);
497 ok(ret_stream_number
== stream_number
, "Expected stream number %u, got %u.\n",
498 stream_number
, ret_stream_number
);
500 IWMStreamConfig_Release(config
);
503 /* WM/VideoFrameRate with a NULL stream number. */
505 size
= sizeof(DWORD
);
508 hr
= IWMHeaderInfo_GetAttributeByName(header_info
, NULL
,
509 L
"WM/VideoFrameRate", &type
, (BYTE
*)&dword
, &size
);
510 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
511 ok(type
== 0xdeadbeef, "Got type %#x.\n", type
);
512 ok(size
== sizeof(DWORD
), "Got size %u.\n", size
);
513 ok(dword
== 0xdeadbeef, "Got frame rate %u.\n", dword
);
515 /* And with a zero stream number. */
518 size
= sizeof(DWORD
);
521 hr
= IWMHeaderInfo_GetAttributeByName(header_info
, &stream_number
,
522 L
"WM/VideoFrameRate", &type
, (BYTE
*)&dword
, &size
);
523 ok(hr
== ASF_E_NOTFOUND
, "Got hr %#x.\n", hr
);
524 ok(type
== 0xdeadbeef, "Got type %#x.\n", type
);
525 ok(size
== sizeof(DWORD
), "Got size %u.\n", size
);
526 ok(dword
== 0xdeadbeef, "Got frame rate %u.\n", dword
);
527 ok(stream_number
== 0, "Got stream number %u.\n", stream_number
);
529 /* Duration with a NULL stream number. */
531 size
= sizeof(QWORD
);
533 duration
= 0xdeadbeef;
534 hr
= IWMHeaderInfo_GetAttributeByName(header_info
, NULL
,
535 L
"Duration", &type
, (BYTE
*)&duration
, &size
);
536 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
537 ok(type
== 0xdeadbeef, "Got type %#x.\n", type
);
538 ok(size
== sizeof(QWORD
), "Got size %u.\n", size
);
539 ok(duration
== 0xdeadbeef, "Got duration %I64u.\n", duration
);
541 /* And with a zero stream number. */
543 size
= sizeof(QWORD
);
545 duration
= 0xdeadbeef;
546 hr
= IWMHeaderInfo_GetAttributeByName(header_info
, &stream_number
,
547 L
"Duration", &type
, (BYTE
*)&duration
, &size
);
548 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
549 ok(type
== WMT_TYPE_QWORD
, "Got type %#x.\n", type
);
550 ok(size
== sizeof(QWORD
), "Got size %u.\n", size
);
551 ok(duration
== 20460000, "Got duration %I64u.\n", duration
);
552 ok(stream_number
== 0, "Got stream number %u.\n", stream_number
);
554 /* Pass a too-small size. */
556 size
= sizeof(QWORD
) - 1;
558 duration
= 0xdeadbeef;
559 hr
= IWMHeaderInfo_GetAttributeByName(header_info
, &stream_number
,
560 L
"Duration", &type
, (BYTE
*)&duration
, &size
);
561 ok(hr
== ASF_E_BUFFERTOOSMALL
, "Got hr %#x.\n", hr
);
562 ok(type
== 0xdeadbeef, "Got type %#x.\n", type
);
563 ok(size
== sizeof(QWORD
), "Got size %u.\n", size
);
564 ok(duration
== 0xdeadbeef, "Got duration %I64u.\n", duration
);
565 ok(stream_number
== 0, "Got stream number %u.\n", stream_number
);
567 /* Pass a NULL buffer. */
571 hr
= IWMHeaderInfo_GetAttributeByName(header_info
, &stream_number
,
572 L
"Duration", &type
, NULL
, &size
);
573 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
574 ok(type
== WMT_TYPE_QWORD
, "Got type %#x.\n", type
);
575 ok(size
== sizeof(QWORD
), "Got size %u.\n", size
);
576 ok(stream_number
== 0, "Got stream number %u.\n", stream_number
);
578 size
= sizeof(DWORD
);
581 hr
= IWMHeaderInfo_GetAttributeByName(header_info
, &stream_number
,
582 L
"Seekable", &type
, (BYTE
*)&dword
, &size
);
583 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
584 ok(type
== WMT_TYPE_BOOL
, "Got type %#x.\n", type
);
585 ok(size
== sizeof(DWORD
), "Got size %u.\n", size
);
586 ok(dword
== TRUE
, "Got duration %I64u.\n", duration
);
587 ok(stream_number
== 0, "Got stream number %u.\n", stream_number
);
589 IWMHeaderInfo_Release(header_info
);
592 static void test_sync_reader_streaming(void)
594 DWORD size
, flags
, output_number
, expect_output_number
;
595 const WCHAR
*filename
= load_resource(L
"test.wmv");
596 WORD stream_numbers
[2], stream_number
;
597 IWMStreamConfig
*config
, *config2
;
598 bool eos
[2] = {0}, first
= true;
599 struct teststream stream
;
600 ULONG i
, j
, count
, ref
;
601 IWMSyncReader
*reader
;
610 file
= CreateFileW(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
611 ok(file
!= INVALID_HANDLE_VALUE
, "Failed to open %s, error %u.\n", debugstr_w(file
), GetLastError());
613 teststream_init(&stream
, file
);
615 hr
= WMCreateSyncReader(NULL
, 0, &reader
);
616 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
617 IWMSyncReader_QueryInterface(reader
, &IID_IWMProfile
, (void **)&profile
);
619 hr
= IWMSyncReader_OpenStream(reader
, &stream
.IStream_iface
);
620 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
621 ok(stream
.refcount
> 1, "Got refcount %d.\n", stream
.refcount
);
623 hr
= IWMProfile_GetStreamCount(profile
, NULL
);
624 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
627 hr
= IWMProfile_GetStreamCount(profile
, &count
);
628 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
629 ok(count
== 2, "Got count %u.\n", count
);
632 hr
= IWMSyncReader_GetOutputCount(reader
, &count
);
633 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
634 ok(count
== 2, "Got count %u.\n", count
);
636 for (i
= 0; i
< 2; ++i
)
638 hr
= IWMProfile_GetStream(profile
, i
, &config
);
639 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
641 hr
= IWMProfile_GetStream(profile
, i
, &config2
);
642 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
643 ok(config2
!= config
, "Expected different objects.\n");
644 ref
= IWMStreamConfig_Release(config2
);
645 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
647 stream_numbers
[i
] = 0xdead;
648 hr
= IWMStreamConfig_GetStreamNumber(config
, &stream_numbers
[i
]);
649 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
650 ok(stream_numbers
[i
] == i
+ 1, "Got stream number %u.\n", stream_numbers
[i
]);
652 ref
= IWMStreamConfig_Release(config
);
653 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
655 hr
= IWMSyncReader_SetReadStreamSamples(reader
, stream_numbers
[i
], FALSE
);
656 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
659 hr
= IWMProfile_GetStream(profile
, 2, &config
);
660 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
662 while (!eos
[0] || !eos
[1])
664 for (j
= 0; j
< 2; ++j
)
666 stream_number
= pts
= duration
= flags
= output_number
= 0xdeadbeef;
667 hr
= IWMSyncReader_GetNextSample(reader
, stream_numbers
[j
], &sample
,
668 &pts
, &duration
, &flags
, &output_number
, &stream_number
);
670 ok(hr
== S_OK
, "Expected at least one valid sample; got hr %#x.\n", hr
);
672 ok(hr
== NS_E_NO_MORE_SAMPLES
, "Got hr %#x.\n", hr
);
674 ok(hr
== S_OK
|| hr
== NS_E_NO_MORE_SAMPLES
, "Got hr %#x.\n", hr
);
678 hr
= INSSBuffer_GetBufferAndLength(sample
, &data
, &size
);
679 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
680 ref
= INSSBuffer_Release(sample
);
681 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
683 hr
= IWMSyncReader_GetOutputNumberForStream(reader
, stream_number
, &expect_output_number
);
684 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
685 ok(output_number
== expect_output_number
, "Expected output number %u, got %u.\n",
686 expect_output_number
, output_number
);
690 ok(pts
== 0xdeadbeef, "Got PTS %I64u.\n", pts
);
691 ok(duration
== 0xdeadbeef, "Got duration %I64u.\n", duration
);
692 ok(flags
== 0xdeadbeef, "Got flags %#x.\n", flags
);
693 ok(output_number
== 0xdeadbeef, "Got output number %u.\n", output_number
);
697 ok(stream_number
== stream_numbers
[j
], "Expected stream number %u, got %u.\n",
698 stream_numbers
[j
], stream_number
);
703 hr
= IWMSyncReader_GetNextSample(reader
, stream_numbers
[0], &sample
,
704 &pts
, &duration
, &flags
, NULL
, NULL
);
705 ok(hr
== NS_E_NO_MORE_SAMPLES
, "Got hr %#x.\n", hr
);
707 hr
= IWMSyncReader_GetNextSample(reader
, stream_numbers
[1], &sample
,
708 &pts
, &duration
, &flags
, NULL
, NULL
);
709 ok(hr
== NS_E_NO_MORE_SAMPLES
, "Got hr %#x.\n", hr
);
711 hr
= IWMSyncReader_SetRange(reader
, 0, 0);
712 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
714 hr
= IWMSyncReader_GetNextSample(reader
, stream_numbers
[0], &sample
, &pts
, &duration
, &flags
, NULL
, NULL
);
715 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
716 INSSBuffer_Release(sample
);
718 hr
= IWMSyncReader_GetNextSample(reader
, 0, &sample
, &pts
, &duration
, &flags
, NULL
, NULL
);
719 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
721 hr
= IWMSyncReader_GetNextSample(reader
, 0, &sample
, &pts
, &duration
, &flags
, &output_number
, NULL
);
722 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
723 INSSBuffer_Release(sample
);
725 hr
= IWMSyncReader_GetNextSample(reader
, 0, &sample
, &pts
, &duration
, &flags
, NULL
, &stream_number
);
726 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
727 INSSBuffer_Release(sample
);
731 stream_number
= pts
= duration
= flags
= output_number
= 0xdeadbeef;
732 hr
= IWMSyncReader_GetNextSample(reader
, 0, &sample
,
733 &pts
, &duration
, &flags
, &output_number
, &stream_number
);
734 ok(hr
== S_OK
|| hr
== NS_E_NO_MORE_SAMPLES
, "Got hr %#x.\n", hr
);
738 hr
= INSSBuffer_GetBufferAndLength(sample
, &data
, &size
);
739 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
740 ref
= INSSBuffer_Release(sample
);
741 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
745 ok(pts
== 0xdeadbeef, "Got PTS %I64u.\n", pts
);
746 ok(duration
== 0xdeadbeef, "Got duration %I64u.\n", duration
);
747 ok(flags
== 0xdeadbeef, "Got flags %#x.\n", flags
);
748 ok(output_number
== 0xdeadbeef, "Got output number %u.\n", output_number
);
749 ok(stream_number
== 0xbeef, "Got stream number %u.\n", stream_number
);
754 hr
= IWMSyncReader_GetNextSample(reader
, 0, &sample
,
755 &pts
, &duration
, &flags
, NULL
, &stream_number
);
756 ok(hr
== NS_E_NO_MORE_SAMPLES
, "Got hr %#x.\n", hr
);
758 hr
= IWMSyncReader_GetNextSample(reader
, stream_numbers
[0], &sample
,
759 &pts
, &duration
, &flags
, NULL
, NULL
);
760 ok(hr
== NS_E_NO_MORE_SAMPLES
, "Got hr %#x.\n", hr
);
762 hr
= IWMSyncReader_GetNextSample(reader
, stream_numbers
[1], &sample
,
763 &pts
, &duration
, &flags
, NULL
, NULL
);
764 ok(hr
== NS_E_NO_MORE_SAMPLES
, "Got hr %#x.\n", hr
);
766 test_reader_attributes(profile
);
768 hr
= IWMSyncReader_Close(reader
);
769 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
771 hr
= IWMSyncReader_Close(reader
);
772 ok(hr
== NS_E_INVALID_REQUEST
, "Got hr %#x.\n", hr
);
774 ok(stream
.refcount
== 1, "Got outstanding refcount %d.\n", stream
.refcount
);
776 SetFilePointer(stream
.file
, 0, NULL
, FILE_BEGIN
);
777 hr
= IWMSyncReader_OpenStream(reader
, &stream
.IStream_iface
);
778 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
779 ok(stream
.refcount
> 1, "Got refcount %d.\n", stream
.refcount
);
781 IWMProfile_Release(profile
);
782 ref
= IWMSyncReader_Release(reader
);
783 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
785 ok(stream
.refcount
== 1, "Got outstanding refcount %d.\n", stream
.refcount
);
786 CloseHandle(stream
.file
);
787 ret
= DeleteFileW(filename
);
788 ok(ret
, "Failed to delete %s, error %u.\n", debugstr_w(filename
), GetLastError());
791 static void check_video_type(const WM_MEDIA_TYPE
*mt
)
793 const VIDEOINFOHEADER
*video_info
= (const VIDEOINFOHEADER
*)mt
->pbFormat
;
794 static const RECT rect
= {.right
= 64, .bottom
= 48};
796 ok(IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
), "Got format %s.\n", debugstr_guid(&mt
->formattype
));
797 ok(mt
->bFixedSizeSamples
== TRUE
, "Got fixed size %d.\n", mt
->bFixedSizeSamples
);
798 ok(!mt
->bTemporalCompression
, "Got temporal compression %d.\n", mt
->bTemporalCompression
);
799 ok(!mt
->pUnk
, "Got pUnk %p.\n", mt
->pUnk
);
801 ok(EqualRect(&video_info
->rcSource
, &rect
), "Got source rect %s.\n", wine_dbgstr_rect(&rect
));
802 ok(EqualRect(&video_info
->rcTarget
, &rect
), "Got target rect %s.\n", wine_dbgstr_rect(&rect
));
803 ok(!video_info
->dwBitRate
, "Got bit rate %u.\n", video_info
->dwBitRate
);
804 ok(!video_info
->dwBitErrorRate
, "Got bit error rate %u.\n", video_info
->dwBitErrorRate
);
805 ok(video_info
->bmiHeader
.biSize
== sizeof(video_info
->bmiHeader
),
806 "Got size %u.\n", video_info
->bmiHeader
.biSize
);
807 ok(video_info
->bmiHeader
.biWidth
== 64, "Got width %d.\n", video_info
->bmiHeader
.biWidth
);
808 ok(video_info
->bmiHeader
.biHeight
== 48, "Got height %d.\n", video_info
->bmiHeader
.biHeight
);
809 ok(video_info
->bmiHeader
.biPlanes
== 1, "Got planes %d.\n", video_info
->bmiHeader
.biPlanes
);
812 static void check_audio_type(const WM_MEDIA_TYPE
*mt
)
814 const WAVEFORMATEX
*wave_format
= (const WAVEFORMATEX
*)mt
->pbFormat
;
816 ok(IsEqualGUID(&mt
->subtype
, &MEDIASUBTYPE_PCM
), "Got subtype %s.\n", debugstr_guid(&mt
->subtype
));
817 ok(IsEqualGUID(&mt
->formattype
, &FORMAT_WaveFormatEx
), "Got format %s.\n", debugstr_guid(&mt
->formattype
));
818 ok(mt
->bFixedSizeSamples
== TRUE
, "Got fixed size %d.\n", mt
->bFixedSizeSamples
);
819 ok(!mt
->bTemporalCompression
, "Got temporal compression %d.\n", mt
->bTemporalCompression
);
820 ok(!mt
->pUnk
, "Got pUnk %p.\n", mt
->pUnk
);
822 ok(wave_format
->wFormatTag
== WAVE_FORMAT_PCM
, "Got tag %#x.\n", wave_format
->wFormatTag
);
825 static void test_sync_reader_types(void)
827 char mt_buffer
[2000], mt2_buffer
[2000];
828 const WCHAR
*filename
= load_resource(L
"test.wmv");
829 IWMOutputMediaProps
*output_props
, *output_props2
;
830 WM_MEDIA_TYPE
*mt2
= (WM_MEDIA_TYPE
*)mt2_buffer
;
831 WM_MEDIA_TYPE
*mt
= (WM_MEDIA_TYPE
*)mt_buffer
;
832 bool got_video
= false, got_audio
= false;
833 DWORD size
, ret_size
, output_number
;
834 WORD stream_number
, stream_number2
;
835 struct teststream stream
;
836 IWMStreamConfig
*config
;
837 ULONG count
, ref
, i
, j
;
838 IWMSyncReader
*reader
;
845 file
= CreateFileW(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
846 ok(file
!= INVALID_HANDLE_VALUE
, "Failed to open %s, error %u.\n", debugstr_w(file
), GetLastError());
848 teststream_init(&stream
, file
);
850 hr
= WMCreateSyncReader(NULL
, 0, &reader
);
851 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
852 IWMSyncReader_QueryInterface(reader
, &IID_IWMProfile
, (void **)&profile
);
854 hr
= IWMSyncReader_OpenStream(reader
, &stream
.IStream_iface
);
855 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
856 ok(stream
.refcount
> 1, "Got refcount %d.\n", stream
.refcount
);
858 for (i
= 0; i
< 2; ++i
)
860 winetest_push_context("Stream %u", i
);
862 hr
= IWMProfile_GetStream(profile
, i
, &config
);
863 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
865 stream_number
= 0xdead;
866 hr
= IWMStreamConfig_GetStreamNumber(config
, &stream_number
);
867 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
868 ok(stream_number
== i
+ 1, "Got stream number %u.\n", stream_number
);
870 hr
= IWMStreamConfig_GetStreamType(config
, &majortype
);
871 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
873 ok(IsEqualGUID(&majortype
, &MEDIATYPE_Video
), "Got major type %s.\n", debugstr_guid(&majortype
));
875 ok(IsEqualGUID(&majortype
, &MEDIATYPE_Audio
), "Got major type %s.\n", debugstr_guid(&majortype
));
877 ref
= IWMStreamConfig_Release(config
);
878 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
880 output_number
= 0xdeadbeef;
881 hr
= IWMSyncReader_GetOutputNumberForStream(reader
, stream_number
, &output_number
);
882 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
883 todo_wine
ok(output_number
== 1 - i
, "Got output number %u.\n", output_number
);
885 stream_number2
= 0xdead;
886 hr
= IWMSyncReader_GetStreamNumberForOutput(reader
, output_number
, &stream_number2
);
887 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
888 ok(stream_number2
== stream_number
, "Expected stream number %u, got %u.\n", stream_number
, stream_number2
);
890 hr
= IWMSyncReader_GetOutputProps(reader
, output_number
, &output_props
);
891 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
893 ret_size
= sizeof(mt_buffer
);
894 hr
= IWMOutputMediaProps_GetMediaType(output_props
, mt
, &ret_size
);
895 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
897 ref
= IWMOutputMediaProps_Release(output_props
);
898 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
900 if (IsEqualGUID(&majortype
, &MEDIATYPE_Audio
))
903 check_audio_type(mt
);
907 ok(IsEqualGUID(&majortype
, &MEDIATYPE_Video
), "Got major type %s.\n", debugstr_guid(&majortype
));
909 check_video_type(mt
);
913 hr
= IWMSyncReader_GetOutputFormatCount(reader
, output_number
, &count
);
914 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
915 ok(count
> 0, "Got count %u.\n", count
);
917 for (j
= 0; j
< count
; ++j
)
919 winetest_push_context("Format %u", j
);
921 hr
= IWMSyncReader_GetOutputFormat(reader
, output_number
, j
, &output_props
);
922 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
924 hr
= IWMSyncReader_GetOutputFormat(reader
, output_number
, j
, &output_props2
);
925 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
926 ok(output_props2
!= output_props
, "Expected different objects.\n");
927 ref
= IWMOutputMediaProps_Release(output_props2
);
928 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
931 hr
= IWMOutputMediaProps_GetMediaType(output_props
, NULL
, &size
);
932 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
933 ok(size
!= 0xdeadbeef && size
>= sizeof(WM_MEDIA_TYPE
), "Got size %u.\n", size
);
936 hr
= IWMOutputMediaProps_GetMediaType(output_props
, mt
, &ret_size
);
937 ok(hr
== ASF_E_BUFFERTOOSMALL
, "Got hr %#x.\n", hr
);
938 ok(ret_size
== size
, "Expected size %u, got %u.\n", size
, ret_size
);
940 ret_size
= sizeof(mt_buffer
);
941 memset(mt_buffer
, 0xcc, sizeof(mt_buffer
));
942 hr
= IWMOutputMediaProps_GetMediaType(output_props
, mt
, &ret_size
);
943 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
944 ok(ret_size
== size
, "Expected size %u, got %u.\n", size
, ret_size
);
945 ok(size
== sizeof(WM_MEDIA_TYPE
) + mt
->cbFormat
, "Expected size %u, got %u.\n",
946 sizeof(WM_MEDIA_TYPE
) + mt
->cbFormat
, size
);
948 ok(IsEqualGUID(&mt
->majortype
, &majortype
), "Got major type %s.\n", debugstr_guid(&mt
->majortype
));
950 if (IsEqualGUID(&mt
->majortype
, &MEDIATYPE_Audio
))
951 check_audio_type(mt
);
953 check_video_type(mt
);
955 hr
= IWMSyncReader_SetOutputProps(reader
, output_number
, output_props
);
956 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
957 hr
= IWMSyncReader_SetOutputProps(reader
, 1 - output_number
, output_props
);
959 todo_wine
ok(hr
== ASF_E_BADMEDIATYPE
, "Got hr %#x.\n", hr
);
961 ok(hr
== NS_E_INCOMPATIBLE_FORMAT
962 || hr
== NS_E_INVALID_OUTPUT_FORMAT
/* win10 */, "Got hr %#x.\n", hr
);
963 hr
= IWMSyncReader_SetOutputProps(reader
, 2, output_props
);
964 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
966 hr
= IWMSyncReader_GetOutputProps(reader
, output_number
, &output_props2
);
967 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
968 ok(output_props2
!= output_props
, "Expected different objects.\n");
970 ret_size
= sizeof(mt2_buffer
);
971 hr
= IWMOutputMediaProps_GetMediaType(output_props2
, mt2
, &ret_size
);
972 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
973 ok(compare_media_types(mt
, mt2
), "Media types didn't match.\n");
975 ref
= IWMOutputMediaProps_Release(output_props2
);
976 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
977 ref
= IWMOutputMediaProps_Release(output_props
);
978 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
980 winetest_pop_context();
983 hr
= IWMSyncReader_GetOutputFormat(reader
, output_number
, count
, &output_props
);
984 ok(hr
== NS_E_INVALID_OUTPUT_FORMAT
, "Got hr %#x.\n", hr
);
986 hr
= IWMSyncReader_GetOutputProps(reader
, output_number
, &output_props
);
987 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
989 hr
= IWMSyncReader_GetOutputProps(reader
, output_number
, &output_props2
);
990 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
991 ok(output_props2
!= output_props
, "Expected different objects.\n");
993 ref
= IWMOutputMediaProps_Release(output_props2
);
994 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
995 ref
= IWMOutputMediaProps_Release(output_props
);
996 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
998 winetest_pop_context();
1001 ok(got_audio
, "No audio stream was enumerated.\n");
1002 ok(got_video
, "No video stream was enumerated.\n");
1005 hr
= IWMSyncReader_GetOutputFormatCount(reader
, 2, &count
);
1006 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1007 ok(count
== 0xdeadbeef, "Got count %#x.\n", count
);
1009 output_props
= (void *)0xdeadbeef;
1010 hr
= IWMSyncReader_GetOutputProps(reader
, 2, &output_props
);
1011 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1012 ok(output_props
== (void *)0xdeadbeef, "Got output props %p.\n", output_props
);
1014 output_props
= (void *)0xdeadbeef;
1015 hr
= IWMSyncReader_GetOutputFormat(reader
, 2, 0, &output_props
);
1016 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1017 ok(output_props
== (void *)0xdeadbeef, "Got output props %p.\n", output_props
);
1019 IWMProfile_Release(profile
);
1020 ref
= IWMSyncReader_Release(reader
);
1021 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1023 ok(stream
.refcount
== 1, "Got outstanding refcount %d.\n", stream
.refcount
);
1024 CloseHandle(stream
.file
);
1025 ret
= DeleteFileW(filename
);
1026 ok(ret
, "Failed to delete %s, error %u.\n", debugstr_w(filename
), GetLastError());
1029 static void test_sync_reader_file(void)
1031 const WCHAR
*filename
= load_resource(L
"test.wmv");
1032 IWMSyncReader
*reader
;
1033 IWMProfile
*profile
;
1039 hr
= WMCreateSyncReader(NULL
, 0, &reader
);
1040 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1041 IWMSyncReader_QueryInterface(reader
, &IID_IWMProfile
, (void **)&profile
);
1043 hr
= IWMSyncReader_Open(reader
, filename
);
1044 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1047 hr
= IWMSyncReader_GetOutputCount(reader
, &count
);
1048 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1049 ok(count
== 2, "Got count %u.\n", count
);
1051 hr
= IWMSyncReader_Close(reader
);
1052 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1054 hr
= IWMSyncReader_Close(reader
);
1055 ok(hr
== NS_E_INVALID_REQUEST
, "Got hr %#x.\n", hr
);
1057 hr
= IWMSyncReader_Open(reader
, filename
);
1058 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1060 IWMProfile_Release(profile
);
1061 ref
= IWMSyncReader_Release(reader
);
1062 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1064 ret
= DeleteFileW(filename
);
1065 ok(ret
, "Failed to delete %s, error %u.\n", debugstr_w(filename
), GetLastError());
1070 IWMReaderCallback IWMReaderCallback_iface
;
1072 HANDLE got_opened
, got_stopped
, eof_event
;
1073 unsigned int got_closed
, got_started
, got_sample
, got_end_of_streaming
, got_eof
;
1076 static struct callback
*impl_from_IWMReaderCallback(IWMReaderCallback
*iface
)
1078 return CONTAINING_RECORD(iface
, struct callback
, IWMReaderCallback_iface
);
1081 static HRESULT WINAPI
callback_QueryInterface(IWMReaderCallback
*iface
, REFIID iid
, void **out
)
1083 if (winetest_debug
> 1)
1084 trace("%04x: IWMReaderCallback::QueryInterface(%s)\n", GetCurrentThreadId(), debugstr_guid(iid
));
1086 if (!IsEqualGUID(iid
, &IID_IWMReaderCallbackAdvanced
) && !IsEqualGUID(iid
, &IID_IWMCredentialCallback
))
1087 ok(0, "Unexpected IID %s.\n", debugstr_guid(iid
));
1089 return E_NOINTERFACE
;
1092 static ULONG WINAPI
callback_AddRef(IWMReaderCallback
*iface
)
1094 struct callback
*callback
= impl_from_IWMReaderCallback(iface
);
1096 return InterlockedIncrement(&callback
->refcount
);
1099 static ULONG WINAPI
callback_Release(IWMReaderCallback
*iface
)
1101 struct callback
*callback
= impl_from_IWMReaderCallback(iface
);
1103 return InterlockedDecrement(&callback
->refcount
);
1106 static HRESULT WINAPI
callback_OnStatus(IWMReaderCallback
*iface
, WMT_STATUS status
,
1107 HRESULT hr
, WMT_ATTR_DATATYPE type
, BYTE
*value
, void *context
)
1109 struct callback
*callback
= impl_from_IWMReaderCallback(iface
);
1111 if (winetest_debug
> 1)
1112 trace("%u: %04x: IWMReaderCallback::OnStatus(status %u, hr %#x, type %#x, value %p)\n",
1113 GetTickCount(), GetCurrentThreadId(), status
, hr
, type
, value
);
1118 ok(type
== WMT_TYPE_DWORD
, "Got type %#x.\n", type
);
1119 ok(!*(DWORD
*)value
, "Got value %#x.\n", *(DWORD
*)value
);
1120 ok(context
== (void *)0xdeadbeef, "Got unexpected context %p.\n", context
);
1121 SetEvent(callback
->got_opened
);
1125 ok(type
== WMT_TYPE_DWORD
, "Got type %#x.\n", type
);
1126 ok(!*(DWORD
*)value
, "Got value %#x.\n", *(DWORD
*)value
);
1127 ok(context
== (void *)0xfacade, "Got unexpected context %p.\n", context
);
1128 ++callback
->got_started
;
1132 ok(type
== WMT_TYPE_DWORD
, "Got type %#x.\n", type
);
1133 ok(!*(DWORD
*)value
, "Got value %#x.\n", *(DWORD
*)value
);
1134 ok(context
== (void *)0xfacade, "Got unexpected context %p.\n", context
);
1135 SetEvent(callback
->got_stopped
);
1139 ok(type
== WMT_TYPE_DWORD
, "Got type %#x.\n", type
);
1140 ok(!*(DWORD
*)value
, "Got value %#x.\n", *(DWORD
*)value
);
1141 todo_wine
ok(context
== (void *)0xfacade, "Got unexpected context %p.\n", context
);
1142 ++callback
->got_closed
;
1145 case WMT_END_OF_STREAMING
:
1146 ok(type
== WMT_TYPE_DWORD
, "Got type %#x.\n", type
);
1147 ok(!*(DWORD
*)value
, "Got value %#x.\n", *(DWORD
*)value
);
1148 ok(context
== (void *)0xfacade, "Got unexpected context %p.\n", context
);
1149 ok(!callback
->got_eof
, "Got %u WMT_EOF callbacks.\n", callback
->got_eof
);
1150 ++callback
->got_end_of_streaming
;
1154 ok(type
== WMT_TYPE_DWORD
, "Got type %#x.\n", type
);
1155 ok(!*(DWORD
*)value
, "Got value %#x.\n", *(DWORD
*)value
);
1156 ok(context
== (void *)0xfacade, "Got unexpected context %p.\n", context
);
1157 ok(callback
->got_sample
> 0, "Got no samples.\n");
1158 ok(callback
->got_end_of_streaming
== 1, "Got %u WMT_END_OF_STREAMING callbacks.\n",
1159 callback
->got_end_of_streaming
);
1160 ++callback
->got_eof
;
1161 SetEvent(callback
->eof_event
);
1164 /* Not sent when not using IWMReaderAdvanced::DeliverTime(). */
1165 case WMT_END_OF_SEGMENT
:
1166 ok(type
== WMT_TYPE_QWORD
, "Got type %#x.\n", type
);
1167 ok(*(QWORD
*)value
== 3000, "Got value %#x.\n", *(DWORD
*)value
);
1168 ok(context
== (void *)0xfacade, "Got unexpected context %p.\n", context
);
1169 ok(callback
->got_sample
> 0, "Got no samples.\n");
1170 ok(callback
->got_eof
== 1, "Got %u WMT_EOF callbacks.\n", callback
->got_eof
);
1174 ok(0, "Unexpected status %#x.\n", status
);
1177 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1181 static HRESULT WINAPI
callback_OnSample(IWMReaderCallback
*iface
, DWORD output
,
1182 QWORD time
, QWORD duration
, DWORD flags
, INSSBuffer
*sample
, void *context
)
1184 struct callback
*callback
= impl_from_IWMReaderCallback(iface
);
1189 if (winetest_debug
> 1)
1190 trace("%u: %04x: IWMReaderCallback::OnSample(output %u, time %I64u, duration %I64u, flags %#x)\n",
1191 GetTickCount(), GetCurrentThreadId(), output
, time
, duration
, flags
);
1193 ok(context
== (void *)0xfacade, "Got unexpected context %p.\n", context
);
1195 hr
= INSSBuffer_GetBufferAndLength(sample
, &data
, &size
);
1196 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1198 ok(callback
->got_started
> 0, "Got %u WMT_STARTED callbacks.\n", callback
->got_started
);
1199 ok(!callback
->got_eof
, "Got %u WMT_EOF callbacks.\n", callback
->got_eof
);
1200 ++callback
->got_sample
;
1205 static const IWMReaderCallbackVtbl callback_vtbl
=
1207 callback_QueryInterface
,
1214 static void callback_init(struct callback
*callback
)
1216 memset(callback
, 0, sizeof(*callback
));
1217 callback
->IWMReaderCallback_iface
.lpVtbl
= &callback_vtbl
;
1218 callback
->refcount
= 1;
1219 callback
->got_opened
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1220 callback
->got_stopped
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1221 callback
->eof_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1224 static void callback_cleanup(struct callback
*callback
)
1226 CloseHandle(callback
->got_opened
);
1227 CloseHandle(callback
->got_stopped
);
1228 CloseHandle(callback
->eof_event
);
1231 static void test_async_reader_streaming(void)
1233 const WCHAR
*filename
= load_resource(L
"test.wmv");
1234 IWMReaderAdvanced2
*advanced
;
1235 struct teststream stream
;
1236 struct callback callback
;
1237 IWMStreamConfig
*config
;
1238 WORD stream_numbers
[2];
1239 IWMProfile
*profile
;
1240 ULONG i
, count
, ref
;
1246 file
= CreateFileW(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1247 ok(file
!= INVALID_HANDLE_VALUE
, "Failed to open %s, error %u.\n", debugstr_w(file
), GetLastError());
1249 teststream_init(&stream
, file
);
1250 callback_init(&callback
);
1252 hr
= WMCreateReader(NULL
, 0, &reader
);
1253 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1254 IWMReader_QueryInterface(reader
, &IID_IWMProfile
, (void **)&profile
);
1255 IWMReader_QueryInterface(reader
, &IID_IWMReaderAdvanced2
, (void **)&advanced
);
1257 hr
= IWMReaderAdvanced2_OpenStream(advanced
, &stream
.IStream_iface
, &callback
.IWMReaderCallback_iface
, (void **)0xdeadbeef);
1258 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1259 ok(stream
.refcount
> 1, "Got refcount %d.\n", stream
.refcount
);
1260 ok(callback
.refcount
> 1, "Got refcount %d.\n", callback
.refcount
);
1261 ret
= WaitForSingleObject(callback
.got_opened
, 1000);
1262 ok(!ret
, "Wait timed out.\n");
1265 hr
= IWMReader_GetOutputCount(reader
, &count
);
1266 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1267 ok(count
== 2, "Got count %u.\n", count
);
1269 for (i
= 0; i
< 2; ++i
)
1271 hr
= IWMProfile_GetStream(profile
, i
, &config
);
1272 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1274 stream_numbers
[i
] = 0xdead;
1275 hr
= IWMStreamConfig_GetStreamNumber(config
, &stream_numbers
[i
]);
1276 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1277 ok(stream_numbers
[i
] == i
+ 1, "Got stream number %u.\n", stream_numbers
[i
]);
1279 ref
= IWMStreamConfig_Release(config
);
1280 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1283 hr
= IWMReader_Start(reader
, 0, 0, 1.0f
, (void *)0xfacade);
1284 todo_wine
ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1288 /* By default the reader will time itself, and attempt to deliver samples
1289 * according to their presentation time. Call DeliverTime with the file
1290 * duration in order to request all samples as fast as possible. */
1291 hr
= IWMReaderAdvanced2_DeliverTime(advanced
, 3000 * 10000);
1292 ok(hr
== E_UNEXPECTED
, "Got hr %#x.\n", hr
);
1293 hr
= IWMReaderAdvanced2_SetUserProvidedClock(advanced
, TRUE
);
1294 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1295 hr
= IWMReaderAdvanced2_DeliverTime(advanced
, 3000 * 10000);
1296 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1298 ret
= WaitForSingleObject(callback
.eof_event
, 1000);
1299 ok(!ret
, "Wait timed out.\n");
1300 ok(callback
.got_eof
== 1, "Got %u WMT_EOF callbacks.\n", callback
.got_eof
);
1302 hr
= IWMReader_Stop(reader
);
1303 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1304 ret
= WaitForSingleObject(callback
.got_stopped
, 1000);
1305 ok(!ret
, "Wait timed out.\n");
1307 hr
= IWMReader_Stop(reader
);
1308 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1309 ret
= WaitForSingleObject(callback
.got_stopped
, 1000);
1310 ok(!ret
, "Wait timed out.\n");
1313 test_reader_attributes(profile
);
1315 hr
= IWMReader_Close(reader
);
1316 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1317 ok(callback
.got_closed
== 1, "Got %u WMT_CLOSED callbacks.\n", callback
.got_closed
);
1318 ok(callback
.refcount
== 1, "Got outstanding refcount %d.\n", callback
.refcount
);
1319 callback_cleanup(&callback
);
1321 ok(stream
.refcount
== 1, "Got outstanding refcount %d.\n", stream
.refcount
);
1322 CloseHandle(stream
.file
);
1323 ret
= DeleteFileW(filename
);
1324 ok(ret
, "Failed to delete %s, error %u.\n", debugstr_w(filename
), GetLastError());
1326 hr
= IWMReader_Close(reader
);
1327 ok(hr
== NS_E_INVALID_REQUEST
, "Got hr %#x.\n", hr
);
1329 IWMReaderAdvanced2_Release(advanced
);
1330 IWMProfile_Release(profile
);
1331 ref
= IWMReader_Release(reader
);
1332 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1335 static void test_async_reader_types(void)
1337 char mt_buffer
[2000], mt2_buffer
[2000];
1338 const WCHAR
*filename
= load_resource(L
"test.wmv");
1339 IWMOutputMediaProps
*output_props
, *output_props2
;
1340 WM_MEDIA_TYPE
*mt2
= (WM_MEDIA_TYPE
*)mt2_buffer
;
1341 WM_MEDIA_TYPE
*mt
= (WM_MEDIA_TYPE
*)mt_buffer
;
1342 bool got_video
= false, got_audio
= false;
1343 DWORD size
, ret_size
, output_number
;
1344 IWMReaderAdvanced2
*advanced
;
1345 struct teststream stream
;
1346 struct callback callback
;
1347 IWMStreamConfig
*config
;
1348 ULONG count
, ref
, i
, j
;
1349 IWMProfile
*profile
;
1356 file
= CreateFileW(filename
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
1357 ok(file
!= INVALID_HANDLE_VALUE
, "Failed to open %s, error %u.\n", debugstr_w(file
), GetLastError());
1359 teststream_init(&stream
, file
);
1360 callback_init(&callback
);
1362 hr
= WMCreateReader(NULL
, 0, &reader
);
1363 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1364 IWMReader_QueryInterface(reader
, &IID_IWMProfile
, (void **)&profile
);
1365 IWMReader_QueryInterface(reader
, &IID_IWMReaderAdvanced2
, (void **)&advanced
);
1367 hr
= IWMReaderAdvanced2_OpenStream(advanced
, &stream
.IStream_iface
, &callback
.IWMReaderCallback_iface
, (void **)0xdeadbeef);
1368 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1369 ok(stream
.refcount
> 1, "Got refcount %d.\n", stream
.refcount
);
1370 ok(callback
.refcount
> 1, "Got refcount %d.\n", callback
.refcount
);
1371 ret
= WaitForSingleObject(callback
.got_opened
, 1000);
1372 ok(!ret
, "Wait timed out.\n");
1374 for (i
= 0; i
< 2; ++i
)
1376 winetest_push_context("Stream %u", i
);
1378 hr
= IWMProfile_GetStream(profile
, i
, &config
);
1379 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1381 hr
= IWMStreamConfig_GetStreamType(config
, &majortype
);
1382 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1384 ok(IsEqualGUID(&majortype
, &MEDIATYPE_Video
), "Got major type %s.\n", debugstr_guid(&majortype
));
1386 ok(IsEqualGUID(&majortype
, &MEDIATYPE_Audio
), "Got major type %s.\n", debugstr_guid(&majortype
));
1388 ref
= IWMStreamConfig_Release(config
);
1389 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1391 winetest_pop_context();
1394 for (i
= 0; i
< 2; ++i
)
1396 winetest_push_context("Output %u", i
);
1399 hr
= IWMReader_GetOutputProps(reader
, output_number
, &output_props
);
1400 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1402 ret_size
= sizeof(mt_buffer
);
1403 hr
= IWMOutputMediaProps_GetMediaType(output_props
, mt
, &ret_size
);
1404 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1406 ref
= IWMOutputMediaProps_Release(output_props
);
1407 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1409 majortype
= mt
->majortype
;
1410 if (IsEqualGUID(&majortype
, &MEDIATYPE_Audio
))
1413 check_audio_type(mt
);
1415 /* R.U.S.E. enumerates all audio formats, picks the first one it
1416 * likes, and then sets the wrong stream to that format.
1417 * Accordingly we need the first audio format to be the default
1418 * format, and we need it to be a format that the game is happy
1419 * with. In particular it has to be PCM. */
1421 hr
= IWMReader_GetOutputFormat(reader
, output_number
, 0, &output_props
);
1422 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1424 ret_size
= sizeof(mt2_buffer
);
1425 hr
= IWMOutputMediaProps_GetMediaType(output_props
, mt2
, &ret_size
);
1426 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1428 ref
= IWMOutputMediaProps_Release(output_props
);
1429 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1431 /* The sample size might differ. */
1432 mt2
->lSampleSize
= mt
->lSampleSize
;
1433 ok(compare_media_types(mt
, mt2
), "Media types didn't match.\n");
1437 ok(IsEqualGUID(&majortype
, &MEDIATYPE_Video
), "Got major type %s.\n", debugstr_guid(&majortype
));
1439 check_video_type(mt
);
1443 hr
= IWMReader_GetOutputFormatCount(reader
, output_number
, &count
);
1444 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1445 ok(count
> 0, "Got count %u.\n", count
);
1447 for (j
= 0; j
< count
; ++j
)
1449 winetest_push_context("Format %u", j
);
1451 hr
= IWMReader_GetOutputFormat(reader
, output_number
, j
, &output_props
);
1452 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1454 hr
= IWMReader_GetOutputFormat(reader
, output_number
, j
, &output_props2
);
1455 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1456 ok(output_props2
!= output_props
, "Expected different objects.\n");
1457 ref
= IWMOutputMediaProps_Release(output_props2
);
1458 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1461 hr
= IWMOutputMediaProps_GetMediaType(output_props
, NULL
, &size
);
1462 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1463 ok(size
!= 0xdeadbeef && size
>= sizeof(WM_MEDIA_TYPE
), "Got size %u.\n", size
);
1465 ret_size
= size
- 1;
1466 hr
= IWMOutputMediaProps_GetMediaType(output_props
, mt
, &ret_size
);
1467 ok(hr
== ASF_E_BUFFERTOOSMALL
, "Got hr %#x.\n", hr
);
1468 ok(ret_size
== size
, "Expected size %u, got %u.\n", size
, ret_size
);
1470 ret_size
= sizeof(mt_buffer
);
1471 memset(mt_buffer
, 0xcc, sizeof(mt_buffer
));
1472 hr
= IWMOutputMediaProps_GetMediaType(output_props
, mt
, &ret_size
);
1473 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1474 ok(ret_size
== size
, "Expected size %u, got %u.\n", size
, ret_size
);
1475 ok(size
== sizeof(WM_MEDIA_TYPE
) + mt
->cbFormat
, "Expected size %u, got %u.\n",
1476 sizeof(WM_MEDIA_TYPE
) + mt
->cbFormat
, size
);
1478 ok(IsEqualGUID(&mt
->majortype
, &majortype
), "Got major type %s.\n", debugstr_guid(&mt
->majortype
));
1480 if (IsEqualGUID(&mt
->majortype
, &MEDIATYPE_Audio
))
1481 check_audio_type(mt
);
1483 check_video_type(mt
);
1485 hr
= IWMReader_SetOutputProps(reader
, output_number
, output_props
);
1486 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1487 hr
= IWMReader_SetOutputProps(reader
, 1 - output_number
, output_props
);
1489 ok(hr
== NS_E_INCOMPATIBLE_FORMAT
/* win < 8, win10 1507-1809 */
1490 || hr
== ASF_E_BADMEDIATYPE
/* win8, win10 1909+ */, "Got hr %#x.\n", hr
);
1492 todo_wine
ok(hr
== NS_E_INVALID_REQUEST
, "Got hr %#x.\n", hr
);
1493 hr
= IWMReader_SetOutputProps(reader
, 2, output_props
);
1494 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1496 hr
= IWMReader_GetOutputProps(reader
, output_number
, &output_props2
);
1497 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1498 ok(output_props2
!= output_props
, "Expected different objects.\n");
1500 ret_size
= sizeof(mt2_buffer
);
1501 hr
= IWMOutputMediaProps_GetMediaType(output_props2
, mt2
, &ret_size
);
1502 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1503 ok(compare_media_types(mt
, mt2
), "Media types didn't match.\n");
1505 ref
= IWMOutputMediaProps_Release(output_props2
);
1506 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1507 ref
= IWMOutputMediaProps_Release(output_props
);
1508 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1510 winetest_pop_context();
1513 hr
= IWMReader_GetOutputFormat(reader
, output_number
, count
, &output_props
);
1514 ok(hr
== NS_E_INVALID_OUTPUT_FORMAT
, "Got hr %#x.\n", hr
);
1516 hr
= IWMReader_GetOutputProps(reader
, output_number
, &output_props
);
1517 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1519 hr
= IWMReader_GetOutputProps(reader
, output_number
, &output_props2
);
1520 ok(hr
== S_OK
, "Got hr %#x.\n", hr
);
1521 ok(output_props2
!= output_props
, "Expected different objects.\n");
1523 ref
= IWMOutputMediaProps_Release(output_props2
);
1524 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1525 ref
= IWMOutputMediaProps_Release(output_props
);
1526 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1528 winetest_pop_context();
1531 ok(got_audio
, "No audio stream was enumerated.\n");
1532 ok(got_video
, "No video stream was enumerated.\n");
1535 hr
= IWMReader_GetOutputFormatCount(reader
, 2, &count
);
1536 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1537 ok(count
== 0xdeadbeef, "Got count %#x.\n", count
);
1539 output_props
= (void *)0xdeadbeef;
1540 hr
= IWMReader_GetOutputProps(reader
, 2, &output_props
);
1541 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1542 ok(output_props
== (void *)0xdeadbeef, "Got output props %p.\n", output_props
);
1544 output_props
= (void *)0xdeadbeef;
1545 hr
= IWMReader_GetOutputFormat(reader
, 2, 0, &output_props
);
1546 ok(hr
== E_INVALIDARG
, "Got hr %#x.\n", hr
);
1547 ok(output_props
== (void *)0xdeadbeef, "Got output props %p.\n", output_props
);
1549 IWMReaderAdvanced2_Release(advanced
);
1550 IWMProfile_Release(profile
);
1551 ref
= IWMReader_Release(reader
);
1552 ok(!ref
, "Got outstanding refcount %d.\n", ref
);
1554 ok(stream
.refcount
== 1, "Got outstanding refcount %d.\n", stream
.refcount
);
1555 CloseHandle(stream
.file
);
1556 ret
= DeleteFileW(filename
);
1557 ok(ret
, "Failed to delete %s, error %u.\n", debugstr_w(filename
), GetLastError());
1564 hr
= CoInitialize(0);
1565 ok(hr
== S_OK
, "failed to init com\n");
1569 test_wmreader_interfaces();
1570 test_wmsyncreader_interfaces();
1571 test_wmwriter_interfaces();
1572 test_profile_manager_interfaces();
1573 test_WMCreateWriterPriv();
1574 test_urlextension();
1575 test_iscontentprotected();
1576 test_sync_reader_streaming();
1577 test_sync_reader_types();
1578 test_sync_reader_file();
1579 test_async_reader_streaming();
1580 test_async_reader_types();