Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/buffer.c | 62 +++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat.spec | 1 + dlls/mfplat/tests/mfplat.c | 70 ++++++++++++++++++++++++++++++++++++++ include/mfapi.h | 2 ++ 4 files changed, 135 insertions(+)
diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c index 590288e344..b1d353a59b 100644 --- a/dlls/mfplat/buffer.c +++ b/dlls/mfplat/buffer.c @@ -448,6 +448,68 @@ HRESULT WINAPI MFCreate2DMediaBuffer(DWORD width, DWORD height, DWORD fourcc, BO return create_2d_buffer(width, height, fourcc, buffer); }
+static unsigned int buffer_get_aligned_length(unsigned int length, unsigned int alignment) +{ + length = (length + alignment) / alignment; + length *= alignment; + + return length; +} + +HRESULT WINAPI MFCreateMediaBufferFromMediaType(IMFMediaType *media_type, LONGLONG duration, DWORD min_length, + DWORD alignment, IMFMediaBuffer **buffer) +{ + UINT32 length = 0, block_alignment; + LONGLONG avg_length; + HRESULT hr; + GUID major; + + TRACE("%p, %s, %u, %u, %p.\n", media_type, wine_dbgstr_longlong(duration), min_length, alignment, buffer); + + if (!media_type) + return E_INVALIDARG; + + if (FAILED(hr = IMFMediaType_GetMajorType(media_type, &major))) + return hr; + + if (IsEqualGUID(&major, &MFMediaType_Audio)) + { + block_alignment = 0; + if (FAILED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_alignment))) + WARN("Block alignment was not specified.\n"); + + if (block_alignment) + { + avg_length = 0; + + if (duration) + { + length = 0; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &length))) + { + /* 100 ns -> 1 s */ + avg_length = length * duration / (10 * 1000 * 1000); + } + } + + alignment = max(16, alignment); + + length = buffer_get_aligned_length(avg_length + 1, alignment); + length = buffer_get_aligned_length(length, block_alignment); + } + else + length = 0; + + length = max(length, min_length); + + return create_1d_buffer(length, MF_1_BYTE_ALIGNMENT, buffer); + } + else + FIXME("Major type %s is not supported.\n", debugstr_guid(&major)); + + return E_NOTIMPL; +} + static HRESULT WINAPI sample_QueryInterface(IMFSample *iface, REFIID riid, void **out) { TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 2fb6388a31..9f08d1aff2 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -52,6 +52,7 @@ @ stdcall MFCreateMFByteStreamOnStreamEx(ptr ptr) @ stdcall MFCreateMFByteStreamWrapper(ptr ptr) @ stub MFCreateMFVideoFormatFromMFMediaType +@ stdcall MFCreateMediaBufferFromMediaType(ptr int64 long long ptr) @ stub MFCreateMediaBufferWrapper @ stdcall MFCreateMediaEvent(long ptr long ptr ptr) @ stdcall MFCreateMediaType(ptr) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 31194db77f..65e9b66447 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -95,6 +95,8 @@ static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride); static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up, IMFMediaBuffer **buffer); +static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length, + DWORD min_alignment, IMFMediaBuffer **buffer);
static const WCHAR fileschemeW[] = L"file://";
@@ -665,6 +667,7 @@ static void init_functions(void) X(MFCreate2DMediaBuffer); X(MFCreateDXGIDeviceManager); X(MFCreateSourceResolver); + X(MFCreateMediaBufferFromMediaType); X(MFCreateMFByteStreamOnStream); X(MFCreateTransformActivate); X(MFGetPlaneSize); @@ -4587,6 +4590,72 @@ static void test_MFCreate2DMediaBuffer(void) IMFMediaBuffer_Release(buffer); }
+static void test_MFCreateMediaBufferFromMediaType(void) +{ + static struct audio_buffer_test + { + unsigned int duration; + unsigned int min_length; + unsigned int min_alignment; + unsigned int block_alignment; + unsigned int bytes_per_second; + 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 }, + }; + IMFMediaBuffer *buffer; + UINT32 length; + HRESULT hr; + IMFMediaType *media_type; + unsigned int i; + + if (!pMFCreateMediaBufferFromMediaType) + { + win_skip("MFCreateMediaBufferFromMediaType() is not available.\n"); + return; + } + + hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(audio_tests); ++i) + { + const struct audio_buffer_test *ptr = &audio_tests[i]; + + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length, + ptr->min_alignment, &buffer); + ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#x.\n", hr); + if (FAILED(hr)) + break; + + hr = IMFMediaBuffer_GetMaxLength(buffer, &length); + ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr); + ok(ptr->buffer_length == length, "%d: unexpected buffer length %u, expected %u.\n", i, length, ptr->buffer_length); + + IMFMediaBuffer_Release(buffer); + } + + IMFMediaType_Release(media_type); +} + START_TEST(mfplat) { char **argv; @@ -4640,6 +4709,7 @@ START_TEST(mfplat) test_queue_com(); test_MFGetStrideForBitmapInfoHeader(); test_MFCreate2DMediaBuffer(); + test_MFCreateMediaBufferFromMediaType();
CoUninitialize(); } diff --git a/include/mfapi.h b/include/mfapi.h index 9f4db44d1e..9c22b6bfd8 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -411,6 +411,8 @@ HRESULT WINAPI MFCreateDXGIDeviceManager(UINT *token, IMFDXGIDeviceManager **man HRESULT WINAPI MFCreateEventQueue(IMFMediaEventQueue **queue); HRESULT WINAPI MFCreateFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE openmode, MF_FILE_FLAGS flags, LPCWSTR url, IMFByteStream **bytestream); +HRESULT WINAPI MFCreateMediaBufferFromMediaType(IMFMediaType *media_type, LONGLONG duration, DWORD min_length, + DWORD min_alignment, IMFMediaBuffer **buffer); HRESULT WINAPI MFCreateMediaEvent(MediaEventType type, REFGUID extended_type, HRESULT status, const PROPVARIANT *value, IMFMediaEvent **event); HRESULT WINAPI MFCreateMediaType(IMFMediaType **type);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mediatype.c | 17 +++++++++++++ dlls/mfplat/tests/mfplat.c | 49 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 6958421826..d764baf0b9 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -29,6 +29,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC1, MAKEFOURCC('I','M','C','1')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC2, MAKEFOURCC('I','M','C','2')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC3, MAKEFOURCC('I','M','C','3')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC4, MAKEFOURCC('I','M','C','4')); + struct media_type { struct attributes attributes; @@ -1785,9 +1790,15 @@ static const struct uncompressed_video_format video_formats[] = { &MFVideoFormat_A2R10G10B10, 4, 3, 1 }, { &MFVideoFormat_RGB8, 1, 3, 1 }, { &MFVideoFormat_L8, 1, 3, 1 }, + { &MFVideoFormat_AYUV, 4, 3, 0 }, + { &MFVideoFormat_IMC1, 2, 3, 0 }, + { &MFVideoFormat_IMC2, 1, 0, 0 }, + { &MFVideoFormat_IMC3, 2, 3, 0 }, + { &MFVideoFormat_IMC4, 1, 0, 0 }, { &MFVideoFormat_NV12, 1, 0, 0 }, { &MFVideoFormat_D16, 2, 3, 0 }, { &MFVideoFormat_L16, 2, 3, 0 }, + { &MFVideoFormat_YV12, 1, 0, 0 }, { &MFVideoFormat_A16B16G16R16F, 8, 3, 1 }, };
@@ -1852,7 +1863,10 @@ HRESULT WINAPI MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height
switch (subtype->Data1) { + case MAKEFOURCC('I','M','C','2'): + case MAKEFOURCC('I','M','C','4'): case MAKEFOURCC('N','V','1','2'): + case MAKEFOURCC('Y','V','1','2'): /* 2 x 2 block, interleaving UV for half the height */ *size = ((width + 1) & ~1) * height * 3 / 2; break; @@ -1890,7 +1904,10 @@ HRESULT WINAPI MFGetPlaneSize(DWORD fourcc, DWORD width, DWORD height, DWORD *si
switch (fourcc) { + case MAKEFOURCC('I','M','C','2'): + case MAKEFOURCC('I','M','C','4'): case MAKEFOURCC('N','V','1','2'): + case MAKEFOURCC('Y','V','1','2'): *size = stride * height * 3 / 2; break; default: diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 65e9b66447..621b5b4393 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -48,6 +48,11 @@ DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22, DEFINE_GUID(DUMMY_GUID3, 0x12345678,0x1234,0x1234,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23); DEFINE_GUID(CLSID_FileSchemeHandler, 0x477ec299, 0x1421, 0x4bdd, 0x97, 0x1f, 0x7c, 0xcb, 0x93, 0x3f, 0x21, 0xad);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC1, MAKEFOURCC('I','M','C','1')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC2, MAKEFOURCC('I','M','C','2')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC3, MAKEFOURCC('I','M','C','3')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC4, MAKEFOURCC('I','M','C','4')); + static BOOL is_win8_plus;
#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__) @@ -3414,6 +3419,32 @@ static void test_MFCalculateImageSize(void) { &MFVideoFormat_NV12, 2, 2, 6, 6 }, { &MFVideoFormat_NV12, 3, 2, 12, 9 }, { &MFVideoFormat_NV12, 4, 2, 12, 12 }, + { &MFVideoFormat_AYUV, 1, 1, 4 }, + { &MFVideoFormat_AYUV, 2, 1, 8 }, + { &MFVideoFormat_AYUV, 1, 2, 8 }, + { &MFVideoFormat_AYUV, 4, 3, 48 }, + { &MFVideoFormat_IMC1, 1, 1, 4 }, + { &MFVideoFormat_IMC1, 2, 1, 4 }, + { &MFVideoFormat_IMC1, 1, 2, 8 }, + { &MFVideoFormat_IMC1, 4, 3, 24 }, + { &MFVideoFormat_IMC3, 1, 1, 4 }, + { &MFVideoFormat_IMC3, 2, 1, 4 }, + { &MFVideoFormat_IMC3, 1, 2, 8 }, + { &MFVideoFormat_IMC3, 4, 3, 24 }, + { &MFVideoFormat_IMC2, 1, 3, 9, 4 }, + { &MFVideoFormat_IMC2, 1, 2, 6, 3 }, + { &MFVideoFormat_IMC2, 2, 2, 6, 6 }, + { &MFVideoFormat_IMC2, 3, 2, 12, 9 }, + { &MFVideoFormat_IMC2, 4, 2, 12, 12 }, + { &MFVideoFormat_IMC4, 1, 3, 9, 4 }, + { &MFVideoFormat_IMC4, 1, 2, 6, 3 }, + { &MFVideoFormat_IMC4, 2, 2, 6, 6 }, + { &MFVideoFormat_IMC4, 3, 2, 12, 9 }, + { &MFVideoFormat_IMC4, 4, 2, 12, 12 }, + { &MFVideoFormat_YV12, 1, 1, 3, 1 }, + { &MFVideoFormat_YV12, 2, 1, 3 }, + { &MFVideoFormat_YV12, 1, 2, 6, 3 }, + { &MFVideoFormat_YV12, 4, 3, 18 }, }; unsigned int i; UINT32 size; @@ -4525,6 +4556,24 @@ static void test_MFGetStrideForBitmapInfoHeader(void) { &MFVideoFormat_NV12, 1, 1 }, { &MFVideoFormat_NV12, 2, 2 }, { &MFVideoFormat_NV12, 3, 3 }, + { &MFVideoFormat_AYUV, 1, 4 }, + { &MFVideoFormat_AYUV, 4, 16 }, + { &MFVideoFormat_AYUV, 5, 20 }, + { &MFVideoFormat_IMC1, 1, 4 }, + { &MFVideoFormat_IMC1, 2, 4 }, + { &MFVideoFormat_IMC1, 3, 8 }, + { &MFVideoFormat_IMC3, 1, 4 }, + { &MFVideoFormat_IMC3, 2, 4 }, + { &MFVideoFormat_IMC3, 3, 8 }, + { &MFVideoFormat_IMC2, 1, 1 }, + { &MFVideoFormat_IMC2, 2, 2 }, + { &MFVideoFormat_IMC2, 3, 3 }, + { &MFVideoFormat_IMC4, 1, 1 }, + { &MFVideoFormat_IMC4, 2, 2 }, + { &MFVideoFormat_IMC4, 3, 3 }, + { &MFVideoFormat_YV12, 1, 1 }, + { &MFVideoFormat_YV12, 2, 2 }, + { &MFVideoFormat_YV12, 3, 3 }, }; unsigned int i; LONG stride;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 275 +++++++++++++++++++++++---------------------- 1 file changed, 139 insertions(+), 136 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 09d6a63bba..a5c954161d 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -29,6 +29,7 @@ #include "winreg.h"
#include "initguid.h" +#include "rtworkq.h" #include "ole2.h" #include "propsys.h" #include "dxgi.h" @@ -40,7 +41,6 @@ #include "mfreadwrite.h" #include "propvarutil.h" #include "strsafe.h" -#include "rtworkq.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
@@ -3363,8 +3363,8 @@ typedef struct bytestream struct attributes attributes; IMFByteStream IMFByteStream_iface; IMFGetService IMFGetService_iface; - IMFAsyncCallback read_callback; - IMFAsyncCallback write_callback; + IRtwqAsyncCallback read_callback; + IRtwqAsyncCallback write_callback; IStream *stream; HANDLE hfile; QWORD position; @@ -3383,12 +3383,12 @@ static struct bytestream *impl_bytestream_from_IMFGetService(IMFGetService *ifac return CONTAINING_RECORD(iface, struct bytestream, IMFGetService_iface); }
-static struct bytestream *impl_from_read_callback_IMFAsyncCallback(IMFAsyncCallback *iface) +static struct bytestream *impl_from_read_callback_IRtwqAsyncCallback(IRtwqAsyncCallback *iface) { return CONTAINING_RECORD(iface, struct bytestream, read_callback); }
-static struct bytestream *impl_from_write_callback_IMFAsyncCallback(IMFAsyncCallback *iface) +static struct bytestream *impl_from_write_callback_IRtwqAsyncCallback(IRtwqAsyncCallback *iface) { return CONTAINING_RECORD(iface, struct bytestream, write_callback); } @@ -3473,7 +3473,7 @@ static HRESULT bytestream_create_io_request(struct bytestream *stream, enum asyn const BYTE *data, ULONG size, IMFAsyncCallback *callback, IUnknown *state) { struct async_stream_op *op; - IMFAsyncResult *request; + IRtwqAsyncResult *request; HRESULT hr;
op = heap_alloc(sizeof(*op)); @@ -3486,15 +3486,18 @@ static HRESULT bytestream_create_io_request(struct bytestream *stream, enum asyn op->position = stream->position; op->requested_length = size; op->type = type; - if (FAILED(hr = MFCreateAsyncResult((IUnknown *)&stream->IMFByteStream_iface, callback, state, &op->caller))) + if (FAILED(hr = RtwqCreateAsyncResult((IUnknown *)&stream->IMFByteStream_iface, (IRtwqAsyncCallback *)callback, state, + (IRtwqAsyncResult **)&op->caller))) + { goto failed; + }
- if (FAILED(hr = MFCreateAsyncResult(&op->IUnknown_iface, type == ASYNC_STREAM_OP_READ ? &stream->read_callback : + if (FAILED(hr = RtwqCreateAsyncResult(&op->IUnknown_iface, type == ASYNC_STREAM_OP_READ ? &stream->read_callback : &stream->write_callback, NULL, &request))) goto failed;
- MFPutWorkItemEx(MFASYNC_CALLBACK_QUEUE_STANDARD, request); - IMFAsyncResult_Release(request); + RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, 0, request); + IRtwqAsyncResult_Release(request);
failed: IUnknown_Release(&op->IUnknown_iface); @@ -3530,13 +3533,13 @@ static HRESULT bytestream_complete_io_request(struct bytestream *stream, enum as return hr; }
-static HRESULT WINAPI bytestream_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) +static HRESULT WINAPI bytestream_callback_QueryInterface(IRtwqAsyncCallback *iface, REFIID riid, void **obj) { - if (IsEqualIID(riid, &IID_IMFAsyncCallback) || + if (IsEqualIID(riid, &IID_IRtwqAsyncCallback) || IsEqualIID(riid, &IID_IUnknown)) { *obj = iface; - IMFAsyncCallback_AddRef(iface); + IRtwqAsyncCallback_AddRef(iface); return S_OK; }
@@ -3545,32 +3548,32 @@ static HRESULT WINAPI bytestream_callback_QueryInterface(IMFAsyncCallback *iface return E_NOINTERFACE; }
-static ULONG WINAPI bytestream_read_callback_AddRef(IMFAsyncCallback *iface) +static ULONG WINAPI bytestream_read_callback_AddRef(IRtwqAsyncCallback *iface) { - struct bytestream *stream = impl_from_read_callback_IMFAsyncCallback(iface); + struct bytestream *stream = impl_from_read_callback_IRtwqAsyncCallback(iface); return IMFByteStream_AddRef(&stream->IMFByteStream_iface); }
-static ULONG WINAPI bytestream_read_callback_Release(IMFAsyncCallback *iface) +static ULONG WINAPI bytestream_read_callback_Release(IRtwqAsyncCallback *iface) { - struct bytestream *stream = impl_from_read_callback_IMFAsyncCallback(iface); + struct bytestream *stream = impl_from_read_callback_IRtwqAsyncCallback(iface); return IMFByteStream_Release(&stream->IMFByteStream_iface); }
-static HRESULT WINAPI bytestream_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) +static HRESULT WINAPI bytestream_callback_GetParameters(IRtwqAsyncCallback *iface, DWORD *flags, DWORD *queue) { return E_NOTIMPL; }
-static ULONG WINAPI bytestream_write_callback_AddRef(IMFAsyncCallback *iface) +static ULONG WINAPI bytestream_write_callback_AddRef(IRtwqAsyncCallback *iface) { - struct bytestream *stream = impl_from_write_callback_IMFAsyncCallback(iface); + struct bytestream *stream = impl_from_write_callback_IRtwqAsyncCallback(iface); return IMFByteStream_AddRef(&stream->IMFByteStream_iface); }
-static ULONG WINAPI bytestream_write_callback_Release(IMFAsyncCallback *iface) +static ULONG WINAPI bytestream_write_callback_Release(IRtwqAsyncCallback *iface) { - struct bytestream *stream = impl_from_write_callback_IMFAsyncCallback(iface); + struct bytestream *stream = impl_from_write_callback_IRtwqAsyncCallback(iface); return IMFByteStream_Release(&stream->IMFByteStream_iface); }
@@ -4104,15 +4107,15 @@ static const IMFAttributesVtbl mfbytestream_attributes_vtbl = mfattributes_CopyAllItems };
-static HRESULT WINAPI bytestream_stream_read_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +static HRESULT WINAPI bytestream_stream_read_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) { - struct bytestream *stream = impl_from_read_callback_IMFAsyncCallback(iface); + struct bytestream *stream = impl_from_read_callback_IRtwqAsyncCallback(iface); struct async_stream_op *op; LARGE_INTEGER position; IUnknown *object; HRESULT hr;
- if (FAILED(hr = IMFAsyncResult_GetObject(result, &object))) + if (FAILED(hr = IRtwqAsyncResult_GetObject(result, &object))) return hr;
op = impl_async_stream_op_from_IUnknown(object); @@ -4136,15 +4139,15 @@ static HRESULT WINAPI bytestream_stream_read_callback_Invoke(IMFAsyncCallback *i return S_OK; }
-static HRESULT WINAPI bytestream_stream_write_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +static HRESULT WINAPI bytestream_stream_write_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) { - struct bytestream *stream = impl_from_read_callback_IMFAsyncCallback(iface); + struct bytestream *stream = impl_from_read_callback_IRtwqAsyncCallback(iface); struct async_stream_op *op; LARGE_INTEGER position; IUnknown *object; HRESULT hr;
- if (FAILED(hr = IMFAsyncResult_GetObject(result, &object))) + if (FAILED(hr = IRtwqAsyncResult_GetObject(result, &object))) return hr;
op = impl_async_stream_op_from_IUnknown(object); @@ -4168,7 +4171,7 @@ static HRESULT WINAPI bytestream_stream_write_callback_Invoke(IMFAsyncCallback * return S_OK; }
-static const IMFAsyncCallbackVtbl bytestream_stream_read_callback_vtbl = +static const IRtwqAsyncCallbackVtbl bytestream_stream_read_callback_vtbl = { bytestream_callback_QueryInterface, bytestream_read_callback_AddRef, @@ -4177,7 +4180,7 @@ static const IMFAsyncCallbackVtbl bytestream_stream_read_callback_vtbl = bytestream_stream_read_callback_Invoke, };
-static const IMFAsyncCallbackVtbl bytestream_stream_write_callback_vtbl = +static const IRtwqAsyncCallbackVtbl bytestream_stream_write_callback_vtbl = { bytestream_callback_QueryInterface, bytestream_write_callback_AddRef, @@ -4235,21 +4238,21 @@ HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **byt return S_OK; }
-static HRESULT WINAPI bytestream_file_read_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +static HRESULT WINAPI bytestream_file_read_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) { FIXME("%p, %p.\n", iface, result);
return E_NOTIMPL; }
-static HRESULT WINAPI bytestream_file_write_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +static HRESULT WINAPI bytestream_file_write_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) { FIXME("%p, %p.\n", iface, result);
return E_NOTIMPL; }
-static const IMFAsyncCallbackVtbl bytestream_file_read_callback_vtbl = +static const IRtwqAsyncCallbackVtbl bytestream_file_read_callback_vtbl = { bytestream_callback_QueryInterface, bytestream_read_callback_AddRef, @@ -4258,7 +4261,7 @@ static const IMFAsyncCallbackVtbl bytestream_file_read_callback_vtbl = bytestream_file_read_callback_Invoke, };
-static const IMFAsyncCallbackVtbl bytestream_file_write_callback_vtbl = +static const IRtwqAsyncCallbackVtbl bytestream_file_write_callback_vtbl = { bytestream_callback_QueryInterface, bytestream_write_callback_AddRef, @@ -5742,7 +5745,7 @@ struct resolver_queued_result IUnknown *object; MF_OBJECT_TYPE obj_type; HRESULT hr; - IMFAsyncResult *inner_result; + IRtwqAsyncResult *inner_result; enum resolved_object_origin origin; };
@@ -5764,8 +5767,8 @@ struct source_resolver { IMFSourceResolver IMFSourceResolver_iface; LONG refcount; - IMFAsyncCallback stream_callback; - IMFAsyncCallback url_callback; + IRtwqAsyncCallback stream_callback; + IRtwqAsyncCallback url_callback; CRITICAL_SECTION cs; struct list pending; }; @@ -5775,20 +5778,20 @@ static struct source_resolver *impl_from_IMFSourceResolver(IMFSourceResolver *if return CONTAINING_RECORD(iface, struct source_resolver, IMFSourceResolver_iface); }
-static struct source_resolver *impl_from_stream_IMFAsyncCallback(IMFAsyncCallback *iface) +static struct source_resolver *impl_from_stream_IRtwqAsyncCallback(IRtwqAsyncCallback *iface) { return CONTAINING_RECORD(iface, struct source_resolver, stream_callback); }
-static struct source_resolver *impl_from_url_IMFAsyncCallback(IMFAsyncCallback *iface) +static struct source_resolver *impl_from_url_IRtwqAsyncCallback(IRtwqAsyncCallback *iface) { return CONTAINING_RECORD(iface, struct source_resolver, url_callback); }
static HRESULT resolver_handler_end_create(struct source_resolver *resolver, enum resolved_object_origin origin, - IMFAsyncResult *result) + IRtwqAsyncResult *result) { - IMFAsyncResult *inner_result = (IMFAsyncResult *)IMFAsyncResult_GetStateNoAddRef(result); + IRtwqAsyncResult *inner_result = (IRtwqAsyncResult *)IRtwqAsyncResult_GetStateNoAddRef(result); struct resolver_queued_result *queued_result; union { @@ -5799,16 +5802,16 @@ static HRESULT resolver_handler_end_create(struct source_resolver *resolver, enu
queued_result = heap_alloc_zero(sizeof(*queued_result));
- IMFAsyncResult_GetObject(inner_result, &handler.handler); + IRtwqAsyncResult_GetObject(inner_result, &handler.handler);
switch (origin) { case OBJECT_FROM_BYTESTREAM: - queued_result->hr = IMFByteStreamHandler_EndCreateObject(handler.stream_handler, result, + queued_result->hr = IMFByteStreamHandler_EndCreateObject(handler.stream_handler, (IMFAsyncResult *)result, &queued_result->obj_type, &queued_result->object); break; case OBJECT_FROM_URL: - queued_result->hr = IMFSchemeHandler_EndCreateObject(handler.scheme_handler, result, + queued_result->hr = IMFSchemeHandler_EndCreateObject(handler.scheme_handler, (IMFAsyncResult *)result, &queued_result->obj_type, &queued_result->object); break; default: @@ -5819,12 +5822,12 @@ static HRESULT resolver_handler_end_create(struct source_resolver *resolver, enu
if (SUCCEEDED(queued_result->hr)) { - MFASYNCRESULT *data = (MFASYNCRESULT *)inner_result; + RTWQASYNCRESULT *data = (RTWQASYNCRESULT *)inner_result;
if (data->hEvent) { queued_result->inner_result = inner_result; - IMFAsyncResult_AddRef(queued_result->inner_result); + IRtwqAsyncResult_AddRef(queued_result->inner_result); }
/* Push resolved object type and created object, so we don't have to guess on End*() call. */ @@ -5836,13 +5839,13 @@ static HRESULT resolver_handler_end_create(struct source_resolver *resolver, enu SetEvent(data->hEvent); else { - IUnknown *caller_state = IMFAsyncResult_GetStateNoAddRef(inner_result); - IMFAsyncResult *caller_result; + IUnknown *caller_state = IRtwqAsyncResult_GetStateNoAddRef(inner_result); + IRtwqAsyncResult *caller_result;
- if (SUCCEEDED(MFCreateAsyncResult(queued_result->object, data->pCallback, caller_state, &caller_result))) + if (SUCCEEDED(RtwqCreateAsyncResult(queued_result->object, data->pCallback, caller_state, &caller_result))) { - MFInvokeCallback(caller_result); - IMFAsyncResult_Release(caller_result); + RtwqInvokeCallback(caller_result); + IRtwqAsyncResult_Release(caller_result); } } } @@ -5930,13 +5933,13 @@ static HRESULT resolver_create_cancel_object(IUnknown *handler, enum resolved_ob return S_OK; }
-static HRESULT WINAPI source_resolver_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) +static HRESULT WINAPI source_resolver_callback_QueryInterface(IRtwqAsyncCallback *iface, REFIID riid, void **obj) { - if (IsEqualIID(riid, &IID_IMFAsyncCallback) || + if (IsEqualIID(riid, &IID_IRtwqAsyncCallback) || IsEqualIID(riid, &IID_IUnknown)) { *obj = iface; - IMFAsyncCallback_AddRef(iface); + IRtwqAsyncCallback_AddRef(iface); return S_OK; }
@@ -5944,31 +5947,31 @@ static HRESULT WINAPI source_resolver_callback_QueryInterface(IMFAsyncCallback * return E_NOINTERFACE; }
-static ULONG WINAPI source_resolver_callback_stream_AddRef(IMFAsyncCallback *iface) +static ULONG WINAPI source_resolver_callback_stream_AddRef(IRtwqAsyncCallback *iface) { - struct source_resolver *resolver = impl_from_stream_IMFAsyncCallback(iface); + struct source_resolver *resolver = impl_from_stream_IRtwqAsyncCallback(iface); return IMFSourceResolver_AddRef(&resolver->IMFSourceResolver_iface); }
-static ULONG WINAPI source_resolver_callback_stream_Release(IMFAsyncCallback *iface) +static ULONG WINAPI source_resolver_callback_stream_Release(IRtwqAsyncCallback *iface) { - struct source_resolver *resolver = impl_from_stream_IMFAsyncCallback(iface); + struct source_resolver *resolver = impl_from_stream_IRtwqAsyncCallback(iface); return IMFSourceResolver_Release(&resolver->IMFSourceResolver_iface); }
-static HRESULT WINAPI source_resolver_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) +static HRESULT WINAPI source_resolver_callback_GetParameters(IRtwqAsyncCallback *iface, DWORD *flags, DWORD *queue) { return E_NOTIMPL; }
-static HRESULT WINAPI source_resolver_callback_stream_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +static HRESULT WINAPI source_resolver_callback_stream_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) { - struct source_resolver *resolver = impl_from_stream_IMFAsyncCallback(iface); + struct source_resolver *resolver = impl_from_stream_IRtwqAsyncCallback(iface);
return resolver_handler_end_create(resolver, OBJECT_FROM_BYTESTREAM, result); }
-static const IMFAsyncCallbackVtbl source_resolver_callback_stream_vtbl = +static const IRtwqAsyncCallbackVtbl source_resolver_callback_stream_vtbl = { source_resolver_callback_QueryInterface, source_resolver_callback_stream_AddRef, @@ -5977,26 +5980,26 @@ static const IMFAsyncCallbackVtbl source_resolver_callback_stream_vtbl = source_resolver_callback_stream_Invoke, };
-static ULONG WINAPI source_resolver_callback_url_AddRef(IMFAsyncCallback *iface) +static ULONG WINAPI source_resolver_callback_url_AddRef(IRtwqAsyncCallback *iface) { - struct source_resolver *resolver = impl_from_url_IMFAsyncCallback(iface); + struct source_resolver *resolver = impl_from_url_IRtwqAsyncCallback(iface); return IMFSourceResolver_AddRef(&resolver->IMFSourceResolver_iface); }
-static ULONG WINAPI source_resolver_callback_url_Release(IMFAsyncCallback *iface) +static ULONG WINAPI source_resolver_callback_url_Release(IRtwqAsyncCallback *iface) { - struct source_resolver *resolver = impl_from_url_IMFAsyncCallback(iface); + struct source_resolver *resolver = impl_from_url_IRtwqAsyncCallback(iface); return IMFSourceResolver_Release(&resolver->IMFSourceResolver_iface); }
-static HRESULT WINAPI source_resolver_callback_url_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +static HRESULT WINAPI source_resolver_callback_url_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) { - struct source_resolver *resolver = impl_from_url_IMFAsyncCallback(iface); + struct source_resolver *resolver = impl_from_url_IRtwqAsyncCallback(iface);
return resolver_handler_end_create(resolver, OBJECT_FROM_URL, result); }
-static const IMFAsyncCallbackVtbl source_resolver_callback_url_vtbl = +static const IRtwqAsyncCallbackVtbl source_resolver_callback_url_vtbl = { source_resolver_callback_QueryInterface, source_resolver_callback_url_AddRef, @@ -6227,13 +6230,13 @@ static HRESULT resolver_get_scheme_handler(const WCHAR *url, DWORD flags, IMFSch }
static HRESULT resolver_end_create_object(struct source_resolver *resolver, enum resolved_object_origin origin, - IMFAsyncResult *result, MF_OBJECT_TYPE *obj_type, IUnknown **out) + IRtwqAsyncResult *result, MF_OBJECT_TYPE *obj_type, IUnknown **out) { struct resolver_queued_result *queued_result = NULL, *iter; IUnknown *object; HRESULT hr;
- if (FAILED(hr = IMFAsyncResult_GetObject(result, &object))) + if (FAILED(hr = IRtwqAsyncResult_GetObject(result, &object))) return hr;
EnterCriticalSection(&resolver->cs); @@ -6258,7 +6261,7 @@ static HRESULT resolver_end_create_object(struct source_resolver *resolver, enum *obj_type = queued_result->obj_type; hr = queued_result->hr; if (queued_result->inner_result) - IMFAsyncResult_Release(queued_result->inner_result); + IRtwqAsyncResult_Release(queued_result->inner_result); heap_free(queued_result); } else @@ -6328,8 +6331,8 @@ static HRESULT WINAPI source_resolver_CreateObjectFromURL(IMFSourceResolver *ifa { struct source_resolver *resolver = impl_from_IMFSourceResolver(iface); IMFSchemeHandler *handler; - IMFAsyncResult *result; - MFASYNCRESULT *data; + IRtwqAsyncResult *result; + RTWQASYNCRESULT *data; HRESULT hr;
TRACE("%p, %s, %#x, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, obj_type, object); @@ -6340,26 +6343,26 @@ static HRESULT WINAPI source_resolver_CreateObjectFromURL(IMFSourceResolver *ifa if (FAILED(hr = resolver_get_scheme_handler(url, flags, &handler))) return hr;
- hr = MFCreateAsyncResult((IUnknown *)handler, NULL, NULL, &result); + hr = RtwqCreateAsyncResult((IUnknown *)handler, NULL, NULL, &result); IMFSchemeHandler_Release(handler); if (FAILED(hr)) return hr;
- data = (MFASYNCRESULT *)result; + data = (RTWQASYNCRESULT *)result; data->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
- hr = IMFSchemeHandler_BeginCreateObject(handler, url, flags, props, NULL, &resolver->url_callback, + hr = IMFSchemeHandler_BeginCreateObject(handler, url, flags, props, NULL, (IMFAsyncCallback *)&resolver->url_callback, (IUnknown *)result); if (FAILED(hr)) { - IMFAsyncResult_Release(result); + IRtwqAsyncResult_Release(result); return hr; }
WaitForSingleObject(data->hEvent, INFINITE);
hr = resolver_end_create_object(resolver, OBJECT_FROM_URL, result, obj_type, object); - IMFAsyncResult_Release(result); + IRtwqAsyncResult_Release(result);
return hr; } @@ -6369,8 +6372,8 @@ static HRESULT WINAPI source_resolver_CreateObjectFromByteStream(IMFSourceResolv { struct source_resolver *resolver = impl_from_IMFSourceResolver(iface); IMFByteStreamHandler *handler; - IMFAsyncResult *result; - MFASYNCRESULT *data; + IRtwqAsyncResult *result; + RTWQASYNCRESULT *data; HRESULT hr;
TRACE("%p, %p, %s, %#x, %p, %p, %p.\n", iface, stream, debugstr_w(url), flags, props, obj_type, object); @@ -6381,26 +6384,26 @@ static HRESULT WINAPI source_resolver_CreateObjectFromByteStream(IMFSourceResolv if (FAILED(hr = resolver_get_bytestream_handler(stream, url, flags, &handler))) goto fallback;
- hr = MFCreateAsyncResult((IUnknown *)handler, NULL, NULL, &result); + hr = RtwqCreateAsyncResult((IUnknown *)handler, NULL, NULL, &result); IMFByteStreamHandler_Release(handler); if (FAILED(hr)) return hr;
- data = (MFASYNCRESULT *)result; + data = (RTWQASYNCRESULT *)result; data->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
- hr = IMFByteStreamHandler_BeginCreateObject(handler, stream, url, flags, props, NULL, &resolver->stream_callback, - (IUnknown *)result); + hr = IMFByteStreamHandler_BeginCreateObject(handler, stream, url, flags, props, NULL, + (IMFAsyncCallback *)&resolver->stream_callback, (IUnknown *)result); if (FAILED(hr)) { - IMFAsyncResult_Release(result); + IRtwqAsyncResult_Release(result); return hr; }
WaitForSingleObject(data->hEvent, INFINITE);
hr = resolver_end_create_object(resolver, OBJECT_FROM_BYTESTREAM, result, obj_type, object); - IMFAsyncResult_Release(result); + IRtwqAsyncResult_Release(result);
/* TODO: following stub is left intentionally until real source plugins are implemented. */ if (SUCCEEDED(hr)) @@ -6432,7 +6435,7 @@ static HRESULT WINAPI source_resolver_BeginCreateObjectFromURL(IMFSourceResolver struct source_resolver *resolver = impl_from_IMFSourceResolver(iface); IMFSchemeHandler *handler; IUnknown *inner_cookie = NULL; - IMFAsyncResult *result; + IRtwqAsyncResult *result; HRESULT hr;
TRACE("%p, %s, %#x, %p, %p, %p, %p.\n", iface, debugstr_w(url), flags, props, cancel_cookie, callback, state); @@ -6443,18 +6446,18 @@ static HRESULT WINAPI source_resolver_BeginCreateObjectFromURL(IMFSourceResolver if (cancel_cookie) *cancel_cookie = NULL;
- hr = MFCreateAsyncResult((IUnknown *)handler, callback, state, &result); + hr = RtwqCreateAsyncResult((IUnknown *)handler, (IRtwqAsyncCallback *)callback, state, &result); IMFSchemeHandler_Release(handler); if (FAILED(hr)) return hr;
hr = IMFSchemeHandler_BeginCreateObject(handler, url, flags, props, cancel_cookie ? &inner_cookie : NULL, - &resolver->url_callback, (IUnknown *)result); + (IMFAsyncCallback *)&resolver->url_callback, (IUnknown *)result);
if (SUCCEEDED(hr) && inner_cookie) resolver_create_cancel_object((IUnknown *)handler, OBJECT_FROM_URL, inner_cookie, cancel_cookie);
- IMFAsyncResult_Release(result); + IRtwqAsyncResult_Release(result);
return hr; } @@ -6466,7 +6469,7 @@ static HRESULT WINAPI source_resolver_EndCreateObjectFromURL(IMFSourceResolver *
TRACE("%p, %p, %p, %p.\n", iface, result, obj_type, object);
- return resolver_end_create_object(resolver, OBJECT_FROM_URL, result, obj_type, object); + return resolver_end_create_object(resolver, OBJECT_FROM_URL, (IRtwqAsyncResult *)result, obj_type, object); }
static HRESULT WINAPI source_resolver_BeginCreateObjectFromByteStream(IMFSourceResolver *iface, IMFByteStream *stream, @@ -6476,7 +6479,7 @@ static HRESULT WINAPI source_resolver_BeginCreateObjectFromByteStream(IMFSourceR struct source_resolver *resolver = impl_from_IMFSourceResolver(iface); IMFByteStreamHandler *handler; IUnknown *inner_cookie = NULL; - IMFAsyncResult *result; + IRtwqAsyncResult *result; HRESULT hr;
TRACE("%p, %p, %s, %#x, %p, %p, %p, %p.\n", iface, stream, debugstr_w(url), flags, props, cancel_cookie, @@ -6488,19 +6491,19 @@ static HRESULT WINAPI source_resolver_BeginCreateObjectFromByteStream(IMFSourceR if (cancel_cookie) *cancel_cookie = NULL;
- hr = MFCreateAsyncResult((IUnknown *)handler, callback, state, &result); + hr = RtwqCreateAsyncResult((IUnknown *)handler, (IRtwqAsyncCallback *)callback, state, &result); IMFByteStreamHandler_Release(handler); if (FAILED(hr)) return hr;
hr = IMFByteStreamHandler_BeginCreateObject(handler, stream, url, flags, props, - cancel_cookie ? &inner_cookie : NULL, &resolver->stream_callback, (IUnknown *)result); + cancel_cookie ? &inner_cookie : NULL, (IMFAsyncCallback *)&resolver->stream_callback, (IUnknown *)result);
/* Cancel object wraps underlying handler cancel cookie with context necessary to call CancelObjectCreate(). */ if (SUCCEEDED(hr) && inner_cookie) resolver_create_cancel_object((IUnknown *)handler, OBJECT_FROM_BYTESTREAM, inner_cookie, cancel_cookie);
- IMFAsyncResult_Release(result); + IRtwqAsyncResult_Release(result);
return hr; } @@ -6512,7 +6515,7 @@ static HRESULT WINAPI source_resolver_EndCreateObjectFromByteStream(IMFSourceRes
TRACE("%p, %p, %p, %p.\n", iface, result, obj_type, object);
- return resolver_end_create_object(resolver, OBJECT_FROM_BYTESTREAM, result, obj_type, object); + return resolver_end_create_object(resolver, OBJECT_FROM_BYTESTREAM, (IRtwqAsyncResult *)result, obj_type, object); }
static HRESULT WINAPI source_resolver_CancelObjectCreation(IMFSourceResolver *iface, IUnknown *cancel_cookie) @@ -7055,7 +7058,7 @@ struct event_queue struct list events; BOOL is_shut_down; BOOL notified; - IMFAsyncResult *subscriber; + IRtwqAsyncResult *subscriber; };
struct queued_event @@ -7182,7 +7185,7 @@ static void queue_notify_subscriber(struct event_queue *queue) return;
queue->notified = TRUE; - MFPutWorkItemEx(MFASYNC_CALLBACK_QUEUE_STANDARD, queue->subscriber); + RtwqPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, 0, queue->subscriber); }
static HRESULT WINAPI eventqueue_BeginGetEvent(IMFMediaEventQueue *iface, IMFAsyncCallback *callback, IUnknown *state) @@ -7203,14 +7206,14 @@ static HRESULT WINAPI eventqueue_BeginGetEvent(IMFMediaEventQueue *iface, IMFAsy else if (result_data) { if (result_data->pCallback == callback) - hr = IMFAsyncResult_GetStateNoAddRef(queue->subscriber) == state ? + hr = IRtwqAsyncResult_GetStateNoAddRef(queue->subscriber) == state ? MF_S_MULTIPLE_BEGIN : MF_E_MULTIPLE_BEGIN; else hr = MF_E_MULTIPLE_SUBSCRIBERS; } else { - hr = MFCreateAsyncResult(NULL, callback, state, &queue->subscriber); + hr = RtwqCreateAsyncResult(NULL, (IRtwqAsyncCallback *)callback, state, &queue->subscriber); if (SUCCEEDED(hr)) queue_notify_subscriber(queue); } @@ -7231,11 +7234,11 @@ static HRESULT WINAPI eventqueue_EndGetEvent(IMFMediaEventQueue *iface, IMFAsync
if (queue->is_shut_down) hr = MF_E_SHUTDOWN; - else if (queue->subscriber == result) + else if (queue->subscriber == (IRtwqAsyncResult *)result) { *event = queue_pop_event(queue); if (queue->subscriber) - IMFAsyncResult_Release(queue->subscriber); + IRtwqAsyncResult_Release(queue->subscriber); queue->subscriber = NULL; queue->notified = FALSE; hr = *event ? S_OK : E_FAIL; @@ -8101,7 +8104,7 @@ HRESULT WINAPI MFCreateSystemTimeSource(IMFPresentationTimeSource **time_source)
struct async_create_file { - IMFAsyncCallback IMFAsyncCallback_iface; + IRtwqAsyncCallback IRtwqAsyncCallback_iface; LONG refcount; MF_FILE_ACCESSMODE access_mode; MF_FILE_OPENMODE open_mode; @@ -8112,25 +8115,25 @@ struct async_create_file struct async_create_file_result { struct list entry; - IMFAsyncResult *result; + IRtwqAsyncResult *result; IMFByteStream *stream; };
static struct list async_create_file_results = LIST_INIT(async_create_file_results); static CRITICAL_SECTION async_create_file_cs = { NULL, -1, 0, 0, 0, 0 };
-static struct async_create_file *impl_from_create_file_IMFAsyncCallback(IMFAsyncCallback *iface) +static struct async_create_file *impl_from_create_file_IRtwqAsyncCallback(IRtwqAsyncCallback *iface) { - return CONTAINING_RECORD(iface, struct async_create_file, IMFAsyncCallback_iface); + return CONTAINING_RECORD(iface, struct async_create_file, IRtwqAsyncCallback_iface); }
-static HRESULT WINAPI async_create_file_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) +static HRESULT WINAPI async_create_file_callback_QueryInterface(IRtwqAsyncCallback *iface, REFIID riid, void **obj) { - if (IsEqualIID(riid, &IID_IMFAsyncCallback) || + if (IsEqualIID(riid, &IID_IRtwqAsyncCallback) || IsEqualIID(riid, &IID_IUnknown)) { *obj = iface; - IMFAsyncCallback_AddRef(iface); + IRtwqAsyncCallback_AddRef(iface); return S_OK; }
@@ -8138,9 +8141,9 @@ static HRESULT WINAPI async_create_file_callback_QueryInterface(IMFAsyncCallback return E_NOINTERFACE; }
-static ULONG WINAPI async_create_file_callback_AddRef(IMFAsyncCallback *iface) +static ULONG WINAPI async_create_file_callback_AddRef(IRtwqAsyncCallback *iface) { - struct async_create_file *async = impl_from_create_file_IMFAsyncCallback(iface); + struct async_create_file *async = impl_from_create_file_IRtwqAsyncCallback(iface); ULONG refcount = InterlockedIncrement(&async->refcount);
TRACE("%p, refcount %u.\n", iface, refcount); @@ -8148,9 +8151,9 @@ static ULONG WINAPI async_create_file_callback_AddRef(IMFAsyncCallback *iface) return refcount; }
-static ULONG WINAPI async_create_file_callback_Release(IMFAsyncCallback *iface) +static ULONG WINAPI async_create_file_callback_Release(IRtwqAsyncCallback *iface) { - struct async_create_file *async = impl_from_create_file_IMFAsyncCallback(iface); + struct async_create_file *async = impl_from_create_file_IRtwqAsyncCallback(iface); ULONG refcount = InterlockedDecrement(&async->refcount);
TRACE("%p, refcount %u.\n", iface, refcount); @@ -8164,19 +8167,19 @@ static ULONG WINAPI async_create_file_callback_Release(IMFAsyncCallback *iface) return refcount; }
-static HRESULT WINAPI async_create_file_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) +static HRESULT WINAPI async_create_file_callback_GetParameters(IRtwqAsyncCallback *iface, DWORD *flags, DWORD *queue) { return E_NOTIMPL; }
-static HRESULT WINAPI async_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +static HRESULT WINAPI async_create_file_callback_Invoke(IRtwqAsyncCallback *iface, IRtwqAsyncResult *result) { - struct async_create_file *async = impl_from_create_file_IMFAsyncCallback(iface); - IMFAsyncResult *caller; + struct async_create_file *async = impl_from_create_file_IRtwqAsyncCallback(iface); + IRtwqAsyncResult *caller; IMFByteStream *stream; HRESULT hr;
- caller = (IMFAsyncResult *)IMFAsyncResult_GetStateNoAddRef(result); + caller = (IRtwqAsyncResult *)IRtwqAsyncResult_GetStateNoAddRef(result);
hr = MFCreateFile(async->access_mode, async->open_mode, async->flags, async->path, &stream); if (SUCCEEDED(hr)) @@ -8187,7 +8190,7 @@ static HRESULT WINAPI async_create_file_callback_Invoke(IMFAsyncCallback *iface, if (result_item) { result_item->result = caller; - IMFAsyncResult_AddRef(caller); + IRtwqAsyncResult_AddRef(caller); result_item->stream = stream; IMFByteStream_AddRef(stream);
@@ -8199,14 +8202,14 @@ static HRESULT WINAPI async_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFByteStream_Release(stream); } else - IMFAsyncResult_SetStatus(caller, hr); + IRtwqAsyncResult_SetStatus(caller, hr);
- MFInvokeCallback(caller); + RtwqInvokeCallback(caller);
return S_OK; }
-static const IMFAsyncCallbackVtbl async_create_file_callback_vtbl = +static const IRtwqAsyncCallbackVtbl async_create_file_callback_vtbl = { async_create_file_callback_QueryInterface, async_create_file_callback_AddRef, @@ -8222,7 +8225,7 @@ HRESULT WINAPI MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode, MF_FILE_OPENMOD const WCHAR *path, IMFAsyncCallback *callback, IUnknown *state, IUnknown **cancel_cookie) { struct async_create_file *async = NULL; - IMFAsyncResult *caller, *item = NULL; + IRtwqAsyncResult *caller, *item = NULL; HRESULT hr;
TRACE("%#x, %#x, %#x, %s, %p, %p, %p.\n", access_mode, open_mode, flags, debugstr_w(path), callback, state, @@ -8231,7 +8234,7 @@ HRESULT WINAPI MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode, MF_FILE_OPENMOD if (cancel_cookie) *cancel_cookie = NULL;
- if (FAILED(hr = MFCreateAsyncResult(NULL, callback, state, &caller))) + if (FAILED(hr = RtwqCreateAsyncResult(NULL, (IRtwqAsyncCallback *)callback, state, &caller))) return hr;
async = heap_alloc(sizeof(*async)); @@ -8241,7 +8244,7 @@ HRESULT WINAPI MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode, MF_FILE_OPENMOD goto failed; }
- async->IMFAsyncCallback_iface.lpVtbl = &async_create_file_callback_vtbl; + async->IRtwqAsyncCallback_iface.lpVtbl = &async_create_file_callback_vtbl; async->refcount = 1; async->access_mode = access_mode; async->open_mode = open_mode; @@ -8249,7 +8252,7 @@ HRESULT WINAPI MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode, MF_FILE_OPENMOD if (FAILED(hr = heap_strdupW(path, &async->path))) goto failed;
- hr = MFCreateAsyncResult(NULL, &async->IMFAsyncCallback_iface, (IUnknown *)caller, &item); + hr = RtwqCreateAsyncResult(NULL, &async->IRtwqAsyncCallback_iface, (IUnknown *)caller, &item); if (FAILED(hr)) goto failed;
@@ -8259,15 +8262,15 @@ HRESULT WINAPI MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode, MF_FILE_OPENMOD IUnknown_AddRef(*cancel_cookie); }
- hr = MFInvokeCallback(item); + hr = RtwqInvokeCallback(item);
failed: if (async) - IMFAsyncCallback_Release(&async->IMFAsyncCallback_iface); + IRtwqAsyncCallback_Release(&async->IRtwqAsyncCallback_iface); if (item) - IMFAsyncResult_Release(item); + IRtwqAsyncResult_Release(item); if (caller) - IMFAsyncResult_Release(caller); + IRtwqAsyncResult_Release(caller);
return hr; } @@ -8276,11 +8279,11 @@ static HRESULT async_create_file_pull_result(IUnknown *unk, IMFByteStream **stre { struct async_create_file_result *item; HRESULT hr = MF_E_UNEXPECTED; - IMFAsyncResult *result; + IRtwqAsyncResult *result;
*stream = NULL;
- if (FAILED(IUnknown_QueryInterface(unk, &IID_IMFAsyncResult, (void **)&result))) + if (FAILED(IUnknown_QueryInterface(unk, &IID_IRtwqAsyncResult, (void **)&result))) return hr;
EnterCriticalSection(&async_create_file_cs); @@ -8290,7 +8293,7 @@ static HRESULT async_create_file_pull_result(IUnknown *unk, IMFByteStream **stre if (result == item->result) { *stream = item->stream; - IMFAsyncResult_Release(item->result); + IRtwqAsyncResult_Release(item->result); list_remove(&item->entry); heap_free(item); break; @@ -8300,9 +8303,9 @@ static HRESULT async_create_file_pull_result(IUnknown *unk, IMFByteStream **stre LeaveCriticalSection(&async_create_file_cs);
if (*stream) - hr = IMFAsyncResult_GetStatus(result); + hr = IRtwqAsyncResult_GetStatus(result);
- IMFAsyncResult_Release(result); + IRtwqAsyncResult_Release(result);
return hr; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mfplat.spec | 2 +- dlls/mfplat/queue.c | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-)
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 9f08d1aff2..5af717419b 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -40,7 +40,7 @@ @ stdcall MFCreate2DMediaBuffer(long long long long ptr) @ stub MFCreateAMMediaTypeFromMFMediaType @ stdcall MFCreateAlignedMemoryBuffer(long long ptr) -@ stdcall MFCreateAsyncResult(ptr ptr ptr ptr) +@ stdcall MFCreateAsyncResult(ptr ptr ptr ptr) rtworkq.RtwqCreateAsyncResult @ stdcall MFCreateAttributes(ptr long) @ stub MFCreateAudioMediaType @ stdcall MFCreateCollection(ptr) diff --git a/dlls/mfplat/queue.c b/dlls/mfplat/queue.c index d39d6af3a5..6ad3977e59 100644 --- a/dlls/mfplat/queue.c +++ b/dlls/mfplat/queue.c @@ -139,16 +139,6 @@ HRESULT WINAPI MFInvokeCallback(IMFAsyncResult *result) return RtwqInvokeCallback((IRtwqAsyncResult *)result); }
-/*********************************************************************** - * MFCreateAsyncResult (mfplat.@) - */ -HRESULT WINAPI MFCreateAsyncResult(IUnknown *object, IMFAsyncCallback *callback, IUnknown *state, IMFAsyncResult **out) -{ - TRACE("%p, %p, %p, %p.\n", object, callback, state, out); - - return RtwqCreateAsyncResult(object, (IRtwqAsyncCallback *)callback, state, (IRtwqAsyncResult **)out); -} - /*********************************************************************** * MFGetTimerPeriodicity (mfplat.@) */
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/buffer.c | 229 +++++++++++++++++++++++++++++++---- dlls/mfplat/mediatype.c | 54 +++++---- dlls/mfplat/mfplat_private.h | 2 +- dlls/mfplat/tests/mfplat.c | 193 ++++++++++++++++++++++++++++- 4 files changed, 427 insertions(+), 51 deletions(-)
diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c index b1d353a59b..69633134f5 100644 --- a/dlls/mfplat/buffer.c +++ b/dlls/mfplat/buffer.c @@ -35,6 +35,21 @@ struct memory_buffer BYTE *data; DWORD max_length; DWORD current_length; + + struct + { + BYTE *linear_buffer; + unsigned int plane_size; + + BYTE *scanline0; + unsigned int width; + unsigned int height; + int pitch; + + unsigned int locks; + } _2d; + + CRITICAL_SECTION cs; };
enum sample_prop_flags @@ -113,6 +128,8 @@ static ULONG WINAPI memory_buffer_Release(IMFMediaBuffer *iface)
if (!refcount) { + DeleteCriticalSection(&buffer->cs); + heap_free(buffer->_2d.linear_buffer); heap_free(buffer->data); heap_free(buffer); } @@ -226,13 +243,73 @@ static HRESULT WINAPI memory_1d_2d_buffer_QueryInterface(IMFMediaBuffer *iface, return S_OK; }
+static HRESULT WINAPI memory_1d_2d_buffer_Lock(IMFMediaBuffer *iface, BYTE **data, DWORD *max_length, DWORD *current_length) +{ + struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); + HRESULT hr = S_OK; + + TRACE("%p, %p, %p, %p.\n", iface, data, max_length, current_length); + + if (!data) + return E_POINTER; + + /* Allocate linear buffer and return it as a copy of current content. Maximum and current length are + unrelated to 2D buffer maximum allocate length, or maintained current length. */ + + EnterCriticalSection(&buffer->cs); + + if (!buffer->_2d.linear_buffer && buffer->_2d.locks) + hr = MF_E_INVALIDREQUEST; + else if (!buffer->_2d.linear_buffer) + { + if (!(buffer->_2d.linear_buffer = heap_alloc(ALIGN_SIZE(buffer->_2d.plane_size, 64)))) + hr = E_OUTOFMEMORY; + } + + if (SUCCEEDED(hr)) + { + ++buffer->_2d.locks; + *data = buffer->_2d.linear_buffer; + if (max_length) + *max_length = buffer->_2d.plane_size; + if (current_length) + *current_length = buffer->_2d.plane_size; + } + + LeaveCriticalSection(&buffer->cs); + + return hr; +} + +static HRESULT WINAPI memory_1d_2d_buffer_Unlock(IMFMediaBuffer *iface) +{ + struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); + + TRACE("%p.\n", iface); + + EnterCriticalSection(&buffer->cs); + + if (buffer->_2d.linear_buffer && !--buffer->_2d.locks) + { + MFCopyImage(buffer->data, buffer->_2d.pitch, buffer->_2d.linear_buffer, buffer->_2d.width, + buffer->_2d.width, buffer->_2d.height); + + heap_free(buffer->_2d.linear_buffer); + buffer->_2d.linear_buffer = NULL; + } + + LeaveCriticalSection(&buffer->cs); + + return S_OK; +} + static const IMFMediaBufferVtbl memory_1d_2d_buffer_vtbl = { memory_1d_2d_buffer_QueryInterface, memory_buffer_AddRef, memory_buffer_Release, - memory_buffer_Lock, - memory_buffer_Unlock, + memory_1d_2d_buffer_Lock, + memory_1d_2d_buffer_Unlock, memory_buffer_GetCurrentLength, memory_buffer_SetCurrentLength, memory_buffer_GetMaxLength, @@ -256,39 +333,117 @@ static ULONG WINAPI memory_2d_buffer_Release(IMF2DBuffer2 *iface) return IMFMediaBuffer_Release(&buffer->IMFMediaBuffer_iface); }
+static HRESULT memory_2d_buffer_lock(struct memory_buffer *buffer, BYTE **scanline0, LONG *pitch, + BYTE **buffer_start, DWORD *buffer_length) +{ + HRESULT hr = S_OK; + + if (buffer->_2d.linear_buffer) + hr = MF_E_UNEXPECTED; + else + { + ++buffer->_2d.locks; + *scanline0 = buffer->data; + *pitch = buffer->_2d.pitch; + if (buffer_start) + *buffer_start = buffer->data; + if (buffer_length) + *buffer_length = buffer->max_length; + } + + return hr; +} + static HRESULT WINAPI memory_2d_buffer_Lock2D(IMF2DBuffer2 *iface, BYTE **scanline0, LONG *pitch) { - FIXME("%p, %p, %p.\n", iface, scanline0, pitch); + struct memory_buffer *buffer = impl_from_IMF2DBuffer2(iface); + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p, %p.\n", iface, scanline0, pitch); + + if (!scanline0 || !pitch) + return E_POINTER; + + EnterCriticalSection(&buffer->cs); + + hr = memory_2d_buffer_lock(buffer, scanline0, pitch, NULL, NULL); + + LeaveCriticalSection(&buffer->cs); + + return hr; }
static HRESULT WINAPI memory_2d_buffer_Unlock2D(IMF2DBuffer2 *iface) { - FIXME("%p.\n", iface); + struct memory_buffer *buffer = impl_from_IMF2DBuffer2(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p.\n", iface); + + EnterCriticalSection(&buffer->cs); + + if (!buffer->_2d.linear_buffer) + { + if (buffer->_2d.locks) + --buffer->_2d.locks; + else + hr = HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED); + } + + LeaveCriticalSection(&buffer->cs); + + return hr; }
static HRESULT WINAPI memory_2d_buffer_GetScanline0AndPitch(IMF2DBuffer2 *iface, BYTE **scanline0, LONG *pitch) { - FIXME("%p, %p, %p.\n", iface, scanline0, pitch); + struct memory_buffer *buffer = impl_from_IMF2DBuffer2(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %p, %p.\n", iface, scanline0, pitch); + + if (!scanline0 || !pitch) + return E_POINTER; + + EnterCriticalSection(&buffer->cs); + + if (buffer->_2d.linear_buffer || !buffer->_2d.locks) + hr = HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED); + else + { + *scanline0 = buffer->_2d.scanline0; + *pitch = buffer->_2d.pitch; + } + + LeaveCriticalSection(&buffer->cs); + + return hr; }
static HRESULT WINAPI memory_2d_buffer_IsContiguousFormat(IMF2DBuffer2 *iface, BOOL *is_contiguous) { - FIXME("%p, %p.\n", iface, is_contiguous); + TRACE("%p, %p.\n", iface, is_contiguous);
- return E_NOTIMPL; + if (!is_contiguous) + return E_POINTER; + + *is_contiguous = FALSE; + + return S_OK; }
static HRESULT WINAPI memory_2d_buffer_GetContiguousLength(IMF2DBuffer2 *iface, DWORD *length) { - FIXME("%p, %p.\n", iface, length); + struct memory_buffer *buffer = impl_from_IMF2DBuffer2(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, length); + + if (!length) + return E_POINTER; + + *length = buffer->_2d.plane_size; + + return S_OK; }
static HRESULT WINAPI memory_2d_buffer_ContiguousCopyTo(IMF2DBuffer2 *iface, BYTE *dest_buffer, DWORD dest_length) @@ -308,9 +463,21 @@ static HRESULT WINAPI memory_2d_buffer_ContiguousCopyFrom(IMF2DBuffer2 *iface, c static HRESULT WINAPI memory_2d_buffer_Lock2DSize(IMF2DBuffer2 *iface, MF2DBuffer_LockFlags flags, BYTE **scanline0, LONG *pitch, BYTE **buffer_start, DWORD *buffer_length) { - FIXME("%p, %#x, %p, %p, %p, %p.\n", iface, flags, scanline0, pitch, buffer_start, buffer_length); + struct memory_buffer *buffer = impl_from_IMF2DBuffer2(iface); + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %#x, %p, %p, %p, %p.\n", iface, flags, scanline0, pitch, buffer_start, buffer_length); + + if (!scanline0 || !pitch || !buffer_start || !buffer_length) + return E_POINTER; + + EnterCriticalSection(&buffer->cs); + + hr = memory_2d_buffer_lock(buffer, scanline0, pitch, buffer_start, buffer_length); + + LeaveCriticalSection(&buffer->cs); + + return hr; }
static HRESULT WINAPI memory_2d_buffer_Copy2DTo(IMF2DBuffer2 *iface, IMF2DBuffer2 *dest_buffer) @@ -347,6 +514,7 @@ static HRESULT memory_buffer_init(struct memory_buffer *buffer, DWORD max_length buffer->refcount = 1; buffer->max_length = max_length; buffer->current_length = 0; + InitializeCriticalSection(&buffer->cs);
return S_OK; } @@ -377,12 +545,14 @@ static HRESULT create_1d_buffer(DWORD max_length, DWORD alignment, IMFMediaBuffe return S_OK; }
-static HRESULT create_2d_buffer(DWORD width, DWORD height, DWORD fourcc, IMFMediaBuffer **buffer) +static HRESULT create_2d_buffer(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up, IMFMediaBuffer **buffer) { + unsigned int bpp, max_length, plane_size; struct memory_buffer *object; - unsigned int bpp, max_length; GUID subtype; + BOOL is_yuv; HRESULT hr; + int pitch;
if (!buffer) return E_POINTER; @@ -392,30 +562,43 @@ static HRESULT create_2d_buffer(DWORD width, DWORD height, DWORD fourcc, IMFMedi memcpy(&subtype, &MFVideoFormat_Base, sizeof(subtype)); subtype.Data1 = fourcc;
- if (!(bpp = mf_format_get_bpp(&subtype))) + if (!(bpp = mf_format_get_bpp(&subtype, &is_yuv))) + return MF_E_INVALIDMEDIATYPE; + + if (is_yuv && bottom_up) return MF_E_INVALIDMEDIATYPE;
+ if (FAILED(hr = MFGetPlaneSize(fourcc, width, height, &plane_size))) + return hr; + object = heap_alloc_zero(sizeof(*object)); if (!object) return E_OUTOFMEMORY;
+ pitch = ALIGN_SIZE(width * bpp, 64); + switch (fourcc) { case MAKEFOURCC('N','V','1','2'): - max_length = ALIGN_SIZE(width * bpp, 64) * height * 3 / 2; + max_length = pitch * height * 3 / 2; break; default: - max_length = ALIGN_SIZE(width * bpp, 64) * height; + max_length = pitch * height; }
- hr = memory_buffer_init(object, max_length, MF_1_BYTE_ALIGNMENT, &memory_1d_2d_buffer_vtbl); - object->IMF2DBuffer2_iface.lpVtbl = &memory_2d_buffer_vtbl; - if (FAILED(hr)) + if (FAILED(hr = memory_buffer_init(object, max_length, MF_1_BYTE_ALIGNMENT, &memory_1d_2d_buffer_vtbl))) { heap_free(object); return hr; }
+ object->IMF2DBuffer2_iface.lpVtbl = &memory_2d_buffer_vtbl; + object->_2d.plane_size = plane_size; + object->_2d.width = width * bpp; + object->_2d.height = height; + object->_2d.pitch = bottom_up ? -pitch : pitch; + object->_2d.scanline0 = bottom_up ? object->data + object->_2d.width * (object->_2d.height - 1) : object->data; + *buffer = &object->IMFMediaBuffer_iface;
return S_OK; @@ -445,7 +628,7 @@ HRESULT WINAPI MFCreate2DMediaBuffer(DWORD width, DWORD height, DWORD fourcc, BO { TRACE("%u, %u, %#x, %d, %p.\n", width, height, fourcc, bottom_up, buffer);
- return create_2d_buffer(width, height, fourcc, buffer); + return create_2d_buffer(width, height, fourcc, bottom_up, buffer); }
static unsigned int buffer_get_aligned_length(unsigned int length, unsigned int alignment) diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index d764baf0b9..142ee69cf6 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -1768,9 +1768,10 @@ HRESULT WINAPI MFCreatePresentationDescriptor(DWORD count, IMFStreamDescriptor * struct uncompressed_video_format { const GUID *subtype; - unsigned int bytes_per_pixel; - unsigned int alignment; - BOOL bottom_up; + unsigned char bytes_per_pixel; + unsigned char alignment; + unsigned char bottom_up; + unsigned char yuv; };
static int __cdecl uncompressed_video_format_compare(const void *a, const void *b) @@ -1782,24 +1783,24 @@ static int __cdecl uncompressed_video_format_compare(const void *a, const void *
static const struct uncompressed_video_format video_formats[] = { - { &MFVideoFormat_RGB24, 3, 3, 1 }, - { &MFVideoFormat_ARGB32, 4, 3, 1 }, - { &MFVideoFormat_RGB32, 4, 3, 1 }, - { &MFVideoFormat_RGB565, 2, 3, 1 }, - { &MFVideoFormat_RGB555, 2, 3, 1 }, - { &MFVideoFormat_A2R10G10B10, 4, 3, 1 }, - { &MFVideoFormat_RGB8, 1, 3, 1 }, - { &MFVideoFormat_L8, 1, 3, 1 }, - { &MFVideoFormat_AYUV, 4, 3, 0 }, - { &MFVideoFormat_IMC1, 2, 3, 0 }, - { &MFVideoFormat_IMC2, 1, 0, 0 }, - { &MFVideoFormat_IMC3, 2, 3, 0 }, - { &MFVideoFormat_IMC4, 1, 0, 0 }, - { &MFVideoFormat_NV12, 1, 0, 0 }, - { &MFVideoFormat_D16, 2, 3, 0 }, - { &MFVideoFormat_L16, 2, 3, 0 }, - { &MFVideoFormat_YV12, 1, 0, 0 }, - { &MFVideoFormat_A16B16G16R16F, 8, 3, 1 }, + { &MFVideoFormat_RGB24, 3, 3, 1, 0 }, + { &MFVideoFormat_ARGB32, 4, 3, 1, 0 }, + { &MFVideoFormat_RGB32, 4, 3, 1, 0 }, + { &MFVideoFormat_RGB565, 2, 3, 1, 0 }, + { &MFVideoFormat_RGB555, 2, 3, 1, 0 }, + { &MFVideoFormat_A2R10G10B10, 4, 3, 1, 0 }, + { &MFVideoFormat_RGB8, 1, 3, 1, 0 }, + { &MFVideoFormat_L8, 1, 3, 1, 0 }, + { &MFVideoFormat_AYUV, 4, 3, 0, 1 }, + { &MFVideoFormat_IMC1, 2, 3, 0, 1 }, + { &MFVideoFormat_IMC2, 1, 0, 0, 1 }, + { &MFVideoFormat_IMC3, 2, 3, 0, 1 }, + { &MFVideoFormat_IMC4, 1, 0, 0, 1 }, + { &MFVideoFormat_NV12, 1, 0, 0, 1 }, + { &MFVideoFormat_D16, 2, 3, 0, 0 }, + { &MFVideoFormat_L16, 2, 3, 0, 0 }, + { &MFVideoFormat_YV12, 1, 0, 0, 1 }, + { &MFVideoFormat_A16B16G16R16F, 8, 3, 1, 0 }, };
static struct uncompressed_video_format *mf_get_video_format(const GUID *subtype) @@ -1813,10 +1814,17 @@ static unsigned int mf_get_stride_for_format(const struct uncompressed_video_for return (width * format->bytes_per_pixel + format->alignment) & ~format->alignment; }
-unsigned int mf_format_get_bpp(const GUID *subtype) +unsigned int mf_format_get_bpp(const GUID *subtype, BOOL *is_yuv) { struct uncompressed_video_format *format = mf_get_video_format(subtype); - return format ? format->bytes_per_pixel : 0; + + if (format) + { + *is_yuv = format->yuv; + return format->bytes_per_pixel; + } + + return 0; }
/*********************************************************************** diff --git a/dlls/mfplat/mfplat_private.h b/dlls/mfplat/mfplat_private.h index d68a8ed550..0c374f116b 100644 --- a/dlls/mfplat/mfplat_private.h +++ b/dlls/mfplat/mfplat_private.h @@ -114,7 +114,7 @@ static inline BOOL mf_array_reserve(void **elements, size_t *capacity, size_t co return TRUE; }
-extern unsigned int mf_format_get_bpp(const GUID *subtype) DECLSPEC_HIDDEN; +extern unsigned int mf_format_get_bpp(const GUID *subtype, BOOL *is_yuv) DECLSPEC_HIDDEN;
static inline const char *debugstr_propvar(const PROPVARIANT *v) { diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 621b5b4393..bf63337b60 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -41,6 +41,7 @@ #define D3D11_INIT_GUID #include "initguid.h" #include "d3d11_4.h" +#include "d3d9types.h"
DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19); DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21); @@ -4599,11 +4600,31 @@ static void test_MFGetStrideForBitmapInfoHeader(void)
static void test_MFCreate2DMediaBuffer(void) { + static const struct _2d_buffer_test + { + unsigned int width; + unsigned int height; + unsigned int fourcc; + unsigned int contiguous_length; + } _2d_buffer_tests[] = + { + { 2, 2, MAKEFOURCC('N','V','1','2'), 6 }, + { 4, 2, MAKEFOURCC('N','V','1','2'), 12 }, + { 2, 4, MAKEFOURCC('N','V','1','2'), 12 }, + { 1, 3, MAKEFOURCC('N','V','1','2'), 4 }, + + { 2, 4, D3DFMT_A8R8G8B8, 32 }, + { 1, 4, D3DFMT_A8R8G8B8, 16 }, + { 4, 1, D3DFMT_A8R8G8B8, 16 }, + }; + unsigned int max_length, length, length2; + BYTE *buffer_start, *data, *data2; IMF2DBuffer2 *_2dbuffer2; IMF2DBuffer *_2dbuffer; IMFMediaBuffer *buffer; - DWORD length; + int i, pitch; HRESULT hr; + BOOL ret;
if (!pMFCreate2DMediaBuffer) { @@ -4617,26 +4638,190 @@ static void test_MFCreate2DMediaBuffer(void) hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL); ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
+ /* YUV formats can't be bottom-up. */ + hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer); + ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr); + hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer); ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
- hr = IMFMediaBuffer_GetMaxLength(buffer, &length); + /* Full backing buffer size, with 64 bytes per row alignment. */ + hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length); ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr); - ok(length > 0, "Unexpected length.\n"); + ok(max_length > 0, "Unexpected length %u.\n", max_length); + + hr = IMFMediaBuffer_GetCurrentLength(buffer, &length); + ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr); + ok(!length, "Unexpected length.\n"); + + hr = IMFMediaBuffer_SetCurrentLength(buffer, 10); + 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 == 10, "Unexpected length.\n"); + + /* Linear lock/unlock. */ + + hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length); + ok(FAILED(hr), "Unexpected hr %#x.\n", hr); + + /* Linear locking call returns plane size.*/ + hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length); + ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr); + ok(max_length == length, "Unexpected length.\n"); + + length = 0; + pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length); + ok(max_length == length && length == 9, "Unexpected length %u.\n", length); + + /* Already locked */ + hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL); + ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr); + ok(data2 == data, "Unexpected pointer.\n"); + + hr = IMFMediaBuffer_Unlock(buffer); + ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer); ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr); - IMF2DBuffer_Release(_2dbuffer); + + hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length); + ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr); + ok(length == 9, "Unexpected length %u.\n", length); + + hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + /* 2D lock. */ + hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch); + ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr); + + hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch); + ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr); + + hr = IMFMediaBuffer_Unlock(buffer); + ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr); + + hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch); + ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr); + + hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch); + ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr); + ok(!!data, "Expected data pointer.\n"); + ok(pitch == 64, "Unexpected pitch %d.\n", pitch); + + hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch); + ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr); + ok(data == data2, "Expected data pointer.\n"); + + hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + /* Active 2D lock */ + hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL); + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr); + + hr = IMF2DBuffer_Unlock2D(_2dbuffer); + ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr); + + hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL); + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr); + + hr = IMF2DBuffer_Unlock2D(_2dbuffer); + ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr); + + hr = IMF2DBuffer_Unlock2D(_2dbuffer); + ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2); ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#x.\n", hr);
if (SUCCEEDED(hr)) + { + hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch); + ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr); + + hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length); + ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr); + + hr = IMF2DBuffer_Unlock2D(_2dbuffer); + ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr); + + hr = IMF2DBuffer_Unlock2D(_2dbuffer); + ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr); + + /* Flags are ignored. */ + hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length); + ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr); + + hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, &length); + ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr); + + hr = IMF2DBuffer_Unlock2D(_2dbuffer); + ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr); + + hr = IMF2DBuffer_Unlock2D(_2dbuffer); + ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr); + + hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + IMF2DBuffer2_Release(_2dbuffer2); + } else win_skip("IMF2DBuffer2 is not supported.\n");
+ IMF2DBuffer_Release(_2dbuffer); + IMFMediaBuffer_Release(buffer); + + for (i = 0; i < ARRAY_SIZE(_2d_buffer_tests); ++i) + { + const struct _2d_buffer_test *ptr = &_2d_buffer_tests[i]; + + hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->fourcc, FALSE, &buffer); + ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr); + + hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer); + ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr); + + hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length); + ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr); + ok(length == ptr->contiguous_length, "%d: unexpected contiguous length %u for %u x %u, format %s.\n", + i, length, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4)); + + hr = pMFGetPlaneSize(ptr->fourcc, ptr->width, ptr->height, &length2); + ok(hr == S_OK, "Failed to get plane size, hr %#x.\n", hr); + ok(length2 == length, "%d: contiguous length %u does not match plane size %u.\n", i, length, length2); + + ret = TRUE; + hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret); + ok(hr == S_OK, "Failed to get format flag, hr %#x.\n", hr); + ok(!ret, "%d: unexpected format flag %d.\n", i, ret); + + IMF2DBuffer_Release(_2dbuffer); + + IMFMediaBuffer_Release(buffer); + } }
static void test_MFCreateMediaBufferFromMediaType(void)