diff --git a/dlls/mf/mf.spec b/dlls/mf/mf.spec index e3563102391..b2e0b9bea61 100644 --- a/dlls/mf/mf.spec +++ b/dlls/mf/mf.spec @@ -54,7 +54,7 @@ @ stub MFCreateSampleGrabberSinkActivate @ stub MFCreateSecureHttpSchemePlugin @ stub MFCreateSequencerSegmentOffset -@ stub MFCreateSequencerSource +@ stdcall MFCreateSequencerSource(ptr ptr) @ stub MFCreateSequencerSourceRemoteStream @ stub MFCreateSimpleTypeHandler @ stdcall MFCreateSourceResolver(ptr) mfplat.MFCreateSourceResolver diff --git a/dlls/mf/tests/Makefile.in b/dlls/mf/tests/Makefile.in index f989baa2300..f233cff3fc6 100644 --- a/dlls/mf/tests/Makefile.in +++ b/dlls/mf/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = mf.dll -IMPORTS = mf +IMPORTS = mf mfplat C_SRCS = \ mf.c diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index acbba2ca68a..6e77f6b77c3 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -27,6 +27,7 @@ #include "winbase.h" #include "initguid.h" +#include "mfapi.h" #include "mfidl.h" #include "wine/test.h" @@ -178,8 +179,26 @@ static void test_MFGetService(void) ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n"); } +static void test_MFCreateSequencerSource(void) +{ + IMFSequencerSource *seq_source; + HRESULT hr; + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Startup failure, hr %#x.\n", hr); + + hr = MFCreateSequencerSource(NULL, &seq_source); + ok(hr == S_OK, "Failed to create sequencer source, hr %#x.\n", hr); + + IMFSequencerSource_Release(seq_source); + + hr = MFShutdown(); + ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr); +} + START_TEST(mf) { test_topology(); test_MFGetService(); + test_MFCreateSequencerSource(); } diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index 6d7c9f3a58a..308a1e3ce96 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -47,6 +47,12 @@ struct topology_node MF_TOPOLOGY_TYPE node_type; }; +struct seq_source +{ + IMFSequencerSource IMFSequencerSource_iface; + LONG refcount; +}; + static inline struct topology *impl_from_IMFTopology(IMFTopology *iface) { return CONTAINING_RECORD(iface, struct topology, IMFTopology_iface); @@ -57,6 +63,11 @@ static struct topology_node *impl_from_IMFTopologyNode(IMFTopologyNode *iface) return CONTAINING_RECORD(iface, struct topology_node, IMFTopologyNode_iface); } +static struct seq_source *impl_from_IMFSequencerSource(IMFSequencerSource *iface) +{ + return CONTAINING_RECORD(iface, struct seq_source, IMFSequencerSource_iface); +} + static HRESULT WINAPI topology_QueryInterface(IMFTopology *iface, REFIID riid, void **out) { struct topology *topology = impl_from_IMFTopology(iface); @@ -1052,3 +1063,122 @@ HRESULT WINAPI MFCreateTopologyNode(MF_TOPOLOGY_TYPE node_type, IMFTopologyNode return S_OK; } + +static HRESULT WINAPI seq_source_QueryInterface(IMFSequencerSource *iface, REFIID riid, void **out) +{ + struct seq_source *seq_source = impl_from_IMFSequencerSource(iface); + + TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFSequencerSource) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = &seq_source->IMFSequencerSource_iface; + IMFSequencerSource_AddRef(iface); + return S_OK; + } + + WARN("Unimplemented %s.\n", debugstr_guid(riid)); + *out = NULL; + + return E_NOINTERFACE; +} + +static ULONG WINAPI seq_source_AddRef(IMFSequencerSource *iface) +{ + struct seq_source *seq_source = impl_from_IMFSequencerSource(iface); + ULONG refcount = InterlockedIncrement(&seq_source->refcount); + + TRACE("(%p) refcount=%u\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI seq_source_Release(IMFSequencerSource *iface) +{ + struct seq_source *seq_source = impl_from_IMFSequencerSource(iface); + ULONG refcount = InterlockedDecrement(&seq_source->refcount); + + TRACE("(%p) refcount=%u\n", iface, refcount); + + if (!refcount) + { + heap_free(seq_source); + } + + return refcount; +} + +static HRESULT WINAPI seq_source_AppendTopology(IMFSequencerSource *iface, IMFTopology *topology, + DWORD flags, MFSequencerElementId *id) +{ + FIXME("%p, %p, %x, %p\n", iface, topology, flags, id); + + return E_NOTIMPL; +} + +static HRESULT WINAPI seq_source_DeleteTopology(IMFSequencerSource *iface, MFSequencerElementId id) +{ + FIXME("%p, %#x\n", iface, id); + + return E_NOTIMPL; +} + +static HRESULT WINAPI seq_source_GetPresentationContext(IMFSequencerSource *iface, + IMFPresentationDescriptor *descriptor, MFSequencerElementId *id, IMFTopology **topology) +{ + FIXME("%p, %p, %p, %p\n", iface, descriptor, id, topology); + + return E_NOTIMPL; +} + +static HRESULT WINAPI seq_source_UpdateTopology(IMFSequencerSource *iface, MFSequencerElementId id, + IMFTopology *topology) +{ + FIXME("%p, %#x, %p\n", iface, id, topology); + + return E_NOTIMPL; +} + +static HRESULT WINAPI seq_source_UpdateTopologyFlags(IMFSequencerSource *iface, MFSequencerElementId id, DWORD flags) +{ + FIXME("%p, %#x, %#x\n", iface, id, flags); + + return E_NOTIMPL; +} + +static const IMFSequencerSourceVtbl seqsourcevtbl = +{ + seq_source_QueryInterface, + seq_source_AddRef, + seq_source_Release, + seq_source_AppendTopology, + seq_source_DeleteTopology, + seq_source_GetPresentationContext, + seq_source_UpdateTopology, + seq_source_UpdateTopologyFlags, +}; + +/*********************************************************************** + * MFCreateSequencerSource (mf.@) + */ +HRESULT WINAPI MFCreateSequencerSource(IUnknown *reserved, IMFSequencerSource **seq_source) +{ + struct seq_source *object; + + TRACE("(%p, %p)\n", reserved, seq_source); + + if (!seq_source) + return E_POINTER; + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->IMFSequencerSource_iface.lpVtbl = &seqsourcevtbl; + object->refcount = 1; + + *seq_source = &object->IMFSequencerSource_iface; + + return S_OK; +} diff --git a/include/mfidl.idl b/include/mfidl.idl index 2670c36c611..82a87bab36b 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -307,6 +307,7 @@ interface IMFSequencerSource : IUnknown cpp_quote("HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **session);") cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **bytestream);" ) +cpp_quote("HRESULT WINAPI MFCreateSequencerSource(IUnknown *reserved, IMFSequencerSource **seq_source);" ) cpp_quote("HRESULT WINAPI MFCreateSourceResolver(IMFSourceResolver **resolver);") cpp_quote("HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD cMediaTypes,") cpp_quote(" IMFMediaType **types, IMFStreamDescriptor **descriptor);")