From: Conor McCarthy <cmccarthy@codeweavers.com> Windows does not call MFTEnumEx to get a color converter. --- dlls/mf/tests/topology.c | 7 ++---- dlls/mf/topology_loader.c | 47 +++++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/dlls/mf/tests/topology.c b/dlls/mf/tests/topology.c index 46bc9d52d7a..f80bff61154 100644 --- a/dlls/mf/tests/topology.c +++ b/dlls/mf/tests/topology.c @@ -2699,7 +2699,7 @@ static void test_topology_loader(void) .input_types = {&audio_mp3_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_DIRECT, .mft_input_type = &audio_aac_44100, .mft_output_types = {&audio_pcm_48000}, .expected_result = MF_E_TOPO_CODEC_NOT_FOUND, - .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO | LOADER_TODO, + .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO, }, { @@ -2830,7 +2830,7 @@ static void test_topology_loader(void) .input_types = {&video_h264_1280}, .output_types = {&video_color_convert_1280_rgb32}, .sink_method = -1, .source_method = -1, .mft_input_type = &video_color_convert_1280_rgb32, .mft_output_types = {&video_color_convert_1280_rgb32}, .expected_result = MF_E_TOPO_CODEC_NOT_FOUND, .decoder_class = CLSID_CMSH264DecoderMFT, - .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO | LOADER_TODO, + .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO, }, { /* H264 -> RGB32, Video Processor media type, add test MFT */ @@ -3298,13 +3298,11 @@ todo_wine { hr = IMFTopologyNode_GetGUID(mft_node, &MF_TOPONODE_TRANSFORM_OBJECTID, &class_id); if (test->flags & LOADER_SET_XVP_FOR_PLAYBACK) { - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Got attribute hr %#lx.\n", hr); } else { ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr); - todo_wine_if(IsEqualGUID(&test->converter_class, &CLSID_CColorConvertDMO)) ok(IsEqualGUID(&class_id, &test->converter_class), "got MF_TOPONODE_TRANSFORM_OBJECTID %s.\n", debugstr_guid(&class_id)); } @@ -3427,7 +3425,6 @@ todo_wine { ok(ref == 0, "Release returned %ld\n", ref); ref = IMFMediaType_Release(input_types[0]); - todo_wine ok(ref == 0, "Release returned %ld\n", ref); ref = IMFMediaType_Release(input_types[1]); ok(ref == 0, "Release returned %ld\n", ref); diff --git a/dlls/mf/topology_loader.c b/dlls/mf/topology_loader.c index 4a73c8441d7..a78ee5ad8f9 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -304,10 +304,9 @@ static HRESULT topology_branch_connect(IMFTopology *topology, MF_CONNECT_METHOD struct topology_branch *branch, BOOL enumerate_source_types); static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_METHOD method, struct topology_branch *branch, IMFMediaType *up_type); -static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNECT_METHOD method_mask, +static HRESULT topology_branch_connect_decoder(IMFTopology *topology, struct topology_branch *branch, IMFMediaType *up_type, IMFMediaType *down_type) { - BOOL decoder = (method_mask & MF_CONNECT_ALLOW_DECODER) == MF_CONNECT_ALLOW_DECODER; MFT_REGISTER_TYPE_INFO input_info, output_info; IMFTransform *transform; IMFActivate **activates; @@ -316,7 +315,7 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC GUID category, guid; HRESULT hr; - TRACE("topology %p, method_mask %#x, branch %s, up_type %s, down_type %s.\n", topology, method_mask, + TRACE("topology %p, branch %s, up_type %s, down_type %s.\n", topology, debugstr_topology_branch(branch), debugstr_media_type(up_type), debugstr_media_type(down_type)); if (FAILED(hr = IMFMediaType_GetMajorType(up_type, &input_info.guidMajorType))) @@ -334,32 +333,26 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC } if (IsEqualGUID(&input_info.guidMajorType, &MFMediaType_Audio)) - category = decoder ? MFT_CATEGORY_AUDIO_DECODER : MFT_CATEGORY_AUDIO_EFFECT; + category = MFT_CATEGORY_AUDIO_DECODER; else if (IsEqualGUID(&input_info.guidMajorType, &MFMediaType_Video)) - category = decoder ? MFT_CATEGORY_VIDEO_DECODER : MFT_CATEGORY_VIDEO_PROCESSOR; + category = MFT_CATEGORY_VIDEO_DECODER; else return MF_E_INVALIDMEDIATYPE; if (FAILED(hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node))) return hr; - if (!decoder) - method_mask = MF_CONNECT_DIRECT; - else - { - IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_DECODER, 1); - IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_MARKIN_HERE, 1); - IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_MARKOUT_HERE, 1); - method_mask = MF_CONNECT_ALLOW_CONVERTER; - } + IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_DECODER, 1); + IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_MARKIN_HERE, 1); + IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_MARKOUT_HERE, 1); - if (FAILED(hr = MFTEnumEx(category, MFT_ENUM_FLAG_ALL, &input_info, decoder ? NULL : &output_info, &activates, &count))) + if (FAILED(hr = MFTEnumEx(category, MFT_ENUM_FLAG_ALL, &input_info, NULL, &activates, &count))) return hr; for (i = 0, hr = MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION; i < count; ++i) { struct topology_branch down_branch = {.up.node = node, .down = branch->down}; struct topology_branch up_branch = {.up = branch->up, .down.node = node}; - MF_CONNECT_METHOD method = method_mask; + MF_CONNECT_METHOD method = MF_CONNECT_ALLOW_CONVERTER; IMFMediaType *media_type; if (FAILED(IMFActivate_ActivateObject(activates[i], &IID_IMFTransform, (void **)&transform))) @@ -388,7 +381,12 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC } if (SUCCEEDED(hr)) + { hr = topology_branch_connect(topology, method, &down_branch, !down_type); + /* Failure to connect a converter must result in MF_E_TOPO_CODEC_NOT_FOUND */ + if (hr == MF_E_INVALIDMEDIATYPE || hr == MF_E_NO_MORE_TYPES) + hr = MF_E_TOPO_CODEC_NOT_FOUND; + } if (SUCCEEDED(hr)) hr = IMFTopology_AddNode(topology, node); if (SUCCEEDED(hr)) @@ -498,7 +496,19 @@ static HRESULT topology_branch_connect_converter_with_types(IMFTopology *topolog } else if (IsEqualGUID(&major, &MFMediaType_Video)) { - return topology_branch_connect_indirect(topology, MF_CONNECT_ALLOW_CONVERTER, branch, up_type, down_type); + UINT32 enable_xvp = 0; + + IMFTopology_GetUINT32(topology, &MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK, &enable_xvp); + + /* Changing the color converter GUID in Windows regedit does not prevent a CColorConvertDMO + * being used, implying that MFTEnumEx() is not called for converters. + * TODO: The same is not true for the VideoProcessorMFT, so MFTEnumEx() should be used when ENABLE_XVP is specified. */ + if (enable_xvp) + hr = create_transform_node(&CLSID_VideoProcessorMFT, &node, &transform, FALSE); + else + hr = create_transform_node(&CLSID_CColorConvertDMO, &node, &transform, TRUE); + if (FAILED(hr)) + return hr; } else { @@ -622,8 +632,7 @@ static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_ME hr = topology_branch_connect_converter_with_types(topology, branch, up_type, down_type); if (FAILED(hr) && (method & MF_CONNECT_ALLOW_DECODER) == MF_CONNECT_ALLOW_DECODER) - hr = topology_branch_connect_indirect(topology, MF_CONNECT_ALLOW_DECODER, - branch, up_type, down_type); + hr = topology_branch_connect_decoder(topology, branch, up_type, down_type); done: if (down_type) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10009