Commit 4fd32ad0 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

mfplat: Move buffer implementation to separate file.

parent 8de65329
......@@ -3,6 +3,7 @@ IMPORTLIB = mfplat
IMPORTS = advapi32 ole32
C_SRCS = \
buffer.c \
main.c \
mediatype.c \
queue.c
/*
* 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);
}
......@@ -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
{
......
......@@ -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
......
......@@ -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();
......
......@@ -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);
......
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