Commit 0ecde550 authored by Giovanni Mascellani's avatar Giovanni Mascellani Committed by Alexandre Julliard

mfplat: Properly align system memory buffers.

parent 288a1024
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#define COBJMACROS #define COBJMACROS
#include <malloc.h>
#include "mfplat_private.h" #include "mfplat_private.h"
#include "rtworkq.h" #include "rtworkq.h"
...@@ -171,7 +173,7 @@ static ULONG WINAPI memory_buffer_Release(IMFMediaBuffer *iface) ...@@ -171,7 +173,7 @@ static ULONG WINAPI memory_buffer_Release(IMFMediaBuffer *iface)
} }
DeleteCriticalSection(&buffer->cs); DeleteCriticalSection(&buffer->cs);
free(buffer->_2d.linear_buffer); free(buffer->_2d.linear_buffer);
free(buffer->data); _aligned_free(buffer->data);
free(buffer); free(buffer);
} }
...@@ -1254,8 +1256,26 @@ static const IMFDXGIBufferVtbl dxgi_buffer_vtbl = ...@@ -1254,8 +1256,26 @@ static const IMFDXGIBufferVtbl dxgi_buffer_vtbl =
static HRESULT memory_buffer_init(struct buffer *buffer, DWORD max_length, DWORD alignment, static HRESULT memory_buffer_init(struct buffer *buffer, DWORD max_length, DWORD alignment,
const IMFMediaBufferVtbl *vtbl) const IMFMediaBufferVtbl *vtbl)
{ {
if (!(buffer->data = calloc(1, ALIGN_SIZE(max_length, alignment)))) size_t size;
if (!alignment) alignment = MF_64_BYTE_ALIGNMENT;
alignment++;
if (alignment & (alignment - 1))
{
alignment--;
alignment |= alignment >> 1;
alignment |= alignment >> 2;
alignment |= alignment >> 4;
alignment |= alignment >> 8;
alignment |= alignment >> 16;
alignment++;
}
size = ALIGN_SIZE(max_length, alignment - 1);
if (!(buffer->data = _aligned_malloc(size, alignment)))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
memset(buffer->data, 0, size);
buffer->IMFMediaBuffer_iface.lpVtbl = vtbl; buffer->IMFMediaBuffer_iface.lpVtbl = vtbl;
buffer->refcount = 1; buffer->refcount = 1;
......
...@@ -2287,8 +2287,25 @@ static void test_system_memory_buffer(void) ...@@ -2287,8 +2287,25 @@ static void test_system_memory_buffer(void)
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
IMFMediaBuffer_Release(buffer); IMFMediaBuffer_Release(buffer);
}
static void test_system_memory_aligned_buffer(void)
{
static const DWORD alignments[] =
{
MF_16_BYTE_ALIGNMENT,
MF_32_BYTE_ALIGNMENT,
MF_64_BYTE_ALIGNMENT,
MF_128_BYTE_ALIGNMENT,
MF_256_BYTE_ALIGNMENT,
MF_512_BYTE_ALIGNMENT,
};
IMFMediaBuffer *buffer;
DWORD length, max;
unsigned int i;
BYTE *data;
HRESULT hr;
/* Aligned buffer. */
hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL); hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL);
ok(FAILED(hr), "Unexpected hr %#lx.\n", hr); ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
...@@ -2324,6 +2341,25 @@ static void test_system_memory_buffer(void) ...@@ -2324,6 +2341,25 @@ static void test_system_memory_buffer(void)
ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr); ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
IMFMediaBuffer_Release(buffer); IMFMediaBuffer_Release(buffer);
for (i = 0; i < ARRAY_SIZE(alignments); ++i)
{
hr = MFCreateAlignedMemoryBuffer(200, alignments[i], &buffer);
ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
ok(max == 200 && !length, "Unexpected length.\n");
ok(!((uintptr_t)data & alignments[i]), "Data at %p is misaligned.\n", data);
hr = IMFMediaBuffer_Unlock(buffer);
ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
IMFMediaBuffer_Release(buffer);
}
hr = MFCreateAlignedMemoryBuffer(200, 0, &buffer);
ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
IMFMediaBuffer_Release(buffer);
} }
static void test_sample(void) static void test_sample(void)
...@@ -7980,6 +8016,7 @@ START_TEST(mfplat) ...@@ -7980,6 +8016,7 @@ START_TEST(mfplat)
test_file_stream(); test_file_stream();
test_MFCreateMFByteStreamOnStream(); test_MFCreateMFByteStreamOnStream();
test_system_memory_buffer(); test_system_memory_buffer();
test_system_memory_aligned_buffer();
test_source_resolver(); test_source_resolver();
test_MFCreateAsyncResult(); test_MFCreateAsyncResult();
test_allocate_queue(); test_allocate_queue();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment