Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/mf/topology.c | 109 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index ce107d05f2..4298ab1bc5 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -1913,6 +1913,97 @@ static ULONG WINAPI topology_loader_Release(IMFTopoLoader *iface) return refcount; }
+ +/* Resolves a branch with the supplied source and sink */ +static HRESULT topology_loader_resolve_branch(struct topology_node *src, struct topology_node *sink, struct topology *full_topology) +{ + IMFStreamDescriptor *strm_desc; + IMFMediaType **src_mediatypes; + UINT32 method, enum_src_types; + IMFMediaTypeHandler *mth_src; + IMFAttributes *attrs_src; + IMFMediaType *mtype_src; + DWORD num_media_types; + HRESULT hr; + int i; + + attrs_src = src->attributes; + if (FAILED(hr = IMFAttributes_GetUnknown(attrs_src, &MF_TOPONODE_STREAM_DESCRIPTOR, &IID_IMFStreamDescriptor, (void **)&strm_desc))) + return hr; + + if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(strm_desc, &mth_src))) + { + IMFStreamDescriptor_Release(strm_desc); + return hr; + } + IMFStreamDescriptor_Release(strm_desc); + + if (FAILED(IMFTopology_GetUINT32(&full_topology->IMFTopology_iface, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, &enum_src_types))) + enum_src_types = 0; + + if (!enum_src_types) + { + num_media_types = 1; + if (FAILED(hr = IMFMediaTypeHandler_GetCurrentMediaType(mth_src, &mtype_src))) + if (FAILED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth_src, 0, &mtype_src))) + { + IMFMediaTypeHandler_Release(mth_src); + return hr; + } + } + else + IMFMediaTypeHandler_GetMediaTypeCount(mth_src, &num_media_types); + + src_mediatypes = heap_alloc(sizeof(IMFMediaType *) * num_media_types); + if (!src_mediatypes) + { + if (!enum_src_types) + IMFMediaType_Release(mtype_src); + IMFMediaTypeHandler_Release(mth_src); + return E_OUTOFMEMORY; + } + + if (enum_src_types) + for (i = 0; i < num_media_types; i++) + IMFMediaTypeHandler_GetMediaTypeByIndex(mth_src, i, &src_mediatypes[i]); + else + src_mediatypes[0] = mtype_src; + + hr = IMFAttributes_GetUINT32(attrs_src, &MF_TOPONODE_CONNECT_METHOD, &method); + if (!enum_src_types || (hr == S_OK && !(method & MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES))) + { + for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++) + { + for (i = 0; i < num_media_types; i++) + { + IMFMediaTypeHandler_SetCurrentMediaType(mth_src, src_mediatypes[i]); + hr = S_OK; + goto out; + } + } + } + else + { + for (i = 0; i < num_media_types; i++) + { + for (method = MF_CONNECT_DIRECT; method < MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES; method++) + { + IMFMediaTypeHandler_SetCurrentMediaType(mth_src, src_mediatypes[i]); + hr = S_OK; + goto out; + } + } + } + +out: + while (num_media_types--) + IMFMediaType_Release(src_mediatypes[num_media_types]); + IMFMediaTypeHandler_Release(mth_src); + heap_free(src_mediatypes); + + return hr; +} + static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *input_topology, IMFTopology **output_topology, IMFTopology *current_topology) { @@ -2005,10 +2096,26 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in IMFStreamSink_Release(sink); }
+ /* resolve each branch */ + for (i = 0; i < num_connections; i++) + { + struct topology_node *sink = node_pairs[i][1]; + struct topology_node *src = node_pairs[i][0]; + + if (FAILED(hr = topology_loader_resolve_branch(src, sink, full_topology))) + { + FIXME("Check for MF_CONNECT_AS_OPTIONAL and MF_CONNECT_AS_OPTIONAL_BRANCH flags.\n"); + goto out; + } + } + *output_topology = &full_topology->IMFTopology_iface; - hr = S_OK; + out: + if (FAILED(hr)) + IMFTopology_Release(&full_topology->IMFTopology_iface); heap_free(node_pairs); + return hr; }