From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/mfmediaengine/tests/mfmediaengine.c | 104 +++++++++++++---------- 1 file changed, 57 insertions(+), 47 deletions(-)
diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 318684dc4f9..08caa73f8e8 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -267,7 +267,8 @@ static ID3D11Device *create_d3d11_device(void) return NULL; }
-static IMFMediaEngine *create_media_engine(IMFMediaEngineNotify *callback, IMFDXGIDeviceManager *manager, UINT32 output_format) +static HRESULT create_media_engine(IMFMediaEngineNotify *callback, IMFDXGIDeviceManager *manager, UINT32 output_format, + REFIID riid, void **obj) { IMFMediaEngine *media_engine; IMFAttributes *attributes; @@ -292,21 +293,10 @@ static IMFMediaEngine *create_media_engine(IMFMediaEngineNotify *callback, IMFDX
IMFAttributes_Release(attributes);
- return media_engine; -} - -static IMFMediaEngineEx *create_media_engine_ex(IMFMediaEngineNotify *callback, IMFDXGIDeviceManager *manager, UINT32 output_format) -{ - IMFMediaEngine *engine = create_media_engine(callback, manager, output_format); - IMFMediaEngineEx *engine_ex = NULL; - - if (engine) - { - IMFMediaEngine_QueryInterface(engine, &IID_IMFMediaEngineEx, (void **)&engine_ex); - IMFMediaEngine_Release(engine); - } + hr = IMFMediaEngine_QueryInterface(media_engine, riid, obj); + IMFMediaEngine_Release(media_engine);
- return engine_ex; + return hr; }
static void test_factory(void) @@ -460,7 +450,9 @@ static void test_Shutdown(void)
notify = create_callback();
- media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN); + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN, + &IID_IMFMediaEngine, (void **)&media_engine); + ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
hr = IMFMediaEngine_Shutdown(media_engine); ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr); @@ -647,7 +639,9 @@ static void test_Play(void)
notify = create_callback();
- media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN); + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN, + &IID_IMFMediaEngine, (void **)&media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaEngine_GetBuffered(media_engine, &range); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -696,7 +690,9 @@ static void test_Play(void) IMFMediaEngine_Release(media_engine);
/* Play -> Pause */ - media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN); + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN, + &IID_IMFMediaEngine, (void **)&media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaEngine_Play(media_engine); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -723,7 +719,9 @@ static void test_playback_rate(void)
notify = create_callback();
- media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN); + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN, + &IID_IMFMediaEngine, (void **)&media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
rate = IMFMediaEngine_GetDefaultPlaybackRate(media_engine); ok(rate == 1.0, "Unexpected default rate.\n"); @@ -753,7 +751,9 @@ static void test_mute(void)
notify = create_callback();
- media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN); + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN, + &IID_IMFMediaEngine, (void **)&media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ret = IMFMediaEngine_GetMuted(media_engine); ok(!ret, "Unexpected state.\n"); @@ -784,7 +784,9 @@ static void test_error(void)
notify = create_callback();
- media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN); + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN, + &IID_IMFMediaEngine, (void **)&media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
eo = (void *)0xdeadbeef; hr = IMFMediaEngine_GetError(media_engine, &eo); @@ -1046,8 +1048,9 @@ static void test_SetSourceFromByteStream(void)
notify = create_callback();
- media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN); - if (!media_engine) + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN, + &IID_IMFMediaEngineEx, (void **)&media_engine); + if (FAILED(hr)) { win_skip("IMFMediaEngineEx is not supported.\n"); IMFMediaEngineNotify_Release(¬ify->IMFMediaEngineNotify_iface); @@ -1090,8 +1093,9 @@ static void test_audio_configuration(void)
notify = create_callback();
- media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN); - if (!media_engine) + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN, + &IID_IMFMediaEngineEx, (void **)&media_engine); + if (FAILED(hr)) { IMFMediaEngineNotify_Release(¬ify->IMFMediaEngineNotify_iface); return; @@ -1284,7 +1288,8 @@ static void test_TransferVideoFrame(void) hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface, manager, DXGI_FORMAT_B8G8R8X8_UNORM); + create_media_engine(¬ify->IMFMediaEngineNotify_iface, manager, DXGI_FORMAT_B8G8R8X8_UNORM, + &IID_IMFMediaEngineEx, (void **)&media_engine);
IMFDXGIDeviceManager_Release(manager);
@@ -1787,8 +1792,8 @@ HRESULT passthrough_mft_create(UINT32 index, struct passthrough_mft **out) static void test_effect(void) { struct passthrough_mft *video_effect = NULL, *video_effect2 = NULL, *audio_effect = NULL, *audio_effect2 = NULL; + IMFMediaEngineEx *media_engine = NULL; struct test_transfer_notify *notify; - IMFMediaEngineEx *media_engine_ex = NULL; ID3D11Texture2D *texture = NULL; IMFDXGIDeviceManager *manager; ID3D11Device *device = NULL; @@ -1816,12 +1821,12 @@ static void test_effect(void) hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- media_engine_ex = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface, - manager, DXGI_FORMAT_B8G8R8X8_UNORM); + create_media_engine(¬ify->IMFMediaEngineNotify_iface, manager, DXGI_FORMAT_B8G8R8X8_UNORM, + &IID_IMFMediaEngineEx, (void **)&media_engine);
IMFDXGIDeviceManager_Release(manager);
- if (!(notify->media_engine = media_engine_ex)) + if (!(notify->media_engine = media_engine)) goto done;
memset(&desc, 0, sizeof(desc)); @@ -1834,7 +1839,7 @@ static void test_effect(void) hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFMediaEngineEx_RemoveAllEffects(media_engine_ex); + hr = IMFMediaEngineEx_RemoveAllEffects(media_engine); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = passthrough_mft_create(0, &video_effect); @@ -1843,24 +1848,24 @@ static void test_effect(void) hr = passthrough_mft_create(1, &video_effect2); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFMediaEngineEx_InsertVideoEffect(media_engine_ex, (IUnknown *)&video_effect->IMFTransform_iface, FALSE); + hr = IMFMediaEngineEx_InsertVideoEffect(media_engine, (IUnknown *)&video_effect->IMFTransform_iface, FALSE); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); EXPECT_REF(&video_effect->IMFTransform_iface, 2);
- hr = IMFMediaEngineEx_InsertVideoEffect(media_engine_ex, (IUnknown *)&video_effect2->IMFTransform_iface, FALSE); + hr = IMFMediaEngineEx_InsertVideoEffect(media_engine, (IUnknown *)&video_effect2->IMFTransform_iface, FALSE); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); EXPECT_REF(&video_effect2->IMFTransform_iface, 2);
- hr = IMFMediaEngineEx_RemoveAllEffects(media_engine_ex); + hr = IMFMediaEngineEx_RemoveAllEffects(media_engine); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); EXPECT_REF(&video_effect->IMFTransform_iface, 1); EXPECT_REF(&video_effect2->IMFTransform_iface, 1);
- hr = IMFMediaEngineEx_InsertVideoEffect(media_engine_ex, (IUnknown *)&video_effect->IMFTransform_iface, FALSE); + hr = IMFMediaEngineEx_InsertVideoEffect(media_engine, (IUnknown *)&video_effect->IMFTransform_iface, FALSE); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); EXPECT_REF(&video_effect->IMFTransform_iface, 2);
- hr = IMFMediaEngineEx_InsertVideoEffect(media_engine_ex, (IUnknown *)&video_effect2->IMFTransform_iface, FALSE); + hr = IMFMediaEngineEx_InsertVideoEffect(media_engine, (IUnknown *)&video_effect2->IMFTransform_iface, FALSE); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); EXPECT_REF(&video_effect2->IMFTransform_iface, 2);
@@ -1870,16 +1875,16 @@ static void test_effect(void) hr = passthrough_mft_create(1, &audio_effect2); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFMediaEngineEx_InsertAudioEffect(media_engine_ex, (IUnknown *)&audio_effect->IMFTransform_iface, FALSE); + hr = IMFMediaEngineEx_InsertAudioEffect(media_engine, (IUnknown *)&audio_effect->IMFTransform_iface, FALSE); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); EXPECT_REF(&audio_effect->IMFTransform_iface, 2);
- hr = IMFMediaEngineEx_InsertAudioEffect(media_engine_ex, (IUnknown *)&audio_effect2->IMFTransform_iface, FALSE); + hr = IMFMediaEngineEx_InsertAudioEffect(media_engine, (IUnknown *)&audio_effect2->IMFTransform_iface, FALSE); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); EXPECT_REF(&audio_effect2->IMFTransform_iface, 2);
url = SysAllocString(L"i420-64x64.avi"); - hr = IMFMediaEngineEx_SetSourceFromByteStream(media_engine_ex, stream, url); + hr = IMFMediaEngineEx_SetSourceFromByteStream(media_engine, stream, url); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); SysFreeString(url); IMFByteStream_Release(stream); @@ -1909,14 +1914,14 @@ static void test_effect(void) }
done: - if (media_engine_ex) + if (media_engine) { - IMFMediaEngineEx_Shutdown(media_engine_ex); + IMFMediaEngineEx_Shutdown(media_engine);
- hr = IMFMediaEngineEx_RemoveAllEffects(media_engine_ex); + hr = IMFMediaEngineEx_RemoveAllEffects(media_engine); ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
- IMFMediaEngineEx_Release(media_engine_ex); + IMFMediaEngineEx_Release(media_engine); }
if (texture) @@ -1949,9 +1954,10 @@ static void test_GetDuration(void) BSTR url;
notify = create_transfer_notify(); - media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_B8G8R8X8_UNORM); + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_B8G8R8X8_UNORM, + &IID_IMFMediaEngineEx, (void **)&media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); notify->media_engine = media_engine; - ok(!!media_engine, "create_media_engine_ex failed.\n");
stream = load_resource(L"i420-64x64.avi", L"video/avi"); url = SysAllocString(L"i420-64x64.avi"); @@ -2275,7 +2281,9 @@ static void test_GetSeekable(void) BSTR url;
notify = create_seek_notify(); - media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_B8G8R8X8_UNORM); + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_B8G8R8X8_UNORM, + &IID_IMFMediaEngineEx, (void **)&media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IMFMediaEngineNotify_Release(¬ify->IMFMediaEngineNotify_iface);
stream = load_resource(L"i420-64x64.avi", L"video/avi"); @@ -2332,7 +2340,9 @@ static void test_GetSeekable(void)
/* Unseekable bytestreams */ notify = create_seek_notify(); - media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_B8G8R8X8_UNORM); + hr = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_B8G8R8X8_UNORM, + &IID_IMFMediaEngineEx, (void **)&media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IMFMediaEngineNotify_Release(¬ify->IMFMediaEngineNotify_iface); unseekable_stream = create_unseekable_stream(stream); hr = IMFMediaEngineEx_SetSourceFromByteStream(media_engine, unseekable_stream, url);
From: Nikolay Sivov nsivov@codeweavers.com
--- include/mfmediaengine.idl | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/include/mfmediaengine.idl b/include/mfmediaengine.idl index aaf3bb55e4d..f73b9d78914 100644 --- a/include/mfmediaengine.idl +++ b/include/mfmediaengine.idl @@ -353,3 +353,15 @@ interface IMFMediaEngineNotify : IUnknown { HRESULT EventNotify([in] DWORD event, [in] DWORD_PTR param1, [in] DWORD param2); } + +[ + object, + uuid(7a3bac98-0e76-49fb-8c20-8a86fd98eaf2), + local, + pointer_default(unique) +] +interface IMFMediaEngineAudioEndpointId : IUnknown +{ + HRESULT SetAudioEndpointId([in] LPCWSTR id); + HRESULT GetAudioEndpointId([out] LPWSTR *id); +}
From: Nikolay Sivov nsivov@codeweavers.com
--- dlls/mfmediaengine/main.c | 12 ++++++++++-- dlls/mfmediaengine/tests/mfmediaengine.c | 1 - 2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index b0c67f031a9..5a63974967d 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -1705,17 +1705,25 @@ static HRESULT WINAPI media_engine_Load(IMFMediaEngineEx *iface) return hr; }
-static HRESULT WINAPI media_engine_CanPlayType(IMFMediaEngineEx *iface, BSTR type, MF_MEDIA_ENGINE_CANPLAY *answer) +static HRESULT WINAPI media_engine_CanPlayType(IMFMediaEngineEx *iface, BSTR mime_type, MF_MEDIA_ENGINE_CANPLAY *answer) { struct media_engine *engine = impl_from_IMFMediaEngineEx(iface); HRESULT hr = E_NOTIMPL;
- FIXME("(%p, %s, %p): stub.\n", iface, debugstr_w(type), answer); + TRACE("%p, %s, %p.\n", iface, debugstr_w(mime_type), answer);
EnterCriticalSection(&engine->cs);
if (engine->flags & FLAGS_ENGINE_SHUT_DOWN) hr = MF_E_SHUTDOWN; + else + { + FIXME("Check builtin supported types.\n"); + + if (engine->extension) + hr = IMFMediaEngineExtension_CanPlayType(engine->extension, !!(engine->flags & MF_MEDIA_ENGINE_AUDIOONLY), + mime_type, answer); + }
LeaveCriticalSection(&engine->cs);
diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index d236d2b4bb8..66a1f0b79e9 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -2495,7 +2495,6 @@ static void test_media_extension(void)
mime = SysAllocString(L"doesnotexist"); hr = IMFMediaEngine_CanPlayType(media_engine, mime, &answer); - todo_wine ok(hr == 0x80001234, "Unexpected hr %#lx.\n", hr); SysFreeString(mime);
From: Nikolay Sivov nsivov@codeweavers.com
--- 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); +}