[PATCH 4/4] mf: Implement MFGetTopoNodeCurrentType().

Nikolay Sivov nsivov at codeweavers.com
Tue Mar 10 07:23:00 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mf/mf.spec    |  2 +-
 dlls/mf/tests/mf.c | 81 +++++++++++++++++++++++++++++++++++++++++++
 dlls/mf/topology.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++
 include/mfidl.idl  |  1 +
 4 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/dlls/mf/mf.spec b/dlls/mf/mf.spec
index 1c3fc9c953..4b5b085d08 100644
--- a/dlls/mf/mf.spec
+++ b/dlls/mf/mf.spec
@@ -75,7 +75,7 @@
 @ stdcall MFGetService(ptr ptr ptr ptr)
 @ stdcall MFGetSupportedMimeTypes(ptr)
 @ stdcall MFGetSupportedSchemes(ptr)
-@ stub MFGetTopoNodeCurrentType
+@ stdcall MFGetTopoNodeCurrentType(ptr long long ptr)
 @ stub MFReadSequencerSegmentOffset
 @ stub MFRequireProtectedEnvironment
 @ stdcall MFShutdownObject(ptr)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index dcb20aff05..da533d05d3 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -3103,6 +3103,86 @@ static void test_sample_copier(void)
     IMFTransform_Release(copier);
 }
 
+static void test_MFGetTopoNodeCurrentType(void)
+{
+    IMFMediaType *media_type, *media_type2;
+    IMFTopologyNode *node;
+    HRESULT hr;
+
+    /* Tee node. */
+    hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
+    ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
+
+    hr = MFGetTopoNodeCurrentType(node, 0, TRUE, &media_type);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    hr = MFCreateMediaType(&media_type2);
+    ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
+
+    hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+
+    /* Input type returned, if set. */
+    hr = IMFTopologyNode_SetInputPrefType(node, 0, media_type2);
+    ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
+
+    hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(media_type == media_type2, "Unexpected pointer.\n");
+    IMFMediaType_Release(media_type);
+
+    hr = IMFTopologyNode_SetInputPrefType(node, 0, NULL);
+    ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
+
+    hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    /* Set second output. */
+    hr = IMFTopologyNode_SetOutputPrefType(node, 1, media_type2);
+    ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
+
+    hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
+    ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFTopologyNode_SetOutputPrefType(node, 1, NULL);
+    ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
+
+    /* Set first output. */
+    hr = IMFTopologyNode_SetOutputPrefType(node, 0, media_type2);
+    ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
+
+    hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(media_type == media_type2, "Unexpected pointer.\n");
+    IMFMediaType_Release(media_type);
+
+    hr = IMFTopologyNode_SetOutputPrefType(node, 0, NULL);
+    ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
+
+    /* Set primary output. */
+    hr = IMFTopologyNode_SetOutputPrefType(node, 1, media_type2);
+    ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
+
+    hr = IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_PRIMARYOUTPUT, 1);
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+
+    hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(media_type == media_type2, "Unexpected pointer.\n");
+    IMFMediaType_Release(media_type);
+
+    hr = MFGetTopoNodeCurrentType(node, 0, TRUE, &media_type);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(media_type == media_type2, "Unexpected pointer.\n");
+    IMFMediaType_Release(media_type);
+
+    IMFTopologyNode_Release(node);
+    IMFMediaType_Release(media_type2);
+}
+
 START_TEST(mf)
 {
     test_topology();
@@ -3121,4 +3201,5 @@ START_TEST(mf)
     test_MFGetSupportedMimeTypes();
     test_MFGetSupportedSchemes();
     test_sample_copier();
+    test_MFGetTopoNodeCurrentType();
 }
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c
index db82816328..67afba6ba4 100644
--- a/dlls/mf/topology.c
+++ b/dlls/mf/topology.c
@@ -1786,6 +1786,91 @@ HRESULT WINAPI MFCreateTopologyNode(MF_TOPOLOGY_TYPE node_type, IMFTopologyNode
     return hr;
 }
 
+/***********************************************************************
+ *      MFGetTopoNodeCurrentType (mf.@)
+ */
+HRESULT WINAPI MFGetTopoNodeCurrentType(IMFTopologyNode *node, DWORD stream, BOOL output, IMFMediaType **type)
+{
+    IMFMediaTypeHandler *type_handler;
+    MF_TOPOLOGY_TYPE node_type;
+    IMFStreamSink *stream_sink;
+    IMFStreamDescriptor *sd;
+    IMFTransform *transform;
+    UINT32 primary_output;
+    IUnknown *object;
+    HRESULT hr;
+
+    TRACE("%p, %u, %d, %p.\n", node, stream, output, type);
+
+    if (FAILED(hr = IMFTopologyNode_GetNodeType(node, &node_type)))
+        return hr;
+
+    switch (node_type)
+    {
+        case MF_TOPOLOGY_OUTPUT_NODE:
+            if (FAILED(hr = IMFTopologyNode_GetObject(node, &object)))
+                return hr;
+
+            hr = IUnknown_QueryInterface(object, &IID_IMFStreamSink, (void **)&stream_sink);
+            IUnknown_Release(object);
+            if (SUCCEEDED(hr))
+            {
+                hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &type_handler);
+                IMFStreamSink_Release(stream_sink);
+
+                if (SUCCEEDED(hr))
+                {
+                    hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, type);
+                    IMFMediaTypeHandler_Release(type_handler);
+                }
+            }
+            break;
+        case MF_TOPOLOGY_SOURCESTREAM_NODE:
+            if (FAILED(hr = IMFTopologyNode_GetUnknown(node, &MF_TOPONODE_STREAM_DESCRIPTOR, &IID_IMFStreamDescriptor,
+                    (void **)&sd)))
+            {
+                return hr;
+            }
+
+            hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &type_handler);
+            IMFStreamDescriptor_Release(sd);
+            if (SUCCEEDED(hr))
+            {
+                hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, type);
+                IMFMediaTypeHandler_Release(type_handler);
+            }
+            break;
+        case MF_TOPOLOGY_TRANSFORM_NODE:
+            if (FAILED(hr = IMFTopologyNode_GetObject(node, &object)))
+                return hr;
+
+            hr = IUnknown_QueryInterface(object, &IID_IMFTransform, (void **)&transform);
+            IUnknown_Release(object);
+            if (SUCCEEDED(hr))
+            {
+                if (output)
+                    hr = IMFTransform_GetOutputCurrentType(transform, stream, type);
+                else
+                    hr = IMFTransform_GetInputCurrentType(transform, stream, type);
+                IMFTransform_Release(transform);
+            }
+            break;
+        case MF_TOPOLOGY_TEE_NODE:
+            if (SUCCEEDED(hr = IMFTopologyNode_GetInputPrefType(node, 0, type)))
+                break;
+
+            if (FAILED(IMFTopologyNode_GetUINT32(node, &MF_TOPONODE_PRIMARYOUTPUT, &primary_output)))
+                primary_output = 0;
+
+            hr = IMFTopologyNode_GetOutputPrefType(node, primary_output, type);
+            break;
+        default:
+            ;
+    }
+
+    return hr;
+}
+
 static HRESULT WINAPI topology_loader_QueryInterface(IMFTopoLoader *iface, REFIID riid, void **out)
 {
     TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
diff --git a/include/mfidl.idl b/include/mfidl.idl
index cf04ec17ce..60337f8106 100644
--- a/include/mfidl.idl
+++ b/include/mfidl.idl
@@ -609,6 +609,7 @@ cpp_quote("HRESULT WINAPI MFGetSupportedMimeTypes(PROPVARIANT *array);")
 cpp_quote("HRESULT WINAPI MFGetSupportedSchemes(PROPVARIANT *array);")
 cpp_quote("HRESULT WINAPI MFGetService(IUnknown *object, REFGUID service, REFIID iid, void **obj);")
 cpp_quote("MFTIME  WINAPI MFGetSystemTime(void);")
+cpp_quote("HRESULT WINAPI MFGetTopoNodeCurrentType(IMFTopologyNode *node, DWORD stream, BOOL output, IMFMediaType **type);")
 cpp_quote("HRESULT WINAPI MFShutdownObject(IUnknown *object);")
 
 typedef enum _MFMEDIASOURCE_CHARACTERISTICS
-- 
2.25.1




More information about the wine-devel mailing list