From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/transform.c | 541 +++++++++++++++++++++----------------- 1 file changed, 306 insertions(+), 235 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 4c650b33297..d700f8a222b 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -444,6 +444,51 @@ static void check_mft_set_input_type_required_(int line, IMFTransform *transform ok_(__FILE__, line)(!ref, "Release returned %lu\n", ref); }
+static void check_mft_set_input_type(IMFTransform *transform, const struct attribute_desc *attributes) +{ + IMFMediaType *media_type; + HRESULT hr; + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "MFCreateMediaType returned hr %#lx.\n", hr); + init_media_type(media_type, attributes, -1); + + hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY); + ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); + hr = IMFTransform_SetInputType(transform, 0, media_type, 0); + ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); + + IMFMediaType_Release(media_type); +} + +#define check_mft_get_input_current_type(a, b) check_mft_get_input_current_type_(a, b, FALSE, FALSE) +static void check_mft_get_input_current_type_(IMFTransform *transform, const struct attribute_desc *attributes, + BOOL todo_current, BOOL todo_compare) +{ + HRESULT hr, expect_hr = attributes ? S_OK : MF_E_TRANSFORM_TYPE_NOT_SET; + IMFMediaType *media_type, *current_type; + BOOL result; + + hr = IMFTransform_GetInputCurrentType(transform, 0, ¤t_type); + todo_wine_if(todo_current) + ok(hr == expect_hr, "GetInputCurrentType returned hr %#lx.\n", hr); + if (FAILED(hr)) + return; + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "MFCreateMediaType returned hr %#lx.\n", hr); + init_media_type(media_type, attributes, -1); + + hr = IMFMediaType_Compare(current_type, (IMFAttributes *)media_type, + MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result); + ok(hr == S_OK, "Compare returned hr %#lx.\n", hr); + todo_wine_if(todo_compare) + ok(result, "got result %u.\n", !!result); + + IMFMediaType_Release(media_type); + IMFMediaType_Release(current_type); +} + #define check_mft_set_output_type_required(a, b) check_mft_set_output_type_required_(__LINE__, a, b) static void check_mft_set_output_type_required_(int line, IMFTransform *transform, const struct attribute_desc *attributes) { @@ -474,6 +519,52 @@ static void check_mft_set_output_type_required_(int line, IMFTransform *transfor ok_(__FILE__, line)(!ref, "Release returned %lu\n", ref); }
+static void check_mft_set_output_type(IMFTransform *transform, const struct attribute_desc *attributes, + HRESULT expect_hr) +{ + IMFMediaType *media_type; + HRESULT hr; + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "MFCreateMediaType returned hr %#lx.\n", hr); + init_media_type(media_type, attributes, -1); + + hr = IMFTransform_SetOutputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY); + ok(hr == expect_hr, "SetOutputType returned %#lx.\n", hr); + hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); + ok(hr == expect_hr, "SetOutputType returned %#lx.\n", hr); + + IMFMediaType_Release(media_type); +} + +#define check_mft_get_output_current_type(a, b) check_mft_get_output_current_type_(a, b, FALSE, FALSE) +static void check_mft_get_output_current_type_(IMFTransform *transform, const struct attribute_desc *attributes, + BOOL todo_current, BOOL todo_compare) +{ + HRESULT hr, expect_hr = attributes ? S_OK : MF_E_TRANSFORM_TYPE_NOT_SET; + IMFMediaType *media_type, *current_type; + BOOL result; + + hr = IMFTransform_GetOutputCurrentType(transform, 0, ¤t_type); + todo_wine_if(todo_current) + ok(hr == expect_hr, "GetOutputCurrentType returned hr %#lx.\n", hr); + if (FAILED(hr)) + return; + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "MFCreateMediaType returned hr %#lx.\n", hr); + init_media_type(media_type, attributes, -1); + + hr = IMFMediaType_Compare(current_type, (IMFAttributes *)media_type, + MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result); + ok(hr == S_OK, "Compare returned hr %#lx.\n", hr); + todo_wine_if(todo_compare) + ok(result, "got result %u.\n", !!result); + + IMFMediaType_Release(media_type); + IMFMediaType_Release(current_type); +} + #define check_mft_process_output(a, b, c) check_mft_process_output_(__LINE__, a, b, c) static HRESULT check_mft_process_output_(int line, IMFTransform *transform, IMFSample *output_sample, DWORD *output_status) { @@ -1102,17 +1193,8 @@ static void test_sample_copier(void) hr = IMFTransform_GetOutputAvailableType(copier, 1, 0, &mediatype); ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
- hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr); - - hr = IMFTransform_GetInputCurrentType(copier, 1, &mediatype); - ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr); - - hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr); - - hr = IMFTransform_GetOutputCurrentType(copier, 1, &mediatype); - ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr); + check_mft_get_input_current_type(copier, NULL); + check_mft_get_output_current_type(copier, NULL);
hr = MFCreateSample(&sample); ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr); @@ -1156,8 +1238,7 @@ static void test_sample_copier(void) ok(hr == S_OK, "Failed to get current type, hr %#lx.\n", hr); IMFMediaType_Release(mediatype2);
- hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype2); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr); + check_mft_get_input_current_type(copier, NULL);
hr = IMFTransform_GetInputStatus(copier, 0, &flags); ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr); @@ -1543,7 +1624,6 @@ static void test_aac_encoder(void)
MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Audio, MFAudioFormat_AAC}; MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Audio, MFAudioFormat_PCM}; - IMFMediaType *media_type; IMFTransform *transform; HRESULT hr; ULONG ret; @@ -1571,37 +1651,13 @@ static void test_aac_encoder(void) check_mft_get_input_stream_info(transform, &input_info); check_mft_get_output_stream_info(transform, &initial_output_info);
- check_mft_set_input_type_required(transform, input_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, input_type_desc, -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 1, "Release returned %lu\n", ret); - 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);
- hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 1, "Release returned %lu\n", ret); - - hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type); - ok(hr == S_OK, "GetInputCurrentType returned %#lx.\n", hr); - check_media_type(media_type, expect_input_type_desc, -1); - ret = IMFMediaType_Release(media_type); - ok(ret <= 1, "Release returned %lu\n", ret); - - hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type); - ok(hr == S_OK, "GetOutputCurrentType returned %#lx.\n", hr); - check_media_type(media_type, expect_output_type_desc, -1); - ret = IMFMediaType_Release(media_type); - ok(ret <= 1, "Release returned %lu\n", ret); + 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);
check_mft_get_input_stream_info(transform, &input_info); check_mft_get_output_stream_info(transform, &output_info); @@ -1790,24 +1846,12 @@ static void test_aac_decoder(void) "%lu input media types\n", i);
/* setting output media type first doesn't work */ - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_set_output_type(transform, output_type_desc, MF_E_TRANSFORM_TYPE_NOT_SET); + check_mft_get_output_current_type(transform, NULL);
check_mft_set_input_type_required(transform, input_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, input_type_desc, -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 1, "Release returned %lu\n", ret); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type(transform, input_type_desc);
/* check new output media types */
@@ -1828,14 +1872,8 @@ static void test_aac_decoder(void) ok(i == ARRAY_SIZE(expect_available_outputs), "%lu input media types\n", i);
check_mft_set_output_type_required(transform, output_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 1, "Release returned %lu\n", ret); + check_mft_set_output_type(transform, output_type_desc, S_OK); + check_mft_get_output_current_type(transform, output_type_desc);
check_mft_get_input_stream_info(transform, &input_info); check_mft_get_output_stream_info(transform, &output_info); @@ -1909,6 +1947,31 @@ static void test_wma_encoder(void) ATTR_BLOB(MF_MT_USER_DATA, wma_codec_data, sizeof(wma_codec_data), .required = TRUE), {0}, }; + static const struct attribute_desc expect_input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_Float), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 32), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 8), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 22050), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 22050 * 8), + ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK, 3), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + {0}, + }; + const struct attribute_desc expect_output_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_WMAudioV8), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 22050), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 4003), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, wmaenc_block_size), + ATTR_BLOB(MF_MT_USER_DATA, wma_codec_data, sizeof(wma_codec_data)), + ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1), + {0}, + }; const MFT_OUTPUT_STREAM_INFO output_info = { .cbSize = wmaenc_block_size, @@ -1998,14 +2061,12 @@ static void test_wma_encoder(void) ok(ret == 0, "Release returned %lu\n", ret);
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);
- hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + 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);
check_mft_get_input_stream_info(transform, &input_info); check_mft_get_output_stream_info(transform, &output_info); @@ -2182,6 +2243,31 @@ static void test_wma_decoder(void) ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 2 * (16 / 8) * 22050, .required = TRUE), {0}, }; + const struct attribute_desc expect_input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_WMAudioV8), + ATTR_BLOB(MF_MT_USER_DATA, wma_codec_data, sizeof(wma_codec_data)), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, wmaenc_block_size), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 22050), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 4003), + ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1), + {0}, + }; + static const struct attribute_desc expect_output_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 22050 * 4), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 22050), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 4), + ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + {0}, + }; const MFT_INPUT_STREAM_INFO input_info = { .cbSize = wmaenc_block_size, @@ -2290,24 +2376,12 @@ static void test_wma_decoder(void) ok(i == 4, "%lu input media types\n", i);
/* setting output media type first doesn't work */ - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_set_output_type(transform, output_type_desc, MF_E_TRANSFORM_TYPE_NOT_SET); + check_mft_get_output_current_type_(transform, NULL, TRUE, FALSE);
check_mft_set_input_type_required(transform, input_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, input_type_desc, -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type_(transform, expect_input_type_desc, TRUE, FALSE);
check_mft_get_input_stream_info(transform, NULL); check_mft_get_output_stream_info(transform, NULL); @@ -2328,14 +2402,8 @@ static void test_wma_decoder(void) ok(i == 2, "%lu output media types\n", i);
check_mft_set_output_type_required(transform, output_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_set_output_type(transform, output_type_desc, S_OK); + check_mft_get_output_current_type_(transform, expect_output_type_desc, TRUE, FALSE);
check_mft_get_input_stream_info(transform, &input_info); check_mft_get_output_stream_info(transform, &output_info); @@ -2623,6 +2691,32 @@ static void test_h264_decoder(void) ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), {0}, }; + const struct attribute_desc expect_input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_H264), + ATTR_RATIO(MF_MT_FRAME_SIZE, input_width, input_height), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 0), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 0), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 0), + ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE, 0), + ATTR_UINT32(MF_MT_COMPRESSED, 1), + {0}, + }; + const struct attribute_desc expect_output_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), + ATTR_RATIO(MF_MT_FRAME_SIZE, input_width, input_height), + ATTR_RATIO(MF_MT_FRAME_RATE, 60000, 1000), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 2, 1), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 3840), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, 3840 * input_height * 3 / 2), + ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), + ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE, 0), + ATTR_UINT32(MF_MT_COMPRESSED, 0), + {0}, + }; static const struct attribute_desc new_output_type_desc[] = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), @@ -2632,6 +2726,17 @@ static void test_h264_decoder(void) ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 2), {0}, }; + static const struct attribute_desc expect_new_output_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_I420), + ATTR_RATIO(MF_MT_FRAME_SIZE, 96, 96), + ATTR_RATIO(MF_MT_FRAME_RATE, 1, 1), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 2), + ATTR_UINT32(MF_MT_COMPRESSED, 0), + ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE, 0), + {0}, + }; static const MFVideoArea actual_aperture = {.Area={82,84}}; static const DWORD actual_width = 96, actual_height = 96; const media_type_desc actual_outputs[] = @@ -2806,18 +2911,10 @@ static void test_h264_decoder(void)
hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputAvailableType returned %#lx\n", hr); - hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputCurrentType returned %#lx\n", hr);
/* setting output media type first doesn't work */ - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, default_outputs[0], -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_set_output_type(transform, output_type_desc, MF_E_TRANSFORM_TYPE_NOT_SET); + check_mft_get_output_current_type(transform, NULL);
/* check available input types */
@@ -2835,14 +2932,8 @@ static void test_h264_decoder(void) ok(i == 2 || broken(i == 1) /* Win7 */, "%lu input media types\n", i);
check_mft_set_input_type_required(transform, input_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, input_type_desc, -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 1, "Release returned %lu\n", ret); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type_(transform, expect_input_type_desc, TRUE, FALSE);
check_mft_get_input_stream_info(transform, &input_info); check_mft_get_output_stream_info(transform, &output_info); @@ -2863,20 +2954,8 @@ static void test_h264_decoder(void) ok(i == 5, "%lu output media types\n", i);
check_mft_set_output_type_required(transform, output_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 1, "Release returned %lu\n", ret); - - hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type); - ok(hr == S_OK, "GetOutputCurrentType returned %#lx\n", hr); - check_media_type(media_type, output_type_desc, -1); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + 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 that the output media type we've selected don't change the enumeration */
@@ -2966,13 +3045,7 @@ static void test_h264_decoder(void) ok(i == 5, "%lu output media types\n", i);
/* current output type is still the one we selected */ - hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type); - ok(hr == S_OK, "GetOutputCurrentType returned %#lx\n", hr); - check_media_type(media_type, output_type_desc, -1); - hr = IMFMediaType_GetItemType(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, NULL); - ok(hr == MF_E_ATTRIBUTENOTFOUND, "GetItemType returned %#lx\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_get_output_current_type_(transform, expect_output_type_desc, FALSE, TRUE);
hr = MFCreateCollection(&output_samples); ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); @@ -3002,13 +3075,7 @@ static void test_h264_decoder(void) ret = IMFMediaType_Release(media_type); ok(ret == 1, "Release returned %lu\n", ret);
- hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type); - ok(hr == S_OK, "GetOutputCurrentType returned %#lx\n", hr); - check_media_type(media_type, new_output_type_desc, -1); - hr = IMFMediaType_GetItemType(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, NULL); - ok(hr == MF_E_ATTRIBUTENOTFOUND, "GetItemType returned %#lx\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_get_output_current_type_(transform, expect_new_output_type_desc, FALSE, TRUE);
output_sample = create_sample(NULL, actual_width * actual_height * 2); hr = check_mft_process_output(transform, output_sample, &output_status); @@ -3176,6 +3243,32 @@ static void test_audio_convert(void) ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 2 * (16 / 8) * 44100, .required = TRUE), {0}, }; + static const struct attribute_desc expect_input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_Float), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 32), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 22050), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 8), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 22050 * 8), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK, 3), + {0}, + }; + const struct attribute_desc expect_output_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 4), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 * 4), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1), + {0}, + }; const MFT_OUTPUT_STREAM_INFO output_info = { .cbSize = 4, @@ -3285,24 +3378,12 @@ static void test_audio_convert(void) ok(i == 2, "%lu input media types\n", i);
/* setting output media type first doesn't work */ - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_set_output_type(transform, output_type_desc, MF_E_TRANSFORM_TYPE_NOT_SET); + check_mft_get_output_current_type(transform, NULL);
check_mft_set_input_type_required(transform, input_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, input_type_desc, -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + 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, NULL); check_mft_get_output_stream_info(transform, NULL); @@ -3323,14 +3404,8 @@ static void test_audio_convert(void) ok(i == 4, "%lu output media types\n", i);
check_mft_set_output_type_required(transform, output_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + 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_get_input_stream_info(transform, &input_info); check_mft_get_output_stream_info(transform, &output_info); @@ -3561,6 +3636,31 @@ static void test_color_convert(void) ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), {0}, }; + const struct attribute_desc expect_input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + 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 struct attribute_desc expect_output_type_desc[] = + { + 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, @@ -3666,24 +3766,12 @@ static void test_color_convert(void) ok(i == 20, "%lu input media types\n", i);
check_mft_set_output_type_required(transform, output_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + 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); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, input_type_desc, -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + 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, &input_info); check_mft_get_output_stream_info(transform, &output_info); @@ -3977,17 +4065,8 @@ static void test_video_processor(void) hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#lx.\n", hr);
- hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr); - - hr = IMFTransform_GetInputCurrentType(transform, 1, &media_type); - ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr); - - hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr); - - hr = IMFTransform_GetOutputCurrentType(transform, 1, &media_type); - ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr); + check_mft_get_input_current_type(transform, NULL); + check_mft_get_output_current_type(transform, NULL);
check_mft_get_input_stream_info(transform, &initial_input_info); check_mft_get_output_stream_info(transform, &initial_output_info); @@ -4260,24 +4339,12 @@ static void test_video_processor(void) ok(i == 22 || i == 30 || broken(i == 26) /* w1064v1507 */, "%lu input media types\n", i);
check_mft_set_input_type_required(transform, input_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, input_type_desc, -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 1, "Release returned %lu\n", ret); + 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); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 1, "Release returned %lu\n", ret); + check_mft_set_output_type(transform, output_type_desc, S_OK); + check_mft_get_output_current_type(transform, output_type_desc);
input_info.cbSize = actual_width * actual_height * 3 / 2; output_info.cbSize = actual_width * actual_height * 4; @@ -4470,6 +4537,28 @@ static void test_mp3_decoder(void) ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 2 * (16 / 8) * 22050, .required = TRUE), {0}, }; + const struct attribute_desc expect_input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_MP3), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 22050), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1), + {0}, + }; + static const struct attribute_desc expect_output_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16), + ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2), + ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 22050), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 4), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 22050 * 4), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1), + {0}, + }; const MFT_OUTPUT_STREAM_INFO output_info = { .cbSize = mp3dec_block_size, @@ -4568,24 +4657,12 @@ static void test_mp3_decoder(void) ok(i == ARRAY_SIZE(expect_available_inputs), "%lu input media types\n", i);
/* setting output media type first doesn't work */ - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_set_output_type(transform, output_type_desc, MF_E_TRANSFORM_TYPE_NOT_SET); + check_mft_get_output_current_type(transform, NULL);
check_mft_set_input_type_required(transform, input_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, input_type_desc, -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_set_input_type(transform, input_type_desc); + check_mft_get_input_current_type(transform, expect_input_type_desc);
check_mft_get_input_stream_info(transform, NULL); check_mft_get_output_stream_info(transform, NULL); @@ -4606,14 +4683,8 @@ static void test_mp3_decoder(void) ok(i == ARRAY_SIZE(expect_available_outputs), "%lu output media types\n", i);
check_mft_set_output_type_required(transform, output_type_desc); - - hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); - init_media_type(media_type, output_type_desc, -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); - ret = IMFMediaType_Release(media_type); - ok(ret == 0, "Release returned %lu\n", ret); + check_mft_set_output_type(transform, output_type_desc, S_OK); + check_mft_get_output_current_type(transform, expect_output_type_desc);
check_mft_get_input_stream_info(transform, &input_info); check_mft_get_output_stream_info(transform, &output_info);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/aacencdata.bin | Bin 0 -> 24861 bytes dlls/mf/tests/resource.rc | 3 + dlls/mf/tests/transform.c | 108 +++++++++++++++++++++++++++++++++-- 3 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 dlls/mf/tests/aacencdata.bin
diff --git a/dlls/mf/tests/aacencdata.bin b/dlls/mf/tests/aacencdata.bin new file mode 100644 index 0000000000000000000000000000000000000000..355310632fa98e5570083802779d8fc879a86da3 GIT binary patch literal 24861 zcmY(qWn9$z^FEA7H`1Nb-Ccs9v~+iOcSwt*s36@Tv4nJYcXxLzwZsy8FP`r?zyJMg zUp)H^GjqjU?_(Gk7(~~FC<R<3xDXSnViof+WNcU|iRc7cT;>Q;hDsGmDl3E$4iaLr znU(2ypZ2!L&FyOQ@q!$RISkd+&G>_@z*u$&gPrLzm*321jI!rf;||YoMT$})ll$zZ zM3BHg$UhA8vy(jUX=;3@tu!3C!^6Qljgwi=f2L#Ci8TlmA|SEPe#ME#BMd~cs4O$L zkKmnrn;J4Paa5y1zF!s(@9%Xka_V7pGU|Sj0WWXju%*r6)&Rv0bZd{~N`jFU)(^hR zCfnX<MJws(b0@IfKWe>Hj;xqkVj{G&*|^fTD$OzvG+hX{lYLa$Kz~1%5c;{ucyR9| z6B2rGiQr-BBob9<X>kxkqO{>)!c+N7WC)P~tq{^~WNw>1yH!04a%&h!9Z2?f$!KXo zEPb$q+cr_DOiOH1fqVnf8k>e~AAigTzV!94%}quewpGS_WDy)$lgh@aqOE@RLt-vt zHN^Rz5)B>~>a)d5tpY_Ho!aeMg<r9fyxn#nR<t7ON=LzG)pVukQu=iyoXp5MvK zUHIOVxc-zG?Vd|_1!sL>wZPXF`6F{|XW=(}U$th+&LnQQ$KSv<)T#B}`YOrv%um&P ziwP~35ew$COc@8Ixh<81$izTCkKZJh6v4*r%ZEEcKb)EvDI!EA5sQ|GFdUYV6H7%J zmnkyTB3KGWYLw6<xHC>HYFCXyS>(|B>3Y4!3}oHnkmUtblP7Bp<}d5w*ZUJ&2);;* zq?pHFbk3Co6DT;6+GF0`7zY_azBk<RMcyM2$AYFW+WX5meCs|2(0_zP0KD#>I2axt z&RGc>dXMMBp6+PiE@5x$-cow7&rAU??K6+FXL_$i0dd;#a_4GOqi=z+`gBF-&%B1D zmiHj7#nb$^Emzg;jGSLIDkcm`TlbUp8sElrx$&9ZdbO5|svXIGUg$Rcoa9^fZA1z5 ztyZn6$iQ&5g7;4N`FGbH_}@>b#YXCqlt`GMl_r9Rlah#1kut|dhK2q`#g>dv2L=v~ zWin!jp+n_5E8*Jl77!F)mKmYj_P9)l3^~51#?)FW`zRJAtbJleVPKJRBJ66=`|9e` z_MMS(reHS3S1wFJ3f}p_aMejkt%kj<acm_e%|<Cev&xq0RPd3n^@qs!rW66@b$)c+ zzvLtakPpieb<g$k@wY`HT*ijcjOb1e6Kn*72aL<!h_AJCZ~Xx~(79;Ti^bKCk6|1U z7dJ!7;oVhH)4U31OV9T|(6NC`YF|&A0e9+`jmYp5KNC7klYFXR;!H8Ha?u=FSw|>3 z|8=3-@$kQ|e~*U@*Cizxr9z8~jUEz0MI}c^#TXV5Mw$Ixh@%oo0!b$i{kv*#{d3Z} z?;Y~~VGBD&rT1gBW)0@~^%uhApmD=&=Q96m2D~PN&w=;jpz)+F!4|E2;I~kL+WpSx zbDt}CQ_15h2H-XDms}N}v(Kks%UT27zS!f1l68=-|Epn%xWIk#bu@J6B}xAu2x*fH zOOMk}eUaNH=KWy#5iUQnl5m-~vU-#OZDm}B$>umHm(IjZS&=Dka&r>jlCa-#e2pGv zXn2;*WMDczoR8Iaa_7%k-w8cab|hOutV-gH{_aR!Pr&#)gK_N5q1W+nQS(8u0Nktp z`W`+cgfd&2ff@xaq?3vYiGhn4?!75iF0K&Aq(mi>6e$TuZVcRQX2pknDo<VchOFYB zN<s2#I9J&ik&}^jJxAlP>mg13d!1u6?|Izz$O;RqKBnyk;gs8jY_w~uzoF~yI(oci zS>|p}V?X#T`p5M#=4$gu(;mZxoiO(R5iNp-?cng$%&Kh3V8YmB>Dv%cov(}#Uc7bD zq59F!@rgq^_R3`~Msb=prazH3rR>@z?c+14vB1UMA7bs|BsW%R<NW2{?)TmFUT<7$ zT=TJ{Ra(Wx)C|>#Q>YP5VlC{7nEB9sxLCn9IOr3W9#^nSYG>1!HE_A}J{~PNzj$c_ zXTqqD)Kp<opQ*CL7~Z@=iug>K9YsgQ85R~w#h}7OMra+5uL8%iu^93CmCQ{`UaPm> zR!^kqZvdb`!~Lrm=-3*-J0g2Kjj8?BhZ?Byxq{c*CJoC8G%Bv^+U~--an)eYY_9N& zvCo}Pei$|2@w~^3oLwb=sA=8+DB|skSRIWtv}I7Ew{Bz`c7i<TnfofJ$d2=g{d)$; z264NYr|w;LSN2i;bPyLA7>7_t$HP-(tC{JXG2vu%<*G3W-Q)QFolK(se9>NLZn;l2 zQ~f61ZQ5Pii5?@?Ty@p=H9P0D#?kKRf|Zeb@AYXx0hIs#`N&~mIT8s_Ov8qUrGgIp z%MTQ4j;Il7T&c)V%V;=CDkNw7?pGlcWXMCYnb_Ocq683kZ;BJD(y{wWijb|oYZJ)t zz&GNpPmnwn2AO%IW~H`=)1S)(?{{ka)*<5QxVOtim7lK~-;Dz!SIC$>oogLc>M6RS zdVCOXw<73^IZ)ZF=+|R^j2hTkocj>&W(ld|7aP|0N;Q0Cu!Jc35AKenuS<?6|Jgp_ z_(sB-cOs7`U^?B|AY~f$6eJPQ<hy{|bc1-AeRHU9Fs4^<pkKt!s^aW}BD>X{u3PSs z9U3HXy{>ZLa08dPJPrrM`I5q{+gDYm!8Wfc`0NJeMcqLAw;HsB;Rx@Hp`(C}3J)hK z{Y62V78xETXEG8Vwo{tQGB!o^J*?a1kBe*37O<aF(e>A%3$WrI3d6>FYA?n3qgB_> zsiCy`HeWC({V2X&{5INOYWLUTZ8-%7H_caw{+}c<Z_)hkaP21(_sM-xB^p_Zyy$`; z@X)ui_MnOGGbQvdjSrDkd)Ze;UK<8?*8bvXK8JXx#^J6X6QW&suXr9uEPq0ZfU<2% z_mDS~bW|MNrJ%YbHYM(h3$e$AgTd3}>6)n482RMyo)pAC6gC0f(Ygc~9Ab3VO=f|h zR1KgVu>Hrwd*ye96%^8kEuIc|{A&9AC8guSsT-hioDgrf$NlZE0<Zq92h~e=NMb>o z0vQSil2{YcFF)uwu@cUpxPZcv3yc5K8^N`H2y5KuB5GT=KEb{Ab6+QhR#E3SKSb5n z)nQp%Hcd#zL+YE;L7>}R^8VwbNg-!5Lf7%Aq?q<>rB$iR$!7yPOCAW>#cA-`?y#LD zfNV_cc;3XI8dKb!c9)x7Jc7jC`5WUo+{O8lWWVWywN1d+4BCa;N0rEJpME9;x<tf7 zeLXS8!_@for4rb0QSZkwrR(s2TI+dCdKu#$njiiFA0c<|6&?@@TDadmHV%cKaRUJ# z?iMFX35hOUa|HS{+!)Gl!_`R2meB1vf&AVq1Rba^MX-nR0%!}sN<oW2jgO3t^iqv{ zT%=eyDrp9H6Jyv8D$5u?XjkxS$n-}f{gB5<*+oRUxbX>PJ_O&?U}6F(^#bkFa_&QZ zfXb4$V0{EZpw*)z$EmzR(0k3X%u3Daiju|gZ?oQC@73KERfa|G&+!QI_z#Xot_@pM z^PMSIff$>oZjF5AOky=uxIz)t=FOdi<sAh5x;d!SbzE5^o4R>%c&MsvCw7v$0qOzq zw3sPQHS(=*X$~GjrMiw5E1I!KF_dxYHD{)u)TfZ+(VyP>pX5biF5pQkDl9r;ROns0 z>35@A31@@L5`WJ;vPJb-Hd}Ejm~v|S^vbxkx&p?HqLVwY{w)VJ@jr0Ef(xw+l@zob zc*tQNL!oFXjfVpNF3&QUB^USI`@gd?zbfGZa(|Y^-JYoj`8-=@wV0-R2Ht<u0eDk{ z8P(&B^Z5b$cHxSPxlTn$kM`9A(7#n_CDpFdZVY>aT&NPz`sAOriDrNJ^P~~sp?7a% zCykMnJ8AZjoX3)dXP(f&onCRhYlGwSv5tOZLG!yT!TIK6_I2iZzlPp<xsmn$X~4J1 zQBXxgX#L^SMN3T}Uv@L|U>SJ0jaX6d`=>$=tvKwsz)YV)5}g)r2Q3SdKYsqj{i&7X zY*@{05Oe0BG267tmYs~Xs&z&-%WbW<E3Rt7&R#}=O%N^ds?gy7_QnfxLJ>pG6944~ zR?Yy!CzKZm&6&~Vn3Sf3qryOcSsjt9oEKNSG9bQ3BO{s*j$*q?(^FYdf7)2P=y~l9 z0=M(R*fYyNV-LHf6;8}2%Zpz<>aqI($IIBsjzGH7-iFurwytT04*g4?MZc!qRLh+( zwg(Pj3M%#*xHYE~PUy2~N<!$AHHMR{NU3MLazs4ybBLCho(d3x$|~GJZOym|g9Qic zmNjuaZ2TvC%1S>e*!E;i`n>N#O>SFy_*Vn>g4iz)$}$~{ri^dx3+Fq)(OjNrbA1eC zrK$2h*T2;J_M46<bpVkh#KY;^D8=)ZXNKApn06Hc&jEoN%o|Vt$0v~yBqgG>>D~~- zK{1sw>V;b<m{I1;2ys-y!XW8%)}SH4#<$pS7d};cf}7f`7MaS;77mFq#z|T*H%kC< zX2-69M&t6|c<nQMo}56_=q@Jt6&mrp$Bw_*;YYF3y9j1Xf-D~#dP@oK&O8+C3d$WY zj?ktWkoLSJ=?0Oei+@}RTl6yGWWZjf7cgjE7y&*#JN-&zG#}0l0Cum3r7cXuA?HDk z>&VOI3rfs@`!ICNADI!fI?K)`eu@e=?TXp=cN>*@7^B%mDI0U4f?3`Dwzm<He3vOv zCvjJ<n&~Xb@EYE$mTvT;MjcosXYCv9^RoT7IH`%@LPD^z<rt`m(L%y0vwIk@iIKu0 zRnG09gi;FMda?R*C<Uu>5OHPbK;)#8zw`XhXBFXG^2>$vj5?1J-8;-L_OwQqD2Q^0 zM<B$z3Z4wU%)`XB5_{rqd)Z`3GP7D8xdZD^gspjcKI1fkUO!S+hW(sc?ljqf@>PRX z=~)C+`!u|?J;%hdvIBbK^y519&_<`_(gvX1wT~`?;^i6m924_Wb|J~Hff@bRN%{VR zSacuCw_q4t@^^CeuhHSK#3G|$-ZcJjHW1IKR#rB{A?tmZIfwD<sl{E1JuPA~{Mnnl z`t|c7-Y-R6Kb|7u29GAdcpro=xdZ-R^njwNR0vfi6g`l_;iRMz5~yjBVtS~c+R~m3 zR|ka>COrKwvovzq@1MARs=XF!zxWaL^c0{#D|VSKCBg{fGq%`fWgIxe37+ZKtD%Qb zL}?Uh24WWVk-mk$t5{>m{BDb{hfe2#xGCxQ?bpq~NRnRLnNyTqc^pCpJ2uF5Ca;?u z`;Uto>xuO8x4!ZW`7!7~ROf#pN5*^Zt6mf&-Vy6BxL7t<^ej@t6`Qm@0OSB8&Nj_1 zG(yEw*e1z#zZtc+pEOY{KRMPaCHcZBC?$vE!c=H!AGkH8g5sOf7YJdrH!E6HCc`o0 zHzY_W0TQ<5@5&J3XH}D65y}5unY2{!FX#ysl*rKC`7#b~-h_3@aJ;ZB;&9l!$%tqw zn19$M+?o;JzU<evo9DTQ3gGbh3OiskogEUJtk+G+7V<C}*hg+&9$3x=k<90+#{|p* z^7$p>i1mN93)8mjzo)-?5V>dLGt6URPY-xX)9${_AYr}TzCGe~RQlM4u+U#4Z1}r* zaU2;|<P{NfRTWPPZ4_sBFzheCk`Dz{u;mjUoN}$#>M72^W8&y0H7WsCAJH(&fz1?W zi79~?D2{aWyFu>p-GBy8+mjFj7U7dDr$6e2WRnM@`iLw91#E<_D7$TX{x$j2!)Id# zE38pzpen9!9CMFbQ7baNJv5|d;T|ou?k9e?V3(kw%eMbOg_a0j3aUX;7_d>`q&j61 zW0<f};6ox*4!Sz1V4x7oksBK_TIe+8yf&t0RPq$-WjK9HE7)en;zTh?Zw*S(P1Q50 zIk-0fK^hm@eaN1T*})l0A2#oedaiD(O7Uy0nX*ztwgIcdyM|iElPIw(+r~Pr^i$7e z&L>6_aWg+PWk%Gn5N;ygQjSa*w^Q3+f4AX8A=QTAx+WzAB!nFD7}kS*Pw8ThLdwaB z#_PXlnOOY1f&q-K7KRnz+C)+&B8>&uO5dvre5(CDA2dEJ`u!%X9ObcEc;=A*vF<X& zvDXl$`P0H;C672k=3<9nT|cU&tq_1JYF~I@oTQ=0OdvV-C`cY~W#j)}*HEKi{RI^U zDHOCY=ne^k?hv$)5aVJM7F^WG_oTS0xxs%OC_+?a1Ea!6uje&`si#MEv@3AM1xQ0l zr@@^cSP?y){>=0ATE-`UBSr{|Q+J*{_SaEp$xZ-L?7?o5o=2VtR)%W2?TFCr!l$6= zQKu3ez0TtGF9*q!2V3XZ22*y5OWIbYex#Q(?+EZ3)lRSazA;Zwwh4uKJB{Vztfc2~ z?>@iA7L8~4R!@fUbUGwE*Au?UJ?DR(lr_&7h$d~7`9)vtWXieM|J_|9worB~TK#1; zE3+#1CU5xQH+za?RFUWl8lK-_2rV}gNY@%25?Rgo!>~Nsjx+f*EPMBU6Y2FFO%+kC zaRx`Hpt`f;GYqo-&6NrsGCFLI6qfeit_f4gj$)9)j*>P}Nl+QWMR~DqwEwqaNc(1L zz=qx=HRraXrlI8Q705iH(T&dOzL&dgUMJ&L2u4>12u<yQO^=zeuwrjPets!oiT=$^ zj#nPDfCr?}^)883KN@8a0-B~Ry09CwwaM=%wZ5r_{xmH3YP20UX_(U+>o5o3H>*oe zXFJD>-CXEdcKHOGcAhaVV<?aJ7worf5xQgLiw>W%&+E6JUB+lNmhe{rcR4)dk;hAX ze{c%1#BJwquNO@YFE0-L+h`FO=7#nf56syo(l+!+Ol~<=`mhcKX#mp;U$^cU$;i-r zXEvOE3lC<_T?y3Ie*u0sxZeJ{oi)8V3;c9P{omrj3P+NJQZ!mzRCp{&6(}CzAVu{_ zzT@~~G8r5kjy0KQNr(ow4w7y370+-iO@(ASoPLuB)M6N7w4I0?SI$GkH(S)Rs^0-X z?*u3oLMq&hou^uOypt~XB=hThC#sXqn>8o%i`{g8;@P_y`N=jN>8f9K-kl1se+iry z9nIn8oQNYp9nLCs4QN%FIxc1yXdWIxX*A{I%%fEuLh;iHI~7rvRU-Rnx@YxpmHf-$ z`MH(hI<xPI-06o_25nrB)dM}rw}A2OLkBCEtY|FK?0UcQJ++w9d#XQ0B3eezzd8{t zuFxZYgm}q38U;LS?v`E`H^U^5M&dRm5WZp}v_EY?LqWKIqfX=bQ!2ah)l37b1{h4R zIPf}{@c*h5)|Eq<Jpg62=pmBQ&^=9q6^<n-QK>IN!lS|hBQ=JeV$6XLKzPy^Y+mvT z;>T@XYC*rPp6IfvcNEfSM7$l}C$W>+A+bE7kV~X$ghf4Wqq)$#SqW-?w4rYgD-<JF zB*H)%UhU($yv!)lD$$XwXe9ELWqEXcDphWT2P^Y6Piha{iF>N%V(0ye8hbpF1zz}7 zGas*TE-SawqAO8gEQ$usj0l?Y3k)~w%IOsD1xgeXwMW37J!(GTbKd#PBpOGH&zEg3 z9CT=6s|Y>vh)+I?GyV9)7H2qqEJl^(6rcDVGap}TKZrQEqXSo^QDu}{@{MLD+H_`& zk~fEfMGZ=qNkl*Lw7=t8tAV}Ie<OyEf))bh_9+Z+UKTTD?!bF0lyF!{sY(?kGD2q* zN-AlnDH4ur%mUVM+XVWFL<_B6ZDlaq%_w@r$+8=9PY-z(Ry<&K=G0=Z=IMoRHwtax z?2k5Nt<f|_h!DnzZp*<3SZBSdQS3y)`&BRFBR&;3o!h)yi?4OaP+w96Vl6h3YNES^ z2b~@L?gX)BI>OO3KM}1$YLJNoTSL*y*S?YP#RcRW?vL#;7!;&<IqBCt?fZMY<_)n2 zgWIj!rM@`_NVu&LX)|?g%ruE%EzP;R&j;cul$E~&E1~c(7=Kx${DUHQKvJ9xF3*UZ z_sopFd#KpqBWu#|HV_~(VeB(AvefCVZhPnHHYqf*LE{K?Y>Mj4LVszVzpgQMSV-qz ziHsEvHBg{zhZgFjNJ%0qnB!8xhkSNE=$65%4yMX`Kf*zXTDrr34ovC*M0**Yo%cW1 z`tol2&ldx=bJ4HFO9nnuZ6$29AEpA^yB^xe_WDzfx9w-*-^M+BF%mERl028=fi@4J z;H;ifYp+uo+bbw!=y%&UoEj!s`}DD>_SQ<r|7qBxGoqEX?t8SaInJM}sl?io>AQ;h z&?+c_OqabkkPS-fdl=19s?RD|GvQP7@>BVKuRPwcXoObl(XI4ou9&>-i^;psn}NyL zni~Oe<Sd)QLfDfCdAnuGM_>14(@jz^*R6>F+xM1Bv3Cx+tGr^ao87U6xF(qLpJ|Gr z#eW0s7%25+fwDeWN#h(s209chsn6KODo3=aFOCv?uoTv01g>gmBgPPLv)k8D%d7D= z!yjh*8ogo{?Yl>?i_LJfP1io}>)+izjknehZdtut%$efiGhWsM@zSehxrj!8B8Lw5 zjnHF<U0Y!Gei1}7C@k^@)$Zst72MZd(5$+(S>lLnlC!o>H|^+8C_Osa<{T~6J&l}( z>G904f2)(?&T*JX=nJ^kAP$|<Yu4@C=#WGOwcKu1@5hPnc!Trh^BRAu=+U8`bRS|= z@0JO*k0r}is#LslPa(%rG+76B;s`g!oVzM`0oX(WMCAfkQMX&J4DIZU8}_>2_8h(^ z)-i8x)#n<2?`!71R(rYC+WPdk)%NdHDNv)JONC)oLU|xcIGm&;ln2s6eH9w$52&y5 z|5%Ow%|(tBaSw|_{)Vl`lf$_eRbZ`<qw=J0l|YV}2~l&GDBo)s(JZd9NHPrYlXruU zx*$Map9WncFnQCW1wZKRS+BIk1G4g@m)4-l;Qd~Xj&oC6l;yeFW@kBiz$?7X*M^+G zoC~wrbH?mMiGaG%V0)~=_BSdO7_x`(Vg?8;PT^me@icumgv8Z><&`b|kS0FR4L7m( zk*$QaLVtz(FO#mu)GB(5PX-tODDw+^-zU4z&0+R77}PJb^Iha_=<zE%{rPf-_<(Fr z^1~8Bo3!P4;14S7P|vvgFtfJn`kih^VvRiCW~a8c>gs=N$rsOs8aXT^0&2lRk)1FM zN(`aghbRi_Qs=0@c+$aG#60$0(H!r(uRHIqfTPdjUNMkpUKihtEWb?1Xv{rUw$_MB z(i3ukO=WQV{Dq+B5)r6n2lcJmSI}u~d{96jiNCqB#vmM(>g~EXreNsnK{thB2_sVf z&adlVo+Uu{hRgKsH?4jk<L<*btsh!yiKu=wICAvgrrg49@GO{W0)4*Kk2X$IOw3>W zpzOHRqw{KQ))?Ygyn)osMm-KFiiRIO#@0ATWL@$E0+8Fvt}D{AseQ!Z7D+!!_8*A+ z#7A7!IPWivf3Q*gm>cW4_PQ#AlR#}|c6h9&TZGJG{9^me#-HXtfWk(G3MoqMmn96{ z#<_CPYQ%(u8)s_^aZE5&N}v<J9Oh7ye}3AWeCX%869YbcC{Ef%<Qt&R`W(pa*SeRm z(PAvV3+sM9=3&)q_`JQkn>7CAsU5R~+v?rj9e`8K{}{X~{tNbsnVLCqNZewVj6v0+ zf)ZobvnXi~r3H`X;R%t+5$BFf;?c#)%GF>dN(+nx9+EZj2@TglDk}W!H*Q}-(rW8; zVD-Sx4N!K;KBaz)OWO4K7L;0~u@VA#J{MUW%z3hIJ#>6Vg?xhP0a43y4In>~t3H-e zMS{29i+Q-tCxKylKI^?%3r<+F=|KD0%9QNftUZ4tC4mJq5W7eC?!7uwuKFw6jjoXB zh~V$U6-Lr`RFuxd|5qmX5Gu(^Ii?q9O42wxN{$)@=|zT1TXUh{NqvT@?+G{<teW>E z3?w)POPc2wEsy5AV)d&2RRBJREkov7KS8zzZcxlQNe^dZRMvL3v;Wql|4i-iqvLJ- zu6b4vJy{L)G~^ZH)y2b^%*6e7h0>&e?BBoo#_?*%edENQjHbN<pM|$(kdLFL7oGy} zExXz1gng#jRzR#rhBwITiWUqtGTqbk{t#(jw6aQ6njN?OKNH|x7ff<0cHaFnx29Te z7MGFSb!@BH_$w_lv@ol_NxRV^Cc*i6UHeL8BHqcaoD7l2EdlDL4@E%{%7-i8=vV6~ z4U&=!8jEG5O>Y|&41d?{mu~Fs1K2SjLx=wVr^b=d|B+ZPO%y{#C~ZlFLMD@kN=Zri zKYQxpp|?eVz<73R8kTQRGjz7p?QN1W5AaCt$x1oBVlFhaU5wX$r~M6@(?dr45W6S4 zY~C}ScYZmtXaToA9siDLoh~!Q?+NxyEuOaAx*>J|IukyDA(~37G3!*T3AKj4#P8$R z7~+vSd#BR}Hmy?pbvjh$@*pmsGv?X01K%XI6XKv+^G8fN-0}<2*4`r~StH5$7VCzE zX40WUc`8pfwS$#rsp#chQ&xZYjGtBD_oMF?cI++MyFEf(3CA<1NQ-_q%EYjq&&??) zTiQ3b#c1^0n6fj*cXtI!uM_--*icFnMp>*v%ZGv#_SyJl`C|Q$l9WhLXTW;{MQoLW z?vT$&uTXhRB3_$Oh^IOwU9Ee8mjK8?`$582Lv#7Z-LkYM)6ZGCoSqjgf_}*?5XC7C z%>BpP6VTqNdOLz?5N|j()3!>KstjDi6xYu!5{Okl8<Eo6<6oxg!{nd*8r%?^D;{R~ zRqh0PfAhvRuo|u#p|>^r|49^{U=Q#vkfR?onl6(|Ip0Kn(~vx6a`m8BsS=b^WubQa zdze1sIBzwh_9u6k3&j(Rx2+Xk7+lXdQgS@TH#!{T^*o18cjNwdy`XCccxvI84xpH6 z?khLsye528q#@3AUdC7%g(Dn>o#iq6(~84KVTxgG0sMa^C;^Jy*ivDXP!5BS3{OZc z5j8Oa^(VSJYh++MD4{1{C}!J6et0<AY-x8&zH7vkT;92{Crds=+0TDYnhPxxXr8ie z$VQwLlM>ZmJVN?9(EM9axo<1yWBqWwF+_Ak@{hxZVH*--Pp7G@VdMM9l*UP)0)Qf@ z&aGc@`6`2X(4VfYfc$ZRGVH;?iNQ}v(x(@R=3A%moLrxeyk9S=QlcYE6~RPJ)$AUO z%Lb`_^PnpO>#b<JNlTNq^(pas+krhe!WSZjND{(^goHDeY@@CCKxccL=;ctvJ}K0g z$D~v*6|~(<l~udE&Qc7Vck~%y<Fv?Pc26Xs*LAOEMw#jk<j&-)AW0@~Ird5nxnuZm zw-CXj<@`O5K`-Q;FEkGq8&4_{+D2?IJeUfF3YF*O64E4g`OyE-D_z#>>+JLRF6*69 z1jLJKD7`Hf2gtY@NU<-;2}$PPeAK67-}$!A3F~wB_3o+Xz4JZ4lJ0BCXv<Zm>XEMs zY{!E7ECgd-7CZXVDSGm=KC{3Lce7DsF9X>6MSWrI19*E>uQPj&f<AwV6To<m+kIPt zq#`8@y80awx<*{2T?PER$zR3>c|bLb*b$O+%(^l4=6wB8l~b$IlPdWKqyBN9A1)9A z@=6bMRX&y~^f9jZp9iL{<}BihMx`sy&w%~y3wF&_7N^Q+H;{X%2Q^c{^MJ<(61Ot` zeHZyrUy?m+;p$ef*0f-EqHlA6_b}kQz+ZM_OBkhu58b+-RkCMj|8c|fpyxEG`5CT~ ztuMq821h0FkL^dey}I7wgV}yq=iM+qt)#dPocm3PL$65E|KZ#q;5P1rLILqfrCuyl ztAs*&J{$c?E$d^$HIBddw$3VmFAID*nXt#PbP})2BR=9U>CLTX;Du>R^z0$${0c-K zkJ%vD)x?XbaMO0Cx;MJJQ1LO~V|pEt)aP%X14Ni&n2(w7Z)_fcAFXRD9X*`NGX&Y& zWsJKN9d9<*_c@O%(zdrs-}}?GV=W7~!g%)SiJY9@D__E47>$1AS>!x$d&D2mejVt= zFsrO=qm>DOOD*4y_d+?Wq&KCBjpIt+Y`g4J%`DXX(is=3(NnSi?(3{c^xgj`a+CrM zGBT2+BnPyIUi?7lyh-CS!o!+SQ7;H_Y~;q`{yn*O7&G`=-4;~<WtHboApCfk-lKUg z&Kb>THY8KBUT6OPj)8O+N(1;{ytFTdb!5R$a+cBqY4R7Zs?6M-p7nzKMIN$7UATh4 zgVQUtE#;T>Z;~16A3tw2$jNNdb@6ADoqzT1ubPo+M4II7Qg#GeE~Ma{Namat!VD!G zj;Jnv$821^xX)y8?Gv6y5&Bap7gB4aTcYKlm;q#WY%rWX^$m77Q3!d|Dtc?8Y43ra z*Xbj~z>s9=`26}@=Tlw%5|0xiyGmLYnboTO+v%r`3Xtz0e{7@`C4Bl|MP&l^#z(t? z*Yx?igVQN*WukZupI@JH!*0<2J8&-y@Uw9a(#z#Qs#7vS8)}1vbxA>EIp%mM*nf2u zloq_)nV`}f^6HxQY41k)lcV$#>EkNzf+z1_&?CIhP={v5R@!r}&g!jo_Oh6>e=>39 z+gSd77f==Ak2lB+8mWK!yQA+xpf^=iPO=;p1YPbXI@~FaIR%Dd=}k|G8eW6TO0lW+ zS@y^Nd}*8V*vTG&5+50V1g;JTs%XtMn6+j3zGGE`Z|7sz`>0WM?z|LRa?cn<SK=pz zwfY0rQ_!ka<iKq1w1|%97tY<zGm$Y1bxr~&8B5TU@V2_vr-&p2*F$*s8G$vR+>w^H zZ4A~|8^WMfH&XF9GX2CV0e8g@E_fuBVJ3}5%?KX4Y*qx~>^9}=o6H;kN(q&}0v+og zfesa-#j0>PMDX~XlM%uHot^wXI;uO1LaNtlHYtSReHxkl(4BvZlC5ue_Yhr;eY~FK zC$yQ@^^C7IH@zFT7_)NQoLc$Ra|mo4+}~VY+`XQj-Z*VH6J(b0F(@=HTxc(QR5;aN z7Xh`s)jIIGx#!D366D*uX)G9#)B+Q^2GWq(RMo_{(<C2jbF8hA#;%3H4rWnsU*9jM zYx~NS*NBS7=Z9>s`IDn)i3G0i3V5m?tj+X^-sAKx|G+fL5`7@L)p&MKWlX!QiAb7} zX=%26D118H^kRS4S?^aHf9+3us}@^2(K2t21s81DwA>L+Pcn&wHfl&T?VOUn&*b_j zYb-%P|G!33fkGLaq)HCl-+0SsC@W-vc2roWM3jQmi|ZU_BH(V4jr8i(UxALoO5N!4 zc%QK^{#EHA>(_Y5(+%X*Z>19P2j}v%jbmJ@gwK{3>^b^_j?G+-JGX&g*rP}vzo{`B zN=TI3Q7)Rm)$^5!ffzDtFZ~3B*Lk#-UQlXuR&RR}Nhn;B*7%icvs`We94B~}4V2-X zC5GuUY6sF?G*_ETQEIxGQc?c>Cpxp}j<)L5J-M*pXDw3Iuah0y=CCol^Q2;}5Ahxr zEkb6<2S%%9!n9T#j0s08=0ywcyuCZ$)-XQPT1egmN*;O?I^n9?sY{+R-XX^m#dIh% z<^x{Qz&p<Tj*j7oq(My*if+nK08#TY$JPY-1>SH8kp8b!bog(eS1Zb#zd8dtbI`~m z)WU$uQY=*ra`d0CjA8MuyHOZAF=KmKx4Xr6T;v|UiBdnMu2kG6CR}#^oPaPrBE^?3 zEMYq&e^57SstH*9PITnEzUrmws&%|X3nP#8?zv4$*!>1e%zbpV%c-8YY#wfwNKexL zcn<b@wvXxyYvjGru<43nzqtP~0jj>q8=4beD>lrG#Ap#Ff_{B<BVyE`gX&u!J><*k zjwDYN!^}`GxcC&5Xj1T`xI<el<uhbkyH45#Vsyg$)Z`l#j4-+~{dDgAdC?NA<w1GL zd&8PA@}x)iW*c;SQrkW+(as+Z?=Q%hjx-uae6L*+dpD-4u*9nGx^0m-=z8{4=J$AM zg!59L7q92PE5!?ihMGPJ`8ZfVpgED34w87uiCN;R2LHOxY!iLm3T$7)5W~*-lDD#- zW<H>M&0n2=0fVtKQ3zf`G`#!p95&l`l0-il#1n8JnR6Ye%KHTn&N=bre&gnw3SLvW z(IAg>gjTTVFeu*E>~Pe}F>=1mqp_abY_V|Xq7RL04sd#Za>H9?8m6^r9Kok0aQL9= zr2ie{vDv`w&4i-Yj+4B6<iZ(0alu6g><3O4&~FXTlFp`TV59bQF8WRNw8JA_v)3gi z3=CzVxXEYjKX6EBnaK8D0X{RtRZYRQts5@*CL~uMRk*VYDCvHk>NDX?H}lguDH;Dz zT6-$16Pu3l@2Y+=yk5>*fAQV~YNRrlLa)7{l+fi(kN#Z>7DmE)vId2rL$@`=NNIa< zd+co6iof7Pt0y-LU7lyi>0)ToA#!Z{uUE$g#0U>9q3BJgkgw~+Zs8PKNyBRu$>+qF zb_cezi>-UV3AiHn9z6CP8!EP*ek@-AJi(DJKygA3I|-v<;&Cf|><SFS&FlFRz^b4W zJ&ZC1ictE;t0SOM=5PM4P95F4M%66aUDpxq;fB^bt!U$6a;F@b?pO{?^h~~ZK)H=& zczxgOW0S&_p6{{7dhnVO->uf|FeAqVo1DoZe^H)zJ_;)BlAS=KqC6ViPPd42vF*OD z1HuW%O>NUp)Q$hE2-FMwYYO5)8wDB+7+~N+!Tkv3kE$q8e+L(OmPqATlp#b~(~Xah zT%VS(C2Q8Dk_{|xzx~7yJoX!&5Y~yPvjz=dN*{odAJPxz_cyHs#^Vi6@_Q&Q=*`j% zQje>mGt%z`7;>+*n1xWJzLjl)M*vg(D&U=n?OIZ#6&_Uo{$@YYi5tq;sy&D0lM%4* z{!dQjV0NK>kBHH{B9)f$RJ}a@;1iqWdFS<Bnw6090xzm&k3VJUbD^cc*&O^P`ZTSi zp3~@}!n|D6KMG^M52~^<idUI{iSY0Y0#hp^rYGYwK;0l8Tf5CS*AkF=Z(1B@?DxJE z50Xt)1GI69aid0AqJMh?3g^&`@;74%O^q054=~{pAxoLONrC>LL4Ma65%cc_)VRsd zx@LCt*ig|={HC#*AnnfyP|E{MhB`EJLTMDZ4y6xkr@@+{SXD*=oCeB$S^K_=o4Xk` z1y=MU;7+k8HYcq&L^eeAB#^+zRZ#s8G5frQ3%&XMo)wd%yuu%H7pbQ;E&0ap03HD4 zx_v+0Z_wxnR#x3q?&Lu|keR22Tw~fE$Qysad*zSOd6k&?D__%HxX6M!z;8)F=`88s zsRw}0;i#%IP-+<EwA+4Fr(fEgKQt0mtG0RTB^Zk}QdlhMB;<iYTiC(CIg;H=X&h^S zLx4B0_uVe_*zt7TEcUj)2;}ydBJlQq#erh@U&0&(bxNUo1*=k}43{Gu)&!eDg%%Hm z2&&Oxs&S>T{`%|;9x_J#pLew{+s!tG?ldZ%M9Z(Re#f<T?<b0RVG`)nu^LaGKZo|t zE-<wO)K?!Wxj_E#tTK3(rGJQ#kU9;OW8M3p)OXH;n=HFKW0h$@pl)TAm_@#RXtr1Z zXtj5u7oPp%JMY!jQ&Z;D$65nI+et5UaZVH4?M6F|mK#ftkN=pnOb(WgE}bY{^=tvR zEAkR>)b&cQ-fB2?*Oj}zMO!SY>zTVZYz^`oc^6=J%MB4{1um^w^OHB;zFDbuI%M@F zym9LHUshchE5CQF+A(q7Cu{6gB{KE5YWTHcS9fmM^t(3dsQ27+ULi1RJSgDf9pnEB zrG$?R*8|O_Ycp^`^LbJxlmma+p$XQ@?S=-L(Sx!cmh6{p^O7!^ZoGKB6QgKdB_@%z z=yd5Mw--v*qPx1h>F<3ceZ1kDYw@{si+}he)j}NP|C~u-{xlQbNY7!M3Xk6`LPkgj zI};P}seZI{VC-2<ddg5k>-Pu6Y4$O3<wWs~YtOm@L_7RA@T}x52_dBtMB<tLvZ|l< zwzZmG2;Qc2J$<X)!nM~)?Hamw2@s>~>aXL5|6~%J>9hoCYB4nzA{r<1qaC85!@l11 zx34^U_2b-*lZPjz9hy<v+KmxEDVr`pGf7QPE)G`0`8CfRLg@Hi=A7oF`4(#f7Dfk+ zHDyKtWv9*#`4#?5?i`!CeqzsIDX253j}zm+k)x#!$AG#Ts?smfP8t~o=rxN477O+t z>(p$w^ZsJ9d7S;vO?yr6SNRi!6HyN)$a|Rr;tnVLc?wHz?Fbj6dPH$<{SKELr_=NY zhc@a=af-VM2xpk@yDbuPbDl4DWMwOui+RJ7y-n%z3HmUbZ1DiC<+4^n>eIDs*>(E| zO|}QYk9|7r>~H9Ib3Nr<na;0i;yMNA?Mu+SPU`MhkDf^cjF6o4vw>yZg5D1FJEx1} z>e6@xHw)@NM~Ru*TZ~EMf;QA5sq&R2x+P&qh0w8#SNqCy=CMjX7F{-y!-$1;OU4hM zQfq-$`;+AqZQW8@q6UBZ3T`R62yFUDIX8}7WPEJummF@_Grx_Q@AyxG(LyudFUC9d zUyb@#g2{!yP@R`#qjfGm3gtg{EygxbVDZ5luUkma*}l8H=%*{drOp0k+no!|kFzbM z%;E#A#%KP__MOx=_{YIKc3j!Ot?avom~DdtkBW6LgYRpV>IECo`R_r@7oUD>s(5^@ z>vajzZg6B?kHjj<0kpb$D4h)=hVr(TWKdd;n$UK&MzP1`kfR;^+5gJcX6FrN>{;v) z1NGPXyH>0{Uz|8BnhWcR8wrbk$-b+|F5mw{h*vT9;qH}Zv+0LB2JzD;&BJ(i;E4E9 zgJ-zWe%BK*Ek*2?dIN2FBkN#AHBZ7I^$E#yrQu;R7LUPL&%%YJriSUl#qIZZ-3F!g zb5`>^$^TxDq0<Is&M*Ghi%flqw?X}9^pH?04i#!#q?kTQsp4xBbB4-Sr~-T@!JRxA zE6+*eqc>LvN<v=)tbj+~TT*Eqi0enqirj&_%`t|P{y=((oe_h*Vh3(eo5pWIXcG3? zH`J8$KcKApyv_bw1ZOAa8HL;@x*IwEePEp^KfakFJ(fCLkER@DnER2BC;jI!?b+kJ z!=C-&#xsGn%zQcexX*#4TzR-c%)13kL8kpb1c9#3qnEz?AoA4H9N|L6tc+hxcYEc_ z1w?QS=MW#nZ68pKZgVI$m@|m;_EOWl7yZ3<EYj3GQQt%3eb4*S!d?99CxPT3YJTi} z!7)?B*I8o;CM}?&P2!YsvZmyzGaumfan`Jl(f>TNC^<an@-}@b&dc)t4DF;ITq>k4 z8jfOU2muFSh)3oB0xaO<L+^ka(e(-UFYB>%&|p#Oj)%>0gDs|-lIBOJ0NT@TDHN@9 zeaM%{AI`}(=hg@1gnWIrL}zB@a)qB))l=4v{;2EX<&}<tvKnqg+7mPVZP>f7Sbi>* zc$f;ou<XTtZ6veT|J8<oh^HngVw{Dt_1=#+cXwe9%(iCtv5HJc)jf;U_#<lkLaVCE zsN1gx!8*~ed2lm*IYJ>*eu`i(ll)W7pdUU4p;Cp8`|oCCPoh)SD-sthUI*f3Tvh#k z4co>^GdKu7EAD`ooF-I%B_B@f0ZVJMGRO>zm5>mmu5*g?X5+sZd%=9D4+K5ppd$ah za<SkNA@xvkLXB2xlyIa@iDGw?&ai)CU>(M+Vt9ecY3&XWkO+12756o<;Ut>N)}UeF z<g~BIkX&H+rI6mu#bL4f;yU<l3(j$1D=nt8m%&mQ6p*UyPoHW<T!YctFuM0>d1vt^ zfN(Q+noJa%WN{xb{;uTq%&S9j$Apl*{&S!I(^tp`R_2c=4|-wl{HyoK_5wx@CT`@| z7@mfV>~FjjTOPQTHkn)12P}B*lN~0H*VKl%onr-W&1otwY3`ERIBtnP+>_e{YQX6Y zTyiDiEp?Fp>{pr~luea|{Zp}lEcS6wC+Omp<G^Ix<EO&kJ~x^>>x4VY0F9+<qvpuN z^KCGj(!VvLBzy^)LlYX%XIC%02zo7jgMuY(icJ{Bpz#JiwA&&C78WZKVT2(MkuN`M zRv(iA@ZMo1@|yn3D%sJ*J!x#d@DIUA{ArPQ+^RO3xk@oqK`N@9WH;ysLCg<Yekjt= zhexlFofTljZFdiW&jTcV-6HKra9!Mv9g3>xLavY3lrg<?D=I}ky_ZUvUE(C0u~v~) z>^)~3<8R#`R-{G!5K#4;tk-<(J#&)BT+R)b$G&w$F1QDY&%ZB3&`}n%I=OdL$1(Q1 zsP-F|lR@x!Y9&3tzIXN24G^CpEFP8;Fqk?8nJk{IG`!2**W&&@ri6S1x+%Epk(VP) z_ArK1x9;nMc}?Zv1q)w=n^7WBvWu(-x^A{6BzW_J`v0ETq4^Bx`ay-(2>Lon8Y;wK zr6dwYsA;j0(Q+pvqEs#ZT0ts&s78alv%B<u{R`{QZPfj6H>@19zHQuVrDft&1AZm9 z$Gj0y2=!MOe#bk}eg5xgc%Aor#R!j0Fnf_?Fn6sS1yW~SuGVYu)mZ~tW<uCA$OKb_ z0q@X}a>PcTS94y+U?-?Pgm5rU2sT?uNBdqOFY12cl{BnOJaQNMxohzm7SMcQIt)%1 z_|R|#4b9vXJr*2&+A=Gb26i$S(&69XIq|jN1})AM6pf?Re{x|&&sVa^McK&&jn9&P ziA(i3Qm;`?6PWriTblls=s0zr6vy8y&Zn)U#I53R`)+;u>%U$-RE(PZJ#s;##;9=6 zhM``0f%gtd9&6|u6$GveM}HBqTc~-HiP74e?9j`2s*Q5R<MhU6B2R3z08PUs;^{WM ztsWYGREkwZzx)VEqI>iWK~$Gne{Ri8rrIZ}K2^2on0SN<SkYy{>ktU!dMG%3PSU3m zOzQ{@T`W00vGQ#K*oz;}$%k(G<{HQdKfa!CFkEt-`Ur;b)^*8#ozlm&&XGbA78gZB z9YBY$H7f}SVkxm!ukbnW#ZJ_+aLDh2g_0x6MWwo!5bf6)mpuFk2x|<y;EsPQ?|O2- zZEh4{S9~TfUFW$gC4SpK@!S`_kZ&BdZM&tYZ>O<KpmSE-qFb-ssOS%B1_O^x|DV*; z-$!f-(Dd<NnO>P-j!PKU2UV!57-WRn2+>dn@+Ef)pLIEZelC3G!q!^@5mWd5dUDH1 z@Az<guQlEld1IEkKVe>N<17o-{P6Ae@e(&DFzt&iEu8)9>`J&e4(6fub^U2)DU>St zMe8R!5A?Up`}I9Hn^*q%#H#PJ`(;G=_&ppkfUB4#LK^_Ctg44hQ5WM?y=bNfKRBL@ zL+9_dl<k-5&p{ib{jmwC2626Lb`VsljR@ISpV}luaBZd_!!|<na20k%=0!zee6@zF zyhD&(vXg}r0;2%bw_||F&pvq{G0r0l_J2;#>3K;$%ItT$?m?^z#_s!B{aGz@|2Quh z>R4MuEY2)9>f@Kq*GGOP<o<6vzxZNkP<p5m2F->+Vg4ns@q+gpQ4{94OkcY5P^n~s zk^Z65M^nVl<N*+$9s7qw@f*%jW+e@+Cm1ajyJfu(-T`Z`FPqrdFzm7K&CMHTt1bhO zx06cMu)I>zuv9ez11?S5D70|c%ik;TQN4XQ#1YX3V1EAC@;WPq+yxT_*FRiK_?qEo z>G&L;d8o${fw}0@LW8^TKvAKjNIG|MEyTn1+G{+U6G3w!`jS_CTI~THD`=T%C}nms zkIu1RH?o@x^(v*`FyLNbCu8M&x}9uYy8RA>9yjKEg}3%mhW#Uf`zq6}fNa0?MFshC ztGBI|YL-$tGp?<>`FAU~Hjk_C8t*eth?nqK`H8u2jyt<~&;Ku$ij0mR#qo0N`JYiA zhD!w3MZ<~oH(>Z4D>&?bk7ALU@-h3-!vj|NNw2|Q%<rb}B(?RPRxRgXpKy`WqOC)0 zc;g)(cRknv1*~bdDJcpc57`_v(Nv7vbv^Iw9rcnMjkQ=#e#{<o1*XoVxjv@m_s_Mz zTd%@NrQg;$6RimNqEMYT(eZSHe7q66iF+M#&s>YNjElj=6;w2}s0%UeGMSsdeiogO z3>O*lOdkUM>_g7Oc$m)V9%eG^oYSw3`SI-2YP()&3$fe6uZ#YZr8?mPsulSqeWB5K z1v=&1#%rM9uj&-Am>v7#66Yq2BU+UfSEg=c&~x?Z+fG<}{x9G88_fuV-qabW{!SMZ z%>NP}97?E?=Zbt!3=@t8J+TuS^P%qUWC{d|dfh93*mT3ZX<2Vvvk*u9X-$5im;D%@ zRt&U`a+uu2f8;4%nqj(97i)68)HB?dQD@Wl81ESNne`A!oE+8vbZuck$beH5eLYN2 zB{QmXxr^AkN3uOqSkiuSRW=ib4S4ej*t7=T`Nn)$$sS#T6*6`Fb@LgcAMM21`^%?c zz2MH{&U;5KXGFJY)W)p*en7Ic052zY1!TzEnSfi97O0VvKNLvP)OMdn@%sRc9t)wv z|7W+;=Sl8+`R_ol^Y~=_2!j~GFEo7Ph6e`Ss@0AcY0K@QRcpX__SL}Oga7w3hV~_G z`S+}Y1XW&AP;tS74Ud&G86K<+2cOE({i+H*aIgNN<F*=NIeYfXnz#9(|L`|y=m4T( z0}yYkR}5fv*cdr?V>13E`RUd=$1n;2`H?&W=zp{!+&eTwA7l3dFusu@e7(E$_{6lR zw~jP;Fg~oV^NRnRrapdI?Wcp<8Nlq%WC3N)R=&8rzvaN>e0L7&485Pl52|>4w<nO^ zmtA`^&E*g3rv3XPfnJ)tuSC>)c!YsfYU&vTiL$0+h{xbpCuq@piwzP%0Z-yu>7$=_ z>g9jx#b5aT3TB_=$U-X5%jIQyM%ch2#pOdFT-W>*Yst(VQd_YM?5;>Bi%Y$H^ad{( z{a<v22>$O&kiXFtXkukRjv6^e>dQaT70Q=~#V^jFew*uZciw~Gh=Di-xPz<a)#*YE z`?%Q^jX1&CozaJ+vd%wW4E-F3Qz}|J>S<`&H}pHs0dA>Z;UX#?k3lVsDs1^x*!m%o z9!7~E_BntKNlMU(Eoz{b^qGwkU3m^E$@w}(AYZA&N-&{=OTjMOGdH+cSl_34<*n!< zye&{kQQWjGWS!L;9d$wMMr#I=hX7PvbuN<j{f08o>=dPso*%l=6uj_LwHG`ItMw9H zDTaeA?vh|>9Pah+kqw6wjnZ|YTj%pMa-#i!!R{5NBA^4rKujl8QwS$ae=Wnx5l{_` zAt>54s(hc3^T$YSeN^s5{(mB<)F>=}wSzfStHVihB14^b=nkG7{8wJd5YjcD>o;hu zU$xU)Tubp5l2scH%j|as-b(s97p@9FHGf|^cH_BAuxKd{<lxP|JO%jrx&Jb9yenx( zD1ZUZNM5&Q1q?J1GMrJ0Bi_BzGLB+PXnz$8?DIitjVw>f%Nsqj*ekqzBZ*<S+e+5b zR_eYkG+@{%d^pZ1)7LLIc41d5lkOZ#*lAf?fbLP58Q^%s<tQvJNO1$+jbE*!34Brz zw49!LBn(Pz9^t|gpOh(Wqtv2Pn3&-|dfP!zu==O5NknbfZMI{yxwT;hbWS&WXeIiq zD%S#lPs7-<P0buApe}IbBj_j=XoxSmJ9S6(Khx*$`@8?Y4CO+h40{O_(&BPKfeIZL z`a=I7cZ{8)(eLP-W4`v#u-rzaaz=kU_Ja^8^_(a;D-$hc^0-QT;4$G-UH>b<{b8YP z`=fDw2z#`(|Ask_y`J1wlNxq4ryeWb(7ilwam8Lu$&WwEHbLrFH=k<v+eJKi&-UZ7 zT;}yHrQOZn7A5~WJf%x!w>NJ480KC+#eJj89N;G*eP8gI-+$!96D&BkJ4KGJL&}fr z!U|-PBe|#BQ(l9bt4<Kd#xOcG!3?i`z;ic*gbd3LwU;>XtjJvhM>2TY8-Z?03dQ zY6Na=%RkLEG%;xj>&U+Lq_t>mW428>+9ghPEB*QVmNU!HshdXZFH-%>kwafNGBpV_ zA_h%*L(v?r=k4DoCQRY5IWNu_^tGmSHyT4{eAX!c;20zVBH!p{e&m*MLrRo&;La|E z^d7jPg~}p@VOu5so-}#gkWo~ek9rXJZoZ`=`8z}qGJ)7VFUiL9t#ctv^XkvYg=L|L zOG$Jzk6&Pgc-0Rvu9GMJ=9=?)R}(^R`NsaD_HAqX+63jduwaL%@Vr5z{$ECjM!d9{ z-=*K3Ue#E!JAnZPqryZN8=<;a{+!uzmx1#uO#;PIm3j};F5la4{9X6Zcb%x1IRy(j z0CGb|H15Z<6~G}DZ?)XkXEmG;Ty~maGxDXG5rS2E9u)>a|7ToqZD_FGOXFA)CeY%e zhKGfiP^K{8qacS!N>(MX;F7@gNUBomV3CpVps>8)6f_D(qAtEF)`B0lx_h#YQ=~O5 zE~b~aUORqakNYR^u^$4A`MFF|m-@*-JaiT!|D4f7@Sw#H7SLsG5HRqB^nWJ9&!%Yt zS4J{^fuAf`*6E!<E#6cQk*=VeEnZ1h^6VVjc>O%endME_9jK2>g&T|cATHQ{q&$1c zem4<NQQKe*@G>9AIG{*iCo_HB%YwuG;d>&x<Ol?Rhp{LK9xs6SzRX(z!ys!cSNKfJ zEh~d=Gc|s)qMSbOH)~|(9g41Gc>e02&`ImBSc98-Q9LxuNX=Hv71V;Sen^|s(%RB1 zeTw^l6qa4z@1$S3Zz|H66_Kxq<d#I@^0D*n5+>*W*Tq@5HQ9!391x`&0YO1RQWzyj zj+8C|DJhYb?i>vYh)5|ZpdvAbbd8B9rL>f^bd1rXHoj;0zVG)P-=DA@_jBF%b)LWT z{E=1gm}<q-vyQ>8NL$_g;SXZVZ}jQKk#x89@$7lmYm1Bc)nZ~z?p9%8nro4<poo7} zYurO1rV!9OlmL@M31@QPc35D~CkDvp8&^pINXFOp3*JBUJfm8+b)XAM#=2^Z<h#!j z!iTbUx_lixr~4|5Gcu0wLfB{axV-`Es}H-Do9emsn)L&_d(eCgzgWtA<AIg$oFO-Z z#8^4mv3nT@a-K8tol)nRB}^>ySRN}+7lHmQ7a}u(ahXbX%-S)Y4<BIv?KQS0fUKk$ z$qE#%ju`8y3YE9h?E3sw)c)h4x}H1755LXtR(2gDa<h4itH;jaFSz;y-HNoV9(|HZ zyi3u9Zo620r($K7-c-(R?|2dyP1hAbqa~$Jq5RHB&7tROaN%L9yOQ!xeEQBNm;s?3 z%Tn_fVn<Cu(OGu=b-_N=JcJ&f^8W;gNeJ4NaXOk)`Zq;o-UC~kVuhl=hmWab*6Lt~ zE52qptQ&cwfQIC7O`8y#!1AI#pGydS*P({^*mBm#WAN5zFKdy)lY!r#d981;@GH9g zWZMGRl$)I_mZ=9{w#M10;ZYSb?}eD&*S6fCJFp(w7r@L+-g%eiTZx+HuV6g)o3}sk z_=2fg&A9!v%Bp@q{qvkHtS%kfXEq}5?$$yq?=Z*sME;8ggQQu?pN3wc{=~X=R6z^g zwaLe^CdsX+W^wRAs6yS5OX%hqp-}57Uz%WAVJOdQPVVws;k+sN-*qvvEnfHRG{@av zi-<rMObjQ>I~Zm2beqw^E$8Ui9k&1GIq)P<2KEiyI!_Kflahcf{wj6*kZQV8FS}}{ z6E04`8*X^EwvR#aCzF(XJ#|8Ww;}h$)hN>1QaUojsI~@AA54>E!jovwTdyL;mXwPF z3-$;w-t9-Q1Y5$W1K37OFy}s6ex?(JsUup@c_vsZ4py%$BRN4Eic~_W5G)5oAFu2L zN~7yXI>zkl-D5#HEvaHlSnc~Sf=5V3T{M|}GTs~gIpx)+iiiy8X+G$dbQDvbpWK_| z)Nnahk~Y#0FCD(Qe?x@~8s<=X_4VhU$;CVG<y+DP&R*?r+uY{Yz<Ny(CJ$*YK0%%c z4mXqGx=8B#t#?<b$<qy1fcRglJA;?7PhM2alrqUf#uU&OOw!=}{|CR|P7HA@?$ZLM zxd8Bv0>(NwJAl{6*)#@90P%Z*E0_3-4kBT%2u4~UVCVHK<g^5Xxz$B{<TUHAes3SN zyS~Z!;%(iUdHtp=>0!6d9%MS;V?qgc^kFX%?Yo3I6NC5HDK@yh0Q^OyvFKQ>3)Ujl zu_F24X-LOF{g%h)JSkt65?D3iX#vrMX0_4{XR?7a@Q@GN=P=5Hc&I1b_s<7nqjSyB z&<(Fu`&5SqIeQ$e#x?@JZIAl%^4L=3J*MB5FJ}=r_r*(1#=pEvxU28;RQvl*!Arxs zrovx$l3rSH%cRPGI;$NFJ3(+hPc<HWh~Id#mgc^qgvZiouUL}T_}AxMzRUVQNWT}Y z=UMGrAWE%Ca7XE{Ax}Y|3^>mm47e9Ju*?F&bTVMb<D&Tt#Kg+cI72@F9NHR6<&nXY zqUXZq&gP*<!+1h)vVW_qFw)A9m2{Jhayv&DMY}bI#2~iZNAfL6`l``OdW^N7f-z?v zEmHcVs866z+-3)3(Zd5;ezZ@_&``fT>weMg0lR+H#HtO9wt8^=_GA0S$Z!T?V}2!x zR3|^f?}J_%8O8AHX6}|m#H|%K=YLJPyIH*3{@nx-DP~S2+1*p0gM^1XbG+wNX=*6; zz(}%g>H2IMWW({@;-nBF`)oP+0%mw)qw2H8ZrewO@^7IWs%V}XS<(T2*vsNFr=1El zaKHRm)|dZHqL4BHX9ai_sb2Ceue4R@snY@3<JB8pM#`kS5tr0FfG8H72(|{D4LF7j zdsVt#d70nPl!>7HfiOT}gO<5=4%T;)hQpI4D$>tp>OG=MqjEZ<MM<;6V~?7r#b){z zETx5y<Qz}rA83wQIb>D%PFGainhx|a(fKCfugyO`J!4SIhkitVUMu6%!)3T|J7304 z!+F~dBRyjcLyEm$JC)%%$T|5_gDi#?6K?yjZmn9Tbk#37d8b(fsCzu69J?y|JdK?# zZNu5ZC2g&{)nv36ktH}5(Qp5Bjod-@A!5a+6K#I8jFUNGv^jl|u7%|%5D=_jLVh); z6qgx~ruV$Opa2e08yG8;?YKk10N54@I1F3@AjhIS*S=CyM*!ouSGbr^`ZS>}S5hsf z`*$1NK0VX1ja-3_K7Wp$#MrBn$D7VezfSY{CQDpDRf>6&T3KLsg0vE(-ej{fA}iFA zX)eakC?M|nab#k<OrixFY}CJh>tl^qly!UL4=7Ww2yAwOcLYU#fFH*Df1hh~e#2Q) z-Pp2mVtKbOkduM+I@u!Bx>a~Ha=aLk^CiDSR`s=%TiHpH)2n!J0xF$Zv7#64@_yPw zhcfkS)EXk@&NjSp%Kl5`w!1}sunTj<?@2^|8?{m3ECJjzlB4`J`x@H@)da>4t%$hW znSD_u;9aMyU9)Tp)fmW-a?D`()e3slELyP{qPzKf^k}~)^zwqbd^`dN1}CsS!->$i z&xng&J^h;!AWLfkL2U<W0^D6C%tVqmk}_hFjkQ(|oFV!#w|wn8Vfkot(AF1ONNl3x zd6ino%mG`5{t(zKd*oXOYAPLkwc9wu!`a9}K}7y0>#!z4gK-zSu)*7vnlkFA5!V=P zP7E@COUe@#LLIarmokILlx&;0&pn=9b!znrXUli?7S;diIrdHDnK*Q>sm`Yxk;;R7 zOKFl`A#)L$fBo=SpHSaeT~dh}9y$dIG5|Fdo~K$g+J~41zTY~hYLFCb`nVM3ZfNEf zR?>?p`jE;>@Z=iJ<Eb1WP?$yZjajMXd}HSAHm|Pzf*J<T%boS|+)x9ZFAAT4VFLUe zg(}nlAWj_fm0ej_|0Rp?aDu|6;RWO^OxE<)=L6<ChO8$k2EBK0o-P;df0VN<P)Jq` zwC*^zq#E#b9EO{XvK<(r<@nl{H|o0ig1LCk8onEJSmnQ3m>fO`KA+uJ0`0RJo*^1u zcgQLRUn$^_#XN)zSj=^)Ngqy_7%CDhMqL}lvp)MV+iW5l@i^>>=O@DlGwVBDEC%_y zhhcZCdfVSMP5TEqqxjTvJKVjOjC*(4Ud$0?NW2;Rgajv0ZH|Q<hi|bwW1)GEHwcRl zo!30`o7<vSj<?@0P4UFMpduUTs(uEGK6;BaUmbL3SF=gVif0KIP8iO!sL)8NN^H>e zscUz!9YVT#nSvtz*I%X~0cf#*qJcm>rJL7)BniilO_&Q`<}5C!Z}G_}gq3aT8dTt- z30^U)EJF$Z&5dH~_=S=>`2+Hi9Ewgoz^j9pVf;0`A#en5a_lh1P<av6NN;V<E!A|g z=V|bu-kL|%+)+ZvyHQi_j_Y?j>0d77p25uMkPhDfQ%iodL%is8*o2l4h3>@-J<sdK z2(jx@gpPL_5qUX@GIsl*>aEaW{<<ZhYu!Jcmf=2gTaK#E@*1Um-wp^~Fs`_f>(Q+c znk+xASmV9EtlF_b4*dY?zha;|slWL6PBX)Ri6F+Z%Oy3ELq~4YTLIsQU|jGk!Dyil zEy)$airPCqa`;tzY~z3A@d|JLODbq{0M|6`;^tMtkqU}c0Lei@{EfrlHqIv`iCI`% z8oZj0Zx3KV3KK#F&!&7st58^IosS>ljl)2O{;tp5N&NG5`>nF9J?UW8>Evu|t~;9; zM`E)7*81LoYs=f`@=T*a0=9z}y8;XEN9(-UUymvxm7*qd%?(+5VJd<l*1nQ`r%z3K zE2kTkkn%MCQTG?c9MlYtBGVFQA7WY$M72XQN%~vt)y>axc9poZ=r(4A`GPVVe5G5< zn^`Mb4x}Z^>||tX_8H1yLlQ%?k;^-C%VbL<*OsZ@=FpP%UA2<sX<NNhg3gG0oPGnU zRU+N}vM@?|MIlkkKPKHK7vCU&tEfW-Dd}tPqxp7*$*4pi39VcN;x7IeLP-e=GR^&O zlK_e$a50^KLZ(W>`r5QWM&r^1^8=FZ%)AUr34dG2u2RiN?e553a9dCfkNn23EwEo) z(mp%kQG#=d_e>#nA5sYotj`o9H>I-KK=Nq~7n=d2D!rPGJ=D~;;^8K`tQNDc;K{EP zb2zqQubL)y9IC7rgNAC>c4#3=0<_ZSI%+~|+vQmw+5K3Plo53$ivw1vDD95z$DA@I z<qvup(8Gcr$fJ$YP&juSo5+W~jU92k6pE%a<RPnEEE86FH~0L6)Vyur2n}D797A}c zOMZkSQlsUZDih1dEEEfRpJ8qUd_3T&32V3wO7)O;&<OB|Int?=u+L;Z-6`#OJ(kC3 zIV-~>U>_jmGM02YCA_o2_~qYsA)wh4UM7`+SlrbpKoc<qj8yU{+#RQ6bh&ah0*<Oe zb;R8oT-uaWPWr+~alSPhi)LnDtIoH?Zj;VE9$ttwRUEN#Im*vQ!%IDG6NNoXcY7jh zJrpKm<dCvZxLlD#d2bi6X{?P|s~$4BK9JljAeIqzp^W;{?LD>#7Hmg_OrE<r1=c&j zwPMdcR7$|ZUB+t<r1yIA_4RHMoQp1}KZ!Lx^Kah_f1M1Aj<HnPatZHh5J}uq?T8A# zTd9`^Zp|ps%2)T+8^$18e$kq=m*5xfh#}I4#PcG3+tR$NzO&_~+#2=m|M-dZWP&jI z@p|AyqDI&ojT7boDR1FY?Vnam>+LVkdUx7ntU#KL6KI<F*i8NTOHlK&vgyWUN0Itn zT7YPM{<nUGJ}TC8=h=_~PO=vUFxFs;L5NXc_<$gy{VcoZ))Y9vap7HRz<Rg(A4R)9 zmd8K^iyMdaN5h-hU-nrh3Sy0lHr853Jj<-#{3TMfOpy*tK>-ICE7iI{hhH7PVeJw` zR+`~N1;kfYJW!7g`?qb?Y;wVGGiOjdoVP;s)ow+F3aHq|Q(w&FozFgU__<YubbS_f zpQx8S)r<W84?1(IZw8OKpXjw7loaZts4(|JAg98%rRgvG&f(V^vicjzUJ2<Mk7`0b zCw1Nrjp|h>pq1;M(VE6rRlE<P2zyq=EP}WpR5jiucUob(kRt9p=O-1SJ^tlCF&5a^ z<8TujXN)NUe4;5(Qv{G_G=N1PPnjf+Pi*iH1?@2l8?;?mP02~Y*hnM<aSwg+k+LpW zJ7<~sL$JT8a7fT;?Ye3Zc0Ijsq1@Ne!wB#BtDYlJ0tLE1j&!wrY{K_iq5bFgSjk>- zKB-C(Cy3%tk935+>k!^zrVW|1rQL>JRZFSel)edOZM>^z&KpkR7<qN~7iW7OlXC&o z!;=2+exZPOt%BvAKbQsD7SuIe?aLJlW%-R9<A2?#n+hWLw}CQxj%IMyO~vGI_JT8x zp|UrcE%a+twsNlZ4JZcJO24<yg>PRFDaWq4ek~e;q(qC>yvcviEF{tk(h6U1{9$r` zPV8ImkvQsOm|N4~$({dnd|iO(P`ZpBTsj=M6zW4DdT<Azg*E{HknlFH4U@@0$yqK4 z1G@4vbMkxRz;lVmDrBRD1g-F5OFqY|zcCustr<<Ls16iSU-Vs;w4z7brAe?%{RsOY ztjEr)a0#%dSagtyT?IQ9N~CD0Eg6G|ZUjSfJcLBQON)_|fF1nd#*&~qL0K$kAIW?; zyl&_U6X@&M2aa6B)xO!vmO{J9r^?^VvbdlT&RM?%C;A+VA3;Ker5N5ct%Qv3f_E6y zB*#Qtw#kd^8P{nB`^q9(ZL?#ZlCCF3yeWRog#JE=Ix@y&s4p!Bv^(XM%b7OmesuMF z&Y6dFno5JN7mTc}qFP}Q|8fd|2n!$_z?{KpJh*J-1TO~}0E@FT#b|PnvMbvIGaCQz zzEx$`!i_OrKp+wOdMJe{Ms6tRr>Mq&Ii=4-HD7R5f8dmD&F<;M=>ArOT8T0wCv7V| zNnIE8+GU;debfwD?RfNnu|$_CNe!usk0xCii!Anhu?I3Nxu%s}jYh`(9CEq0hc{VU z6(jyoku70(+jZ{a2pC__DpE$o=fTknL<N_$<f@@`wGb?B`+M<Z?$%z_Bla3*siQE& z49H9gy&^AVI8e?dF2lx}H(@9}0Pbx;Cah1NeS$op7K&xKziL9Rnw+-}9fNHyU2qN~ zT+5C(pnA2Fj0SSDZVw!jtjJmxWajtM$8L?RE+AYDL;s!5m(ExuP(FftH(vf(KLH&q z3J@R@9?$}5mRQ@huiXYVxa=~pg&|J)F~)m4o~vzw6c>5O)trmnj0@$uvm0@E=VU+c zUwg54^e{7&(x5F*W|o%-fzKgXaV7~RSFyR8-%qf7Z;qyM^o^I$l4Q&|@^IN)NVX>b zdAUfNPW}O(B7Y%%(n;YSWU5PS=1upiP9*IPL_^KC&bb=~^CTXN*L`i)c-6)&vmhFl zYIngJ81F%exyNQf(Py}sY1Ole>UR?xiI~jAX3gM*x;DQE)tG}@c;!SM_nn){vA*RW zJ+a^Dy%Lhi%vCg@Z4;1}t6-<{lhUcBliC0euZJU$i_nj{`cQ#}>-A}bqX`9mlN1JY z`0AbKzg!uPdBH8~f8)%!n86YkNkUX1aJrt+)5a1kEa38nxYkJ^;_c(CvDy*2CkqYw z*|_Y+28wIo|I@t)GuUjV23ZgtW>8eKmNpX~IvtkX4+=p}&CSgA5F*|lPY@AszaprI zLfmsGlYe)1%EIy3>b2fr+$?1HU`H0`O#W1lCaU~^>K1PjL1?NF6HGXat+ch9tDlmS z3T6`voy~X=udP)^!q|u|EaNZbtMOakm`lMZcayPqF0+GK;5zH)@l8+YuHOa{hixe( zroo(7KgCgJIajH3MD34d+eoZtrOe4WY5QLlYk&WM+$tC&mw+&d8x1AwA0>48od3+} z?XY7~kEwW7PGwRVC}PqA4i7Kl3;j>q-~fsxa7&pJ5LW@9yW0sk)>RiMQ|soH#0_hE z>c8sGb++3jQBP4%cbtBmt(O+-et$F~h|Z8<E!i#=4c~W13@%6nQIM8dwIPoDj`O)L zD2lTX68MlZe9HK}ng(Y6U?_ONzhWloi+EXOyZiBiZ|BaFF4ZR25Q@3$Ig$>|GKed2 z;lBkDmh1g|>x9T>2dj)hJed#lN?fgUyQdi1e!T!cXC^<5+Ym>e4_Ka@@<oeiCkcG5 zvK4VhTeP;Vh$37zs82DiowkATTjPZS;2YNvT~?{sOp4radg*t!NkH68$O?uE?t`j+ zntNh_JPwOlmNZtgVeS&1|C!D}gBD<|0-G2PmBw`;b&HbT>S(Y20<^PSmNO^8bs$t! zv#Yr%NpI`2oVdZ6m-e1uEX*6LHr8yC*eNE+0MvlAxXN&`t|1OThbKaMn>5eQef~6& zKZ#$!%4x-$kURXSQ_Wftz8Gw`&@n`$Je`tno}_wU8=eApBKSQX%-?pE`3;Y$mL(GF zz4`T=Ctv^h$HLHzYJ;xR?64UhFR+9MWA!b5Id{Ymew2gRVF%Sq^Nm6X{n!*{@lVlt zr!dvt3lq-`1{!@C@4Z*}%bHK8PZeU{NexcYb`oIO3gfX<0jm&F4`o^U<JlLMbT4X# zvSVyN+_%kLN!l462uJITxjBNQP_r{mu>ZG(u`~Vsn36gEUgdWqsHtNBDic^z!8=_Y z5h%ozZ)E}Iz5!J;oT>93p(kTW#;&etuHA@a?a>=DNYM%bp$2hfl_M5Swn)@2Syk>R zCk1U~Dk&knUB0As_AKY9OfF5r8!ls0Cb-QaUZ}c&Ui^|X2x<higgi#_sWZzbd_6UP zV*Nu?+omiNk8m*biLrV_qlm=}M&O}+0yfgEvMqQ3Z4vc#V6QrHjUB<-<E!sWp+{X0 zL~dYurJBKk%C5#pjB5`zWB1+fywUBO-$*{?pBBLKxZS8&=I38_`fZO4A=v!>T#Uam z`Ib~>rxp5D^!cyc039po@eJgfDMNFiw{ysaHO_0H|1|p~0kuZ}lF1I_P=I$J&|U+q zW1_eR4|~E8Aw69j0ll(95$+>0ctAy){0NdfUGI?vW0{swzNwZ@=-IqF-=Iom&o1p4 zk?VFXt80#eZrXRjtIy({(T^bi@x?rI50$Q(`fGDT;64?&_ee9Nqa4ZM_#fX&Z)HkL zPy>}l{TeSAU7gX;BCt(j0%QB6A^1Z%=j8avWMU^t=k`nOCfn5ywta&2p=DU$$70la z#^dvNu4FV`Z%`YJ)OnzkvxkmYnM&z+1If2C<2Q>jdP}|(*cWw3qBSRJZYfozIv(e7 z-2mnijhz$K^lKC5{Lq`Tt`KG*+N$kqR%$5LBD?KDF;d$h7?j<+=Zik^@&rW?<Fr#x zrZ-%?#Luq*<e|1Ej*===<kfcJBz{f+gub<1=$M}qEUdjFHsxhdR%HRu!}+vo*2C4U zBmcHGBI{$6K-LLrT8+s2=<vAfbGIJs>{&Sf6aUSAI1l)aUWS9|a@yi3Uy>|m83L;N z*ot8#<1AF~ia**@2rl9z|1gk7G@Xb)J{v1qQxI<0x-8hZn_&JS81C%3vmqAaOt37m z7;Aqz4sNTpBdu*Koz&Fxt8j#nozP(>Saeq{Xsjk}6Ss8D21{DhLIN}~)>nA)rZlM! z5tWB?D4u!ydy)ht&w)BhU3=)L$B~aQeHfm(LXzpPY$!|Kwg992%Gu15veU3;^WZ=U z+<(E%l(<{<1)uyj9`!r?i>mRn6d!9nxA3<cFw`>l+)HB~<l@Nq$@$Zu97yQv&HjV6 zb;Q)jfwTvBuEu&j>`XYdlsBb>I>qww4RqJm#RA0R!%Z_N%V&oP_B0eW)B1v<x#{@) zOa^mSi$T2I^=Tl2Od5{Qx`7kw?+4w4vebB?COx2W%V~!Lb86OL<4_Un%8!h-V`j%~ zYsWRsY_yL)OtQMmS@*Lbvm{40ht7U%?z`$4=boJGK0F*58_@78`GM#<I<g+`xrG3K zH+-hoIuq>Yys^4fGnJue2@{C3y!lD<hPbJE?2UVwXLs<1u5r8@a^ZSU$LCX>kgJk3 z+moiQLRibf+c4dIM{1gIkc05)_RsA~>X;aB2a$WiY1)cUX5ozHY=SG=G_ALvM>>`~ G^86o5k7#cI
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc index 43493319046..25ac6d2fe0c 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -26,6 +26,9 @@ audiodata.bin RCDATA audiodata.bin /* @makedep: audioconvdata.bin */ audioconvdata.bin RCDATA audioconvdata.bin
+/* @makedep: aacencdata.bin */ +aacencdata.bin RCDATA aacencdata.bin + /* @makedep: wmaencdata.bin */ wmaencdata.bin RCDATA wmaencdata.bin
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index d700f8a222b..f4148692489 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -894,6 +894,13 @@ static void dump_mf_media_buffer(IMFMediaBuffer *buffer, const struct buffer_des buffer_desc->dump(data, length, &buffer_desc->rect, output); else { + if (buffer_desc->length == -1) + { + ret = WriteFile(output, &length, sizeof(length), &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == sizeof(length), "written %lu bytes\n", written); + } + ret = WriteFile(output, data, length, &written, NULL); ok(ret, "WriteFile failed, error %lu\n", GetLastError()); ok(written == length, "written %lu bytes\n", written); @@ -930,14 +937,21 @@ static void dump_mf_sample_collection(IMFCollection *samples, const struct sampl static DWORD check_mf_media_buffer_(int line, IMFMediaBuffer *buffer, const struct buffer_desc *expect, const BYTE **expect_data, DWORD *expect_data_len) { - DWORD length, diff = 0; + DWORD length, diff = 0, expect_length = expect->length; HRESULT hr; BYTE *data;
+ if (expect_length == -1) + { + expect_length = *(DWORD *)*expect_data; + *expect_data = *expect_data + sizeof(DWORD); + *expect_data_len = *expect_data_len - sizeof(DWORD); + } + hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length); ok_(__FILE__, line)(hr == S_OK, "Lock returned %#lx\n", hr); todo_wine_if(expect->todo_length) - ok_(__FILE__, line)(length == expect->length, "got length %#lx\n", length); + ok_(__FILE__, line)(length == expect_length, "got length %#lx\n", length);
if (*expect_data_len < length) todo_wine_if(expect->todo_length) @@ -968,8 +982,9 @@ struct check_mf_sample_context static void check_mf_sample_buffer(IMFMediaBuffer *buffer, const struct buffer_desc *expect, void *context) { struct check_mf_sample_context *ctx = context; + DWORD expect_length = expect->length == -1 ? *(DWORD *)ctx->data : expect->length; ctx->diff += check_mf_media_buffer_(ctx->line, buffer, expect, &ctx->data, &ctx->data_len); - ctx->total_length += expect->length; + ctx->total_length += expect_length; }
#define check_mf_sample(a, b, c, d) check_mf_sample_(__LINE__, a, b, c, d) @@ -1021,8 +1036,8 @@ static DWORD check_mf_sample_(int line, IMFSample *sample, const struct sample_d ok_(__FILE__, line)(*expect_data_len >= ctx.total_length, "missing %#lx data\n", ctx.total_length - *expect_data_len);
- *expect_data = *expect_data + min(total_length, *expect_data_len); - *expect_data_len = *expect_data_len - min(total_length, *expect_data_len); + *expect_data = ctx.data; + *expect_data_len = ctx.data_len;
return ctx.diff / buffer_count; } @@ -1622,11 +1637,35 @@ static void test_aac_encoder(void) const MFT_OUTPUT_STREAM_INFO initial_output_info = {0}, output_info = {.cbSize = 0x600}; const MFT_INPUT_STREAM_INFO input_info = {0};
+ const struct buffer_desc output_buffer_desc[] = + { + {.length = -1 /* variable */}, + }; + const struct attribute_desc output_sample_attributes[] = + { + ATTR_UINT32(MFSampleExtension_CleanPoint, 1), + {0}, + }; + const struct sample_desc output_sample_desc[] = + { + { + .repeat_count = 88, + .attributes = output_sample_attributes, + .sample_time = 0, .sample_duration = 113823, + .buffer_count = 1, .buffers = output_buffer_desc, + }, + }; + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Audio, MFAudioFormat_AAC}; MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Audio, MFAudioFormat_PCM}; + IMFSample *input_sample, *output_sample; + IMFCollection *output_samples; + ULONG i, ret, audio_data_len; + DWORD length, output_status; IMFTransform *transform; + const BYTE *audio_data; HRESULT hr; - ULONG ret; + LONG ref;
hr = CoInitialize(NULL); ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr); @@ -1662,6 +1701,63 @@ static void test_aac_encoder(void) check_mft_get_input_stream_info(transform, &input_info); check_mft_get_output_stream_info(transform, &output_info);
+ if (!has_video_processor) + { + win_skip("Skipping AAC encoder tests on Win7\n"); + goto done; + } + + load_resource(L"audiodata.bin", &audio_data, &audio_data_len); + ok(audio_data_len == 179928, "got length %lu\n", audio_data_len); + + input_sample = create_sample(audio_data, audio_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_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0); + ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr); + ref = IMFSample_Release(input_sample); + ok(ref <= 1, "Release returned %ld\n", ref); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + output_sample = create_sample(NULL, 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, 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 == 88, "got %lu output samples\n", i); + + ret = check_mf_sample_collection(output_samples, output_sample_desc, L"aacencdata.bin"); + ok(ret == 0, "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); + 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); + +done: ret = IMFTransform_Release(transform); ok(ret == 0, "Release returned %lu\n", ret);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/aacdecdata.bin | Bin 0 -> 2048 bytes dlls/mf/tests/resource.rc | 3 ++ dlls/mf/tests/transform.c | 84 ++++++++++++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 dlls/mf/tests/aacdecdata.bin
diff --git a/dlls/mf/tests/aacdecdata.bin b/dlls/mf/tests/aacdecdata.bin new file mode 100644 index 0000000000000000000000000000000000000000..2ff06b66e406e8e1cb16f28bd7033fa522a907c3 GIT binary patch literal 2048 zcmeIu`#%#1008h!Q_W)=dJxuTO*3ut7^kwt47aW6G0%>PxLoUex~r}$wWXKI?TkW+ zqLx!^vuT)-N0eN`g|@6K4ar%inhaZi#{JUwPxt}=-+UYRHt>H9>;}99{9%!75xm@W ziEqhXAb}@M?O;EE7ii2O6TotW+tAHpkb%Wat7D*gd%V@0UHB?57{XCE8n@}%aR0`t zx4@OPukU~r`ZUl3J<>p#J2(OX0j6MYGlJaILmtY(eq`Iz%>iXf6;q}}Ck5zFK~W1Q zpvJ{2($M_jz`pj><ryusWpbUsa$x$2T_O(?r4`8HzLT-T;-4MbmfH&0dgNLu;Ua4G zOJk4|ti^uJ88LU?l`@q{xjh|B#+Rwn#&YT+w>2$2W476LNi?&~CqDQMTiKp{Kw4&a zn0|(_1mI0-&znSbd%()d3h(0zC3cXX`?#n2biceuHh^lW?wNcD<c<r0+!~>mf2zbt zJfE9lIGlT6>|LRFntpf4a^c}mr@5t08Ke0~w6j>^Hq$x7=d?ByTZ>Xj|7t*9gIxei zRT10zLbf}fT*5AN?Rrsa+3C(Ri(HU?jcVv6byk5=GoPFPlCOiRVj+dvlfq(6=(&B} zDNQK~(`d<~xIW{v;M$_$SJN)_Pa&79GxOo9U_qKT$<v~>+GDKZ1E>q@Vy*T%^JJJ% z(gCK4W4R##K|*{sqh_O-ld*fdm6;O_ps>pq-+AcW83AU_RAgve0Ve6lb@z|I&xbK0 zkz0SD52B(s#UrP-6h$Dq>HC+Yukb#Vcfr_h;;I&hAlKRt<UmFPhK+1CbLjn)1jqjU zalu>T9hS%UVxL1<KUO*;sAdk+pBLK(|HLZYggFKe)EE)li4*H^%pA~0Z^;2{Z>TvW z2j1d`%d%eu<eHqWw1?U?wF(FoSDYy0ytzF?c;~%BR51m}eeVY35(1-Mn|hAVpSq=& zJJd(lk`yxO%%ccpQFS=*{v{XN3-@NN-ioI_Yf2gqb~cGJ2X5Hp(;GrByZ1t>BYUqG zz@_nGm?%9P@_=~ZUe$#B*M^^Oo5dct6iTAq_jkC6wrfz6y(mWiXJ->kI4XrO>wNDf z6rR1u>~hHWXjxg%U4BJ-R^jt0yA9st+jul@yzHXdm~B{GSEl-pR-C7uxw)cvwTNDL zurL}CSo7O@X-635R-I#*OT$i``fudY+Ey_{qCg|NC0}AdRUkst<<ywMEY?vVcf%vq zc~2pq$IKmB;0p3g&(W?>2GM{@AlrJbraI$a;BXj=byCdE$s=f^t{zP$OMD`!Zj9C5 zj<mJpp<w@#-Y6h<gkfy}`~C7U&3*jMW+&Ze`yh3F3X4>wjiqU8Le4ym@Xg{?;@CIS zw<~WXCF=7MV?59*f7yn5x^C1vCRuZinxkzFEq^}~o>|+M79>9vKil^j-_ez~W4&xe zdYwFdhh>>GVw``P2IMXgqypkLGp7S<=IkV`fbC5lw#MNJA>pKnHOmrg`ehL~kk77U zBR0{#o9*jk%cAyTW5f1U&R1m#r~j!u^hTxM1sU<Yn*Hv0$tyWTfEtOsI%@;ut{Db$ fPd?s4V>L%p9UK0tFtk(o>G#VgVB$j-&X2zWwqq|&
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc index 25ac6d2fe0c..08d123d5c8f 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -29,6 +29,9 @@ audioconvdata.bin RCDATA audioconvdata.bin /* @makedep: aacencdata.bin */ aacencdata.bin RCDATA aacencdata.bin
+/* @makedep: aacdecdata.bin */ +aacdecdata.bin RCDATA aacdecdata.bin + /* @makedep: wmaencdata.bin */ wmaencdata.bin RCDATA wmaencdata.bin
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index f4148692489..0e0ae2417d5 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -1889,11 +1889,33 @@ static void test_aac_decoder(void) MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE | MFT_INPUT_STREAM_HOLDS_BUFFERS, };
+ const struct buffer_desc output_buffer_desc[] = + { + {.length = 0x800}, + }; + const struct attribute_desc output_sample_attributes[] = + { + ATTR_UINT32(MFSampleExtension_CleanPoint, 1), + {0}, + }; + const struct sample_desc output_sample_desc[] = + { + { + .attributes = output_sample_attributes + (has_video_processor ? 0 : 1) /* MFSampleExtension_CleanPoint missing on Win7 */, + .sample_time = 0, .sample_duration = 232200, + .buffer_count = 1, .buffers = output_buffer_desc, + }, + }; + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Audio, MFAudioFormat_Float}; MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Audio, MFAudioFormat_AAC}; + IMFSample *input_sample, *output_sample; + ULONG i, ret, ref, aacenc_data_len; + IMFCollection *output_samples; + DWORD length, output_status; IMFMediaType *media_type; IMFTransform *transform; - ULONG i, ret; + const BYTE *aacenc_data; HRESULT hr;
hr = CoInitialize(NULL); @@ -1974,6 +1996,66 @@ static void test_aac_decoder(void) check_mft_get_input_stream_info(transform, &input_info); check_mft_get_output_stream_info(transform, &output_info);
+ load_resource(L"aacencdata.bin", &aacenc_data, &aacenc_data_len); + ok(aacenc_data_len == 24861, "got length %lu\n", aacenc_data_len); + + input_sample = create_sample(aacenc_data + sizeof(DWORD), *(DWORD *)aacenc_data); + 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); + + /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES + * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */ + + hr = check_mft_process_output(transform, NULL, &output_status); + ok(hr == E_INVALIDARG, "ProcessOutput returned %#lx\n", hr); + ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + 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); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + output_sample = create_sample(NULL, 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, output_info.cbSize); + winetest_pop_context(); + } + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ok(output_status == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE, "got output[0].dwStatus %#lx\n", output_status); + 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, L"aacdecdata.bin"); + ok(ret == 0, "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 == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE, "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); + + ret = IMFSample_Release(input_sample); + ok(ret == 0, "Release returned %lu\n", ret); ret = IMFTransform_Release(transform); ok(ret == 0, "Release returned %lu\n", ret);
From: Rémi Bernon rbernon@codeweavers.com
Some transform do not handle the MFT_SET_TYPE_TEST_ONLY correctly, and setting the type may have undesired side effects. We already check the required attributes consistently now. --- dlls/mf/tests/transform.c | 19 ------------------- 1 file changed, 19 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 0e0ae2417d5..c494891c78a 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -1951,9 +1951,6 @@ static void test_aac_decoder(void) ok(hr == S_OK, "GetInputAvailableType returned %#lx\n", hr); check_media_type(media_type, expect_input_attributes, -1); check_media_type(media_type, expect_available_inputs[i], -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY); - if (i != 1) ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - else ok(hr == MF_E_INVALIDMEDIATYPE, "SetInputType returned %#lx.\n", hr); ret = IMFMediaType_Release(media_type); ok(ret <= 1, "Release returned %lu\n", ret); winetest_pop_context(); @@ -1980,8 +1977,6 @@ static void test_aac_decoder(void) ok(hr == S_OK, "GetOutputAvailableType returned %#lx\n", hr); check_media_type(media_type, expect_output_attributes, -1); check_media_type(media_type, expect_available_outputs[i], -1); - hr = IMFTransform_SetOutputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY); - ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); ret = IMFMediaType_Release(media_type); ok(ret <= 1, "Release returned %lu\n", ret); winetest_pop_context(); @@ -2542,8 +2537,6 @@ static void test_wma_decoder(void) winetest_push_context("in %lu", i); ok(hr == S_OK, "GetInputAvailableType returned %#lx\n", hr); check_media_type(media_type, expect_available_inputs[i], -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == MF_E_INVALIDMEDIATYPE, "SetInputType returned %#lx.\n", hr); ret = IMFMediaType_Release(media_type); ok(ret == 0, "Release returned %lu\n", ret); winetest_pop_context(); @@ -3546,8 +3539,6 @@ static void test_audio_convert(void) winetest_push_context("in %lu", i); ok(hr == S_OK, "GetInputAvailableType returned %#lx\n", hr); check_media_type(media_type, expect_available_inputs[i], -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == MF_E_INVALIDMEDIATYPE, "SetInputType returned %#lx.\n", hr); ret = IMFMediaType_Release(media_type); ok(ret == 0, "Release returned %lu\n", ret); winetest_pop_context(); @@ -3928,14 +3919,6 @@ static void test_color_convert(void) 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); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - if (i == 12) - { - todo_wine - ok(hr == MF_E_INVALIDMEDIATYPE, "SetInputType returned %#lx.\n", hr); - } - else - ok(hr == E_INVALIDARG, "SetInputType returned %#lx.\n", hr); ret = IMFMediaType_Release(media_type); ok(ret == 0, "Release returned %lu\n", ret); winetest_pop_context(); @@ -4823,8 +4806,6 @@ static void test_mp3_decoder(void) winetest_push_context("in %lu", i); ok(hr == S_OK, "GetInputAvailableType returned %#lx\n", hr); check_media_type(media_type, expect_available_inputs[i], -1); - hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - ok(hr == MF_E_INVALIDMEDIATYPE, "SetInputType returned %#lx.\n", hr); ret = IMFMediaType_Release(media_type); ok(ret == 0, "Release returned %lu\n", ret); winetest_pop_context();
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/transform.c | 481 ++++++++++++++++++++++++++++++++------ 1 file changed, 416 insertions(+), 65 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index c494891c78a..1a75fc00919 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -48,6 +48,8 @@ DEFINE_GUID(DMOVideoFormat_RGB8,D3DFMT_P8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf DEFINE_GUID(MFAudioFormat_RAW_AAC1,WAVE_FORMAT_RAW_AAC1,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); DEFINE_GUID(MFVideoFormat_ABGR32,0x00000020,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); DEFINE_GUID(MFVideoFormat_P208,0x38303250,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MFVideoFormat_VC1S,0x53314356,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(MFVideoFormat_WMV_Unknown,0x7ce12ca9,0xbfbf,0x43d9,0x9d,0x00,0x82,0xb8,0xed,0x54,0x31,0x6b);
DEFINE_GUID(mft_output_sample_incomplete,0xffffff,0xffff,0xffff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
@@ -382,15 +384,15 @@ static void check_mft_input_stream_info_(int line, MFT_INPUT_STREAM_INFO *value, check_member_(__FILE__, line, *value, *expect, "%#lx", cbAlignment); }
-#define check_mft_get_input_stream_info(a, b) check_mft_get_input_stream_info_(__LINE__, a, b) -static void check_mft_get_input_stream_info_(int line, IMFTransform *transform, const MFT_INPUT_STREAM_INFO *expect) +#define check_mft_get_input_stream_info(a, b, c) check_mft_get_input_stream_info_(__LINE__, a, b, c) +static void check_mft_get_input_stream_info_(int line, IMFTransform *transform, HRESULT expect_hr, const MFT_INPUT_STREAM_INFO *expect) { MFT_INPUT_STREAM_INFO info, empty = {0}; HRESULT hr;
memset(&info, 0xcd, sizeof(info)); hr = IMFTransform_GetInputStreamInfo(transform, 0, &info); - ok_(__FILE__, line)(hr == (expect ? S_OK : MF_E_TRANSFORM_TYPE_NOT_SET), "GetInputStreamInfo returned %#lx\n", hr); + ok_(__FILE__, line)(hr == expect_hr, "GetInputStreamInfo returned %#lx\n", hr); check_mft_input_stream_info_(line, &info, expect ? expect : &empty); }
@@ -402,15 +404,15 @@ static void check_mft_output_stream_info_(int line, MFT_OUTPUT_STREAM_INFO *valu check_member_(__FILE__, line, *value, *expect, "%#lx", cbAlignment); }
-#define check_mft_get_output_stream_info(a, b) check_mft_get_output_stream_info_(__LINE__, a, b) -static void check_mft_get_output_stream_info_(int line, IMFTransform *transform, const MFT_OUTPUT_STREAM_INFO *expect) +#define check_mft_get_output_stream_info(a, b, c) check_mft_get_output_stream_info_(__LINE__, a, b, c) +static void check_mft_get_output_stream_info_(int line, IMFTransform *transform, HRESULT expect_hr, const MFT_OUTPUT_STREAM_INFO *expect) { MFT_OUTPUT_STREAM_INFO info, empty = {0}; HRESULT hr;
memset(&info, 0xcd, sizeof(info)); hr = IMFTransform_GetOutputStreamInfo(transform, 0, &info); - ok_(__FILE__, line)(hr == (expect ? S_OK : MF_E_TRANSFORM_TYPE_NOT_SET), "GetInputStreamInfo returned %#lx\n", hr); + ok_(__FILE__, line)(hr == expect_hr, "GetOutputStreamInfo returned %#lx\n", hr); check_mft_output_stream_info_(line, &info, expect ? expect : &empty); }
@@ -1232,8 +1234,8 @@ static void test_sample_copier(void) hr = IMFMediaType_SetUINT64(mediatype, &MF_MT_FRAME_SIZE, ((UINT64)16) << 32 | 16); ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
- check_mft_get_input_stream_info(copier, &initial_input_info); - check_mft_get_output_stream_info(copier, &initial_output_info); + check_mft_get_input_stream_info(copier, S_OK, &initial_input_info); + check_mft_get_output_stream_info(copier, S_OK, &initial_output_info);
hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0); ok(hr == S_OK, "Failed to set input type, hr %#lx.\n", hr); @@ -1247,7 +1249,7 @@ static void test_sample_copier(void) check_member(info, initial_input_info, "%#lx", cbSize); check_member(info, initial_input_info, "%#lx", cbMaxLookahead); check_member(info, initial_input_info, "%#lx", cbAlignment); - check_mft_get_output_stream_info(copier, &output_info); + check_mft_get_output_stream_info(copier, S_OK, &output_info);
hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype2); ok(hr == S_OK, "Failed to get current type, hr %#lx.\n", hr); @@ -1274,8 +1276,8 @@ static void test_sample_copier(void) ok(is_sample_copier_available_type(mediatype2), "Unexpected type.\n"); IMFMediaType_Release(mediatype2);
- check_mft_get_input_stream_info(copier, &input_info); - check_mft_get_output_stream_info(copier, &output_info); + check_mft_get_input_stream_info(copier, S_OK, &input_info); + check_mft_get_output_stream_info(copier, S_OK, &output_info);
hr = IMFTransform_GetOutputAvailableType(copier, 0, 0, &mediatype2); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -1325,8 +1327,8 @@ static void test_sample_copier(void) hr = IMFTransform_ProcessInput(copier, 0, sample, 0); ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#lx.\n", hr);
- check_mft_get_input_stream_info(copier, &input_info); - check_mft_get_output_stream_info(copier, &output_info); + check_mft_get_input_stream_info(copier, S_OK, &input_info); + check_mft_get_output_stream_info(copier, S_OK, &output_info);
hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &media_buffer); ok(hr == S_OK, "Failed to create media buffer, hr %#lx.\n", hr); @@ -1687,8 +1689,8 @@ static void test_aac_encoder(void)
check_mft_optional_methods(transform); check_mft_get_attributes(transform, NULL, FALSE); - check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &initial_output_info); + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &initial_output_info);
check_mft_set_output_type_required(transform, output_type_desc); check_mft_set_output_type(transform, output_type_desc, S_OK); @@ -1698,8 +1700,8 @@ static void test_aac_encoder(void) check_mft_set_input_type(transform, input_type_desc); check_mft_get_input_current_type(transform, expect_input_type_desc);
- check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &output_info);
if (!has_video_processor) { @@ -1938,8 +1940,8 @@ static void test_aac_decoder(void)
check_mft_optional_methods(transform); check_mft_get_attributes(transform, expect_transform_attributes, FALSE); - check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &output_info);
hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputAvailableType returned %#lx\n", hr); @@ -1988,8 +1990,8 @@ static void test_aac_decoder(void) check_mft_set_output_type(transform, output_type_desc, S_OK); check_mft_get_output_current_type(transform, output_type_desc);
- check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + 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"aacencdata.bin", &aacenc_data, &aacenc_data_len); ok(aacenc_data_len == 24861, "got length %lu\n", aacenc_data_len); @@ -2220,8 +2222,8 @@ static void test_wma_encoder(void)
check_mft_optional_methods(transform); check_mft_get_attributes(transform, NULL, FALSE); - check_mft_get_input_stream_info(transform, NULL); - check_mft_get_output_stream_info(transform, NULL); + 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);
check_mft_set_input_type_required(transform, input_type_desc);
@@ -2241,8 +2243,8 @@ static void test_wma_encoder(void) check_mft_set_input_type(transform, input_type_desc); check_mft_get_input_current_type(transform, expect_input_type_desc);
- check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + 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"audiodata.bin", &audio_data, &audio_data_len); ok(audio_data_len == 179928, "got length %lu\n", audio_data_len); @@ -2525,8 +2527,8 @@ static void test_wma_decoder(void)
check_mft_optional_methods(transform); check_mft_get_attributes(transform, NULL, FALSE); - check_mft_get_input_stream_info(transform, NULL); - check_mft_get_output_stream_info(transform, NULL); + 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);
hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputAvailableType returned %#lx\n", hr); @@ -2554,8 +2556,8 @@ static void test_wma_decoder(void) check_mft_set_input_type(transform, input_type_desc); check_mft_get_input_current_type_(transform, expect_input_type_desc, TRUE, FALSE);
- check_mft_get_input_stream_info(transform, NULL); - check_mft_get_output_stream_info(transform, NULL); + 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);
/* check new output media types */
@@ -2576,8 +2578,8 @@ static void test_wma_decoder(void) check_mft_set_output_type(transform, output_type_desc, S_OK); check_mft_get_output_current_type_(transform, expect_output_type_desc, TRUE, FALSE);
- check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + 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"wmaencdata.bin", &wmaenc_data, &wmaenc_data_len); ok(wmaenc_data_len % wmaenc_block_size == 0, "got length %lu\n", wmaenc_data_len); @@ -3069,8 +3071,8 @@ static void test_h264_decoder(void)
check_mft_optional_methods(transform); check_mft_get_attributes(transform, expect_transform_attributes, TRUE); - check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &initial_output_info); + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &initial_output_info);
hr = IMFTransform_GetAttributes(transform, &attributes); ok(hr == S_OK, "GetAttributes returned %#lx\n", hr); @@ -3106,8 +3108,8 @@ static void test_h264_decoder(void) check_mft_set_input_type(transform, input_type_desc); check_mft_get_input_current_type_(transform, expect_input_type_desc, TRUE, FALSE);
- check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &output_info);
/* output types can now be enumerated (though they are actually the same for all input types) */
@@ -3143,8 +3145,8 @@ static void test_h264_decoder(void) ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); ok(i == 5, "%lu output media types\n", i);
- check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + 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"h264data.bin", &h264_encoded_data, &h264_encoded_data_len);
@@ -3199,8 +3201,8 @@ static void test_h264_decoder(void) ret = IMFSample_Release(output_sample); ok(ret == 0, "Release returned %lu\n", ret);
- check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &actual_output_info); + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &actual_output_info);
i = -1; while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, ++i, &media_type))) @@ -3517,8 +3519,8 @@ static void test_audio_convert(void)
check_mft_optional_methods(transform); check_mft_get_attributes(transform, NULL, FALSE); - check_mft_get_input_stream_info(transform, NULL); - check_mft_get_output_stream_info(transform, NULL); + 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))) @@ -3554,8 +3556,8 @@ static void test_audio_convert(void) 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, NULL); - check_mft_get_output_stream_info(transform, NULL); + 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);
/* check new output media types */
@@ -3576,8 +3578,8 @@ static void test_audio_convert(void) 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_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + 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"audiodata.bin", &audio_data, &audio_data_len); ok(audio_data_len == 179928, "got length %lu\n", audio_data_len); @@ -3641,6 +3643,354 @@ failed: CoUninitialize(); }
+static void test_wmv_decoder(void) +{ + const GUID *const class_id = &CLSID_CWMVDecMediaObject; + const struct transform_info expect_mft_info = + { + .name = L"WMVideo Decoder MFT", + .major_type = &MFMediaType_Video, + .inputs = + { + {.subtype = &MFVideoFormat_WMV1}, + {.subtype = &MFVideoFormat_WMV2}, + {.subtype = &MFVideoFormat_WMV3}, + {.subtype = &MEDIASUBTYPE_WMVP}, + {.subtype = &MEDIASUBTYPE_WVP2}, + {.subtype = &MEDIASUBTYPE_WMVR}, + {.subtype = &MEDIASUBTYPE_WMVA}, + {.subtype = &MFVideoFormat_WVC1}, + {.subtype = &MFVideoFormat_VC1S}, + }, + .outputs = + { + {.subtype = &MFVideoFormat_YV12}, + {.subtype = &MFVideoFormat_YUY2}, + {.subtype = &MFVideoFormat_UYVY}, + {.subtype = &MFVideoFormat_YVYU}, + {.subtype = &MFVideoFormat_NV11}, + {.subtype = &MFVideoFormat_NV12}, + {.subtype = &DMOVideoFormat_RGB32}, + {.subtype = &DMOVideoFormat_RGB24}, + {.subtype = &DMOVideoFormat_RGB565}, + {.subtype = &DMOVideoFormat_RGB555}, + {.subtype = &DMOVideoFormat_RGB8}, + }, + }; + const struct transform_info expect_dmo_info = + { + .name = L"WMVideo Decoder DMO", + .major_type = &MEDIATYPE_Video, + .inputs = + { + {.subtype = &MEDIASUBTYPE_WMV1}, + {.subtype = &MEDIASUBTYPE_WMV2}, + {.subtype = &MEDIASUBTYPE_WMV3}, + {.subtype = &MEDIASUBTYPE_WMVA}, + {.subtype = &MEDIASUBTYPE_WVC1}, + {.subtype = &MEDIASUBTYPE_WMVP}, + {.subtype = &MEDIASUBTYPE_WVP2}, + {.subtype = &MFVideoFormat_VC1S}, + }, + .outputs = + { + {.subtype = &MEDIASUBTYPE_YV12}, + {.subtype = &MEDIASUBTYPE_YUY2}, + {.subtype = &MEDIASUBTYPE_UYVY}, + {.subtype = &MEDIASUBTYPE_YVYU}, + {.subtype = &MEDIASUBTYPE_NV11}, + {.subtype = &MEDIASUBTYPE_NV12}, + {.subtype = &MEDIASUBTYPE_RGB32}, + {.subtype = &MEDIASUBTYPE_RGB24}, + {.subtype = &MEDIASUBTYPE_RGB565}, + {.subtype = &MEDIASUBTYPE_RGB555}, + {.subtype = &MEDIASUBTYPE_RGB8}, + }, + }; + + static const struct attribute_desc expect_common_attributes[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + {0}, + }; + static const media_type_desc expect_available_inputs[] = + { + {ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WMV1)}, + {ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WMV2)}, + {ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_WMVA)}, + {ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_WMVP)}, + {ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_WVP2)}, + {ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WMV_Unknown)}, + {ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WVC1)}, + {ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WMV3)}, + {ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_VC1S)}, + }; + static const MFVideoArea actual_aperture = {.Area={96,96}}; + static const DWORD actual_width = 96, actual_height = 96; + const struct attribute_desc expect_output_attributes[] = + { + ATTR_BLOB(MF_MT_GEOMETRIC_APERTURE, &actual_aperture, sizeof(actual_aperture)), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, sizeof(actual_aperture)), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_INTERLACE_MODE, 2), + {0}, + }; + const media_type_desc expect_available_outputs[] = + { + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YV12), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_IYUV), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_I420), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 2), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 2), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_UYVY), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 2), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 2), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YVYU), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 2), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 2), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV11), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + }, + { + 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_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 3), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB565), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 2), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 2), + /* ATTR_BLOB(MF_MT_PALETTE, ... with 12 elements), */ + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB555), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 2), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 2), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB8), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height), + /* ATTR_BLOB(MF_MT_PALETTE, ... with 904 elements), */ + }, + }; + const struct attribute_desc expect_attributes[] = + { + ATTR_UINT32(MF_LOW_LATENCY, 0), + ATTR_UINT32(MF_SA_D3D11_AWARE, 1), + ATTR_UINT32(MF_SA_D3D_AWARE, 1), + ATTR_UINT32(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER, 0), + /* more attributes from CODECAPI */ + {0}, + }; + const struct attribute_desc input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WMV1, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + {0}, + }; + const struct attribute_desc output_type_desc[] = + { + 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), + {0}, + }; + const struct attribute_desc expect_input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WMV1), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + {0}, + }; + const struct attribute_desc expect_output_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + 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 empty_output_info = + { + .dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_DISCARDABLE, + }; + const MFT_INPUT_STREAM_INFO expect_input_info = + { + .cbSize = 0x3600, + .cbAlignment = 1, + }; + + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Video, MFVideoFormat_NV12}; + MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Video, MFVideoFormat_WMV1}; + IMFMediaType *media_type; + IMFTransform *transform; + ULONG i, ret; + HRESULT hr; + + hr = CoInitialize(NULL); + ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr); + + winetest_push_context("wmvdec"); + + if (!has_video_processor) + { + win_skip("Skipping inconsistent WMV decoder tests on Win7\n"); + goto failed; + } + + if (!check_mft_enum(MFT_CATEGORY_VIDEO_DECODER, &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); + check_interface(transform, &IID_IPropertyBag, TRUE); + + check_mft_optional_methods(transform); + check_mft_get_attributes(transform, expect_attributes, TRUE); + 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, &empty_output_info); + + hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); + todo_wine + ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputAvailableType returned %#lx\n", hr); + + 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_common_attributes, -1); + check_media_type(media_type, expect_available_inputs[i], -1); + ret = IMFMediaType_Release(media_type); + ok(!ret, "Release returned %lu\n", ret); + winetest_pop_context(); + } + todo_wine + ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr); + todo_wine + ok(i == ARRAY_SIZE(expect_available_inputs), "%lu input media types\n", i); + + if (hr == E_NOTIMPL) + goto skip_tests; + + check_mft_set_output_type(transform, output_type_desc, MF_E_TRANSFORM_TYPE_NOT_SET); + check_mft_get_output_current_type(transform, NULL); + + 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); + + 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_common_attributes, -1); + check_media_type(media_type, expect_output_attributes, -1); + check_media_type(media_type, expect_available_outputs[i], -1); + ret = IMFMediaType_Release(media_type); + ok(!ret, "Release returned %lu\n", ret); + winetest_pop_context(); + } + 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); + + 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_get_input_stream_info(transform, S_OK, &expect_input_info); + check_mft_get_output_stream_info(transform, S_OK, &expect_output_info); + +skip_tests: + ret = IMFTransform_Release(transform); + ok(ret == 0, "Release returned %lu\n", ret); + +failed: + winetest_pop_context(); + CoUninitialize(); +} + static void test_color_convert(void) { const GUID *const class_id = &CLSID_CColorConvertDMO; @@ -3895,8 +4245,8 @@ static void test_color_convert(void)
check_mft_optional_methods(transform); check_mft_get_attributes(transform, NULL, FALSE); - check_mft_get_input_stream_info(transform, NULL); - check_mft_get_output_stream_info(transform, NULL); + 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))) @@ -3934,8 +4284,8 @@ static void test_color_convert(void) 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, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + 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 */ @@ -4229,8 +4579,8 @@ static void test_video_processor(void) check_mft_get_input_current_type(transform, NULL); check_mft_get_output_current_type(transform, NULL);
- check_mft_get_input_stream_info(transform, &initial_input_info); - check_mft_get_output_stream_info(transform, &initial_output_info); + check_mft_get_input_stream_info(transform, S_OK, &initial_input_info); + check_mft_get_output_stream_info(transform, S_OK, &initial_output_info);
/* Configure stream types. */ for (i = 0;;++i) @@ -4306,8 +4656,8 @@ static void test_video_processor(void) || IsEqualGUID(&guid, &MFVideoFormat_Y41P)) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); } - check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &initial_output_info); + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &initial_output_info);
IMFMediaType_Release(media_type); } @@ -4338,8 +4688,8 @@ static void test_video_processor(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = MFCalculateImageSize(&MFVideoFormat_RGB32, 16, 16, (UINT32 *)&output_info.cbSize); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + check_mft_get_input_stream_info(transform, S_OK, &input_info); + check_mft_get_output_stream_info(transform, S_OK, &output_info);
hr = MFCreateSample(&input_sample); ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr); @@ -4411,8 +4761,8 @@ static void test_video_processor(void)
check_mft_optional_methods(transform); check_mft_get_attributes(transform, expect_transform_attributes, TRUE); - check_mft_get_input_stream_info(transform, &initial_input_info); - check_mft_get_output_stream_info(transform, &initial_output_info); + check_mft_get_input_stream_info(transform, S_OK, &initial_input_info); + check_mft_get_output_stream_info(transform, S_OK, &initial_output_info);
hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); @@ -4509,8 +4859,8 @@ static void test_video_processor(void)
input_info.cbSize = actual_width * actual_height * 3 / 2; output_info.cbSize = actual_width * actual_height * 4; - check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + 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 */ @@ -4794,8 +5144,8 @@ static void test_mp3_decoder(void)
check_mft_optional_methods(transform); check_mft_get_attributes(transform, NULL, FALSE); - check_mft_get_input_stream_info(transform, NULL); - check_mft_get_output_stream_info(transform, NULL); + 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);
hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputAvailableType returned %#lx\n", hr); @@ -4823,8 +5173,8 @@ static void test_mp3_decoder(void) check_mft_set_input_type(transform, input_type_desc); check_mft_get_input_current_type(transform, expect_input_type_desc);
- check_mft_get_input_stream_info(transform, NULL); - check_mft_get_output_stream_info(transform, NULL); + 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);
/* check new output media types */
@@ -4845,8 +5195,8 @@ static void test_mp3_decoder(void) check_mft_set_output_type(transform, output_type_desc, S_OK); check_mft_get_output_current_type(transform, expect_output_type_desc);
- check_mft_get_input_stream_info(transform, &input_info); - check_mft_get_output_stream_info(transform, &output_info); + 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"mp3encdata.bin", &mp3enc_data, &mp3enc_data_len); ok(mp3enc_data_len == 6295, "got length %lu\n", mp3enc_data_len); @@ -4940,6 +5290,7 @@ START_TEST(transform) test_wma_encoder(); test_wma_decoder(); test_h264_decoder(); + test_wmv_decoder(); test_audio_convert(); test_color_convert(); test_video_processor();
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/transform.c | 382 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 367 insertions(+), 15 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 1a75fc00919..8daa2ce1d3a 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -267,7 +267,7 @@ void init_media_type(IMFMediaType *mediatype, const struct attribute_desc *desc, } }
-static void check_mft_optional_methods(IMFTransform *transform) +static void check_mft_optional_methods(IMFTransform *transform, DWORD output_count) { DWORD in_id, out_id, in_count, out_count, in_min, in_max, out_min, out_max; PROPVARIANT propvar = {.vt = VT_EMPTY}; @@ -279,14 +279,14 @@ static void check_mft_optional_methods(IMFTransform *transform) ok(hr == S_OK, "GetStreamLimits returned %#lx\n", hr); ok(in_min == 1, "got input_min %lu\n", in_min); ok(in_max == 1, "got input_max %lu\n", in_max); - ok(out_min == 1, "got output_min %lu\n", out_min); - ok(out_max == 1, "got output_max %lu\n", out_max); + ok(out_min == output_count, "got output_min %lu\n", out_min); + ok(out_max == output_count, "got output_max %lu\n", out_max);
in_count = out_count = 0xdeadbeef; hr = IMFTransform_GetStreamCount(transform, &in_count, &out_count); ok(hr == S_OK, "GetStreamCount returned %#lx\n", hr); ok(in_count == 1, "got input_count %lu\n", in_count); - ok(out_count == 1, "got output_count %lu\n", out_count); + ok(out_count == output_count, "got output_count %lu\n", out_count);
in_count = out_count = 1; in_id = out_id = 0xdeadbeef; @@ -1184,7 +1184,7 @@ static void test_sample_copier(void) check_interface(copier, &IID_IPropertyStore, FALSE); check_interface(copier, &IID_IPropertyBag, FALSE);
- check_mft_optional_methods(copier); + check_mft_optional_methods(copier, 1); check_mft_get_attributes(copier, expect_transform_attributes, FALSE);
/* Available types. */ @@ -1687,7 +1687,7 @@ static void test_aac_encoder(void) check_interface(transform, &IID_IPropertyStore, FALSE); check_interface(transform, &IID_IPropertyBag, FALSE);
- check_mft_optional_methods(transform); + check_mft_optional_methods(transform, 1); check_mft_get_attributes(transform, NULL, FALSE); check_mft_get_input_stream_info(transform, S_OK, &input_info); check_mft_get_output_stream_info(transform, S_OK, &initial_output_info); @@ -1938,7 +1938,7 @@ static void test_aac_decoder(void) check_interface(transform, &IID_IPropertyStore, FALSE); check_interface(transform, &IID_IPropertyBag, FALSE);
- check_mft_optional_methods(transform); + check_mft_optional_methods(transform, 1); check_mft_get_attributes(transform, expect_transform_attributes, FALSE); check_mft_get_input_stream_info(transform, S_OK, &input_info); check_mft_get_output_stream_info(transform, S_OK, &output_info); @@ -2220,7 +2220,7 @@ static void test_wma_encoder(void) check_interface(transform, &IID_IPropertyStore, TRUE); check_interface(transform, &IID_IPropertyBag, TRUE);
- check_mft_optional_methods(transform); + 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); @@ -2525,7 +2525,7 @@ static void test_wma_decoder(void) check_interface(transform, &IID_IPropertyStore, TRUE); check_interface(transform, &IID_IPropertyBag, TRUE);
- check_mft_optional_methods(transform); + 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); @@ -3069,7 +3069,7 @@ static void test_h264_decoder(void) check_interface(transform, &IID_IPropertyStore, FALSE); check_interface(transform, &IID_IPropertyBag, FALSE);
- check_mft_optional_methods(transform); + check_mft_optional_methods(transform, 1); check_mft_get_attributes(transform, expect_transform_attributes, TRUE); check_mft_get_input_stream_info(transform, S_OK, &input_info); check_mft_get_output_stream_info(transform, S_OK, &initial_output_info); @@ -3517,7 +3517,7 @@ static void test_audio_convert(void) check_interface(transform, &IID_IPropertyBag, TRUE); /* check_interface(transform, &IID_IWMResamplerProps, TRUE); */
- check_mft_optional_methods(transform); + 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); @@ -3643,6 +3643,357 @@ failed: CoUninitialize(); }
+static void test_wmv_encoder(void) +{ + const GUID *const class_id = &CLSID_CWMVXEncMediaObject; + const struct transform_info expect_mft_info = + { + .name = L"WMVideo8 Encoder MFT", + .major_type = &MFMediaType_Video, + .inputs = + { + {.subtype = &MFVideoFormat_IYUV}, + {.subtype = &MFVideoFormat_I420}, + {.subtype = &MFVideoFormat_YV12}, + {.subtype = &MFVideoFormat_NV11}, + {.subtype = &MFVideoFormat_NV12}, + {.subtype = &MFVideoFormat_YUY2}, + {.subtype = &MFVideoFormat_UYVY}, + {.subtype = &MFVideoFormat_YVYU}, + {.subtype = &MFVideoFormat_YVU9}, + {.subtype = &DMOVideoFormat_RGB32}, + {.subtype = &DMOVideoFormat_RGB24}, + {.subtype = &DMOVideoFormat_RGB565}, + {.subtype = &DMOVideoFormat_RGB555}, + {.subtype = &DMOVideoFormat_RGB8}, + }, + .outputs = + { + {.subtype = &MFVideoFormat_WMV1}, + {.subtype = &MFVideoFormat_WMV2}, + }, + }; + const struct transform_info expect_dmo_info = + { + .name = L"WMVideo8 Encoder DMO", + .major_type = &MEDIATYPE_Video, + .inputs = + { + {.subtype = &MEDIASUBTYPE_IYUV}, + {.subtype = &MEDIASUBTYPE_I420}, + {.subtype = &MEDIASUBTYPE_YV12}, + {.subtype = &MEDIASUBTYPE_NV11}, + {.subtype = &MEDIASUBTYPE_NV12}, + {.subtype = &MEDIASUBTYPE_YUY2}, + {.subtype = &MEDIASUBTYPE_UYVY}, + {.subtype = &MEDIASUBTYPE_YVYU}, + {.subtype = &MEDIASUBTYPE_YVU9}, + {.subtype = &MEDIASUBTYPE_RGB32}, + {.subtype = &MEDIASUBTYPE_RGB24}, + {.subtype = &MEDIASUBTYPE_RGB565}, + {.subtype = &MEDIASUBTYPE_RGB555}, + {.subtype = &MEDIASUBTYPE_RGB8}, + }, + .outputs = + { + {.subtype = &MEDIASUBTYPE_WMV1}, + {.subtype = &MEDIASUBTYPE_WMV2}, + }, + }; + + static const media_type_desc expect_available_inputs[] = + { + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_IYUV), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_I420), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YV12), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV11), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_UYVY), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YVYU), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB565), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB555), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_RGB8), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + }; + static const media_type_desc expect_available_outputs[] = + { + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WMV1), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WMV2), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + ATTR_UINT32(MF_MT_TRANSFER_FUNCTION, 0), + ATTR_UINT32(MF_MT_VIDEO_PRIMARIES, 0), + ATTR_UINT32(MF_MT_YUV_MATRIX, 0), + }, + }; + + static const DWORD actual_width = 96, actual_height = 96; + const struct attribute_desc input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), /* required for SetOutputType */ + {0}, + }; + const struct attribute_desc output_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video, .required = TRUE), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WMV1, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .required = TRUE), + ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001, .required = TRUE), + ATTR_UINT32(MF_MT_AVG_BITRATE, 193540, .required = TRUE), + {0}, + }; + + const struct attribute_desc expect_input_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), + ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + 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[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_WMV1), + ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height), + ATTR_RATIO(MF_MT_FRAME_RATE, 30000, 1001), + ATTR_UINT32(MF_MT_AVG_BITRATE, 193540), + ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1), + {0}, + }; + static const MFT_OUTPUT_STREAM_INFO empty_output_info = + { + .dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER, + }; + static const MFT_INPUT_STREAM_INFO empty_input_info = + { + .dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER, + }; + static const MFT_OUTPUT_STREAM_INFO expect_output_info = + { + .dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER, + .cbSize = 0x8000, + .cbAlignment = 1, + }; + static const MFT_INPUT_STREAM_INFO expect_input_info = + { + .dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER, + .cbSize = 0x3600, + .cbAlignment = 1, + }; + + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Video, MFVideoFormat_WMV1}; + MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Video, MFVideoFormat_NV12}; + IMFMediaType *media_type; + IMFTransform *transform; + ULONG i, ret; + HRESULT hr; + + hr = CoInitialize(NULL); + ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr); + + winetest_push_context("wmvenc"); + + if (!check_mft_enum(MFT_CATEGORY_VIDEO_ENCODER, &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); + check_interface(transform, &IID_IPropertyBag, TRUE); + + check_mft_optional_methods(transform, 2); + check_mft_get_attributes(transform, NULL, FALSE); + check_mft_get_input_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, &empty_input_info); + check_mft_get_output_stream_info(transform, MF_E_TRANSFORM_TYPE_NOT_SET, &empty_output_info); + + i = -1; + while (SUCCEEDED(hr = IMFTransform_GetInputAvailableType(transform, 0, ++i, &media_type))) + { + winetest_push_context("in 0 %lu", i); + ok(hr == S_OK, "GetInputAvailableType returned %#lx\n", hr); + ret = IMFMediaType_Release(media_type); + ok(ret <= 1, "Release returned %lu\n", ret); + winetest_pop_context(); + } + ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr); + ok(i == ARRAY_SIZE(expect_available_inputs), "%lu input media types\n", i); + + 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); + ret = IMFMediaType_Release(media_type); + ok(ret <= 1, "Release returned %lu\n", ret); + winetest_pop_context(); + } + ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); + ok(i == ARRAY_SIZE(expect_available_outputs), "%lu output media types\n", i); + + check_mft_set_output_type(transform, output_type_desc, MF_E_TRANSFORM_TYPE_NOT_SET); + check_mft_get_output_current_type(transform, NULL); + + 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); + + check_mft_get_input_stream_info(transform, S_OK, &expect_input_info); + check_mft_get_output_stream_info(transform, S_OK, &expect_output_info); + + ret = IMFTransform_Release(transform); + ok(ret == 0, "Release returned %lu\n", ret); + +failed: + winetest_pop_context(); + CoUninitialize(); +} + static void test_wmv_decoder(void) { const GUID *const class_id = &CLSID_CWMVDecMediaObject; @@ -3925,7 +4276,7 @@ static void test_wmv_decoder(void) check_interface(transform, &IID_IPropertyStore, TRUE); check_interface(transform, &IID_IPropertyBag, TRUE);
- check_mft_optional_methods(transform); + check_mft_optional_methods(transform, 1); check_mft_get_attributes(transform, expect_attributes, TRUE); 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, &empty_output_info); @@ -4243,7 +4594,7 @@ static void test_color_convert(void) check_interface(transform, &IID_IMFRealTimeClient, TRUE); /* check_interface(transform, &IID_IWMColorConvProps, TRUE); */
- check_mft_optional_methods(transform); + 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); @@ -4759,7 +5110,7 @@ static void test_video_processor(void) check_interface(transform, &IID_IPropertyStore, FALSE); check_interface(transform, &IID_IPropertyBag, FALSE);
- check_mft_optional_methods(transform); + check_mft_optional_methods(transform, 1); check_mft_get_attributes(transform, expect_transform_attributes, TRUE); check_mft_get_input_stream_info(transform, S_OK, &initial_input_info); check_mft_get_output_stream_info(transform, S_OK, &initial_output_info); @@ -5142,7 +5493,7 @@ static void test_mp3_decoder(void) check_interface(transform, &IID_IPropertyStore, TRUE); check_interface(transform, &IID_IPropertyBag, FALSE);
- check_mft_optional_methods(transform); + 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); @@ -5290,6 +5641,7 @@ START_TEST(transform) test_wma_encoder(); test_wma_decoder(); test_h264_decoder(); + test_wmv_encoder(); test_wmv_decoder(); test_audio_convert(); test_color_convert();
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/resource.rc | 3 ++ dlls/mf/tests/transform.c | 94 ++++++++++++++++++++++++++++++++++- dlls/mf/tests/wmvencdata.bin | Bin 0 -> 911 bytes 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 dlls/mf/tests/wmvencdata.bin
diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc index 08d123d5c8f..6cbf64d4528 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -38,6 +38,9 @@ wmaencdata.bin RCDATA wmaencdata.bin /* @makedep: wmadecdata.bin */ wmadecdata.bin RCDATA wmadecdata.bin
+/* @makedep: wmvencdata.bin */ +wmvencdata.bin RCDATA wmvencdata.bin + /* Generated with: * gst-launch-1.0 filesrc location=dlls/mf/tests/audiodata.bin ! \ * audio/x-raw,format=F32LE,rate=22050,channels=2,layout=interleaved ! \ diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 8daa2ce1d3a..dc3ae2b7201 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -572,7 +572,7 @@ static HRESULT check_mft_process_output_(int line, IMFTransform *transform, IMFS { static const DWORD expect_flags = MFT_OUTPUT_DATA_BUFFER_INCOMPLETE | MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE | MFT_OUTPUT_DATA_BUFFER_STREAM_END | MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE; - MFT_OUTPUT_DATA_BUFFER output[2]; + MFT_OUTPUT_DATA_BUFFER output[3]; HRESULT hr, ret; DWORD status;
@@ -3917,12 +3917,47 @@ static void test_wmv_encoder(void) .cbAlignment = 1, };
+ const struct buffer_desc output_buffer_desc[] = + { + {.length = -1 /* variable */}, + }; + const struct attribute_desc output_sample_attributes_key[] = + { + ATTR_UINT32(MFSampleExtension_CleanPoint, 1), + {0}, + }; + const struct attribute_desc output_sample_attributes[] = + { + ATTR_UINT32(MFSampleExtension_CleanPoint, 0), + {0}, + }; + const struct sample_desc output_sample_desc[] = + { + { + .attributes = output_sample_attributes_key, + .sample_time = 0, .sample_duration = 333333, + .buffer_count = 1, .buffers = output_buffer_desc, + }, + { + .attributes = output_sample_attributes, + .sample_time = 333333, .sample_duration = 333333, + .buffer_count = 1, .buffers = output_buffer_desc, .repeat_count = 4 + }, + }; + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Video, MFVideoFormat_WMV1}; MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Video, MFVideoFormat_NV12}; + IMFSample *input_sample, *output_sample; + DWORD status, length, output_status; + MFT_OUTPUT_DATA_BUFFER output; + IMFCollection *output_samples; + const BYTE *nv12frame_data; IMFMediaType *media_type; + ULONG nv12frame_data_len; IMFTransform *transform; ULONG i, ret; HRESULT hr; + LONG ref;
hr = CoInitialize(NULL); ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr); @@ -3986,6 +4021,63 @@ static void test_wmv_encoder(void) check_mft_get_input_stream_info(transform, S_OK, &expect_input_info); check_mft_get_output_stream_info(transform, S_OK, &expect_output_info);
+ if (!has_video_processor) + { + win_skip("Skipping WMV encoder tests on Win7\n"); + goto done; + } + + 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); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + for (i = 0; i < 5; i++) + { + input_sample = create_sample(nv12frame_data, nv12frame_data_len); + hr = IMFSample_SetSampleTime(input_sample, i * 333333); + 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); + ref = IMFSample_Release(input_sample); + ok(ref <= 1, "Release returned %ld\n", ref); + + output_sample = create_sample(NULL, expect_output_info.cbSize); + hr = check_mft_process_output(transform, output_sample, &output_status); + 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); + } + + ret = check_mf_sample_collection(output_samples, output_sample_desc, L"wmvencdata.bin"); + ok(ret == 0, "got %lu%% diff\n", ret); + IMFCollection_Release(output_samples); + + output_sample = create_sample(NULL, expect_output_info.cbSize); + status = 0xdeadbeef; + memset(&output, 0, sizeof(output)); + output.pSample = output_sample; + hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); + ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + ok(output.pSample == output_sample, "got pSample %p\n", output.pSample); + ok(output.dwStatus == 0, "got dwStatus %#lx\n", output.dwStatus); + ok(status == 0, "got status %#lx\n", status); + hr = IMFSample_GetTotalLength(output.pSample, &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); + +done: ret = IMFTransform_Release(transform); ok(ret == 0, "Release returned %lu\n", ret);
diff --git a/dlls/mf/tests/wmvencdata.bin b/dlls/mf/tests/wmvencdata.bin new file mode 100644 index 0000000000000000000000000000000000000000..a409afaf143822627e2bf775fb88900cca342dda GIT binary patch literal 911 zcmV;A191GB0ssIBu8bT3fq~%AIYNR{@QN4swwy9rXSC6Bn@H;gbL$uN9-_s+55w^M z0|=XmP^i!grpsU@(aAO7fD?8|_kts#Mar;W-7X4$TBhXxDKb!H)InM*%YslMgPCv; zNC*hnO9VxArkjgt^X0c~BB9js-Np}rFXILS3>ZOhVk5zv4Z#sI3<1zEl7PepgE<%Y zejkV6TpXe-nAONM7k4E@otHr;kwA=9ksFKU$gvxC*pf=+B#Od%9v{nT{P)D86ar%I z-J)Bn%oO(2i@)l`DhWPZQh(6C52p4I-uRR!1dn8H2M6F40zlzBAI1y`7%*cXfDA-H z2ZJ{cf+AcH!Q1*MF#JCc!|*N+TD#YP5KWif9HK0mHD^$B-7E?}2>wuHkBcY~Szt;; zP-6fBL_};xf7`byqS}0a^X;kuz?Q(^`~sjz94Fw2=mrFg7&(wY1|lE>ft!cH5g&>K zFm}F*j6V;<@cavjemIp*{1GZ@`Ju~Odhh}XvitKBn4;AXPP$wa{)S6)@{=SyT}9H% zE(t)24qy;S2n~SC!}&_aOd{9}IAv3e9|B*-3<el5g5bnQgE$+4B4ii?pkXBehz$mE zFYx?755TxNL|HUyN?f8<JMcuQtLCv*L~bvaBF}0~u_TqsNfm_jJU^Dx`R|EFC<MiW zT0mLc_bOUxf{Ikzkg!>e3vz|eM1_I#+nD0Fz9dkeFdoR*7#~oS2Pl*fXp|yElyEu> z52?WsC2}g$!E1e7oc~skGuDuDuvXF_9^AB>2K+w{!|*!6kU<3)K?D%^91WL(C?XC) z)(2TL3Irbx8wU=UYrQPtUwDpi|A!=#B$6haa#miffBLMwU(40js<nT={mhep{kJ9% z05t#r07qxQS57%HAA?qVCjOPdqF`uU^c+)_9}mI0VUvFWT{%(k#gl(Z;L$KNF8Wl1 zLU9N}92}4U002aQZ4xJev`C%?(IR*oM2X;S5+{LQ5V%*uaA<ayPioD?CtGcSUmBHz zQ*_WYux@6Eku*e!q9jcbB4~*d2OL5|&k4bxh~A&o+o(=~v`C%?(IR*oM2X;S5+{MQ zNS+0J6|9hhL$<GU_N?4P(Q|FNUk0KnGz}~j%!rv0G9qL|$cbMZCgDSoq7G6wc;FKN l002d2|4mFo^w4Nu|I<?=2ATK-W(fcQ07Vb~|No|gRepa*iw^(*
literal 0 HcmV?d00001
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/transform.c | 62 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index dc3ae2b7201..e66baa6e7c9 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4336,11 +4336,33 @@ static void test_wmv_decoder(void) .cbAlignment = 1, };
+ const struct attribute_desc output_sample_attributes[] = + { + ATTR_UINT32(MFSampleExtension_CleanPoint, 1), + {0}, + }; + const struct buffer_desc output_buffer_desc_nv12 = + { + .length = actual_width * actual_height * 3 / 2, + .compare = compare_nv12, .dump = dump_nv12, .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, + }; + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Video, MFVideoFormat_NV12}; MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Video, MFVideoFormat_WMV1}; + IMFSample *input_sample, *output_sample; + IMFCollection *output_samples; IMFMediaType *media_type; IMFTransform *transform; - ULONG i, ret; + const BYTE *wmvenc_data; + ULONG wmvenc_data_len; + DWORD output_status; + ULONG i, ret, ref; HRESULT hr;
hr = CoInitialize(NULL); @@ -4425,6 +4447,44 @@ static void test_wmv_decoder(void) 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); + skip_tests: ret = IMFTransform_Release(transform); ok(ret == 0, "Release returned %lu\n", ret);