[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