mf: Implement MFGetTopoNodeCurrentType().

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Nikolay Sivov 2020-03-10 15:23:00 +03:00 committed by Alexandre Julliard
parent 3e1cfb3dd8
commit 82eecc50b5
4 changed files with 168 additions and 1 deletions

View File

@ -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)

View File

@ -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();
}

View File

@ -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);

View File

@ -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