From: Conor McCarthy <cmccarthy@codeweavers.com> The todo_wine on test line 2712 is for a sink with zero supported media types, not valid on recent Windows versions. --- dlls/mf/tests/mf.c | 2 +- dlls/mf/tests/topology.c | 14 ++++----- dlls/mf/topology_loader.c | 61 ++++++++++++++++++++++----------------- 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index d3e191d8721..68fe4743efe 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2635,7 +2635,6 @@ static void test_media_session_events(void) ok(propvar.punkVal != (IUnknown *)topology, "got punkVal %p\n", propvar.punkVal); PropVariantClear(&propvar); - todo_wine ok(!handler->enum_count, "got %lu GetMediaTypeByIndex\n", handler->enum_count); ok(handler->set_current_count, "got %lu SetCurrentMediaType\n", handler->set_current_count); handler->enum_count = handler->set_current_count = 0; @@ -2709,6 +2708,7 @@ static void test_media_session_events(void) ok(propvar.punkVal != (IUnknown *)topology, "got punkVal %p\n", propvar.punkVal); PropVariantClear(&propvar); + todo_wine ok(!handler->enum_count, "got %lu GetMediaTypeByIndex\n", handler->enum_count); ok(handler->set_current_count, "got %lu SetCurrentMediaType\n", handler->set_current_count); handler->enum_count = handler->set_current_count = 0; diff --git a/dlls/mf/tests/topology.c b/dlls/mf/tests/topology.c index 52a95e2d973..a1fcff28e33 100644 --- a/dlls/mf/tests/topology.c +++ b/dlls/mf/tests/topology.c @@ -2486,7 +2486,6 @@ static void test_topology_loader(void) .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_44100}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .current_input = &audio_pcm_44100_incomplete, .expected_result = MF_E_INVALIDMEDIATYPE, - .flags = LOADER_TODO, }, { /* PCM -> PCM, same enumerated bps, different current bps */ @@ -2513,7 +2512,7 @@ static void test_topology_loader(void) .input_types = {&audio_pcm_44100_incomplete}, .output_types = {&audio_pcm_44100}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .current_input = &audio_pcm_44100, .expected_result = MF_E_NO_MORE_TYPES, - .flags = LOADER_SET_ENUMERATE_SOURCE_TYPES | LOADER_TODO, + .flags = LOADER_SET_ENUMERATE_SOURCE_TYPES, }, { @@ -2661,7 +2660,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, + .flags = LOADER_ADD_TEST_MFT, }, { /* PCM -> PCM, different enumerated bps, add test MFT */ @@ -2676,7 +2675,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, + .flags = LOADER_ADD_TEST_MFT, }, { /* PCM -> PCM, different enumerated bps, add test MFT, configure MFT, no output types */ @@ -2684,7 +2683,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, + .flags = LOADER_ADD_TEST_MFT | LOADER_NO_CURRENT_OUTPUT, }, { /* MP3 -> PCM, different enumerated bps, add test MFT, configure MFT */ @@ -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 */ @@ -3417,7 +3416,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 3b20b5b7cb9..ce7ef64e228 100644 --- a/dlls/mf/topology_loader.c +++ b/dlls/mf/topology_loader.c @@ -326,11 +326,13 @@ struct connection_context { MF_TOPOLOGY_TYPE up_node_type; struct connection_context_type_enumerator up_types; + struct connection_context_type_enumerator down_types; }; static void connection_context_destroy(struct connection_context *context) { type_enumerator_release(&context->up_types); + type_enumerator_release(&context->down_types); } static HRESULT connection_context_init(struct connection_context *context, IMFTopology *topology, @@ -344,6 +346,8 @@ static HRESULT connection_context_init(struct connection_context *context, IMFTo if (FAILED(hr = topology_node_get_type_handler(branch->up.node, branch->up.stream, TRUE, &context->up_types.handler))) return hr; + if (FAILED(hr = topology_node_get_type_handler(branch->down.node, branch->down.stream, FALSE, &context->down_types.handler))) + goto failed; enumerate_source_types = context->up_node_type == MF_TOPOLOGY_SOURCESTREAM_NODE && enumerate_source_types; if (!(context->up_types.enumerate = enumerate_source_types)) @@ -357,6 +361,9 @@ static HRESULT connection_context_init(struct connection_context *context, IMFTo goto failed; context->up_types.index0 = up_type; + hr = IMFMediaTypeHandler_GetCurrentMediaType(context->down_types.handler, &context->down_types.current); + context->down_types.enumerate = (hr == MF_E_NOT_INITIALIZED || hr == MF_E_TRANSFORM_TYPE_NOT_SET); + return S_OK; failed: @@ -364,12 +371,19 @@ failed: return hr; } +static void connection_context_init_down_type_enumeration(struct connection_context *context) +{ + /* Types are fetched by index only if GetCurrentMediaType() returned MF_E_NOT_INITIALIZED or MF_E_TRANSFORM_TYPE_NOT_SET. */ + if (context->down_types.enumerate && !context->down_types.index0) + IMFMediaTypeHandler_GetMediaTypeByIndex(context->down_types.handler, 0, &context->down_types.index0); +} + 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, - struct topology_branch *branch, IMFMediaType *up_type); + struct topology_branch *branch, IMFMediaType *up_type, struct connection_context *context); static HRESULT topology_branch_connect_indirect(IMFTopology *topology, MF_CONNECT_METHOD method_mask, - struct topology_branch *branch, IMFMediaType *up_type, IMFMediaType *down_type) + 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; @@ -421,6 +435,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; IMFMediaType *media_type; @@ -432,7 +447,14 @@ 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 (FAILED(hr = connection_context_init(&up_context, topology, &up_branch, MF_CONNECT_DIRECT, enumerate))) + { + IMFTransform_Release(transform); + continue; + } + + hr = topology_branch_connect_down(topology, MF_CONNECT_DIRECT, &up_branch, up_type, &up_context); + connection_context_destroy(&up_context); if (down_type && SUCCEEDED(MFCreateMediaType(&media_type))) { if (SUCCEEDED(IMFMediaType_CopyAllItems(down_type, (IMFAttributes *)media_type)) @@ -509,13 +531,12 @@ 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) + struct topology_branch *branch, IMFMediaType *up_type, struct connection_context *context) { - IMFMediaTypeHandler *down_handler; - IMFMediaType *down_type = NULL; + IMFMediaTypeHandler *down_handler = context->down_types.handler; + IMFMediaType *down_type; MF_TOPOLOGY_TYPE type; UINT32 method; - DWORD flags; HRESULT hr; TRACE("topology %p, method_mask %#x, branch %s, up_type %s.\n", @@ -524,17 +545,6 @@ 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)) - && IMFMediaType_IsEqual(up_type, down_type, &flags) == S_OK) - { - TRACE("Connecting branch %s with current type %s.\n", debugstr_topology_branch(branch), debugstr_media_subtype(up_type)); - hr = IMFTopologyNode_ConnectOutput(branch->up.node, branch->up.stream, branch->down.node, branch->down.stream); - goto done; - } - if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(down_handler, up_type, NULL))) { TRACE("Connected branch %s with upstream type %s.\n", debugstr_topology_branch(branch), debugstr_media_subtype(up_type)); @@ -548,19 +558,18 @@ static HRESULT topology_branch_connect_down(IMFTopology *topology, MF_CONNECT_ME goto done; } + connection_context_init_down_type_enumeration(context); + 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) hr = topology_branch_connect_indirect(topology, MF_CONNECT_ALLOW_CONVERTER, - branch, up_type, down_type); + branch, context->up_types.enumerate, up_type, down_type); 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); + branch, context->up_types.enumerate, up_type, down_type); done: - if (down_type) - IMFMediaType_Release(down_type); - IMFMediaTypeHandler_Release(down_handler); - return hr; } @@ -574,7 +583,7 @@ static HRESULT topology_branch_foreach_up_types(IMFTopology *topology, MF_CONNEC while (SUCCEEDED(hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, index++, &type))) { - hr = topology_branch_connect_down(topology, method_mask, branch, type); + hr = topology_branch_connect_down(topology, method_mask, branch, type, context); if (SUCCEEDED(hr)) hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, type); IMFMediaType_Release(type); @@ -620,7 +629,7 @@ static HRESULT topology_branch_connect(IMFTopology *topology, MF_CONNECT_METHOD type_enumerator_reset(&context.up_types); while (SUCCEEDED(type_enumerator_get_next_media_type(&context.up_types, &up_type))) { - hr = topology_branch_connect_down(topology, method_mask, branch, up_type); + hr = topology_branch_connect_down(topology, method_mask, branch, up_type, &context); /* Upstream type is left unset only for an unenumerated media source. */ if (SUCCEEDED(hr) && context.up_node_type != MF_TOPOLOGY_SOURCESTREAM_NODE) hr = IMFMediaTypeHandler_SetCurrentMediaType(context.up_types.handler, up_type); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10009