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

mfplat: Add MFGetStrideForBitmapInfoHeader().

parent a60b3985
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#define COBJMACROS #define COBJMACROS
#include "mfplat_private.h" #include "mfplat_private.h"
#include "d3d9types.h"
#include "initguid.h" #include "initguid.h"
#include "ks.h" #include "ks.h"
...@@ -1763,6 +1764,8 @@ struct uncompressed_video_format ...@@ -1763,6 +1764,8 @@ struct uncompressed_video_format
{ {
const GUID *subtype; const GUID *subtype;
unsigned int bytes_per_pixel; unsigned int bytes_per_pixel;
unsigned int alignment;
BOOL bottom_up;
}; };
static int __cdecl uncompressed_video_format_compare(const void *a, const void *b) static int __cdecl uncompressed_video_format_compare(const void *a, const void *b)
...@@ -1772,33 +1775,57 @@ static int __cdecl uncompressed_video_format_compare(const void *a, const void * ...@@ -1772,33 +1775,57 @@ static int __cdecl uncompressed_video_format_compare(const void *a, const void *
return memcmp(guid, format->subtype, sizeof(*guid)); return memcmp(guid, format->subtype, sizeof(*guid));
} }
static HRESULT mf_get_image_size(REFGUID subtype, unsigned int width, unsigned int height, unsigned int *size) 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_NV12, 1, 0, 0 },
{ &MFVideoFormat_D16, 2, 3, 0 },
{ &MFVideoFormat_L16, 2, 3, 0 },
{ &MFVideoFormat_A16B16G16R16F, 8, 3, 1 },
};
static struct uncompressed_video_format *mf_get_video_format(const GUID *subtype)
{
return bsearch(subtype, video_formats, ARRAY_SIZE(video_formats), sizeof(*video_formats),
uncompressed_video_format_compare);
}
static unsigned int mf_get_stride_for_format(const struct uncompressed_video_format *format, unsigned int width)
{
return (width * format->bytes_per_pixel + format->alignment) & ~format->alignment;
}
/***********************************************************************
* MFGetStrideForBitmapInfoHeader (mfplat.@)
*/
HRESULT WINAPI MFGetStrideForBitmapInfoHeader(DWORD fourcc, DWORD width, LONG *stride)
{ {
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; struct uncompressed_video_format *format;
GUID subtype;
format = bsearch(subtype, video_formats, ARRAY_SIZE(video_formats), sizeof(*video_formats), TRACE("%#x, %u, %p.\n", fourcc, width, stride);
uncompressed_video_format_compare);
if (format) memcpy(&subtype, &MFVideoFormat_Base, sizeof(subtype));
{ subtype.Data1 = fourcc;
*size = ((width * format->bytes_per_pixel + 3) & ~3) * height;
} if (!(format = mf_get_video_format(&subtype)))
else
{ {
*size = 0; *stride = 0;
return MF_E_INVALIDMEDIATYPE;
} }
return format ? S_OK : E_INVALIDARG; *stride = mf_get_stride_for_format(format, width);
if (format->bottom_up)
*stride *= -1;
return S_OK;
} }
/*********************************************************************** /***********************************************************************
...@@ -1806,24 +1833,65 @@ static HRESULT mf_get_image_size(REFGUID subtype, unsigned int width, unsigned i ...@@ -1806,24 +1833,65 @@ static HRESULT mf_get_image_size(REFGUID subtype, unsigned int width, unsigned i
*/ */
HRESULT WINAPI MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height, UINT32 *size) HRESULT WINAPI MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height, UINT32 *size)
{ {
struct uncompressed_video_format *format;
unsigned int stride;
TRACE("%s, %u, %u, %p.\n", debugstr_mf_guid(subtype), width, height, size); TRACE("%s, %u, %u, %p.\n", debugstr_mf_guid(subtype), width, height, size);
return mf_get_image_size(subtype, width, height, size); if (!(format = mf_get_video_format(subtype)))
{
*size = 0;
return E_INVALIDARG;
}
switch (subtype->Data1)
{
case MAKEFOURCC('N','V','1','2'):
/* 2 x 2 block, interleaving UV for half the height */
*size = ((width + 1) & ~1) * height * 3 / 2;
break;
case D3DFMT_L8:
case D3DFMT_L16:
case D3DFMT_D16:
*size = width * format->bytes_per_pixel * height;
break;
default:
stride = mf_get_stride_for_format(format, width);
*size = stride * height;
}
return S_OK;
} }
/*********************************************************************** /***********************************************************************
* MFGetPlaneSize (mfplat.@) * MFGetPlaneSize (mfplat.@)
*/ */
HRESULT WINAPI MFGetPlaneSize(DWORD format, DWORD width, DWORD height, DWORD *size) HRESULT WINAPI MFGetPlaneSize(DWORD fourcc, DWORD width, DWORD height, DWORD *size)
{ {
struct uncompressed_video_format *format;
unsigned int stride;
GUID subtype; GUID subtype;
TRACE("%#x, %u, %u, %p.\n", format, width, height, size); TRACE("%#x, %u, %u, %p.\n", fourcc, width, height, size);
memcpy(&subtype, &MFVideoFormat_Base, sizeof(subtype)); memcpy(&subtype, &MFVideoFormat_Base, sizeof(subtype));
subtype.Data1 = format; subtype.Data1 = fourcc;
if (!(format = mf_get_video_format(&subtype)))
return MF_E_INVALIDMEDIATYPE;
stride = mf_get_stride_for_format(format, width);
return mf_get_image_size(&subtype, width, height, size); switch (fourcc)
{
case MAKEFOURCC('N','V','1','2'):
*size = stride * height * 3 / 2;
break;
default:
*size = stride * height;
}
return S_OK;
} }
/*********************************************************************** /***********************************************************************
......
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
@ stdcall MFGetPluginControl(ptr) @ stdcall MFGetPluginControl(ptr)
@ stub MFGetPrivateWorkqueues @ stub MFGetPrivateWorkqueues
@ stub MFGetSockaddrFromNumericName @ stub MFGetSockaddrFromNumericName
@ stub MFGetStrideForBitmapInfoHeader @ stdcall MFGetStrideForBitmapInfoHeader(long long ptr)
@ stdcall MFGetSystemTime() @ stdcall MFGetSystemTime()
@ stdcall MFGetTimerPeriodicity(ptr) @ stdcall MFGetTimerPeriodicity(ptr)
@ stub MFGetUncompressedVideoFormat @ stub MFGetUncompressedVideoFormat
......
...@@ -92,6 +92,7 @@ static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_typ ...@@ -92,6 +92,7 @@ static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_typ
static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type, static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type,
const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count); const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count);
static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height, DWORD *size); static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height, DWORD *size);
static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride);
static const WCHAR fileschemeW[] = L"file://"; static const WCHAR fileschemeW[] = L"file://";
...@@ -664,6 +665,7 @@ static void init_functions(void) ...@@ -664,6 +665,7 @@ static void init_functions(void)
X(MFCreateMFByteStreamOnStream); X(MFCreateMFByteStreamOnStream);
X(MFCreateTransformActivate); X(MFCreateTransformActivate);
X(MFGetPlaneSize); X(MFGetPlaneSize);
X(MFGetStrideForBitmapInfoHeader);
X(MFHeapAlloc); X(MFHeapAlloc);
X(MFHeapFree); X(MFHeapFree);
X(MFPutWaitingWorkItem); X(MFPutWaitingWorkItem);
...@@ -3376,6 +3378,7 @@ static void test_MFCalculateImageSize(void) ...@@ -3376,6 +3378,7 @@ static void test_MFCalculateImageSize(void)
UINT32 width; UINT32 width;
UINT32 height; UINT32 height;
UINT32 size; UINT32 size;
UINT32 plane_size; /* Matches image size when 0. */
} }
image_size_tests[] = image_size_tests[] =
{ {
...@@ -3395,6 +3398,13 @@ static void test_MFCalculateImageSize(void) ...@@ -3395,6 +3398,13 @@ static void test_MFCalculateImageSize(void)
{ &MFVideoFormat_A2R10G10B10, 1, 1, 4 }, { &MFVideoFormat_A2R10G10B10, 1, 1, 4 },
{ &MFVideoFormat_A16B16G16R16F, 3, 5, 120 }, { &MFVideoFormat_A16B16G16R16F, 3, 5, 120 },
{ &MFVideoFormat_A16B16G16R16F, 1, 1, 8 }, { &MFVideoFormat_A16B16G16R16F, 1, 1, 8 },
/* YUV */
{ &MFVideoFormat_NV12, 1, 3, 9, 4 },
{ &MFVideoFormat_NV12, 1, 2, 6, 3 },
{ &MFVideoFormat_NV12, 2, 2, 6, 6 },
{ &MFVideoFormat_NV12, 3, 2, 12, 9 },
{ &MFVideoFormat_NV12, 4, 2, 12, 12 },
}; };
unsigned int i; unsigned int i;
UINT32 size; UINT32 size;
...@@ -3422,11 +3432,13 @@ static void test_MFCalculateImageSize(void) ...@@ -3422,11 +3432,13 @@ static void test_MFCalculateImageSize(void)
if (pMFGetPlaneSize) if (pMFGetPlaneSize)
{ {
unsigned int plane_size = image_size_tests[i].plane_size ? image_size_tests[i].plane_size :
image_size_tests[i].size;
hr = pMFGetPlaneSize(image_size_tests[i].subtype->Data1, image_size_tests[i].width, image_size_tests[i].height, hr = pMFGetPlaneSize(image_size_tests[i].subtype->Data1, image_size_tests[i].width, image_size_tests[i].height,
&size); &size);
ok(hr == S_OK, "%u: failed to get plane size, hr %#x.\n", i, hr); ok(hr == S_OK, "%u: failed to get plane size, hr %#x.\n", i, hr);
ok(size == image_size_tests[i].size, "%u: unexpected plane size %u, expected %u.\n", i, size, ok(size == plane_size, "%u: unexpected plane size %u, expected %u.\n", i, size, plane_size);
image_size_tests[i].size);
} }
} }
} }
...@@ -4473,6 +4485,60 @@ static void test_queue_com_state(const char *name) ...@@ -4473,6 +4485,60 @@ static void test_queue_com_state(const char *name)
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
} }
static void test_MFGetStrideForBitmapInfoHeader(void)
{
static const struct stride_test
{
const GUID *subtype;
unsigned int width;
LONG stride;
}
stride_tests[] =
{
{ &MFVideoFormat_RGB8, 3, -4 },
{ &MFVideoFormat_RGB8, 1, -4 },
{ &MFVideoFormat_RGB555, 3, -8 },
{ &MFVideoFormat_RGB555, 1, -4 },
{ &MFVideoFormat_RGB565, 3, -8 },
{ &MFVideoFormat_RGB565, 1, -4 },
{ &MFVideoFormat_RGB24, 3, -12 },
{ &MFVideoFormat_RGB24, 1, -4 },
{ &MFVideoFormat_RGB32, 3, -12 },
{ &MFVideoFormat_RGB32, 1, -4 },
{ &MFVideoFormat_ARGB32, 3, -12 },
{ &MFVideoFormat_ARGB32, 1, -4 },
{ &MFVideoFormat_A2R10G10B10, 3, -12 },
{ &MFVideoFormat_A2R10G10B10, 1, -4 },
{ &MFVideoFormat_A16B16G16R16F, 3, -24 },
{ &MFVideoFormat_A16B16G16R16F, 1, -8 },
/* YUV */
{ &MFVideoFormat_NV12, 1, 1 },
{ &MFVideoFormat_NV12, 2, 2 },
{ &MFVideoFormat_NV12, 3, 3 },
};
unsigned int i;
LONG stride;
HRESULT hr;
if (!pMFGetStrideForBitmapInfoHeader)
{
win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
return;
}
hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
{
hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
ok(hr == S_OK, "%u: failed to get stride, hr %#x.\n", i, hr);
ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %d, expected %d.\n", i,
wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
}
}
START_TEST(mfplat) START_TEST(mfplat)
{ {
char **argv; char **argv;
...@@ -4524,6 +4590,7 @@ START_TEST(mfplat) ...@@ -4524,6 +4590,7 @@ START_TEST(mfplat)
test_MFCreateTransformActivate(); test_MFCreateTransformActivate();
test_MFTRegisterLocal(); test_MFTRegisterLocal();
test_queue_com(); test_queue_com();
test_MFGetStrideForBitmapInfoHeader();
CoUninitialize(); CoUninitialize();
} }
...@@ -421,6 +421,7 @@ void * WINAPI MFHeapAlloc(SIZE_T size, ULONG flags, char *file, int line, EAllo ...@@ -421,6 +421,7 @@ void * WINAPI MFHeapAlloc(SIZE_T size, ULONG flags, char *file, int line, EAllo
void WINAPI MFHeapFree(void *ptr); void WINAPI MFHeapFree(void *ptr);
HRESULT WINAPI MFGetAttributesAsBlob(IMFAttributes *attributes, UINT8 *buffer, UINT size); HRESULT WINAPI MFGetAttributesAsBlob(IMFAttributes *attributes, UINT8 *buffer, UINT size);
HRESULT WINAPI MFGetAttributesAsBlobSize(IMFAttributes *attributes, UINT32 *size); HRESULT WINAPI MFGetAttributesAsBlobSize(IMFAttributes *attributes, UINT32 *size);
HRESULT WINAPI MFGetStrideForBitmapInfoHeader(DWORD format, DWORD width, LONG *stride);
HRESULT WINAPI MFGetPlaneSize(DWORD format, DWORD width, DWORD height, DWORD *size); HRESULT WINAPI MFGetPlaneSize(DWORD format, DWORD width, DWORD height, DWORD *size);
HRESULT WINAPI MFGetTimerPeriodicity(DWORD *periodicity); HRESULT WINAPI MFGetTimerPeriodicity(DWORD *periodicity);
HRESULT WINAPI MFTEnum(GUID category, UINT32 flags, MFT_REGISTER_TYPE_INFO *input_type, HRESULT WINAPI MFTEnum(GUID category, UINT32 flags, MFT_REGISTER_TYPE_INFO *input_type,
......
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