Module: wine Branch: master Commit: b5d43949139ea89e708fd5e3ec9f937b72febec1 URL: https://gitlab.winehq.org/wine/wine/-/commit/b5d43949139ea89e708fd5e3ec9f937...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Fri Oct 13 11:30:04 2023 +0200
mfmediaengine: Keep engine extension pointer.
---
dlls/mfmediaengine/main.c | 17 +++- dlls/mfmediaengine/tests/mfmediaengine.c | 133 +++++++++++++++++++++++++++++++ include/mfmediaengine.idl | 15 ++++ 3 files changed, 162 insertions(+), 3 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index 1395eb9bffc..b0c67f031a9 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -158,6 +158,7 @@ struct media_engine IMFMediaSession *session; IMFPresentationClock *clock; IMFSourceResolver *resolver; + IMFMediaEngineExtension *extension; BSTR current_source; struct { @@ -1460,6 +1461,8 @@ static void free_media_engine(struct media_engine *engine) IMFAttributes_Release(engine->attributes); if (engine->resolver) IMFSourceResolver_Release(engine->resolver); + if (engine->extension) + IMFMediaEngineExtension_Release(engine->extension); media_engine_clear_effects(&engine->audio_effects); media_engine_clear_effects(&engine->video_effects); media_engine_release_video_frame_resources(engine); @@ -1559,6 +1562,9 @@ static HRESULT media_engine_set_source(struct media_engine *engine, IMFByteStrea
if (url || bytestream) { + if (engine->extension) + FIXME("Use extension to load from.\n"); + flags = MF_RESOLUTION_MEDIASOURCE | MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE; if (engine->flags & MF_MEDIA_ENGINE_DISABLE_LOCAL_PLUGINS) flags |= MF_RESOLUTION_DISABLE_LOCAL_PLUGINS; @@ -3246,10 +3252,15 @@ static HRESULT init_media_engine(DWORD flags, IMFAttributes *attributes, struct engine->video_frame.pts = MINLONGLONG; InitializeCriticalSection(&engine->cs);
- hr = IMFAttributes_GetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, &IID_IMFMediaEngineNotify, - (void **)&engine->callback); - if (FAILED(hr)) + if (FAILED(hr = IMFAttributes_GetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, &IID_IMFMediaEngineNotify, + (void **)&engine->callback))) + { + WARN("Notification callback was not provided.\n"); return hr; + } + + IMFAttributes_GetUnknown(attributes, &MF_MEDIA_ENGINE_EXTENSION, &IID_IMFMediaEngineExtension, + (void **)&engine->extension);
IMFAttributes_GetUnknown(attributes, &MF_MEDIA_ENGINE_DXGI_MANAGER, &IID_IMFDXGIDeviceManager, (void **)&engine->device_manager); diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 08caa73f8e8..d236d2b4bb8 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -2373,6 +2373,138 @@ done: IMFByteStream_Release(stream); }
+struct test_extension +{ + IMFMediaEngineExtension IMFMediaEngineExtension_iface; + LONG refcount; +}; + +static struct test_extension *impl_from_IMFMediaEngineExtension(IMFMediaEngineExtension *iface) +{ + return CONTAINING_RECORD(iface, struct test_extension, IMFMediaEngineExtension_iface); +} + +static HRESULT WINAPI test_extension_QI(IMFMediaEngineExtension *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IMFMediaEngineExtension) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFMediaEngineExtension_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI test_extension_AddRef(IMFMediaEngineExtension *iface) +{ + struct test_extension *extension = impl_from_IMFMediaEngineExtension(iface); + return InterlockedIncrement(&extension->refcount); +} + +static ULONG WINAPI test_extension_Release(IMFMediaEngineExtension *iface) +{ + struct test_extension *extension = impl_from_IMFMediaEngineExtension(iface); + ULONG refcount = InterlockedDecrement(&extension->refcount); + + if (!refcount) + free(extension); + + return refcount; +} + +static HRESULT WINAPI test_extension_CanPlayType(IMFMediaEngineExtension *iface, + BOOL audio_only, BSTR mime_type, MF_MEDIA_ENGINE_CANPLAY *answer) +{ + return 0x80001234; +} + +static HRESULT WINAPI test_extension_BeginCreateObject(IMFMediaEngineExtension *iface, + BSTR url, IMFByteStream *bytestream, MF_OBJECT_TYPE type, IUnknown **cancel_cookie, + IMFAsyncCallback *callback, IUnknown *state) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI test_extension_CancelObjectCreation(IMFMediaEngineExtension *iface, + IUnknown *cancel_cookie) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI test_extension_EndCreateObject(IMFMediaEngineExtension *iface, IMFAsyncResult *result, + IUnknown **object) +{ + return E_NOTIMPL; +} + +static const IMFMediaEngineExtensionVtbl test_extension_vtbl = +{ + test_extension_QI, + test_extension_AddRef, + test_extension_Release, + test_extension_CanPlayType, + test_extension_BeginCreateObject, + test_extension_CancelObjectCreation, + test_extension_EndCreateObject, +}; + +static struct test_extension *create_extension(void) +{ + struct test_extension *object; + + object = calloc(1, sizeof(*object)); + + object->IMFMediaEngineExtension_iface.lpVtbl = &test_extension_vtbl; + object->refcount = 1; + + return object; +} + +static void test_media_extension(void) +{ + struct media_engine_notify *notify; + struct test_extension *extension; + MF_MEDIA_ENGINE_CANPLAY answer; + IMFMediaEngine *media_engine; + IMFAttributes *attributes; + HRESULT hr; + BSTR mime; + + notify = create_callback(); + + hr = MFCreateAttributes(&attributes, 3); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + extension = create_extension(); + ok(!!extension, "Failed to create an extension.\n"); + + hr = IMFAttributes_SetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, (IUnknown *)¬ify->IMFMediaEngineNotify_iface); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_SetUINT32(attributes, &MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, DXGI_FORMAT_UNKNOWN); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_SetUnknown(attributes, &MF_MEDIA_ENGINE_EXTENSION, (IUnknown *)&extension->IMFMediaEngineExtension_iface); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaEngineClassFactory_CreateInstance(factory, MF_MEDIA_ENGINE_AUDIOONLY, attributes, &media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFAttributes_Release(attributes); + + mime = SysAllocString(L"doesnotexist"); + hr = IMFMediaEngine_CanPlayType(media_engine, mime, &answer); + todo_wine + ok(hr == 0x80001234, "Unexpected hr %#lx.\n", hr); + SysFreeString(mime); + + IMFMediaEngine_Release(media_engine); + + IMFMediaEngineNotify_Release(¬ify->IMFMediaEngineNotify_iface); + IMFMediaEngineExtension_Release(&extension->IMFMediaEngineExtension_iface); +} + START_TEST(mfmediaengine) { HRESULT hr; @@ -2407,6 +2539,7 @@ START_TEST(mfmediaengine) test_effect(); test_GetDuration(); test_GetSeekable(); + test_media_extension();
IMFMediaEngineClassFactory_Release(factory);
diff --git a/include/mfmediaengine.idl b/include/mfmediaengine.idl index f73b9d78914..6547ef87462 100644 --- a/include/mfmediaengine.idl +++ b/include/mfmediaengine.idl @@ -365,3 +365,18 @@ interface IMFMediaEngineAudioEndpointId : IUnknown HRESULT SetAudioEndpointId([in] LPCWSTR id); HRESULT GetAudioEndpointId([out] LPWSTR *id); } + +[ + object, + uuid(2f69d622-20b5-41e9-afdf-89ced1dda04e), + local, + pointer_default(unique) +] +interface IMFMediaEngineExtension : IUnknown +{ + HRESULT CanPlayType([in] BOOL audio_only, [in] BSTR mime_type, [out] MF_MEDIA_ENGINE_CANPLAY *answer); + HRESULT BeginCreateObject([in] BSTR url, [in] IMFByteStream *bytestream, [in] MF_OBJECT_TYPE type, + [out] IUnknown **cancel_cookie, [in] IMFAsyncCallback *callback, [in] IUnknown *state); + HRESULT CancelObjectCreation([in] IUnknown *cancel_cookie); + HRESULT EndCreateObject([in] IMFAsyncResult *result, [out] IUnknown **object); +}