[PATCH] mfplat: Initial support for WAVE_FORMAT_EXTENSIBLE in MFInitMediaTypeFromWaveFormatEx().

Nikolay Sivov nsivov at codeweavers.com
Thu Apr 9 07:33:40 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 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




More information about the wine-devel mailing list