From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/mf/tests/topology.c | 22 ++++++------ dlls/mf/topology_loader.c | 76 +++++++++++++++++++++------------------ 2 files changed, 52 insertions(+), 46 deletions(-) diff --git a/dlls/mf/tests/topology.c b/dlls/mf/tests/topology.c index 39e8ecdb401..fc3fc68aa21 100644 --- a/dlls/mf/tests/topology.c +++ b/dlls/mf/tests/topology.c @@ -2761,7 +2761,7 @@ static void test_topology_loader(void) .input_types = {&video_h264_1280}, .output_types = {&video_color_convert_1280_rgb32, &video_video_processor_1280_rgb32}, .sink_method = -1, .source_method = -1, .decoded_type = &video_nv12_1280, .expected_output_index = 1, .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_CColorConvertDMO, - .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_EXPECT_SINK_ENUMERATED_TODO | LOADER_TODO, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_EXPECT_SINK_ENUMERATED, }, { /* H264 -> {DMO_RGB32, MF_RGB32} */ @@ -2776,28 +2776,28 @@ static void test_topology_loader(void) .decoded_type = &video_generic_yuv_1280, .expected_output_index = 1, .decoded_subtypes = {&MFVideoFormat_NV12, &MFVideoFormat_YUY2}, .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_CColorConvertDMO, - .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_TODO_OUT_TYPE | LOADER_EXPECT_SINK_ENUMERATED_TODO, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_TODO_OUT_TYPE | LOADER_EXPECT_SINK_ENUMERATED, }, { /* H264 -> {RGB24, RGB32} */ .input_types = {&video_h264_1280}, .output_types = {&video_video_processor_1280_rgb24, &video_video_processor_1280_rgb32}, .sink_method = -1, .source_method = -1, .decoded_type = &video_nv12_1280, .expected_output_index = 1, .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_CColorConvertDMO, - .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_TODO_OUT_TYPE | LOADER_EXPECT_SINK_ENUMERATED_TODO, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_TODO_OUT_TYPE | LOADER_EXPECT_SINK_ENUMERATED, }, { /* H264 -> {RGB24, RGB555} */ .input_types = {&video_h264_1280}, .output_types = {&video_video_processor_1280_rgb24, &video_video_processor_1280_rgb555}, .sink_method = -1, .source_method = -1, .decoded_type = &video_nv12_1280, .expected_output_index = 1, .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_CColorConvertDMO, - .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_TODO_OUT_TYPE | LOADER_EXPECT_SINK_ENUMERATED_TODO, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_TODO_OUT_TYPE | LOADER_EXPECT_SINK_ENUMERATED, }, { /* H264 -> {RGB555, RGB24} */ .input_types = {&video_h264_1280}, .output_types = {&video_video_processor_1280_rgb555, &video_video_processor_1280_rgb24}, .sink_method = -1, .source_method = -1, .decoded_type = &video_nv12_1280, .expected_output_index = 1, .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_CColorConvertDMO, - .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_TODO_OUT_TYPE | LOADER_EXPECT_SINK_ENUMERATED_TODO, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_TODO_OUT_TYPE | LOADER_EXPECT_SINK_ENUMERATED, }, { @@ -2805,7 +2805,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, .decoded_type = &video_nv12_1280, .expected_result = MF_E_TOPO_CODEC_NOT_FOUND, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_CColorConvertDMO, - .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_EXPECT_SINK_ENUMERATED_TODO, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_EXPECT_SINK_ENUMERATED, }, { @@ -2814,7 +2814,7 @@ static void test_topology_loader(void) .decoded_type = &video_generic_yuv_1280, .expected_output_index = 1, .decoded_subtypes = {&MFVideoFormat_NV12, &MFVideoFormat_YUY2}, .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_VideoProcessorMFT, - .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_SET_XVP_FOR_PLAYBACK | LOADER_EXPECT_SINK_ENUMERATED_TODO | LOADER_TODO, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_SET_XVP_FOR_PLAYBACK | LOADER_EXPECT_SINK_ENUMERATED, }, { /* H264 -> RGB32, resize, set XVP */ @@ -2829,21 +2829,21 @@ 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, + .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_INPUT_ENUMERATED, }, { /* H264 -> RGB32, Video Processor media type, add test MFT */ .input_types = {&video_h264_1280}, .output_types = {&video_video_processor_1280_rgb32}, .sink_method = -1, .source_method = -1, .mft_input_type = &video_video_processor_1280_rgb32, .mft_output_types = {&video_video_processor_1280_rgb32}, .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_CColorConvertDMO, - .flags = LOADER_ADD_TEST_MFT | LOADER_TEST_MFT_EXPECT_CONVERTER | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO, + .flags = LOADER_ADD_TEST_MFT | LOADER_TEST_MFT_EXPECT_CONVERTER | LOADER_EXPECT_MFT_INPUT_ENUMERATED, }, { /* H264 -> NV12, add test MFT */ .input_types = {&video_h264_1280}, .output_types = {&video_nv12_1280}, .sink_method = -1, .source_method = -1, .mft_input_type = &video_nv12_1280, .mft_output_types = {&video_nv12_1280}, .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, - .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO, + .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_INPUT_ENUMERATED, }, }; @@ -3287,13 +3287,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)); } diff --git a/dlls/mf/topology_loader.c b/dlls/mf/topology_loader.c index fef4446a298..e499d84d4aa 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -329,6 +329,7 @@ struct connection_context MF_TOPOLOGY_TYPE up_node_type; struct connection_context_type_enumerator up_types; struct connection_context_type_enumerator down_types; + BOOL enable_xvp; BOOL is_video; }; @@ -353,6 +354,8 @@ static HRESULT connection_context_init(struct connection_context *context, IMFTo if (FAILED(hr = topology_node_get_type_handler(branch->down.node, branch->down.stream, FALSE, &context->down_types.handler))) goto failed; + IMFTopology_GetUINT32(topology, &MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK, (UINT32 *)&context->enable_xvp); + enumerate_source_types = context->up_node_type == MF_TOPOLOGY_SOURCESTREAM_NODE && enumerate_source_types; if (!(context->up_types.enumerate = enumerate_source_types)) { @@ -423,10 +426,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_mask, struct topology_branch *branch, IMFMediaType *up_type, struct connection_context *context); -static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNECT_METHOD method_mask, +static HRESULT topology_branch_connect_indirect(IMFTopology *topology, struct topology_branch *branch, BOOL enumerate, 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; @@ -435,7 +437,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_subtype(up_type), debugstr_media_subtype(down_type)); if (FAILED(hr = IMFMediaType_GetMajorType(up_type, &input_info.guidMajorType))) @@ -453,23 +455,17 @@ 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); - method_mask = MF_CONNECT_ALLOW_CONVERTER; - } + IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_DECODER, 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) @@ -477,7 +473,7 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC struct topology_branch down_branch = {.up.node = node, .down = branch->down}; struct topology_branch up_branch = {.up = branch->up, .down.node = node}; struct connection_context up_context = {0}; - 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))) @@ -577,7 +573,7 @@ HRESULT topology_node_init_media_type(IMFTopologyNode *node, DWORD stream, BOOL } static HRESULT create_transform_node(const GUID *class_id, IMFTopologyNode **node_out, - IMFTransform **transform_out) + IMFTransform **transform_out, BOOL set_id) { IMFTopologyNode *node = NULL; IMFTransform *transform; @@ -587,7 +583,7 @@ static HRESULT create_transform_node(const GUID *class_id, IMFTopologyNode **nod return hr; if (FAILED(hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node)) - || FAILED(hr = IMFTopologyNode_SetGUID(node, &MF_TOPONODE_TRANSFORM_OBJECTID, class_id)) + || (set_id && FAILED(hr = IMFTopologyNode_SetGUID(node, &MF_TOPONODE_TRANSFORM_OBJECTID, class_id))) || FAILED(hr = IMFTopologyNode_SetObject(node, (IUnknown *)transform))) goto failed; @@ -617,10 +613,25 @@ static HRESULT topology_branch_connect_converter_with_types(IMFTopology *topolog TRACE("branch %s, up_type %s, down_type %s.\n", debugstr_topology_branch(branch), debugstr_media_subtype(up_type), debugstr_media_subtype(down_type)); - /* Changing the resampler GUID in Windows regedit does not prevent a CResamplerMediaObject - * being used, implying that MFTEnumEx() is not called for resamplers. */ - if (FAILED(hr = create_transform_node(&CLSID_CResamplerMediaObject, &node, &transform))) - return hr; + if (!context->is_video) + { + /* Changing the resampler GUID in Windows regedit does not prevent a CResamplerMediaObject + * being used, implying that MFTEnumEx() is not called for resamplers. */ + if (FAILED(hr = create_transform_node(&CLSID_CResamplerMediaObject, &node, &transform, TRUE))) + return hr; + } + else + { + /* 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 (context->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; + } if (FAILED(hr = IMFTransform_SetInputType(transform, 0, up_type, 0)) || FAILED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(up_handler, up_type, NULL))) @@ -697,13 +708,17 @@ static HRESULT topology_branch_connect_converter(IMFTopology *topology, { IMFMediaType *up_type, *down_type; HRESULT hr; - GUID subtype; - if (FAILED(hr = IMFMediaType_GetGUID(context->up_types.index0, &MF_MT_SUBTYPE, &subtype))) - return hr; + if (!context->is_video) + { + GUID subtype; - if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float)) - return MF_E_TOPO_CODEC_NOT_FOUND; + if (FAILED(hr = IMFMediaType_GetGUID(context->up_types.index0, &MF_MT_SUBTYPE, &subtype))) + return hr; + + if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float)) + return MF_E_TOPO_CODEC_NOT_FOUND; + } connection_context_init_down_type_enumeration(context); @@ -764,17 +779,10 @@ static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_ME down_type = context->down_types.current ? context->down_types.current : context->down_types.index0; if (FAILED(hr) && (method & method_mask & MF_CONNECT_ALLOW_CONVERTER) == MF_CONNECT_ALLOW_CONVERTER) - { - if (context->is_video) - hr = topology_branch_connect_indirect(topology, MF_CONNECT_ALLOW_CONVERTER, - branch, context->up_types.enumerate, up_type, down_type); - else - hr = topology_branch_connect_converter(topology, branch, context); - } + hr = topology_branch_connect_converter(topology, branch, context); if (FAILED(hr) && (method & method_mask & MF_CONNECT_ALLOW_DECODER) == MF_CONNECT_ALLOW_DECODER) - hr = topology_branch_connect_indirect(topology, MF_CONNECT_ALLOW_DECODER, - branch, context->up_types.enumerate, up_type, down_type); + hr = topology_branch_connect_indirect(topology, branch, context->up_types.enumerate, up_type, down_type); done: return hr; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10009