Commit abcea9a3 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

mfplat: Implement MFCalculateImageSize().

parent 9caaebf2
......@@ -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;
}
......@@ -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
......
......@@ -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();
}
......@@ -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);
......
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