Signed-off-by: Nikolay Sivov <nsivov(a)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(¬ify->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(¬ify->IMFMediaEngineNotify_iface);
+ if (!media_engine)
+ {
+ win_skip("IMFMediaEngineEx is not supported.\n");
+ IMFMediaEngineNotify_Release(¬ify->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(¬ify->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