[v2 10/10] mf: Introduce topology_loader_connect_converter_node() and topology_loader_connect_decoder_node() helper functions.
Sergio Gómez Del Real
sdelreal at codeweavers.com
Sun Jul 5 09:16:15 CDT 2020
Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
---
dlls/mf/Makefile.in | 2 +-
dlls/mf/tests/mf.c | 4 --
dlls/mf/topology.c | 124 +++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 123 insertions(+), 7 deletions(-)
diff --git a/dlls/mf/Makefile.in b/dlls/mf/Makefile.in
index fe156e43ab..34118fed67 100644
--- a/dlls/mf/Makefile.in
+++ b/dlls/mf/Makefile.in
@@ -1,6 +1,6 @@
MODULE = mf.dll
IMPORTLIB = mf
-IMPORTS = advapi32 mfplat ole32 uuid mfuuid
+IMPORTS = advapi32 mfplat ole32 uuid mfuuid wmcodecdspuuid
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 28efe310f6..0d7ab15d8a 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -1841,7 +1841,6 @@ todo_wine
/* if no current media type set, loader uses first index exclusively */
hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
-todo_wine
ok(hr == MF_E_TOPO_CODEC_NOT_FOUND, "Unexpected hr %#x.\n", hr);
hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &mth);
@@ -1855,7 +1854,6 @@ todo_wine
ok(hr == S_OK, "Failed setting current media type, hr %#x.\n", hr);
hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
-todo_wine
ok(hr == MF_E_TOPO_CODEC_NOT_FOUND, "Unexpected hr %#x.\n", hr);
hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth, 1, &media_type);
@@ -1935,7 +1933,6 @@ todo_wine
ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
hr = IMFTopology_GetNodeCount(full_topology, &node_count);
ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
-todo_wine
ok(node_count == 3, "Unexpected node count %d.\n", node_count);
IMFTopology_Release(full_topology);
@@ -1952,7 +1949,6 @@ todo_wine
hr = IMFTopology_GetNodeCount(full_topology, &node_count);
ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
-todo_wine
ok(node_count == 3, "Unexpected node count %d.\n", node_count);
/* now test without MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES on source */
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
index 3ee8ddc40b..d278f84899 100644
--- a/dlls/mf/topology.c
+++ b/dlls/mf/topology.c
@@ -29,6 +29,7 @@
#include "mfapi.h"
#include "mferror.h"
#include "mfidl.h"
+#include "wmcodecdsp.h"
#include "wine/debug.h"
@@ -2089,15 +2090,134 @@ static HRESULT topology_loader_connect_direct(IMFTopologyNode *upstream_node, un
return hr;
}
+static HRESULT topology_loader_connect_converter_node(struct topoloader_context *context, IMFTopologyNode *upstream_node, unsigned int output_index,
+ IMFTopologyNode *downstream_node, unsigned int input_index, IMFMediaType *output_type, const CLSID *clsid)
+{
+ IMFTransform *transform = NULL;
+ IMFMediaType *mediatype = NULL;
+ HRESULT hr;
+
+ if (FAILED(hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform)))
+ {
+ WARN("Failed to create converter transform for %s, hr %#x.\n", debugstr_guid(clsid), hr);
+ return hr;
+ }
+
+ if (SUCCEEDED(hr = IMFTransform_SetInputType(transform, 0, output_type, 0)))
+ {
+ IMFTopologyNode *converter_node;
+
+ MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &converter_node);
+ IMFTopologyNode_SetObject(converter_node, (IUnknown *)transform);
+
+ if (SUCCEEDED(hr = topology_loader_connect_direct(upstream_node, output_index, converter_node, 0, mediatype)))
+ {
+ unsigned int i = 0;
+ while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, i++, &mediatype)))
+ {
+ hr = topology_loader_connect_direct(converter_node, 0, downstream_node, input_index, mediatype);
+
+ IMFMediaType_Release(mediatype);
+
+ if (SUCCEEDED(hr))
+ {
+ IMFTopology_AddNode(context->output_topology, converter_node);
+ break;
+ }
+ }
+ }
+
+ IMFTransform_Release(transform);
+ IMFTopologyNode_Release(converter_node);
+ }
+
+ return hr;
+}
+
+static HRESULT topology_loader_connect_decoder_node(struct topoloader_context *context, IMFTopologyNode *upstream_node, unsigned int output_index,
+ IMFTopologyNode *downstream_node, unsigned int input_index, IMFMediaType *input_type, const CLSID *clsid)
+{
+ HRESULT hr = MF_E_TOPO_CODEC_NOT_FOUND;
+ unsigned int i = 0, j = 0, count = 0;
+ MFT_REGISTER_TYPE_INFO input_info;
+ IMFMediaType *current_mediatype;
+ IMFActivate **activators = NULL;
+ IMFTransform *transform = NULL;
+ IMFTopologyNode *decoder_node;
+ const GUID *category;
+
+ IMFMediaType_GetMajorType(input_type, &input_info.guidMajorType);
+ IMFMediaType_GetGUID(input_type, &MF_MT_SUBTYPE, &input_info.guidSubtype);
+
+ if (IsEqualGUID(&MFMediaType_Audio, &input_info.guidMajorType))
+ category = &MFT_CATEGORY_AUDIO_DECODER;
+ else
+ category = &MFT_CATEGORY_VIDEO_DECODER;
+
+ if (SUCCEEDED(MFTEnumEx(*category, MFT_ENUM_FLAG_ALL, &input_info, NULL, &activators, &count)))
+ {
+ for (i = 0; i < count; ++i)
+ {
+ if (FAILED(IMFActivate_ActivateObject(activators[i], &IID_IMFTransform, (void **)&transform)))
+ {
+ WARN("Failed to activate transform, hr %#x.\n", hr);
+ continue;
+ }
+
+ if (SUCCEEDED(MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &decoder_node))
+ && SUCCEEDED(IMFTransform_SetInputType(transform, 0, input_type, 0))
+ && SUCCEEDED(IMFTopologyNode_SetObject(decoder_node, (IUnknown *)transform)))
+ {
+ j = 0;
+ while (SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, j++, ¤t_mediatype)))
+ {
+ if (SUCCEEDED(hr = topology_loader_connect_direct(decoder_node, 0, downstream_node, input_index, current_mediatype))
+ || SUCCEEDED(hr = topology_loader_connect_converter_node(context, decoder_node, 0, downstream_node, input_index, current_mediatype, clsid)))
+ {
+ IMFTopology_AddNode(context->output_topology, decoder_node);
+ IMFTransform_SetOutputType(transform, 0, current_mediatype, 0);
+ IMFMediaType_Release(current_mediatype);
+ break;
+ }
+ IMFMediaType_Release(current_mediatype);
+ }
+ IMFTopologyNode_Release(decoder_node);
+ }
+
+ IMFTransform_Release(transform);
+
+ if (SUCCEEDED(hr))
+ break;
+ }
+ for (i = 0; i < count; ++i)
+ IMFActivate_Release(activators[i]);
+ CoTaskMemFree(activators);
+ }
+
+ return hr;
+}
+
static HRESULT topology_loader_connect_nodes(struct topoloader_context *context, IMFTopologyNode *upstream_node, unsigned int output_index,
IMFTopologyNode *downstream_node, unsigned int input_index, IMFMediaType *output_type, UINT32 connect_method)
{
+ const GUID *clsid;
HRESULT hr;
GUID major;
if (FAILED(hr = IMFMediaType_GetMajorType(output_type, &major)))
goto out;
+ if (IsEqualGUID(&major, &MFMediaType_Video))
+ clsid = &CLSID_VideoProcessorMFT;
+ else if (IsEqualGUID(&major, &MFMediaType_Audio))
+ clsid = &CLSID_CResamplerMediaObject;
+ else
+ {
+ WARN("Unexpected major type %s.\n", debugstr_guid(&major));
+ hr = E_UNEXPECTED;
+ goto out;
+ }
+
/* always try first a direct connection */
if (FAILED(hr = topology_loader_connect_direct(upstream_node, output_index, downstream_node, input_index, output_type))
&& connect_method != MF_CONNECT_DIRECT)
@@ -2105,10 +2225,10 @@ static HRESULT topology_loader_connect_nodes(struct topoloader_context *context,
switch (connect_method)
{
case MF_CONNECT_ALLOW_CONVERTER:
- hr = S_OK;
+ hr = topology_loader_connect_converter_node(context, upstream_node, output_index, downstream_node, input_index, output_type, clsid);
break;
case MF_CONNECT_ALLOW_DECODER:
- hr = S_OK;
+ hr = topology_loader_connect_decoder_node(context, upstream_node, output_index, downstream_node, input_index, output_type, clsid);
break;
}
}
--
2.17.1
More information about the wine-devel
mailing list