mfreadwrite/tests: Add some tests for source reader.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8be164c921
commit
1d2567e03a
|
@ -3,3 +3,5 @@ IMPORTS = ole32 mfplat mfreadwrite mfuuid
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
mfplat.c
|
mfplat.c
|
||||||
|
|
||||||
|
RC_SRCS = resource.rc
|
||||||
|
|
|
@ -26,12 +26,19 @@
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
|
|
||||||
|
#include "initguid.h"
|
||||||
|
#include "ole2.h"
|
||||||
|
|
||||||
|
DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
#undef INITGUID
|
#undef INITGUID
|
||||||
|
#include "guiddef.h"
|
||||||
#include "mfapi.h"
|
#include "mfapi.h"
|
||||||
#include "mfidl.h"
|
#include "mfidl.h"
|
||||||
#include "mferror.h"
|
#include "mferror.h"
|
||||||
#include "mfreadwrite.h"
|
#include "mfreadwrite.h"
|
||||||
|
|
||||||
|
#include "wine/heap.h"
|
||||||
#include "wine/test.h"
|
#include "wine/test.h"
|
||||||
|
|
||||||
static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
|
static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
|
||||||
|
@ -45,10 +52,37 @@ static void init_functions(void)
|
||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static IMFByteStream *get_resource_stream(const char *name)
|
||||||
|
{
|
||||||
|
IMFByteStream *bytestream;
|
||||||
|
IStream *stream;
|
||||||
|
DWORD written;
|
||||||
|
HRESULT hr;
|
||||||
|
HRSRC res;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
res = FindResourceA(NULL, name, (const char *)RT_RCDATA);
|
||||||
|
ok(res != 0, "Resource %s wasn't found.\n", name);
|
||||||
|
|
||||||
|
ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
|
||||||
|
|
||||||
|
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||||
|
ok(hr == S_OK, "Failed to create memory stream, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IStream_Write(stream, ptr, SizeofResource(GetModuleHandleA(NULL), res), &written);
|
||||||
|
ok(hr == S_OK, "Failed to write stream content, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
|
||||||
|
ok(hr == S_OK, "Failed to create bytestream, hr %#x.\n", hr);
|
||||||
|
IStream_Release(stream);
|
||||||
|
|
||||||
|
return bytestream;
|
||||||
|
}
|
||||||
|
|
||||||
static void test_MFCreateSourceReaderFromByteStream(void)
|
static void test_MFCreateSourceReaderFromByteStream(void)
|
||||||
{
|
{
|
||||||
static const WCHAR audio[] = {'A','u','d','i','o',0};
|
static const WCHAR audio[] = {'A','u','d','i','o',0};
|
||||||
IMFSourceReader *source = NULL;
|
IMFSourceReader *reader = NULL;
|
||||||
IMFAttributes *attributes;
|
IMFAttributes *attributes;
|
||||||
IMFByteStream *bytestream = NULL;
|
IMFByteStream *bytestream = NULL;
|
||||||
IStream *stream = NULL;
|
IStream *stream = NULL;
|
||||||
|
@ -75,15 +109,15 @@ static void test_MFCreateSourceReaderFromByteStream(void)
|
||||||
hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
|
hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
|
||||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
hr = MFCreateSourceReaderFromByteStream(bytestream, attributes, &source);
|
hr = MFCreateSourceReaderFromByteStream(bytestream, attributes, &reader);
|
||||||
todo_wine
|
todo_wine
|
||||||
ok(hr == S_OK || hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got 0x%08x\n", hr);
|
ok(hr == S_OK || hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got 0x%08x\n", hr);
|
||||||
|
|
||||||
IStream_Release(stream);
|
IStream_Release(stream);
|
||||||
IMFByteStream_Release(bytestream);
|
IMFByteStream_Release(bytestream);
|
||||||
IMFAttributes_Release(attributes);
|
IMFAttributes_Release(attributes);
|
||||||
if(source)
|
if (reader)
|
||||||
IMFSourceReader_Release(source);
|
IMFSourceReader_Release(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_factory(void)
|
static void test_factory(void)
|
||||||
|
@ -106,6 +140,236 @@ static void test_factory(void)
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct async_callback
|
||||||
|
{
|
||||||
|
IMFSourceReaderCallback IMFSourceReaderCallback_iface;
|
||||||
|
LONG refcount;
|
||||||
|
HANDLE event;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct async_callback *impl_from_IMFSourceReaderCallback(IMFSourceReaderCallback *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, struct async_callback, IMFSourceReaderCallback_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI async_callback_QueryInterface(IMFSourceReaderCallback *iface, REFIID riid, void **out)
|
||||||
|
{
|
||||||
|
if (IsEqualIID(riid, &IID_IMFSourceReaderCallback) ||
|
||||||
|
IsEqualIID(riid, &IID_IUnknown))
|
||||||
|
{
|
||||||
|
*out = iface;
|
||||||
|
IMFSourceReaderCallback_AddRef(iface);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI async_callback_AddRef(IMFSourceReaderCallback *iface)
|
||||||
|
{
|
||||||
|
struct async_callback *callback = impl_from_IMFSourceReaderCallback(iface);
|
||||||
|
return InterlockedIncrement(&callback->refcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI async_callback_Release(IMFSourceReaderCallback *iface)
|
||||||
|
{
|
||||||
|
struct async_callback *callback = impl_from_IMFSourceReaderCallback(iface);
|
||||||
|
ULONG refcount = InterlockedDecrement(&callback->refcount);
|
||||||
|
|
||||||
|
if (!refcount)
|
||||||
|
{
|
||||||
|
heap_free(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
return refcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI async_callback_OnReadSample(IMFSourceReaderCallback *iface, HRESULT hr, DWORD stream_index,
|
||||||
|
DWORD stream_flags, LONGLONG timestamp, IMFSample *sample)
|
||||||
|
{
|
||||||
|
ok(0, "Unexpected call.\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI async_callback_OnFlush(IMFSourceReaderCallback *iface, DWORD stream_index)
|
||||||
|
{
|
||||||
|
ok(0, "Unexpected call.\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI async_callback_OnEvent(IMFSourceReaderCallback *iface, DWORD stream_index, IMFMediaEvent *event)
|
||||||
|
{
|
||||||
|
ok(0, "Unexpected call.\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IMFSourceReaderCallbackVtbl async_callback_vtbl =
|
||||||
|
{
|
||||||
|
async_callback_QueryInterface,
|
||||||
|
async_callback_AddRef,
|
||||||
|
async_callback_Release,
|
||||||
|
async_callback_OnReadSample,
|
||||||
|
async_callback_OnFlush,
|
||||||
|
async_callback_OnEvent,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct async_callback *create_async_callback(void)
|
||||||
|
{
|
||||||
|
struct async_callback *callback;
|
||||||
|
|
||||||
|
callback = heap_alloc(sizeof(*callback));
|
||||||
|
callback->IMFSourceReaderCallback_iface.lpVtbl = &async_callback_vtbl;
|
||||||
|
callback->refcount = 1;
|
||||||
|
|
||||||
|
return callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_source_reader(void)
|
||||||
|
{
|
||||||
|
struct async_callback *callback;
|
||||||
|
IMFAttributes *attributes;
|
||||||
|
IMFMediaType *mediatype;
|
||||||
|
IMFSourceReader *reader;
|
||||||
|
IMFMediaSource *source;
|
||||||
|
IMFByteStream *stream;
|
||||||
|
BOOL selected;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!pMFCreateMFByteStreamOnStream)
|
||||||
|
return;
|
||||||
|
|
||||||
|
stream = get_resource_stream("test.wav");
|
||||||
|
|
||||||
|
hr = MFCreateSourceReaderFromByteStream(stream, NULL, &reader);
|
||||||
|
todo_wine
|
||||||
|
ok(hr == S_OK, "Failed to create source reader, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
IMFByteStream_Release(stream);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Access underlying media source object. */
|
||||||
|
hr = IMFSourceReader_GetServiceForStream(reader, MF_SOURCE_READER_MEDIASOURCE, &GUID_NULL, &IID_IMFMediaSource,
|
||||||
|
(void **)&source);
|
||||||
|
ok(hr == S_OK, "Failed to get media source interface, hr %#x.\n", hr);
|
||||||
|
IMFMediaSource_Release(source);
|
||||||
|
|
||||||
|
/* Stream selection. */
|
||||||
|
hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &selected);
|
||||||
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_GetStreamSelection(reader, 100, &selected);
|
||||||
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
selected = FALSE;
|
||||||
|
hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected);
|
||||||
|
ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr);
|
||||||
|
ok(selected, "Unexpected selection.\n");
|
||||||
|
|
||||||
|
selected = FALSE;
|
||||||
|
hr = IMFSourceReader_GetStreamSelection(reader, 0, &selected);
|
||||||
|
ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr);
|
||||||
|
ok(selected, "Unexpected selection.\n");
|
||||||
|
|
||||||
|
hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, TRUE);
|
||||||
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_SetStreamSelection(reader, 100, TRUE);
|
||||||
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, FALSE);
|
||||||
|
ok(hr == S_OK, "Failed to deselect a stream, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
selected = TRUE;
|
||||||
|
hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected);
|
||||||
|
ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr);
|
||||||
|
ok(!selected, "Unexpected selection.\n");
|
||||||
|
|
||||||
|
hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_ALL_STREAMS, TRUE);
|
||||||
|
ok(hr == S_OK, "Failed to deselect a stream, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
selected = FALSE;
|
||||||
|
hr = IMFSourceReader_GetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &selected);
|
||||||
|
ok(hr == S_OK, "Failed to get stream selection, hr %#x.\n", hr);
|
||||||
|
ok(selected, "Unexpected selection.\n");
|
||||||
|
|
||||||
|
/* Native media type. */
|
||||||
|
hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &mediatype);
|
||||||
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_GetNativeMediaType(reader, 100, 0, &mediatype);
|
||||||
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &mediatype);
|
||||||
|
ok(hr == S_OK, "Failed to get native mediatype, hr %#x.\n", hr);
|
||||||
|
IMFMediaType_Release(mediatype);
|
||||||
|
|
||||||
|
/* MF_SOURCE_READER_CURRENT_TYPE_INDEX is Win8+ */
|
||||||
|
hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM,
|
||||||
|
MF_SOURCE_READER_CURRENT_TYPE_INDEX, &mediatype);
|
||||||
|
ok(hr == S_OK || broken(hr == MF_E_NO_MORE_TYPES), "Failed to get native mediatype, hr %#x.\n", hr);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
IMFMediaType_Release(mediatype);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 1, &mediatype);
|
||||||
|
ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
/* Current media type. */
|
||||||
|
hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &mediatype);
|
||||||
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_GetCurrentMediaType(reader, 100, &mediatype);
|
||||||
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &mediatype);
|
||||||
|
ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr);
|
||||||
|
IMFMediaType_Release(mediatype);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_GetCurrentMediaType(reader, 0, &mediatype);
|
||||||
|
ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr);
|
||||||
|
IMFMediaType_Release(mediatype);
|
||||||
|
|
||||||
|
/* Flush. */
|
||||||
|
hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM);
|
||||||
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_Flush(reader, 100);
|
||||||
|
ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM);
|
||||||
|
ok(hr == S_OK, "Failed to flush stream, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM);
|
||||||
|
ok(hr == S_OK, "Failed to flush stream, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFSourceReader_Flush(reader, MF_SOURCE_READER_ALL_STREAMS);
|
||||||
|
ok(hr == S_OK, "Failed to flush all streams, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
IMFSourceReader_Release(reader);
|
||||||
|
|
||||||
|
/* Async mode. */
|
||||||
|
callback = create_async_callback();
|
||||||
|
|
||||||
|
hr = MFCreateAttributes(&attributes, 1);
|
||||||
|
ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IMFAttributes_SetUnknown(attributes, &MF_SOURCE_READER_ASYNC_CALLBACK,
|
||||||
|
(IUnknown *)&callback->IMFSourceReaderCallback_iface);
|
||||||
|
ok(hr == S_OK, "Failed to set attribute value, hr %#x.\n", hr);
|
||||||
|
IMFSourceReaderCallback_Release(&callback->IMFSourceReaderCallback_iface);
|
||||||
|
|
||||||
|
hr = MFCreateSourceReaderFromByteStream(stream, attributes, &reader);
|
||||||
|
ok(hr == S_OK, "Failed to create source reader, hr %#x.\n", hr);
|
||||||
|
IMFAttributes_Release(attributes);
|
||||||
|
|
||||||
|
IMFSourceReader_Release(reader);
|
||||||
|
|
||||||
|
IMFByteStream_Release(stream);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(mfplat)
|
START_TEST(mfplat)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -117,6 +381,7 @@ START_TEST(mfplat)
|
||||||
|
|
||||||
test_MFCreateSourceReaderFromByteStream();
|
test_MFCreateSourceReaderFromByteStream();
|
||||||
test_factory();
|
test_factory();
|
||||||
|
test_source_reader();
|
||||||
|
|
||||||
hr = MFShutdown();
|
hr = MFShutdown();
|
||||||
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
|
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 Nikolay Sivov 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"
|
||||||
|
|
||||||
|
/* @makedep: test.wav */
|
||||||
|
test.wav RCDATA test.wav
|
Binary file not shown.
Loading…
Reference in New Issue