[PATCH] mfplat: Fix alignment used by audio buffers created with MFCreateMediaBufferFromMediaType().

Nikolay Sivov nsivov at codeweavers.com
Mon Apr 11 03:44:35 CDT 2022


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfplat/buffer.c       |  6 ++---
 dlls/mfplat/tests/mfplat.c | 54 +++++++++++++++++++++++++++++++-------
 2 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c
index 8ea2283e24b..eada3df18ad 100644
--- a/dlls/mfplat/buffer.c
+++ b/dlls/mfplat/buffer.c
@@ -1596,6 +1596,8 @@ HRESULT WINAPI MFCreateMediaBufferFromMediaType(IMFMediaType *media_type, LONGLO
         if (FAILED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_alignment)))
             WARN("Block alignment was not specified.\n");
 
+        alignment = max(16, alignment);
+
         if (block_alignment)
         {
             avg_length = 0;
@@ -1610,8 +1612,6 @@ HRESULT WINAPI MFCreateMediaBufferFromMediaType(IMFMediaType *media_type, LONGLO
                 }
             }
 
-            alignment = max(16, alignment);
-
             length = buffer_get_aligned_length(avg_length + 1, alignment);
             length = buffer_get_aligned_length(length, block_alignment);
         }
@@ -1620,7 +1620,7 @@ HRESULT WINAPI MFCreateMediaBufferFromMediaType(IMFMediaType *media_type, LONGLO
 
         length = max(length, min_length);
 
-        return create_1d_buffer(length, MF_1_BYTE_ALIGNMENT, buffer);
+        return create_1d_buffer(length, alignment - 1, buffer);
     }
     else
         FIXME("Major type %s is not supported.\n", debugstr_guid(&major));
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 16d24bbff51..8d21f2ed60e 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -6057,18 +6057,21 @@ static void test_MFCreateMediaBufferFromMediaType(void)
         unsigned int buffer_length;
     } audio_tests[] =
     {
-        { 0,  0,  0,  4,  0, 20 },
-        { 0, 16,  0,  4,  0, 20 },
-        { 0,  0, 32,  4,  0, 36 },
-        { 0, 64, 32,  4,  0, 64 },
-        { 1,  0,  0,  4, 16, 36 },
-        { 2,  0,  0,  4, 16, 52 },
+        { 0,  0,   0,  4,  0, 20 },
+        { 0, 16,   0,  4,  0, 20 },
+        { 0,  0,  32,  4,  0, 36 },
+        { 0, 64,  32,  4,  0, 64 },
+        { 1,  0,   0,  4, 16, 36 },
+        { 2,  0,   0,  4, 16, 52 },
+        { 2,  0,  64,  4, 16, 68 },
+        { 2,  0, 128,  4, 16,132 },
     };
+    IMFMediaType *media_type, *media_type2;
+    unsigned int i, alignment;
     IMFMediaBuffer *buffer;
-    DWORD length;
+    DWORD length, max;
+    BYTE *data;
     HRESULT hr;
-    IMFMediaType *media_type;
-    unsigned int i;
 
     if (!pMFCreateMediaBufferFromMediaType)
     {
@@ -6082,9 +6085,15 @@ static void test_MFCreateMediaBufferFromMediaType(void)
     hr = MFCreateMediaType(&media_type);
     ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
 
+    hr = MFCreateMediaType(&media_type2);
+    ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
+
     hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
     ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
 
+    hr = IMFMediaType_CopyAllItems(media_type, (IMFAttributes *)media_type2);
+    ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
     for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
     {
         const struct audio_buffer_test *ptr = &audio_tests[i];
@@ -6107,10 +6116,37 @@ static void test_MFCreateMediaBufferFromMediaType(void)
         ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
         ok(ptr->buffer_length == length, "%d: unexpected buffer length %lu, expected %u.\n", i, length, ptr->buffer_length);
 
+        alignment = ptr->min_alignment ? ptr->min_alignment - 1 : MF_16_BYTE_ALIGNMENT;
+        hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
+        ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
+        ok(ptr->buffer_length == max && !length, "Unexpected length.\n");
+        ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
+        hr = IMFMediaBuffer_Unlock(buffer);
+        ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
+
+        IMFMediaBuffer_Release(buffer);
+
+        /* Only major type is set. */
+        hr = pMFCreateMediaBufferFromMediaType(media_type2, ptr->duration * 10000000, ptr->min_length,
+                ptr->min_alignment, &buffer);
+        ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+        hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
+        ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
+        ok(ptr->min_length == length, "%u: unexpected buffer length %lu, expected %u.\n", i, length, ptr->min_length);
+
+        hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
+        ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
+        ok(ptr->min_length == max && !length, "Unexpected length.\n");
+        ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
+        hr = IMFMediaBuffer_Unlock(buffer);
+        ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
+
         IMFMediaBuffer_Release(buffer);
     }
 
     IMFMediaType_Release(media_type);
+    IMFMediaType_Release(media_type2);
 }
 
 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
-- 
2.35.1




More information about the wine-devel mailing list