diff --git a/dlls/mf/mf.spec b/dlls/mf/mf.spec index 6e64404ba63..f13a2451fb6 100644 --- a/dlls/mf/mf.spec +++ b/dlls/mf/mf.spec @@ -58,7 +58,7 @@ @ stub MFCreateSequencerSourceRemoteStream @ stub MFCreateSimpleTypeHandler @ stdcall MFCreateSourceResolver(ptr) mfplat.MFCreateSourceResolver -@ stub MFCreateStandardQualityManager +@ stdcall MFCreateStandardQualityManager(ptr) @ stdcall MFCreateTopoLoader(ptr) @ stdcall MFCreateTopology(ptr) @ stdcall MFCreateTopologyNode(long ptr) diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 1276f2ec929..ecee112c3f8 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -133,6 +133,12 @@ struct presentation_clock CRITICAL_SECTION cs; }; +struct quality_manager +{ + IMFQualityManager IMFQualityManager_iface; + LONG refcount; +}; + static inline struct media_session *impl_from_IMFMediaSession(IMFMediaSession *iface) { return CONTAINING_RECORD(iface, struct media_session, IMFMediaSession_iface); @@ -193,6 +199,11 @@ static struct sink_notification *impl_from_IUnknown(IUnknown *iface) return CONTAINING_RECORD(iface, struct sink_notification, IUnknown_iface); } +static struct quality_manager *impl_from_IMFQualityManager(IMFQualityManager *iface) +{ + return CONTAINING_RECORD(iface, struct quality_manager, IMFQualityManager_iface); +} + static HRESULT WINAPI session_op_QueryInterface(IUnknown *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IUnknown)) @@ -1542,3 +1553,122 @@ HRESULT WINAPI MFCreatePresentationClock(IMFPresentationClock **clock) return S_OK; } + +static HRESULT WINAPI standard_quality_manager_QueryInterface(IMFQualityManager *iface, REFIID riid, void **out) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFQualityManager) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + IMFQualityManager_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI standard_quality_manager_AddRef(IMFQualityManager *iface) +{ + struct quality_manager *manager = impl_from_IMFQualityManager(iface); + ULONG refcount = InterlockedIncrement(&manager->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI standard_quality_manager_Release(IMFQualityManager *iface) +{ + struct quality_manager *manager = impl_from_IMFQualityManager(iface); + ULONG refcount = InterlockedDecrement(&manager->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(manager); + } + + return refcount; +} + +static HRESULT WINAPI standard_quality_manager_NotifyTopology(IMFQualityManager *iface, IMFTopology *topology) +{ + FIXME("%p, %p stub.\n", iface, topology); + + return E_NOTIMPL; +} + +static HRESULT WINAPI standard_quality_manager_NotifyPresentationClock(IMFQualityManager *iface, + IMFPresentationClock *clock) +{ + FIXME("%p, %p stub.\n", iface, clock); + + return E_NOTIMPL; +} + +static HRESULT WINAPI standard_quality_manager_NotifyProcessInput(IMFQualityManager *iface, IMFTopologyNode *node, + LONG input_index, IMFSample *sample) +{ + FIXME("%p, %p, %d, %p stub.\n", iface, node, input_index, sample); + + return E_NOTIMPL; +} + +static HRESULT WINAPI standard_quality_manager_NotifyProcessOutput(IMFQualityManager *iface, IMFTopologyNode *node, + LONG output_index, IMFSample *sample) +{ + FIXME("%p, %p, %d, %p stub.\n", iface, node, output_index, sample); + + return E_NOTIMPL; +} + +static HRESULT WINAPI standard_quality_manager_NotifyQualityEvent(IMFQualityManager *iface, IUnknown *object, + IMFMediaEvent *event) +{ + FIXME("%p, %p, %p stub.\n", iface, object, event); + + return E_NOTIMPL; +} + +static HRESULT WINAPI standard_quality_manager_Shutdown(IMFQualityManager *iface) +{ + FIXME("%p stub.\n", iface); + + return E_NOTIMPL; +} + +static IMFQualityManagerVtbl standard_quality_manager_vtbl = +{ + standard_quality_manager_QueryInterface, + standard_quality_manager_AddRef, + standard_quality_manager_Release, + standard_quality_manager_NotifyTopology, + standard_quality_manager_NotifyPresentationClock, + standard_quality_manager_NotifyProcessInput, + standard_quality_manager_NotifyProcessOutput, + standard_quality_manager_NotifyQualityEvent, + standard_quality_manager_Shutdown, +}; + +HRESULT WINAPI MFCreateStandardQualityManager(IMFQualityManager **manager) +{ + struct quality_manager *object; + + TRACE("%p.\n", manager); + + object = heap_alloc_zero(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->IMFQualityManager_iface.lpVtbl = &standard_quality_manager_vtbl; + object->refcount = 1; + + *manager = &object->IMFQualityManager_iface; + + return S_OK; +} diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 0a8a88d6c35..00dc2daed5c 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2398,6 +2398,17 @@ failed: CoUninitialize(); } +static void test_quality_manager(void) +{ + IMFQualityManager *manager; + HRESULT hr; + + hr = MFCreateStandardQualityManager(&manager); + ok(hr == S_OK, "Failed to create quality manager, hr %#x.\n", hr); + + IMFQualityManager_Release(manager); +} + START_TEST(mf) { test_topology(); @@ -2409,4 +2420,5 @@ START_TEST(mf) test_presentation_clock(); test_sample_grabber(); test_video_processor(); + test_quality_manager(); } diff --git a/include/mfidl.idl b/include/mfidl.idl index f40f16e4804..ab6d0d9984c 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -577,6 +577,7 @@ cpp_quote("HRESULT WINAPI MFCreateSampleGrabberSinkActivate(IMFMediaType *media_ cpp_quote(" IMFSampleGrabberSinkCallback *callback, IMFActivate **activate);") cpp_quote("HRESULT WINAPI MFCreateSequencerSource(IUnknown *reserved, IMFSequencerSource **seq_source);" ) cpp_quote("HRESULT WINAPI MFCreateSourceResolver(IMFSourceResolver **resolver);") +cpp_quote("HRESULT WINAPI MFCreateStandardQualityManager(IMFQualityManager **manager);") cpp_quote("HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD cMediaTypes,") cpp_quote(" IMFMediaType **types, IMFStreamDescriptor **descriptor);") cpp_quote("HRESULT WINAPI MFCreateSystemTimeSource(IMFPresentationTimeSource **time_source);") @@ -738,6 +739,29 @@ interface IMFShutdown : IUnknown HRESULT GetShutdownStatus([out] MFSHUTDOWN_STATUS *status); } +[ + object, + uuid(8d009d86-5b9f-4115-b1fc-9f80d52ab8ab), + local +] +interface IMFQualityManager : IUnknown +{ + HRESULT NotifyTopology([in] IMFTopology *topology); + HRESULT NotifyPresentationClock([in] IMFPresentationClock *clock); + HRESULT NotifyProcessInput( + [in] IMFTopologyNode *node, + [in] LONG input_index, + [in] IMFSample *sample); + HRESULT NotifyProcessOutput( + [in] IMFTopologyNode *node, + [in] LONG output_index, + [in] IMFSample *sample); + HRESULT NotifyQualityEvent( + [in] IUnknown *object, + [in] IMFMediaEvent *event); + HRESULT Shutdown(); +} + cpp_quote("#define MF_RESOLUTION_MEDIASOURCE 0x00000001") cpp_quote("#define MF_RESOLUTION_BYTESTREAM 0x00000002") cpp_quote("#define MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE 0x00000010")