[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