[PATCH 3/5] mfplat: Move buffer implementation to separate file.

Nikolay Sivov nsivov at codeweavers.com
Tue Mar 5 01:49:40 CST 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfplat/Makefile.in    |   1 +
 dlls/mfplat/buffer.c       | 216 +++++++++++++++++++++++++++++++++++++
 dlls/mfplat/main.c         | 174 ------------------------------
 dlls/mfplat/mfplat.spec    |   2 +-
 dlls/mfplat/tests/mfplat.c |  52 ++++++---
 include/mfapi.h            |  16 +++
 6 files changed, 273 insertions(+), 188 deletions(-)
 create mode 100644 dlls/mfplat/buffer.c

diff --git a/dlls/mfplat/Makefile.in b/dlls/mfplat/Makefile.in
index 261c121cab..a117ede271 100644
--- a/dlls/mfplat/Makefile.in
+++ b/dlls/mfplat/Makefile.in
@@ -3,6 +3,7 @@ IMPORTLIB = mfplat
 IMPORTS   = advapi32 ole32
 
 C_SRCS = \
+	buffer.c \
 	main.c \
 	mediatype.c \
 	queue.c
diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c
new file mode 100644
index 0000000000..e206b356dc
--- /dev/null
+++ b/dlls/mfplat/buffer.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2018 Alistair Leslie-Hughes
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+
+#include "mfplat_private.h"
+
+#include "wine/debug.h"
+#include "wine/heap.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+
+struct memory_buffer
+{
+    IMFMediaBuffer IMFMediaBuffer_iface;
+    LONG refcount;
+
+    BYTE *data;
+    DWORD max_length;
+    DWORD current_length;
+};
+
+static inline struct memory_buffer *impl_from_IMFMediaBuffer(IMFMediaBuffer *iface)
+{
+    return CONTAINING_RECORD(iface, struct memory_buffer, IMFMediaBuffer_iface);
+}
+
+static HRESULT WINAPI memory_buffer_QueryInterface(IMFMediaBuffer *iface, REFIID riid, void **out)
+{
+    struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface);
+
+    TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
+
+    if (IsEqualIID(riid, &IID_IMFMediaBuffer) ||
+            IsEqualIID(riid, &IID_IUnknown))
+    {
+        *out = &buffer->IMFMediaBuffer_iface;
+    }
+    else
+    {
+        FIXME("(%s, %p)\n", debugstr_guid(riid), out);
+        *out = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*out);
+    return S_OK;
+}
+
+static ULONG WINAPI memory_buffer_AddRef(IMFMediaBuffer *iface)
+{
+    struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface);
+    ULONG refcount = InterlockedIncrement(&buffer->refcount);
+
+    TRACE("%p, refcount %u.\n", buffer, refcount);
+
+    return refcount;
+}
+
+static ULONG WINAPI memory_buffer_Release(IMFMediaBuffer *iface)
+{
+    struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface);
+    ULONG refcount = InterlockedDecrement(&buffer->refcount);
+
+    TRACE("%p, refcount %u.\n", iface, refcount);
+
+    if (!refcount)
+    {
+        heap_free(buffer->data);
+        heap_free(buffer);
+    }
+
+    return refcount;
+}
+
+static HRESULT WINAPI memory_buffer_Lock(IMFMediaBuffer *iface, BYTE **data, DWORD *max_length, DWORD *current_length)
+{
+    struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface);
+
+    TRACE("%p, %p %p, %p.\n", iface, data, max_length, current_length);
+
+    if (!data)
+        return E_INVALIDARG;
+
+    *data = buffer->data;
+    if (max_length)
+        *max_length = buffer->max_length;
+    if (current_length)
+        *current_length = buffer->current_length;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI memory_buffer_Unlock(IMFMediaBuffer *iface)
+{
+    TRACE("%p.\n", iface);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI memory_buffer_GetCurrentLength(IMFMediaBuffer *iface, DWORD *current_length)
+{
+    struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface);
+
+    TRACE("%p.\n", iface);
+
+    if (!current_length)
+        return E_INVALIDARG;
+
+    *current_length = buffer->current_length;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI memory_buffer_SetCurrentLength(IMFMediaBuffer *iface, DWORD current_length)
+{
+    struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface);
+
+    TRACE("%p, %u.\n", iface, current_length);
+
+    if (current_length > buffer->max_length)
+        return E_INVALIDARG;
+
+    buffer->current_length = current_length;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI memory_buffer_GetMaxLength(IMFMediaBuffer *iface, DWORD *max_length)
+{
+    struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface);
+
+    TRACE("%p, %p.\n", iface, max_length);
+
+    if (!max_length)
+        return E_INVALIDARG;
+
+    *max_length = buffer->max_length;
+
+    return S_OK;
+}
+
+static const IMFMediaBufferVtbl memorybuffervtbl =
+{
+    memory_buffer_QueryInterface,
+    memory_buffer_AddRef,
+    memory_buffer_Release,
+    memory_buffer_Lock,
+    memory_buffer_Unlock,
+    memory_buffer_GetCurrentLength,
+    memory_buffer_SetCurrentLength,
+    memory_buffer_GetMaxLength,
+};
+
+static HRESULT create_memory_buffer(DWORD max_length, DWORD alignment, IMFMediaBuffer **buffer)
+{
+    struct memory_buffer *object;
+
+    if (!buffer)
+        return E_INVALIDARG;
+
+    object = heap_alloc(sizeof(*object));
+    if (!object)
+        return E_OUTOFMEMORY;
+
+    object->data = heap_alloc((max_length + alignment) & ~alignment);
+    if (!object->data)
+    {
+        heap_free(object);
+        return E_OUTOFMEMORY;
+    }
+
+    object->IMFMediaBuffer_iface.lpVtbl = &memorybuffervtbl;
+    object->refcount = 1;
+    object->max_length = max_length;
+    object->current_length = 0;
+
+    *buffer = &object->IMFMediaBuffer_iface;
+
+    return S_OK;
+}
+
+/***********************************************************************
+ *      MFCreateMemoryBuffer (mfplat.@)
+ */
+HRESULT WINAPI MFCreateMemoryBuffer(DWORD max_length, IMFMediaBuffer **buffer)
+{
+    TRACE("%u, %p.\n", max_length, buffer);
+
+    return create_memory_buffer(max_length, MF_1_BYTE_ALIGNMENT, buffer);
+}
+
+/***********************************************************************
+ *      MFCreateAlignedMemoryBuffer (mfplat.@)
+ */
+HRESULT WINAPI MFCreateAlignedMemoryBuffer(DWORD max_length, DWORD alignment, IMFMediaBuffer **buffer)
+{
+    TRACE("%u, %u, %p.\n", max_length, alignment, buffer);
+
+    return create_memory_buffer(max_length, alignment, buffer);
+}
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index 2217f3fb94..57943cf115 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -2798,180 +2798,6 @@ HRESULT WINAPI MFCreateEventQueue(IMFMediaEventQueue **queue)
     return S_OK;
 }
 
-typedef struct _mfbuffer
-{
-    IMFMediaBuffer IMFMediaBuffer_iface;
-    LONG ref;
-
-    BYTE *buffer;
-    DWORD max_length;
-    DWORD current;
-} mfbuffer;
-
-static inline mfbuffer *impl_from_IMFMediaBuffer(IMFMediaBuffer *iface)
-{
-    return CONTAINING_RECORD(iface, mfbuffer, IMFMediaBuffer_iface);
-}
-
-static HRESULT WINAPI mfbuffer_QueryInterface(IMFMediaBuffer *iface, REFIID riid, void **out)
-{
-    mfbuffer *This = impl_from_IMFMediaBuffer(iface);
-
-    TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), out);
-
-    if(IsEqualGUID(riid, &IID_IUnknown) ||
-       IsEqualGUID(riid, &IID_IMFMediaBuffer))
-    {
-        *out = &This->IMFMediaBuffer_iface;
-    }
-    else
-    {
-        FIXME("(%s, %p)\n", debugstr_guid(riid), out);
-        *out = NULL;
-        return E_NOINTERFACE;
-    }
-
-    IUnknown_AddRef((IUnknown*)*out);
-    return S_OK;
-}
-
-static ULONG WINAPI mfbuffer_AddRef(IMFMediaBuffer *iface)
-{
-    mfbuffer *This = impl_from_IMFMediaBuffer(iface);
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p) ref=%u\n", This, ref);
-
-    return ref;
-}
-
-static ULONG WINAPI mfbuffer_Release(IMFMediaBuffer *iface)
-{
-    mfbuffer *This = impl_from_IMFMediaBuffer(iface);
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p) ref=%u\n", This, ref);
-
-    if (!ref)
-    {
-        heap_free(This->buffer);
-        heap_free(This);
-    }
-
-    return ref;
-}
-
-static HRESULT WINAPI mfbuffer_Lock(IMFMediaBuffer *iface, BYTE **buffer, DWORD *max, DWORD *current)
-{
-    mfbuffer *This = impl_from_IMFMediaBuffer(iface);
-
-    TRACE("%p, %p %p, %p\n", This, buffer, max, current);
-
-    if(!buffer)
-        return E_INVALIDARG;
-
-    *buffer = This->buffer;
-    if(max)
-        *max = This->max_length;
-    if(current)
-        *current = This->current;
-
-    return S_OK;
-}
-
-static HRESULT WINAPI mfbuffer_Unlock(IMFMediaBuffer *iface)
-{
-    mfbuffer *This = impl_from_IMFMediaBuffer(iface);
-
-    TRACE("%p\n", This);
-
-    return S_OK;
-}
-
-static HRESULT WINAPI mfbuffer_GetCurrentLength(IMFMediaBuffer *iface, DWORD *current)
-{
-    mfbuffer *This = impl_from_IMFMediaBuffer(iface);
-
-    TRACE("%p\n", This);
-
-    if(!current)
-        return E_INVALIDARG;
-
-    *current = This->current;
-
-    return S_OK;
-}
-
-static HRESULT WINAPI mfbuffer_SetCurrentLength(IMFMediaBuffer *iface, DWORD current)
-{
-    mfbuffer *This = impl_from_IMFMediaBuffer(iface);
-
-    TRACE("%p, %u\n", This, current);
-
-    if(current > This->max_length)
-        return E_INVALIDARG;
-
-    This->current = current;
-
-    return S_OK;
-}
-
-static HRESULT WINAPI mfbuffer_GetMaxLength(IMFMediaBuffer *iface, DWORD *max)
-{
-    mfbuffer *This = impl_from_IMFMediaBuffer(iface);
-
-    TRACE("%p, %p\n", This, max);
-
-    if(!max)
-        return E_INVALIDARG;
-
-    *max = This->max_length;
-
-    return S_OK;
-}
-
-static const IMFMediaBufferVtbl mfbuffer_vtbl =
-{
-    mfbuffer_QueryInterface,
-    mfbuffer_AddRef,
-    mfbuffer_Release,
-    mfbuffer_Lock,
-    mfbuffer_Unlock,
-    mfbuffer_GetCurrentLength,
-    mfbuffer_SetCurrentLength,
-    mfbuffer_GetMaxLength
-};
-
-HRESULT WINAPI MFCreateMemoryBuffer(DWORD max_length, IMFMediaBuffer **buffer)
-{
-    mfbuffer *object;
-    BYTE *bytes;
-
-    TRACE("%u, %p\n", max_length, buffer);
-
-    if(!buffer)
-        return E_INVALIDARG;
-
-    object = heap_alloc( sizeof(*object) );
-    if(!object)
-        return E_OUTOFMEMORY;
-
-    bytes = heap_alloc( max_length );
-    if(!bytes)
-    {
-        heap_free(object);
-        return E_OUTOFMEMORY;
-    }
-
-    object->ref = 1;
-    object->max_length = max_length;
-    object->current = 0;
-    object->buffer = bytes;
-    object->IMFMediaBuffer_iface.lpVtbl = &mfbuffer_vtbl;
-    *buffer = &object->IMFMediaBuffer_iface;
-
-    return S_OK;
-}
 
 typedef struct _mfsample
 {
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
index 741dfafad3..900efc3780 100644
--- a/dlls/mfplat/mfplat.spec
+++ b/dlls/mfplat/mfplat.spec
@@ -37,7 +37,7 @@
 @ stub MFConvertToFP16Array
 @ stdcall MFCopyImage(ptr long ptr long long long)
 @ stub MFCreateAMMediaTypeFromMFMediaType
-@ stub MFCreateAlignedMemoryBuffer
+@ stdcall MFCreateAlignedMemoryBuffer(long long ptr)
 @ stdcall MFCreateAsyncResult(ptr ptr ptr ptr)
 @ stdcall MFCreateAttributes(ptr long)
 @ stub MFCreateAudioMediaType
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index aa4104d9ed..674bcf418e 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -42,7 +42,6 @@ static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *s
         DWORD width, DWORD lines);
 static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
 static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
-static HRESULT (WINAPI *pMFCreateMemoryBuffer)(DWORD max_length, IMFMediaBuffer **buffer);
 static void*   (WINAPI *pMFHeapAlloc)(SIZE_T size, ULONG flags, char *file, int line, EAllocationType type);
 static void    (WINAPI *pMFHeapFree)(void *p);
 static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
@@ -323,7 +322,6 @@ static void init_functions(void)
     X(MFCopyImage);
     X(MFCreateSourceResolver);
     X(MFCreateMFByteStreamOnStream);
-    X(MFCreateMemoryBuffer);
     X(MFHeapAlloc);
     X(MFHeapFree);
     X(MFPutWaitingWorkItem);
@@ -602,23 +600,17 @@ static void test_MFCreateFile(void)
     DeleteFileW(newfilename);
 }
 
-static void test_MFCreateMemoryBuffer(void)
+static void test_system_memory_buffer(void)
 {
     IMFMediaBuffer *buffer;
     HRESULT hr;
     DWORD length, max;
     BYTE *data, *data2;
 
-    if(!pMFCreateMemoryBuffer)
-    {
-        win_skip("MFCreateMemoryBuffer() not found\n");
-        return;
-    }
-
-    hr = pMFCreateMemoryBuffer(1024, NULL);
+    hr = MFCreateMemoryBuffer(1024, NULL);
     ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
 
-    hr = pMFCreateMemoryBuffer(0, &buffer);
+    hr = MFCreateMemoryBuffer(0, &buffer);
     ok(hr == S_OK, "got 0x%08x\n", hr);
     if(buffer)
     {
@@ -629,7 +621,7 @@ static void test_MFCreateMemoryBuffer(void)
         IMFMediaBuffer_Release(buffer);
     }
 
-    hr = pMFCreateMemoryBuffer(1024, &buffer);
+    hr = MFCreateMemoryBuffer(1024, &buffer);
     ok(hr == S_OK, "got 0x%08x\n", hr);
 
     hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
@@ -686,6 +678,40 @@ static void test_MFCreateMemoryBuffer(void)
     ok(hr == S_OK, "got 0x%08x\n", hr);
 
     IMFMediaBuffer_Release(buffer);
+
+    /* Aligned buffer. */
+    hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
+    ok(hr == S_OK, "Failed to create memory buffer, hr %#x.\n", hr);
+
+    hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
+    ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
+    ok(length == 0, "Unexpected current length %u.\n", length);
+
+    hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
+    ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
+    hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
+    ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
+    ok(length == 1, "Unexpected current length %u.\n", length);
+
+    hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
+    ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
+    ok(length == 201, "Unexpected max length %u.\n", length);
+
+    hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+    hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
+    ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
+    ok(length == 201, "Unexpected max length %u.\n", length);
+    hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
+    ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
+
+    hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
+    ok(hr == S_OK, "Failed to lock, hr %#x.\n", hr);
+    ok(max == 201 && length == 10, "Unexpected length.\n");
+    hr = IMFMediaBuffer_Unlock(buffer);
+    ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
+
+    IMFMediaBuffer_Release(buffer);
 }
 
 static void test_MFSample(void)
@@ -1518,7 +1544,7 @@ START_TEST(mfplat)
     test_MFSample();
     test_MFCreateFile();
     test_MFCreateMFByteStreamOnStream();
-    test_MFCreateMemoryBuffer();
+    test_system_memory_buffer();
     test_source_resolver();
     test_MFCreateAsyncResult();
     test_allocate_queue();
diff --git a/include/mfapi.h b/include/mfapi.h
index 4560d5dee7..4062e2fd13 100644
--- a/include/mfapi.h
+++ b/include/mfapi.h
@@ -97,11 +97,27 @@ typedef enum
 
 typedef void (CALLBACK *MFPERIODICCALLBACK)(IUnknown *context);
 
+#define MF_1_BYTE_ALIGNMENT       0x00000000
+#define MF_2_BYTE_ALIGNMENT       0x00000001
+#define MF_4_BYTE_ALIGNMENT       0x00000003
+#define MF_8_BYTE_ALIGNMENT       0x00000007
+#define MF_16_BYTE_ALIGNMENT      0x0000000f
+#define MF_32_BYTE_ALIGNMENT      0x0000001f
+#define MF_64_BYTE_ALIGNMENT      0x0000003f
+#define MF_128_BYTE_ALIGNMENT     0x0000007f
+#define MF_256_BYTE_ALIGNMENT     0x000000ff
+#define MF_512_BYTE_ALIGNMENT     0x000001ff
+#define MF_1024_BYTE_ALIGNMENT    0x000003ff
+#define MF_2048_BYTE_ALIGNMENT    0x000007ff
+#define MF_4096_BYTE_ALIGNMENT    0x00000fff
+#define MF_8192_BYTE_ALIGNMENT    0x00001fff
+
 HRESULT WINAPI MFAddPeriodicCallback(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key);
 HRESULT WINAPI MFAllocateWorkQueue(DWORD *queue);
 HRESULT WINAPI MFAllocateWorkQueueEx(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue);
 HRESULT WINAPI MFCancelWorkItem(MFWORKITEM_KEY key);
 HRESULT WINAPI MFCopyImage(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride, DWORD width, DWORD lines);
+HRESULT WINAPI MFCreateAlignedMemoryBuffer(DWORD max_length, DWORD alignment, IMFMediaBuffer **buffer);
 HRESULT WINAPI MFCreateAttributes(IMFAttributes **attributes, UINT32 size);
 HRESULT WINAPI MFCreateAsyncResult(IUnknown *object, IMFAsyncCallback *callback, IUnknown *state, IMFAsyncResult **result);
 HRESULT WINAPI MFCreateCollection(IMFCollection **collection);
-- 
2.20.1




More information about the wine-devel mailing list