Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/tests/mf.c | 9 +++++-- dlls/mf/topology.c | 63 +++++++++++++++++++++++++++++++++++++++++----- include/mfidl.idl | 9 +++++++ 3 files changed, 73 insertions(+), 8 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 7cebb4c555..2a5efc99e8 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -785,8 +785,9 @@ static void test_MFGetService(void) ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n"); }
-static void test_MFCreateSequencerSource(void) +static void test_sequencer_source(void) { + IMFMediaSourceTopologyProvider *provider; IMFSequencerSource *seq_source; HRESULT hr;
@@ -796,6 +797,10 @@ static void test_MFCreateSequencerSource(void) hr = MFCreateSequencerSource(NULL, &seq_source); ok(hr == S_OK, "Failed to create sequencer source, hr %#x.\n", hr);
+ hr = IMFSequencerSource_QueryInterface(seq_source, &IID_IMFMediaSourceTopologyProvider, (void **)&provider); + ok(hr == S_OK, "Failed to get provider interface, hr %#x.\n", hr); + IMFMediaSourceTopologyProvider_Release(provider); + IMFSequencerSource_Release(seq_source);
hr = MFShutdown(); @@ -2455,7 +2460,7 @@ START_TEST(mf) test_topology(); test_topology_loader(); test_MFGetService(); - test_MFCreateSequencerSource(); + test_sequencer_source(); test_media_session(); test_MFShutdownObject(); test_presentation_clock(); diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index 8d928ad3f9..ad89739d4a 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -89,6 +89,7 @@ struct topology_loader struct seq_source { IMFSequencerSource IMFSequencerSource_iface; + IMFMediaSourceTopologyProvider IMFMediaSourceTopologyProvider_iface; LONG refcount; };
@@ -127,6 +128,11 @@ static struct seq_source *impl_from_IMFSequencerSource(IMFSequencerSource *iface return CONTAINING_RECORD(iface, struct seq_source, IMFSequencerSource_iface); }
+static struct seq_source *impl_from_IMFMediaSourceTopologyProvider(IMFMediaSourceTopologyProvider *iface) +{ + return CONTAINING_RECORD(iface, struct seq_source, IMFMediaSourceTopologyProvider_iface); +} + static HRESULT topology_node_reserve_streams(struct node_streams *streams, DWORD index) { if (!mf_array_reserve((void **)&streams->streams, &streams->size, index + 1, sizeof(*streams->streams))) @@ -1875,20 +1881,29 @@ static HRESULT WINAPI seq_source_QueryInterface(IMFSequencerSource *iface, REFII { struct seq_source *seq_source = impl_from_IMFSequencerSource(iface);
- TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), out); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + *out = NULL;
if (IsEqualIID(riid, &IID_IMFSequencerSource) || IsEqualIID(riid, &IID_IUnknown)) { *out = &seq_source->IMFSequencerSource_iface; - IMFSequencerSource_AddRef(iface); - return S_OK; + } + else if (IsEqualIID(riid, &IID_IMFMediaSourceTopologyProvider)) + { + *out = &seq_source->IMFMediaSourceTopologyProvider_iface; + } + else + { + WARN("Unimplemented %s.\n", debugstr_guid(riid)); + return E_NOINTERFACE; }
- WARN("Unimplemented %s.\n", debugstr_guid(riid)); - *out = NULL; + if (*out) + IUnknown_AddRef((IUnknown *)*out);
- return E_NOINTERFACE; + return S_OK; }
static ULONG WINAPI seq_source_AddRef(IMFSequencerSource *iface) @@ -1954,6 +1969,41 @@ static HRESULT WINAPI seq_source_UpdateTopologyFlags(IMFSequencerSource *iface, return E_NOTIMPL; }
+static HRESULT WINAPI seq_source_topology_provider_QueryInterface(IMFMediaSourceTopologyProvider *iface, REFIID riid, + void **obj) +{ + struct seq_source *seq_source = impl_from_IMFMediaSourceTopologyProvider(iface); + return IMFSequencerSource_QueryInterface(&seq_source->IMFSequencerSource_iface, riid, obj); +} + +static ULONG WINAPI seq_source_topology_provider_AddRef(IMFMediaSourceTopologyProvider *iface) +{ + struct seq_source *seq_source = impl_from_IMFMediaSourceTopologyProvider(iface); + return IMFSequencerSource_AddRef(&seq_source->IMFSequencerSource_iface); +} + +static ULONG WINAPI seq_source_topology_provider_Release(IMFMediaSourceTopologyProvider *iface) +{ + struct seq_source *seq_source = impl_from_IMFMediaSourceTopologyProvider(iface); + return IMFSequencerSource_Release(&seq_source->IMFSequencerSource_iface); +} + +static HRESULT WINAPI seq_source_topology_provider_GetMediaSourceTopology(IMFMediaSourceTopologyProvider *iface, + IMFPresentationDescriptor *pd, IMFTopology **topology) +{ + FIXME("%p, %p, %p.\n", iface, pd, topology); + + return E_NOTIMPL; +} + +static const IMFMediaSourceTopologyProviderVtbl seq_source_topology_provider_vtbl = +{ + seq_source_topology_provider_QueryInterface, + seq_source_topology_provider_AddRef, + seq_source_topology_provider_Release, + seq_source_topology_provider_GetMediaSourceTopology, +}; + static const IMFSequencerSourceVtbl seqsourcevtbl = { seq_source_QueryInterface, @@ -1983,6 +2033,7 @@ HRESULT WINAPI MFCreateSequencerSource(IUnknown *reserved, IMFSequencerSource ** return E_OUTOFMEMORY;
object->IMFSequencerSource_iface.lpVtbl = &seqsourcevtbl; + object->IMFMediaSourceTopologyProvider_iface.lpVtbl = &seq_source_topology_provider_vtbl; object->refcount = 1;
*seq_source = &object->IMFSequencerSource_iface; diff --git a/include/mfidl.idl b/include/mfidl.idl index 908c659f1d..df48cb3ab9 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -783,6 +783,15 @@ interface IMFLocalMFTRegistration : IUnknown HRESULT RegisterMFTs([in, size_is(count)] MFT_REGISTRATION_INFO *info, [in] DWORD count); }
+[ + object, + uuid(0e1d6009-c9f3-442d-8c51-a42d2d49452f), +] +interface IMFMediaSourceTopologyProvider : IUnknown +{ + HRESULT GetMediaSourceTopology([in] IMFPresentationDescriptor *pd, [out] IMFTopology **topology); +} + 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")