From: Nikolay Sivov Subject: [PATCH] mfplat: Initial support for WAVE_FORMAT_EXTENSIBLE in MFInitMediaTypeFromWaveFormatEx(). Message-Id: <20200409123340.709634-1-nsivov@codeweavers.com> Date: Thu, 9 Apr 2020 15:33:40 +0300 Signed-off-by: Nikolay Sivov --- dlls/mfplat/mediatype.c | 58 +++++++++-------- dlls/mfplat/tests/mfplat.c | 127 +++++++++++++++++++++++++++---------- 2 files changed, 125 insertions(+), 60 deletions(-) diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index b832e00bdd..ddbffd5441 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -2107,6 +2107,7 @@ static void mediatype_set_guid(IMFMediaType *mediatype, const GUID *attr, const */ HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size) { + const WAVEFORMATEXTENSIBLE *wfex = (const WAVEFORMATEXTENSIBLE *)format; GUID subtype; HRESULT hr; @@ -2115,47 +2116,54 @@ HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WA if (!mediatype || !format) return E_POINTER; + if (format->cbSize && format->cbSize < sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)) + return E_INVALIDARG; + + if (format->cbSize + sizeof(*format) > size) + return E_INVALIDARG; + + hr = IMFMediaType_DeleteAllItems(mediatype); + + mediatype_set_guid(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio, &hr); + if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - FIXME("WAVE_FORMAT_EXTENSIBLE is not supported.\n"); - return E_NOTIMPL; + mediatype_set_guid(mediatype, &MF_MT_SUBTYPE, &wfex->SubFormat, &hr); + + if (wfex->dwChannelMask) + mediatype_set_uint32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, wfex->dwChannelMask, &hr); + + if (format->wBitsPerSample && wfex->Samples.wValidBitsPerSample) + mediatype_set_uint32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, wfex->Samples.wValidBitsPerSample, &hr); } else { - hr = IMFMediaType_DeleteAllItems(mediatype); - - mediatype_set_guid(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio, &hr); - memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype)); subtype.Data1 = format->wFormatTag; mediatype_set_guid(mediatype, &MF_MT_SUBTYPE, &subtype, &hr); - if (format->nChannels) - mediatype_set_uint32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, format->nChannels, &hr); + mediatype_set_uint32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1, &hr); + } - if (format->nSamplesPerSec) - mediatype_set_uint32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, format->nSamplesPerSec, &hr); + if (format->nChannels) + mediatype_set_uint32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, format->nChannels, &hr); - if (format->nAvgBytesPerSec) - mediatype_set_uint32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, format->nAvgBytesPerSec, &hr); + if (format->nSamplesPerSec) + mediatype_set_uint32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, format->nSamplesPerSec, &hr); - if (format->nBlockAlign) - mediatype_set_uint32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, format->nBlockAlign, &hr); + if (format->nAvgBytesPerSec) + mediatype_set_uint32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, format->nAvgBytesPerSec, &hr); - if (format->wBitsPerSample) - mediatype_set_uint32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, format->wBitsPerSample, &hr); + if (format->nBlockAlign) + mediatype_set_uint32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, format->nBlockAlign, &hr); - mediatype_set_uint32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1, &hr); - } + if (format->wBitsPerSample) + mediatype_set_uint32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, format->wBitsPerSample, &hr); - switch (subtype.Data1) + if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) || + IsEqualGUID(&subtype, &MFAudioFormat_Float)) { - case WAVE_FORMAT_PCM: - case WAVE_FORMAT_IEEE_FLOAT: - mediatype_set_uint32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1, &hr); - break; - default: - FIXME("Unhandled type %d.\n", subtype.Data1); + mediatype_set_uint32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1, &hr); } return hr; diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index d9fbff570f..007db891c1 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -42,6 +42,8 @@ #include "initguid.h" #include "d3d11_4.h" #include "d3d9types.h" +#include "ks.h" +#include "ksmedia.h" DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19); DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21); @@ -5099,56 +5101,79 @@ static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *for if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - } - else - { - memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype)); - subtype.Data1 = format->wFormatTag; - ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid)); + const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format; + ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid)); - if (format->nChannels) + if (fex->dwChannelMask) { - hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value); + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value); ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); - ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value); + ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value); } - if (format->nSamplesPerSec) + if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample) { - hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value); + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value); ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); - ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value); + ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value); } + } + else + { + memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype)); + subtype.Data1 = format->wFormatTag; + ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid)); - if (format->nAvgBytesPerSec) - { - hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value); - ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); - ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value); - } + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value); + ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); + ok(value, "Unexpected value.\n"); + } - if (format->nBlockAlign) - { - hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value); - ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); - ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value); - } + if (format->nChannels) + { + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value); + ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); + ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value); + } - if (format->wBitsPerSample) - { - hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value); - ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); - ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value); - } + if (format->nSamplesPerSec) + { + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value); + ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); + ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value); + } - hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value); + if (format->nAvgBytesPerSec) + { + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value); ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); - ok(value, "Unexpected value.\n"); + ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value); + } + + if (format->nBlockAlign) + { + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value); + ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); + ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value); + } + + if (format->wBitsPerSample) + { + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value); + ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); + ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value); } /* Only set for uncompressed formats. */ - if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value))) + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value); + if (IsEqualGUID(&guid, &MFAudioFormat_Float) || + IsEqualGUID(&guid, &MFAudioFormat_PCM)) + { + ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n"); + } + else + ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n"); } static void test_MFInitMediaTypeFromWaveFormatEx(void) @@ -5159,9 +5184,29 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 }, { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 }, { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 }, + { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 }, { 1234, 0, 0, 0, 0, 0 }, - { WAVE_FORMAT_MPEGLAYER3, 0, 0, 0, 0, 0 }, + { WAVE_FORMAT_ALAW }, + { WAVE_FORMAT_CREATIVE_ADPCM }, + { WAVE_FORMAT_MPEGLAYER3 }, + { WAVE_FORMAT_MPEG_ADTS_AAC }, + { WAVE_FORMAT_ALAC }, + { WAVE_FORMAT_AMR_NB }, + { WAVE_FORMAT_AMR_WB }, + { WAVE_FORMAT_AMR_WP }, + { WAVE_FORMAT_DOLBY_AC3_SPDIF }, + { WAVE_FORMAT_DRM }, + { WAVE_FORMAT_DTS }, + { WAVE_FORMAT_FLAC }, + { WAVE_FORMAT_MPEG }, + { WAVE_FORMAT_WMAVOICE9 }, + { WAVE_FORMAT_OPUS }, + { WAVE_FORMAT_WMAUDIO2 }, + { WAVE_FORMAT_WMAUDIO3 }, + { WAVE_FORMAT_WMAUDIO_LOSSLESS }, + { WAVE_FORMAT_WMASPDIF }, }; + WAVEFORMATEXTENSIBLE waveformatext; IMFMediaType *mediatype; unsigned int i; HRESULT hr; @@ -5172,9 +5217,21 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i) { hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i])); - ok(hr == S_OK, "Failed to initialize media type, hr %#x.\n", hr); + ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#x.\n", i, waveformatex_tests[i].wFormatTag, hr); validate_media_type(mediatype, &waveformatex_tests[i]); + + waveformatext.Format = waveformatex_tests[i]; + waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format); + waveformatext.Samples.wSamplesPerBlock = 123; + waveformatext.dwChannelMask = 0x8; + memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat)); + waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag; + hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext)); + ok(hr == S_OK, "Failed to initialize media type, hr %#x.\n", hr); + + validate_media_type(mediatype, &waveformatext.Format); } IMFMediaType_Release(mediatype); -- 2.25.1