Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wmvcore/tests/Makefile.in | 3 + dlls/wmvcore/tests/rsrc.rc | 25 +++ dlls/wmvcore/tests/test.wmv | Bin 0 -> 45663 bytes dlls/wmvcore/tests/wmvcore.c | 392 +++++++++++++++++++++++++++++++++ 4 files changed, 420 insertions(+) create mode 100644 dlls/wmvcore/tests/rsrc.rc create mode 100644 dlls/wmvcore/tests/test.wmv
diff --git a/dlls/wmvcore/tests/Makefile.in b/dlls/wmvcore/tests/Makefile.in index 8054ddd0a2e..856e02d45d5 100644 --- a/dlls/wmvcore/tests/Makefile.in +++ b/dlls/wmvcore/tests/Makefile.in @@ -3,3 +3,6 @@ IMPORTS = ole32 wmvcore
C_SRCS = \ wmvcore.c + +RC_SRCS = \ + rsrc.rc diff --git a/dlls/wmvcore/tests/rsrc.rc b/dlls/wmvcore/tests/rsrc.rc new file mode 100644 index 00000000000..cd642ceb1d0 --- /dev/null +++ b/dlls/wmvcore/tests/rsrc.rc @@ -0,0 +1,25 @@ +/* + * Resource file for wmvcore tests + * + * Copyright 2021 Zebediah Figura for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "windef.h" + +/* ffmpeg -f lavfi -i smptebars -f lavfi -i "sine=frequency=700" -t 2.0 -f asf -vcodec wmv1 -vf scale=64x48 -acodec wmav1 test.wmv */ +/* @makedep: test.wmv */ +test.wmv RCDATA "test.wmv" diff --git a/dlls/wmvcore/tests/test.wmv b/dlls/wmvcore/tests/test.wmv new file mode 100644 index 0000000000000000000000000000000000000000..fa953771cd31213ec24bef9000127125047e0623 GIT binary patch literal 45663 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
literal 0 HcmV?d00001
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 79bcfef0d52..dd1e3027d57 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -1,6 +1,7 @@ /* * Copyright 2017 Alistair Leslie-Hughes * Copyright 2019 Vijay Kiran Kamuju + * Copyright 2021 Zebediah Figura for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,15 +17,43 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + +#include <stdbool.h> #define COBJMACROS #define WIN32_LEAN_AND_MEAN #include "initguid.h" #include "wmsdk.h" +#include "wmsecure.h"
#include "wine/test.h"
HRESULT WINAPI WMCreateWriterPriv(IWMWriter **writer);
+static WCHAR *load_resource(const WCHAR *name) +{ + static WCHAR pathW[MAX_PATH]; + DWORD written; + HANDLE file; + HRSRC res; + void *ptr; + + GetTempPathW(ARRAY_SIZE(pathW), pathW); + wcscat(pathW, name); + + file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s, error %u.\n", + wine_dbgstr_w(pathW), GetLastError()); + + res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA); + ok(!!res, "Failed to load resource, error %u.\n", GetLastError()); + ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res)); + WriteFile(file, ptr, SizeofResource( GetModuleHandleA(NULL), res), &written, NULL); + ok(written == SizeofResource(GetModuleHandleA(NULL), res), "Failed to write resource.\n"); + CloseHandle(file); + + return pathW; +} + #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) static HRESULT check_interface_(unsigned int line, void *iface, REFIID riid, BOOL supported) { @@ -225,6 +254,368 @@ static void test_iscontentprotected(void) ok(drm == FALSE, "got %0dx\n", drm); }
+struct teststream +{ + IStream IStream_iface; + LONG refcount; + HANDLE file; +}; + +static struct teststream *impl_from_IStream(IStream *iface) +{ + return CONTAINING_RECORD(iface, struct teststream, IStream_iface); +} + +static HRESULT WINAPI stream_QueryInterface(IStream *iface, REFIID iid, void **out) +{ + if (winetest_debug > 1) + trace("%04x: IStream::QueryInterface(%s)\n", GetCurrentThreadId(), debugstr_guid(iid)); + + if (!IsEqualGUID(iid, &IID_IWMGetSecureChannel) && !IsEqualGUID(iid, &IID_IWMIStreamProps)) + ok(0, "Unexpected IID %s.\n", debugstr_guid(iid)); + + return E_NOINTERFACE; +} + +static ULONG WINAPI stream_AddRef(IStream *iface) +{ + struct teststream *stream = impl_from_IStream(iface); + + return InterlockedIncrement(&stream->refcount); +} + +static ULONG WINAPI stream_Release(IStream *iface) +{ + struct teststream *stream = impl_from_IStream(iface); + + return InterlockedDecrement(&stream->refcount); +} + +static HRESULT WINAPI stream_Read(IStream *iface, void *data, ULONG size, ULONG *ret_size) +{ + struct teststream *stream = impl_from_IStream(iface); + + if (winetest_debug > 2) + trace("%04x: IStream::Read(size %u)\n", GetCurrentThreadId(), size); + + ok(size > 0, "Got zero size.\n"); + ok(!!ret_size, "Got NULL ret_size pointer.\n"); + if (!ReadFile(stream->file, data, size, ret_size, NULL)) + return HRESULT_FROM_WIN32(GetLastError()); + return S_OK; +} + +static HRESULT WINAPI stream_Write(IStream *iface, const void *data, ULONG size, ULONG *ret_size) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_Seek(IStream *iface, LARGE_INTEGER offset, DWORD method, ULARGE_INTEGER *ret_offset) +{ + struct teststream *stream = impl_from_IStream(iface); + LARGE_INTEGER size; + + if (winetest_debug > 2) + trace("%04x: IStream::Seek(offset %I64u, method %#x)\n", GetCurrentThreadId(), offset.QuadPart, method); + + GetFileSizeEx(stream->file, &size); + ok(offset.QuadPart < size.QuadPart, "Expected offset less than size %I64u, got %I64u.\n", + size.QuadPart, offset.QuadPart); + + ok(method == STREAM_SEEK_SET, "Got method %#x.\n", method); + ok(!ret_offset, "Got unexpected ret_offset pointer %p\n", ret_offset); + + if (!SetFilePointerEx(stream->file, offset, &offset, method)) + return HRESULT_FROM_WIN32(GetLastError()); + return S_OK; +} + +static HRESULT WINAPI stream_SetSize(IStream *iface, ULARGE_INTEGER size) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_CopyTo(IStream *iface, IStream *dest, ULARGE_INTEGER size, + ULARGE_INTEGER *read_size, ULARGE_INTEGER *write_size) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_Commit(IStream *iface, DWORD flags) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_Revert(IStream *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_LockRegion(IStream *iface, ULARGE_INTEGER offset, ULARGE_INTEGER size, DWORD type) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset, ULARGE_INTEGER size, DWORD type) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_Stat(IStream *iface, STATSTG *stat, DWORD flags) +{ + struct teststream *stream = impl_from_IStream(iface); + LARGE_INTEGER size; + + if (winetest_debug > 1) + trace("%04x: IStream::Stat(flags %#x)\n", GetCurrentThreadId(), flags); + + ok(flags == STATFLAG_NONAME, "Got flags %#x.\n", flags); + + stat->type = 0xdeadbeef; + GetFileSizeEx(stream->file, &size); + stat->cbSize.QuadPart = size.QuadPart; + stat->grfMode = 0; + stat->grfLocksSupported = TRUE; + + return S_OK; +} + +static HRESULT WINAPI stream_Clone(IStream *iface, IStream **out) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static const IStreamVtbl stream_vtbl = +{ + stream_QueryInterface, + stream_AddRef, + stream_Release, + stream_Read, + stream_Write, + stream_Seek, + stream_SetSize, + stream_CopyTo, + stream_Commit, + stream_Revert, + stream_LockRegion, + stream_UnlockRegion, + stream_Stat, + stream_Clone, +}; + +static void test_sync_reader_streaming(void) +{ + DWORD size, flags, output_number, expect_output_number; + const WCHAR *filename = load_resource(L"test.wmv"); + WORD stream_numbers[2], stream_number; + IWMStreamConfig *config, *config2; + bool eos[2] = {0}, first = true; + struct teststream stream = {0}; + ULONG i, j, count, ref; + IWMSyncReader *reader; + IWMProfile *profile; + QWORD pts, duration; + INSSBuffer *sample; + HANDLE file; + HRESULT hr; + BYTE *data; + BOOL ret; + + file = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u.\n", debugstr_w(file), GetLastError()); + + stream.IStream_iface.lpVtbl = &stream_vtbl; + stream.refcount = 1; + stream.file = file; + + hr = WMCreateSyncReader(NULL, 0, &reader); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IWMSyncReader_QueryInterface(reader, &IID_IWMProfile, (void **)&profile); + + hr = IWMSyncReader_OpenStream(reader, &stream.IStream_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(stream.refcount > 1, "Got refcount %d.\n", stream.refcount); + + hr = IWMProfile_GetStreamCount(profile, NULL); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + + count = 0xdeadbeef; + hr = IWMProfile_GetStreamCount(profile, &count); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(count == 2, "Got count %u.\n", count); + + count = 0xdeadbeef; + hr = IWMSyncReader_GetOutputCount(reader, &count); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(count == 2, "Got count %u.\n", count); + + for (i = 0; i < 2; ++i) + { + hr = IWMProfile_GetStream(profile, i, &config); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + + if (hr == S_OK) + { + hr = IWMProfile_GetStream(profile, i, &config2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(config2 != config, "Expected different objects.\n"); + ref = IWMStreamConfig_Release(config2); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + stream_numbers[i] = 0xdead; + hr = IWMStreamConfig_GetStreamNumber(config, &stream_numbers[i]); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(stream_numbers[i] == i + 1, "Got stream number %u.\n", stream_numbers[i]); + + ref = IWMStreamConfig_Release(config); + ok(!ref, "Got outstanding refcount %d.\n", ref); + } + + hr = IWMSyncReader_SetReadStreamSamples(reader, stream_numbers[i], FALSE); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + } + + hr = IWMProfile_GetStream(profile, 2, &config); + todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + + while (!eos[0] || !eos[1]) + { + for (j = 0; j < 2; ++j) + { + stream_number = pts = duration = flags = output_number = 0xdeadbeef; + hr = IWMSyncReader_GetNextSample(reader, stream_numbers[j], &sample, + &pts, &duration, &flags, &output_number, &stream_number); + if (first) + todo_wine ok(hr == S_OK, "Expected at least one valid sample; got hr %#x.\n", hr); + else if (eos[j]) + ok(hr == NS_E_NO_MORE_SAMPLES, "Got hr %#x.\n", hr); + else + ok(hr == S_OK || hr == NS_E_NO_MORE_SAMPLES, "Got hr %#x.\n", hr); + + if (hr == S_OK) + { + hr = INSSBuffer_GetBufferAndLength(sample, &data, &size); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ref = INSSBuffer_Release(sample); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + hr = IWMSyncReader_GetOutputNumberForStream(reader, stream_number, &expect_output_number); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(output_number == expect_output_number, "Expected output number %u, got %u.\n", + expect_output_number, output_number); + } + else + { + ok(pts == 0xdeadbeef, "Got PTS %I64u.\n", pts); + ok(duration == 0xdeadbeef, "Got duration %I64u.\n", duration); + ok(flags == 0xdeadbeef, "Got flags %#x.\n", flags); + ok(output_number == 0xdeadbeef, "Got output number %u.\n", output_number); + eos[j] = true; + } + + todo_wine ok(stream_number == stream_numbers[j], "Expected stream number %u, got %u.\n", + stream_numbers[j], stream_number); + } + first = false; + } + + hr = IWMSyncReader_GetNextSample(reader, stream_numbers[0], &sample, + &pts, &duration, &flags, NULL, NULL); + todo_wine ok(hr == NS_E_NO_MORE_SAMPLES, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_GetNextSample(reader, stream_numbers[1], &sample, + &pts, &duration, &flags, NULL, NULL); + todo_wine ok(hr == NS_E_NO_MORE_SAMPLES, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_SetRange(reader, 0, 0); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_GetNextSample(reader, stream_numbers[0], &sample, &pts, &duration, &flags, NULL, NULL); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + if (hr == S_OK) + INSSBuffer_Release(sample); + + hr = IWMSyncReader_GetNextSample(reader, 0, &sample, &pts, &duration, &flags, NULL, NULL); + todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_GetNextSample(reader, 0, &sample, &pts, &duration, &flags, &output_number, NULL); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + if (hr == S_OK) + INSSBuffer_Release(sample); + + hr = IWMSyncReader_GetNextSample(reader, 0, &sample, &pts, &duration, &flags, NULL, &stream_number); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + if (hr == S_OK) + INSSBuffer_Release(sample); + + for (;;) + { + stream_number = pts = duration = flags = output_number = 0xdeadbeef; + hr = IWMSyncReader_GetNextSample(reader, 0, &sample, + &pts, &duration, &flags, &output_number, &stream_number); + todo_wine ok(hr == S_OK || hr == NS_E_NO_MORE_SAMPLES, "Got hr %#x.\n", hr); + + if (hr == S_OK) + { + hr = INSSBuffer_GetBufferAndLength(sample, &data, &size); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ref = INSSBuffer_Release(sample); + ok(!ref, "Got outstanding refcount %d.\n", ref); + } + else + { + ok(pts == 0xdeadbeef, "Got PTS %I64u.\n", pts); + ok(duration == 0xdeadbeef, "Got duration %I64u.\n", duration); + ok(flags == 0xdeadbeef, "Got flags %#x.\n", flags); + ok(output_number == 0xdeadbeef, "Got output number %u.\n", output_number); + ok(stream_number == 0xbeef, "Got stream number %u.\n", stream_number); + break; + } + } + + hr = IWMSyncReader_GetNextSample(reader, 0, &sample, + &pts, &duration, &flags, NULL, &stream_number); + todo_wine ok(hr == NS_E_NO_MORE_SAMPLES, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_GetNextSample(reader, stream_numbers[0], &sample, + &pts, &duration, &flags, NULL, NULL); + todo_wine ok(hr == NS_E_NO_MORE_SAMPLES, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_GetNextSample(reader, stream_numbers[1], &sample, + &pts, &duration, &flags, NULL, NULL); + todo_wine ok(hr == NS_E_NO_MORE_SAMPLES, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_Close(reader); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_Close(reader); + todo_wine ok(hr == NS_E_INVALID_REQUEST, "Got hr %#x.\n", hr); + + ok(stream.refcount == 1, "Got outstanding refcount %d.\n", stream.refcount); + + SetFilePointer(stream.file, 0, NULL, FILE_BEGIN); + hr = IWMSyncReader_OpenStream(reader, &stream.IStream_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(stream.refcount > 1, "Got refcount %d.\n", stream.refcount); + + IWMProfile_Release(profile); + ref = IWMSyncReader_Release(reader); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + ok(stream.refcount == 1, "Got outstanding refcount %d.\n", stream.refcount); + CloseHandle(stream.file); + ret = DeleteFileW(filename); + ok(ret, "Failed to delete %s, error %u.\n", debugstr_w(filename), GetLastError()); +} + START_TEST(wmvcore) { HRESULT hr; @@ -241,6 +632,7 @@ START_TEST(wmvcore) test_WMCreateWriterPriv(); test_urlextension(); test_iscontentprotected(); + test_sync_reader_streaming();
CoUninitialize(); }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wmvcore/tests/wmvcore.c | 267 +++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+)
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index dd1e3027d57..91849990a85 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -24,11 +24,20 @@ #include "initguid.h" #include "wmsdk.h" #include "wmsecure.h" +#include "amvideo.h" +#include "uuids.h" +#include "wmcodecdsp.h"
#include "wine/test.h"
HRESULT WINAPI WMCreateWriterPriv(IWMWriter **writer);
+static BOOL compare_media_types(const WM_MEDIA_TYPE *a, const WM_MEDIA_TYPE *b) +{ + return !memcmp(a, b, offsetof(WM_MEDIA_TYPE, pbFormat)) + && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat); +} + static WCHAR *load_resource(const WCHAR *name) { static WCHAR pathW[MAX_PATH]; @@ -616,6 +625,263 @@ static void test_sync_reader_streaming(void) ok(ret, "Failed to delete %s, error %u.\n", debugstr_w(filename), GetLastError()); }
+static void check_video_type(const WM_MEDIA_TYPE *mt) +{ + const VIDEOINFOHEADER *video_info = (const VIDEOINFOHEADER *)mt->pbFormat; + static const RECT rect = {.right = 64, .bottom = 48}; + + /* Call of Juarez breaks if I420 is enumerated. */ + ok(!IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_I420), "I420 should not be enumerated.\n"); + + ok(IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo), "Got format %s.\n", debugstr_guid(&mt->formattype)); + todo_wine ok(mt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", mt->bFixedSizeSamples); + todo_wine ok(!mt->bTemporalCompression, "Got temporal compression %d.\n", mt->bTemporalCompression); + ok(!mt->pUnk, "Got pUnk %p.\n", mt->pUnk); + + todo_wine ok(EqualRect(&video_info->rcSource, &rect), "Got source rect %s.\n", wine_dbgstr_rect(&rect)); + todo_wine ok(EqualRect(&video_info->rcTarget, &rect), "Got target rect %s.\n", wine_dbgstr_rect(&rect)); + ok(!video_info->dwBitRate, "Got bit rate %u.\n", video_info->dwBitRate); + ok(!video_info->dwBitErrorRate, "Got bit error rate %u.\n", video_info->dwBitErrorRate); + ok(video_info->bmiHeader.biSize == sizeof(video_info->bmiHeader), + "Got size %u.\n", video_info->bmiHeader.biSize); + ok(video_info->bmiHeader.biWidth == 64, "Got width %d.\n", video_info->bmiHeader.biWidth); + ok(video_info->bmiHeader.biHeight == 48, "Got height %d.\n", video_info->bmiHeader.biHeight); + ok(video_info->bmiHeader.biPlanes == 1, "Got planes %d.\n", video_info->bmiHeader.biPlanes); +} + +static void check_audio_type(const WM_MEDIA_TYPE *mt) +{ + const WAVEFORMATEX *wave_format = (const WAVEFORMATEX *)mt->pbFormat; + + ok(IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_PCM), "Got subtype %s.\n", debugstr_guid(&mt->subtype)); + ok(IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx), "Got format %s.\n", debugstr_guid(&mt->formattype)); + ok(mt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", mt->bFixedSizeSamples); + ok(!mt->bTemporalCompression, "Got temporal compression %d.\n", mt->bTemporalCompression); + ok(!mt->pUnk, "Got pUnk %p.\n", mt->pUnk); + + ok(wave_format->wFormatTag == WAVE_FORMAT_PCM, "Got tag %#x.\n", wave_format->wFormatTag); +} + +static void test_sync_reader_types(void) +{ + char mt_buffer[2000], mt2_buffer[2000]; + const WCHAR *filename = load_resource(L"test.wmv"); + IWMOutputMediaProps *output_props, *output_props2; + WM_MEDIA_TYPE *mt2 = (WM_MEDIA_TYPE *)mt2_buffer; + WM_MEDIA_TYPE *mt = (WM_MEDIA_TYPE *)mt_buffer; + bool got_video = false, got_audio = false; + DWORD size, ret_size, output_number; + WORD stream_number, stream_number2; + struct teststream stream = {0}; + IWMStreamConfig *config; + ULONG count, ref, i, j; + IWMSyncReader *reader; + IWMProfile *profile; + GUID majortype; + HANDLE file; + HRESULT hr; + BOOL ret; + + file = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "Failed to open %s, error %u.\n", debugstr_w(file), GetLastError()); + + stream.IStream_iface.lpVtbl = &stream_vtbl; + stream.refcount = 1; + stream.file = file; + + hr = WMCreateSyncReader(NULL, 0, &reader); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IWMSyncReader_QueryInterface(reader, &IID_IWMProfile, (void **)&profile); + + hr = IWMSyncReader_OpenStream(reader, &stream.IStream_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(stream.refcount > 1, "Got refcount %d.\n", stream.refcount); + + for (i = 0; i < 2; ++i) + { + winetest_push_context("Stream %u", i); + + hr = IWMProfile_GetStream(profile, i, &config); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + if (hr != S_OK) + { + winetest_pop_context(); + continue; + } + + stream_number = 0xdead; + hr = IWMStreamConfig_GetStreamNumber(config, &stream_number); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(stream_number == i + 1, "Got stream number %u.\n", stream_number); + + hr = IWMStreamConfig_GetStreamType(config, &majortype); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + if (!i) + todo_wine ok(IsEqualGUID(&majortype, &MEDIATYPE_Video), "Got major type %s.\n", debugstr_guid(&majortype)); + else + todo_wine ok(IsEqualGUID(&majortype, &MEDIATYPE_Audio), "Got major type %s.\n", debugstr_guid(&majortype)); + + ref = IWMStreamConfig_Release(config); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + output_number = 0xdeadbeef; + hr = IWMSyncReader_GetOutputNumberForStream(reader, stream_number, &output_number); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(output_number == 1 - i, "Got output number %u.\n", output_number); + + stream_number2 = 0xdead; + hr = IWMSyncReader_GetStreamNumberForOutput(reader, output_number, &stream_number2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(stream_number2 == stream_number, "Expected stream number %u, got %u.\n", stream_number, stream_number2); + + hr = IWMSyncReader_GetOutputProps(reader, output_number, &output_props); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + + ret_size = sizeof(mt_buffer); + hr = IWMOutputMediaProps_GetMediaType(output_props, mt, &ret_size); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + ref = IWMOutputMediaProps_Release(output_props); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + if (IsEqualGUID(&majortype, &MEDIATYPE_Audio)) + { + got_audio = true; + check_audio_type(mt); + } + else + { + ok(IsEqualGUID(&majortype, &MEDIATYPE_Video), "Got major type %s.\n", debugstr_guid(&majortype)); + got_video = true; + check_video_type(mt); + } + + count = 0; + hr = IWMSyncReader_GetOutputFormatCount(reader, output_number, &count); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(count > 0, "Got count %u.\n", count); + + for (j = 0; j < count; ++j) + { + winetest_push_context("Format %u", j); + + hr = IWMSyncReader_GetOutputFormat(reader, output_number, j, &output_props); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_GetOutputFormat(reader, output_number, j, &output_props2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(output_props2 != output_props, "Expected different objects.\n"); + ref = IWMOutputMediaProps_Release(output_props2); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + size = 0xdeadbeef; + hr = IWMOutputMediaProps_GetMediaType(output_props, NULL, &size); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(size != 0xdeadbeef && size >= sizeof(WM_MEDIA_TYPE), "Got size %u.\n", size); + + ret_size = size - 1; + hr = IWMOutputMediaProps_GetMediaType(output_props, mt, &ret_size); + ok(hr == ASF_E_BUFFERTOOSMALL, "Got hr %#x.\n", hr); + ok(ret_size == size, "Expected size %u, got %u.\n", size, ret_size); + + ret_size = sizeof(mt_buffer); + memset(mt_buffer, 0xcc, sizeof(mt_buffer)); + hr = IWMOutputMediaProps_GetMediaType(output_props, mt, &ret_size); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(ret_size == size, "Expected size %u, got %u.\n", size, ret_size); + ok(size == sizeof(WM_MEDIA_TYPE) + mt->cbFormat, "Expected size %u, got %u.\n", + sizeof(WM_MEDIA_TYPE) + mt->cbFormat, size); + + ok(IsEqualGUID(&mt->majortype, &majortype), "Got major type %s.\n", debugstr_guid(&mt->majortype)); + + if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio)) + check_audio_type(mt); + else + check_video_type(mt); + + hr = IWMSyncReader_SetOutputProps(reader, output_number, output_props); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + if (hr != S_OK) + { + ref = IWMOutputMediaProps_Release(output_props); + ok(!ref, "Got outstanding refcount %d.\n", ref); + winetest_pop_context(); + continue; + } + hr = IWMSyncReader_SetOutputProps(reader, 1 - output_number, output_props); + if (!i) + todo_wine ok(hr == ASF_E_BADMEDIATYPE, "Got hr %#x.\n", hr); + else + ok(hr == NS_E_INCOMPATIBLE_FORMAT, "Got hr %#x.\n", hr); + hr = IWMSyncReader_SetOutputProps(reader, 2, output_props); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_GetOutputProps(reader, output_number, &output_props2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(output_props2 != output_props, "Expected different objects.\n"); + + ret_size = sizeof(mt2_buffer); + hr = IWMOutputMediaProps_GetMediaType(output_props2, mt2, &ret_size); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(compare_media_types(mt, mt2), "Media types didn't match.\n"); + + ref = IWMOutputMediaProps_Release(output_props2); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IWMOutputMediaProps_Release(output_props); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + winetest_pop_context(); + } + + hr = IWMSyncReader_GetOutputFormat(reader, output_number, count, &output_props); + todo_wine ok(hr == NS_E_INVALID_OUTPUT_FORMAT, "Got hr %#x.\n", hr); + + hr = IWMSyncReader_GetOutputProps(reader, output_number, &output_props); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + + if (hr == S_OK) + { + hr = IWMSyncReader_GetOutputProps(reader, output_number, &output_props2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(output_props2 != output_props, "Expected different objects.\n"); + + ref = IWMOutputMediaProps_Release(output_props2); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IWMOutputMediaProps_Release(output_props); + ok(!ref, "Got outstanding refcount %d.\n", ref); + } + + winetest_pop_context(); + } + + todo_wine ok(got_audio, "No audio stream was enumerated.\n"); + todo_wine ok(got_video, "No video stream was enumerated.\n"); + + count = 0xdeadbeef; + hr = IWMSyncReader_GetOutputFormatCount(reader, 2, &count); + todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + ok(count == 0xdeadbeef, "Got count %#x.\n", count); + + output_props = (void *)0xdeadbeef; + hr = IWMSyncReader_GetOutputProps(reader, 2, &output_props); + todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + ok(output_props == (void *)0xdeadbeef, "Got output props %p.\n", output_props); + + output_props = (void *)0xdeadbeef; + hr = IWMSyncReader_GetOutputFormat(reader, 2, 0, &output_props); + todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + ok(output_props == (void *)0xdeadbeef, "Got output props %p.\n", output_props); + + IWMProfile_Release(profile); + ref = IWMSyncReader_Release(reader); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + ok(stream.refcount == 1, "Got outstanding refcount %d.\n", stream.refcount); + CloseHandle(stream.file); + ret = DeleteFileW(filename); + ok(ret, "Failed to delete %s, error %u.\n", debugstr_w(filename), GetLastError()); +} + START_TEST(wmvcore) { HRESULT hr; @@ -633,6 +899,7 @@ START_TEST(wmvcore) test_urlextension(); test_iscontentprotected(); test_sync_reader_streaming(); + test_sync_reader_types();
CoUninitialize(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=100716
Your paranoid android.
=== w8 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w8adm (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w864 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064v1507 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w1064v1809 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w1064 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w1064_tsign (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w864 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064v1507 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064v1809 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064_2qxl (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064_tsign (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w10pro64 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64_ar (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64_he (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w10pro64_ja (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64_zh_CN (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gst_private.h | 6 +++++ dlls/winegstreamer/wm_asyncreader.c | 2 ++ dlls/winegstreamer/wm_reader.c | 37 +++++++++++++++++++++++++++++ dlls/winegstreamer/wm_syncreader.c | 18 +++++++++----- dlls/wmvcore/tests/wmvcore.c | 10 ++++---- 5 files changed, 62 insertions(+), 11 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index c757dfbefd8..a07195a4a1e 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -122,6 +122,9 @@ struct wm_reader IWMReaderPlaylistBurn IWMReaderPlaylistBurn_iface; IWMReaderTimecode IWMReaderTimecode_iface; LONG refcount; + CRITICAL_SECTION cs; + + IStream *source_stream;
const struct wm_reader_ops *ops; }; @@ -132,6 +135,9 @@ struct wm_reader_ops void (*destroy)(struct wm_reader *reader); };
+void wm_reader_cleanup(struct wm_reader *reader); +HRESULT wm_reader_close(struct wm_reader *reader); void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops); +HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream);
#endif /* __GST_PRIVATE_INCLUDED__ */ diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index 12b96245707..4fec89a2100 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -1255,6 +1255,8 @@ static void async_reader_destroy(struct wm_reader *iface)
TRACE("reader %p.\n", reader);
+ wm_reader_close(&reader->reader); + wm_reader_cleanup(&reader->reader); free(reader); }
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 963d33afe0f..e5c2d2a9789 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -759,6 +759,34 @@ static const IWMReaderTimecodeVtbl timecode_vtbl = timecode_GetTimecodeRangeBounds, };
+HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream) +{ + EnterCriticalSection(&reader->cs); + + IStream_AddRef(reader->source_stream = stream); + + LeaveCriticalSection(&reader->cs); + + return S_OK; +} + +HRESULT wm_reader_close(struct wm_reader *reader) +{ + EnterCriticalSection(&reader->cs); + + if (!reader->source_stream) + { + LeaveCriticalSection(&reader->cs); + return NS_E_INVALID_REQUEST; + } + + IStream_Release(reader->source_stream); + reader->source_stream = NULL; + + LeaveCriticalSection(&reader->cs); + return S_OK; +} + void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops) { reader->IWMHeaderInfo3_iface.lpVtbl = &header_info_vtbl; @@ -769,4 +797,13 @@ void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops) reader->IWMReaderTimecode_iface.lpVtbl = &timecode_vtbl; reader->refcount = 1; reader->ops = ops; + + InitializeCriticalSection(&reader->cs); + reader->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wm_reader.cs"); +} + +void wm_reader_cleanup(struct wm_reader *reader) +{ + reader->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&reader->cs); } diff --git a/dlls/winegstreamer/wm_syncreader.c b/dlls/winegstreamer/wm_syncreader.c index 0113ced1730..bb98a60ad48 100644 --- a/dlls/winegstreamer/wm_syncreader.c +++ b/dlls/winegstreamer/wm_syncreader.c @@ -55,9 +55,11 @@ static ULONG WINAPI WMSyncReader_Release(IWMSyncReader2 *iface)
static HRESULT WINAPI WMSyncReader_Close(IWMSyncReader2 *iface) { - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p): stub!\n", This); - return E_NOTIMPL; + struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p.\n", reader); + + return wm_reader_close(&reader->reader); }
static HRESULT WINAPI WMSyncReader_GetMaxOutputSampleSize(IWMSyncReader2 *iface, DWORD output, DWORD *max) @@ -157,9 +159,11 @@ static HRESULT WINAPI WMSyncReader_Open(IWMSyncReader2 *iface, const WCHAR *file
static HRESULT WINAPI WMSyncReader_OpenStream(IWMSyncReader2 *iface, IStream *stream) { - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%p): stub!\n", This, stream); - return S_OK; + struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, stream %p.\n", reader, stream); + + return wm_reader_open_stream(&reader->reader, stream); }
static HRESULT WINAPI WMSyncReader_SetOutputProps(IWMSyncReader2 *iface, DWORD output_num, IWMOutputMediaProps *output) @@ -309,6 +313,8 @@ static void sync_reader_destroy(struct wm_reader *iface)
TRACE("reader %p.\n", reader);
+ wm_reader_close(&reader->reader); + wm_reader_cleanup(&reader->reader); free(reader); }
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 91849990a85..13d3cbe9d43 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -451,7 +451,7 @@ static void test_sync_reader_streaming(void)
hr = IWMSyncReader_OpenStream(reader, &stream.IStream_iface); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(stream.refcount > 1, "Got refcount %d.\n", stream.refcount); + ok(stream.refcount > 1, "Got refcount %d.\n", stream.refcount);
hr = IWMProfile_GetStreamCount(profile, NULL); ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); @@ -603,17 +603,17 @@ static void test_sync_reader_streaming(void) todo_wine ok(hr == NS_E_NO_MORE_SAMPLES, "Got hr %#x.\n", hr);
hr = IWMSyncReader_Close(reader); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IWMSyncReader_Close(reader); - todo_wine ok(hr == NS_E_INVALID_REQUEST, "Got hr %#x.\n", hr); + ok(hr == NS_E_INVALID_REQUEST, "Got hr %#x.\n", hr);
ok(stream.refcount == 1, "Got outstanding refcount %d.\n", stream.refcount);
SetFilePointer(stream.file, 0, NULL, FILE_BEGIN); hr = IWMSyncReader_OpenStream(reader, &stream.IStream_iface); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(stream.refcount > 1, "Got refcount %d.\n", stream.refcount); + ok(stream.refcount > 1, "Got refcount %d.\n", stream.refcount);
IWMProfile_Release(profile); ref = IWMSyncReader_Release(reader); @@ -695,7 +695,7 @@ static void test_sync_reader_types(void)
hr = IWMSyncReader_OpenStream(reader, &stream.IStream_iface); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(stream.refcount > 1, "Got refcount %d.\n", stream.refcount); + ok(stream.refcount > 1, "Got refcount %d.\n", stream.refcount);
for (i = 0; i < 2; ++i) {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=100717
Your paranoid android.
=== w8 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w8adm (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w864 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064v1507 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w1064v1809 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w1064 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w1064_tsign (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w864 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064v1507 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064v1809 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064_2qxl (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064_tsign (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w10pro64 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64_ar (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64_he (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w10pro64_ja (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64_zh_CN (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gst_private.h | 3 + dlls/winegstreamer/wm_reader.c | 113 ++++++++++++++++++++++++++++++- 2 files changed, 115 insertions(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index a07195a4a1e..caa449956bf 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -125,6 +125,9 @@ struct wm_reader CRITICAL_SECTION cs;
IStream *source_stream; + HANDLE read_thread; + bool read_thread_shutdown; + struct wg_parser *wg_parser;
const struct wm_reader_ops *ops; }; diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index e5c2d2a9789..163eebf8c55 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -20,6 +20,68 @@
WINE_DEFAULT_DEBUG_CHANNEL(wmvcore);
+static DWORD CALLBACK read_thread(void *arg) +{ + struct wm_reader *reader = arg; + IStream *stream = reader->source_stream; + size_t buffer_size = 4096; + uint64_t file_size; + STATSTG stat; + void *data; + + if (!(data = malloc(buffer_size))) + return 0; + + IStream_Stat(stream, &stat, STATFLAG_NONAME); + file_size = stat.cbSize.QuadPart; + + TRACE("Starting read thread for reader %p.\n", reader); + + while (!reader->read_thread_shutdown) + { + LARGE_INTEGER stream_offset; + uint64_t offset; + ULONG ret_size; + uint32_t size; + HRESULT hr; + + if (!wg_parser_get_next_read_offset(reader->wg_parser, &offset, &size)) + continue; + + if (offset >= file_size) + size = 0; + else if (offset + size >= file_size) + size = file_size - offset; + + if (!size) + { + wg_parser_push_data(reader->wg_parser, data, 0); + continue; + } + + if (!array_reserve(&data, &buffer_size, size, 1)) + { + free(data); + return 0; + } + + ret_size = 0; + + stream_offset.QuadPart = offset; + if (SUCCEEDED(hr = IStream_Seek(stream, stream_offset, STREAM_SEEK_SET, NULL))) + hr = IStream_Read(stream, data, size, &ret_size); + if (FAILED(hr)) + ERR("Failed to read %u bytes at offset %I64u, hr %#x.\n", size, offset, hr); + else if (ret_size != size) + ERR("Unexpected short read: requested %u bytes, got %u.\n", size, ret_size); + wg_parser_push_data(reader->wg_parser, SUCCEEDED(hr) ? data : NULL, ret_size); + } + + free(data); + TRACE("Reader is shutting down; exiting.\n"); + return 0; +} + static struct wm_reader *impl_from_IWMProfile3(IWMProfile3 *iface) { return CONTAINING_RECORD(iface, struct wm_reader, IWMProfile3_iface); @@ -761,13 +823,53 @@ static const IWMReaderTimecodeVtbl timecode_vtbl =
HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream) { + struct wg_parser *wg_parser; + STATSTG stat; + HRESULT hr; + + if (FAILED(hr = IStream_Stat(stream, &stat, STATFLAG_NONAME))) + { + ERR("Failed to stat stream, hr %#x.\n", hr); + return hr; + } + + if (!(wg_parser = wg_parser_create(WG_PARSER_DECODEBIN, false))) + return E_OUTOFMEMORY; + EnterCriticalSection(&reader->cs);
+ reader->wg_parser = wg_parser; IStream_AddRef(reader->source_stream = stream); + reader->read_thread_shutdown = false; + if (!(reader->read_thread = CreateThread(NULL, 0, read_thread, reader, 0, NULL))) + { + hr = E_OUTOFMEMORY; + goto out_destroy_parser; + } + + if (FAILED(hr = wg_parser_connect(reader->wg_parser, stat.cbSize.QuadPart))) + { + ERR("Failed to connect parser, hr %#x.\n", hr); + goto out_shutdown_thread; + }
LeaveCriticalSection(&reader->cs); - return S_OK; + +out_shutdown_thread: + reader->read_thread_shutdown = true; + WaitForSingleObject(reader->read_thread, INFINITE); + CloseHandle(reader->read_thread); + reader->read_thread = NULL; + +out_destroy_parser: + wg_parser_destroy(reader->wg_parser); + reader->wg_parser = NULL; + IStream_Release(reader->source_stream); + reader->source_stream = NULL; + + LeaveCriticalSection(&reader->cs); + return hr; }
HRESULT wm_reader_close(struct wm_reader *reader) @@ -780,6 +882,15 @@ HRESULT wm_reader_close(struct wm_reader *reader) return NS_E_INVALID_REQUEST; }
+ wg_parser_disconnect(reader->wg_parser); + + reader->read_thread_shutdown = true; + WaitForSingleObject(reader->read_thread, INFINITE); + CloseHandle(reader->read_thread); + reader->read_thread = NULL; + + wg_parser_destroy(reader->wg_parser); + reader->wg_parser = NULL; IStream_Release(reader->source_stream); reader->source_stream = NULL;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gst_private.h | 2 ++ dlls/winegstreamer/wm_reader.c | 10 ++++++++-- dlls/wmvcore/tests/wmvcore.c | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index caa449956bf..86ddc3c85c8 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -129,6 +129,8 @@ struct wm_reader bool read_thread_shutdown; struct wg_parser *wg_parser;
+ WORD stream_count; + const struct wm_reader_ops *ops; };
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 163eebf8c55..689d2232b73 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -188,12 +188,16 @@ static HRESULT WINAPI profile_SetDescription(IWMProfile3 *iface, const WCHAR *de
static HRESULT WINAPI profile_GetStreamCount(IWMProfile3 *iface, DWORD *count) { - FIXME("iface %p, count %p, stub!\n", iface, count); + struct wm_reader *reader = impl_from_IWMProfile3(iface); + + TRACE("reader %p, count %p.\n", reader, count);
if (!count) return E_INVALIDARG;
- *count = 0; + EnterCriticalSection(&reader->cs); + *count = reader->stream_count; + LeaveCriticalSection(&reader->cs); return S_OK; }
@@ -853,6 +857,8 @@ HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream) goto out_shutdown_thread; }
+ reader->stream_count = wg_parser_get_stream_count(reader->wg_parser); + LeaveCriticalSection(&reader->cs); return S_OK;
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 13d3cbe9d43..d19ea592ed9 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -459,7 +459,7 @@ static void test_sync_reader_streaming(void) count = 0xdeadbeef; hr = IWMProfile_GetStreamCount(profile, &count); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(count == 2, "Got count %u.\n", count); + ok(count == 2, "Got count %u.\n", count);
count = 0xdeadbeef; hr = IWMSyncReader_GetOutputCount(reader, &count);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=100719
Your paranoid android.
=== w8 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w8adm (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w864 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064v1507 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w1064v1809 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w1064 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w1064_tsign (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64 (32 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w864 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064v1507 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064v1809 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064_2qxl (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w1064_tsign (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w10pro64 (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64_ar (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64_he (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.
=== w10pro64_ja (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated. wmvcore.c:815: Test failed: Stream 1: Format 0: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 1: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 2: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 3: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 4: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 5: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 6: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 7: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 8: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 9: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 10: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 11: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 12: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 13: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 14: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 15: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 16: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 17: Got hr 0xc00d0bbb. wmvcore.c:815: Test failed: Stream 1: Format 18: Got hr 0xc00d0bbb.
=== w10pro64_zh_CN (64 bit report) ===
wmvcore: wmvcore.c:634: Test failed: Stream 0: Format 3: I420 should not be enumerated.