[PATCH v4] mfplat: Improve CreateObjectFromByteStream stub in IMFSourceResolver.

Sven Baars sven.wine at gmail.com
Thu Nov 22 14:00:45 CST 2018


Signed-off-by: Sven Baars <sven.wine at gmail.com>
---

v4: Rebased on top of Alistair's commit. I also used his naming convention while at it.

 dlls/mfplat/main.c         | 187 +++++++++++++++++++++++++++++++++++++
 dlls/mfplat/tests/mfplat.c |  78 +++++++++++++++-
 include/mfidl.idl          |  36 +++++++
 3 files changed, 299 insertions(+), 2 deletions(-)

diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 46a697538c..62461bb5f7 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -1315,6 +1315,174 @@ HRESULT WINAPI MFGetPluginControl(IMFPluginControl **ret)
     return S_OK;
 }
 
+typedef struct _mfsource
+{
+    IMFMediaSource IMFMediaSource_iface;
+    LONG ref;
+} mfsource;
+
+static inline mfsource *impl_from_IMFMediaSource(IMFMediaSource *iface)
+{
+    return CONTAINING_RECORD(iface, mfsource, IMFMediaSource_iface);
+}
+
+static HRESULT WINAPI mfsource_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), out);
+
+    if (IsEqualIID(riid, &IID_IMFMediaSource) ||
+        IsEqualIID(riid, &IID_IMFMediaEventGenerator) ||
+        IsEqualIID(riid, &IID_IUnknown))
+    {
+        *out = &This->IMFMediaSource_iface;
+    }
+    else
+    {
+        FIXME("(%s, %p)\n", debugstr_guid(riid), out);
+        *out = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*out);
+    return S_OK;
+}
+
+static ULONG WINAPI mfsource_AddRef(IMFMediaSource *iface)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+    ULONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%u\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI mfsource_Release(IMFMediaSource *iface)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+    ULONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%u\n", This, ref);
+
+    if (!ref)
+    {
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI mfsource_GetEvent(IMFMediaSource *iface, DWORD flags, IMFMediaEvent **event)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    FIXME("(%p)->(%#x, %p)\n", This, flags, event);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfsource_BeginGetEvent(IMFMediaSource *iface, IMFAsyncCallback *callback, IUnknown *state)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    FIXME("(%p)->(%p, %p)\n", This, callback, state);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfsource_EndGetEvent(IMFMediaSource *iface, IMFAsyncResult *result, IMFMediaEvent **event)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    FIXME("(%p)->(%p, %p)\n", This, result, event);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfsource_QueueEvent(IMFMediaSource *iface, MediaEventType event_type, REFGUID ext_type,
+        HRESULT hr, const PROPVARIANT *value)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    FIXME("(%p)->(%d, %s, %#x, %p)\n", This, event_type, debugstr_guid(ext_type), hr, value);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfsource_GetCharacteristics(IMFMediaSource *iface, DWORD *characteristics)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    FIXME("(%p)->(%p): stub\n", This, characteristics);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfsource_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **descriptor)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    FIXME("(%p)->(%p): stub\n", This, descriptor);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfsource_Start(IMFMediaSource *iface, IMFPresentationDescriptor *descriptor,
+                                     const GUID *time_format, const PROPVARIANT *start_position)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    FIXME("(%p)->(%p, %p, %p): stub\n", This, descriptor, time_format, start_position);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfsource_Stop(IMFMediaSource *iface)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    FIXME("(%p): stub\n", This);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfsource_Pause(IMFMediaSource *iface)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    FIXME("(%p): stub\n", This);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfsource_Shutdown(IMFMediaSource *iface)
+{
+    mfsource *This = impl_from_IMFMediaSource(iface);
+
+    FIXME("(%p): stub\n", This);
+
+    return S_OK;
+}
+
+static const IMFMediaSourceVtbl mfsourcevtbl =
+{
+    mfsource_QueryInterface,
+    mfsource_AddRef,
+    mfsource_Release,
+    mfsource_GetEvent,
+    mfsource_BeginGetEvent,
+    mfsource_EndGetEvent,
+    mfsource_QueueEvent,
+    mfsource_GetCharacteristics,
+    mfsource_CreatePresentationDescriptor,
+    mfsource_Start,
+    mfsource_Stop,
+    mfsource_Pause,
+    mfsource_Shutdown,
+};
+
 typedef struct _mfsourceresolver
 {
     IMFSourceResolver IMFSourceResolver_iface;
@@ -1388,6 +1556,25 @@ static HRESULT WINAPI mfsourceresolver_CreateObjectFromByteStream(IMFSourceResol
 
     FIXME("(%p)->(%p, %s, %#x, %p, %p, %p): stub\n", This, stream, debugstr_w(url), flags, props, obj_type, object);
 
+    if (!stream || !obj_type || !object)
+        return E_POINTER;
+
+    if (flags & MF_RESOLUTION_MEDIASOURCE)
+    {
+        mfsource *new_object;
+
+        new_object = HeapAlloc( GetProcessHeap(), 0, sizeof(*object) );
+        if (!new_object)
+            return E_OUTOFMEMORY;
+
+        new_object->IMFMediaSource_iface.lpVtbl = &mfsourcevtbl;
+        new_object->ref = 1;
+
+        *object = (IUnknown *)&new_object->IMFMediaSource_iface;
+        *obj_type = MF_OBJECT_MEDIASOURCE;
+        return S_OK;
+    }
+
     return E_NOTIMPL;
 }
 
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 48a8d0d361..d0f7ea4c98 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -42,6 +42,8 @@ static HRESULT (WINAPI *pMFCreateMemoryBuffer)(DWORD max_length, IMFMediaBuffer
 
 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 
+DEFINE_GUID(MF_BYTESTREAM_CONTENT_TYPE, 0xfc358289,0x3cb6,0x460c,0xa4,0x24,0xb6,0x68,0x12,0x60,0x37,0x5a);
+
 DEFINE_GUID(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 0xa634a91c, 0x822b, 0x41b9, 0xa4, 0x94, 0x4d, 0xe4, 0x64, 0x36, 0x12, 0xb0);
 
 DEFINE_GUID(MFT_CATEGORY_OTHER, 0x90175d57,0xb7ea,0x4901,0xae,0xb3,0x93,0x3a,0x87,0x47,0x75,0x6f);
@@ -200,7 +202,14 @@ if(0)
 static void test_source_resolver(void)
 {
     IMFSourceResolver *resolver, *resolver2;
+    IMFByteStream *bytestream;
+    IMFAttributes *attributes;
+    IMFMediaSource *mediasource;
+    MF_OBJECT_TYPE obj_type;
     HRESULT hr;
+    WCHAR *filename;
+
+    static const WCHAR file_type[] = {'v','i','d','e','o','/','m','p','4',0};
 
     if (!pMFCreateSourceResolver)
     {
@@ -208,6 +217,9 @@ static void test_source_resolver(void)
         return;
     }
 
+    hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
     hr = pMFCreateSourceResolver(NULL);
     ok(hr == E_POINTER, "got %#x\n", hr);
 
@@ -218,8 +230,70 @@ static void test_source_resolver(void)
     ok(hr == S_OK, "got %#x\n", hr);
     ok(resolver != resolver2, "Expected new instance\n");
 
-    IMFSourceResolver_Release(resolver);
     IMFSourceResolver_Release(resolver2);
+
+    filename = load_resource(mp4file);
+
+    hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
+                      MF_FILEFLAGS_NONE, filename, &bytestream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IMFSourceResolver_CreateObjectFromByteStream(
+        resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
+        &obj_type, (IUnknown **)&mediasource);
+    ok(hr == E_POINTER, "got 0x%08x\n", hr);
+
+    hr = IMFSourceResolver_CreateObjectFromByteStream(
+        resolver, bytestream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
+        NULL, (IUnknown **)&mediasource);
+    ok(hr == E_POINTER, "got 0x%08x\n", hr);
+
+    hr = IMFSourceResolver_CreateObjectFromByteStream(
+        resolver, bytestream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
+        &obj_type, NULL);
+    ok(hr == E_POINTER, "got 0x%08x\n", hr);
+
+    hr = IMFSourceResolver_CreateObjectFromByteStream(
+        resolver, bytestream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
+        &obj_type, (IUnknown **)&mediasource);
+    todo_wine ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got 0x%08x\n", hr);
+    if (hr == S_OK) IMFMediaSource_Release(mediasource);
+
+    hr = IMFSourceResolver_CreateObjectFromByteStream(
+        resolver, bytestream, NULL, MF_RESOLUTION_BYTESTREAM, NULL,
+        &obj_type, (IUnknown **)&mediasource);
+    todo_wine ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got 0x%08x\n", hr);
+
+    IMFByteStream_Release(bytestream);
+
+    /* We have to create a new bytestream here, because all following
+     * calls to CreateObjectFromByteStream will fail. */
+    hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
+                      MF_FILEFLAGS_NONE, filename, &bytestream);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IUnknown_QueryInterface(bytestream, &IID_IMFAttributes,
+                                 (void **)&attributes);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, file_type);
+    todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
+    IMFAttributes_Release(attributes);
+
+    hr = IMFSourceResolver_CreateObjectFromByteStream(
+        resolver, bytestream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
+        &obj_type, (IUnknown **)&mediasource);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(mediasource != NULL, "got %p\n", mediasource);
+    ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
+
+    IMFMediaSource_Release(mediasource);
+    IMFByteStream_Release(bytestream);
+
+    IMFSourceResolver_Release(resolver);
+
+    MFShutdown();
+
+    DeleteFileW(filename);
 }
 
 static void init_functions(void)
@@ -619,7 +693,6 @@ START_TEST(mfplat)
     init_functions();
 
     test_register();
-    test_source_resolver();
     test_MFCreateMediaType();
     test_MFCreateMediaEvent();
     test_MFCreateAttributes();
@@ -627,6 +700,7 @@ START_TEST(mfplat)
     test_MFCreateFile();
     test_MFCreateMFByteStreamOnStream();
     test_MFCreateMemoryBuffer();
+    test_source_resolver();
 
     CoUninitialize();
 }
diff --git a/include/mfidl.idl b/include/mfidl.idl
index 170588bb5f..2373e418be 100644
--- a/include/mfidl.idl
+++ b/include/mfidl.idl
@@ -313,3 +313,39 @@ cpp_quote("     IMFMediaType **types, IMFStreamDescriptor **descriptor);")
 cpp_quote("HRESULT WINAPI MFCreateTopology(IMFTopology **topology);")
 cpp_quote("HRESULT WINAPI MFGetSupportedMimeTypes(PROPVARIANT *array);")
 cpp_quote("HRESULT WINAPI MFGetService(IUnknown *object, REFGUID service, REFIID iid, void **obj);")
+
+[
+    object,
+    uuid(279a808d-aec7-40c8-9c6b-a6b492c78a66),
+]
+interface IMFMediaSource : IMFMediaEventGenerator
+{
+    HRESULT GetCharacteristics(
+        [out] DWORD *characteristics );
+
+    [local]
+    HRESULT CreatePresentationDescriptor(
+        [out] IMFPresentationDescriptor **descriptor );
+    [call_as(CreatePresentationDescriptor)]
+    HRESULT RemoteCreatePresentationDescriptor(
+        [out] DWORD *count,
+        [out, size_is(,*count)] BYTE **data,
+        [out] IMFPresentationDescriptor **descriptor );
+
+    HRESULT Start(
+        [in] IMFPresentationDescriptor *descriptor,
+        [in, unique] const GUID *time_format,
+        [in, unique] const PROPVARIANT *start_position );
+
+    HRESULT Stop();
+    HRESULT Pause();
+    HRESULT Shutdown();
+}
+
+cpp_quote("#define MF_RESOLUTION_MEDIASOURCE                                           0x00000001")
+cpp_quote("#define MF_RESOLUTION_BYTESTREAM                                            0x00000002")
+cpp_quote("#define MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE 0x00000010")
+cpp_quote("#define MF_RESOLUTION_KEEP_BYTE_STREAM_ALIVE_ON_FAIL                        0x00000020")
+cpp_quote("#define MF_RESOLUTION_READ                                                  0x00010000")
+cpp_quote("#define MF_RESOLUTION_WRITE                                                 0x00020000")
+cpp_quote("#define MF_RESOLUTION_DISABLE_LOCAL_PLUGINS                                 0x00000040")
-- 
2.17.1




More information about the wine-devel mailing list