Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mfreadwrite/tests/mfplat.c | 222 ++++++++++++++++++++++++++ dlls/mfreadwrite/tests/resource.rc | 4 + dlls/mfreadwrite/tests/test-48000.wav | Bin 0 -> 2104 bytes 3 files changed, 226 insertions(+) create mode 100644 dlls/mfreadwrite/tests/test-48000.wav
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index e3ff7f6e7aa..8c2aab6714d 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -1230,6 +1230,227 @@ done: DestroyWindow(window); }
+struct audio_format +{ + GUID subtype; + UINT32 bits; + UINT32 rate; +}; + +static void test_audio_media_type(const char *resource_name, IMFMediaType *media_type, struct audio_format *expect) +{ + UINT32 uint32_value, buffer_value_size; + BYTE buffer_value[512]; + double double_value; + GUID guid_value; + HRESULT hr; + + memset(&guid_value, 0xcd, sizeof(guid_value)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid_value); + ok(hr == S_OK, "missing MF_MT_MAJOR_TYPE, hr %#x\n", hr); + ok(IsEqualGUID(&guid_value, &MFMediaType_Audio), "got MF_MT_MAJOR_TYPE %s\n", debugstr_guid(&guid_value)); + + memset(&guid_value, 0xcd, sizeof(guid_value)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid_value); + ok(hr == S_OK, "missing MF_MT_SUBTYPE, hr %#x\n", hr); + ok(IsEqualGUID(&guid_value, &expect->subtype), "got MF_MT_SUBTYPE %s\n", debugstr_guid(&guid_value)); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &uint32_value); + ok(hr == S_OK, "missing MF_MT_ALL_SAMPLES_INDEPENDENT, hr %#x\n", hr); + ok(uint32_value == 1, "got MF_MT_ALL_SAMPLES_INDEPENDENT %u\n", uint32_value); + + hr = IMFMediaType_GetGUID(media_type, &MF_MT_AM_FORMAT_TYPE, &guid_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AM_FORMAT_TYPE, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_COMPRESSED, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_COMPRESSED, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_FIXED_SIZE_SAMPLES, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_SAMPLE_SIZE, hr %#x\n", hr); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA, buffer_value, sizeof(buffer_value), &buffer_value_size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_USER_DATA, hr %#x\n", hr); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_WRAPPED_TYPE, buffer_value, sizeof(buffer_value), &buffer_value_size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_WRAPPED_TYPE, hr %#x\n", hr); + + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AAC_PAYLOAD_TYPE, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AAC_PAYLOAD_TYPE, hr %#x\n", hr); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &uint32_value); + todo_wine + ok(hr == S_OK, "missing MF_MT_AUDIO_AVG_BYTES_PER_SECOND, hr %#x\n", hr); + todo_wine + ok(uint32_value == expect->rate * expect->bits / 8, "got MF_MT_AUDIO_AVG_BYTES_PER_SECOND %u\n", uint32_value); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &uint32_value); + ok(hr == S_OK, "missing MF_MT_AUDIO_BITS_PER_SAMPLE, hr %#x\n", hr); + ok(uint32_value == expect->bits, "got MF_MT_AUDIO_BITS_PER_SAMPLE %u\n", uint32_value); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &uint32_value); + todo_wine + ok(hr == S_OK, "missing MF_MT_AUDIO_BLOCK_ALIGNMENT, hr %#x\n", hr); + todo_wine + ok(uint32_value == expect->bits / 8, "got MF_MT_AUDIO_BLOCK_ALIGNMENT %u\n", uint32_value); + + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_CHANNEL_MASK, &uint32_value); + todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AUDIO_CHANNEL_MASK, hr %#x\n", hr); + hr = IMFMediaType_GetDouble(media_type, &MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND, &double_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND, hr %#x\n", hr); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_AUDIO_FOLDDOWN_MATRIX, buffer_value, sizeof(buffer_value), &buffer_value_size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AUDIO_FOLDDOWN_MATRIX, hr %#x\n", hr); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, &uint32_value); + ok(hr == S_OK, "missing MF_MT_AUDIO_NUM_CHANNELS, hr %#x\n", hr); + ok(uint32_value == 1, "got MF_MT_AUDIO_NUM_CHANNELS %u\n", uint32_value); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &uint32_value); + todo_wine + ok(hr == S_OK, "missing MF_MT_AUDIO_PREFER_WAVEFORMATEX, hr %#x\n", hr); + todo_wine + ok(uint32_value == 1, "got MF_MT_AUDIO_PREFER_WAVEFORMATEX %u\n", uint32_value); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_BLOCK, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AUDIO_SAMPLES_PER_BLOCK, hr %#x\n", hr); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &uint32_value); + ok(hr == S_OK, "missing MF_MT_AUDIO_SAMPLES_PER_SECOND, hr %#x\n", hr); + ok(uint32_value == expect->rate, "got MF_MT_AUDIO_SAMPLES_PER_SECOND %u\n", uint32_value); + + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_WMADRC_AVGREF, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AUDIO_WMADRC_AVGREF, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_WMADRC_AVGTARGET, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AUDIO_WMADRC_AVGTARGET, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_WMADRC_PEAKREF, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AUDIO_WMADRC_PEAKREF, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_WMADRC_PEAKTARGET, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AUDIO_WMADRC_PEAKTARGET, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ORIGINAL_WAVE_FORMAT_TAG, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_ORIGINAL_WAVE_FORMAT_TAG, hr %#x\n", hr); +} + +struct test_media_types_params +{ + const char *resource; + BOOL has_audio; + struct audio_format audio_format; +}; + +static void test_media_types(void) +{ + struct test_media_types_params tests[] = + { + {.resource = "test.wav", .has_audio = TRUE, .audio_format = + {.subtype = MFAudioFormat_PCM, .bits = 8, .rate = 44100} + }, + {.resource = "test-48000.wav", .has_audio = TRUE, .audio_format = + {.subtype = MFAudioFormat_PCM, .bits = 16, .rate = 48000} + }, + }; + + struct audio_format test_audio_formats[] = + { + {.subtype = MFAudioFormat_PCM, .bits = 8, .rate = 44100}, + {.subtype = MFAudioFormat_Float, .bits = 32, .rate = 44100}, + {.subtype = MFAudioFormat_PCM, .bits = 8, .rate = 48000}, + {.subtype = MFAudioFormat_Float, .bits = 32, .rate = 48000}, + }; + + int i, j, old_mute_threshold; + IMFMediaType *media_type; + IMFSourceReader *reader; + IMFByteStream *stream; + HRESULT hr; + + if (!pMFCreateMFByteStreamOnStream) + { + win_skip("MFCreateMFByteStreamOnStream() not found\n"); + return; + } + + /* FIXME: remove this when enough todo_wine are fixed */ + old_mute_threshold = winetest_mute_threshold; + winetest_mute_threshold = 1; + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context(tests[i].resource); + + for (j = 0; tests[i].has_audio && j < ARRAY_SIZE(test_audio_formats); ++j) + { + stream = get_resource_stream(tests[i].resource); + if (FAILED(hr = MFCreateSourceReaderFromByteStream(stream, NULL, &reader))) + { + todo_wine + win_skip("MFCreateSourceReaderFromByteStream() failed\n"); + IMFByteStream_Release(stream); + continue; + } + ok(hr == S_OK, "Failed to create source reader, hr %#x.\n", hr); + + hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, &media_type); + ok(hr == S_OK, "Failed to get native mediatype, hr %#x.\n", hr); + winetest_push_context("native audio"); + test_audio_media_type(tests[i].resource, media_type, &tests[i].audio_format); + IMFMediaType_Release(media_type); + winetest_pop_context(); + + hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 1, &media_type); + todo_wine + ok(hr == MF_E_NO_MORE_TYPES, "Expected only one native mediatype, hr %#x.\n", hr); + if (hr == S_OK) IMFMediaType_Release(media_type); + + hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, TRUE); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &test_audio_formats[j].subtype); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, test_audio_formats[j].bits); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, test_audio_formats[j].rate); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, test_audio_formats[j].bits / 8); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, test_audio_formats[j].rate * test_audio_formats[j].bits / 8); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + hr = IMFSourceReader_SetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, NULL, media_type); + todo_wine + ok(hr == S_OK || broken(hr == MF_E_TOPO_CODEC_NOT_FOUND) /* <= win7 */, "Failed setting current media type %u, hr %#x.\n", j, hr); + IMFMediaType_Release(media_type); + if (hr != S_OK) continue; + + hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &media_type); + ok(hr == S_OK, "Failed to get current mediatype, hr %#x.\n", hr); + winetest_push_context("current audio %u", j); + test_audio_media_type(tests[i].resource, media_type, &test_audio_formats[j]); + winetest_pop_context(); + IMFMediaType_Release(media_type); + + IMFSourceReader_Release(reader); + IMFByteStream_Release(stream); + } + + winetest_pop_context(); + } + + winetest_mute_threshold = old_mute_threshold; +} + START_TEST(mfplat) { HRESULT hr; @@ -1242,6 +1463,7 @@ START_TEST(mfplat) test_factory(); test_source_reader(); test_source_reader_from_media_source(); + test_media_types(); test_reader_d3d9();
hr = MFShutdown(); diff --git a/dlls/mfreadwrite/tests/resource.rc b/dlls/mfreadwrite/tests/resource.rc index f54212a8c8f..5b3269fef1d 100644 --- a/dlls/mfreadwrite/tests/resource.rc +++ b/dlls/mfreadwrite/tests/resource.rc @@ -20,3 +20,7 @@
/* @makedep: test.wav */ test.wav RCDATA test.wav + +/* @makedep: test-48000.wav */ +test-48000.wav RCDATA test-48000.wav + diff --git a/dlls/mfreadwrite/tests/test-48000.wav b/dlls/mfreadwrite/tests/test-48000.wav new file mode 100644 index 0000000000000000000000000000000000000000..dedd660bb9a97a9cacedabaddc1b1bafd2f4a176 GIT binary patch literal 2104 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
literal 0 HcmV?d00001
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mfreadwrite/tests/mfplat.c | 303 +++++++++++++++++++++ dlls/mfreadwrite/tests/resource.rc | 2 + dlls/mfreadwrite/tests/test-40x36-h264.mp4 | Bin 0 -> 11151 bytes 3 files changed, 305 insertions(+) create mode 100644 dlls/mfreadwrite/tests/test-40x36-h264.mp4
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index 8c2aab6714d..3f5e20f844b 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -28,6 +28,7 @@
#include "initguid.h" #include "ole2.h" +#include "uuids.h"
DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -1338,11 +1339,257 @@ static void test_audio_media_type(const char *resource_name, IMFMediaType *media ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_ORIGINAL_WAVE_FORMAT_TAG, hr %#x\n", hr); }
+struct video_format +{ + GUID subtype; + UINT32 width; + UINT32 height; + UINT32 stride; +}; + +static void test_video_media_type(const char *resource_name, IMFMediaType *media_type, struct video_format *expect) +{ + UINT32 uint32_value, buffer_value_size, width = expect->width, height = expect->height; + BOOL is_h264 = IsEqualGUID(&expect->subtype, &MFVideoFormat_H264); + BYTE buffer_value[512]; + UINT64 uint64_value; + GUID guid_value; + HRESULT hr; + + memset(&guid_value, 0xcd, sizeof(guid_value)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid_value); + ok(hr == S_OK, "missing MF_MT_MAJOR_TYPE, hr %#x\n", hr); + ok(IsEqualGUID(&guid_value, &MFMediaType_Video), "got MF_MT_MAJOR_TYPE %s\n", debugstr_guid(&guid_value)); + + memset(&guid_value, 0xcd, sizeof(guid_value)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid_value); + ok(hr == S_OK, "missing MF_MT_SUBTYPE, hr %#x\n", hr); + todo_wine_if(is_h264) + ok(IsEqualGUID(&guid_value, &expect->subtype), "got MF_MT_SUBTYPE %s\n", debugstr_guid(&guid_value)); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &uint32_value); + if (is_h264) + { + todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_ALL_SAMPLES_INDEPENDENT, hr %#x\n", hr); + } + else + { + ok(hr == S_OK, "missing MF_MT_ALL_SAMPLES_INDEPENDENT, hr %#x\n", hr); + ok(uint32_value == 1, "got MF_MT_ALL_SAMPLES_INDEPENDENT %u\n", uint32_value); + } + + memset(&guid_value, 0xcd, sizeof(guid_value)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_AM_FORMAT_TYPE, &guid_value); + if (!is_h264) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AM_FORMAT_TYPE, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_AM_FORMAT_TYPE, hr %#x\n", hr); + todo_wine + ok(IsEqualGUID(&guid_value, &FORMAT_MPEG2Video), "got MF_MT_AM_FORMAT_TYPE %s\n", debugstr_guid(&guid_value)); + } + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_COMPRESSED, &uint32_value); + if (is_h264) todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_COMPRESSED, hr %#x\n", hr); + else + { + ok(hr == S_OK, "missing MF_MT_COMPRESSED, hr %#x\n", hr); + ok(uint32_value == 0, "got MF_MT_COMPRESSED %u\n", uint32_value); + } + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &uint32_value); + if (is_h264) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_FIXED_SIZE_SAMPLES, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_FIXED_SIZE_SAMPLES, hr %#x\n", hr); + todo_wine + ok(uint32_value == 1, "got MF_MT_FIXED_SIZE_SAMPLES %u\n", uint32_value); + } + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &uint32_value); + todo_wine + ok(hr == S_OK, "missing MF_MT_SAMPLE_SIZE, hr %#x\n", hr); + if (is_h264) + { + todo_wine + ok(uint32_value == 1, "got MF_MT_SAMPLE_SIZE %u\n", uint32_value); + } + else + { + todo_wine + ok(uint32_value == width * height * 3 / 2, "got MF_MT_SAMPLE_SIZE %u\n", uint32_value); + } + + hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA, buffer_value, sizeof(buffer_value), &buffer_value_size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_USER_DATA, hr %#x\n", hr); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_WRAPPED_TYPE, buffer_value, sizeof(buffer_value), &buffer_value_size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_WRAPPED_TYPE, hr %#x\n", hr); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AVG_BIT_ERROR_RATE, &uint32_value); + if (is_h264) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AVG_BIT_ERROR_RATE, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_AVG_BIT_ERROR_RATE, hr %#x\n", hr); + todo_wine + ok(uint32_value == 0, "got MF_MT_AVG_BIT_ERROR_RATE %u\n", uint32_value); + } + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AVG_BITRATE, &uint32_value); + todo_wine + ok(hr == S_OK, "missing MF_MT_AVG_BITRATE, hr %#x\n", hr); + todo_wine + ok(uint32_value == 78904, "got MF_MT_AVG_BITRATE %u\n", uint32_value); + + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_CUSTOM_VIDEO_PRIMARIES, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_CUSTOM_VIDEO_PRIMARIES, hr %#x\n", hr); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, &uint32_value); + if (is_h264) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_DEFAULT_STRIDE, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_DEFAULT_STRIDE, hr %#x\n", hr); + todo_wine + ok(uint32_value == width, "got MF_MT_DEFAULT_STRIDE %u\n", uint32_value); + } + + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_DRM_FLAGS, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_DRM_FLAGS, hr %#x\n", hr); + + uint64_value = 0xdeadbeefdeadbeefull; + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_RATE, &uint64_value); + ok(hr == S_OK, "missing MF_MT_FRAME_RATE, hr %#x\n", hr); + ok((uint64_value >> 32) == 30, "got MF_MT_FRAME_RATE %I64x\n", uint64_value); + ok((uint64_value & 0xffffffff) == 1, "got MF_MT_FRAME_RATE %I64x\n", uint64_value); + + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_RATE_RANGE_MAX, &uint64_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_FRAME_RATE_RANGE_MAX, hr %#x\n", hr); + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_RATE_RANGE_MIN, &uint64_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_FRAME_RATE_RANGE_MIN, hr %#x\n", hr); + + uint64_value = 0xdeadbeefdeadbeefull; + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &uint64_value); + ok(hr == S_OK, "missing MF_MT_FRAME_SIZE, hr %#x\n", hr); + ok((uint64_value >> 32) == width, "got MF_MT_FRAME_SIZE %I64x\n", uint64_value); + ok((uint64_value & 0xffffffff) == height, "got MF_MT_FRAME_SIZE %I64x\n", uint64_value); + + hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, buffer_value, sizeof(buffer_value), &buffer_value_size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_GEOMETRIC_APERTURE, hr %#x\n", hr); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &uint32_value); + todo_wine + ok(hr == S_OK, "missing MF_MT_INTERLACE_MODE, hr %#x\n", hr); + todo_wine + ok(uint32_value == MFVideoInterlace_MixedInterlaceOrProgressive, "got MF_MT_INTERLACE_MODE %u\n", uint32_value); + + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MAX_KEYFRAME_SPACING, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MAX_KEYFRAME_SPACING, hr %#x\n", hr); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, buffer_value, sizeof(buffer_value), &buffer_value_size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MINIMUM_DISPLAY_APERTURE, hr %#x\n", hr); + + buffer_value_size = 0xdeadbeef; + memset(buffer_value, 0xcd, sizeof(buffer_value)); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, buffer_value, sizeof(buffer_value), &buffer_value_size); + if (!is_h264) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MPEG_SEQUENCE_HEADER, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_MPEG_SEQUENCE_HEADER, hr %#x\n", hr); + todo_wine + ok(buffer_value_size == 39, "got MF_MT_MPEG_SEQUENCE_HEADER length %u\n", buffer_value_size); + } + + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG_START_TIME_CODE, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MPEG_START_TIME_CODE, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG2_FLAGS, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MPEG2_FLAGS, hr %#x\n", hr); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG2_LEVEL, &uint32_value); + if (!is_h264) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MPEG2_LEVEL, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_MPEG2_LEVEL, hr %#x\n", hr); + todo_wine + ok(uint32_value == 20, "got MF_MT_MPEG2_LEVEL %u\n", uint32_value); + } + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MPEG2_PROFILE, &uint32_value); + if (!is_h264) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MPEG2_PROFILE, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_MPEG2_PROFILE, hr %#x\n", hr); + todo_wine + ok(uint32_value == 100, "got MF_MT_MPEG2_PROFILE %u\n", uint32_value); + } + + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ORIGINAL_4CC, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_ORIGINAL_4CC, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_PAD_CONTROL_FLAGS, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PAD_CONTROL_FLAGS, hr %#x\n", hr); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_PALETTE, buffer_value, sizeof(buffer_value), &buffer_value_size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PALETTE, hr %#x\n", hr); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_PAN_SCAN_APERTURE, buffer_value, sizeof(buffer_value), &buffer_value_size); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PAN_SCAN_APERTURE, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_PAN_SCAN_ENABLED, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PAN_SCAN_ENABLED, hr %#x\n", hr); + + uint64_value = 0xdeadbeefdeadbeefull; + hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &uint64_value); + todo_wine + ok(hr == S_OK, "missing MF_MT_PIXEL_ASPECT_RATIO, hr %#x\n", hr); + todo_wine + ok(uint64_value == 0x100000001ull, "got MF_MT_PIXEL_ASPECT_RATIO %I64x\n", uint64_value); + + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SOURCE_CONTENT_HINT, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_SOURCE_CONTENT_HINT, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_TRANSFER_FUNCTION, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_TRANSFER_FUNCTION, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_3D, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_3D, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_CHROMA_SITING, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_CHROMA_SITING, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_LIGHTING, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_LIGHTING, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_NOMINAL_RANGE, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_NOMINAL_RANGE, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_PRIMARIES, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_PRIMARIES, hr %#x\n", hr); + + uint32_value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_ROTATION, &uint32_value); + ok(hr == S_OK || hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_ROTATION, hr %#x\n", hr); + if (hr == S_OK) ok(uint32_value == 0, "got MF_MT_VIDEO_ROTATION %u\n", uint32_value); + + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_YUV_MATRIX, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_YUV_MATRIX, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_XVP_CALLER_ALLOCATES_OUTPUT, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_XVP_CALLER_ALLOCATES_OUTPUT, hr %#x\n", hr); + hr = IMFMediaType_GetUINT32(media_type, &MF_XVP_DISABLE_FRC, &uint32_value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_XVP_DISABLE_FRC, hr %#x\n", hr); +} + struct test_media_types_params { const char *resource; BOOL has_audio; struct audio_format audio_format; + BOOL has_video; + struct video_format video_format; };
static void test_media_types(void) @@ -1355,6 +1602,9 @@ static void test_media_types(void) {.resource = "test-48000.wav", .has_audio = TRUE, .audio_format = {.subtype = MFAudioFormat_PCM, .bits = 16, .rate = 48000} }, + {.resource = "test-40x36-h264.mp4", .has_video = TRUE, .video_format = + {.subtype = MFVideoFormat_H264, .width = 40, .height = 36} + }, };
struct audio_format test_audio_formats[] = @@ -1364,6 +1614,11 @@ static void test_media_types(void) {.subtype = MFAudioFormat_PCM, .bits = 8, .rate = 48000}, {.subtype = MFAudioFormat_Float, .bits = 32, .rate = 48000}, }; + struct video_format test_video_formats[] = + { + {.subtype = MFVideoFormat_NV12, .width = 40, .height = 36}, + {.subtype = MFVideoFormat_I420, .width = 40, .height = 36}, + };
int i, j, old_mute_threshold; IMFMediaType *media_type; @@ -1445,6 +1700,54 @@ static void test_media_types(void) IMFByteStream_Release(stream); }
+ for (j = 0; tests[i].has_video && j < ARRAY_SIZE(test_video_formats); ++j) + { + stream = get_resource_stream(tests[i].resource); + if (FAILED(hr = MFCreateSourceReaderFromByteStream(stream, NULL, &reader))) + { + todo_wine + win_skip("MFCreateSourceReaderFromByteStream() failed\n"); + IMFByteStream_Release(stream); + continue; + } + ok(hr == S_OK, "Failed to create source reader, hr %#x.\n", hr); + + hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &media_type); + ok(hr == S_OK, "Failed to get native mediatype, hr %#x.\n", hr); + winetest_push_context("native video"); + test_video_media_type(tests[i].resource, media_type, &tests[i].video_format); + IMFMediaType_Release(media_type); + winetest_pop_context(); + + hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 1, &media_type); + todo_wine + ok(hr == MF_E_NO_MORE_TYPES, "Expected only one native mediatype, hr %#x.\n", hr); + if (hr == S_OK) IMFMediaType_Release(media_type); + + hr = IMFSourceReader_SetStreamSelection(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, TRUE); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &test_video_formats[j].subtype); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + hr = IMFSourceReader_SetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, media_type); + ok(hr == S_OK, "Failed setting current media type %u, hr %#x.\n", j, hr); + IMFMediaType_Release(media_type); + + hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &media_type); + ok(hr == S_OK, "Failed to get current mediatype, hr %#x.\n", hr); + winetest_push_context("current video %u", j); + test_video_media_type(tests[i].resource, media_type, &test_video_formats[j]); + winetest_pop_context(); + IMFMediaType_Release(media_type); + + IMFSourceReader_Release(reader); + IMFByteStream_Release(stream); + } + winetest_pop_context(); }
diff --git a/dlls/mfreadwrite/tests/resource.rc b/dlls/mfreadwrite/tests/resource.rc index 5b3269fef1d..5ae9636d671 100644 --- a/dlls/mfreadwrite/tests/resource.rc +++ b/dlls/mfreadwrite/tests/resource.rc @@ -24,3 +24,5 @@ test.wav RCDATA test.wav /* @makedep: test-48000.wav */ test-48000.wav RCDATA test-48000.wav
+/* @makedep: test-40x36-h264.mp4 */ +test-40x36-h264.mp4 RCDATA test-40x36-h264.mp4 diff --git a/dlls/mfreadwrite/tests/test-40x36-h264.mp4 b/dlls/mfreadwrite/tests/test-40x36-h264.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..3b3771a7c67322ed99721a026b9f17d8c7829856 GIT binary patch literal 11151 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
literal 0 HcmV?d00001
On 10/28/21 5:01 PM, Rémi Bernon wrote:
- UINT32 uint32_value, buffer_value_size, width = expect->width, height = expect->height;
- BOOL is_h264 = IsEqualGUID(&expect->subtype, &MFVideoFormat_H264);
- BYTE buffer_value[512];
- UINT64 uint64_value;
- GUID guid_value;
- HRESULT hr;
- memset(&guid_value, 0xcd, sizeof(guid_value));
- hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid_value);
- ok(hr == S_OK, "missing MF_MT_MAJOR_TYPE, hr %#x\n", hr);
- ok(IsEqualGUID(&guid_value, &MFMediaType_Video), "got MF_MT_MAJOR_TYPE %s\n", debugstr_guid(&guid_value));
- memset(&guid_value, 0xcd, sizeof(guid_value));
- hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid_value);
- ok(hr == S_OK, "missing MF_MT_SUBTYPE, hr %#x\n", hr);
- todo_wine_if(is_h264)
- ok(IsEqualGUID(&guid_value, &expect->subtype), "got MF_MT_SUBTYPE %s\n", debugstr_guid(&guid_value));
- uint32_value = 0xdeadbeef;
- hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &uint32_value);
- if (is_h264)
- {
todo_wine
ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_ALL_SAMPLES_INDEPENDENT, hr %#x\n", hr);
- }
- else
- {
ok(hr == S_OK, "missing MF_MT_ALL_SAMPLES_INDEPENDENT, hr %#x\n", hr);
ok(uint32_value == 1, "got MF_MT_ALL_SAMPLES_INDEPENDENT %u\n", uint32_value);
- }
It's certainly possible decoders differ in attributes they use, but here what matters is compressed/uncompressed distinction, and not whether it's H264 or not, I think. So turning this in two paths, with possibility to add more format-specific checks for compressed part, will make this more compact and easy to follow.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mfreadwrite/tests/mfplat.c | 157 ++++++++++++++++++++++++++++---- 1 file changed, 139 insertions(+), 18 deletions(-)
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index 3f5e20f844b..c24582c12b5 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -1347,15 +1347,21 @@ struct video_format UINT32 stride; };
-static void test_video_media_type(const char *resource_name, IMFMediaType *media_type, struct video_format *expect) +static void test_video_media_type(const char *resource_name, IMFMediaType *media_type, struct video_format *expect, BOOL actual) { UINT32 uint32_value, buffer_value_size, width = expect->width, height = expect->height; BOOL is_h264 = IsEqualGUID(&expect->subtype, &MFVideoFormat_H264); - BYTE buffer_value[512]; + UINT32 buffer_value[64]; UINT64 uint64_value; GUID guid_value; HRESULT hr;
+ if (actual) + { + width = (width + 0xf) & ~0xf; + height = (height + 0xf) & ~0xf; + } + memset(&guid_value, 0xcd, sizeof(guid_value)); hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid_value); ok(hr == S_OK, "missing MF_MT_MAJOR_TYPE, hr %#x\n", hr); @@ -1426,9 +1432,9 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media ok(uint32_value == width * height * 3 / 2, "got MF_MT_SAMPLE_SIZE %u\n", uint32_value); }
- hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA, buffer_value, sizeof(buffer_value), &buffer_value_size); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA, (BYTE *)buffer_value, sizeof(buffer_value), &buffer_value_size); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_USER_DATA, hr %#x\n", hr); - hr = IMFMediaType_GetBlob(media_type, &MF_MT_WRAPPED_TYPE, buffer_value, sizeof(buffer_value), &buffer_value_size); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_WRAPPED_TYPE, (BYTE *)buffer_value, sizeof(buffer_value), &buffer_value_size); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_WRAPPED_TYPE, hr %#x\n", hr);
uint32_value = 0xdeadbeef; @@ -1480,11 +1486,30 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media uint64_value = 0xdeadbeefdeadbeefull; hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &uint64_value); ok(hr == S_OK, "missing MF_MT_FRAME_SIZE, hr %#x\n", hr); + todo_wine_if(actual) ok((uint64_value >> 32) == width, "got MF_MT_FRAME_SIZE %I64x\n", uint64_value); + todo_wine_if(actual) ok((uint64_value & 0xffffffff) == height, "got MF_MT_FRAME_SIZE %I64x\n", uint64_value);
- hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, buffer_value, sizeof(buffer_value), &buffer_value_size); - ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_GEOMETRIC_APERTURE, hr %#x\n", hr); + buffer_value_size = 0xdeadbeef; + memset(buffer_value, 0xcd, sizeof(buffer_value)); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (BYTE *)buffer_value, sizeof(buffer_value), &buffer_value_size); + if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_GEOMETRIC_APERTURE, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_GEOMETRIC_APERTURE, hr %#x\n", hr); + todo_wine + ok(buffer_value_size == 16, "got MF_MT_GEOMETRIC_APERTURE length %u\n", buffer_value_size); + todo_wine + ok(buffer_value[0] == 0, "got MF_MT_GEOMETRIC_APERTURE[0] %u\n", buffer_value[0]); + todo_wine + ok(buffer_value[1] == 0, "got MF_MT_GEOMETRIC_APERTURE[1] %u\n", buffer_value[1]); + todo_wine + ok(buffer_value[2] == expect->width, "got MF_MT_GEOMETRIC_APERTURE[2] %u\n", buffer_value[2]); + todo_wine + ok(buffer_value[3] == expect->height, "got MF_MT_GEOMETRIC_APERTURE[3] %u\n", buffer_value[3]); + }
uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &uint32_value); @@ -1495,12 +1520,30 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media
hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MAX_KEYFRAME_SPACING, &uint32_value); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MAX_KEYFRAME_SPACING, hr %#x\n", hr); - hr = IMFMediaType_GetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, buffer_value, sizeof(buffer_value), &buffer_value_size); - ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MINIMUM_DISPLAY_APERTURE, hr %#x\n", hr);
buffer_value_size = 0xdeadbeef; memset(buffer_value, 0xcd, sizeof(buffer_value)); - hr = IMFMediaType_GetBlob(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, buffer_value, sizeof(buffer_value), &buffer_value_size); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)buffer_value, sizeof(buffer_value), &buffer_value_size); + if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MINIMUM_DISPLAY_APERTURE, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_MINIMUM_DISPLAY_APERTURE, hr %#x\n", hr); + todo_wine + ok(buffer_value_size == 16, "got MF_MT_MINIMUM_DISPLAY_APERTURE length %u\n", buffer_value_size); + todo_wine + ok(buffer_value[0] == 0, "got MF_MT_MINIMUM_DISPLAY_APERTURE[0] %u\n", buffer_value[0]); + todo_wine + ok(buffer_value[1] == 0, "got MF_MT_MINIMUM_DISPLAY_APERTURE[1] %u\n", buffer_value[1]); + todo_wine + ok(buffer_value[2] == expect->width, "got MF_MT_MINIMUM_DISPLAY_APERTURE[2] %u\n", buffer_value[2]); + todo_wine + ok(buffer_value[3] == expect->height, "got MF_MT_MINIMUM_DISPLAY_APERTURE[3] %u\n", buffer_value[3]); + } + + buffer_value_size = 0xdeadbeef; + memset(buffer_value, 0xcd, sizeof(buffer_value)); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_MPEG_SEQUENCE_HEADER, (BYTE *)buffer_value, sizeof(buffer_value), &buffer_value_size); if (!is_h264) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MPEG_SEQUENCE_HEADER, hr %#x\n", hr); else { @@ -1541,10 +1584,29 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_ORIGINAL_4CC, hr %#x\n", hr); hr = IMFMediaType_GetUINT32(media_type, &MF_MT_PAD_CONTROL_FLAGS, &uint32_value); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PAD_CONTROL_FLAGS, hr %#x\n", hr); - hr = IMFMediaType_GetBlob(media_type, &MF_MT_PALETTE, buffer_value, sizeof(buffer_value), &buffer_value_size); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_PALETTE, (BYTE *)buffer_value, sizeof(buffer_value), &buffer_value_size); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PALETTE, hr %#x\n", hr); - hr = IMFMediaType_GetBlob(media_type, &MF_MT_PAN_SCAN_APERTURE, buffer_value, sizeof(buffer_value), &buffer_value_size); - ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PAN_SCAN_APERTURE, hr %#x\n", hr); + + buffer_value_size = 0xdeadbeef; + memset(buffer_value, 0xcd, sizeof(buffer_value)); + hr = IMFMediaType_GetBlob(media_type, &MF_MT_PAN_SCAN_APERTURE, (BYTE *)buffer_value, sizeof(buffer_value), &buffer_value_size); + if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PAN_SCAN_APERTURE, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_PAN_SCAN_APERTURE, hr %#x\n", hr); + todo_wine + ok(buffer_value_size == 16, "got MF_MT_PAN_SCAN_APERTURE length %u\n", buffer_value_size); + todo_wine + ok(buffer_value[0] == 0, "got MF_MT_PAN_SCAN_APERTURE[0] %u\n", buffer_value[0]); + todo_wine + ok(buffer_value[1] == 0, "got MF_MT_PAN_SCAN_APERTURE[1] %u\n", buffer_value[1]); + todo_wine + ok(buffer_value[2] == expect->width, "got MF_MT_PAN_SCAN_APERTURE[2] %u\n", buffer_value[2]); + todo_wine + ok(buffer_value[3] == expect->height, "got MF_MT_PAN_SCAN_APERTURE[3] %u\n", buffer_value[3]); + } + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_PAN_SCAN_ENABLED, &uint32_value); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PAN_SCAN_ENABLED, hr %#x\n", hr);
@@ -1557,26 +1619,63 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media
hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SOURCE_CONTENT_HINT, &uint32_value); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_SOURCE_CONTENT_HINT, hr %#x\n", hr); + + uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_TRANSFER_FUNCTION, &uint32_value); - ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_TRANSFER_FUNCTION, hr %#x\n", hr); + if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_TRANSFER_FUNCTION, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_TRANSFER_FUNCTION, hr %#x\n", hr); + todo_wine + ok(uint32_value == MFVideoTransFunc_709, "got MF_MT_TRANSFER_FUNCTION %u\n", uint32_value); + } + hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_3D, &uint32_value); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_3D, hr %#x\n", hr); hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_CHROMA_SITING, &uint32_value); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_CHROMA_SITING, hr %#x\n", hr); hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_LIGHTING, &uint32_value); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_LIGHTING, hr %#x\n", hr); + + uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_NOMINAL_RANGE, &uint32_value); - ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_NOMINAL_RANGE, hr %#x\n", hr); + if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_NOMINAL_RANGE, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_VIDEO_NOMINAL_RANGE, hr %#x\n", hr); + todo_wine + ok(uint32_value == MFNominalRange_Wide, "got MF_MT_VIDEO_NOMINAL_RANGE %u\n", uint32_value); + } + + uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_PRIMARIES, &uint32_value); - ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_PRIMARIES, hr %#x\n", hr); + if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_PRIMARIES, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_VIDEO_PRIMARIES, hr %#x\n", hr); + todo_wine + ok(uint32_value == MFVideoPrimaries_SMPTE170M, "got MF_MT_VIDEO_PRIMARIES %u\n", uint32_value); + }
uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_ROTATION, &uint32_value); ok(hr == S_OK || hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_ROTATION, hr %#x\n", hr); if (hr == S_OK) ok(uint32_value == 0, "got MF_MT_VIDEO_ROTATION %u\n", uint32_value);
+ uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_YUV_MATRIX, &uint32_value); - ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_YUV_MATRIX, hr %#x\n", hr); + if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_YUV_MATRIX, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_YUV_MATRIX, hr %#x\n", hr); + todo_wine + ok(uint32_value == MFVideoTransferMatrix_BT601, "got MF_MT_YUV_MATRIX %u\n", uint32_value); + } + hr = IMFMediaType_GetUINT32(media_type, &MF_XVP_CALLER_ALLOCATES_OUTPUT, &uint32_value); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_XVP_CALLER_ALLOCATES_OUTPUT, hr %#x\n", hr); hr = IMFMediaType_GetUINT32(media_type, &MF_XVP_DISABLE_FRC, &uint32_value); @@ -1624,6 +1723,8 @@ static void test_media_types(void) IMFMediaType *media_type; IMFSourceReader *reader; IMFByteStream *stream; + IMFSample *sample; + DWORD flags; HRESULT hr;
if (!pMFCreateMFByteStreamOnStream) @@ -1696,6 +1797,17 @@ static void test_media_types(void) winetest_pop_context(); IMFMediaType_Release(media_type);
+ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, NULL, &flags, NULL, &sample); + ok(hr == S_OK, "Failed to read sample, hr %#x\n", hr); + IMFSample_Release(sample); + + hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_AUDIO_STREAM, &media_type); + ok(hr == S_OK, "Failed to get current mediatype, hr %#x.\n", hr); + winetest_push_context("actual audio %u", j); + test_audio_media_type(tests[i].resource, media_type, &test_audio_formats[j]); + winetest_pop_context(); + IMFMediaType_Release(media_type); + IMFSourceReader_Release(reader); IMFByteStream_Release(stream); } @@ -1715,7 +1827,7 @@ static void test_media_types(void) hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &media_type); ok(hr == S_OK, "Failed to get native mediatype, hr %#x.\n", hr); winetest_push_context("native video"); - test_video_media_type(tests[i].resource, media_type, &tests[i].video_format); + test_video_media_type(tests[i].resource, media_type, &tests[i].video_format, FALSE); IMFMediaType_Release(media_type); winetest_pop_context();
@@ -1740,10 +1852,19 @@ static void test_media_types(void) hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &media_type); ok(hr == S_OK, "Failed to get current mediatype, hr %#x.\n", hr); winetest_push_context("current video %u", j); - test_video_media_type(tests[i].resource, media_type, &test_video_formats[j]); + test_video_media_type(tests[i].resource, media_type, &test_video_formats[j], FALSE); winetest_pop_context(); IMFMediaType_Release(media_type);
+ hr = IMFSourceReader_ReadSample(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, &flags, NULL, &sample); + ok(hr == S_OK, "Failed to read sample, hr %#x\n", hr); + IMFSample_Release(sample); + + hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &media_type); + ok(hr == S_OK, "Failed to get current mediatype, hr %#x.\n", hr); + winetest_push_context("actual video %u", j); + test_video_media_type(tests[i].resource, media_type, &test_video_formats[j], TRUE); + IMFSourceReader_Release(reader); IMFByteStream_Release(stream); }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mfreadwrite/tests/mfplat.c | 66 ++++++++++++++------- dlls/mfreadwrite/tests/resource.rc | 3 + dlls/mfreadwrite/tests/test-40x36-i420.avi | Bin 0 -> 66320 bytes 3 files changed, 48 insertions(+), 21 deletions(-) create mode 100644 dlls/mfreadwrite/tests/test-40x36-i420.avi
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index c24582c12b5..7715411f205 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -1347,7 +1347,7 @@ struct video_format UINT32 stride; };
-static void test_video_media_type(const char *resource_name, IMFMediaType *media_type, struct video_format *expect, BOOL actual) +static void test_video_media_type(const char *resource_name, IMFMediaType *media_type, struct video_format *expect, BOOL native, BOOL actual) { UINT32 uint32_value, buffer_value_size, width = expect->width, height = expect->height; BOOL is_h264 = IsEqualGUID(&expect->subtype, &MFVideoFormat_H264); @@ -1356,7 +1356,7 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media GUID guid_value; HRESULT hr;
- if (actual) + if (actual && !native) { width = (width + 0xf) & ~0xf; height = (height + 0xf) & ~0xf; @@ -1399,7 +1399,7 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media
uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_COMPRESSED, &uint32_value); - if (is_h264) todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_COMPRESSED, hr %#x\n", hr); + if (native) todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_COMPRESSED, hr %#x\n", hr); else { ok(hr == S_OK, "missing MF_MT_COMPRESSED, hr %#x\n", hr); @@ -1426,6 +1426,11 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media todo_wine ok(uint32_value == 1, "got MF_MT_SAMPLE_SIZE %u\n", uint32_value); } + else if (native && IsEqualGUID(&expect->subtype, &MFVideoFormat_I420)) + { + todo_wine + ok(uint32_value == width * height, "got MF_MT_SAMPLE_SIZE %u\n", uint32_value); + } else { todo_wine @@ -1439,7 +1444,7 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media
uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AVG_BIT_ERROR_RATE, &uint32_value); - if (is_h264) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AVG_BIT_ERROR_RATE, hr %#x\n", hr); + if (native) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AVG_BIT_ERROR_RATE, hr %#x\n", hr); else { todo_wine @@ -1450,10 +1455,14 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media
uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_AVG_BITRATE, &uint32_value); - todo_wine - ok(hr == S_OK, "missing MF_MT_AVG_BITRATE, hr %#x\n", hr); - todo_wine - ok(uint32_value == 78904, "got MF_MT_AVG_BITRATE %u\n", uint32_value); + if (native && !is_h264) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AVG_BITRATE, hr %#x\n", hr); + else + { + todo_wine + ok(hr == S_OK, "missing MF_MT_AVG_BITRATE, hr %#x\n", hr); + todo_wine + ok(uint32_value == 78904, "got MF_MT_AVG_BITRATE %u\n", uint32_value); + }
hr = IMFMediaType_GetUINT32(media_type, &MF_MT_CUSTOM_VIDEO_PRIMARIES, &uint32_value); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_CUSTOM_VIDEO_PRIMARIES, hr %#x\n", hr); @@ -1494,7 +1503,7 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media buffer_value_size = 0xdeadbeef; memset(buffer_value, 0xcd, sizeof(buffer_value)); hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (BYTE *)buffer_value, sizeof(buffer_value), &buffer_value_size); - if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_GEOMETRIC_APERTURE, hr %#x\n", hr); + if (!actual || native) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_GEOMETRIC_APERTURE, hr %#x\n", hr); else { todo_wine @@ -1515,8 +1524,17 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &uint32_value); todo_wine ok(hr == S_OK, "missing MF_MT_INTERLACE_MODE, hr %#x\n", hr); - todo_wine - ok(uint32_value == MFVideoInterlace_MixedInterlaceOrProgressive, "got MF_MT_INTERLACE_MODE %u\n", uint32_value); + if (native && IsEqualGUID(&expect->subtype, &MFVideoFormat_I420)) + { + todo_wine + ok(uint32_value == MFVideoInterlace_MixedInterlaceOrProgressive || + uint32_value == MFVideoInterlace_Progressive, "got MF_MT_INTERLACE_MODE %u\n", uint32_value); + } + else + { + todo_wine + ok(uint32_value == MFVideoInterlace_MixedInterlaceOrProgressive, "got MF_MT_INTERLACE_MODE %u\n", uint32_value); + }
hr = IMFMediaType_GetUINT32(media_type, &MF_MT_MAX_KEYFRAME_SPACING, &uint32_value); ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MAX_KEYFRAME_SPACING, hr %#x\n", hr); @@ -1524,7 +1542,7 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media buffer_value_size = 0xdeadbeef; memset(buffer_value, 0xcd, sizeof(buffer_value)); hr = IMFMediaType_GetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)buffer_value, sizeof(buffer_value), &buffer_value_size); - if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MINIMUM_DISPLAY_APERTURE, hr %#x\n", hr); + if (!actual || native) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_MINIMUM_DISPLAY_APERTURE, hr %#x\n", hr); else { todo_wine @@ -1590,7 +1608,7 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media buffer_value_size = 0xdeadbeef; memset(buffer_value, 0xcd, sizeof(buffer_value)); hr = IMFMediaType_GetBlob(media_type, &MF_MT_PAN_SCAN_APERTURE, (BYTE *)buffer_value, sizeof(buffer_value), &buffer_value_size); - if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PAN_SCAN_APERTURE, hr %#x\n", hr); + if (!actual || native) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_PAN_SCAN_APERTURE, hr %#x\n", hr); else { todo_wine @@ -1622,7 +1640,7 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media
uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_TRANSFER_FUNCTION, &uint32_value); - if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_TRANSFER_FUNCTION, hr %#x\n", hr); + if (!actual || native) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_TRANSFER_FUNCTION, hr %#x\n", hr); else { todo_wine @@ -1640,7 +1658,7 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media
uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_NOMINAL_RANGE, &uint32_value); - if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_NOMINAL_RANGE, hr %#x\n", hr); + if (!actual || native) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_NOMINAL_RANGE, hr %#x\n", hr); else { todo_wine @@ -1651,7 +1669,7 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media
uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_PRIMARIES, &uint32_value); - if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_PRIMARIES, hr %#x\n", hr); + if (!actual || native) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_VIDEO_PRIMARIES, hr %#x\n", hr); else { todo_wine @@ -1667,7 +1685,7 @@ static void test_video_media_type(const char *resource_name, IMFMediaType *media
uint32_value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(media_type, &MF_MT_YUV_MATRIX, &uint32_value); - if (!actual) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_YUV_MATRIX, hr %#x\n", hr); + if (!actual || native) ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_YUV_MATRIX, hr %#x\n", hr); else { todo_wine @@ -1704,6 +1722,9 @@ static void test_media_types(void) {.resource = "test-40x36-h264.mp4", .has_video = TRUE, .video_format = {.subtype = MFVideoFormat_H264, .width = 40, .height = 36} }, + {.resource = "test-40x36-i420.avi", .has_video = TRUE, .video_format = + {.subtype = MFVideoFormat_I420, .width = 40, .height = 36} + }, };
struct audio_format test_audio_formats[] = @@ -1827,7 +1848,7 @@ static void test_media_types(void) hr = IMFSourceReader_GetNativeMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &media_type); ok(hr == S_OK, "Failed to get native mediatype, hr %#x.\n", hr); winetest_push_context("native video"); - test_video_media_type(tests[i].resource, media_type, &tests[i].video_format, FALSE); + test_video_media_type(tests[i].resource, media_type, &tests[i].video_format, TRUE, FALSE); IMFMediaType_Release(media_type); winetest_pop_context();
@@ -1846,13 +1867,15 @@ static void test_media_types(void) hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &test_video_formats[j].subtype); ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); hr = IMFSourceReader_SetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, media_type); - ok(hr == S_OK, "Failed setting current media type %u, hr %#x.\n", j, hr); + ok(hr == S_OK || hr == MF_E_TOPO_CODEC_NOT_FOUND, "Failed setting current media type %u, hr %#x.\n", j, hr); IMFMediaType_Release(media_type); + if (hr != S_OK) continue;
hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &media_type); ok(hr == S_OK, "Failed to get current mediatype, hr %#x.\n", hr); winetest_push_context("current video %u", j); - test_video_media_type(tests[i].resource, media_type, &test_video_formats[j], FALSE); + test_video_media_type(tests[i].resource, media_type, &test_video_formats[j], + IsEqualGUID(&tests[i].video_format.subtype, &test_video_formats[j].subtype), FALSE); winetest_pop_context(); IMFMediaType_Release(media_type);
@@ -1863,7 +1886,8 @@ static void test_media_types(void) hr = IMFSourceReader_GetCurrentMediaType(reader, MF_SOURCE_READER_FIRST_VIDEO_STREAM, &media_type); ok(hr == S_OK, "Failed to get current mediatype, hr %#x.\n", hr); winetest_push_context("actual video %u", j); - test_video_media_type(tests[i].resource, media_type, &test_video_formats[j], TRUE); + test_video_media_type(tests[i].resource, media_type, &test_video_formats[j], + IsEqualGUID(&tests[i].video_format.subtype, &test_video_formats[j].subtype), TRUE);
IMFSourceReader_Release(reader); IMFByteStream_Release(stream); diff --git a/dlls/mfreadwrite/tests/resource.rc b/dlls/mfreadwrite/tests/resource.rc index 5ae9636d671..3f32c2abc30 100644 --- a/dlls/mfreadwrite/tests/resource.rc +++ b/dlls/mfreadwrite/tests/resource.rc @@ -26,3 +26,6 @@ test-48000.wav RCDATA test-48000.wav
/* @makedep: test-40x36-h264.mp4 */ test-40x36-h264.mp4 RCDATA test-40x36-h264.mp4 + +/* @makedep: test-40x36-i420.avi */ +test-40x36-i420.avi RCDATA test-40x36-i420.avi diff --git a/dlls/mfreadwrite/tests/test-40x36-i420.avi b/dlls/mfreadwrite/tests/test-40x36-i420.avi new file mode 100644 index 0000000000000000000000000000000000000000..fde02cb07c7fffe8c4fadcd69addbb066a67e86f GIT binary patch literal 66320 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 WqD`Gsv>z`j+V-CnZQk#z_Wu9`QWzTm
literal 0 HcmV?d00001
On 10/28/21 5:01 PM, Rémi Bernon wrote:
+struct audio_format +{
- GUID subtype;
- UINT32 bits;
- UINT32 rate;
+};
+static void test_audio_media_type(const char *resource_name, IMFMediaType *media_type, struct audio_format *expect) +{
- UINT32 uint32_value, buffer_value_size;
- BYTE buffer_value[512];
- double double_value;
- GUID guid_value;
- HRESULT hr;
- memset(&guid_value, 0xcd, sizeof(guid_value));
- hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid_value);
- ok(hr == S_OK, "missing MF_MT_MAJOR_TYPE, hr %#x\n", hr);
- ok(IsEqualGUID(&guid_value, &MFMediaType_Audio), "got MF_MT_MAJOR_TYPE %s\n", debugstr_guid(&guid_value));
- memset(&guid_value, 0xcd, sizeof(guid_value));
- hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid_value);
- ok(hr == S_OK, "missing MF_MT_SUBTYPE, hr %#x\n", hr);
- ok(IsEqualGUID(&guid_value, &expect->subtype), "got MF_MT_SUBTYPE %s\n", debugstr_guid(&guid_value));
- uint32_value = 0xdeadbeef;
- hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &uint32_value);
- ok(hr == S_OK, "missing MF_MT_ALL_SAMPLES_INDEPENDENT, hr %#x\n", hr);
- ok(uint32_value == 1, "got MF_MT_ALL_SAMPLES_INDEPENDENT %u\n", uint32_value);
- hr = IMFMediaType_GetGUID(media_type, &MF_MT_AM_FORMAT_TYPE, &guid_value);
- ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_AM_FORMAT_TYPE, hr %#x\n", hr);
- hr = IMFMediaType_GetUINT32(media_type, &MF_MT_COMPRESSED, &uint32_value);
- ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_COMPRESSED, hr %#x\n", hr);
- hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &uint32_value);
- ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_FIXED_SIZE_SAMPLES, hr %#x\n", hr);
- hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &uint32_value);
- ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_SAMPLE_SIZE, hr %#x\n", hr);
- hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA, buffer_value, sizeof(buffer_value), &buffer_value_size);
- ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_USER_DATA, hr %#x\n", hr);
- hr = IMFMediaType_GetBlob(media_type, &MF_MT_WRAPPED_TYPE, buffer_value, sizeof(buffer_value), &buffer_value_size);
- ok(hr == MF_E_ATTRIBUTENOTFOUND, "got MF_MT_WRAPPED_TYPE, hr %#x\n", hr);
Is it possible to test attribute count instead, and then all attributes up to this count? Instead of testing what type doesn't have set.