Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/tests/Makefile.in | 2 + dlls/mfreadwrite/tests/mfplat.c | 273 ++++++++++++++++++++++++++++- dlls/mfreadwrite/tests/resource.rc | 22 +++ dlls/mfreadwrite/tests/test.wav | Bin 0 -> 4488 bytes 4 files changed, 293 insertions(+), 4 deletions(-) create mode 100644 dlls/mfreadwrite/tests/resource.rc create mode 100644 dlls/mfreadwrite/tests/test.wav
diff --git a/dlls/mfreadwrite/tests/Makefile.in b/dlls/mfreadwrite/tests/Makefile.in index 5c906a138a..ae86fed95f 100644 --- a/dlls/mfreadwrite/tests/Makefile.in +++ b/dlls/mfreadwrite/tests/Makefile.in @@ -3,3 +3,5 @@ IMPORTS = ole32 mfplat mfreadwrite mfuuid
C_SRCS = \ mfplat.c + +RC_SRCS = resource.rc diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index c031ddc9bd..16fa8223bf 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -26,12 +26,19 @@ #include "winuser.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 +#include "guiddef.h" #include "mfapi.h" #include "mfidl.h" #include "mferror.h" #include "mfreadwrite.h"
+#include "wine/heap.h" #include "wine/test.h"
static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream); @@ -45,10 +52,37 @@ static void init_functions(void) #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 const WCHAR audio[] = {'A','u','d','i','o',0}; - IMFSourceReader *source = NULL; + IMFSourceReader *reader = NULL; IMFAttributes *attributes; IMFByteStream *bytestream = NULL; IStream *stream = NULL; @@ -75,15 +109,15 @@ static void test_MFCreateSourceReaderFromByteStream(void) hr = pMFCreateMFByteStreamOnStream(stream, &bytestream); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = MFCreateSourceReaderFromByteStream(bytestream, attributes, &source); + hr = MFCreateSourceReaderFromByteStream(bytestream, attributes, &reader); todo_wine ok(hr == S_OK || hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got 0x%08x\n", hr);
IStream_Release(stream); IMFByteStream_Release(bytestream); IMFAttributes_Release(attributes); - if(source) - IMFSourceReader_Release(source); + if (reader) + IMFSourceReader_Release(reader); }
static void test_factory(void) @@ -106,6 +140,236 @@ static void test_factory(void) 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) { HRESULT hr; @@ -117,6 +381,7 @@ START_TEST(mfplat)
test_MFCreateSourceReaderFromByteStream(); test_factory(); + test_source_reader();
hr = MFShutdown(); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); diff --git a/dlls/mfreadwrite/tests/resource.rc b/dlls/mfreadwrite/tests/resource.rc new file mode 100644 index 0000000000..f54212a8c8 --- /dev/null +++ b/dlls/mfreadwrite/tests/resource.rc @@ -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 diff --git a/dlls/mfreadwrite/tests/test.wav b/dlls/mfreadwrite/tests/test.wav new file mode 100644 index 0000000000000000000000000000000000000000..51d23936196da1a0452c78713c8af819259d225e GIT binary patch literal 4488 zcmWIYbaQJEWMBw)40BD(Em06)U|?VbLYFlRV9dzC!QkT=93ll2_w;k~_Y8Im;RCXL z63fy|&GbwR^b8FQ8B!8U60LxyG&DA~w6?W(c6Imk^!D}jLqT6(Z%=nuXGeQmYjaa$ zeO*m;Rb_cuX-RQWQDFfL6c!d0mz0*3S5#Kl)YdmNHMg|2cYsVnGN`|=7h+OdYfE!u zLtSl6Rb>Ulq(Zn!AcH_ARa910*VfgKI%zbNM$^)0jvFnPMvKbP3T3p~9c`R|TVA8> dC3y36v{gCU_8#q_jCPtvyOyIJ@PQhp007ieqznK6
literal 0 HcmV?d00001