Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 60 +++++++++++++++++++++++++++++++++++++++++----- dlls/mf/tests/mf.c | 7 ++++++ include/mfidl.idl | 22 +++++++++++++++++ 3 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index a3c0ee717f..5ed29c8525 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -265,6 +265,52 @@ static struct quality_manager *impl_from_IMFQualityManager(IMFQualityManager *if return CONTAINING_RECORD(iface, struct quality_manager, IMFQualityManager_iface); }
+/* IMFLocalMFTRegistration */ +static HRESULT WINAPI local_mft_registration_QueryInterface(IMFLocalMFTRegistration *iface, REFIID riid, void **obj) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IMFLocalMFTRegistration) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFLocalMFTRegistration_AddRef(iface); + return S_OK; + } + + WARN("Unexpected %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI local_mft_registration_AddRef(IMFLocalMFTRegistration *iface) +{ + return 2; +} + +static ULONG WINAPI local_mft_registration_Release(IMFLocalMFTRegistration *iface) +{ + return 1; +} + +static HRESULT WINAPI local_mft_registration_RegisterMFTs(IMFLocalMFTRegistration *iface, MFT_REGISTRATION_INFO *info, + DWORD count) +{ + FIXME("%p, %p, %u.\n", iface, info, count); + + return E_NOTIMPL; +} + +static const IMFLocalMFTRegistrationVtbl local_mft_registration_vtbl = +{ + local_mft_registration_QueryInterface, + local_mft_registration_AddRef, + local_mft_registration_Release, + local_mft_registration_RegisterMFTs, +}; + +static IMFLocalMFTRegistration local_mft_registration = { &local_mft_registration_vtbl }; + static HRESULT WINAPI session_op_QueryInterface(IUnknown *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IUnknown)) @@ -915,16 +961,18 @@ static HRESULT WINAPI session_get_service_GetService(IMFGetService *iface, REFGU { *obj = &session->IMFRateControl_iface; } - - if (*obj) - IUnknown_AddRef((IUnknown *)*obj); - - return *obj ? S_OK : E_NOINTERFACE; + } + else if (IsEqualGUID(service, &MF_LOCAL_MFT_REGISTRATION_SERVICE)) + { + return IMFLocalMFTRegistration_QueryInterface(&local_mft_registration, riid, obj); } else FIXME("Unsupported service %s.\n", debugstr_guid(service));
- return E_NOTIMPL; + if (*obj) + IUnknown_AddRef((IUnknown *)*obj); + + return *obj ? S_OK : E_NOINTERFACE; }
static const IMFGetServiceVtbl session_get_service_vtbl = diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index e118c36ec7..7cebb4c555 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -952,6 +952,7 @@ static void test_session_events(IMFMediaSession *session) static void test_media_session(void) { IMFRateControl *rate_control, *rate_control2; + IMFLocalMFTRegistration *local_reg; MFCLOCK_PROPERTIES clock_props; IMFRateSupport *rate_support; IMFAttributes *attributes; @@ -981,6 +982,12 @@ static void test_media_session(void) hr = IMFGetService_GetService(gs, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, (void **)&rate_control); ok(hr == S_OK, "Failed to get rate control interface, hr %#x.\n", hr);
+ hr = IMFGetService_GetService(gs, &MF_LOCAL_MFT_REGISTRATION_SERVICE, &IID_IMFLocalMFTRegistration, + (void **)&local_reg); + ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Vista */, "Failed to get registration service, hr %#x.\n", hr); + if (SUCCEEDED(hr)) + IMFLocalMFTRegistration_Release(local_reg); + hr = IMFRateSupport_QueryInterface(rate_support, &IID_IMFMediaSession, (void **)&unk); ok(hr == S_OK, "Failed to get session interface, hr %#x.\n", hr); ok(unk == (IUnknown *)session, "Unexpected pointer.\n"); diff --git a/include/mfidl.idl b/include/mfidl.idl index ab6d0d9984..908c659f1d 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -762,6 +762,27 @@ interface IMFQualityManager : IUnknown HRESULT Shutdown(); }
+typedef struct _MFT_REGISTRATION_INFO +{ + CLSID clsid; + GUID guidCategory; + UINT32 uiFlags; + LPCWSTR pszName; + DWORD cInTypes; + [size_is(cInTypes)] MFT_REGISTER_TYPE_INFO *pInTypes; + DWORD cOutTypes; + [size_is(cOutTypes)] MFT_REGISTER_TYPE_INFO *pOutTypes; +} MFT_REGISTRATION_INFO; + +[ + object, + uuid(149c4d73-b4be-4f8d-8b87-079e926b6add) +] +interface IMFLocalMFTRegistration : IUnknown +{ + HRESULT RegisterMFTs([in, size_is(count)] MFT_REGISTRATION_INFO *info, [in] DWORD count); +} + 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") @@ -862,6 +883,7 @@ cpp_quote("EXTERN_GUID(MF_TOPOLOGY_START_TIME_ON_PRESENTATION_SWITCH, 0xc8cc113f cpp_quote("EXTERN_GUID(MF_TOPOLOGY_STATIC_PLAYBACK_OPTIMIZATIONS, 0xb86cac42, 0x41a6, 0x4b79, 0x89, 0x7a, 0x1a, 0xb0, 0xe5, 0x2b, 0x4a, 0x1b);")
cpp_quote("EXTERN_GUID(MF_RATE_CONTROL_SERVICE, 0x866fa297, 0xb802, 0x4bf8, 0x9d, 0xc9, 0x5e, 0x3b, 0x6a, 0x9f, 0x53, 0xc9);") +cpp_quote("EXTERN_GUID(MF_LOCAL_MFT_REGISTRATION_SERVICE, 0xddf5cf9c, 0x4506, 0x45aa, 0xab, 0xf0, 0x6d, 0x5d, 0x94, 0xdd, 0x1b, 0x4a);")
cpp_quote("EXTERN_GUID(MF_SAMPLEGRABBERSINK_SAMPLE_TIME_OFFSET, 0x62e3d776, 0x8100, 0x4e03, 0xa6, 0xe8, 0xbd, 0x38, 0x57, 0xac, 0x9c, 0x47);") cpp_quote("EXTERN_GUID(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, 0x0efda2c0, 0x2b69, 0x4e2e, 0xab, 0x8d, 0x46, 0xdc, 0xbf, 0xf7, 0xd2, 0x5d);")
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 11 +++++++++++ dlls/mfplat/mfplat.spec | 2 +- include/mfapi.h | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 19178d9d51..48e64adeef 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -330,6 +330,17 @@ HRESULT WINAPI MFTRegisterLocal(IClassFactory *factory, REFGUID category, LPCWST return S_OK; }
+HRESULT WINAPI MFTRegisterLocalByCLSID(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags, + UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count, + const MFT_REGISTER_TYPE_INFO *output_types) +{ + + FIXME("%s, %s, %s, %#x, %u, %p, %u, %p.\n", debugstr_guid(clsid), debugstr_guid(category), debugstr_w(name), flags, + input_count, input_types, output_count, output_types); + + return E_NOTIMPL; +} + HRESULT WINAPI MFTUnregisterLocal(IClassFactory *factory) { FIXME("(%p)\n", factory); diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index cc440c5ee0..e48242fa15 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -147,7 +147,7 @@ @ stub MFTGetInfo @ stdcall MFTRegister(int128 int128 wstr long long ptr long ptr ptr) @ stdcall MFTRegisterLocal(ptr ptr wstr long long ptr long ptr) -@ stub MFTRegisterLocalByCLSID +@ stdcall MFTRegisterLocalByCLSID(ptr ptr wstr long long ptr long ptr) @ stdcall MFTUnregister(int128) @ stdcall MFTUnregisterLocal(ptr) @ stub MFTUnregisterLocalByCLSID diff --git a/include/mfapi.h b/include/mfapi.h index 43f5cd6087..182fb19dbf 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -441,6 +441,9 @@ HRESULT WINAPI MFTRegister(CLSID clsid, GUID category, LPWSTR name, UINT32 flags HRESULT WINAPI MFTRegisterLocal(IClassFactory *factory, REFGUID category, LPCWSTR name, UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput, const MFT_REGISTER_TYPE_INFO* output_types); +HRESULT WINAPI MFTRegisterLocalByCLSID(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags, + UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count, + const MFT_REGISTER_TYPE_INFO *output_types); HRESULT WINAPI MFRemovePeriodicCallback(DWORD key); HRESULT WINAPI MFShutdown(void); HRESULT WINAPI MFStartup(ULONG version, DWORD flags);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 5ed29c8525..7a49401d83 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -296,9 +296,21 @@ static ULONG WINAPI local_mft_registration_Release(IMFLocalMFTRegistration *ifac static HRESULT WINAPI local_mft_registration_RegisterMFTs(IMFLocalMFTRegistration *iface, MFT_REGISTRATION_INFO *info, DWORD count) { - FIXME("%p, %p, %u.\n", iface, info, count); + HRESULT hr = S_OK; + DWORD i;
- return E_NOTIMPL; + TRACE("%p, %p, %u.\n", iface, info, count); + + for (i = 0; i < count; ++i) + { + if (FAILED(hr = MFTRegisterLocalByCLSID(&info[i].clsid, &info[i].guidCategory, info[i].pszName, + info[i].uiFlags, info[i].cInTypes, info[i].pInTypes, info[i].cOutTypes, info[i].pOutTypes))) + { + break; + } + } + + return hr; }
static const IMFLocalMFTRegistrationVtbl local_mft_registration_vtbl =
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/topology.c | 126 +++++++++++++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 45 deletions(-)
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index dacb57d264..8d928ad3f9 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -111,6 +111,10 @@ static struct topology_node *unsafe_impl_from_IMFTopologyNode(IMFTopologyNode *i return impl_from_IMFTopologyNode(iface); }
+static HRESULT create_topology_node(MF_TOPOLOGY_TYPE node_type, struct topology_node **node); +static HRESULT topology_node_connect_output(struct topology_node *node, DWORD output_index, + struct topology_node *connection, DWORD input_index); + static struct topology *unsafe_impl_from_IMFTopology(IMFTopology *iface);
static struct topology_loader *impl_from_IMFTopoLoader(IMFTopoLoader *iface) @@ -568,7 +572,6 @@ static HRESULT topology_get_node_by_id(const struct topology *topology, TOPOID i if (topology->nodes.nodes[i]->id == id) { *node = topology->nodes.nodes[i]; - IMFTopologyNode_AddRef(&(*node)->IMFTopologyNode_iface); return S_OK; } } @@ -576,19 +579,15 @@ static HRESULT topology_get_node_by_id(const struct topology *topology, TOPOID i return MF_E_NOT_FOUND; }
-static HRESULT topology_add_node(struct topology *topology, IMFTopologyNode *node_iface) +static HRESULT topology_add_node(struct topology *topology, struct topology_node *node) { - struct topology_node *node = unsafe_impl_from_IMFTopologyNode(node_iface); struct topology_node *match;
if (!node) return E_POINTER;
if (SUCCEEDED(topology_get_node_by_id(topology, node->id, &match))) - { - IMFTopologyNode_Release(&match->IMFTopologyNode_iface); return E_INVALIDARG; - }
if (!mf_array_reserve((void **)&topology->nodes.nodes, &topology->nodes.size, topology->nodes.count + 1, sizeof(*topology->nodes.nodes))) @@ -602,11 +601,12 @@ static HRESULT topology_add_node(struct topology *topology, IMFTopologyNode *nod return S_OK; }
-static HRESULT WINAPI topology_AddNode(IMFTopology *iface, IMFTopologyNode *node) +static HRESULT WINAPI topology_AddNode(IMFTopology *iface, IMFTopologyNode *node_iface) { struct topology *topology = impl_from_IMFTopology(iface); + struct topology_node *node = unsafe_impl_from_IMFTopologyNode(node_iface);
- TRACE("%p, %p.\n", iface, node); + TRACE("%p, %p.\n", iface, node_iface);
return topology_add_node(topology, node); } @@ -684,9 +684,9 @@ static HRESULT WINAPI topology_CloneFrom(IMFTopology *iface, IMFTopology *src) { struct topology *topology = impl_from_IMFTopology(iface); struct topology *src_topology = unsafe_impl_from_IMFTopology(src); - IMFTopologyNode *node; + struct topology_node *node; + size_t i, j; HRESULT hr; - size_t i;
TRACE("%p, %p.\n", iface, src);
@@ -695,19 +695,36 @@ static HRESULT WINAPI topology_CloneFrom(IMFTopology *iface, IMFTopology *src) /* Clone nodes. */ for (i = 0; i < src_topology->nodes.count; ++i) { - if (FAILED(hr = MFCreateTopologyNode(src_topology->nodes.nodes[i]->node_type, &node))) + if (FAILED(hr = create_topology_node(src_topology->nodes.nodes[i]->node_type, &node))) { WARN("Failed to create a node, hr %#x.\n", hr); break; }
- if (SUCCEEDED(hr = IMFTopologyNode_CloneFrom(node, &src_topology->nodes.nodes[i]->IMFTopologyNode_iface))) + if (SUCCEEDED(hr = IMFTopologyNode_CloneFrom(&node->IMFTopologyNode_iface, + &src_topology->nodes.nodes[i]->IMFTopologyNode_iface))) + { topology_add_node(topology, node); + }
- IMFTopologyNode_Release(node); + IMFTopologyNode_Release(&node->IMFTopologyNode_iface); }
- FIXME("Clone node connections.\n"); + /* Clone connections. */ + for (i = 0; i < src_topology->nodes.count; ++i) + { + const struct node_streams *outputs = &src_topology->nodes.nodes[i]->outputs; + + for (j = 0; j < outputs->count; ++j) + { + DWORD input_index = outputs->streams[j].connection_stream; + TOPOID id = outputs->streams[j].connection->id; + + /* Skip node lookup in destination topology, assuming same node order. */ + if (SUCCEEDED(hr = topology_get_node_by_id(topology, id, &node))) + topology_node_connect_output(topology->nodes.nodes[i], j, node, input_index); + } + }
/* Copy attributes and id. */ hr = IMFTopology_CopyAllItems(src, (IMFAttributes *)&topology->IMFTopology_iface); @@ -726,7 +743,10 @@ static HRESULT WINAPI topology_GetNodeByID(IMFTopology *iface, TOPOID id, IMFTop TRACE("%p, %p.\n", iface, ret);
if (SUCCEEDED(hr = topology_get_node_by_id(topology, id, &node))) + { *ret = &node->IMFTopologyNode_iface; + IMFTopologyNode_AddRef(*ret); + } else *ret = NULL;
@@ -1358,22 +1378,12 @@ static HRESULT WINAPI topology_node_GetOutputCount(IMFTopologyNode *iface, DWORD return S_OK; }
-static HRESULT WINAPI topology_node_ConnectOutput(IMFTopologyNode *iface, DWORD output_index, - IMFTopologyNode *peer, DWORD input_index) +static HRESULT topology_node_connect_output(struct topology_node *node, DWORD output_index, + struct topology_node *connection, DWORD input_index) { - struct topology_node *node = impl_from_IMFTopologyNode(iface); - struct topology_node *connection = unsafe_impl_from_IMFTopologyNode(peer); struct node_stream *stream; HRESULT hr;
- TRACE("%p, %u, %p, %u.\n", iface, output_index, peer, input_index); - - if (!connection) - { - WARN("External node implementations are not supported.\n"); - return E_UNEXPECTED; - } - if (node->node_type == MF_TOPOLOGY_OUTPUT_NODE || connection->node_type == MF_TOPOLOGY_SOURCESTREAM_NODE) return E_FAIL;
@@ -1408,6 +1418,23 @@ static HRESULT WINAPI topology_node_ConnectOutput(IMFTopologyNode *iface, DWORD return hr; }
+static HRESULT WINAPI topology_node_ConnectOutput(IMFTopologyNode *iface, DWORD output_index, + IMFTopologyNode *peer, DWORD input_index) +{ + struct topology_node *node = impl_from_IMFTopologyNode(iface); + struct topology_node *connection = unsafe_impl_from_IMFTopologyNode(peer); + + TRACE("%p, %u, %p, %u.\n", iface, output_index, peer, input_index); + + if (!connection) + { + WARN("External node implementations are not supported.\n"); + return E_UNEXPECTED; + } + + return topology_node_connect_output(node, output_index, connection, input_index); +} + static HRESULT WINAPI topology_node_DisconnectOutput(IMFTopologyNode *iface, DWORD output_index) { struct topology_node *node = impl_from_IMFTopologyNode(iface); @@ -1684,6 +1711,29 @@ static const IMFTopologyNodeVtbl topologynodevtbl = topology_node_CloneFrom, };
+static HRESULT create_topology_node(MF_TOPOLOGY_TYPE node_type, struct topology_node **node) +{ + HRESULT hr; + + *node = heap_alloc_zero(sizeof(**node)); + if (!*node) + return E_OUTOFMEMORY; + + (*node)->IMFTopologyNode_iface.lpVtbl = &topologynodevtbl; + (*node)->refcount = 1; + (*node)->node_type = node_type; + hr = MFCreateAttributes(&(*node)->attributes, 0); + if (FAILED(hr)) + { + heap_free(*node); + return hr; + } + (*node)->id = ((TOPOID)GetCurrentProcessId() << 32) | InterlockedIncrement(&next_node_id); + InitializeCriticalSection(&(*node)->cs); + + return S_OK; +} + /*********************************************************************** * MFCreateTopologyNode (mf.@) */ @@ -1692,30 +1742,16 @@ HRESULT WINAPI MFCreateTopologyNode(MF_TOPOLOGY_TYPE node_type, IMFTopologyNode struct topology_node *object; HRESULT hr;
- TRACE("(%p)\n", node); + TRACE("%d, %p.\n", node_type, node);
if (!node) return E_POINTER;
- object = heap_alloc_zero(sizeof(*object)); - if (!object) - return E_OUTOFMEMORY; - - object->IMFTopologyNode_iface.lpVtbl = &topologynodevtbl; - object->refcount = 1; - object->node_type = node_type; - hr = MFCreateAttributes(&object->attributes, 0); - if (FAILED(hr)) - { - heap_free(object); - return hr; - } - object->id = ((TOPOID)GetCurrentProcessId() << 32) | InterlockedIncrement(&next_node_id); - InitializeCriticalSection(&object->cs); - - *node = &object->IMFTopologyNode_iface; + hr = create_topology_node(node_type, &object); + if (SUCCEEDED(hr)) + *node = &object->IMFTopologyNode_iface;
- return S_OK; + return hr; }
static HRESULT WINAPI topology_loader_QueryInterface(IMFTopoLoader *iface, REFIID riid, void **out)
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")
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=57566
Your paranoid android.
=== wvistau64_fr (32 bit report) ===
mf: mf.c:922: Test failed: Unexpected hr 0xc00d36da. mf.c:926: Test failed: Unexpected hr 0. mf.c:942: Test failed: Unexpected return value 0x102.
=== w8adm (32 bit report) ===
mf: mf.c:926: Test failed: Unexpected hr 0xc00d36da. mf.c:934: Test failed: Unexpected hr 0xc00d36d9.
=== w864 (32 bit report) ===
mf: mf.c:922: Test failed: Unexpected hr 0xc00d36da. mf.c:942: Test failed: Unexpected return value 0x102.
=== w1064v1507 (32 bit report) ===
mf: mf.c:922: Test failed: Unexpected hr 0xc00d36da. mf.c:942: Test failed: Unexpected return value 0x102.
=== w864 (64 bit report) ===
mf: mf.c:922: Test failed: Unexpected hr 0xc00d36da. mf.c:942: Test failed: Unexpected return value 0x102.
=== w1064v1507 (64 bit report) ===
mf: mf.c:866: Test failed: Failed to finalize GetEvent, hr 0x80004005. 0fe4:mf: unhandled exception c0000005 at 00000000004026A4
=== debian10 (32 bit French report) ===
mf: Unhandled exception: page fault on execute access to 0x00000000 in 32-bit code (0x00000000).
Report errors: mf:mf crashed (c0000005)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=57562
Your paranoid android.
=== w864 (32 bit report) ===
mf: mf.c:917: Test failed: Unexpected hr 0xc00d36da. mf.c:937: Test failed: Unexpected return value 0x102.
=== w1064v1507 (32 bit report) ===
mf: mf.c:917: Test failed: Unexpected hr 0xc00d36da. mf.c:937: Test failed: Unexpected return value 0x102.
=== w1064v1507 (64 bit report) ===
mf: mf.c:921: Test failed: Unexpected hr 0xc00d36da.
=== w1064v1809 (64 bit report) ===
mf: mf.c:921: Test failed: Unexpected hr 0xc00d36da.