[PATCH 3/4] mfreadwrite/tests: Add some tests for source reader.

Nikolay Sivov nsivov at codeweavers.com
Tue Apr 9 05:45:10 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at 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 at PQhp007ieqznK6

literal 0
HcmV?d00001

-- 
2.20.1




More information about the wine-devel mailing list