[PATCH 4/7] mfplat: Implement MFCalculateImageSize().

Nikolay Sivov nsivov at codeweavers.com
Thu Mar 21 02:42:55 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 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 272b1c2c87..4e6fa80f9c 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 be5d8b2205..d8ed5f90e5 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 9985f59172..b420513e3f 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 b38953c855..1b8eafa9ad 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);
-- 
2.20.1




More information about the wine-devel mailing list