639 lines
22 KiB
C
639 lines
22 KiB
C
/*
|
|
* 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
|
|
* 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 <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)
|
|
{
|
|
HRESULT hr, expected_hr;
|
|
IUnknown *unknown = iface, *out;
|
|
|
|
expected_hr = supported ? S_OK : E_NOINTERFACE;
|
|
|
|
hr = IUnknown_QueryInterface(unknown, riid, (void **)&out);
|
|
ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
|
|
if (SUCCEEDED(hr))
|
|
IUnknown_Release(out);
|
|
return hr;
|
|
}
|
|
|
|
static void test_wmwriter_interfaces(void)
|
|
{
|
|
HRESULT hr;
|
|
IWMWriter *writer;
|
|
|
|
hr = WMCreateWriter( NULL, &writer );
|
|
ok(hr == S_OK, "WMCreateWriter failed 0x%08x\n", hr);
|
|
if(FAILED(hr))
|
|
{
|
|
win_skip("Failed to create IWMWriter\n");
|
|
return;
|
|
}
|
|
|
|
check_interface(writer, &IID_IWMWriterSink, FALSE);
|
|
|
|
check_interface(writer, &IID_IWMWriter, TRUE);
|
|
check_interface(writer, &IID_IWMWriterAdvanced, TRUE);
|
|
check_interface(writer, &IID_IWMWriterAdvanced2, TRUE);
|
|
check_interface(writer, &IID_IWMWriterAdvanced3, TRUE);
|
|
todo_wine check_interface(writer, &IID_IWMWriterPreprocess, TRUE);
|
|
todo_wine check_interface(writer, &IID_IWMHeaderInfo, TRUE);
|
|
todo_wine check_interface(writer, &IID_IWMHeaderInfo2, TRUE);
|
|
todo_wine check_interface(writer, &IID_IWMHeaderInfo3, TRUE);
|
|
|
|
IWMWriter_Release(writer);
|
|
}
|
|
|
|
static void test_wmreader_interfaces(void)
|
|
{
|
|
HRESULT hr;
|
|
IWMReader *reader;
|
|
|
|
hr = WMCreateReader( NULL, 0, &reader );
|
|
ok(hr == S_OK, "WMCreateReader failed 0x%08x\n", hr);
|
|
if(FAILED(hr))
|
|
{
|
|
win_skip("Failed to create IWMReader\n");
|
|
return;
|
|
}
|
|
|
|
check_interface(reader, &IID_IWMDRMReader, FALSE);
|
|
check_interface(reader, &IID_IWMDRMReader2, FALSE);
|
|
check_interface(reader, &IID_IWMDRMReader3, FALSE);
|
|
check_interface(reader, &IID_IWMSyncReader, FALSE);
|
|
check_interface(reader, &IID_IWMSyncReader2, FALSE);
|
|
|
|
check_interface(reader, &IID_IReferenceClock, TRUE);
|
|
check_interface(reader, &IID_IWMHeaderInfo, TRUE);
|
|
check_interface(reader, &IID_IWMHeaderInfo2, TRUE);
|
|
check_interface(reader, &IID_IWMHeaderInfo3, TRUE);
|
|
check_interface(reader, &IID_IWMLanguageList, TRUE);
|
|
check_interface(reader, &IID_IWMPacketSize, TRUE);
|
|
check_interface(reader, &IID_IWMPacketSize2, TRUE);
|
|
check_interface(reader, &IID_IWMProfile, TRUE);
|
|
check_interface(reader, &IID_IWMProfile2, TRUE);
|
|
check_interface(reader, &IID_IWMProfile3, TRUE);
|
|
check_interface(reader, &IID_IWMReader, TRUE);
|
|
check_interface(reader, &IID_IWMReaderAccelerator, TRUE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced, TRUE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced2, TRUE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced3, TRUE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced4, TRUE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced5, TRUE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced6, TRUE);
|
|
check_interface(reader, &IID_IWMReaderNetworkConfig, TRUE);
|
|
check_interface(reader, &IID_IWMReaderNetworkConfig2, TRUE);
|
|
check_interface(reader, &IID_IWMReaderPlaylistBurn, TRUE);
|
|
check_interface(reader, &IID_IWMReaderStreamClock, TRUE);
|
|
check_interface(reader, &IID_IWMReaderTimecode, TRUE);
|
|
check_interface(reader, &IID_IWMReaderTypeNegotiation, TRUE);
|
|
|
|
IWMReader_Release(reader);
|
|
}
|
|
|
|
static void test_wmsyncreader_interfaces(void)
|
|
{
|
|
HRESULT hr;
|
|
IWMSyncReader *reader;
|
|
|
|
hr = WMCreateSyncReader( NULL, 0, &reader );
|
|
ok(hr == S_OK, "WMCreateSyncReader failed 0x%08x\n", hr);
|
|
if(FAILED(hr))
|
|
{
|
|
win_skip("Failed to create IWMSyncReader\n");
|
|
return;
|
|
}
|
|
|
|
check_interface(reader, &IID_IReferenceClock, FALSE);
|
|
check_interface(reader, &IID_IWMDRMReader, FALSE);
|
|
check_interface(reader, &IID_IWMDRMReader2, FALSE);
|
|
check_interface(reader, &IID_IWMDRMReader3, FALSE);
|
|
check_interface(reader, &IID_IWMReader, FALSE);
|
|
check_interface(reader, &IID_IWMReaderAccelerator, FALSE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced, FALSE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced2, FALSE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced3, FALSE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced4, FALSE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced5, FALSE);
|
|
check_interface(reader, &IID_IWMReaderAdvanced6, FALSE);
|
|
check_interface(reader, &IID_IWMReaderNetworkConfig, FALSE);
|
|
check_interface(reader, &IID_IWMReaderNetworkConfig2, FALSE);
|
|
check_interface(reader, &IID_IWMReaderStreamClock, FALSE);
|
|
check_interface(reader, &IID_IWMReaderTypeNegotiation, FALSE);
|
|
|
|
check_interface(reader, &IID_IWMHeaderInfo, TRUE);
|
|
check_interface(reader, &IID_IWMHeaderInfo2, TRUE);
|
|
check_interface(reader, &IID_IWMHeaderInfo3, TRUE);
|
|
check_interface(reader, &IID_IWMLanguageList, TRUE);
|
|
check_interface(reader, &IID_IWMPacketSize, TRUE);
|
|
check_interface(reader, &IID_IWMPacketSize2, TRUE);
|
|
check_interface(reader, &IID_IWMProfile, TRUE);
|
|
check_interface(reader, &IID_IWMProfile2, TRUE);
|
|
check_interface(reader, &IID_IWMProfile3, TRUE);
|
|
check_interface(reader, &IID_IWMReaderPlaylistBurn, TRUE);
|
|
check_interface(reader, &IID_IWMReaderTimecode, TRUE);
|
|
check_interface(reader, &IID_IWMSyncReader, TRUE);
|
|
check_interface(reader, &IID_IWMSyncReader2, TRUE);
|
|
|
|
IWMSyncReader_Release(reader);
|
|
}
|
|
|
|
|
|
static void test_profile_manager_interfaces(void)
|
|
{
|
|
HRESULT hr;
|
|
IWMProfileManager *profile;
|
|
|
|
hr = WMCreateProfileManager(&profile);
|
|
ok(hr == S_OK, "WMCreateProfileManager failed 0x%08x\n", hr);
|
|
if(FAILED(hr))
|
|
{
|
|
win_skip("Failed to create IWMProfileManager\n");
|
|
return;
|
|
}
|
|
|
|
IWMProfileManager_Release(profile);
|
|
}
|
|
|
|
static void test_WMCreateWriterPriv(void)
|
|
{
|
|
IWMWriter *writer, *writer2;
|
|
HRESULT hr;
|
|
|
|
hr = WMCreateWriterPriv(&writer);
|
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
|
|
|
hr = IWMWriter_QueryInterface(writer, &IID_IWMWriter, (void**)&writer2);
|
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
|
|
|
IWMWriter_Release(writer);
|
|
IWMWriter_Release(writer2);
|
|
}
|
|
|
|
static void test_urlextension(void)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = WMCheckURLExtension(NULL);
|
|
ok(hr == E_INVALIDARG, "WMCheckURLExtension failed 0x%08x\n", hr);
|
|
hr = WMCheckURLExtension(L"test.mkv");
|
|
ok(hr == NS_E_INVALID_NAME, "WMCheckURLExtension failed 0x%08x\n", hr);
|
|
hr = WMCheckURLExtension(L"test.mp3");
|
|
todo_wine ok(hr == S_OK, "WMCheckURLExtension failed 0x%08x\n", hr);
|
|
hr = WMCheckURLExtension(L"abcd://test/test.wmv");
|
|
todo_wine ok(hr == S_OK, "WMCheckURLExtension failed 0x%08x\n", hr);
|
|
hr = WMCheckURLExtension(L"http://test/t.asf?alt=t.mkv");
|
|
todo_wine ok(hr == S_OK, "WMCheckURLExtension failed 0x%08x\n", hr);
|
|
}
|
|
|
|
static void test_iscontentprotected(void)
|
|
{
|
|
HRESULT hr;
|
|
BOOL drm;
|
|
|
|
hr = WMIsContentProtected(NULL, NULL);
|
|
ok(hr == E_INVALIDARG, "WMIsContentProtected failed 0x%08x\n", hr);
|
|
hr = WMIsContentProtected(NULL, &drm);
|
|
ok(hr == E_INVALIDARG, "WMIsContentProtected failed 0x%08x\n", hr);
|
|
hr = WMIsContentProtected(L"test.mp3", NULL);
|
|
ok(hr == E_INVALIDARG, "WMIsContentProtected failed 0x%08x\n", hr);
|
|
hr = WMIsContentProtected(L"test.mp3", &drm);
|
|
ok(hr == S_FALSE, "WMIsContentProtected failed 0x%08x\n", hr);
|
|
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;
|
|
|
|
hr = CoInitialize(0);
|
|
ok(hr == S_OK, "failed to init com\n");
|
|
if(hr != S_OK)
|
|
return;
|
|
|
|
test_wmreader_interfaces();
|
|
test_wmsyncreader_interfaces();
|
|
test_wmwriter_interfaces();
|
|
test_profile_manager_interfaces();
|
|
test_WMCreateWriterPriv();
|
|
test_urlextension();
|
|
test_iscontentprotected();
|
|
test_sync_reader_streaming();
|
|
|
|
CoUninitialize();
|
|
}
|