I believe this doesn't conflict with https://gitlab.winehq.org/wine/wine/-/merge_requests/22
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183
-- v3: mf/tests: Add tests for the ColorConvertDMO video transform. mf/tests: Check VideoProcessorMFT transform media types. mf/tests: Add tests for the ResamplerMediaObject audio transform. mf/tests: Add more DMO class name, media type and interface checks. mf/tests: Check expected class GUID in create_transform.
From: Rémi Bernon rbernon@codeweavers.com
Calling MFEnum still makes sure the transform match the given input and output types, and the category.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/mf.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 75c873d5dc0..a2f4b2dae2f 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -5623,7 +5623,7 @@ static void test_MFRequireProtectedEnvironment(void) static BOOL create_transform(GUID category, MFT_REGISTER_TYPE_INFO *input_type, MFT_REGISTER_TYPE_INFO *output_type, const WCHAR *expect_name, const GUID *expect_major_type, const GUID *expect_input, ULONG expect_input_count, const GUID *expect_output, ULONG expect_output_count, - IMFTransform **transform, GUID *class_id) + IMFTransform **transform, const GUID *expect_class_id, GUID *class_id) { MFT_REGISTER_TYPE_INFO *input_types = NULL, *output_types = NULL; UINT32 input_count = 0, output_count = 0, count = 0, i; @@ -5643,6 +5643,7 @@ static BOOL create_transform(GUID category, MFT_REGISTER_TYPE_INFO *input_type, ok(count == 1, "got %u\n", count); *class_id = class_ids[0]; CoTaskMemFree(class_ids); + ok(IsEqualGUID(class_id, expect_class_id), "got class id %s\n", debugstr_guid(class_id));
hr = MFTGetInfo(*class_id, &name, &input_types, &input_count, &output_types, &output_count, NULL); if (FAILED(hr)) @@ -5834,7 +5835,7 @@ static void test_wma_encoder(void)
if (!create_transform(MFT_CATEGORY_AUDIO_ENCODER, &input_type, &output_type, L"WMAudio Encoder MFT", &MFMediaType_Audio, transform_inputs, ARRAY_SIZE(transform_inputs), transform_outputs, ARRAY_SIZE(transform_outputs), - &transform, &class_id)) + &transform, &CLSID_CWMAEncMediaObject, &class_id)) goto failed;
check_interface(transform, &IID_IMediaObject, TRUE); @@ -6064,7 +6065,7 @@ static void test_wma_decoder(void)
if (!create_transform(MFT_CATEGORY_AUDIO_DECODER, &input_type, &output_type, L"WMAudio Decoder MFT", &MFMediaType_Audio, transform_inputs, ARRAY_SIZE(transform_inputs), transform_outputs, ARRAY_SIZE(transform_outputs), - &transform, &class_id)) + &transform, &CLSID_CWMADecMediaObject, &class_id)) goto failed;
check_interface(transform, &IID_IMediaObject, TRUE); @@ -6718,7 +6719,7 @@ static void test_h264_decoder(void)
if (!create_transform(MFT_CATEGORY_VIDEO_DECODER, &input_type, &output_type, L"Microsoft H264 Video Decoder MFT", &MFMediaType_Video, transform_inputs, ARRAY_SIZE(transform_inputs), transform_outputs, ARRAY_SIZE(transform_outputs), - &transform, &class_id)) + &transform, &CLSID_MSH264DecoderMFT, &class_id)) goto failed;
hr = IMFTransform_GetAttributes(transform, &attributes);
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/Makefile.in | 2 +- dlls/mf/tests/mf.c | 82 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/Makefile.in b/dlls/mf/tests/Makefile.in index a0ca40481da..8d1a22fb35f 100644 --- a/dlls/mf/tests/Makefile.in +++ b/dlls/mf/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = mf.dll -IMPORTS = mf mfplat mfuuid ole32 user32 propsys +IMPORTS = mf mfplat mfuuid ole32 user32 propsys msdmo
C_SRCS = \ mf.c diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index a2f4b2dae2f..0541ba6f268 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -28,9 +28,11 @@ #include "winbase.h"
#include "initguid.h" +#include "dmo.h" #include "mediaobj.h" #include "ole2.h" #include "wmcodecdsp.h" +#include "propsys.h" #include "propvarutil.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); @@ -100,6 +102,51 @@ static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID IUnknown_Release(unk); }
+static void check_dmo(const GUID *class_id, const WCHAR *expect_name, const GUID *expect_major_type, + const GUID *expect_input, ULONG expect_input_count, const GUID *expect_output, ULONG expect_output_count) +{ + ULONG i, input_count = 0, output_count = 0; + DMO_PARTIAL_MEDIATYPE output[32] = {{{0}}}; + DMO_PARTIAL_MEDIATYPE input[32] = {{{0}}}; + WCHAR name[80]; + HRESULT hr; + + winetest_push_context("%s", debugstr_w(expect_name)); + + hr = DMOGetName(class_id, name); + ok(hr == S_OK, "DMOGetName returned %#lx\n", hr); + todo_wine_if(!wcscmp(expect_name, L"WMAudio Decoder DMO")) + ok(!wcscmp(name, expect_name), "got name %s\n", debugstr_w(name)); + + hr = DMOGetTypes(class_id, ARRAY_SIZE(input), &input_count, input, + ARRAY_SIZE(output), &output_count, output); + ok(hr == S_OK, "DMOGetTypes returned %#lx\n", hr); + ok(input_count == expect_input_count, "got input_count %lu\n", input_count); + ok(output_count == expect_output_count, "got output_count %lu\n", output_count); + + for (i = 0; i < input_count; ++i) + { + winetest_push_context("in %lu", i); + ok(IsEqualGUID(&input[i].type, expect_major_type), + "got type %s\n", debugstr_guid(&input[i].type)); + ok(IsEqualGUID(&input[i].subtype, expect_input + i), + "got subtype %s\n", debugstr_guid(&input[i].subtype)); + winetest_pop_context(); + } + + for (i = 0; i < output_count; ++i) + { + winetest_push_context("out %lu", i); + ok(IsEqualGUID(&output[i].type, expect_major_type), + "got type %s\n", debugstr_guid(&output[i].type)); + ok(IsEqualGUID(&output[i].subtype, expect_output + i), + "got subtype %s\n", debugstr_guid( &output[i].subtype)); + winetest_pop_context(); + } + + winetest_pop_context(); +} + struct attribute_desc { const GUID *key; @@ -5788,6 +5835,16 @@ static void test_wma_encoder(void) MFAudioFormat_WMAudioV9, MFAudioFormat_WMAudio_Lossless, }; + const GUID dmo_inputs[] = + { + MEDIASUBTYPE_PCM, + }; + const GUID dmo_outputs[] = + { + MEDIASUBTYPE_WMAUDIO2, + MEDIASUBTYPE_WMAUDIO3, + MEDIASUBTYPE_WMAUDIO_LOSSLESS, + };
static const struct attribute_desc input_type_desc[] = { @@ -5838,7 +5895,13 @@ static void test_wma_encoder(void) &transform, &CLSID_CWMAEncMediaObject, &class_id)) goto failed;
+ check_dmo(&class_id, L"WMAudio Encoder DMO", &MEDIATYPE_Audio, dmo_inputs, ARRAY_SIZE(dmo_inputs), + dmo_outputs, ARRAY_SIZE(dmo_outputs)); + + check_interface(transform, &IID_IMFTransform, TRUE); check_interface(transform, &IID_IMediaObject, TRUE); + check_interface(transform, &IID_IPropertyStore, TRUE); + check_interface(transform, &IID_IPropertyBag, TRUE);
hr = MFCreateMediaType(&media_type); ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); @@ -5965,6 +6028,18 @@ static void test_wma_decoder(void) MFAudioFormat_PCM, MFAudioFormat_Float, }; + const GUID dmo_inputs[] = + { + MEDIASUBTYPE_MSAUDIO1, + MEDIASUBTYPE_WMAUDIO2, + MEDIASUBTYPE_WMAUDIO3, + MEDIASUBTYPE_WMAUDIO_LOSSLESS, + }; + const GUID dmo_outputs[] = + { + MEDIASUBTYPE_PCM, + MEDIASUBTYPE_IEEE_FLOAT, + };
static const media_type_desc expect_available_inputs[] = { @@ -6068,7 +6143,14 @@ static void test_wma_decoder(void) &transform, &CLSID_CWMADecMediaObject, &class_id)) goto failed;
+ check_dmo(&class_id, L"WMAudio Decoder DMO", &MEDIATYPE_Audio, dmo_inputs, ARRAY_SIZE(dmo_inputs), + dmo_outputs, ARRAY_SIZE(dmo_outputs)); + + check_interface(transform, &IID_IMFTransform, TRUE); check_interface(transform, &IID_IMediaObject, TRUE); + todo_wine + check_interface(transform, &IID_IPropertyStore, TRUE); + check_interface(transform, &IID_IPropertyBag, TRUE);
/* check default media types */
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/audioconvdata.bin | Bin 0 -> 179924 bytes dlls/mf/tests/mf.c | 403 +++++++++++++++++++++++++++++++- dlls/mf/tests/resource.rc | 3 + 3 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 dlls/mf/tests/audioconvdata.bin
diff --git a/dlls/mf/tests/audioconvdata.bin b/dlls/mf/tests/audioconvdata.bin new file mode 100644 index 0000000000000000000000000000000000000000..2e6ed909deeb252346026ae2f52a1542b9565d94 GIT binary patch literal 179924 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
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 0541ba6f268..80a373551a7 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -38,6 +38,7 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); DEFINE_GUID(MFVideoFormat_P208, 0x38303250, 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(CLSID_WINEAudioConverter, 0x6a170414, 0xaad9, 0x4693, 0xb8, 0x06, 0x3a, 0x0c, 0x47, 0xc5, 0x70, 0xd6);
#undef INITGUID #include <guiddef.h> @@ -5687,8 +5688,16 @@ static BOOL create_transform(GUID category, MFT_REGISTER_TYPE_INFO *input_type, }
ok(hr == S_OK, "MFTEnum returned %lx\n", hr); - ok(count == 1, "got %u\n", count); - *class_id = class_ids[0]; + ok(count > 0, "got %u\n", count); + for (i = 0; i < count; ++i) + { + if (IsEqualGUID(expect_class_id, class_ids + i)) + break; + } + todo_wine_if(IsEqualGUID(class_ids, &CLSID_WINEAudioConverter)) + ok(i < count, "failed to find %s transform\n", debugstr_w(expect_name)); + if (i == count) return FALSE; + *class_id = class_ids[i]; CoTaskMemFree(class_ids); ok(IsEqualGUID(class_id, expect_class_id), "got class id %s\n", debugstr_guid(class_id));
@@ -7323,6 +7332,395 @@ failed: CoUninitialize(); }
+static void test_audio_convert(void) +{ + const GUID transform_inputs[2] = + { + MFAudioFormat_PCM, + MFAudioFormat_Float, + }; + const GUID transform_outputs[2] = + { + MFAudioFormat_PCM, + MFAudioFormat_Float, + }; + + static const media_type_desc expect_available_inputs[] = + { + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_Float), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + }, + }; + static const media_type_desc expect_available_outputs[] = + { + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_Float), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + }, + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_PCM), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + }, + { + 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, 48000), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 384000), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 8), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1), + }, + { + 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, 48000), + ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 192000), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 4), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1), + }, + }; + + static const struct attribute_desc 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_AVG_BYTES_PER_SECOND, 176400), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 8), + {0}, + }; + const struct attribute_desc 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_AVG_BYTES_PER_SECOND, 176400), + ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 4), + {0}, + }; + + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Audio, MFAudioFormat_PCM}; + MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Audio, MFAudioFormat_Float}; + static const ULONG audioconv_block_size = 0x4000; + ULONG audio_data_len, audioconv_data_len; + const BYTE *audio_data, *audioconv_data; + MFT_OUTPUT_STREAM_INFO output_info; + MFT_INPUT_STREAM_INFO input_info; + MFT_OUTPUT_DATA_BUFFER output; + WCHAR output_path[MAX_PATH]; + IMFMediaType *media_type; + LONGLONG time, duration; + IMFTransform *transform; + DWORD length, status; + HANDLE output_file; + IMFSample *sample; + HRSRC resource; + GUID class_id; + ULONG i, ret; + HRESULT hr; + + hr = CoInitialize(NULL); + ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr); + + if (!create_transform(MFT_CATEGORY_AUDIO_EFFECT, &input_type, &output_type, L"Resampler MFT", &MFMediaType_Audio, + transform_inputs, ARRAY_SIZE(transform_inputs), transform_outputs, ARRAY_SIZE(transform_outputs), + &transform, &CLSID_CResamplerMediaObject, &class_id)) + goto failed; + + check_dmo(&class_id, L"Resampler DMO", &MEDIATYPE_Audio, transform_inputs, ARRAY_SIZE(transform_inputs), + transform_outputs, ARRAY_SIZE(transform_outputs)); + + check_interface(transform, &IID_IMFTransform, TRUE); + check_interface(transform, &IID_IMediaObject, TRUE); + check_interface(transform, &IID_IPropertyStore, TRUE); + todo_wine + check_interface(transform, &IID_IPropertyBag, TRUE); + /* check_interface(transform, &IID_IWMResamplerProps, TRUE); */ + + /* check default media types */ + + hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info); + ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetInputStreamInfo returned %#lx\n", hr); + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info); + ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputStreamInfo returned %#lx\n", hr); + + i = -1; + while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, ++i, &media_type))) + { + winetest_push_context("out %lu", i); + ok(hr == S_OK, "GetOutputAvailableType returned %#lx\n", hr); + check_media_type(media_type, expect_available_outputs[i], -1); + ret = IMFMediaType_Release(media_type); + ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context(); + } + ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); + ok(i == 4, "%lu output media types\n", i); + + i = -1; + while (SUCCEEDED(hr = IMFTransform_GetInputAvailableType(transform, 0, ++i, &media_type))) + { + winetest_push_context("in %lu", i); + ok(hr == S_OK, "GetInputAvailableType returned %#lx\n", hr); + check_media_type(media_type, expect_available_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(); + } + ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr); + 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 required input media type attributes */ + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); + hr = IMFTransform_SetInputType(transform, 0, media_type, 0); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "SetInputType returned %#lx.\n", hr); + init_media_type(media_type, input_type_desc, 1); + hr = IMFTransform_SetInputType(transform, 0, media_type, 0); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "SetInputType returned %#lx.\n", hr); + init_media_type(media_type, input_type_desc, 2); + for (i = 2; i < ARRAY_SIZE(input_type_desc) - 1; ++i) + { + hr = IMFTransform_SetInputType(transform, 0, media_type, 0); + ok(hr == MF_E_INVALIDMEDIATYPE, "SetInputType returned %#lx.\n", hr); + init_media_type(media_type, input_type_desc, i + 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); + + hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info); + ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetInputStreamInfo returned %#lx\n", hr); + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info); + ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputStreamInfo returned %#lx\n", hr); + + /* check new output media types */ + + i = -1; + while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, ++i, &media_type))) + { + winetest_push_context("out %lu", i); + ok(hr == S_OK, "GetOutputAvailableType returned %#lx\n", hr); + check_media_type(media_type, expect_available_outputs[i], -1); + ret = IMFMediaType_Release(media_type); + ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context(); + } + ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); + ok(i == 4, "%lu output media types\n", i); + + /* check required output media type attributes */ + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); + hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "SetOutputType 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_ATTRIBUTENOTFOUND, "SetOutputType returned %#lx.\n", hr); + init_media_type(media_type, output_type_desc, 2); + for (i = 2; i < ARRAY_SIZE(output_type_desc) - 1; ++i) + { + hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); + ok(hr == MF_E_INVALIDMEDIATYPE, "SetOutputType returned %#lx.\n", hr); + init_media_type(media_type, output_type_desc, i + 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); + + memset(&input_info, 0xcd, sizeof(input_info)); + hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info); + ok(hr == S_OK, "GetInputStreamInfo returned %#lx\n", hr); + ok(input_info.hnsMaxLatency == 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info.hnsMaxLatency)); + ok(input_info.dwFlags == 0, "got dwFlags %#lx\n", input_info.dwFlags); + ok(input_info.cbSize == 8, "got cbSize %lu\n", input_info.cbSize); + ok(input_info.cbMaxLookahead == 0, "got cbMaxLookahead %#lx\n", input_info.cbMaxLookahead); + ok(input_info.cbAlignment == 1, "got cbAlignment %#lx\n", input_info.cbAlignment); + + memset(&output_info, 0xcd, sizeof(output_info)); + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info); + ok(hr == S_OK, "GetOutputStreamInfo returned %#lx\n", hr); + ok(output_info.dwFlags == 0, "got dwFlags %#lx\n", output_info.dwFlags); + ok(output_info.cbSize == 4, "got cbSize %#lx\n", output_info.cbSize); + ok(output_info.cbAlignment == 1, "got cbAlignment %#lx\n", output_info.cbAlignment); + + resource = FindResourceW(NULL, L"audiodata.bin", (const WCHAR *)RT_RCDATA); + ok(resource != 0, "FindResourceW failed, error %lu\n", GetLastError()); + audio_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); + audio_data_len = SizeofResource(GetModuleHandleW(NULL), resource); + ok(audio_data_len == 179928, "got length %lu\n", audio_data_len); + + sample = create_sample(audio_data, audio_data_len); + hr = IMFSample_SetSampleTime(sample, 0); + ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); + hr = IMFSample_SetSampleDuration(sample, 10000000); + ok(hr == S_OK, "SetSampleDuration returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, 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, sample, 0); + ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr); + IMFSample_Release(sample); + + status = 0xdeadbeef; + sample = create_sample(NULL, audioconv_block_size); + memset(&output, 0, sizeof(output)); + output.pSample = sample; + + resource = FindResourceW(NULL, L"audioconvdata.bin", (const WCHAR *)RT_RCDATA); + ok(resource != 0, "FindResourceW failed, error %lu\n", GetLastError()); + audioconv_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); + audioconv_data_len = SizeofResource(GetModuleHandleW(NULL), resource); + ok(audioconv_data_len == 179924, "got length %lu\n", audioconv_data_len); + + /* and generate a new one as well in a temporary directory */ + GetTempPathW(ARRAY_SIZE(output_path), output_path); + lstrcatW(output_path, L"audioconvdata.bin"); + output_file = CreateFileW(output_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(output_file != INVALID_HANDLE_VALUE, "CreateFileW failed, error %lu\n", GetLastError()); + + i = 0; + while (SUCCEEDED(hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status))) + { + winetest_push_context("%lu", i); + ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr); + ok(output.pSample == sample, "got pSample %p\n", output.pSample); + ok(output.dwStatus == MFT_OUTPUT_DATA_BUFFER_INCOMPLETE || output.dwStatus == 0 || + broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|6) || output.dwStatus == 6) /* win7 */, + "got dwStatus %#lx\n", output.dwStatus); + ok(status == 0, "got status %#lx\n", status); + if (!(output.dwStatus & MFT_OUTPUT_DATA_BUFFER_INCOMPLETE)) + { + winetest_pop_context(); + break; + } + + hr = IMFSample_GetSampleTime(sample, &time); + ok(hr == S_OK, "GetSampleTime returned %#lx\n", hr); + ok(time == i * 928798, "got time %I64d\n", time); + hr = IMFSample_GetSampleDuration(sample, &duration); + ok(hr == S_OK, "GetSampleDuration returned %#lx\n", hr); + ok(duration == 928798, "got duration %I64d\n", duration); + hr = IMFSample_GetTotalLength(sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + ok(length == audioconv_block_size, "got length %lu\n", length); + ok(audioconv_data_len > audioconv_block_size, "got remaining length %lu\n", audioconv_data_len); + check_sample_pcm16(sample, audioconv_data, output_file, FALSE); + audioconv_data_len -= audioconv_block_size; + audioconv_data += audioconv_block_size; + + winetest_pop_context(); + i++; + } + + hr = IMFSample_GetSampleTime(sample, &time); + ok(hr == S_OK, "GetSampleTime returned %#lx\n", hr); + ok(time == i * 928798, "got time %I64d\n", time); + hr = IMFSample_GetSampleDuration(sample, &duration); + ok(hr == S_OK, "GetSampleDuration returned %#lx\n", hr); + todo_wine + ok(duration == 897506, "got duration %I64d\n", duration); + hr = IMFSample_GetTotalLength(sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + todo_wine + ok(length == 15832, "got length %lu\n", length); + ok(audioconv_data_len == 16084, "got remaining length %lu\n", audioconv_data_len); + check_sample_pcm16(sample, audioconv_data, output_file, FALSE); + audioconv_data_len -= length; + audioconv_data += length; + + memset(&output, 0, sizeof(output)); + output.pSample = sample; + hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); + todo_wine + ok(hr == S_OK || broken(hr == MF_E_TRANSFORM_NEED_MORE_INPUT) /* win7 */, "ProcessOutput returned %#lx\n", hr); + ok(output.pSample == sample, "got pSample %p\n", output.pSample); + todo_wine + ok(output.dwStatus == MFT_OUTPUT_DATA_BUFFER_INCOMPLETE || broken(output.dwStatus == 0) /* win7 */, + "got dwStatus %#lx\n", output.dwStatus); + ok(status == 0, "got status %#lx\n", status); + + if (hr == S_OK) + { + hr = IMFSample_GetSampleTime(sample, &time); + ok(hr == S_OK, "GetSampleTime returned %#lx\n", hr); + todo_wine + ok(time == 10185486, "got time %I64d\n", time); + hr = IMFSample_GetSampleDuration(sample, &duration); + ok(hr == S_OK, "GetSampleDuration returned %#lx\n", hr); + todo_wine + ok(duration == 14286, "got duration %I64d\n", duration); + hr = IMFSample_GetTotalLength(sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + todo_wine + ok(length == audioconv_data_len, "got length %lu\n", length); + if (length == audioconv_data_len) + check_sample_pcm16(sample, audioconv_data, output_file, FALSE); + } + + trace("created %s\n", debugstr_w(output_path)); + CloseHandle(output_file); + + ret = IMFSample_Release(sample); + ok(ret == 0, "Release returned %lu\n", ret); + + status = 0xdeadbeef; + sample = create_sample(NULL, audioconv_block_size); + memset(&output, 0, sizeof(output)); + output.pSample = 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 == 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(sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + ok(length == 0, "got length %lu\n", length); + ret = IMFSample_Release(sample); + ok(ret == 0, "Release returned %lu\n", ret); + + ret = IMFTransform_Release(transform); + ok(ret == 0, "Release returned %lu\n", ret); + +failed: + CoUninitialize(); +} + START_TEST(mf) { init_functions(); @@ -7359,4 +7757,5 @@ START_TEST(mf) test_wma_encoder(); test_wma_decoder(); test_h264_decoder(); + test_audio_convert(); } diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc index 49f9b0dc39c..f902ace8a71 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -23,6 +23,9 @@ /* @makedep: audiodata.bin */ audiodata.bin RCDATA audiodata.bin
+/* @makedep: audioconvdata.bin */ +audioconvdata.bin RCDATA audioconvdata.bin + /* @makedep: wmaencdata.bin */ wmaencdata.bin RCDATA wmaencdata.bin
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/mf.c | 210 ++++++++++++++++++++++++++++----------------- 1 file changed, 129 insertions(+), 81 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 80a373551a7..d9e6dad6ffa 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -220,6 +220,80 @@ static HWND create_window(void) 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL); }
+static BOOL create_transform(GUID category, MFT_REGISTER_TYPE_INFO *input_type, + MFT_REGISTER_TYPE_INFO *output_type, const WCHAR *expect_name, const GUID *expect_major_type, + const GUID *expect_input, ULONG expect_input_count, const GUID *expect_output, ULONG expect_output_count, + IMFTransform **transform, const GUID *expect_class_id, GUID *class_id) +{ + MFT_REGISTER_TYPE_INFO *input_types = NULL, *output_types = NULL; + UINT32 input_count = 0, output_count = 0, count = 0, i; + GUID *class_ids = NULL; + WCHAR *name; + HRESULT hr; + + hr = MFTEnum(category, 0, input_type, output_type, NULL, &class_ids, &count); + if (FAILED(hr) || count == 0) + { + todo_wine + win_skip("Failed to enumerate %s, skipping tests.\n", debugstr_w(expect_name)); + return FALSE; + } + + ok(hr == S_OK, "MFTEnum returned %lx\n", hr); + for (i = 0; i < count; ++i) + { + if (IsEqualGUID(expect_class_id, class_ids + i)) + break; + } + todo_wine_if(IsEqualGUID(class_ids, &CLSID_WINEAudioConverter)) + ok(i < count, "failed to find %s transform\n", debugstr_w(expect_name)); + if (i == count) return FALSE; + *class_id = class_ids[i]; + CoTaskMemFree(class_ids); + ok(IsEqualGUID(class_id, expect_class_id), "got class id %s\n", debugstr_guid(class_id)); + + hr = MFTGetInfo(*class_id, &name, &input_types, &input_count, &output_types, &output_count, NULL); + if (FAILED(hr)) + { + todo_wine + win_skip("Failed to get %s info, skipping tests.\n", debugstr_w(expect_name)); + } + else + { + ok(hr == S_OK, "MFTEnum returned %lx\n", hr); + ok(!wcscmp(name, expect_name), "got name %s\n", debugstr_w(name)); + ok(input_count == expect_input_count, "got input_count %u\n", input_count); + for (i = 0; i < input_count; ++i) + { + ok(IsEqualGUID(&input_types[i].guidMajorType, expect_major_type), + "got input[%u] major %s\n", i, debugstr_guid(&input_types[i].guidMajorType)); + ok(IsEqualGUID(&input_types[i].guidSubtype, expect_input + i), + "got input[%u] subtype %s\n", i, debugstr_guid(&input_types[i].guidSubtype)); + } + ok(output_count == expect_output_count, "got output_count %u\n", output_count); + for (i = 0; i < output_count; ++i) + { + ok(IsEqualGUID(&output_types[i].guidMajorType, expect_major_type), + "got output[%u] major %s\n", i, debugstr_guid(&output_types[i].guidMajorType)); + ok(IsEqualGUID(&output_types[i].guidSubtype, expect_output + i), + "got output[%u] subtype %s\n", i, debugstr_guid(&output_types[i].guidSubtype)); + } + CoTaskMemFree(output_types); + CoTaskMemFree(input_types); + CoTaskMemFree(name); + } + + hr = CoCreateInstance(class_id, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)transform); + if (FAILED(hr)) + { + todo_wine + win_skip("Failed to create %s instance, skipping tests.\n", debugstr_w(expect_name)); + return FALSE; + } + + return TRUE; +} + static HRESULT WINAPI test_unk_QueryInterface(IUnknown *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IUnknown)) @@ -3473,6 +3547,57 @@ static BOOL is_supported_video_type(const GUID *guid)
static void test_video_processor(void) { + const GUID transform_inputs[22] = + { + MFVideoFormat_IYUV, + MFVideoFormat_YV12, + MFVideoFormat_NV12, + MFVideoFormat_YUY2, + MFVideoFormat_ARGB32, + MFVideoFormat_RGB32, + MFVideoFormat_NV11, + MFVideoFormat_AYUV, + MFVideoFormat_UYVY, + MEDIASUBTYPE_P208, + MFVideoFormat_RGB24, + MFVideoFormat_RGB555, + MFVideoFormat_RGB565, + MFVideoFormat_RGB8, + MFVideoFormat_I420, + MFVideoFormat_Y216, + MFVideoFormat_v410, + MFVideoFormat_Y41P, + MFVideoFormat_Y41T, + MFVideoFormat_Y42T, + MFVideoFormat_YVYU, + MFVideoFormat_420O, + }; + const GUID transform_outputs[21] = + { + MFVideoFormat_IYUV, + MFVideoFormat_YV12, + MFVideoFormat_NV12, + MFVideoFormat_YUY2, + MFVideoFormat_ARGB32, + MFVideoFormat_RGB32, + MFVideoFormat_NV11, + MFVideoFormat_AYUV, + MFVideoFormat_UYVY, + MEDIASUBTYPE_P208, + MFVideoFormat_RGB24, + MFVideoFormat_RGB555, + MFVideoFormat_RGB565, + MFVideoFormat_RGB8, + MFVideoFormat_I420, + MFVideoFormat_Y216, + MFVideoFormat_v410, + MFVideoFormat_Y41P, + MFVideoFormat_Y41T, + MFVideoFormat_Y42T, + MFVideoFormat_YVYU, + }; + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Video, MFVideoFormat_NV12}; + MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Video, MFVideoFormat_I420}; DWORD input_count, output_count, input_id, output_id, flags; DWORD input_min, input_max, output_min, output_max, i; IMFAttributes *attributes, *attributes2; @@ -3485,6 +3610,7 @@ static void test_video_processor(void) IMFMediaBuffer *buffer; IMFMediaEvent *event; unsigned int value; + GUID class_id; UINT32 count; HRESULT hr; GUID guid; @@ -3492,13 +3618,10 @@ static void test_video_processor(void) hr = CoInitialize(NULL); ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr);
- hr = CoCreateInstance(&CLSID_VideoProcessorMFT, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, - (void **)&transform); - if (FAILED(hr)) - { - skip("Failed to create Video Processor instance, skipping tests.\n"); + if (!create_transform(MFT_CATEGORY_VIDEO_PROCESSOR, &input_type, &output_type, L"Microsoft Video Processor MFT", &MFMediaType_Video, + transform_inputs, ARRAY_SIZE(transform_inputs), transform_outputs, ARRAY_SIZE(transform_outputs), + &transform, &CLSID_VideoProcessorMFT, &class_id)) goto failed; - }
todo_wine check_interface(transform, &IID_IMFVideoProcessorControl, TRUE); @@ -5668,81 +5791,6 @@ static void test_MFRequireProtectedEnvironment(void) IMFPresentationDescriptor_Release(pd); }
-static BOOL create_transform(GUID category, MFT_REGISTER_TYPE_INFO *input_type, - MFT_REGISTER_TYPE_INFO *output_type, const WCHAR *expect_name, const GUID *expect_major_type, - const GUID *expect_input, ULONG expect_input_count, const GUID *expect_output, ULONG expect_output_count, - IMFTransform **transform, const GUID *expect_class_id, GUID *class_id) -{ - MFT_REGISTER_TYPE_INFO *input_types = NULL, *output_types = NULL; - UINT32 input_count = 0, output_count = 0, count = 0, i; - GUID *class_ids = NULL; - WCHAR *name; - HRESULT hr; - - hr = MFTEnum(category, 0, input_type, output_type, NULL, &class_ids, &count); - if (FAILED(hr)) - { - todo_wine - win_skip("Failed to enumerate %s, skipping tests.\n", debugstr_w(expect_name)); - return FALSE; - } - - ok(hr == S_OK, "MFTEnum returned %lx\n", hr); - ok(count > 0, "got %u\n", count); - for (i = 0; i < count; ++i) - { - if (IsEqualGUID(expect_class_id, class_ids + i)) - break; - } - todo_wine_if(IsEqualGUID(class_ids, &CLSID_WINEAudioConverter)) - ok(i < count, "failed to find %s transform\n", debugstr_w(expect_name)); - if (i == count) return FALSE; - *class_id = class_ids[i]; - CoTaskMemFree(class_ids); - ok(IsEqualGUID(class_id, expect_class_id), "got class id %s\n", debugstr_guid(class_id)); - - hr = MFTGetInfo(*class_id, &name, &input_types, &input_count, &output_types, &output_count, NULL); - if (FAILED(hr)) - { - todo_wine - win_skip("Failed to get %s info, skipping tests.\n", debugstr_w(expect_name)); - } - else - { - ok(hr == S_OK, "MFTEnum returned %lx\n", hr); - ok(!wcscmp(name, expect_name), "got name %s\n", debugstr_w(name)); - ok(input_count == expect_input_count, "got input_count %u\n", input_count); - for (i = 0; i < input_count; ++i) - { - ok(IsEqualGUID(&input_types[i].guidMajorType, expect_major_type), - "got input[%u] major %s\n", i, debugstr_guid(&input_types[i].guidMajorType)); - ok(IsEqualGUID(&input_types[i].guidSubtype, expect_input + i), - "got input[%u] subtype %s\n", i, debugstr_guid(&input_types[i].guidSubtype)); - } - ok(output_count == expect_output_count, "got output_count %u\n", output_count); - for (i = 0; i < output_count; ++i) - { - ok(IsEqualGUID(&output_types[i].guidMajorType, expect_major_type), - "got output[%u] major %s\n", i, debugstr_guid(&output_types[i].guidMajorType)); - ok(IsEqualGUID(&output_types[i].guidSubtype, expect_output + i), - "got output[%u] subtype %s\n", i, debugstr_guid(&output_types[i].guidSubtype)); - } - CoTaskMemFree(output_types); - CoTaskMemFree(input_types); - CoTaskMemFree(name); - } - - hr = CoCreateInstance(class_id, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)transform); - if (FAILED(hr)) - { - todo_wine - win_skip("Failed to create %s instance, skipping tests.\n", debugstr_w(expect_name)); - return FALSE; - } - - return TRUE; -} - static IMFSample *create_sample(const BYTE *data, ULONG size) { IMFMediaBuffer *media_buffer;
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/mf.c | 415 ++++++++++++++++++++++++++++++++++- dlls/mf/tests/resource.rc | 3 + dlls/mf/tests/rgb32frame.bin | Bin 0 -> 36864 bytes 3 files changed, 417 insertions(+), 1 deletion(-) create mode 100644 dlls/mf/tests/rgb32frame.bin
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index d9e6dad6ffa..a9706aa7647 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -26,6 +26,7 @@
#include "windef.h" #include "winbase.h" +#include "d3d9types.h"
#include "initguid.h" #include "dmo.h" @@ -40,6 +41,12 @@ DEFINE_GUID(MFVideoFormat_P208, 0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0x DEFINE_GUID(MFVideoFormat_ABGR32, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); DEFINE_GUID(CLSID_WINEAudioConverter, 0x6a170414, 0xaad9, 0x4693, 0xb8, 0x06, 0x3a, 0x0c, 0x47, 0xc5, 0x70, 0xd6);
+DEFINE_GUID(DMOVideoFormat_RGB32, D3DFMT_X8R8G8B8, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); +DEFINE_GUID(DMOVideoFormat_RGB24, D3DFMT_R8G8B8, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); +DEFINE_GUID(DMOVideoFormat_RGB565, D3DFMT_R5G6B5, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); +DEFINE_GUID(DMOVideoFormat_RGB555, D3DFMT_X1R5G5B5, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); +DEFINE_GUID(DMOVideoFormat_RGB8, D3DFMT_P8, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); + #undef INITGUID #include <guiddef.h> #include "mfapi.h" @@ -5822,7 +5829,7 @@ static IMFSample *create_sample(const BYTE *data, ULONG size) }
#define check_sample(a, b, c) check_sample_(__LINE__, a, b, c) -static void check_sample_(int line, IMFSample *sample, const void *expect_buf, HANDLE output_file) +static void check_sample_(int line, IMFSample *sample, const BYTE *expect_buf, HANDLE output_file) { IMFMediaBuffer *media_buffer; DWORD length; @@ -5842,6 +5849,38 @@ static void check_sample_(int line, IMFSample *sample, const void *expect_buf, H ok_(__FILE__, line)(ret == 1, "Release returned %lu\n", ret); }
+#define check_sample_rgb32(a, b, c) check_sample_rgb32_(__LINE__, a, b, c) +static void check_sample_rgb32_(int line, IMFSample *sample, const BYTE *expect_buf, HANDLE output_file) +{ + DWORD i, length, diff = 0, max_diff; + IMFMediaBuffer *media_buffer; + BYTE *buffer; + HRESULT hr; + ULONG ret; + + hr = IMFSample_ConvertToContiguousBuffer(sample, &media_buffer); + ok_(__FILE__, line)(hr == S_OK, "ConvertToContiguousBuffer returned %#lx\n", hr); + hr = IMFMediaBuffer_Lock(media_buffer, &buffer, NULL, &length); + ok_(__FILE__, line)(hr == S_OK, "Lock returned %#lx\n", hr); + + /* check that buffer values are "close" enough, there's some pretty big + * differences with the color converter between ffmpeg and native. + */ + for (i = 0; i < length; i++) + { + if (i % 4 == 3) continue; /* ignore alpha diff */ + diff += abs((int)expect_buf[i] - (int)buffer[i]); + } + max_diff = length * 3 * 256; + ok_(__FILE__, line)(diff * 100 / max_diff == 0, "unexpected buffer data\n"); + + if (output_file) WriteFile(output_file, buffer, length, &length, NULL); + hr = IMFMediaBuffer_Unlock(media_buffer); + ok_(__FILE__, line)(hr == S_OK, "Unlock returned %#lx\n", hr); + ret = IMFMediaBuffer_Release(media_buffer); + ok_(__FILE__, line)(ret == 1, "Release returned %lu\n", ret); +} + #define check_sample_pcm16(a, b, c, d) check_sample_pcm16_(__LINE__, a, b, c, d) static void check_sample_pcm16_(int line, IMFSample *sample, const BYTE *expect_buf, HANDLE output_file, BOOL todo) { @@ -7769,6 +7808,379 @@ failed: CoUninitialize(); }
+static void test_color_convert(void) +{ + const GUID transform_inputs[20] = + { + MFVideoFormat_YV12, + MFVideoFormat_YUY2, + MFVideoFormat_UYVY, + MFVideoFormat_AYUV, + MFVideoFormat_NV12, + DMOVideoFormat_RGB32, + DMOVideoFormat_RGB565, + MFVideoFormat_I420, + MFVideoFormat_IYUV, + MFVideoFormat_YVYU, + DMOVideoFormat_RGB24, + DMOVideoFormat_RGB555, + DMOVideoFormat_RGB8, + MEDIASUBTYPE_V216, + MEDIASUBTYPE_V410, + MFVideoFormat_NV11, + MFVideoFormat_Y41P, + MFVideoFormat_Y41T, + MFVideoFormat_Y42T, + MFVideoFormat_YVU9, + }; + const GUID transform_outputs[16] = + { + MFVideoFormat_YV12, + MFVideoFormat_YUY2, + MFVideoFormat_UYVY, + MFVideoFormat_AYUV, + MFVideoFormat_NV12, + DMOVideoFormat_RGB32, + DMOVideoFormat_RGB565, + MFVideoFormat_I420, + MFVideoFormat_IYUV, + MFVideoFormat_YVYU, + DMOVideoFormat_RGB24, + DMOVideoFormat_RGB555, + DMOVideoFormat_RGB8, + MEDIASUBTYPE_V216, + MEDIASUBTYPE_V410, + MFVideoFormat_NV11, + }; + const GUID dmo_inputs[20] = + { + MEDIASUBTYPE_YV12, + MEDIASUBTYPE_YUY2, + MEDIASUBTYPE_UYVY, + MEDIASUBTYPE_AYUV, + MEDIASUBTYPE_NV12, + MEDIASUBTYPE_RGB32, + MEDIASUBTYPE_RGB565, + MEDIASUBTYPE_I420, + MEDIASUBTYPE_IYUV, + MEDIASUBTYPE_YVYU, + MEDIASUBTYPE_RGB24, + MEDIASUBTYPE_RGB555, + MEDIASUBTYPE_RGB8, + MEDIASUBTYPE_V216, + MEDIASUBTYPE_V410, + MEDIASUBTYPE_NV11, + MEDIASUBTYPE_Y41P, + MEDIASUBTYPE_Y41T, + MEDIASUBTYPE_Y42T, + MEDIASUBTYPE_YVU9, + }; + const GUID dmo_outputs[16] = + { + MEDIASUBTYPE_YV12, + MEDIASUBTYPE_YUY2, + MEDIASUBTYPE_UYVY, + MEDIASUBTYPE_AYUV, + MEDIASUBTYPE_NV12, + MEDIASUBTYPE_RGB32, + MEDIASUBTYPE_RGB565, + MEDIASUBTYPE_I420, + MEDIASUBTYPE_IYUV, + MEDIASUBTYPE_YVYU, + MEDIASUBTYPE_RGB24, + MEDIASUBTYPE_RGB555, + MEDIASUBTYPE_RGB8, + MEDIASUBTYPE_V216, + MEDIASUBTYPE_V410, + MEDIASUBTYPE_NV11, + }; + + static const media_type_desc expect_available_inputs[20] = + { + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YV12), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_UYVY), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_AYUV), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB565), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_I420), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_IYUV), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YVYU), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB555), }, + { ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_RGB8), }, + { ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_V216), }, + { ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_V410), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV11), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_Y41P), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_Y41T), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_Y42T), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YVU9), }, + }; + static const media_type_desc expect_available_outputs[16] = + { + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YV12), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_UYVY), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_AYUV), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB565), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_I420), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_IYUV), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YVYU), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB24), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB555), }, + { ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_RGB8), }, + { ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_V216), }, + { ATTR_GUID(MF_MT_SUBTYPE, MEDIASUBTYPE_V410), }, + { ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV11), }, + }; + static const media_type_desc expect_available_common = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + }; + + static const MFVideoArea actual_aperture = {.Area={82,84}}; + static const DWORD actual_width = 96, actual_height = 96; + const struct attribute_desc 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), + {0}, + }; + const struct attribute_desc 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), + {0}, + }; + + MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Video, MFVideoFormat_NV12}; + MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Video, MFVideoFormat_I420}; + ULONG nv12frame_data_len, rgb32_data_len; + const BYTE *nv12frame_data, *rgb32_data; + MFT_OUTPUT_STREAM_INFO output_info; + MFT_INPUT_STREAM_INFO input_info; + MFT_OUTPUT_DATA_BUFFER output; + WCHAR output_path[MAX_PATH]; + IMFMediaType *media_type; + LONGLONG time, duration; + IMFTransform *transform; + DWORD length, status; + HANDLE output_file; + IMFSample *sample; + HRSRC resource; + GUID class_id; + ULONG i, ret; + HRESULT hr; + + hr = CoInitialize(NULL); + ok(hr == S_OK, "Failed to initialize, hr %#lx.\n", hr); + + if (!create_transform(MFT_CATEGORY_VIDEO_EFFECT, &input_type, &output_type, L"Color Converter MFT", &MFMediaType_Video, + transform_inputs, ARRAY_SIZE(transform_inputs), transform_outputs, ARRAY_SIZE(transform_outputs), + &transform, &CLSID_CColorConvertDMO, &class_id)) + goto failed; + + check_dmo(&CLSID_CColorConvertDMO, L"Color Converter DMO", &MEDIATYPE_Video, dmo_inputs, ARRAY_SIZE(dmo_inputs), + dmo_outputs, ARRAY_SIZE(dmo_outputs)); + + check_interface(transform, &IID_IMFTransform, TRUE); + check_interface(transform, &IID_IMediaObject, TRUE); + check_interface(transform, &IID_IPropertyStore, TRUE); + check_interface(transform, &IID_IMFRealTimeClient, TRUE); + /* check_interface(transform, &IID_IWMColorConvProps, TRUE); */ + + /* check default media types */ + + hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info); + ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetInputStreamInfo returned %#lx\n", hr); + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info); + ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputStreamInfo returned %#lx\n", hr); + + i = -1; + while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, ++i, &media_type))) + { + winetest_push_context("out %lu", i); + ok(hr == S_OK, "GetOutputAvailableType returned %#lx\n", hr); + check_media_type(media_type, expect_available_common, -1); + check_media_type(media_type, expect_available_outputs[i], -1); + ret = IMFMediaType_Release(media_type); + ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context(); + } + ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); + ok(i == 16, "%lu output media types\n", i); + + i = -1; + while (SUCCEEDED(hr = IMFTransform_GetInputAvailableType(transform, 0, ++i, &media_type))) + { + winetest_push_context("in %lu", i); + ok(hr == S_OK, "GetInputAvailableType returned %#lx\n", hr); + check_media_type(media_type, expect_available_common, -1); + check_media_type(media_type, expect_available_inputs[i], -1); + 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(); + } + ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr); + ok(i == 20, "%lu input media types\n", i); + + /* check required output media type attributes */ + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); + hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "SetOutputType 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_ATTRIBUTENOTFOUND, "SetOutputType returned %#lx.\n", hr); + init_media_type(media_type, output_type_desc, 2); + for (i = 2; i < ARRAY_SIZE(output_type_desc) - 1; ++i) + { + hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); + ok(hr == E_INVALIDARG, "SetOutputType returned %#lx.\n", hr); + init_media_type(media_type, output_type_desc, i + 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 required input media type attributes */ + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "MFCreateMediaType returned %#lx\n", hr); + hr = IMFTransform_SetInputType(transform, 0, media_type, 0); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "SetInputType returned %#lx.\n", hr); + init_media_type(media_type, input_type_desc, 1); + hr = IMFTransform_SetInputType(transform, 0, media_type, 0); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "SetInputType returned %#lx.\n", hr); + init_media_type(media_type, input_type_desc, 2); + for (i = 2; i < ARRAY_SIZE(input_type_desc) - 1; ++i) + { + hr = IMFTransform_SetInputType(transform, 0, media_type, 0); + ok(hr == E_INVALIDARG, "SetInputType returned %#lx.\n", hr); + init_media_type(media_type, input_type_desc, i + 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); + + memset(&input_info, 0xcd, sizeof(input_info)); + hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info); + ok(hr == S_OK, "GetInputStreamInfo returned %#lx\n", hr); + ok(input_info.hnsMaxLatency == 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info.hnsMaxLatency)); + ok(input_info.dwFlags == 0, "got dwFlags %#lx\n", input_info.dwFlags); + ok(input_info.cbSize == actual_width * actual_height * 3 / 2, "got cbSize %#lx\n", input_info.cbSize); + ok(input_info.cbMaxLookahead == 0, "got cbMaxLookahead %#lx\n", input_info.cbMaxLookahead); + ok(input_info.cbAlignment == 1, "got cbAlignment %#lx\n", input_info.cbAlignment); + + memset(&output_info, 0xcd, sizeof(output_info)); + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info); + ok(hr == S_OK, "GetOutputStreamInfo returned %#lx\n", hr); + ok(output_info.dwFlags == 0, "got dwFlags %#lx\n", output_info.dwFlags); + ok(output_info.cbSize == actual_width * actual_height * 4, "got cbSize %#lx\n", output_info.cbSize); + ok(output_info.cbAlignment == 1, "got cbAlignment %#lx\n", output_info.cbAlignment); + + resource = FindResourceW(NULL, L"nv12frame.bin", (const WCHAR *)RT_RCDATA); + ok(resource != 0, "FindResourceW failed, error %lu\n", GetLastError()); + nv12frame_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); + nv12frame_data_len = SizeofResource(GetModuleHandleW(NULL), resource); + ok(nv12frame_data_len == 13824, "got length %lu\n", nv12frame_data_len); + + sample = create_sample(nv12frame_data, nv12frame_data_len); + hr = IMFSample_SetSampleTime(sample, 0); + ok(hr == S_OK, "SetSampleTime returned %#lx\n", hr); + hr = IMFSample_SetSampleDuration(sample, 10000000); + ok(hr == S_OK, "SetSampleDuration returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, sample, 0); + ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_ProcessInput(transform, 0, 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); + IMFSample_Release(sample); + + resource = FindResourceW(NULL, L"rgb32frame.bin", (const WCHAR *)RT_RCDATA); + ok(resource != 0, "FindResourceW failed, error %lu\n", GetLastError()); + rgb32_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); + rgb32_data_len = SizeofResource(GetModuleHandleW(NULL), resource); + ok(rgb32_data_len == output_info.cbSize, "got length %lu\n", rgb32_data_len); + + /* and generate a new one as well in a temporary directory */ + GetTempPathW(ARRAY_SIZE(output_path), output_path); + lstrcatW(output_path, L"rgb32frame.bin"); + output_file = CreateFileW(output_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(output_file != INVALID_HANDLE_VALUE, "CreateFileW failed, error %lu\n", GetLastError()); + + status = 0xdeadbeef; + sample = create_sample(NULL, output_info.cbSize); + memset(&output, 0, sizeof(output)); + output.pSample = sample; + hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); + ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr); + ok(output.pSample == sample, "got pSample %p\n", output.pSample); + ok(output.dwStatus == 0 || broken(output.dwStatus == 6) /* win7 */, "got dwStatus %#lx\n", output.dwStatus); + ok(status == 0, "got status %#lx\n", status); + + hr = IMFSample_GetSampleTime(sample, &time); + ok(hr == S_OK, "GetSampleTime returned %#lx\n", hr); + ok(time == 0, "got time %I64d\n", time); + hr = IMFSample_GetSampleDuration(sample, &duration); + ok(hr == S_OK, "GetSampleDuration returned %#lx\n", hr); + ok(duration == 10000000, "got duration %I64d\n", duration); + hr = IMFSample_GetTotalLength(sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + ok(length == output_info.cbSize, "got length %lu\n", length); + check_sample_rgb32(sample, rgb32_data, output_file); + rgb32_data_len -= output_info.cbSize; + rgb32_data += output_info.cbSize; + + trace("created %s\n", debugstr_w(output_path)); + CloseHandle(output_file); + + ret = IMFSample_Release(sample); + ok(ret == 0, "Release returned %lu\n", ret); + + status = 0xdeadbeef; + sample = create_sample(NULL, output_info.cbSize); + memset(&output, 0, sizeof(output)); + output.pSample = 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 == 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(sample, &length); + ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + ok(length == 0, "got length %lu\n", length); + ret = IMFSample_Release(sample); + ok(ret == 0, "Release returned %lu\n", ret); + + IMFTransform_Release(transform); + +failed: + CoUninitialize(); +} + + START_TEST(mf) { init_functions(); @@ -7806,4 +8218,5 @@ START_TEST(mf) test_wma_decoder(); test_h264_decoder(); test_audio_convert(); + test_color_convert(); } diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc index f902ace8a71..dc19d67f0fa 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -40,3 +40,6 @@ nv12frame.bin RCDATA nv12frame.bin
/* @makedep: i420frame.bin */ i420frame.bin RCDATA i420frame.bin + +/* @makedep: rgb32frame.bin */ +rgb32frame.bin RCDATA rgb32frame.bin diff --git a/dlls/mf/tests/rgb32frame.bin b/dlls/mf/tests/rgb32frame.bin new file mode 100644 index 0000000000000000000000000000000000000000..a8155db5efb5a53f7767e54e944ae39dd7810316 GIT binary patch literal 36864 zcmeI5J!@1^5Qaywwh=7sY_znn@`u=3s-?kFk%%G$OprkQs0FbQg9<5ZRIpI&L`Y#k zL<0#yTt83|_8#Y8^A`6UX0{RJDP9=n&SqgUJMVK&2s;de4FN5dVrM3w&B`>S>t)4G zZ=W)MSx8G|ug!fmFOF$ygJoo1ozbw%ETb}CY!*d&Uu)=p|MxLV@9S&m|M=%3GyAoc z{`dD$X7|)u`rr3~%<iwX^uO=J_-~(s@L&8_*_8d$KL^17vGV}@34hizGX9JIDx<>x z@V|Nk{0V=;pWHvUe1ZEn?%(upGn~ITf9V~CvSlQ0?U`1d{lorY|HO8VepZz6dolbE z|HJ?AKmPmoUP##{5=WRvYg&D7<#nfL;@-~JXY7CWKl`8k&;DWm>p80xbN>@Ni>b%< zV*D5X#eeZ%{1^Xid9LR1U;J0^CG>6~61VnDE1$V@(ApmJ=ri~S{(*nsANCLYqny)< z;UD-1{^9@Ml{Lp=Wz1d-f5M;eC;SP2!k;bX)I9tNf5M;e=NNNpuE(7E4E}^a;ZOJz z{)9i3Gg~qI34g+$@TaooSgefMi{VfB6aIuh;ZOLp#hjXlKjBaK6aE}yPR;e0Q=h?~ z@F)BUf5M;er*dX1hCks?_!ItA)*OqKF?%um34g+$@F)BUf3}!Y^YAD934g+$W6Y_! z9&_q5_!ItwKjBaK^Z(+{vf-Q*(3j0(Z(bBzdL7fJckk`VgGW}L&4sl7@|-=scf!uD zoeZh$`ED5<w{6SlqaCx1)KgROH}8KytNtZv%O9q8WKu$USXS-w`b8@{heEpZ>!>Zf z-EW7t4u&+{{o67+U_ULRAGXgjO7(nR&IVUKj%d;As;&jK>~&QuLEZ4Ws#`%_@VbmH zd3{C;UZ0WnG!x(U_lfAP*SWUt$5ht5zUt{_OwV_$RK1$Sbl!h<MpwK(qnlozQKskA l&isAtGw&ICPS2SEW`G%B2ABb6fEi#0m;q*h8Th9&@CUhxTdDv6
literal 0 HcmV?d00001