[PATCH 0/7] MR10585: mf/topology_loader: Always try setting current up type when connecting directly.
And misc refactoring in preparation for further fixes for !10009. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10585
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/mf/tests/topology.c | 1 - dlls/mf/topology_loader.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/mf/tests/topology.c b/dlls/mf/tests/topology.c index 63a8192aca3..fec264cb861 100644 --- a/dlls/mf/tests/topology.c +++ b/dlls/mf/tests/topology.c @@ -3427,7 +3427,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 05f999fcaec..72bc2cfd8bb 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -360,6 +360,7 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC hr = IMFTopology_AddNode(topology, node); if (SUCCEEDED(hr)) break; + IMFTopologyNode_DisconnectOutput(branch->up.node, branch->up.stream); } IMFTopologyNode_Release(node); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10585
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/mf/tests/topology.c | 5 ++--- dlls/mf/topology_loader.c | 8 +++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dlls/mf/tests/topology.c b/dlls/mf/tests/topology.c index fec264cb861..40253beed94 100644 --- a/dlls/mf/tests/topology.c +++ b/dlls/mf/tests/topology.c @@ -2605,7 +2605,6 @@ static void test_topology_loader(void) .input_types = {&audio_mp3_44100}, .output_types = {&audio_pcm_44100}, .sink_method = MF_CONNECT_ALLOW_CONVERTER, .source_method = -1, .current_input = &audio_mp3_44100, .expected_result = MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION, - .flags = LOADER_TODO, }, { /* MP3 -> PCM */ @@ -2699,7 +2698,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 +2829,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 */ diff --git a/dlls/mf/topology_loader.c b/dlls/mf/topology_loader.c index 72bc2cfd8bb..44e7cf8170d 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -320,7 +320,7 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC if (FAILED(hr = MFTEnumEx(category, MFT_ENUM_FLAG_ALL, &input_info, decoder ? NULL : &output_info, &activates, &count))) return hr; - for (i = 0, hr = MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION; i < count; ++i) + for (i = 0; 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}; @@ -368,8 +368,10 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC IMFActivate_Release(activates[i]); CoTaskMemFree(activates); - if (!count) - return MF_E_TOPO_CODEC_NOT_FOUND; + if (!count || FAILED(hr)) + hr = decoder ? MF_E_TOPO_CODEC_NOT_FOUND + : MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION; + TRACE("returning %#lx\n", hr); return hr; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10585
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/mf/topology_loader.c | 58 ++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/dlls/mf/topology_loader.c b/dlls/mf/topology_loader.c index 44e7cf8170d..5344c10fc00 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -175,6 +175,19 @@ static void topology_branch_destroy(struct topology_branch *branch) free(branch); } +static HRESULT topology_branch_create_indirect(struct topology_branch *branch, + IMFTopologyNode *node, struct topology_branch **up, struct topology_branch **down) +{ + HRESULT hr; + + if (FAILED(hr = topology_branch_create(branch->up.node, branch->up.stream, node, 0, up))) + return hr; + if (FAILED(hr = topology_branch_create(node, 0, branch->down.node, branch->down.stream, down))) + topology_branch_destroy(*up); + + return hr; +} + static HRESULT topology_branch_clone_nodes(struct topoloader_context *context, struct topology_branch *branch) { IMFTopologyNode *up, *down; @@ -322,8 +335,7 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC for (i = 0; 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}; + struct topology_branch *up_branch, *down_branch; MF_CONNECT_METHOD method = method_mask; IMFMediaType *media_type; @@ -335,27 +347,35 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC if (SUCCEEDED(IMFActivate_GetGUID(activates[i], &MFT_TRANSFORM_CLSID_Attribute, &guid))) IMFTopologyNode_SetGUID(node, &MF_TOPONODE_TRANSFORM_OBJECTID, &guid); - hr = topology_branch_connect_down(topology, MF_CONNECT_DIRECT, &up_branch, up_type); - if (down_type && SUCCEEDED(MFCreateMediaType(&media_type))) + if (SUCCEEDED(hr = topology_branch_create_indirect(branch, node, &up_branch, &down_branch))) { - if (SUCCEEDED(IMFMediaType_CopyAllItems(down_type, (IMFAttributes *)media_type)) - && SUCCEEDED(update_media_type_from_upstream(media_type, up_type)) - && SUCCEEDED(IMFTransform_SetOutputType(transform, 0, media_type, 0))) - method = MF_CONNECT_DIRECT; - IMFMediaType_Release(media_type); - } - IMFTransform_Release(transform); + if (SUCCEEDED(hr = topology_branch_connect_down(topology, MF_CONNECT_DIRECT, up_branch, up_type))) + { + if (down_type && SUCCEEDED(MFCreateMediaType(&media_type))) + { + if (SUCCEEDED(IMFMediaType_CopyAllItems(down_type, (IMFAttributes *)media_type)) + && SUCCEEDED(update_media_type_from_upstream(media_type, up_type)) + && SUCCEEDED(IMFTransform_SetOutputType(transform, 0, media_type, 0))) + method = MF_CONNECT_DIRECT; + IMFMediaType_Release(media_type); + } - if (SUCCEEDED(hr) && method != MF_CONNECT_DIRECT - && SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type))) - { - if (SUCCEEDED(update_media_type_from_upstream(media_type, up_type))) - IMFTransform_SetOutputType(transform, 0, media_type, 0); - IMFMediaType_Release(media_type); + if (method != MF_CONNECT_DIRECT + && SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type))) + { + if (SUCCEEDED(update_media_type_from_upstream(media_type, up_type))) + IMFTransform_SetOutputType(transform, 0, media_type, 0); + IMFMediaType_Release(media_type); + } + + hr = topology_branch_connect(topology, method, down_branch, !down_type); + } + topology_branch_destroy(down_branch); + topology_branch_destroy(up_branch); } - if (SUCCEEDED(hr)) - hr = topology_branch_connect(topology, method, &down_branch, !down_type); + IMFTransform_Release(transform); + if (SUCCEEDED(hr)) hr = IMFTopology_AddNode(topology, node); if (SUCCEEDED(hr)) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10585
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/mf/topology_loader.c | 59 ++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/dlls/mf/topology_loader.c b/dlls/mf/topology_loader.c index 5344c10fc00..ada72430487 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -127,6 +127,7 @@ struct topology_branch { IMFTopologyNode *node; DWORD stream; + IMFMediaTypeHandler *handler; } up, down; struct list entry; @@ -154,15 +155,31 @@ static const char *debugstr_topology_branch(struct topology_branch *branch) static HRESULT topology_branch_create(IMFTopologyNode *source, DWORD source_stream, IMFTopologyNode *sink, DWORD sink_stream, struct topology_branch **out) { + IMFMediaTypeHandler *source_handler, *sink_handler; struct topology_branch *branch; + HRESULT hr; + + if (FAILED(hr = topology_node_get_type_handler(source, source_stream, TRUE, &source_handler))) + return hr; + if (FAILED(hr = topology_node_get_type_handler(sink, sink_stream, FALSE, &sink_handler))) + { + IMFMediaTypeHandler_Release(source_handler); + return hr; + } if (!(branch = calloc(1, sizeof(*branch)))) + { + IMFMediaTypeHandler_Release(sink_handler); + IMFMediaTypeHandler_Release(source_handler); return E_OUTOFMEMORY; + } IMFTopologyNode_AddRef((branch->up.node = source)); branch->up.stream = source_stream; + branch->up.handler = source_handler; IMFTopologyNode_AddRef((branch->down.node = sink)); branch->down.stream = sink_stream; + branch->down.handler = sink_handler; *out = branch; return S_OK; @@ -171,7 +188,9 @@ static HRESULT topology_branch_create(IMFTopologyNode *source, DWORD source_stre static void topology_branch_destroy(struct topology_branch *branch) { IMFTopologyNode_Release(branch->up.node); + IMFMediaTypeHandler_Release(branch->up.handler); IMFTopologyNode_Release(branch->down.node); + IMFMediaTypeHandler_Release(branch->down.handler); free(branch); } @@ -341,11 +360,11 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC if (FAILED(IMFActivate_ActivateObject(activates[i], &IID_IMFTransform, (void **)&transform))) continue; - IMFTopologyNode_SetObject(node, (IUnknown *)transform); IMFTopologyNode_DeleteItem(node, &MF_TOPONODE_TRANSFORM_OBJECTID); if (SUCCEEDED(IMFActivate_GetGUID(activates[i], &MFT_TRANSFORM_CLSID_Attribute, &guid))) IMFTopologyNode_SetGUID(node, &MF_TOPONODE_TRANSFORM_OBJECTID, &guid); + IMFTransform_Release(transform); if (SUCCEEDED(hr = topology_branch_create_indirect(branch, node, &up_branch, &down_branch))) { @@ -355,16 +374,16 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC { if (SUCCEEDED(IMFMediaType_CopyAllItems(down_type, (IMFAttributes *)media_type)) && SUCCEEDED(update_media_type_from_upstream(media_type, up_type)) - && SUCCEEDED(IMFTransform_SetOutputType(transform, 0, media_type, 0))) + && SUCCEEDED(IMFMediaTypeHandler_SetCurrentMediaType(down_branch->up.handler, media_type))) method = MF_CONNECT_DIRECT; IMFMediaType_Release(media_type); } if (method != MF_CONNECT_DIRECT - && SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type))) + && SUCCEEDED(IMFMediaTypeHandler_GetMediaTypeByIndex(down_branch->up.handler, 0, &media_type))) { if (SUCCEEDED(update_media_type_from_upstream(media_type, up_type))) - IMFTransform_SetOutputType(transform, 0, media_type, 0); + IMFMediaTypeHandler_SetCurrentMediaType(down_branch->up.handler, media_type); IMFMediaType_Release(media_type); } @@ -374,8 +393,6 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC topology_branch_destroy(up_branch); } - IMFTransform_Release(transform); - if (SUCCEEDED(hr)) hr = IMFTopology_AddNode(topology, node); if (SUCCEEDED(hr)) @@ -437,7 +454,6 @@ HRESULT topology_node_init_media_type(IMFTopologyNode *node, DWORD stream, BOOL static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_METHOD method_mask, struct topology_branch *branch, IMFMediaType *up_type) { - IMFMediaTypeHandler *down_handler; IMFMediaType *down_type = NULL; UINT32 method; DWORD flags; @@ -449,10 +465,7 @@ static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_ME if (FAILED(IMFTopologyNode_GetUINT32(branch->down.node, &MF_TOPONODE_CONNECT_METHOD, &method))) method = MF_CONNECT_ALLOW_DECODER; - if (FAILED(hr = topology_node_get_type_handler(branch->down.node, branch->down.stream, FALSE, &down_handler))) - return hr; - - if (SUCCEEDED(hr = get_first_supported_media_type(down_handler, &down_type)) + if (SUCCEEDED(hr = get_first_supported_media_type(branch->down.handler, &down_type)) && IMFMediaType_IsEqual(up_type, down_type, &flags) == S_OK) { TRACE("Connecting branch %s with current type %s.\n", debugstr_topology_branch(branch), debugstr_media_type(up_type)); @@ -460,12 +473,12 @@ static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_ME goto done; } - if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(down_handler, up_type, NULL))) + if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(branch->down.handler, up_type, NULL))) { TRACE("Connected branch %s with upstream type %s.\n", debugstr_topology_branch(branch), debugstr_media_type(up_type)); if (topology_node_get_type(branch->down.node) == MF_TOPOLOGY_TRANSFORM_NODE - && FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(down_handler, up_type))) + && FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(branch->down.handler, up_type))) WARN("Failed to set transform node media type, hr %#lx\n", hr); hr = IMFTopologyNode_ConnectOutput(branch->up.node, branch->up.stream, branch->down.node, branch->down.stream); @@ -484,33 +497,25 @@ static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_ME done: if (down_type) IMFMediaType_Release(down_type); - IMFMediaTypeHandler_Release(down_handler); - return hr; } static HRESULT topology_branch_foreach_up_types(IMFTopology *topology, MF_CONNECT_METHOD method_mask, struct topology_branch *branch) { - IMFMediaTypeHandler *handler; IMFMediaType *type; DWORD index = 0; HRESULT hr; - if (FAILED(hr = topology_node_get_type_handler(branch->up.node, branch->up.stream, TRUE, &handler))) - return hr; - - while (SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, index++, &type))) + while (SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(branch->up.handler, index++, &type))) { hr = topology_branch_connect_down(topology, method_mask, branch, type); if (SUCCEEDED(hr)) - hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, type); + hr = IMFMediaTypeHandler_SetCurrentMediaType(branch->up.handler, type); IMFMediaType_Release(type); if (SUCCEEDED(hr)) break; } - - IMFMediaTypeHandler_Release(handler); return hr; } @@ -542,18 +547,14 @@ static HRESULT topology_branch_connect(IMFTopology *topology, MF_CONNECT_METHOD } else { - IMFMediaTypeHandler *up_handler; IMFMediaType *up_type; - if (FAILED(hr = topology_node_get_type_handler(branch->up.node, branch->up.stream, TRUE, &up_handler))) - return hr; - if (SUCCEEDED(hr = IMFMediaTypeHandler_GetCurrentMediaType(up_handler, &up_type)) - || SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(up_handler, 0, &up_type))) + if (SUCCEEDED(hr = IMFMediaTypeHandler_GetCurrentMediaType(branch->up.handler, &up_type)) + || SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(branch->up.handler, 0, &up_type))) { hr = topology_branch_connect_down(topology, method_mask, branch, up_type); IMFMediaType_Release(up_type); } - IMFMediaTypeHandler_Release(up_handler); } TRACE("returning %#lx\n", hr); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10585
From: Rémi Bernon <rbernon@codeweavers.com> And current down type for transforms. Based on patches from Conor McCarthy. --- dlls/mf/tests/topology.c | 14 ++++++-------- dlls/mf/topology_loader.c | 37 ++++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/dlls/mf/tests/topology.c b/dlls/mf/tests/topology.c index 40253beed94..7271359d29b 100644 --- a/dlls/mf/tests/topology.c +++ b/dlls/mf/tests/topology.c @@ -2265,7 +2265,6 @@ enum loader_test_flags LOADER_EXPECT_MFT_OUTPUT_ENUMERATED = 0x4000, LOADER_EXPECT_MFT_INPUT_ENUMERATED = 0x8000, LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO = 0x10000, - LOADER_TODO_MFT_IN_TYPE = 0x20000, LOADER_TODO_MFT_OUT_TYPE = 0x40000, }; @@ -2660,7 +2659,7 @@ static void test_topology_loader(void) .mft_output_types = {&audio_float_minimal, &audio_pcm_minimal, &audio_float_48000, &audio_pcm_48000}, .mft_current_output = &audio_pcm_minimal, .expected_result = MF_E_INVALIDMEDIATYPE, - .flags = LOADER_ADD_TEST_MFT | LOADER_TODO_MFT_IN_TYPE | LOADER_TODO_MFT_OUT_TYPE | LOADER_TODO, + .flags = LOADER_ADD_TEST_MFT | LOADER_TODO_MFT_OUT_TYPE | LOADER_TODO, }, { /* PCM -> PCM, different enumerated bps, add test MFT */ @@ -2675,7 +2674,7 @@ static void test_topology_loader(void) .mft_output_types = {&audio_float_minimal, &audio_pcm_minimal, &audio_float_48000, &audio_pcm_48000_resampler}, .mft_current_output = &audio_pcm_48000, .expected_result = S_OK, - .flags = LOADER_ADD_TEST_MFT | LOADER_TODO_MFT_IN_TYPE | LOADER_TODO_MFT_OUT_TYPE, + .flags = LOADER_ADD_TEST_MFT, }, { /* PCM -> PCM, different enumerated bps, add test MFT, configure MFT, no output types */ @@ -2683,7 +2682,7 @@ static void test_topology_loader(void) .mft_output_types = {&audio_float_minimal, &audio_pcm_minimal, &audio_float_48000, &audio_pcm_48000_resampler}, .mft_current_output = &audio_pcm_48000, .expected_result = S_OK, - .flags = LOADER_ADD_TEST_MFT | LOADER_NO_CURRENT_OUTPUT | LOADER_TODO_MFT_IN_TYPE | LOADER_TODO_MFT_OUT_TYPE, + .flags = LOADER_ADD_TEST_MFT | LOADER_NO_CURRENT_OUTPUT, }, { /* MP3 -> PCM, different enumerated bps, add test MFT, configure MFT */ @@ -2691,7 +2690,7 @@ static void test_topology_loader(void) .mft_input_type = &audio_pcm_44100, .mft_output_types = {&audio_pcm_48000}, .decoded_type = &audio_pcm_44100, .expected_result = S_OK, .decoder_class = CLSID_CMP3DecMediaObject, - .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO | LOADER_TODO_MFT_OUT_TYPE, + .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO, }, { /* MP3 -> PCM, different enumerated bps, add incompatible test MFT, configure MFT */ @@ -2836,14 +2835,14 @@ static void test_topology_loader(void) .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_TODO_MFT_OUT_TYPE | 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_TODO, }, { /* 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_TODO_MFT_OUT_TYPE | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO, + .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO, }, }; @@ -3383,7 +3382,6 @@ todo_wine { todo_wine_if(test_transform->output_enum_complete && (test->flags & LOADER_TODO)) ok(test_transform->output_enum_complete == !!(test->flags & LOADER_EXPECT_MFT_OUTPUT_ENUMERATED), "got transform output_enum_complete %u\n", test_transform->output_enum_complete); - todo_wine_if(test->flags & LOADER_TODO_MFT_IN_TYPE) ok(test_transform->input_type_set == (test->expected_result != MF_E_TOPO_CODEC_NOT_FOUND), "Got transform input_type_set %u.\n", test_transform->input_type_set); todo_wine_if(test->flags & LOADER_TODO_MFT_OUT_TYPE) diff --git a/dlls/mf/topology_loader.c b/dlls/mf/topology_loader.c index ada72430487..4836ada2d6b 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -297,6 +297,27 @@ static HRESULT update_media_type_from_upstream(IMFMediaType *media_type, IMFMedi return hr; } +static HRESULT topology_branch_connect_with_type(IMFTopology *topology, struct topology_branch *branch, IMFMediaType *type) +{ + HRESULT hr; + + if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(branch->up.handler, type))) + { + WARN("Failed to set upstream node media type, hr %#lx\n", hr); + return hr; + } + + if (topology_node_get_type(branch->down.node) == MF_TOPOLOGY_TRANSFORM_NODE + && FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(branch->down.handler, type))) + { + WARN("Failed to set transform node media type, hr %#lx\n", hr); + return hr; + } + + TRACE("Connecting branch %s with type %s.\n", debugstr_topology_branch(branch), debugstr_media_type(type)); + return IMFTopologyNode_ConnectOutput(branch->up.node, branch->up.stream, branch->down.node, branch->down.stream); +} + static HRESULT topology_branch_connect(IMFTopology *topology, MF_CONNECT_METHOD method_mask, struct topology_branch *branch, BOOL enumerate_source_types); static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_METHOD method_mask, @@ -368,7 +389,7 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC if (SUCCEEDED(hr = topology_branch_create_indirect(branch, node, &up_branch, &down_branch))) { - if (SUCCEEDED(hr = topology_branch_connect_down(topology, MF_CONNECT_DIRECT, up_branch, up_type))) + if (SUCCEEDED(hr = topology_branch_connect_with_type(topology, up_branch, up_type))) { if (down_type && SUCCEEDED(MFCreateMediaType(&media_type))) { @@ -468,21 +489,13 @@ static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_ME if (SUCCEEDED(hr = get_first_supported_media_type(branch->down.handler, &down_type)) && IMFMediaType_IsEqual(up_type, down_type, &flags) == S_OK) { - TRACE("Connecting branch %s with current type %s.\n", debugstr_topology_branch(branch), debugstr_media_type(up_type)); - hr = IMFTopologyNode_ConnectOutput(branch->up.node, branch->up.stream, branch->down.node, branch->down.stream); + hr = topology_branch_connect_with_type(topology, branch, up_type); goto done; } if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(branch->down.handler, up_type, NULL))) { - TRACE("Connected branch %s with upstream type %s.\n", debugstr_topology_branch(branch), debugstr_media_type(up_type)); - - if (topology_node_get_type(branch->down.node) == MF_TOPOLOGY_TRANSFORM_NODE - && FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(branch->down.handler, up_type))) - WARN("Failed to set transform node media type, hr %#lx\n", hr); - - hr = IMFTopologyNode_ConnectOutput(branch->up.node, branch->up.stream, branch->down.node, branch->down.stream); - + hr = topology_branch_connect_with_type(topology, branch, up_type); goto done; } @@ -510,8 +523,6 @@ static HRESULT topology_branch_foreach_up_types(IMFTopology *topology, MF_CONNEC while (SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(branch->up.handler, index++, &type))) { hr = topology_branch_connect_down(topology, method_mask, branch, type); - if (SUCCEEDED(hr)) - hr = IMFMediaTypeHandler_SetCurrentMediaType(branch->up.handler, type); IMFMediaType_Release(type); if (SUCCEEDED(hr)) break; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10585
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/mf/topology_loader.c | 108 ++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 44 deletions(-) diff --git a/dlls/mf/topology_loader.c b/dlls/mf/topology_loader.c index 4836ada2d6b..d7681c1a952 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -35,6 +35,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat); +enum connect_method +{ + CONNECT_DIRECT = 1, + CONNECT_CONVERTER = 2, + CONNECT_DECODER = 4, +}; + +static enum connect_method connect_method_from_mf(MF_CONNECT_METHOD mf_method) +{ + enum connect_method method = CONNECT_DIRECT; + if ((mf_method & MF_CONNECT_ALLOW_CONVERTER) == MF_CONNECT_ALLOW_CONVERTER) + method |= CONNECT_CONVERTER; + if ((mf_method & MF_CONNECT_ALLOW_DECODER) == MF_CONNECT_ALLOW_DECODER) + method |= CONNECT_DECODER; + return method; +} + struct topology_loader { IMFTopoLoader IMFTopoLoader_iface; @@ -318,14 +335,14 @@ static HRESULT topology_branch_connect_with_type(IMFTopology *topology, struct t return IMFTopologyNode_ConnectOutput(branch->up.node, branch->up.stream, branch->down.node, branch->down.stream); } -static HRESULT topology_branch_connect(IMFTopology *topology, MF_CONNECT_METHOD method_mask, +static HRESULT topology_branch_connect(IMFTopology *topology, enum connect_method method_mask, struct topology_branch *branch, BOOL enumerate_source_types); -static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_METHOD method_mask, +static HRESULT topology_branch_connect_down(IMFTopology *topology, enum connect_method method_mask, 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_indirect(IMFTopology *topology, BOOL decoder, struct topology_branch *branch, IMFMediaType *up_type, IMFMediaType *down_type) { - BOOL decoder = (method_mask & MF_CONNECT_ALLOW_DECODER) == MF_CONNECT_ALLOW_DECODER; + enum connect_method method_mask = CONNECT_DIRECT; MFT_REGISTER_TYPE_INFO input_info, output_info; IMFTransform *transform; IMFActivate **activates; @@ -334,7 +351,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, decoder %u, branch %s, up_type %s, down_type %s.\n", topology, decoder, debugstr_topology_branch(branch), debugstr_media_type(up_type), debugstr_media_type(down_type)); if (FAILED(hr = IMFMediaType_GetMajorType(up_type, &input_info.guidMajorType))) @@ -360,14 +377,12 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC if (FAILED(hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node))) return hr; - if (!decoder) - method_mask = MF_CONNECT_DIRECT; - else + if (decoder) { 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; + method_mask |= CONNECT_CONVERTER; } if (FAILED(hr = MFTEnumEx(category, MFT_ENUM_FLAG_ALL, &input_info, decoder ? NULL : &output_info, &activates, &count))) @@ -376,7 +391,7 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC for (i = 0; i < count; ++i) { struct topology_branch *up_branch, *down_branch; - MF_CONNECT_METHOD method = method_mask; + enum connect_method method = method_mask; IMFMediaType *media_type; if (FAILED(IMFActivate_ActivateObject(activates[i], &IID_IMFTransform, (void **)&transform))) @@ -396,11 +411,11 @@ static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNEC if (SUCCEEDED(IMFMediaType_CopyAllItems(down_type, (IMFAttributes *)media_type)) && SUCCEEDED(update_media_type_from_upstream(media_type, up_type)) && SUCCEEDED(IMFMediaTypeHandler_SetCurrentMediaType(down_branch->up.handler, media_type))) - method = MF_CONNECT_DIRECT; + method = CONNECT_DIRECT; IMFMediaType_Release(media_type); } - if (method != MF_CONNECT_DIRECT + if (method != CONNECT_DIRECT && SUCCEEDED(IMFMediaTypeHandler_GetMediaTypeByIndex(down_branch->up.handler, 0, &media_type))) { if (SUCCEEDED(update_media_type_from_upstream(media_type, up_type))) @@ -472,40 +487,43 @@ HRESULT topology_node_init_media_type(IMFTopologyNode *node, DWORD stream, BOOL return hr; } -static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_METHOD method_mask, +static HRESULT topology_branch_connect_down(IMFTopology *topology, enum connect_method method_mask, struct topology_branch *branch, IMFMediaType *up_type) { + HRESULT hr = MF_E_INVALIDMEDIATYPE; IMFMediaType *down_type = NULL; - UINT32 method; + enum connect_method method; + UINT32 value; DWORD flags; - HRESULT hr; TRACE("topology %p, method_mask %#x, branch %s, up_type %s.\n", topology, method_mask, debugstr_topology_branch(branch), debugstr_media_type(up_type)); - if (FAILED(IMFTopologyNode_GetUINT32(branch->down.node, &MF_TOPONODE_CONNECT_METHOD, &method))) - method = MF_CONNECT_ALLOW_DECODER; + if (FAILED(IMFTopologyNode_GetUINT32(branch->down.node, &MF_TOPONODE_CONNECT_METHOD, &value))) + value = MF_CONNECT_ALLOW_DECODER; + method = connect_method_from_mf(value) & method_mask; - if (SUCCEEDED(hr = get_first_supported_media_type(branch->down.handler, &down_type)) - && IMFMediaType_IsEqual(up_type, down_type, &flags) == S_OK) - { - hr = topology_branch_connect_with_type(topology, branch, up_type); - goto done; - } + get_first_supported_media_type(branch->down.handler, &down_type); - if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(branch->down.handler, up_type, NULL))) + if (method & CONNECT_DIRECT) { - hr = topology_branch_connect_with_type(topology, branch, up_type); - goto done; - } + if (down_type && IMFMediaType_IsEqual(up_type, down_type, &flags) == S_OK) + { + hr = topology_branch_connect_with_type(topology, branch, up_type); + goto done; + } - if (FAILED(hr) && (method & method_mask & MF_CONNECT_ALLOW_CONVERTER) == MF_CONNECT_ALLOW_CONVERTER) - hr = topology_branch_connect_indirect(topology, MF_CONNECT_ALLOW_CONVERTER, - branch, up_type, down_type); + if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(branch->down.handler, up_type, NULL))) + { + hr = topology_branch_connect_with_type(topology, branch, up_type); + goto done; + } + } - 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, up_type, down_type); + if (FAILED(hr) && (method & CONNECT_CONVERTER)) + hr = topology_branch_connect_indirect(topology, FALSE, branch, up_type, down_type); + if (FAILED(hr) && (method & CONNECT_DECODER)) + hr = topology_branch_connect_indirect(topology, TRUE, branch, up_type, down_type); done: if (down_type) @@ -513,7 +531,7 @@ done: return hr; } -static HRESULT topology_branch_foreach_up_types(IMFTopology *topology, MF_CONNECT_METHOD method_mask, +static HRESULT topology_branch_foreach_up_types(IMFTopology *topology, enum connect_method method_mask, struct topology_branch *branch) { IMFMediaType *type; @@ -530,10 +548,10 @@ static HRESULT topology_branch_foreach_up_types(IMFTopology *topology, MF_CONNEC return hr; } -static HRESULT topology_branch_connect(IMFTopology *topology, MF_CONNECT_METHOD method_mask, +static HRESULT topology_branch_connect(IMFTopology *topology, enum connect_method method_mask, struct topology_branch *branch, BOOL enumerate_source_types) { - HRESULT hr; + HRESULT hr = MF_E_INVALIDMEDIATYPE; TRACE("topology %p, method_mask %#x, branch %s.\n", topology, method_mask, debugstr_topology_branch(branch)); @@ -546,14 +564,15 @@ static HRESULT topology_branch_connect(IMFTopology *topology, MF_CONNECT_METHOD method = MF_CONNECT_DIRECT; if (method & MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES) - hr = topology_branch_foreach_up_types(topology, method_mask & MF_CONNECT_ALLOW_DECODER, branch); + hr = topology_branch_foreach_up_types(topology, method_mask, branch); else { - hr = topology_branch_foreach_up_types(topology, method_mask & MF_CONNECT_DIRECT, branch); - if (FAILED(hr)) - hr = topology_branch_foreach_up_types(topology, method_mask & MF_CONNECT_ALLOW_CONVERTER, branch); - if (FAILED(hr)) - hr = topology_branch_foreach_up_types(topology, method_mask & MF_CONNECT_ALLOW_DECODER, branch); + if (FAILED(hr) && (method_mask & CONNECT_DIRECT)) + hr = topology_branch_foreach_up_types(topology, CONNECT_DIRECT, branch); + if (FAILED(hr) && (method_mask & CONNECT_CONVERTER)) + hr = topology_branch_foreach_up_types(topology, CONNECT_CONVERTER, branch); + if (FAILED(hr) && (method_mask & CONNECT_DECODER)) + hr = topology_branch_foreach_up_types(topology, CONNECT_DECODER, branch); } } else @@ -575,6 +594,7 @@ static HRESULT topology_branch_connect(IMFTopology *topology, MF_CONNECT_METHOD static HRESULT topology_loader_resolve_branches(struct topoloader_context *context, struct list *branches, BOOL enumerate_source_types) { + enum connect_method method_mask = connect_method_from_mf(MF_CONNECT_ALLOW_DECODER); struct topology_branch *branch, *next; HRESULT hr = S_OK; @@ -586,9 +606,9 @@ static HRESULT topology_loader_resolve_branches(struct topoloader_context *conte WARN("Failed to clone nodes for branch %s\n", debugstr_topology_branch(branch)); else { - hr = topology_branch_connect(context->output_topology, MF_CONNECT_ALLOW_DECODER, branch, enumerate_source_types); + hr = topology_branch_connect(context->output_topology, method_mask, branch, enumerate_source_types); if (hr == MF_E_INVALIDMEDIATYPE && !enumerate_source_types && topology_node_get_type(branch->up.node) == MF_TOPOLOGY_TRANSFORM_NODE) - hr = topology_branch_connect(context->output_topology, MF_CONNECT_ALLOW_DECODER, branch, TRUE); + hr = topology_branch_connect(context->output_topology, method_mask, branch, TRUE); } topology_branch_destroy(branch); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10585
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/mf/topology_loader.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/dlls/mf/topology_loader.c b/dlls/mf/topology_loader.c index d7681c1a952..6709675673f 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -487,21 +487,15 @@ HRESULT topology_node_init_media_type(IMFTopologyNode *node, DWORD stream, BOOL return hr; } -static HRESULT topology_branch_connect_down(IMFTopology *topology, enum connect_method method_mask, +static HRESULT topology_branch_connect_down(IMFTopology *topology, enum connect_method method, struct topology_branch *branch, IMFMediaType *up_type) { HRESULT hr = MF_E_INVALIDMEDIATYPE; IMFMediaType *down_type = NULL; - enum connect_method method; - UINT32 value; DWORD flags; - TRACE("topology %p, method_mask %#x, branch %s, up_type %s.\n", - topology, method_mask, debugstr_topology_branch(branch), debugstr_media_type(up_type)); - - if (FAILED(IMFTopologyNode_GetUINT32(branch->down.node, &MF_TOPONODE_CONNECT_METHOD, &value))) - value = MF_CONNECT_ALLOW_DECODER; - method = connect_method_from_mf(value) & method_mask; + TRACE("topology %p, method %#x, branch %s, up_type %s.\n", topology, method, + debugstr_topology_branch(branch), debugstr_media_type(up_type)); get_first_supported_media_type(branch->down.handler, &down_type); @@ -552,26 +546,29 @@ static HRESULT topology_branch_connect(IMFTopology *topology, enum connect_metho struct topology_branch *branch, BOOL enumerate_source_types) { HRESULT hr = MF_E_INVALIDMEDIATYPE; + UINT32 up_method, down_method; TRACE("topology %p, method_mask %#x, branch %s.\n", topology, method_mask, debugstr_topology_branch(branch)); + if (FAILED(IMFTopologyNode_GetUINT32(branch->down.node, &MF_TOPONODE_CONNECT_METHOD, &down_method))) + down_method = MF_CONNECT_ALLOW_DECODER; + down_method = connect_method_from_mf(down_method) & method_mask; + if (enumerate_source_types) { - UINT32 method; - if (topology_node_get_type(branch->up.node) != MF_TOPOLOGY_SOURCESTREAM_NODE - || FAILED(IMFTopologyNode_GetUINT32(branch->up.node, &MF_TOPONODE_CONNECT_METHOD, &method))) - method = MF_CONNECT_DIRECT; + || FAILED(IMFTopologyNode_GetUINT32(branch->up.node, &MF_TOPONODE_CONNECT_METHOD, &up_method))) + up_method = MF_CONNECT_DIRECT; - if (method & MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES) - hr = topology_branch_foreach_up_types(topology, method_mask, branch); + if (up_method & MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES) + hr = topology_branch_foreach_up_types(topology, down_method, branch); else { - if (FAILED(hr) && (method_mask & CONNECT_DIRECT)) + if (FAILED(hr) && (down_method & CONNECT_DIRECT)) hr = topology_branch_foreach_up_types(topology, CONNECT_DIRECT, branch); - if (FAILED(hr) && (method_mask & CONNECT_CONVERTER)) + if (FAILED(hr) && (down_method & CONNECT_CONVERTER)) hr = topology_branch_foreach_up_types(topology, CONNECT_CONVERTER, branch); - if (FAILED(hr) && (method_mask & CONNECT_DECODER)) + if (FAILED(hr) && (down_method & CONNECT_DECODER)) hr = topology_branch_foreach_up_types(topology, CONNECT_DECODER, branch); } } @@ -582,7 +579,7 @@ static HRESULT topology_branch_connect(IMFTopology *topology, enum connect_metho if (SUCCEEDED(hr = IMFMediaTypeHandler_GetCurrentMediaType(branch->up.handler, &up_type)) || SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(branch->up.handler, 0, &up_type))) { - hr = topology_branch_connect_down(topology, method_mask, branch, up_type); + hr = topology_branch_connect_down(topology, down_method, branch, up_type); IMFMediaType_Release(up_type); } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10585
This merge request was approved by Rémi Bernon. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10585
I don't think the test failures are related, it fails before running anything MF related and I can't reproduce them locally. It looks more like some modesetting race condition that I hadn't see for a while, but that maybe came back because of the many MRs running concurrently? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10585#note_135284
participants (3)
-
Conor McCarthy -
Rémi Bernon -
Rémi Bernon (@rbernon)