[PATCH 7/7] mfplat: Partially implement MFInitMediaTypeFromWaveFormatEx().

Nikolay Sivov nsivov at codeweavers.com
Wed Apr 8 09:21:28 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfplat/mediatype.c    | 71 ++++++++++++++++++++++++++++
 dlls/mfplat/mfplat.spec    |  2 +-
 dlls/mfplat/tests/mfplat.c | 97 ++++++++++++++++++++++++++++++++++++++
 include/mfapi.h            |  1 +
 4 files changed, 170 insertions(+), 1 deletion(-)

diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c
index 196d803722..b832e00bdd 100644
--- a/dlls/mfplat/mediatype.c
+++ b/dlls/mfplat/mediatype.c
@@ -2089,3 +2089,74 @@ HRESULT WINAPI MFCreateWaveFormatExFromMFMediaType(IMFMediaType *mediatype, WAVE
 
     return S_OK;
 }
+
+static void mediatype_set_uint32(IMFMediaType *mediatype, const GUID *attr, unsigned int value, HRESULT *hr)
+{
+    if (SUCCEEDED(*hr))
+        *hr = IMFMediaType_SetUINT32(mediatype, attr, value);
+}
+
+static void mediatype_set_guid(IMFMediaType *mediatype, const GUID *attr, const GUID *value, HRESULT *hr)
+{
+    if (SUCCEEDED(*hr))
+        *hr = IMFMediaType_SetGUID(mediatype, attr, value);
+}
+
+/***********************************************************************
+ *      MFInitMediaTypeFromWaveFormatEx (mfplat.@)
+ */
+HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size)
+{
+    GUID subtype;
+    HRESULT hr;
+
+    TRACE("%p, %p, %u.\n", mediatype, format, size);
+
+    if (!mediatype || !format)
+        return E_POINTER;
+
+    if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+    {
+        FIXME("WAVE_FORMAT_EXTENSIBLE is not supported.\n");
+        return E_NOTIMPL;
+    }
+    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);
+
+        if (format->nSamplesPerSec)
+            mediatype_set_uint32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, format->nSamplesPerSec, &hr);
+
+        if (format->nAvgBytesPerSec)
+            mediatype_set_uint32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, format->nAvgBytesPerSec, &hr);
+
+        if (format->nBlockAlign)
+            mediatype_set_uint32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, format->nBlockAlign, &hr);
+
+        if (format->wBitsPerSample)
+            mediatype_set_uint32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, format->wBitsPerSample, &hr);
+
+        mediatype_set_uint32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1, &hr);
+    }
+
+    switch (subtype.Data1)
+    {
+        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);
+    }
+
+    return hr;
+}
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
index 25e5f62f21..a1833312fc 100644
--- a/dlls/mfplat/mfplat.spec
+++ b/dlls/mfplat/mfplat.spec
@@ -121,7 +121,7 @@
 @ stub MFInitMediaTypeFromMPEG2VideoInfo
 @ stub MFInitMediaTypeFromVideoInfoHeader2
 @ stub MFInitMediaTypeFromVideoInfoHeader
-@ stub MFInitMediaTypeFromWaveFormatEx
+@ stdcall MFInitMediaTypeFromWaveFormatEx(ptr ptr long)
 @ stub MFInitVideoFormat
 @ stub MFInitVideoFormat_RGB
 @ stdcall MFInvokeCallback(ptr)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 78d73b7580..d9fbff570f 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -5084,6 +5084,102 @@ static void test_MFCreateMediaBufferFromMediaType(void)
     IMFMediaType_Release(media_type);
 }
 
+static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
+{
+    GUID guid, subtype;
+    UINT32 value;
+    HRESULT hr;
+
+    hr = IMFMediaType_GetMajorType(mediatype, &guid);
+    ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
+    ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
+
+    hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
+    ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
+
+    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));
+
+        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->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);
+        }
+
+        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);
+        }
+
+        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);
+        }
+
+        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");
+    }
+
+    /* Only set for uncompressed formats. */
+    if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value)))
+        ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
+}
+
+static void test_MFInitMediaTypeFromWaveFormatEx(void)
+{
+    static const WAVEFORMATEX waveformatex_tests[] =
+    {
+        { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
+        { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
+        { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
+        { WAVE_FORMAT_PCM, 0,     0, 0, 0, 0 },
+        { 1234, 0,     0, 0, 0, 0 },
+        { WAVE_FORMAT_MPEGLAYER3, 0, 0, 0, 0, 0 },
+    };
+    IMFMediaType *mediatype;
+    unsigned int i;
+    HRESULT hr;
+
+    hr = MFCreateMediaType(&mediatype);
+    ok(hr == S_OK, "Failed to create mediatype, hr %#x.\n", hr);
+
+    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);
+
+        validate_media_type(mediatype, &waveformatex_tests[i]);
+    }
+
+    IMFMediaType_Release(mediatype);
+}
+
 START_TEST(mfplat)
 {
     char **argv;
@@ -5138,6 +5234,7 @@ START_TEST(mfplat)
     test_MFGetStrideForBitmapInfoHeader();
     test_MFCreate2DMediaBuffer();
     test_MFCreateMediaBufferFromMediaType();
+    test_MFInitMediaTypeFromWaveFormatEx();
 
     CoUninitialize();
 }
diff --git a/include/mfapi.h b/include/mfapi.h
index b9383630ab..c8ae665b10 100644
--- a/include/mfapi.h
+++ b/include/mfapi.h
@@ -532,6 +532,7 @@ HRESULT WINAPI MFTEnumEx(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_IN
                          const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate,
                          UINT32 *pcount);
 HRESULT WINAPI MFInitAttributesFromBlob(IMFAttributes *attributes, const UINT8 *buffer, UINT size);
+HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size);
 HRESULT WINAPI MFInvokeCallback(IMFAsyncResult *result);
 HRESULT WINAPI MFLockPlatform(void);
 HRESULT WINAPI MFPutWorkItem(DWORD queue, IMFAsyncCallback *callback, IUnknown *state);
-- 
2.25.1




More information about the wine-devel mailing list