[PATCH 1/2] mfmediaengine: Implement SetSourceFromByteStream().

Nikolay Sivov nsivov at codeweavers.com
Thu Jan 27 07:46:40 CST 2022


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfmediaengine/main.c                | 102 +++++++++++++++--------
 dlls/mfmediaengine/tests/mfmediaengine.c |  47 +++++++++++
 2 files changed, 114 insertions(+), 35 deletions(-)

diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c
index 3fb8e2b9433..ae844c60e54 100644
--- a/dlls/mfmediaengine/main.c
+++ b/dlls/mfmediaengine/main.c
@@ -1202,10 +1202,10 @@ static void media_engine_start_playback(struct media_engine *engine)
 static HRESULT WINAPI media_engine_load_handler_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
 {
     struct media_engine *engine = impl_from_load_handler_IMFAsyncCallback(iface);
+    IUnknown *object = NULL, *state;
     unsigned int start_playback;
     MF_OBJECT_TYPE obj_type;
     IMFMediaSource *source;
-    IUnknown *object = NULL;
     HRESULT hr;
 
     EnterCriticalSection(&engine->cs);
@@ -1216,7 +1216,15 @@ static HRESULT WINAPI media_engine_load_handler_Invoke(IMFAsyncCallback *iface,
     start_playback = engine->flags & FLAGS_ENGINE_PLAY_PENDING;
     media_engine_set_flag(engine, FLAGS_ENGINE_SOURCE_PENDING | FLAGS_ENGINE_PLAY_PENDING, FALSE);
 
-    if (FAILED(hr = IMFSourceResolver_EndCreateObjectFromURL(engine->resolver, result, &obj_type, &object)))
+    if (SUCCEEDED(IMFAsyncResult_GetState(result, &state)))
+    {
+        hr = IMFSourceResolver_EndCreateObjectFromByteStream(engine->resolver, result, &obj_type, &object);
+        IUnknown_Release(state);
+    }
+    else
+        hr = IMFSourceResolver_EndCreateObjectFromURL(engine->resolver, result, &obj_type, &object);
+
+    if (FAILED(hr))
         WARN("Failed to create source object, hr %#x.\n", hr);
 
     if (object)
@@ -1384,50 +1392,60 @@ static HRESULT WINAPI media_engine_SetSourceElements(IMFMediaEngineEx *iface, IM
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI media_engine_SetSource(IMFMediaEngineEx *iface, BSTR url)
+static HRESULT media_engine_set_source(struct media_engine *engine, IMFByteStream *bytestream, BSTR url)
 {
-    struct media_engine *engine = impl_from_IMFMediaEngineEx(iface);
+    IPropertyStore *props = NULL;
+    unsigned int flags;
     HRESULT hr = S_OK;
 
-    TRACE("%p, %s.\n", iface, debugstr_w(url));
+    SysFreeString(engine->current_source);
+    engine->current_source = NULL;
+    if (url)
+        engine->current_source = SysAllocString(url);
 
-    EnterCriticalSection(&engine->cs);
+    engine->ready_state = MF_MEDIA_ENGINE_READY_HAVE_NOTHING;
 
-    if (engine->flags & FLAGS_ENGINE_SHUT_DOWN)
-        hr = MF_E_SHUTDOWN;
-    else
+    IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_PURGEQUEUEDEVENTS, 0, 0);
+
+    engine->network_state = MF_MEDIA_ENGINE_NETWORK_NO_SOURCE;
+
+    if (url || bytestream)
     {
-        SysFreeString(engine->current_source);
-        engine->current_source = NULL;
-        if (url)
-            engine->current_source = SysAllocString(url);
+        flags = MF_RESOLUTION_MEDIASOURCE;
+        if (engine->flags & MF_MEDIA_ENGINE_DISABLE_LOCAL_PLUGINS)
+            flags |= MF_RESOLUTION_DISABLE_LOCAL_PLUGINS;
 
-        engine->ready_state = MF_MEDIA_ENGINE_READY_HAVE_NOTHING;
+        IMFAttributes_GetUnknown(engine->attributes, &MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE,
+                &IID_IPropertyStore, (void **)&props);
+        if (bytestream)
+            hr = IMFSourceResolver_BeginCreateObjectFromByteStream(engine->resolver, bytestream, url, flags,
+                    props, NULL, &engine->load_handler, (IUnknown *)bytestream);
+        else
+            hr = IMFSourceResolver_BeginCreateObjectFromURL(engine->resolver, url, flags, props, NULL,
+                    &engine->load_handler, NULL);
+        if (SUCCEEDED(hr))
+            media_engine_set_flag(engine, FLAGS_ENGINE_SOURCE_PENDING, TRUE);
 
-        IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_PURGEQUEUEDEVENTS, 0, 0);
+        if (props)
+            IPropertyStore_Release(props);
+    }
 
-        engine->network_state = MF_MEDIA_ENGINE_NETWORK_NO_SOURCE;
+    return hr;
+}
 
-        if (url)
-        {
-            IPropertyStore *props = NULL;
-            unsigned int flags;
+static HRESULT WINAPI media_engine_SetSource(IMFMediaEngineEx *iface, BSTR url)
+{
+    struct media_engine *engine = impl_from_IMFMediaEngineEx(iface);
+    HRESULT hr;
 
-            flags = MF_RESOLUTION_MEDIASOURCE;
-            if (engine->flags & MF_MEDIA_ENGINE_DISABLE_LOCAL_PLUGINS)
-                flags |= MF_RESOLUTION_DISABLE_LOCAL_PLUGINS;
+    TRACE("%p, %s.\n", iface, debugstr_w(url));
 
-            IMFAttributes_GetUnknown(engine->attributes, &MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE,
-                    &IID_IPropertyStore, (void **)&props);
-            hr = IMFSourceResolver_BeginCreateObjectFromURL(engine->resolver, url, flags, props, NULL,
-                    &engine->load_handler, NULL);
-            if (SUCCEEDED(hr))
-                media_engine_set_flag(engine, FLAGS_ENGINE_SOURCE_PENDING, TRUE);
+    EnterCriticalSection(&engine->cs);
 
-            if (props)
-                IPropertyStore_Release(props);
-        }
-    }
+    if (engine->flags & FLAGS_ENGINE_SHUT_DOWN)
+        hr = MF_E_SHUTDOWN;
+    else
+        hr = media_engine_set_source(engine, NULL, url);
 
     LeaveCriticalSection(&engine->cs);
 
@@ -2257,9 +2275,23 @@ static HRESULT WINAPI media_engine_OnVideoStreamTick(IMFMediaEngineEx *iface, LO
 
 static HRESULT WINAPI media_engine_SetSourceFromByteStream(IMFMediaEngineEx *iface, IMFByteStream *bytestream, BSTR url)
 {
-    FIXME("%p, %p, %s stub.\n", iface, bytestream, debugstr_w(url));
+    struct media_engine *engine = impl_from_IMFMediaEngineEx(iface);
+    HRESULT hr;
 
-    return E_NOTIMPL;
+    TRACE("%p, %p, %s.\n", iface, bytestream, debugstr_w(url));
+
+    EnterCriticalSection(&engine->cs);
+
+    if (engine->flags & FLAGS_ENGINE_SHUT_DOWN)
+        hr = MF_E_SHUTDOWN;
+    else if (!bytestream || !url)
+        hr = E_POINTER;
+    else
+        hr = media_engine_set_source(engine, bytestream, url);
+
+    LeaveCriticalSection(&engine->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI media_engine_GetStatistics(IMFMediaEngineEx *iface, MF_MEDIA_ENGINE_STATISTIC stat_id, PROPVARIANT *stat)
diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c
index 1f0a2eda1b3..3368484f58e 100644
--- a/dlls/mfmediaengine/tests/mfmediaengine.c
+++ b/dlls/mfmediaengine/tests/mfmediaengine.c
@@ -165,6 +165,20 @@ static IMFMediaEngine *create_media_engine(IMFMediaEngineNotify *callback)
     return media_engine;
 }
 
+static IMFMediaEngineEx *create_media_engine_ex(IMFMediaEngineNotify *callback)
+{
+    IMFMediaEngine *engine = create_media_engine(callback);
+    IMFMediaEngineEx *engine_ex = NULL;
+
+    if (engine)
+    {
+        IMFMediaEngine_QueryInterface(engine, &IID_IMFMediaEngineEx, (void **)&engine_ex);
+        IMFMediaEngine_Release(engine);
+    }
+
+    return engine_ex;
+}
+
 static void test_factory(void)
 {
     IMFMediaEngineClassFactory *factory, *factory2;
@@ -279,6 +293,7 @@ static void test_CreateInstance(void)
 static void test_Shutdown(void)
 {
     struct media_engine_notify *notify;
+    IMFMediaEngineEx *media_engine_ex;
     IMFMediaTimeRange *time_range;
     IMFMediaEngine *media_engine;
     unsigned int state;
@@ -428,6 +443,14 @@ todo_wine
     hr = IMFMediaEngine_GetVideoAspectRatio(media_engine, &cx, &cy);
     ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
 
+    if (SUCCEEDED(IMFMediaEngine_QueryInterface(media_engine, &IID_IMFMediaEngineEx, (void **)&media_engine_ex)))
+    {
+        hr = IMFMediaEngineEx_SetSourceFromByteStream(media_engine_ex, NULL, NULL);
+        ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+        IMFMediaEngineEx_Release(media_engine_ex);
+    }
+
     IMFMediaEngine_Release(media_engine);
     IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
 }
@@ -754,6 +777,29 @@ todo_wine {
     IMFMediaTimeRange_Release(range);
 }
 
+static void test_SetSourceFromByteStream(void)
+{
+    struct media_engine_notify *notify;
+    IMFMediaEngineEx *media_engine;
+    HRESULT hr;
+
+    notify = create_callback();
+
+    media_engine = create_media_engine_ex(&notify->IMFMediaEngineNotify_iface);
+    if (!media_engine)
+    {
+        win_skip("IMFMediaEngineEx is not supported.\n");
+        IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
+        return;
+    }
+
+    hr = IMFMediaEngineEx_SetSourceFromByteStream(media_engine, NULL, NULL);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    IMFMediaEngineEx_Release(media_engine);
+    IMFMediaEngineNotify_Release(&notify->IMFMediaEngineNotify_iface);
+}
+
 START_TEST(mfmediaengine)
 {
     HRESULT hr;
@@ -782,6 +828,7 @@ START_TEST(mfmediaengine)
     test_mute();
     test_error();
     test_time_range();
+    test_SetSourceFromByteStream();
 
     IMFMediaEngineClassFactory_Release(factory);
 
-- 
2.34.1




More information about the wine-devel mailing list