Signed-off-by: Nikolay Sivov nsivov@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);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfmediaengine/main.c | 72 +++++++++++++++++++++--- dlls/mfmediaengine/tests/mfmediaengine.c | 44 +++++++++++++++ 2 files changed, 108 insertions(+), 8 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index ae844c60e54..5c00c10f718 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -29,6 +29,8 @@ #include "mferror.h" #include "dxgi.h" #include "d3d11.h" +#include "mmdeviceapi.h" +#include "audiosessiontypes.h"
#include "wine/debug.h"
@@ -2495,30 +2497,78 @@ static HRESULT WINAPI media_engine_EnableHorizontalMirrorMode(IMFMediaEngineEx *
static HRESULT WINAPI media_engine_GetAudioStreamCategory(IMFMediaEngineEx *iface, UINT32 *category) { - FIXME("%p, %p stub.\n", iface, category); + struct media_engine *engine = impl_from_IMFMediaEngineEx(iface); + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, category); + + EnterCriticalSection(&engine->cs); + + if (engine->flags & FLAGS_ENGINE_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else + hr = IMFAttributes_GetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_CATEGORY, category); + + LeaveCriticalSection(&engine->cs); + + return hr; }
static HRESULT WINAPI media_engine_SetAudioStreamCategory(IMFMediaEngineEx *iface, UINT32 category) { - FIXME("%p, %u stub.\n", iface, category); + struct media_engine *engine = impl_from_IMFMediaEngineEx(iface); + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %u.\n", iface, category); + + EnterCriticalSection(&engine->cs); + + if (engine->flags & FLAGS_ENGINE_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else + hr = IMFAttributes_SetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_CATEGORY, category); + + LeaveCriticalSection(&engine->cs); + + return hr; }
static HRESULT WINAPI media_engine_GetAudioEndpointRole(IMFMediaEngineEx *iface, UINT32 *role) { - FIXME("%p, %p stub.\n", iface, role); + struct media_engine *engine = impl_from_IMFMediaEngineEx(iface); + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, role); + + EnterCriticalSection(&engine->cs); + + if (engine->flags & FLAGS_ENGINE_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else + hr = IMFAttributes_GetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE, role); + + LeaveCriticalSection(&engine->cs); + + return hr; }
static HRESULT WINAPI media_engine_SetAudioEndpointRole(IMFMediaEngineEx *iface, UINT32 role) { - FIXME("%p, %u stub.\n", iface, role); + struct media_engine *engine = impl_from_IMFMediaEngineEx(iface); + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %u.\n", iface, role); + + EnterCriticalSection(&engine->cs); + + if (engine->flags & FLAGS_ENGINE_SHUT_DOWN) + hr = MF_E_SHUTDOWN; + else + hr = IMFAttributes_SetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE, role); + + LeaveCriticalSection(&engine->cs); + + return hr; }
static HRESULT WINAPI media_engine_GetRealTimeMode(IMFMediaEngineEx *iface, BOOL *enabled) @@ -2867,6 +2917,12 @@ static HRESULT init_media_engine(DWORD flags, IMFAttributes *attributes, struct if (FAILED(hr = IMFAttributes_CopyAllItems(attributes, engine->attributes))) return hr;
+ /* Set default audio configuration */ + if (FAILED(IMFAttributes_GetItem(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_CATEGORY, NULL))) + IMFAttributes_SetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_CATEGORY, AudioCategory_Other); + if (FAILED(IMFAttributes_GetItem(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE, NULL))) + IMFAttributes_SetUINT32(engine->attributes, &MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE, eMultimedia); + IMFAttributes_GetUINT64(attributes, &MF_MEDIA_ENGINE_PLAYBACK_HWND, &playback_hwnd); hr = IMFAttributes_GetUINT32(attributes, &MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, &output_format); if (playback_hwnd) /* FIXME: handle MF_MEDIA_ENGINE_PLAYBACK_VISUAL */ diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 3368484f58e..8584554a2b6 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -29,6 +29,8 @@ #include "mferror.h" #include "dxgi.h" #include "initguid.h" +#include "mmdeviceapi.h" +#include "audiosessiontypes.h"
#include "wine/heap.h" #include "wine/test.h" @@ -297,6 +299,7 @@ static void test_Shutdown(void) IMFMediaTimeRange *time_range; IMFMediaEngine *media_engine; unsigned int state; + UINT32 value; DWORD cx, cy; double val; HRESULT hr; @@ -448,6 +451,18 @@ todo_wine hr = IMFMediaEngineEx_SetSourceFromByteStream(media_engine_ex, NULL, NULL); ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+ hr = IMFMediaEngineEx_GetAudioStreamCategory(media_engine_ex, &value); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaEngineEx_GetAudioEndpointRole(media_engine_ex, &value); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaEngineEx_SetAudioStreamCategory(media_engine_ex, AudioCategory_ForegroundOnlyMedia); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaEngineEx_SetAudioEndpointRole(media_engine_ex, eConsole); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + IMFMediaEngineEx_Release(media_engine_ex); }
@@ -800,6 +815,34 @@ static void test_SetSourceFromByteStream(void) IMFMediaEngineNotify_Release(¬ify->IMFMediaEngineNotify_iface); }
+static void test_audio_configuration(void) +{ + struct media_engine_notify *notify; + IMFMediaEngineEx *media_engine; + UINT32 value; + HRESULT hr; + + notify = create_callback(); + + media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface); + if (!media_engine) + { + IMFMediaEngineNotify_Release(¬ify->IMFMediaEngineNotify_iface); + return; + } + + hr = IMFMediaEngineEx_GetAudioStreamCategory(media_engine, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(value == AudioCategory_Other, "Unexpected value %u.\n", value); + + hr = IMFMediaEngineEx_GetAudioEndpointRole(media_engine, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(value == eMultimedia, "Unexpected value %u.\n", value); + + IMFMediaEngineEx_Release(media_engine); + IMFMediaEngineNotify_Release(¬ify->IMFMediaEngineNotify_iface); +} + START_TEST(mfmediaengine) { HRESULT hr; @@ -829,6 +872,7 @@ START_TEST(mfmediaengine) test_error(); test_time_range(); test_SetSourceFromByteStream(); + test_audio_configuration();
IMFMediaEngineClassFactory_Release(factory);