From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/mf/tests/transform.c | 746 ++++++++++++++++++++++++++++++++++---- 1 file changed, 681 insertions(+), 65 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index b41f87afabe..5717ed0d2ab 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4971,6 +4971,37 @@ static void test_wmv_decoder(void) ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), {0}, }; + const struct attribute_desc output_type_desc_negative_stride[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, -actual_width), + {0}, + }; + const struct attribute_desc output_type_desc_rgb[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + {0}, + }; + const struct attribute_desc output_type_desc_rgb_negative_stride[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, -actual_width * 4), + {0}, + }; + const struct attribute_desc output_type_desc_rgb_positive_stride[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 4), + {0}, + }; const struct attribute_desc expect_input_type_desc[] = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), @@ -4992,12 +5023,57 @@ static void test_wmv_decoder(void) ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), {0}, }; + const struct attribute_desc expect_output_type_desc_rgb[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 4), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 4), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_VIDEO_NOMINAL_RANGE, 2), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + {0}, + }; + const struct attribute_desc expect_output_type_desc_rgb_negative_stride[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, -actual_width * 4), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 4), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_VIDEO_NOMINAL_RANGE, 2), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + {0}, + }; + const struct attribute_desc expect_output_type_desc_rgb_positive_stride[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 4), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 4), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_VIDEO_NOMINAL_RANGE, 2), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + {0}, + }; const MFT_OUTPUT_STREAM_INFO expect_output_info = { .dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_DISCARDABLE, .cbSize = 0x3600, .cbAlignment = 1, }; + const MFT_OUTPUT_STREAM_INFO expect_output_info_rgb = + { + .dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_DISCARDABLE, + .cbSize = 0x9000, + .cbAlignment = 1, + }; const MFT_OUTPUT_STREAM_INFO empty_output_info = { .dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_DISCARDABLE, @@ -5007,6 +5083,11 @@ static void test_wmv_decoder(void) .cbSize = 0x3600, .cbAlignment = 1, }; + const MFT_INPUT_STREAM_INFO expect_input_info_rgb = + { + .cbSize = 0x9000, + .cbAlignment = 1, + };
const struct attribute_desc output_sample_attributes[] = { @@ -5018,12 +5099,23 @@ static void test_wmv_decoder(void) .length = actual_width * actual_height * 3 / 2, .compare = compare_nv12, .dump = dump_nv12, .rect = {.right = 82, .bottom = 84}, }; + const struct buffer_desc output_buffer_desc_rgb = + { + .length = actual_width * actual_height * 4, + .compare = compare_rgb32, .dump = dump_rgb32, .rect = {.right = 82, .bottom = 84}, + }; const struct sample_desc output_sample_desc_nv12 = { .attributes = output_sample_attributes, .sample_time = 0, .sample_duration = 333333, .buffer_count = 1, .buffers = &output_buffer_desc_nv12, }; + const struct sample_desc output_sample_desc_rgb = + { + .attributes = output_sample_attributes, + .sample_time = 0, .sample_duration = 333333, + .buffer_count = 1, .buffers = &output_buffer_desc_rgb, + };
MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Video, MFVideoFormat_NV12}; MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Video, MFVideoFormat_WMV1}; @@ -5114,6 +5206,12 @@ static void test_wmv_decoder(void) ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); ok(i == ARRAY_SIZE(expect_available_outputs), "%lu input media types\n", i);
+ /* WMV1 -> YUV */ + winetest_push_context("WMV1 -> YUV"); + check_mft_set_input_type_required(transform, input_type_desc); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type_(transform, expect_input_type_desc, FALSE, TRUE); + check_mft_set_output_type_required(transform, output_type_desc); check_mft_set_output_type(transform, output_type_desc, S_OK); check_mft_get_output_current_type_(transform, expect_output_type_desc, FALSE, TRUE); @@ -5158,6 +5256,211 @@ static void test_wmv_decoder(void) ret = check_mf_sample_collection(output_samples, &output_sample_desc_nv12, L"nv12frame.bmp"); ok(ret == 0, "got %lu%% diff\n", ret); IMFCollection_Release(output_samples); + winetest_pop_context(); + + winetest_push_context("WMV1 -> YUV (negative strive)"); + check_mft_set_input_type_required(transform, input_type_desc); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type_(transform, expect_input_type_desc, FALSE, TRUE); + + check_mft_set_output_type_required(transform, output_type_desc_negative_stride); + check_mft_set_output_type(transform, output_type_desc_negative_stride, S_OK); + check_mft_get_output_current_type_(transform, expect_output_type_desc, FALSE, TRUE); + + check_mft_get_input_stream_info(transform, S_OK, &expect_input_info); + check_mft_get_output_stream_info(transform, S_OK, &expect_output_info); + + load_resource(L"wmvencdata.bin", &wmvenc_data, &wmvenc_data_len); + + input_sample = create_sample(wmvenc_data + sizeof(DWORD), *(DWORD *)wmvenc_data); + wmvenc_data_len -= *(DWORD *)wmvenc_data + sizeof(DWORD); + wmvenc_data += *(DWORD *)wmvenc_data + sizeof(DWORD); + hr = IMFSample_SetSampleTime(input_sample, 0); + ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); + hr = IMFSample_SetSampleDuration(input_sample, 333333); + ok(hr == S_OK, "SetSampleDuration returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); + ret = IMFSample_Release(input_sample); + ok(ret <= 1, "Release returned %ld\n", ret); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + output_sample = create_sample(NULL, expect_output_info.cbSize); + for (i = 0; SUCCEEDED(hr = check_mft_process_output(transform, output_sample, &output_status)); i++) + { + winetest_push_context("%lu", i); + ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr); + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output_sample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + ref = IMFSample_Release(output_sample); + ok(ref == 1, "Release returned %ld\n", ref); + output_sample = create_sample(NULL, expect_output_info.cbSize); + winetest_pop_context(); + } + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ret = IMFSample_Release(output_sample); + ok(ret == 0, "Release returned %lu\n", ret); + ok(i == 1, "got %lu output samples\n", i); + + ret = check_mf_sample_collection(output_samples, &output_sample_desc_nv12, L"nv12frame.bmp"); + ok(ret == 0, "got %lu%% diff\n", ret); + IMFCollection_Release(output_samples); + winetest_pop_context(); + + winetest_push_context("WMV1 -> RGB"); + check_mft_set_input_type_required(transform, input_type_desc); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type_(transform, expect_input_type_desc, FALSE, TRUE); + + check_mft_set_output_type_required(transform, output_type_desc_rgb); + check_mft_set_output_type(transform, output_type_desc_rgb, S_OK); + check_mft_get_output_current_type_(transform, expect_output_type_desc_rgb, FALSE, TRUE); + + check_mft_get_input_stream_info(transform, S_OK, &expect_input_info_rgb); + check_mft_get_output_stream_info(transform, S_OK, &expect_output_info_rgb); + + load_resource(L"wmvencdata.bin", &wmvenc_data, &wmvenc_data_len); + + input_sample = create_sample(wmvenc_data + sizeof(DWORD), *(DWORD *)wmvenc_data); + wmvenc_data_len -= *(DWORD *)wmvenc_data + sizeof(DWORD); + wmvenc_data += *(DWORD *)wmvenc_data + sizeof(DWORD); + hr = IMFSample_SetSampleTime(input_sample, 0); + ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); + hr = IMFSample_SetSampleDuration(input_sample, 333333); + ok(hr == S_OK, "SetSampleDuration returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); + ret = IMFSample_Release(input_sample); + ok(ret <= 1, "Release returned %ld\n", ret); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + output_sample = create_sample(NULL, expect_output_info_rgb.cbSize); + for (i = 0; SUCCEEDED(hr = check_mft_process_output(transform, output_sample, &output_status)); i++) + { + winetest_push_context("%lu", i); + ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr); + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output_sample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + ref = IMFSample_Release(output_sample); + ok(ref == 1, "Release returned %ld\n", ref); + output_sample = create_sample(NULL, expect_output_info_rgb.cbSize); + winetest_pop_context(); + } + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ret = IMFSample_Release(output_sample); + ok(ret == 0, "Release returned %lu\n", ret); + ok(i == 1, "got %lu output samples\n", i); + + ret = check_mf_sample_collection(output_samples, &output_sample_desc_rgb, L"rgb32frame-vp.bmp"); + ok(ret == 0, "got %lu%% diff\n", ret); + IMFCollection_Release(output_samples); + winetest_pop_context(); + + winetest_push_context("WMV1 -> RGB (negative stride)"); + check_mft_set_input_type_required(transform, input_type_desc); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type_(transform, expect_input_type_desc, FALSE, TRUE); + + check_mft_set_output_type_required(transform, output_type_desc_rgb_negative_stride); + check_mft_set_output_type(transform, output_type_desc_rgb_negative_stride, S_OK); + check_mft_get_output_current_type_(transform, expect_output_type_desc_rgb_negative_stride, FALSE, TRUE); + + check_mft_get_input_stream_info(transform, S_OK, &expect_input_info_rgb); + check_mft_get_output_stream_info(transform, S_OK, &expect_output_info_rgb); + + load_resource(L"wmvencdata.bin", &wmvenc_data, &wmvenc_data_len); + + input_sample = create_sample(wmvenc_data + sizeof(DWORD), *(DWORD *)wmvenc_data); + wmvenc_data_len -= *(DWORD *)wmvenc_data + sizeof(DWORD); + wmvenc_data += *(DWORD *)wmvenc_data + sizeof(DWORD); + hr = IMFSample_SetSampleTime(input_sample, 0); + ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); + hr = IMFSample_SetSampleDuration(input_sample, 333333); + ok(hr == S_OK, "SetSampleDuration returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); + ret = IMFSample_Release(input_sample); + ok(ret <= 1, "Release returned %ld\n", ret); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + output_sample = create_sample(NULL, expect_output_info_rgb.cbSize); + for (i = 0; SUCCEEDED(hr = check_mft_process_output(transform, output_sample, &output_status)); i++) + { + winetest_push_context("%lu", i); + ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr); + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output_sample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + ref = IMFSample_Release(output_sample); + ok(ref == 1, "Release returned %ld\n", ref); + output_sample = create_sample(NULL, expect_output_info_rgb.cbSize); + winetest_pop_context(); + } + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ret = IMFSample_Release(output_sample); + ok(ret == 0, "Release returned %lu\n", ret); + ok(i == 1, "got %lu output samples\n", i); + + ret = check_mf_sample_collection(output_samples, &output_sample_desc_rgb, L"rgb32frame-vp.bmp"); + ok(ret == 0, "got %lu%% diff\n", ret); + IMFCollection_Release(output_samples); + winetest_pop_context(); + + winetest_push_context("WMV1 -> RGB (positive stride)"); + check_mft_set_input_type_required(transform, input_type_desc); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type_(transform, expect_input_type_desc, FALSE, TRUE); + + check_mft_set_output_type_required(transform, output_type_desc_rgb_positive_stride); + check_mft_set_output_type(transform, output_type_desc_rgb_positive_stride, S_OK); + check_mft_get_output_current_type_(transform, expect_output_type_desc_rgb_positive_stride, FALSE, TRUE); + + check_mft_get_input_stream_info(transform, S_OK, &expect_input_info_rgb); + check_mft_get_output_stream_info(transform, S_OK, &expect_output_info_rgb); + + load_resource(L"wmvencdata.bin", &wmvenc_data, &wmvenc_data_len); + + input_sample = create_sample(wmvenc_data + sizeof(DWORD), *(DWORD *)wmvenc_data); + wmvenc_data_len -= *(DWORD *)wmvenc_data + sizeof(DWORD); + wmvenc_data += *(DWORD *)wmvenc_data + sizeof(DWORD); + hr = IMFSample_SetSampleTime(input_sample, 0); + ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); + hr = IMFSample_SetSampleDuration(input_sample, 333333); + ok(hr == S_OK, "SetSampleDuration returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); + ret = IMFSample_Release(input_sample); + ok(ret <= 1, "Release returned %ld\n", ret); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + output_sample = create_sample(NULL, expect_output_info_rgb.cbSize); + for (i = 0; SUCCEEDED(hr = check_mft_process_output(transform, output_sample, &output_status)); i++) + { + winetest_push_context("%lu", i); + ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr); + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output_sample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + ref = IMFSample_Release(output_sample); + ok(ref == 1, "Release returned %ld\n", ref); + output_sample = create_sample(NULL, expect_output_info_rgb.cbSize); + winetest_pop_context(); + } + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ret = IMFSample_Release(output_sample); + ok(ret == 0, "Release returned %lu\n", ret); + ok(i == 1, "got %lu output samples\n", i); + + ret = check_mf_sample_collection(output_samples, &output_sample_desc_rgb, L"rgb32frame-vp.bmp"); + ok(ret == 0, "got %lu%% diff\n", ret); + IMFCollection_Release(output_samples); + winetest_pop_context();
skip_tests: ret = IMFTransform_Release(transform); @@ -5591,6 +5894,22 @@ static void test_color_convert(void) ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), {0}, }; + const struct attribute_desc output_type_desc_negative_stride[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, -actual_width * 4), + {0}, + }; + const struct attribute_desc output_type_desc_positive_stride[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 4), + {0}, + }; const struct attribute_desc expect_input_type_desc[] = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), @@ -5616,6 +5935,18 @@ static void test_color_convert(void) ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), {0}, }; + const struct attribute_desc expect_output_type_desc_negativestride[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, -actual_width * 4), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 4), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + {0}, + }; const MFT_OUTPUT_STREAM_INFO output_info = { .cbSize = actual_width * actual_height * 4, @@ -5659,61 +5990,183 @@ static void test_color_convert(void) hr = CoInitialize(NULL); ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr);
- winetest_push_context("colorconv"); + winetest_push_context("colorconv"); + + if (!check_mft_enum(MFT_CATEGORY_VIDEO_EFFECT, &input_type, &output_type, class_id)) + goto failed; + check_mft_get_info(class_id, &expect_mft_info); + check_dmo_get_info(class_id, &expect_dmo_info); + + if (FAILED(hr = CoCreateInstance(class_id, NULL, CLSCTX_INPROC_SERVER, + &IID_IMFTransform, (void **)&transform))) + goto failed; + + check_interface(transform, &IID_IMFTransform, TRUE); + check_interface(transform, &IID_IMediaObject, TRUE); + check_interface(transform, &IID_IPropertyStore, TRUE); + todo_wine + check_interface(transform, &IID_IPropertyBag, FALSE); + todo_wine + check_interface(transform, &IID_IMFRealTimeClient, TRUE); + /* check_interface(transform, &IID_IWMColorConvProps, TRUE); */ + + check_mft_optional_methods(transform, 1); + check_mft_get_attributes(transform, NULL, FALSE); + check_mft_get_input_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, NULL); + check_mft_get_output_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, NULL); + + i = -1; + while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, ++i, &media_type))) + { + winetest_push_context("out %lu", i); + ok(hr == S_OK, "GetOutputAvailableType returned %#lx\n", hr); + check_media_type(media_type, expect_available_common, -1); + check_media_type(media_type, expect_available_outputs[i], -1); + ret = IMFMediaType_Release(media_type); + ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context(); + } + ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); + ok(i == 16, "%lu output media types\n", i); + + i = -1; + while (SUCCEEDED(hr = IMFTransform_GetInputAvailableType(transform, 0, ++i, &media_type))) + { + winetest_push_context("in %lu", i); + ok(hr == S_OK, "GetInputAvailableType returned %#lx\n", hr); + check_media_type(media_type, expect_available_common, -1); + check_media_type(media_type, expect_available_inputs[i], -1); + ret = IMFMediaType_Release(media_type); + ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context(); + } + ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr); + ok(i == 20, "%lu input media types\n", i); + + winetest_push_context("YUV -> RGB"); + check_mft_set_output_type_required(transform, output_type_desc); + check_mft_set_output_type(transform, output_type_desc, S_OK); + check_mft_get_output_current_type_(transform, expect_output_type_desc, FALSE, TRUE); + + check_mft_set_input_type_required(transform, input_type_desc); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type_(transform, expect_input_type_desc, FALSE, TRUE); + + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &output_info); + + load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len); + /* skip BMP header and RGB data from the dump */ + length = *(DWORD *)(nv12frame_data + 2); + nv12frame_data_len = nv12frame_data_len - length; + nv12frame_data = nv12frame_data + length; + ok(nv12frame_data_len == 13824, "got length %lu\n", nv12frame_data_len); + + input_sample = create_sample(nv12frame_data, nv12frame_data_len); + hr = IMFSample_SetSampleTime(input_sample, 0); + ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); + hr = IMFSample_SetSampleDuration(input_sample, 10000000); + ok(hr == S_OK, "SetSampleDuration returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0); + ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); + ret = IMFSample_Release(input_sample); + ok(ret <= 1, "Release returned %ld\n", ret); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + output_sample = create_sample(NULL, output_info.cbSize); + hr = check_mft_process_output(transform, output_sample, &output_status); + ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr); + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output_sample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + ref = IMFSample_Release(output_sample); + ok(ref == 1, "Release returned %ld\n", ref); + + ret = check_mf_sample_collection(output_samples, &output_sample_desc, L"rgb32frame.bmp"); + ok(ret <= 4 /* small and harmless diff in Wine vs Windows */, "got %lu%% diff\n", ret); + IMFCollection_Release(output_samples); + + output_sample = create_sample(NULL, output_info.cbSize); + hr = check_mft_process_output(transform, output_sample, &output_status); + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + hr = IMFSample_GetTotalLength(output_sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + ok(length == 0, "got length %lu\n", length); + ret = IMFSample_Release(output_sample); + ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context(); + + winetest_push_context("YUV -> RGB (negative stride)"); + check_mft_set_output_type_required(transform, output_type_desc_negative_stride); + check_mft_set_output_type(transform, output_type_desc_negative_stride, S_OK); + check_mft_get_output_current_type_(transform, expect_output_type_desc_negativestride, FALSE, TRUE); + + check_mft_set_input_type_required(transform, input_type_desc); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type_(transform, expect_input_type_desc, FALSE, TRUE); + + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &output_info); + + load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len); + /* skip BMP header and RGB data from the dump */ + length = *(DWORD *)(nv12frame_data + 2); + nv12frame_data_len = nv12frame_data_len - length; + nv12frame_data = nv12frame_data + length; + ok(nv12frame_data_len == 13824, "got length %lu\n", nv12frame_data_len); + + input_sample = create_sample(nv12frame_data, nv12frame_data_len); + hr = IMFSample_SetSampleTime(input_sample, 0); + ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); + hr = IMFSample_SetSampleDuration(input_sample, 10000000); + ok(hr == S_OK, "SetSampleDuration returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0); + ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); + ret = IMFSample_Release(input_sample); + ok(ret <= 1, "Release returned %ld\n", ret);
- if (!check_mft_enum(MFT_CATEGORY_VIDEO_EFFECT, &input_type, &output_type, class_id)) - goto failed; - check_mft_get_info(class_id, &expect_mft_info); - check_dmo_get_info(class_id, &expect_dmo_info); + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr);
- if (FAILED(hr = CoCreateInstance(class_id, NULL, CLSCTX_INPROC_SERVER, - &IID_IMFTransform, (void **)&transform))) - goto failed; + output_sample = create_sample(NULL, output_info.cbSize); + hr = check_mft_process_output(transform, output_sample, &output_status); + ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr); + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output_sample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + ref = IMFSample_Release(output_sample); + ok(ref == 1, "Release returned %ld\n", ref);
- check_interface(transform, &IID_IMFTransform, TRUE); - check_interface(transform, &IID_IMediaObject, TRUE); - check_interface(transform, &IID_IPropertyStore, TRUE); - todo_wine - check_interface(transform, &IID_IPropertyBag, FALSE); + ret = check_mf_sample_collection(output_samples, &output_sample_desc, L"rgb32frame-vp.bmp"); todo_wine - check_interface(transform, &IID_IMFRealTimeClient, TRUE); - /* check_interface(transform, &IID_IWMColorConvProps, TRUE); */ - - check_mft_optional_methods(transform, 1); - check_mft_get_attributes(transform, NULL, FALSE); - check_mft_get_input_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, NULL); - check_mft_get_output_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, NULL); - - i = -1; - while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, ++i, &media_type))) - { - winetest_push_context("out %lu", i); - ok(hr == S_OK, "GetOutputAvailableType returned %#lx\n", hr); - check_media_type(media_type, expect_available_common, -1); - check_media_type(media_type, expect_available_outputs[i], -1); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); - winetest_pop_context(); - } - ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); - ok(i == 16, "%lu output media types\n", i); + ok(ret <= 4 /* small and harmless diff in Wine vs Windows */, "got %lu%% diff\n", ret); + IMFCollection_Release(output_samples);
- i = -1; - while (SUCCEEDED(hr = IMFTransform_GetInputAvailableType(transform, 0, ++i, &media_type))) - { - winetest_push_context("in %lu", i); - ok(hr == S_OK, "GetInputAvailableType returned %#lx\n", hr); - check_media_type(media_type, expect_available_common, -1); - check_media_type(media_type, expect_available_inputs[i], -1); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); - winetest_pop_context(); - } - ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr); - ok(i == 20, "%lu input media types\n", i); + output_sample = create_sample(NULL, output_info.cbSize); + hr = check_mft_process_output(transform, output_sample, &output_status); + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + hr = IMFSample_GetTotalLength(output_sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + ok(length == 0, "got length %lu\n", length); + ret = IMFSample_Release(output_sample); + ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context();
- check_mft_set_output_type_required(transform, output_type_desc); - check_mft_set_output_type(transform, output_type_desc, S_OK); + winetest_push_context("YUV -> RGB (positive stride)"); + check_mft_set_output_type_required(transform, output_type_desc_positive_stride); + check_mft_set_output_type(transform, output_type_desc_positive_stride, S_OK); check_mft_get_output_current_type_(transform, expect_output_type_desc, FALSE, TRUE);
check_mft_set_input_type_required(transform, input_type_desc); @@ -5769,6 +6222,7 @@ static void test_color_convert(void) ok(length == 0, "got length %lu\n", length); ret = IMFSample_Release(output_sample); ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context();
ret = IMFTransform_Release(transform); ok(ret == 0, "Release returned %ld\n", ret); @@ -5944,6 +6398,24 @@ static void test_video_processor(void) ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), {0}, }; + const struct attribute_desc output_type_desc_negative_stride[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, -actual_width * 4), + {0}, + }; + const struct attribute_desc output_type_desc_positive_stride[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 4), + {0}, + }; const MFT_OUTPUT_STREAM_INFO initial_output_info = {0}; const MFT_INPUT_STREAM_INFO initial_input_info = {0}; MFT_OUTPUT_STREAM_INFO output_info = {0}; @@ -6285,6 +6757,7 @@ static void test_video_processor(void) ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr); ok(i == 22 || i == 30 || broken(i == 26) /* w1064v1507 */, "%lu input media types\n", i);
+ winetest_push_context("YUV -> RGB"); check_mft_set_input_type_required(transform, input_type_desc); check_mft_set_input_type(transform, input_type_desc); check_mft_get_input_current_type(transform, input_type_desc); @@ -6328,31 +6801,174 @@ static void test_video_processor(void) if (hr != S_OK) { win_skip("ProcessOutput returned MF_E_SHUTDOWN, skipping tests.\n"); - goto skip_output; } - ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + else + { + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status);
- hr = IMFCollection_AddElement(output_samples, (IUnknown *)output_sample); - ok(hr == S_OK, "AddElement returned %#lx\n", hr); - ref = IMFSample_Release(output_sample); - ok(ref == 1, "Release returned %ld\n", ref); + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output_sample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + ref = IMFSample_Release(output_sample); + ok(ref == 1, "Release returned %ld\n", ref);
- ret = check_mf_sample_collection(output_samples, &output_sample_desc, L"rgb32frame-vp.bmp"); - todo_wine - ok(ret == 0 || broken(ret == 25) /* w1064v1507 / w1064v1809 incorrectly rescale */, "got %lu%% diff\n", ret); - IMFCollection_Release(output_samples); + ret = check_mf_sample_collection(output_samples, &output_sample_desc, L"rgb32frame-vp.bmp"); + todo_wine + ok(ret == 0 || broken(ret == 25) /* w1064v1507 / w1064v1809 incorrectly rescale */, "got %lu%% diff\n", ret); + IMFCollection_Release(output_samples); + + output_sample = create_sample(NULL, output_info.cbSize); + hr = check_mft_process_output(transform, output_sample, &output_status); + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + hr = IMFSample_GetTotalLength(output_sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + ok(length == 0, "got length %lu\n", length); + } + ret = IMFSample_Release(output_sample); + ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context(); + + winetest_push_context("YUV -> RGB (negative stride)"); + check_mft_set_input_type_required(transform, input_type_desc); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type(transform, input_type_desc); + + check_mft_set_output_type_required(transform, output_type_desc_negative_stride); + check_mft_set_output_type(transform, output_type_desc_negative_stride, S_OK); + check_mft_get_output_current_type(transform, output_type_desc_negative_stride); + + input_info.cbSize = actual_width * actual_height * 3 / 2; + output_info.cbSize = actual_width * actual_height * 4; + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &output_info); + + load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len); + /* skip BMP header and RGB data from the dump */ + length = *(DWORD *)(nv12frame_data + 2); + nv12frame_data_len = nv12frame_data_len - length; + nv12frame_data = nv12frame_data + length; + ok(nv12frame_data_len == 13824, "got length %lu\n", nv12frame_data_len); + + input_sample = create_sample(nv12frame_data, nv12frame_data_len); + hr = IMFSample_SetSampleTime(input_sample, 0); + ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); + hr = IMFSample_SetSampleDuration(input_sample, 10000000); + ok(hr == S_OK, "SetSampleDuration returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0); + ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); + ret = IMFSample_Release(input_sample); + ok(ret <= 1, "Release returned %ld\n", ret); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr);
output_sample = create_sample(NULL, output_info.cbSize); hr = check_mft_process_output(transform, output_sample, &output_status); - ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); - ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); - hr = IMFSample_GetTotalLength(output_sample, &length); - ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); - ok(length == 0, "got length %lu\n", length); + ok(hr == S_OK || broken(hr == MF_E_SHUTDOWN) /* w8 */, "ProcessOutput returned %#lx\n", hr); + if (hr != S_OK) + { + win_skip("ProcessOutput returned MF_E_SHUTDOWN, skipping tests.\n"); + } + else + { + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output_sample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + ref = IMFSample_Release(output_sample); + ok(ref == 1, "Release returned %ld\n", ref); + + ret = check_mf_sample_collection(output_samples, &output_sample_desc, L"rgb32frame-vp.bmp"); + todo_wine + ok(ret == 0 || broken(ret == 25) /* w1064v1507 / w1064v1809 incorrectly rescale */, "got %lu%% diff\n", ret); + IMFCollection_Release(output_samples); + + output_sample = create_sample(NULL, output_info.cbSize); + hr = check_mft_process_output(transform, output_sample, &output_status); + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + hr = IMFSample_GetTotalLength(output_sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + ok(length == 0, "got length %lu\n", length); + } + ret = IMFSample_Release(output_sample); + ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context(); + + winetest_push_context("YUV -> RGB (positive stride)"); + check_mft_set_input_type_required(transform, input_type_desc); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type(transform, input_type_desc); + + check_mft_set_output_type_required(transform, output_type_desc_positive_stride); + check_mft_set_output_type(transform, output_type_desc_positive_stride, S_OK); + check_mft_get_output_current_type(transform, output_type_desc_positive_stride); + + input_info.cbSize = actual_width * actual_height * 3 / 2; + output_info.cbSize = actual_width * actual_height * 4; + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &output_info); + + load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len); + /* skip BMP header and RGB data from the dump */ + length = *(DWORD *)(nv12frame_data + 2); + nv12frame_data_len = nv12frame_data_len - length; + nv12frame_data = nv12frame_data + length; + ok(nv12frame_data_len == 13824, "got length %lu\n", nv12frame_data_len); + + input_sample = create_sample(nv12frame_data, nv12frame_data_len); + hr = IMFSample_SetSampleTime(input_sample, 0); + ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); + hr = IMFSample_SetSampleDuration(input_sample, 10000000); + ok(hr == S_OK, "SetSampleDuration returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0); + ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); + ret = IMFSample_Release(input_sample); + ok(ret <= 1, "Release returned %ld\n", ret); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + output_sample = create_sample(NULL, output_info.cbSize); + hr = check_mft_process_output(transform, output_sample, &output_status); + ok(hr == S_OK || broken(hr == MF_E_SHUTDOWN) /* w8 */, "ProcessOutput returned %#lx\n", hr); + if (hr != S_OK) + { + win_skip("ProcessOutput returned MF_E_SHUTDOWN, skipping tests.\n"); + } + else + { + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status);
-skip_output: + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output_sample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + ref = IMFSample_Release(output_sample); + ok(ref == 1, "Release returned %ld\n", ref); + + ret = check_mf_sample_collection(output_samples, &output_sample_desc, L"rgb32frame.bmp"); + todo_wine + ok(ret <= 6 || broken(ret <= 32) /* w1064v1507 / w1064v1809 incorrectly rescale */, "got %lu%% diff\n", ret); + IMFCollection_Release(output_samples); + + output_sample = create_sample(NULL, output_info.cbSize); + hr = check_mft_process_output(transform, output_sample, &output_status); + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + hr = IMFSample_GetTotalLength(output_sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + ok(length == 0, "got length %lu\n", length); + } ret = IMFSample_Release(output_sample); ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context();
ret = IMFTransform_Release(transform); ok(ret == 0, "Release returned %ld\n", ret);