Nikolay Sivov : mfplat: Implement MFCalculateImageSize().
Alexandre Julliard
julliard at winehq.org
Thu Mar 21 17:21:19 CDT 2019
Module: wine
Branch: master
Commit: abcea9a35a89a75bb8eacf0e3ebee626d2b9fad8
URL: https://source.winehq.org/git/wine.git/?a=commit;h=abcea9a35a89a75bb8eacf0e3ebee626d2b9fad8
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Thu Mar 21 10:42:55 2019 +0300
mfplat: Implement MFCalculateImageSize().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mfplat/mediatype.c | 47 +++++++++++++++++++++++++++++++++++++++++
dlls/mfplat/mfplat.spec | 2 +-
dlls/mfplat/tests/mfplat.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++
include/mfapi.h | 21 ++++++++++++++++---
4 files changed, 118 insertions(+), 4 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c
index 272b1c2..4e6fa80 100644
--- a/dlls/mfplat/mediatype.c
+++ b/dlls/mfplat/mediatype.c
@@ -1449,3 +1449,50 @@ HRESULT WINAPI MFCreatePresentationDescriptor(DWORD count, IMFStreamDescriptor *
return S_OK;
}
+
+struct uncompressed_video_format
+{
+ const GUID *subtype;
+ unsigned int bytes_per_pixel;
+};
+
+static int uncompressed_video_format_compare(const void *a, const void *b)
+{
+ const GUID *guid = a;
+ const struct uncompressed_video_format *format = b;
+ return memcmp(guid, format->subtype, sizeof(*guid));
+}
+
+/***********************************************************************
+ * MFCalculateImageSize (mfplat.@)
+ */
+HRESULT WINAPI MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height, UINT32 *size)
+{
+ static const struct uncompressed_video_format video_formats[] =
+ {
+ { &MFVideoFormat_RGB24, 3 },
+ { &MFVideoFormat_ARGB32, 4 },
+ { &MFVideoFormat_RGB32, 4 },
+ { &MFVideoFormat_RGB565, 2 },
+ { &MFVideoFormat_RGB555, 2 },
+ { &MFVideoFormat_A2R10G10B10, 4 },
+ { &MFVideoFormat_RGB8, 1 },
+ { &MFVideoFormat_A16B16G16R16F, 8 },
+ };
+ struct uncompressed_video_format *format;
+
+ TRACE("%s, %u, %u, %p.\n", debugstr_guid(subtype), width, height, size);
+
+ format = bsearch(subtype, video_formats, ARRAY_SIZE(video_formats), sizeof(*video_formats),
+ uncompressed_video_format_compare);
+ if (format)
+ {
+ *size = ((width * format->bytes_per_pixel + 3) & ~3) * height;
+ }
+ else
+ {
+ *size = 0;
+ }
+
+ return format ? S_OK : E_INVALIDARG;
+}
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
index be5d8b2..d8ed5f9 100644
--- a/dlls/mfplat/mfplat.spec
+++ b/dlls/mfplat/mfplat.spec
@@ -26,7 +26,7 @@
@ stub MFBeginUnregisterWorkQueueWithMMCSS
@ stub MFBlockThread
@ stub MFCalculateBitmapImageSize
-@ stub MFCalculateImageSize
+@ stdcall MFCalculateImageSize(ptr long long ptr)
@ stub MFCancelCreateFile
@ stdcall MFCancelWorkItem(int64)
@ stub MFCompareFullToPartialMediaType
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
index 9985f59..b420513 100644
--- a/dlls/mfplat/tests/mfplat.c
+++ b/dlls/mfplat/tests/mfplat.c
@@ -2429,6 +2429,57 @@ static void test_stream_descriptor(void)
IMFStreamDescriptor_Release(stream_desc);
}
+static void test_MFCalculateImageSize(void)
+{
+ static const struct image_size_test
+ {
+ const GUID *subtype;
+ UINT32 width;
+ UINT32 height;
+ UINT32 size;
+ }
+ image_size_tests[] =
+ {
+ { &MFVideoFormat_RGB8, 3, 5, 20 },
+ { &MFVideoFormat_RGB8, 1, 1, 4 },
+ { &MFVideoFormat_RGB555, 3, 5, 40 },
+ { &MFVideoFormat_RGB555, 1, 1, 4 },
+ { &MFVideoFormat_RGB565, 3, 5, 40 },
+ { &MFVideoFormat_RGB565, 1, 1, 4 },
+ { &MFVideoFormat_RGB24, 3, 5, 60 },
+ { &MFVideoFormat_RGB24, 1, 1, 4 },
+ { &MFVideoFormat_RGB32, 3, 5, 60 },
+ { &MFVideoFormat_RGB32, 1, 1, 4 },
+ { &MFVideoFormat_ARGB32, 3, 5, 60 },
+ { &MFVideoFormat_ARGB32, 1, 1, 4 },
+ { &MFVideoFormat_A2R10G10B10, 3, 5, 60 },
+ { &MFVideoFormat_A2R10G10B10, 1, 1, 4 },
+ { &MFVideoFormat_A16B16G16R16F, 3, 5, 120 },
+ { &MFVideoFormat_A16B16G16R16F, 1, 1, 8 },
+ };
+ unsigned int i;
+ UINT32 size;
+ HRESULT hr;
+
+ size = 1;
+ hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
+ ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#x.\n", hr);
+ ok(size == 0, "Unexpected size %u.\n", size);
+
+ for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
+ {
+ /* Those are supported since Win10. */
+ BOOL is_broken = IsEqualGUID(image_size_tests[i].subtype, &MFVideoFormat_A16B16G16R16F) ||
+ IsEqualGUID(image_size_tests[i].subtype, &MFVideoFormat_A2R10G10B10);
+
+ hr = MFCalculateImageSize(image_size_tests[i].subtype, image_size_tests[i].width,
+ image_size_tests[i].height, &size);
+ ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#x.\n", i, hr);
+ ok(size == image_size_tests[i].size, "%u: unexpected image size %u, expected %u.\n", i, size,
+ image_size_tests[i].size);
+ }
+}
+
START_TEST(mfplat)
{
CoInitialize(NULL);
@@ -2458,6 +2509,7 @@ START_TEST(mfplat)
test_system_time_source();
test_MFInvokeCallback();
test_stream_descriptor();
+ test_MFCalculateImageSize();
CoUninitialize();
}
diff --git a/include/mfapi.h b/include/mfapi.h
index b38953c..1b8eafa 100644
--- a/include/mfapi.h
+++ b/include/mfapi.h
@@ -48,11 +48,25 @@ extern "C" {
DEFINE_GUID(name, format, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
#ifndef DIRECT3D_VERSION
-#define D3DFMT_X8R8G8B8 22
+#define D3DFMT_R8G8B8 20
+#define D3DFMT_A8R8G8B8 21
+#define D3DFMT_X8R8G8B8 22
+#define D3DFMT_R5G6B5 23
+#define D3DFMT_X1R5G5B5 24
+#define D3DFMT_A2B10G10R10 31
+#define D3DFMT_P8 41
+#define D3DFMT_A16B16G16R16F 113
#endif
-DEFINE_MEDIATYPE_GUID(MFVideoFormat_WMV3, MAKEFOURCC('W','M','V','3'));
-DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB32, D3DFMT_X8R8G8B8);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_WMV3, MAKEFOURCC('W','M','V','3'));
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB8, D3DFMT_P8);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB555, D3DFMT_X1R5G5B5);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB565, D3DFMT_R5G6B5);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB24, D3DFMT_R8G8B8);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB32, D3DFMT_X8R8G8B8);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_ARGB32, D3DFMT_A8R8G8B8);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_A2R10G10B10, D3DFMT_A2B10G10R10);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_A16B16G16R16F, D3DFMT_A16B16G16R16F);
#if defined(__cplusplus) && !defined(CINTERFACE)
typedef struct tagMFASYNCRESULT : public IMFAsyncResult {
@@ -172,6 +186,7 @@ typedef void (CALLBACK *MFPERIODICCALLBACK)(IUnknown *context);
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 MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height, UINT32 *size);
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);
More information about the wine-cvs
mailing list