diff --git a/dlls/mf/mf.spec b/dlls/mf/mf.spec index b2e0b9bea61..64f0b1db83e 100644 --- a/dlls/mf/mf.spec +++ b/dlls/mf/mf.spec @@ -59,7 +59,7 @@ @ stub MFCreateSimpleTypeHandler @ stdcall MFCreateSourceResolver(ptr) mfplat.MFCreateSourceResolver @ stub MFCreateStandardQualityManager -@ stub MFCreateTopoLoader +@ stdcall MFCreateTopoLoader(ptr) @ stdcall MFCreateTopology(ptr) @ stdcall MFCreateTopologyNode(long ptr) @ stub MFCreateTranscodeProfile diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 150314933d3..91ddd60842e 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -469,9 +469,24 @@ static void test_media_session(void) ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr); } +static void test_topology_loader(void) +{ + IMFTopoLoader *loader; + HRESULT hr; + + hr = MFCreateTopoLoader(NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = MFCreateTopoLoader(&loader); + ok(hr == S_OK, "Failed to create topology loader, hr %#x.\n", hr); + + IMFTopoLoader_Release(loader); +} + START_TEST(mf) { test_topology(); + test_topology_loader(); test_MFGetService(); test_MFCreateSequencerSource(); test_media_session(); diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index 3b4a2e1a58c..84387ae0ccf 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -52,6 +52,12 @@ struct topology_node TOPOID id; }; +struct topology_loader +{ + IMFTopoLoader IMFTopoLoader_iface; + LONG refcount; +}; + struct seq_source { IMFSequencerSource IMFSequencerSource_iface; @@ -68,6 +74,11 @@ static struct topology_node *impl_from_IMFTopologyNode(IMFTopologyNode *iface) return CONTAINING_RECORD(iface, struct topology_node, IMFTopologyNode_iface); } +static struct topology_loader *impl_from_IMFTopoLoader(IMFTopoLoader *iface) +{ + return CONTAINING_RECORD(iface, struct topology_loader, IMFTopoLoader_iface); +} + static struct seq_source *impl_from_IMFSequencerSource(IMFSequencerSource *iface) { return CONTAINING_RECORD(iface, struct seq_source, IMFSequencerSource_iface); @@ -1212,6 +1223,88 @@ HRESULT WINAPI MFCreateTopologyNode(MF_TOPOLOGY_TYPE node_type, IMFTopologyNode return S_OK; } +static HRESULT WINAPI topology_loader_QueryInterface(IMFTopoLoader *iface, REFIID riid, void **out) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFTopoLoader) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + IMFTopoLoader_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI topology_loader_AddRef(IMFTopoLoader *iface) +{ + struct topology_loader *loader = impl_from_IMFTopoLoader(iface); + ULONG refcount = InterlockedIncrement(&loader->refcount); + + TRACE("(%p) refcount=%u\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface) +{ + struct topology_loader *loader = impl_from_IMFTopoLoader(iface); + ULONG refcount = InterlockedDecrement(&loader->refcount); + + TRACE("(%p) refcount=%u\n", iface, refcount); + + if (!refcount) + { + heap_free(loader); + } + + return refcount; +} + +static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *input_topology, + IMFTopology **output_topology, IMFTopology *current_topology) +{ + FIXME("%p, %p, %p, %p.\n", iface, input_topology, output_topology, current_topology); + + return E_NOTIMPL; +} + +static const IMFTopoLoaderVtbl topologyloadervtbl = +{ + topology_loader_QueryInterface, + topology_loader_AddRef, + topology_loader_Release, + topology_loader_Load, +}; + +/*********************************************************************** + * MFCreateTopoLoader (mf.@) + */ +HRESULT WINAPI MFCreateTopoLoader(IMFTopoLoader **loader) +{ + struct topology_loader *object; + + TRACE("%p.\n", loader); + + if (!loader) + return E_POINTER; + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->IMFTopoLoader_iface.lpVtbl = &topologyloadervtbl; + object->refcount = 1; + + *loader = &object->IMFTopoLoader_iface; + + return S_OK; +} + static HRESULT WINAPI seq_source_QueryInterface(IMFSequencerSource *iface, REFIID riid, void **out) { struct seq_source *seq_source = impl_from_IMFSequencerSource(iface); diff --git a/include/mfidl.idl b/include/mfidl.idl index 82a87bab36b..831bc357df1 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -116,6 +116,17 @@ interface IMFTopology : IMFAttributes HRESULT GetOutputNodeCollection([out] IMFCollection **collection); } +[ + object, + uuid(de9a6157-f660-4643-b56a-df9f7998c7cd), + local, +] +interface IMFTopoLoader : IUnknown +{ + HRESULT Load([in] IMFTopology *input_topology, [out] IMFTopology **output_topology, + [in] IMFTopology *current_topology); +} + [ object, uuid(90377834-21d0-4dee-8214-ba2e3e6c1127), @@ -313,6 +324,7 @@ cpp_quote("HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD cMedi cpp_quote(" IMFMediaType **types, IMFStreamDescriptor **descriptor);") cpp_quote("HRESULT WINAPI MFCreateTopology(IMFTopology **topology);") cpp_quote("HRESULT WINAPI MFCreateTopologyNode(MF_TOPOLOGY_TYPE node_type, IMFTopologyNode **node);") +cpp_quote("HRESULT WINAPI MFCreateTopoLoader(IMFTopoLoader **loader);") cpp_quote("HRESULT WINAPI MFGetSupportedMimeTypes(PROPVARIANT *array);") cpp_quote("HRESULT WINAPI MFGetService(IUnknown *object, REFGUID service, REFIID iid, void **obj);") cpp_quote("MFTIME WINAPI MFGetSystemTime(void);")