[PATCH 0/6] MR9947: mf/tests: Add more topology loader tests.
The first three commits are from !9935 which this goes atop, otherwise it will crash. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9947
From: Conor McCarthy <cmccarthy@codeweavers.com> The audio resampler does not implement this behaviour. --- dlls/winegstreamer/resampler.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/dlls/winegstreamer/resampler.c b/dlls/winegstreamer/resampler.c index 910d109c2c6..2b79a613baa 100644 --- a/dlls/winegstreamer/resampler.c +++ b/dlls/winegstreamer/resampler.c @@ -374,12 +374,6 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM if (!impl->input_type && FAILED(hr = MFCreateMediaType(&impl->input_type))) return hr; - if (impl->output_type) - { - IMFMediaType_Release(impl->output_type); - impl->output_type = NULL; - } - if (SUCCEEDED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *)impl->input_type))) impl->input_info.cbSize = block_alignment; else -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9947
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/winegstreamer/resampler.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/dlls/winegstreamer/resampler.c b/dlls/winegstreamer/resampler.c index 2b79a613baa..e861c86f737 100644 --- a/dlls/winegstreamer/resampler.c +++ b/dlls/winegstreamer/resampler.c @@ -327,6 +327,9 @@ static HRESULT check_media_type(IMFMediaType *type) HRESULT hr; ULONG i; + if (!type) + return S_OK; + if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major)) || FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) return MF_E_ATTRIBUTENOTFOUND; @@ -366,11 +369,21 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM if (FAILED(hr = check_media_type(type))) return hr; - if (FAILED(hr = IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_alignment))) + if (type && FAILED(hr = IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_alignment))) return MF_E_INVALIDMEDIATYPE; if (flags & MFT_SET_TYPE_TEST_ONLY) return S_OK; + if (!type) + { + if (impl->input_type) + { + IMFMediaType_Release(impl->input_type); + impl->input_type = NULL; + } + return S_OK; + } + if (!impl->input_type && FAILED(hr = MFCreateMediaType(&impl->input_type))) return hr; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9947
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/winegstreamer/resampler.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dlls/winegstreamer/resampler.c b/dlls/winegstreamer/resampler.c index e861c86f737..fcaadac17e0 100644 --- a/dlls/winegstreamer/resampler.c +++ b/dlls/winegstreamer/resampler.c @@ -412,11 +412,21 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF if (FAILED(hr = check_media_type(type))) return hr; - if (FAILED(hr = IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_alignment))) + if (type && FAILED(hr = IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_alignment))) return MF_E_INVALIDMEDIATYPE; if (flags & MFT_SET_TYPE_TEST_ONLY) return S_OK; + if (!type) + { + if (impl->output_type) + { + IMFMediaType_Release(impl->output_type); + impl->output_type = NULL; + } + return S_OK; + } + if (!impl->output_type && FAILED(hr = MFCreateMediaType(&impl->output_type))) return hr; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9947
From: Conor McCarthy <cmccarthy@codeweavers.com> Before the addition of more complex tests, we need the sink to behave more like a real sink. --- dlls/mf/tests/topology.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/dlls/mf/tests/topology.c b/dlls/mf/tests/topology.c index 9070098a60a..ad89dd3269e 100644 --- a/dlls/mf/tests/topology.c +++ b/dlls/mf/tests/topology.c @@ -1674,6 +1674,8 @@ struct test_handler ULONG set_current_count; IMFMediaType *current_type; IMFMediaType *invalid_type; + BOOL support_any; + BOOL return_media_types; ULONG enum_count; ULONG media_types_count; @@ -1713,6 +1715,7 @@ static HRESULT WINAPI test_handler_IsMediaTypeSupported(IMFMediaTypeHandler *ifa { struct test_handler *impl = impl_from_IMFMediaTypeHandler(iface); BOOL result; + ULONG i; if (out_type) *out_type = NULL; @@ -1721,13 +1724,18 @@ static HRESULT WINAPI test_handler_IsMediaTypeSupported(IMFMediaTypeHandler *ifa MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result) == S_OK && result) return MF_E_INVALIDMEDIATYPE; - if (!impl->current_type) + if (impl->support_any) return S_OK; - if (IMFMediaType_Compare(impl->current_type, (IMFAttributes *)in_type, + if (impl->current_type && IMFMediaType_Compare(impl->current_type, (IMFAttributes *)in_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result) == S_OK && result) return S_OK; + for (i = 0; i < impl->media_types_count; ++i) + if (IMFMediaType_Compare(impl->media_types[i], (IMFAttributes *)in_type, + MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result) == S_OK && result) + return S_OK; + return MF_E_INVALIDMEDIATYPE; } @@ -1742,7 +1750,7 @@ static HRESULT WINAPI test_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *ifac { struct test_handler *impl = impl_from_IMFMediaTypeHandler(iface); - if (impl->media_types) + if (impl->return_media_types && impl->media_types) { impl->enum_count++; @@ -1776,7 +1784,7 @@ static HRESULT WINAPI test_handler_GetCurrentMediaType(IMFMediaTypeHandler *ifac if (!impl->current_type) { - if (!impl->media_types) + if (!impl->return_media_types) return E_FAIL; if (!impl->media_types_count) return MF_E_TRANSFORM_TYPE_NOT_SET; @@ -2185,6 +2193,7 @@ enum loader_test_flags LOADER_SET_INVALID_INPUT = 0x40, LOADER_SET_MEDIA_TYPES = 0x80, LOADER_ADD_RESAMPLER_MFT = 0x100, + LOADER_SUPPORT_ANY = 0x200, }; static void test_topology_loader(void) @@ -2491,13 +2500,13 @@ static void test_topology_loader(void) /* RGB32 -> Any Video, no current output type */ .input_type = &video_i420_1280, .output_type = &video_dummy, .sink_method = -1, .source_method = -1, .expected_result = S_OK, - .flags = LOADER_NO_CURRENT_OUTPUT, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SUPPORT_ANY, }, { /* RGB32 -> Any Video, no current output type, refuse input type */ .input_type = &video_i420_1280, .output_type = &video_dummy, .sink_method = -1, .source_method = -1, .expected_result = S_OK, .converter_class = CLSID_CColorConvertDMO, - .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_INVALID_INPUT, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_INVALID_INPUT | LOADER_SUPPORT_ANY, }, { /* RGB32 -> Any Video, no current output type, refuse input type */ @@ -2662,6 +2671,14 @@ static void test_topology_loader(void) handler.invalid_type = input_type; else handler.invalid_type = NULL; + if (test->flags & LOADER_SUPPORT_ANY) + handler.support_any = TRUE; + else + handler.support_any = FALSE; + if (test->flags & LOADER_SET_MEDIA_TYPES) + handler.return_media_types = TRUE; + else + handler.return_media_types = FALSE; handler.enum_count = 0; if (test->flags & LOADER_SET_MEDIA_TYPES) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9947
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/mf/tests/topology.c | 324 ++++++++++++++++++++++++++++++++------- 1 file changed, 265 insertions(+), 59 deletions(-) diff --git a/dlls/mf/tests/topology.c b/dlls/mf/tests/topology.c index ad89dd3269e..eda0c251e8a 100644 --- a/dlls/mf/tests/topology.c +++ b/dlls/mf/tests/topology.c @@ -1680,6 +1680,7 @@ struct test_handler ULONG enum_count; ULONG media_types_count; IMFMediaType **media_types; + BOOL enum_complete; }; static struct test_handler *impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler *iface) @@ -1755,7 +1756,10 @@ static HRESULT WINAPI test_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *ifac impl->enum_count++; if (index >= impl->media_types_count) + { + impl->enum_complete = TRUE; return MF_E_NO_MORE_TYPES; + } IMFMediaType_AddRef((*type = impl->media_types[index])); return S_OK; @@ -2186,7 +2190,9 @@ static IMFSampleGrabberSinkCallback *create_test_grabber_callback(void) enum loader_test_flags { - LOADER_TODO = 0x4, + LOADER_TODO = 0x1, + LOADER_TODO_OUT_TYPE = 0x2, + LOADER_SET_XVP_FOR_PLAYBACK = 0x4, LOADER_NEEDS_VIDEO_PROCESSOR = 0x8, LOADER_SET_ENUMERATE_SOURCE_TYPES = 0x10, LOADER_NO_CURRENT_OUTPUT = 0x20, @@ -2194,6 +2200,9 @@ enum loader_test_flags LOADER_SET_MEDIA_TYPES = 0x80, LOADER_ADD_RESAMPLER_MFT = 0x100, LOADER_SUPPORT_ANY = 0x200, + LOADER_EXPECT_SINK_ENUMERATED = 0x400, + LOADER_EXPECT_SINK_ENUMERATED_TODO = 0x800, + LOADER_EXPECT_MFT_ENUMERATED = 0x1000, }; static void test_topology_loader(void) @@ -2298,6 +2307,24 @@ static void test_topology_loader(void) ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), ATTR_RATIO(MF_MT_FRAME_SIZE, 1280, 720), }; + static const media_type_desc video_video_processor_1280_rgb24 = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24), + ATTR_RATIO(MF_MT_FRAME_SIZE, 1280, 720), + }; + static const media_type_desc video_video_processor_1280_rgb555 = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB555), + ATTR_RATIO(MF_MT_FRAME_SIZE, 1280, 720), + }; + static const media_type_desc video_video_processor_1024_rgb32 = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), + ATTR_RATIO(MF_MT_FRAME_SIZE, 1024, 576), + }; static const media_type_desc video_video_processor_rgb32 = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), @@ -2329,13 +2356,15 @@ static void test_topology_loader(void) const struct loader_test { - const media_type_desc *input_type; - const media_type_desc *output_type; + const media_type_desc *input_types[2]; + const media_type_desc *output_types[2]; const media_type_desc *current_input; + const media_type_desc *mft_current_output; const media_type_desc *decoded_type; MF_CONNECT_METHOD source_method; MF_CONNECT_METHOD sink_method; HRESULT expected_result; + unsigned int expected_output_index; unsigned int flags; GUID decoder_class; GUID converter_class; @@ -2344,25 +2373,25 @@ static void test_topology_loader(void) { { /* PCM -> PCM, same enumerated type, no current type */ - .input_type = &audio_pcm_44100, .output_type = &audio_pcm_44100, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_44100}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .expected_result = S_OK, }, { /* PCM -> PCM, same enumerated type, incomplete current type */ - .input_type = &audio_pcm_44100, .output_type = &audio_pcm_44100, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .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 */ - .input_type = &audio_pcm_48000, .output_type = &audio_pcm_48000, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .input_types = {&audio_pcm_48000}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .current_input = &audio_pcm_44100, .expected_result = MF_E_INVALIDMEDIATYPE, }, { /* PCM -> PCM, same enumerated bps, different current bps, force enumerate */ - .input_type = &audio_pcm_48000, .output_type = &audio_pcm_48000, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .input_types = {&audio_pcm_48000}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .current_input = &audio_pcm_44100, .expected_result = S_OK, .flags = LOADER_SET_ENUMERATE_SOURCE_TYPES, @@ -2370,13 +2399,13 @@ static void test_topology_loader(void) { /* PCM -> PCM, incomplete enumerated type, same current type */ - .input_type = &audio_pcm_44100_incomplete, .output_type = &audio_pcm_44100, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .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 = S_OK, }, { /* PCM -> PCM, incomplete enumerated type, same current type, force enumerate */ - .input_type = &audio_pcm_44100_incomplete, .output_type = &audio_pcm_44100, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .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, @@ -2384,146 +2413,273 @@ static void test_topology_loader(void) { /* PCM -> PCM, different enumerated bps, no current type */ - .input_type = &audio_pcm_44100, .output_type = &audio_pcm_48000, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .expected_result = MF_E_INVALIDMEDIATYPE, }, { /* PCM -> PCM, different enumerated bps, same current bps */ - .input_type = &audio_pcm_44100, .output_type = &audio_pcm_48000, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .current_input = &audio_pcm_48000, .expected_result = S_OK, }, { /* PCM -> PCM, different enumerated bps, same current bps, force enumerate */ - .input_type = &audio_pcm_44100, .output_type = &audio_pcm_48000, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .current_input = &audio_pcm_48000, .expected_result = MF_E_NO_MORE_TYPES, .flags = LOADER_SET_ENUMERATE_SOURCE_TYPES, }, { /* PCM -> PCM, different enumerated bps, no current type, sink allow converter */ - .input_type = &audio_pcm_44100, .output_type = &audio_pcm_48000, .sink_method = MF_CONNECT_ALLOW_CONVERTER, .source_method = MF_CONNECT_DIRECT, + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_ALLOW_CONVERTER, .source_method = MF_CONNECT_DIRECT, .expected_result = S_OK, .converter_class = CLSID_CResamplerMediaObject, }, { /* PCM -> PCM, different enumerated bps, same current type, sink allow converter, force enumerate */ - .input_type = &audio_pcm_44100, .output_type = &audio_pcm_48000, .sink_method = MF_CONNECT_ALLOW_CONVERTER, .source_method = -1, + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_ALLOW_CONVERTER, .source_method = -1, .current_input = &audio_pcm_48000, .expected_result = S_OK, .converter_class = CLSID_CResamplerMediaObject, .flags = LOADER_SET_ENUMERATE_SOURCE_TYPES, }, + { + /* PCM -> PCM, different enumerated bps, no current type, sink allow converter, no output types */ + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_ALLOW_CONVERTER, .source_method = MF_CONNECT_DIRECT, + .expected_result = MF_E_INVALIDMEDIATYPE, .converter_class = CLSID_CResamplerMediaObject, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_TODO, + }, + { + /* PCM -> PCM, different enumerated bps, no current type, sink allow converter, no current output type */ + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_ALLOW_CONVERTER, .source_method = MF_CONNECT_DIRECT, + .expected_result = S_OK, .converter_class = CLSID_CResamplerMediaObject, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_EXPECT_SINK_ENUMERATED_TODO, + }, { /* PCM -> PCM, different enumerated bps, no current type, sink allow decoder */ - .input_type = &audio_pcm_44100, .output_type = &audio_pcm_48000, .sink_method = MF_CONNECT_ALLOW_DECODER, .source_method = MF_CONNECT_DIRECT, + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_ALLOW_DECODER, .source_method = MF_CONNECT_DIRECT, .expected_result = S_OK, .converter_class = CLSID_CResamplerMediaObject, }, { /* PCM -> PCM, different enumerated bps, no current type, default methods */ - .input_type = &audio_pcm_44100, .output_type = &audio_pcm_48000, .sink_method = -1, .source_method = -1, + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = -1, .source_method = -1, .expected_result = S_OK, .converter_class = CLSID_CResamplerMediaObject, }, { /* PCM -> PCM, different enumerated bps, no current type, source allow converter */ - .input_type = &audio_pcm_44100, .output_type = &audio_pcm_48000, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_ALLOW_CONVERTER, + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_ALLOW_CONVERTER, .expected_result = MF_E_INVALIDMEDIATYPE, }, { /* Float -> PCM, refuse input type, add converter */ - .input_type = &audio_float_44100, .output_type = &audio_pcm_48000, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .input_types = {&audio_float_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .expected_result = MF_E_NO_MORE_TYPES, .converter_class = CLSID_CResamplerMediaObject, .flags = LOADER_SET_INVALID_INPUT | LOADER_ADD_RESAMPLER_MFT, }, { /* Float -> PCM, refuse input type, add converter, allow resampler output type */ - .input_type = &audio_float_44100, .output_type = &audio_pcm_48000_resampler, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .input_types = {&audio_float_44100}, .output_types = {&audio_pcm_48000_resampler}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .expected_result = S_OK, .converter_class = CLSID_CResamplerMediaObject, .flags = LOADER_SET_INVALID_INPUT | LOADER_ADD_RESAMPLER_MFT, }, { /* MP3 -> PCM */ - .input_type = &audio_mp3_44100, .output_type = &audio_pcm_44100, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .input_types = {&audio_mp3_44100}, .output_types = {&audio_pcm_44100}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .current_input = &audio_mp3_44100, .expected_result = MF_E_INVALIDMEDIATYPE, }, { /* MP3 -> PCM, force enumerate */ - .input_type = &audio_mp3_44100, .output_type = &audio_pcm_44100, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, + .input_types = {&audio_mp3_44100}, .output_types = {&audio_pcm_44100}, .sink_method = MF_CONNECT_DIRECT, .source_method = -1, .current_input = &audio_mp3_44100, .expected_result = MF_E_NO_MORE_TYPES, .flags = LOADER_SET_ENUMERATE_SOURCE_TYPES, }, { /* MP3 -> PCM */ - .input_type = &audio_mp3_44100, .output_type = &audio_pcm_44100, .sink_method = MF_CONNECT_ALLOW_CONVERTER, .source_method = -1, + .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 */ - .input_type = &audio_mp3_44100, .output_type = &audio_pcm_44100, .sink_method = MF_CONNECT_ALLOW_DECODER, .source_method = -1, + .input_types = {&audio_mp3_44100}, .output_types = {&audio_pcm_44100}, .sink_method = MF_CONNECT_ALLOW_DECODER, .source_method = -1, .current_input = &audio_mp3_44100, .expected_result = S_OK, .decoder_class = CLSID_CMP3DecMediaObject, }, { /* MP3 -> PCM, need both decoder and converter */ - .input_type = &audio_mp3_44100, .output_type = &audio_float_48000, .sink_method = MF_CONNECT_ALLOW_DECODER, .source_method = -1, + .input_types = {&audio_mp3_44100}, .output_types = {&audio_float_48000}, .sink_method = MF_CONNECT_ALLOW_DECODER, .source_method = -1, + .current_input = &audio_mp3_44100, .decoded_type = &audio_float_44100_stereo, + .expected_result = S_OK, .decoder_class = CLSID_CMP3DecMediaObject, .converter_class = CLSID_CResamplerMediaObject, + }, + { + /* MP3 -> float, need both decoder and converter, no current output type */ + .input_types = {&audio_mp3_44100}, .output_types = {&audio_float_48000}, .sink_method = MF_CONNECT_ALLOW_DECODER, .source_method = -1, + .current_input = &audio_mp3_44100, .decoded_type = &audio_float_44100_stereo, + .expected_result = S_OK, .decoder_class = CLSID_CMP3DecMediaObject, .converter_class = CLSID_CResamplerMediaObject, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_EXPECT_SINK_ENUMERATED_TODO, + }, + { + /* MP3 -> {float, PCM}, need both decoder and converter, no current output type */ + .input_types = {&audio_mp3_44100}, .output_types = {&audio_float_48000, &audio_pcm_48000}, .sink_method = MF_CONNECT_ALLOW_DECODER, .source_method = -1, .current_input = &audio_mp3_44100, .decoded_type = &audio_float_44100_stereo, .expected_result = S_OK, .decoder_class = CLSID_CMP3DecMediaObject, .converter_class = CLSID_CResamplerMediaObject, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_EXPECT_SINK_ENUMERATED_TODO, + }, + { + /* MP3 -> {PCM, float}, need both decoder and converter, no current output type */ + .input_types = {&audio_mp3_44100}, .output_types = {&audio_pcm_48000, &audio_float_48000}, .sink_method = MF_CONNECT_ALLOW_DECODER, .source_method = -1, + .current_input = &audio_mp3_44100, .decoded_type = &audio_float_44100_stereo, .expected_output_index = 1, + .expected_result = S_OK, .decoder_class = CLSID_CMP3DecMediaObject, .converter_class = CLSID_CResamplerMediaObject, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_TODO_OUT_TYPE | LOADER_EXPECT_SINK_ENUMERATED_TODO, + }, + + { + /* {MP3, PCM} -> PCM, force enumerate, sink allow decoder, no output types */ + .input_types = {&audio_mp3_44100, &audio_pcm_44100}, .output_types = {&audio_pcm_44100}, .sink_method = MF_CONNECT_ALLOW_DECODER, .source_method = -1, + .expected_result = S_OK, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_ENUMERATE_SOURCE_TYPES, + }, + { + /* {MP3, PCM} -> PCM, force enumerate, independent outtypes, sink allow decoder, no current output type */ + .input_types = {&audio_mp3_44100, &audio_pcm_44100}, .output_types = {&audio_pcm_44100}, .sink_method = MF_CONNECT_ALLOW_DECODER, + .source_method = MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES, + .expected_result = S_OK, .decoder_class = CLSID_CMP3DecMediaObject, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_SET_ENUMERATE_SOURCE_TYPES | LOADER_EXPECT_SINK_ENUMERATED_TODO, + }, + + { + /* PCM -> PCM, different enumerated bps, add converter, no output types */ + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_DIRECT, + .expected_result = MF_E_NO_MORE_TYPES, .converter_class = CLSID_CResamplerMediaObject, + .flags = LOADER_ADD_RESAMPLER_MFT | LOADER_NO_CURRENT_OUTPUT, + }, + { + /* PCM -> PCM, different enumerated bps, add converter, configure converter, no output types */ + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_DIRECT, + .mft_current_output = &audio_pcm_48000, + .expected_result = S_OK, .converter_class = CLSID_CResamplerMediaObject, + .flags = LOADER_ADD_RESAMPLER_MFT | LOADER_NO_CURRENT_OUTPUT, }, { /* I420 -> RGB32, Color Convert media type */ - .input_type = &video_i420_1280, .output_type = &video_color_convert_1280_rgb32, .sink_method = -1, .source_method = -1, + .input_types = {&video_i420_1280}, .output_types = {&video_color_convert_1280_rgb32}, .sink_method = -1, .source_method = -1, .expected_result = MF_E_TOPO_CODEC_NOT_FOUND, .converter_class = CLSID_CColorConvertDMO, .flags = LOADER_NEEDS_VIDEO_PROCESSOR, }, { /* I420 -> RGB32, Video Processor media type */ - .input_type = &video_i420_1280, .output_type = &video_video_processor_1280_rgb32, .sink_method = -1, .source_method = -1, + .input_types = {&video_i420_1280}, .output_types = {&video_video_processor_1280_rgb32}, .sink_method = -1, .source_method = -1, .expected_result = S_OK, .converter_class = CLSID_CColorConvertDMO, }, { /* I420 -> RGB32, Video Processor media type without frame size */ - .input_type = &video_i420_1280, .output_type = &video_video_processor_rgb32, .sink_method = -1, .source_method = -1, + .input_types = {&video_i420_1280}, .output_types = {&video_video_processor_rgb32}, .sink_method = -1, .source_method = -1, .expected_result = S_OK, .converter_class = CLSID_CColorConvertDMO, }, { /* H264 -> RGB32, Video Processor media type */ - .input_type = &video_h264_1280, .output_type = &video_video_processor_1280_rgb32, .sink_method = -1, .source_method = -1, + .input_types = {&video_h264_1280}, .output_types = {&video_video_processor_1280_rgb32}, .sink_method = -1, .source_method = -1, .decoded_type = &video_nv12_1280, .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_CColorConvertDMO, }, { /* RGB32 -> Any Video, no current output type */ - .input_type = &video_i420_1280, .output_type = &video_dummy, .sink_method = -1, .source_method = -1, + .input_types = {&video_i420_1280}, .output_types = {&video_dummy}, .sink_method = -1, .source_method = -1, .expected_result = S_OK, .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SUPPORT_ANY, }, { /* RGB32 -> Any Video, no current output type, refuse input type */ - .input_type = &video_i420_1280, .output_type = &video_dummy, .sink_method = -1, .source_method = -1, + .input_types = {&video_i420_1280}, .output_types = {&video_dummy}, .sink_method = -1, .source_method = -1, .expected_result = S_OK, .converter_class = CLSID_CColorConvertDMO, .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_INVALID_INPUT | LOADER_SUPPORT_ANY, }, { /* RGB32 -> Any Video, no current output type, refuse input type */ - .input_type = &video_i420_1280, .output_type = &video_video_processor_rgb32, .sink_method = -1, .source_method = -1, + .input_types = {&video_i420_1280}, .output_types = {&video_video_processor_rgb32}, .sink_method = -1, .source_method = -1, .expected_result = S_OK, .converter_class = CLSID_CColorConvertDMO, - .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_INVALID_INPUT | LOADER_SET_MEDIA_TYPES, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_INVALID_INPUT | LOADER_SET_MEDIA_TYPES | LOADER_EXPECT_SINK_ENUMERATED_TODO, + }, + + { + /* H264 -> {DMO_RGB32, MF_RGB32}, no current output type */ + .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, + }, + { + /* H264 -> {DMO_RGB32, MF_RGB32} */ + .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 = MF_E_TOPO_CODEC_NOT_FOUND, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_CColorConvertDMO, + }, + + { + /* H264 -> {RGB32, RGB24} */ + .input_types = {&video_h264_1280}, .output_types = {&video_video_processor_1280_rgb32, &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, + }, + { + /* 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, + }, + { + /* 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, + }, + { + /* 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, + }, + + { + /* H264 -> RGB32, Color Convert media type, no current output type */ + .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, + }, + + { + /* H264 -> {DMO_RGB32, MF_RGB32}, no current output type, set XVP */ + .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_VideoProcessorMFT, + .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_SET_XVP_FOR_PLAYBACK | LOADER_EXPECT_SINK_ENUMERATED_TODO | LOADER_TODO, + }, + { + /* H264 -> RGB32, resize, set XVP */ + .input_types = {&video_h264_1280}, .output_types = {&video_video_processor_1024_rgb32}, .sink_method = -1, .source_method = -1, + .decoded_type = &video_nv12_1280, + .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_VideoProcessorMFT, + .flags = LOADER_SET_XVP_FOR_PLAYBACK, }, }; IMFTopologyNode *src_node, *sink_node, *src_node2, *sink_node2, *mft_node; IMFSampleGrabberSinkCallback *grabber_callback = create_test_grabber_callback(); + IMFMediaType *media_type, *input_types[2], *output_types[2]; struct test_stream_sink stream_sink = test_stream_sink; - IMFMediaType *media_type, *input_type, *output_type; IMFTopology *topology, *topology2, *full_topology; + unsigned int i, count, expected_count, value; struct test_handler handler = test_handler; IMFPresentationDescriptor *pd; - unsigned int i, count, value; IMFActivate *sink_activate; MF_TOPOLOGY_TYPE node_type; IMFStreamDescriptor *sd; @@ -2646,10 +2802,14 @@ static void test_topology_loader(void) ok(ref == 0, "Release returned %ld\n", ref); - hr = MFCreateMediaType(&input_type); + hr = MFCreateMediaType(&input_types[0]); + ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); + hr = MFCreateMediaType(&input_types[1]); ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); - hr = MFCreateMediaType(&output_type); + hr = MFCreateMediaType(&output_types[0]); + ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); + hr = MFCreateMediaType(&output_types[1]); ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); for (i = 0; i < ARRAY_SIZE(loader_tests); ++i) @@ -2658,17 +2818,17 @@ static void test_topology_loader(void) winetest_push_context("%u", i); - init_media_type(input_type, *test->input_type, -1); - init_media_type(output_type, *test->output_type, -1); + init_media_type(input_types[0], *test->input_types[0], -1); + init_media_type(output_types[0], *test->output_types[0], -1); handler.set_current_count = 0; if (test->flags & LOADER_NO_CURRENT_OUTPUT) handler.current_type = NULL; else - IMFMediaType_AddRef((handler.current_type = output_type)); + IMFMediaType_AddRef((handler.current_type = output_types[0])); if (test->flags & LOADER_SET_INVALID_INPUT) - handler.invalid_type = input_type; + handler.invalid_type = input_types[0]; else handler.invalid_type = NULL; if (test->flags & LOADER_SUPPORT_ANY) @@ -2681,15 +2841,19 @@ static void test_topology_loader(void) handler.return_media_types = FALSE; handler.enum_count = 0; - if (test->flags & LOADER_SET_MEDIA_TYPES) + handler.media_types_count = 1; + handler.media_types = output_types; + handler.enum_complete = FALSE; + + if (test->input_types[1]) { - handler.media_types_count = 1; - handler.media_types = &output_type; + init_media_type(input_types[1], *test->input_types[1], -1); } - else + + if (test->output_types[1]) { - handler.media_types_count = 0; - handler.media_types = NULL; + init_media_type(output_types[1], *test->output_types[1], -1); + handler.media_types_count = 2; } if (test->flags & LOADER_ADD_RESAMPLER_MFT) @@ -2710,6 +2874,17 @@ static void test_topology_loader(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFTopologyNode_SetObject(mft_node, (IUnknown *)transform); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (test->mft_current_output) + { + hr = IMFTransform_SetInputType(transform, 0, input_types[0], 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); + init_media_type(media_type, *test->mft_current_output, -1); + hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(media_type); + } IMFTransform_Release(transform); hr = IMFTopology_AddNode(topology, mft_node); @@ -2732,7 +2907,7 @@ static void test_topology_loader(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); } - create_descriptors(1, &input_type, test->current_input, &pd, &sd); + create_descriptors(1 + !!test->input_types[1], input_types, test->current_input, &pd, &sd); source = create_test_source(pd); @@ -2745,8 +2920,11 @@ static void test_topology_loader(void) if (test->flags & LOADER_SET_ENUMERATE_SOURCE_TYPES) IMFTopology_SetUINT32(topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, 1); + if (test->flags & LOADER_SET_XVP_FOR_PLAYBACK) + IMFTopology_SetUINT32(topology, &MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK, 1); hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); IMFTopology_DeleteItem(topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES); + IMFTopology_DeleteItem(topology, &MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK); if (test->flags & LOADER_NEEDS_VIDEO_PROCESSOR && !has_video_processor) ok(hr == MF_E_INVALIDMEDIATYPE || hr == MF_E_TOPO_CODEC_NOT_FOUND, @@ -2771,11 +2949,12 @@ static void test_topology_loader(void) ok(oldtopoid == newtopoid, "Expected the same topology id. %I64u == %I64u\n", oldtopoid, newtopoid); ok(topology != full_topology, "Expected a different object for the resolved topology.\n"); + expected_count = 1 + !!(test->flags & LOADER_SET_ENUMERATE_SOURCE_TYPES) + + !!(test->flags & LOADER_SET_XVP_FOR_PLAYBACK); hr = IMFTopology_GetCount(full_topology, &count); ok(hr == S_OK, "Failed to get attribute count, hr %#lx.\n", hr); todo_wine - ok(count == (test->flags & LOADER_SET_ENUMERATE_SOURCE_TYPES ? 2 : 1), - "Unexpected count %u.\n", count); + ok(count == expected_count, "Unexpected count %u.\n", count); value = 0xdeadbeef; hr = IMFTopology_GetUINT32(full_topology, &MF_TOPOLOGY_RESOLUTION_STATUS, &value); @@ -2799,12 +2978,23 @@ todo_wine { hr = IMFTopology_GetNodeByID(full_topology, node_id, &src_node2); ok(hr == S_OK, "Failed to get source in resolved topology, hr %#lx.\n", hr); + hr = IMFTopologyNode_GetOutputPrefType(src_node2, 0, &media_type); + ok(hr == E_FAIL, "Got src pref type hr %#lx.\n", hr); + hr = IMFTopologyNode_GetTopoNodeID(sink_node, &node_id); ok(hr == S_OK, "Failed to get sink node id, hr %#lx.\n", hr); hr = IMFTopology_GetNodeByID(full_topology, node_id, &sink_node2); ok(hr == S_OK, "Failed to get sink in resolved topology, hr %#lx.\n", hr); + hr = IMFTopologyNode_GetInputPrefType(sink_node, 0, &media_type); + ok(hr == E_FAIL, "Got sink pref type hr %#lx.\n", hr); + hr = IMFTopologyNode_GetInputPrefType(sink_node2, 0, &media_type); + todo_wine + ok(hr == S_OK, "Failed to get sink pref type, hr %#lx.\n", hr); + if (hr == S_OK) + IMFMediaType_Release(media_type); + if (!IsEqualGUID(&test->decoder_class, &GUID_NULL)) { GUID class_id; @@ -2837,7 +3027,7 @@ todo_wine { hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type); ok(hr == S_OK, "Failed to get transform input type, hr %#lx.\n", hr); - hr = IMFMediaType_Compare(input_type, (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); + hr = IMFMediaType_Compare(input_types[0], (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); ok(hr == S_OK, "Failed to compare media types, hr %#lx.\n", hr); ok(ret, "Input type of first transform doesn't match source node type.\n"); IMFMediaType_Release(media_type); @@ -2846,7 +3036,7 @@ todo_wine { ok(hr == S_OK, "Failed to get transform input type, hr %#lx.\n", hr); if (IsEqualGUID(&test->converter_class, &GUID_NULL)) { - hr = IMFMediaType_Compare(output_type, (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); + hr = IMFMediaType_Compare(output_types[test->expected_output_index], (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); ok(hr == S_OK, "Failed to compare media types, hr %#lx.\n", hr); ok(ret, "Output type of first transform doesn't match sink node type.\n"); } @@ -2873,9 +3063,17 @@ todo_wine { class_id = GUID_NULL; hr = IMFTopologyNode_GetGUID(mft_node, &MF_TOPONODE_TRANSFORM_OBJECTID, &class_id); - 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)); + 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)); + } hr = IMFTopologyNode_GetObject(mft_node, &node_object); ok(hr == S_OK, "Failed to get object of transform node, hr %#lx.\n", hr); @@ -2889,7 +3087,7 @@ todo_wine { ok(hr == S_OK, "Failed to get transform input type, hr %#lx.\n", hr); if (IsEqualGUID(&test->decoder_class, &GUID_NULL)) { - hr = IMFMediaType_Compare(input_type, (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); + hr = IMFMediaType_Compare(input_types[0], (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); ok(hr == S_OK, "Failed to compare media types, hr %#lx.\n", hr); ok(ret, "Input type of last transform doesn't match source node type.\n"); } @@ -2900,9 +3098,10 @@ todo_wine { IMFMediaType_Release(media_type); hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type); - ok(hr == S_OK, "Failed to get transform input type, hr %#lx.\n", hr); - hr = IMFMediaType_Compare(output_type, (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); + ok(hr == S_OK, "Failed to get transform output type, hr %#lx.\n", hr); + hr = IMFMediaType_Compare(output_types[test->expected_output_index], (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); ok(hr == S_OK, "Failed to compare media types, hr %#lx.\n", hr); + todo_wine_if(test->flags & LOADER_TODO_OUT_TYPE) ok(ret, "Output type of last transform doesn't match sink node type.\n"); IMFMediaType_Release(media_type); @@ -2938,6 +3137,9 @@ todo_wine { else ok(!handler.enum_count, "got %lu GetMediaTypeByIndex\n", handler.enum_count); ok(!handler.set_current_count, "got %lu SetCurrentMediaType\n", handler.set_current_count); + todo_wine_if(test->flags & LOADER_EXPECT_SINK_ENUMERATED_TODO) + ok(handler.enum_complete == !!(test->flags & (LOADER_EXPECT_SINK_ENUMERATED | LOADER_EXPECT_SINK_ENUMERATED_TODO)), + "Got enum_complete %u.\n", handler.enum_complete); if (handler.current_type) IMFMediaType_Release(handler.current_type); @@ -2968,9 +3170,13 @@ todo_wine { ref = IMFTopologyNode_Release(sink_node); ok(ref == 0, "Release returned %ld\n", ref); - ref = IMFMediaType_Release(input_type); + ref = IMFMediaType_Release(input_types[0]); + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFMediaType_Release(input_types[1]); + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFMediaType_Release(output_types[0]); ok(ref == 0, "Release returned %ld\n", ref); - ref = IMFMediaType_Release(output_type); + ref = IMFMediaType_Release(output_types[1]); ok(ref == 0, "Release returned %ld\n", ref); hr = MFShutdown(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9947
From: Conor McCarthy <cmccarthy@codeweavers.com> --- dlls/mf/tests/topology.c | 237 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 222 insertions(+), 15 deletions(-) diff --git a/dlls/mf/tests/topology.c b/dlls/mf/tests/topology.c index eda0c251e8a..823999b8538 100644 --- a/dlls/mf/tests/topology.c +++ b/dlls/mf/tests/topology.c @@ -245,6 +245,11 @@ struct test_transform UINT output_count; IMFMediaType **output_types; IMFMediaType *output_type; + BOOL input_enum_complete; + BOOL output_enum_complete; + BOOL input_type_set; + BOOL output_type_set; + BOOL set_input_nulls_output; IDirect3DDeviceManager9 *expect_d3d9_device_manager; BOOL got_d3d9_device_manager; @@ -381,6 +386,7 @@ static HRESULT WINAPI test_transform_GetInputAvailableType(IMFTransform *iface, if (index >= transform->input_count) { *type = NULL; + transform->input_enum_complete = TRUE; return MF_E_NO_MORE_TYPES; } @@ -397,6 +403,7 @@ static HRESULT WINAPI test_transform_GetOutputAvailableType(IMFTransform *iface, if (index >= transform->output_count) { *type = NULL; + transform->output_enum_complete = TRUE; return MF_E_NO_MORE_TYPES; } @@ -408,12 +415,39 @@ static HRESULT WINAPI test_transform_GetOutputAvailableType(IMFTransform *iface, static HRESULT WINAPI test_transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) { struct test_transform *transform = test_transform_from_IMFTransform(iface); + BOOL result; + UINT i; + + if (type) + { + for (i = 0; i < transform->input_count; ++i) + { + if (IMFMediaType_Compare(transform->input_types[i], (IMFAttributes *)type, + MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result) == S_OK && result) + break; + } + if (i == transform->input_count) + return MF_E_INVALIDMEDIATYPE; + } + if (flags & MFT_SET_TYPE_TEST_ONLY) return S_OK; + if (transform->input_type) IMFMediaType_Release(transform->input_type); + if ((transform->input_type = type)) + { + transform->input_type_set = TRUE; IMFMediaType_AddRef(transform->input_type); + } + + if (transform->output_type && (!type || transform->set_input_nulls_output)) + { + IMFMediaType_Release(transform->output_type); + transform->output_type = NULL; + } + return S_OK; } @@ -425,7 +459,10 @@ static HRESULT WINAPI test_transform_SetOutputType(IMFTransform *iface, DWORD id if (transform->output_type) IMFMediaType_Release(transform->output_type); if ((transform->output_type = type)) + { + transform->output_type_set = TRUE; IMFMediaType_AddRef(transform->output_type); + } return S_OK; } @@ -590,6 +627,7 @@ static HRESULT WINAPI test_transform_create(UINT input_count, IMFMediaType **inp { struct test_transform *transform; HRESULT hr; + GUID type; if (!(transform = calloc(1, sizeof(*transform)))) return E_OUTOFMEMORY; @@ -605,6 +643,9 @@ static HRESULT WINAPI test_transform_create(UINT input_count, IMFMediaType **inp transform->output_type = output_types[0]; IMFMediaType_AddRef(transform->output_type); + transform->set_input_nulls_output = SUCCEEDED(IMFMediaType_GetGUID(output_types[0], &MF_MT_MAJOR_TYPE, &type)) + && !IsEqualGUID(&type, &MFMediaType_Audio); + hr = MFCreateAttributes(&transform->attributes, 1); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFAttributes_SetUINT32(transform->attributes, &MF_SA_D3D_AWARE, d3d_aware); @@ -2202,7 +2243,13 @@ enum loader_test_flags LOADER_SUPPORT_ANY = 0x200, LOADER_EXPECT_SINK_ENUMERATED = 0x400, LOADER_EXPECT_SINK_ENUMERATED_TODO = 0x800, - LOADER_EXPECT_MFT_ENUMERATED = 0x1000, + LOADER_ADD_TEST_MFT = 0x1000, + LOADER_TEST_MFT_EXPECT_CONVERTER = 0x2000, + 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, }; static void test_topology_loader(void) @@ -2277,6 +2324,18 @@ static void test_topology_loader(void) ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 8), }; + static const media_type_desc audio_float_minimal = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_Float), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + }; + static const media_type_desc audio_pcm_minimal = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + }; static const media_type_desc audio_float_44100_stereo = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), @@ -2289,6 +2348,15 @@ static void test_topology_loader(void) ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK, 3, .todo = TRUE), ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), }; + static const media_type_desc audio_aac_44100 = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_AAC), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 1), + }; static const media_type_desc video_i420_1280 = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), @@ -2358,6 +2426,8 @@ static void test_topology_loader(void) { const media_type_desc *input_types[2]; const media_type_desc *output_types[2]; + const media_type_desc *mft_input_type; + const media_type_desc *mft_output_types[5]; const media_type_desc *current_input; const media_type_desc *mft_current_output; const media_type_desc *decoded_type; @@ -2435,7 +2505,7 @@ static void test_topology_loader(void) .expected_result = S_OK, .converter_class = CLSID_CResamplerMediaObject, }, { - /* PCM -> PCM, different enumerated bps, same current type, sink allow converter, force enumerate */ + /* #10 PCM -> PCM, different enumerated bps, same current type, sink allow converter, force enumerate */ .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_ALLOW_CONVERTER, .source_method = -1, .current_input = &audio_pcm_48000, .expected_result = S_OK, .converter_class = CLSID_CResamplerMediaObject, @@ -2496,7 +2566,7 @@ static void test_topology_loader(void) .flags = LOADER_SET_ENUMERATE_SOURCE_TYPES, }, { - /* MP3 -> PCM */ + /* #20 MP3 -> PCM */ .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, @@ -2550,6 +2620,53 @@ static void test_topology_loader(void) .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SET_MEDIA_TYPES | LOADER_SET_ENUMERATE_SOURCE_TYPES | LOADER_EXPECT_SINK_ENUMERATED_TODO, }, + { + /* PCM -> PCM, different enumerated bps, add test MFT, configure MFT incomplete type */ + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_DIRECT, + .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, + }, + { + /* PCM -> PCM, different enumerated bps, add test MFT */ + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_DIRECT, + .mft_output_types = {&audio_float_minimal, &audio_pcm_minimal, &audio_float_48000, &audio_pcm_48000_resampler}, + .expected_result = MF_E_NO_MORE_TYPES, + .flags = LOADER_ADD_TEST_MFT | LOADER_EXPECT_MFT_OUTPUT_ENUMERATED, + }, + { + /* #30 PCM -> PCM, different enumerated bps, add test MFT, configure MFT */ + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_DIRECT, + .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, + }, + { + /* PCM -> PCM, different enumerated bps, add test MFT, configure MFT, no output types */ + .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_DIRECT, + .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, + }, + { + /* MP3 -> PCM, different enumerated bps, add test MFT, configure MFT */ + .input_types = {&audio_mp3_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_DIRECT, + .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, + }, + { + /* MP3 -> PCM, different enumerated bps, add incompatible test MFT, configure MFT */ + .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, + }, + { /* PCM -> PCM, different enumerated bps, add converter, no output types */ .input_types = {&audio_pcm_44100}, .output_types = {&audio_pcm_48000}, .sink_method = MF_CONNECT_DIRECT, .source_method = MF_CONNECT_DIRECT, @@ -2587,7 +2704,7 @@ static void test_topology_loader(void) .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_CColorConvertDMO, }, { - /* RGB32 -> Any Video, no current output type */ + /* #40 RGB32 -> Any Video, no current output type */ .input_types = {&video_i420_1280}, .output_types = {&video_dummy}, .sink_method = -1, .source_method = -1, .expected_result = S_OK, .flags = LOADER_NO_CURRENT_OUTPUT | LOADER_SUPPORT_ANY, @@ -2657,7 +2774,7 @@ static void test_topology_loader(void) }, { - /* H264 -> {DMO_RGB32, MF_RGB32}, no current output type, set XVP */ + /* #50 H264 -> {DMO_RGB32, MF_RGB32}, no current output type, set XVP */ .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_VideoProcessorMFT, @@ -2670,6 +2787,28 @@ static void test_topology_loader(void) .expected_result = S_OK, .decoder_class = CLSID_CMSH264DecoderMFT, .converter_class = CLSID_VideoProcessorMFT, .flags = LOADER_SET_XVP_FOR_PLAYBACK, }, + + { + /* H264 -> RGB32, Color Convert media type, add test MFT */ + .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, + }, + { + /* 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_TODO_MFT_OUT_TYPE | 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, + }, }; IMFTopologyNode *src_node, *sink_node, *src_node2, *sink_node2, *mft_node; @@ -2677,7 +2816,7 @@ static void test_topology_loader(void) IMFMediaType *media_type, *input_types[2], *output_types[2]; struct test_stream_sink stream_sink = test_stream_sink; IMFTopology *topology, *topology2, *full_topology; - unsigned int i, count, expected_count, value; + unsigned int i, j, count, expected_count, value; struct test_handler handler = test_handler; IMFPresentationDescriptor *pd; IMFActivate *sink_activate; @@ -2815,6 +2954,9 @@ static void test_topology_loader(void) for (i = 0; i < ARRAY_SIZE(loader_tests); ++i) { const struct loader_test *test = &loader_tests[i]; + struct test_transform *test_transform = NULL; + IMFMediaType *mft_output_types[4] = {0}; + IMFMediaType *mft_input_type = NULL; winetest_push_context("%u", i); @@ -2856,7 +2998,7 @@ static void test_topology_loader(void) handler.media_types_count = 2; } - if (test->flags & LOADER_ADD_RESAMPLER_MFT) + if (test->flags & (LOADER_ADD_RESAMPLER_MFT | LOADER_ADD_TEST_MFT)) { hr = IMFTopology_Clear(topology); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -2867,11 +3009,33 @@ static void test_topology_loader(void) hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &mft_node); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (test->flags & LOADER_ADD_TEST_MFT) + { + mft_input_type = input_types[0]; - hr = CoCreateInstance(&CLSID_CResamplerMediaObject, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - hr = IMFTopologyNode_SetGUID(mft_node, &MF_TOPONODE_TRANSFORM_OBJECTID, &CLSID_CResamplerMediaObject); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (test->mft_input_type) + { + hr = MFCreateMediaType(&mft_input_type); + ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); + init_media_type(mft_input_type, *test->mft_input_type, -1); + } + for (j = 0; test->mft_output_types[j]; ++j) + { + hr = MFCreateMediaType(&mft_output_types[j]); + ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); + init_media_type(mft_output_types[j], *test->mft_output_types[j], -1); + } + test_transform_create(1, &mft_input_type, j, mft_output_types, FALSE, &transform); + test_transform = test_transform_from_IMFTransform(transform); + IMFTransform_AddRef(transform); + } + else + { + hr = CoCreateInstance(&CLSID_CResamplerMediaObject, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopologyNode_SetGUID(mft_node, &MF_TOPONODE_TRANSFORM_OBJECTID, &CLSID_CResamplerMediaObject); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } hr = IMFTopologyNode_SetObject(mft_node, (IUnknown *)transform); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); if (test->mft_current_output) @@ -2885,8 +3049,19 @@ static void test_topology_loader(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); IMFMediaType_Release(media_type); } + else + { + IMFTransform_SetInputType(transform, 0, NULL, 0); + IMFTransform_SetOutputType(transform, 0, NULL, 0); + } IMFTransform_Release(transform); + if (test_transform) + { + test_transform->input_type_set = FALSE; + test_transform->output_type_set = FALSE; + } + hr = IMFTopology_AddNode(topology, mft_node); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFTopologyNode_ConnectOutput(src_node, 0, mft_node, 0); @@ -2962,7 +3137,7 @@ todo_wine { ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr); ok(value == MF_TOPOLOGY_RESOLUTION_SUCCEEDED, "Unexpected value %#x.\n", value); } - count = 2; + count = 2 + !!test_transform; if (!IsEqualGUID(&test->decoder_class, &GUID_NULL)) count++; if (!IsEqualGUID(&test->converter_class, &GUID_NULL)) @@ -3034,9 +3209,10 @@ todo_wine { hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type); ok(hr == S_OK, "Failed to get transform input type, hr %#lx.\n", hr); - if (IsEqualGUID(&test->converter_class, &GUID_NULL)) + if (IsEqualGUID(&test->converter_class, &GUID_NULL) && !test_transform) { - hr = IMFMediaType_Compare(output_types[test->expected_output_index], (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); + IMFMediaType *expected = test_transform ? mft_input_type : output_types[test->expected_output_index]; + hr = IMFMediaType_Compare(expected, (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); ok(hr == S_OK, "Failed to compare media types, hr %#lx.\n", hr); ok(ret, "Output type of first transform doesn't match sink node type.\n"); } @@ -3054,9 +3230,18 @@ todo_wine { GUID class_id; hr = IMFTopologyNode_GetInput(sink_node2, 0, &mft_node, &index); - ok(hr == S_OK, "Failed to get decoder in resolved topology, hr %#lx.\n", hr); + ok(hr == S_OK, "Failed to get converter in resolved topology, hr %#lx.\n", hr); ok(!index, "Unexpected stream index %lu.\n", index); + if (test->flags & LOADER_TEST_MFT_EXPECT_CONVERTER) + { + IMFTopologyNode *test_mft_node = mft_node; + hr = IMFTopologyNode_GetInput(test_mft_node, 0, &mft_node, &index); + ok(hr == S_OK, "Failed to get converter in resolved topology, hr %#lx.\n", hr); + ok(!index, "Unexpected stream index %lu.\n", index); + IMFTopologyNode_Release(test_mft_node); + } + hr = IMFTopologyNode_GetNodeType(mft_node, &node_type); ok(hr == S_OK, "Failed to get transform node type in resolved topology, hr %#lx.\n", hr); ok(node_type == MF_TOPOLOGY_TRANSFORM_NODE, "Unexpected node type %u.\n", node_type); @@ -3141,6 +3326,23 @@ todo_wine { ok(handler.enum_complete == !!(test->flags & (LOADER_EXPECT_SINK_ENUMERATED | LOADER_EXPECT_SINK_ENUMERATED_TODO)), "Got enum_complete %u.\n", handler.enum_complete); + if (test_transform) + { + todo_wine_if(test->flags & LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO) + ok(test_transform->input_enum_complete == !!(test->flags & (LOADER_EXPECT_MFT_INPUT_ENUMERATED | LOADER_EXPECT_MFT_INPUT_ENUMERATED_TODO)), + "got transform input_enum_complete %u\n", test_transform->input_enum_complete); + 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) + ok(test_transform->output_type_set == SUCCEEDED(test->expected_result), + "Got transform output_type_set %u.\n", test_transform->output_type_set); + IMFTransform_Release(&test_transform->IMFTransform_iface); + } + if (handler.current_type) IMFMediaType_Release(handler.current_type); handler.current_type = NULL; @@ -3157,6 +3359,10 @@ todo_wine { ok(ref == 0, "Release returned %ld\n", ref); ref = IMFStreamDescriptor_Release(sd); ok(ref == 0, "Release returned %ld\n", ref); + if (mft_input_type && test->mft_input_type) + IMFMediaType_Release(mft_input_type); + for (j = 0; j < ARRAY_SIZE(mft_output_types) && mft_output_types[j]; ++j) + IMFMediaType_Release(mft_output_types[j]); winetest_pop_context(); } @@ -3171,6 +3377,7 @@ 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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9947
There are some failures on the CI. Is this something new? I get different set of failures locally. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9947#note_127764
On Tue Jan 27 13:55:29 2026 +0000, Nikolay Sivov wrote:
There are some failures on the CI. Is this something new? I get different set of failures locally. The CI failures are in new tests, in the decoded video type. I get different failures locally too, in audio not video. I could add alternate expected decoded types, and maybe limit which attributes are checked. What do you think?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9947#note_128144
On Tue Jan 27 13:55:29 2026 +0000, Conor McCarthy wrote:
The CI failures are in new tests, in the decoded video type. I get different failures locally too, in audio not video. I could add alternate expected decoded types, and maybe limit which attributes are checked. What do you think? I think test data that works everywhere is better than multiple variants.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9947#note_128145
On Tue Jan 27 13:58:18 2026 +0000, Nikolay Sivov wrote:
I think test data that works everywhere is better than multiple variants. Different Windows versions and/or combinations of version and hardware select different decoded types for two video tests. The decoded type test can be skipped entirely there, since it's not particularly relevant, if that's ok. Not sure about audio; I need to look at the details in Windows. Those failures already existed.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9947#note_128146
On Tue Jan 27 14:04:01 2026 +0000, Conor McCarthy wrote:
Different Windows versions and/or combinations of version and hardware select different decoded types for two video tests. The decoded type test can be skipped entirely there, since it's not particularly relevant, if that's ok. Not sure about audio; I need to look at the details in Windows. Those failures already existed. Are there any aspects of it that we want to test, and that are stable?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9947#note_128147
On Tue Jan 27 14:08:35 2026 +0000, Nikolay Sivov wrote:
Are there any aspects of it that we want to test, and that are stable? The subtype is not stable, which means the sample size and stride are not either. We could check frame size and a few other things.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9947#note_128148
On Tue Jan 27 14:12:25 2026 +0000, Conor McCarthy wrote:
The subtype is not stable, which means the sample size and stride are not either. We could check frame size and a few other things. I see, we could infer size/stride from subtype + frame size I suppose. Expected values do not all have to be static. And then verify that subtype in a hopefully small list of acceptable types.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9947#note_128149
On Tue Jan 27 14:15:30 2026 +0000, Nikolay Sivov wrote:
I see, we could infer size/stride from subtype + frame size I suppose. Expected values do not all have to be static. And then verify that subtype in a hopefully small list of acceptable types. They would need to be treated as special cases because currently we specify a struct media_type_desc and it tries to match everything there.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9947#note_128150
On Tue Jan 27 14:18:35 2026 +0000, Conor McCarthy wrote:
They would need to be treated as special cases because currently we specify a struct media_type_desc and it tries to match everything there. These decoded type mismatches only occur where the type is not sent to the sink, but is instead converted to RGB, so it's invisible to the app unless it goes poking around in the topology.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/9947#note_128151
participants (3)
-
Conor McCarthy -
Conor McCarthy (@cmccarthy) -
Nikolay Sivov (@nsivov)