This format is used by many Unity games, with D3D-enabled source reader.
-- v7: mfreadwrite/reader: Fixup MFVideoFormat_ABGR32 subtype to enumerate the video processor. winegstreamer: Support MFVideoFormat_ABGR32 output in the video processor. mfreadwrite/tests: Add tests with MFVideoFormat_ABGR32 output format. mf/tests: Add video processor tests with MFVideoFormat_ABGR32 format. mfplat: Add MFVideoFormat_ABGR32 format information.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 4 ++++ dlls/mfplat/tests/mfplat.c | 30 +++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index dd0b29fac32..3944d64849e 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -39,6 +39,7 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB1, D3DFMT_A1); DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB4, MAKEFOURCC('4','P','x','x')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_ABGR32, D3DFMT_A8B8G8R8); DEFINE_MEDIATYPE_GUID(MFVideoFormat_ARGB1555, D3DFMT_A1R5G5B5); DEFINE_MEDIATYPE_GUID(MFVideoFormat_ARGB4444, D3DFMT_A4R4G4B4); /* SDK MFVideoFormat_A2R10G10B10 uses D3DFMT_A2B10G10R10, let's name it the other way */ @@ -2713,6 +2714,7 @@ static struct uncompressed_video_format video_formats[] = { &MFVideoFormat_RGB32, 32, 3, 1, 0, BI_RGB }, { &MFVideoFormat_RGB565, 16, 3, 1, 0, BI_BITFIELDS }, { &MFVideoFormat_RGB555, 16, 3, 1, 0, BI_RGB }, + { &MFVideoFormat_ABGR32, 32, 3, 1, 0, BI_RGB }, { &MFVideoFormat_A2R10G10B10, 32, 3, 1, 0, -1 }, { &MFVideoFormat_A2B10G10R10, 32, 3, 1, 0, -1 }, { &MFVideoFormat_RGB8, 8, 3, 1, 0, BI_RGB }, @@ -3632,6 +3634,8 @@ DXGI_FORMAT WINAPI MFMapDX9FormatToDXGIFormat(DWORD format) return DXGI_FORMAT_B8G8R8A8_UNORM; case D3DFMT_X8R8G8B8: return DXGI_FORMAT_B8G8R8X8_UNORM; + case D3DFMT_A8B8G8R8: + return DXGI_FORMAT_R8G8B8A8_UNORM; case MAKEFOURCC('A','Y','U','V'): return DXGI_FORMAT_AYUV; case MAKEFOURCC('Y','4','1','0'): diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index a4ca567367c..21977807ac2 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -67,9 +67,11 @@ DEFINE_GUID(DUMMY_GUID3, 0x12345678,0x1234,0x1234,0x23,0x23,0x23,0x23,0x23,0x23, extern const CLSID CLSID_FileSchemePlugin;
DEFINE_MEDIATYPE_GUID(MEDIASUBTYPE_Base,0); +DEFINE_GUID(MEDIASUBTYPE_ABGR32,D3DFMT_A8B8G8R8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB1, D3DFMT_A1); DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB4, MAKEFOURCC('4','P','x','x')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_ABGR32, D3DFMT_A8B8G8R8); DEFINE_MEDIATYPE_GUID(MFVideoFormat_ARGB1555, D3DFMT_A1R5G5B5); DEFINE_MEDIATYPE_GUID(MFVideoFormat_ARGB4444, D3DFMT_A4R4G4B4); /* SDK MFVideoFormat_A2R10G10B10 uses D3DFMT_A2B10G10R10, let's name it the other way */ @@ -4748,6 +4750,9 @@ image_size_tests[] = { &MFVideoFormat_ARGB32, 3, 5, 60, 0, 320, 60, 64 }, { &MFVideoFormat_ARGB32, 1, 1, 4, 0, 64, 4, 64 }, { &MFVideoFormat_ARGB32, 320, 240, 307200, 0, 307200, 307200, 1280 }, + { &MFVideoFormat_ABGR32, 3, 5, 60, 0, 320, 60, 64 }, + { &MFVideoFormat_ABGR32, 1, 1, 4, 0, 64, 4, 64 }, + { &MFVideoFormat_ABGR32, 320, 240, 307200, 0, 307200, 307200, 1280 }, { &MFVideoFormat_A2R10G10B10, 3, 5, 60, 0, 320, 60, 64 }, { &MFVideoFormat_A2R10G10B10, 1, 1, 4, 0, 64, 4, 64 }, { &MFVideoFormat_A2R10G10B10, 320, 240, 307200, 0, 307200, 307200, 1280 }, @@ -4910,12 +4915,16 @@ static void test_MFCalculateImageSize(void)
/* Those are supported since Win10. */ BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) || - IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10); + IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10) || + IsEqualGUID(ptr->subtype, &MFVideoFormat_ABGR32);
hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size); - ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#lx.\n", i, hr); - ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size, - ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4)); + ok(hr == S_OK || broken(is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#lx.\n", i, hr); + if (hr == S_OK) + { + ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size, + ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4)); + } } }
@@ -6224,6 +6233,8 @@ static void test_MFGetStrideForBitmapInfoHeader(void) { &MFVideoFormat_RGB32, 1, -4 }, { &MFVideoFormat_ARGB32, 3, -12 }, { &MFVideoFormat_ARGB32, 1, -4 }, + { &MFVideoFormat_ABGR32, 3, -12 }, + { &MFVideoFormat_ABGR32, 1, -4 }, { &MFVideoFormat_A2R10G10B10, 3, -12 }, { &MFVideoFormat_A2R10G10B10, 1, -4 }, { &MFVideoFormat_A2B10G10R10, 3, -12 }, @@ -9272,6 +9283,7 @@ static void test_MFMapDXGIFormatToDX9Format(void) { DXGI_FORMAT dxgi_format; DWORD d3d9_format; + BOOL broken; } formats_map[] = { @@ -9304,6 +9316,7 @@ static void test_MFMapDXGIFormatToDX9Format(void) { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 }, { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 }, { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 }, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3DFMT_A8B8G8R8, .broken = TRUE /* <= w1064v1507 */ }, { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') }, { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') }, { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') }, @@ -9332,7 +9345,8 @@ static void test_MFMapDXGIFormatToDX9Format(void) for (i = 0; i < ARRAY_SIZE(formats_map); ++i) { format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format); - ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#lx, dxgi format %#x.\n", format, formats_map[i].dxgi_format); + ok(format == formats_map[i].d3d9_format || broken(formats_map[i].broken && format == 0), + "Unexpected d3d9 format %#lx, dxgi format %#x.\n", format, formats_map[i].dxgi_format); } }
@@ -9342,6 +9356,7 @@ static void test_MFMapDX9FormatToDXGIFormat(void) { DXGI_FORMAT dxgi_format; DWORD d3d9_format; + BOOL broken; } formats_map[] = { @@ -9369,6 +9384,7 @@ static void test_MFMapDX9FormatToDXGIFormat(void) { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 }, { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 }, { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 }, + { DXGI_FORMAT_R8G8B8A8_UNORM, D3DFMT_A8B8G8R8, .broken = TRUE }, { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') }, { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') }, { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') }, @@ -9397,8 +9413,8 @@ static void test_MFMapDX9FormatToDXGIFormat(void) for (i = 0; i < ARRAY_SIZE(formats_map); ++i) { format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format); - ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#lx.\n", - format, formats_map[i].d3d9_format); + ok(format == formats_map[i].dxgi_format || broken(formats_map[i].broken && format == 0), + "Unexpected DXGI format %#x, d3d9 format %#lx.\n", format, formats_map[i].d3d9_format); } }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/abgr32frame-crop.bmp | Bin 0 -> 27606 bytes dlls/mf/tests/resource.rc | 8 + dlls/mf/tests/rgb32frame-crop-flip.bmp | Bin 0 -> 27606 bytes dlls/mf/tests/rgb32frame-crop.bmp | Bin 27606 -> 27606 bytes dlls/mf/tests/transform.c | 372 +++++++++++++++++++++++-- 5 files changed, 350 insertions(+), 30 deletions(-) create mode 100644 dlls/mf/tests/abgr32frame-crop.bmp create mode 100644 dlls/mf/tests/rgb32frame-crop-flip.bmp
diff --git a/dlls/mf/tests/abgr32frame-crop.bmp b/dlls/mf/tests/abgr32frame-crop.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2e18f395cbb220cf761a891835669e8fd05a8082 GIT binary patch literal 27606 zcmeIwF-ikb6o%2UkTlLHq_MPg1r|zB>@_0p!cEy57Z4P66)r#s3ge6f#rFCL*}<)b zoPqDcW4fPne(`o&t-hmj4@=jjo6=TwP;OP-t^cnc>(jPv$Oa5BzyJdbFu(u<3^2gJ z<{DTo=b`)ti^U|A-=O{43E6-F1{h#~0R|XgfB^=EXyEzpGL+xo`29YV-=OZgkPR4M zfB^;=V1NMz7+_$C2F5>6q5KA;kF!vIgSu}*Hei4O1{h#~0R|XgfPo<zn7&Ly`3+_# zvrvA6zV1RcV1NMz7+`<_1{h#~fgu|B9Y2Qh8+?vVL-`H*rU}`A0R|XgfB^;=V1NMz phG^h*|0<N<V6y!X%5Si@`yH|Y0}L?000Rs#zyJdbFtE7>{sEA~Q{(^u
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc index 357a083bc66..6c9a6601c24 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -109,6 +109,14 @@ rgb32frame-flip.bmp RCDATA rgb32frame-flip.bmp /* @makedep: rgb32frame-crop.bmp */ rgb32frame-crop.bmp RCDATA rgb32frame-crop.bmp
+/* Generated from running the tests on Windows */ +/* @makedep: rgb32frame-crop-flip.bmp */ +rgb32frame-crop-flip.bmp RCDATA rgb32frame-crop-flip.bmp + +/* Generated from running the tests on Windows */ +/* @makedep: abgr32frame-crop.bmp */ +abgr32frame-crop.bmp RCDATA abgr32frame-crop.bmp + /* Generated from running the tests on Windows */ /* @makedep: rgb32frame-grabber.bmp */ rgb32frame-grabber.bmp RCDATA rgb32frame-grabber.bmp diff --git a/dlls/mf/tests/rgb32frame-crop-flip.bmp b/dlls/mf/tests/rgb32frame-crop-flip.bmp new file mode 100644 index 0000000000000000000000000000000000000000..34a28ad44732f38d4165bdc00de313db7c2f390a GIT binary patch literal 27606 zcmeI&!3}~y5J1tP6OUG40p7hByRa#%vK-cdFbyys_V7q%2_Yn#pLc<9e|+DuAGchu zInSI|&JvegBR<Fd{o+_g#4s8#zyJdbFu(u<3^2d|0}L?GGZ3+6LUX=BeV)+pe8a7s zj=g^6Pe&cg!VG5~d7Qyv?SV%g%fbw29(kO>VeNs(e|lW=y~b$300Rs#zyJdbFu(u< z3^2ez&%iQb7!4R;fB^;=V1NMz7+`<_1{mlW$iD%G(SQL47+`<_1{h#~0R|XgfPtQY v-qY&q#{dHiFu(u<3^2d|0}L?0z-GXqfC36Apnw7jD4>7>3Mim}0{sF%iRi;|
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/rgb32frame-crop.bmp b/dlls/mf/tests/rgb32frame-crop.bmp index 34a28ad44732f38d4165bdc00de313db7c2f390a..310824a5e1061b8ec9a122b3a3638d3844a291bb 100644 GIT binary patch literal 27606 zcmeI4y-EX75Jo40?_uc^SXkPp5g)>hl|L__rJaQ!B4{TB?8Qo~Ed;^JR2H_0m6hXc zHunkUE2cPsZ!aO-%W(G0z3dj*8Gjtu^0O7!&B$(KFEX-?xSHLqeqVlBUHs3TBpJLV z=W`DR2jQscML5E-(w>5k_=t}h2jB?DN)A-2g>y#J8*r3yJen_@<QV)uxsT!zo8%Zg zzvSk_f8Ym4jYn{VW2HR>AMp_%H4eZLj+Gp!R14>frZ;+ylkbis8O&~9dAe4-U6@|M z5sq~nz(>u!fFm3g`<iMEe8fkUONw>y5g!#Esn)<pnUBYFbCP55etG6=;Wo)JxV|}u zp}-?J<~(eD3`aON7b=YSh>sOKY&GB`J~kIBjQEI;6+CP;^gd4ZCnU+>ar@rg;*|%< zF<Ae}&4>TM4~`m-;0VV`dkQ|{BR*;zfFm3$IZ&w<&KXT_1jj>LkR*c#`*e%`AUOsn z_60+MM{vw}*!mcbaBMDA81WGwD|pyyz(;&+E>sxt5g#jf*lOr~?5rb61{Zc3V#hxe tkQ9TNjZ^dCKR5_SO)tU`j+OQle8fk5)Hnb~I976?QZ1Y_n%?L+{sU%+=K=r#
literal 27606 zcmeI&!3}~y5J1tP6OUG40p7hByRa#%vK-cdFbyys_V7q%2_Yn#pLc<9e|+DuAGchu zInSI|&JvegBR<Fd{o+_g#4s8#zyJdbFu(u<3^2d|0}L?GGZ3+6LUX=BeV)+pe8a7s zj=g^6Pe&cg!VG5~d7Qyv?SV%g%fbw29(kO>VeNs(e|lW=y~b$300Rs#zyJdbFu(u< z3^2ez&%iQb7!4R;fB^;=V1NMz7+`<_1{mlW$iD%G(SQL47+`<_1{h#~0R|XgfPtQY v-qY&q#{dHiFu(u<3^2d|0}L?0z-GXqfC36Apnw7jD4>7>3Mim}0{sF%iRi;|
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 6600b413f7a..97f8c8358ff 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -55,10 +55,10 @@ DEFINE_GUID(DMOVideoFormat_RGB555,D3DFMT_X1R5G5B5,0x524f,0x11ce,0x9f,0x53,0x00,0 DEFINE_GUID(DMOVideoFormat_RGB565,D3DFMT_R5G6B5,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); DEFINE_GUID(DMOVideoFormat_RGB8,D3DFMT_P8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70); DEFINE_GUID(MFAudioFormat_RAW_AAC1,WAVE_FORMAT_RAW_AAC1,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); -DEFINE_GUID(MFVideoFormat_ABGR32,0x00000020,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); -DEFINE_GUID(MFVideoFormat_P208,0x38303250,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); -DEFINE_GUID(MFVideoFormat_VC1S,0x53314356,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); DEFINE_GUID(MFVideoFormat_WMV_Unknown,0x7ce12ca9,0xbfbf,0x43d9,0x9d,0x00,0x82,0xb8,0xed,0x54,0x31,0x6b); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_ABGR32,D3DFMT_A8B8G8R8); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_P208,MAKEFOURCC('P','2','0','8')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_VC1S,MAKEFOURCC('V','C','1','S')); DEFINE_MEDIATYPE_GUID(MEDIASUBTYPE_IV50,MAKEFOURCC('I','V','5','0'));
DEFINE_GUID(mft_output_sample_incomplete,0xffffff,0xffff,0xffff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff); @@ -773,20 +773,23 @@ static void check_mft_set_output_type_required_(int line, IMFTransform *transfor ok_(__FILE__, line)(!ref, "Release returned %lu\n", ref); }
-static void check_mft_set_output_type(IMFTransform *transform, const struct attribute_desc *attributes, - HRESULT expect_hr) +#define check_mft_set_output_type(a, b, c) check_mft_set_output_type_(__LINE__, a, b, c, FALSE, FALSE) +static void check_mft_set_output_type_(int line, IMFTransform *transform, const struct attribute_desc *attributes, + HRESULT expect_hr, BOOL todo_test, BOOL todo) { IMFMediaType *media_type; HRESULT hr;
hr = MFCreateMediaType(&media_type); - ok(hr == S_OK, "MFCreateMediaType returned hr %#lx.\n", hr); + ok_(__FILE__, line)(hr == S_OK, "MFCreateMediaType returned hr %#lx.\n", hr); init_media_type(media_type, attributes, -1);
hr = IMFTransform_SetOutputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY); - ok(hr == expect_hr, "SetOutputType returned %#lx.\n", hr); + todo_wine_if(todo_test) + ok_(__FILE__, line)(hr == expect_hr, "SetOutputType returned %#lx.\n", hr); hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == expect_hr, "SetOutputType returned %#lx.\n", hr); + todo_wine_if(todo) + ok_(__FILE__, line)(hr == expect_hr, "SetOutputType returned %#lx.\n", hr);
IMFMediaType_Release(media_type); } @@ -934,6 +937,32 @@ DWORD compare_i420(const BYTE *data, DWORD *length, const SIZE *size, const RECT return diff * 100 / 256 / data_size; }
+static DWORD compare_abgr32(const BYTE *data, DWORD *length, const SIZE *size, const RECT *rect, const BYTE *expect) +{ + DWORD x, y, data_size, diff = 0, width = size->cx, height = size->cy; + + /* skip BMP header from the dump */ + data_size = *(DWORD *)(expect + 2 + 2 * sizeof(DWORD)); + *length = *length + data_size; + expect = expect + data_size; + + for (y = 0; y < height; y++, data += width * 4, expect += width * 4) + { + if (y < rect->top || y >= rect->bottom) continue; + for (x = 0; x < width; x++) + { + if (x < rect->left || x >= rect->right) continue; + diff += abs((int)expect[4 * x + 0] - (int)data[4 * x + 0]); + diff += abs((int)expect[4 * x + 1] - (int)data[4 * x + 1]); + diff += abs((int)expect[4 * x + 2] - (int)data[4 * x + 2]); + diff += abs((int)expect[4 * x + 3] - (int)data[4 * x + 3]); + } + } + + data_size = (rect->right - rect->left) * (rect->bottom - rect->top) * 4; + return diff * 100 / 256 / data_size; +} + static DWORD compare_rgb(const BYTE *data, DWORD *length, const SIZE *size, const RECT *rect, const BYTE *expect, UINT bits) { DWORD x, y, step = bits / 8, data_size, diff = 0, width = size->cx, height = size->cy; @@ -7595,22 +7624,22 @@ static void test_video_processor(void) }, { .input_type_desc = nv12_with_aperture, .input_bitmap = L"nv12frame.bmp", - .output_type_desc = rgb32_no_aperture, .output_bitmap = L"rgb32frame-crop.bmp", + .output_type_desc = rgb32_no_aperture, .output_bitmap = L"rgb32frame-crop-flip.bmp", .output_sample_desc = &rgb32_crop_sample_desc, }, { - .input_type_desc = rgb32_no_aperture, .input_bitmap = L"rgb32frame-crop.bmp", + .input_type_desc = rgb32_no_aperture, .input_bitmap = L"rgb32frame-crop-flip.bmp", .output_type_desc = rgb32_with_aperture, .output_bitmap = L"rgb32frame-flip.bmp", .output_sample_desc = &rgb32_sample_desc, .broken = TRUE /* old Windows version incorrectly rescale */ }, { .input_type_desc = rgb32_with_aperture, .input_bitmap = L"rgb32frame-flip.bmp", - .output_type_desc = rgb32_no_aperture, .output_bitmap = L"rgb32frame-crop.bmp", + .output_type_desc = rgb32_no_aperture, .output_bitmap = L"rgb32frame-crop-flip.bmp", .output_sample_desc = &rgb32_crop_sample_desc, }, { .input_type_desc = rgb32_with_aperture_positive_stride, .input_bitmap = L"rgb32frame.bmp", - .output_type_desc = rgb32_no_aperture, .output_bitmap = L"rgb32frame-crop.bmp", + .output_type_desc = rgb32_no_aperture, .output_bitmap = L"rgb32frame-crop-flip.bmp", .output_sample_desc = &rgb32_crop_sample_desc, .delta = 3, /* Windows returns 3 */ }, }; @@ -7925,6 +7954,22 @@ static void test_video_processor(void) } ok(hr == MF_E_NO_MORE_TYPES, "GetInputAvailableType returned %#lx\n", hr);
+ /* MFVideoFormat_ABGR32 isn't supported by the video processor in non-D3D mode */ + check_mft_set_input_type(transform, nv12_default_stride); + + hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_ABGR32); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); + ok(hr == MF_E_INVALIDMEDIATYPE, "got %#lx\n", hr); + IMFMediaType_Release(media_type); + + /* MFVideoFormat_RGB32 output format works */ + + check_mft_set_output_type(transform, rgb32_default_stride, S_OK); + check_mft_get_output_current_type(transform, rgb32_default_stride); + for (i = 0; i < ARRAY_SIZE(video_processor_tests); i++) { const struct transform_desc *test = video_processor_tests + i; @@ -8597,6 +8642,17 @@ static void test_h264_with_dxgi_manager(void) ok(hr == S_OK, "got %#lx\n", hr); IMFMediaType_Release(type);
+ /* MFVideoFormat_ABGR32 output isn't supported by the D3D11-enabled decoder */ + hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &type); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, &MFVideoFormat_ABGR32); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFTransform_SetOutputType(transform, 0, type, 0); + ok(hr == MF_E_INVALIDMEDIATYPE, "got %#lx\n", hr); + IMFMediaType_Release(type); + hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &type); ok(hr == S_OK, "got %#lx\n", hr); hr = IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); @@ -8985,6 +9041,32 @@ static void test_iv50_decoder(void) IMFCollection_Release(collection); }
+static IMFSample *create_d3d_sample(IMFVideoSampleAllocator *allocator, const void *data, ULONG size) +{ + IMFMediaBuffer *media_buffer; + IMFSample *sample; + BYTE *buffer; + HRESULT hr; + + hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFSample_SetSampleTime(sample, 0); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFSample_SetSampleDuration(sample, 0); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFSample_GetBufferByIndex(sample, 0, &media_buffer); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaBuffer_Lock(media_buffer, &buffer, NULL, NULL); + ok(hr == S_OK, "got %#lx\n", hr); + if (!data) memset(buffer, 0xcd, size); + else memcpy(buffer, data, size); + hr = IMFMediaBuffer_Unlock(media_buffer); + ok(hr == S_OK, "got %#lx\n", hr); + IMFMediaBuffer_Release(media_buffer); + + return sample; +} + static void test_video_processor_with_dxgi_manager(void) { static const unsigned int set_width = 82, set_height = 84, aligned_width = 96, aligned_height = 96; @@ -9005,6 +9087,76 @@ static void test_video_processor_with_dxgi_manager(void) .buffer_count = 1, .buffers = &output_buffer_desc_rgb32, };
+ const struct buffer_desc output_buffer_desc_rgb32_crop = + { + .length = set_width * set_height * 4, + .compare = compare_rgb32, .compare_rect = {.right = set_width, .bottom = set_height}, + .dump = dump_rgb32, .size = {.cx = set_width, .cy = set_height}, + }; + const struct sample_desc output_sample_desc_rgb32_crop = + { + .attributes = output_sample_attributes, + .sample_time = 0, .sample_duration = 0, + .buffer_count = 1, .buffers = &output_buffer_desc_rgb32_crop, + }; + + const struct buffer_desc output_buffer_desc_abgr32_crop = + { + .length = set_width * set_height * 4, + .compare = compare_abgr32, .compare_rect = {.right = set_width, .bottom = set_height}, + .dump = dump_rgb32, .size = {.cx = set_width, .cy = set_height}, + }; + const struct sample_desc output_sample_desc_abgr32_crop = + { + .attributes = output_sample_attributes, + .sample_time = 0, .sample_duration = 0, + .buffer_count = 1, .buffers = &output_buffer_desc_abgr32_crop, + }; + + const GUID expect_available_outputs[] = + { + MFVideoFormat_ARGB32, + MFVideoFormat_ABGR32, + MFVideoFormat_A2R10G10B10, + MFVideoFormat_A16B16G16R16F, + MFVideoFormat_NV12, + MFVideoFormat_P010, + MFVideoFormat_YUY2, + MFVideoFormat_L8, + MFVideoFormat_L16, + MFVideoFormat_D16, + }; + static const media_type_desc expect_available_common = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + }; + + static const MFVideoArea aperture = {.Area={set_width, set_height}}; + const struct attribute_desc nv12_with_aperture[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12), + ATTR_RATIO(MF_MT_FRAME_SIZE, aligned_width, aligned_height), + ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &aperture, 16), + ATTR_BLOB(MF_MT_GEOMETRIC_APERTURE, &aperture, 16), + ATTR_BLOB(MF_MT_PAN_SCAN_APERTURE, &aperture, 16), + {0}, + }; + const struct attribute_desc rgb32_no_aperture[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), + ATTR_RATIO(MF_MT_FRAME_SIZE, set_width, set_height), + {0}, + }; + const struct attribute_desc abgr32_no_aperture[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_ABGR32), + ATTR_RATIO(MF_MT_FRAME_SIZE, set_width, set_height), + {0}, + }; + IMFVideoSampleAllocator *allocator = NULL; IMFDXGIDeviceManager *manager = NULL; IMFTrackedSample *tracked_sample; @@ -9025,9 +9177,8 @@ static void test_video_processor_with_dxgi_manager(void) ID3D11Device *d3d11; IMFMediaType *type; DWORD status, val; - ULONG i, length; + ULONG i, j, length; UINT32 value; - BYTE *data; HRESULT hr; UINT token; DWORD ret; @@ -9106,6 +9257,45 @@ static void test_video_processor_with_dxgi_manager(void) ok(hr == S_OK, "got %#lx\n", hr); IMFMediaType_Release(type);
+ j = i = 0; + while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, ++i, &type))) + { + GUID guid; + winetest_push_context("out %lu", i); + ok(hr == S_OK, "GetOutputAvailableType returned %#lx\n", hr); + check_media_type(type, expect_available_common, -1); + + hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &guid); + ok(hr == S_OK, "GetGUID returned %#lx\n", hr); + + for (; j < ARRAY_SIZE(expect_available_outputs); j++) + if (IsEqualGUID(&expect_available_outputs[j], &guid)) + break; + todo_wine_if(i >= 2) + ok(j < ARRAY_SIZE(expect_available_outputs), "got subtype %s\n", debugstr_guid(&guid)); + + ret = IMFMediaType_Release(type); + ok(ret == 0, "Release returned %lu\n", ret); + winetest_pop_context(); + } + ok(hr == MF_E_NO_MORE_TYPES, "GetOutputAvailableType returned %#lx\n", hr); + + + /* MFVideoFormat_ABGR32 is supported by the D3D11-enabled video processor */ + + hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &type); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetGUID(type, &MF_MT_SUBTYPE, &MFVideoFormat_ABGR32); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaType_SetUINT64(type, &MF_MT_FRAME_SIZE, (UINT64)96 << 32 | 96); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFTransform_SetOutputType(transform, 0, type, 0); + todo_wine ok(hr == S_OK, "got %#lx\n", hr); + IMFMediaType_Release(type); + + hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &type); ok(hr == S_OK, "got %#lx\n", hr); hr = IMFMediaType_SetGUID(type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); @@ -9130,23 +9320,8 @@ static void test_video_processor_with_dxgi_manager(void) nv12frame_data = nv12frame_data + length; ok(nv12frame_data_len == 13824, "got length %lu\n", nv12frame_data_len);
- /* native wants a dxgi buffer on input */ - - hr = IMFVideoSampleAllocator_AllocateSample(allocator, &input_sample); - ok(hr == S_OK, "got %#lx\n", hr); - hr = IMFSample_SetSampleTime(input_sample, 0); - ok(hr == S_OK, "got %#lx\n", hr); - hr = IMFSample_SetSampleDuration(input_sample, 0); - ok(hr == S_OK, "got %#lx\n", hr); - hr = IMFSample_GetBufferByIndex(input_sample, 0, &buffer); - ok(hr == S_OK, "got %#lx\n", hr); - hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL); - ok(hr == S_OK, "got %#lx\n", hr); - memcpy(data, nv12frame_data, nv12frame_data_len); - hr = IMFMediaBuffer_Unlock(buffer); - ok(hr == S_OK, "got %#lx\n", hr); - IMFMediaBuffer_Release(buffer); + input_sample = create_d3d_sample(allocator, nv12frame_data, nv12frame_data_len);
hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); ok(hr == S_OK, "got %#lx\n", hr); @@ -9266,6 +9441,143 @@ static void test_video_processor_with_dxgi_manager(void) if (output.pSample) IMFSample_Release(output.pSample);
+ + /* check RGB32 output aperture cropping with D3D buffers */ + + check_mft_set_input_type(transform, nv12_with_aperture); + check_mft_set_output_type_(__LINE__, transform, rgb32_no_aperture, S_OK, FALSE, TRUE); + + load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len); + /* skip BMP header and RGB data from the dump */ + length = *(DWORD *)(nv12frame_data + 2); + nv12frame_data_len = nv12frame_data_len - length; + nv12frame_data = nv12frame_data + length; + ok(nv12frame_data_len == 13824, "got length %lu\n", nv12frame_data_len); + + input_sample = create_d3d_sample(allocator, nv12frame_data, nv12frame_data_len); + + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + todo_wine ok(hr == S_OK, "got %#lx\n", hr); + + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &info); + ok(hr == S_OK, "got %#lx\n", hr); + ok(info.dwFlags == MFT_OUTPUT_STREAM_PROVIDES_SAMPLES, "got %#lx.\n", info.dwFlags); + + status = 0; + memset(&output, 0, sizeof(output)); + hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); + todo_wine ok(hr == S_OK, "got %#lx\n", hr); + ok(!output.pEvents, "got events\n"); + todo_wine ok(!!output.pSample, "got no sample\n"); + ok(output.dwStatus == 0, "got %#lx\n", output.dwStatus); + ok(status == 0, "got %#lx\n", status); + if (!output.pSample) goto skip_rgb32; + + hr = IMFSample_GetBufferByIndex(output.pSample, 0, &buffer); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer); + ok(hr == S_OK, "got %#lx\n", hr); + + hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&tex2d); + ok(hr == S_OK, "got %#lx\n", hr); + memset(&desc, 0xcc, sizeof(desc)); + ID3D11Texture2D_GetDesc(tex2d, &desc); + ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "got %#x.\n", desc.Format); + ok(!desc.Usage, "got %u.\n", desc.Usage); + ok(desc.BindFlags == (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE), "got %#x.\n", desc.BindFlags); + ok(!desc.CPUAccessFlags, "got %#x.\n", desc.CPUAccessFlags); + ok(!desc.MiscFlags, "got %#x.\n", desc.MiscFlags); + ok(desc.MipLevels == 1, "git %u.\n", desc.MipLevels); + ok(desc.Width == set_width, "got %u.\n", desc.Width); + ok(desc.Height == set_height, "got %u.\n", desc.Height); + + ID3D11Texture2D_Release(tex2d); + IMFDXGIBuffer_Release(dxgi_buffer); + IMFMediaBuffer_Release(buffer); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output.pSample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + IMFSample_Release(output.pSample); + + ret = check_mf_sample_collection(output_samples, &output_sample_desc_rgb32_crop, L"rgb32frame-crop.bmp"); + todo_wine /* FIXME: video process vertically flips the frame... */ + ok(ret <= 5, "got %lu%% diff\n", ret); + + IMFCollection_Release(output_samples); + + +skip_rgb32: + /* check ABGR32 output with D3D buffers */ + + check_mft_set_input_type(transform, nv12_with_aperture); + check_mft_set_output_type_(__LINE__, transform, abgr32_no_aperture, S_OK, TRUE, TRUE); + + load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len); + /* skip BMP header and RGB data from the dump */ + length = *(DWORD *)(nv12frame_data + 2); + nv12frame_data_len = nv12frame_data_len - length; + nv12frame_data = nv12frame_data + length; + ok(nv12frame_data_len == 13824, "got length %lu\n", nv12frame_data_len); + + input_sample = create_d3d_sample(allocator, nv12frame_data, nv12frame_data_len); + + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + todo_wine ok(hr == S_OK, "got %#lx\n", hr); + + hr = IMFTransform_GetOutputStreamInfo(transform, 0, &info); + ok(hr == S_OK, "got %#lx\n", hr); + ok(info.dwFlags == MFT_OUTPUT_STREAM_PROVIDES_SAMPLES, "got %#lx.\n", info.dwFlags); + + status = 0; + memset(&output, 0, sizeof(output)); + hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); + todo_wine ok(hr == S_OK, "got %#lx\n", hr); + ok(!output.pEvents, "got events\n"); + todo_wine ok(!!output.pSample, "got no sample\n"); + ok(output.dwStatus == 0, "got %#lx\n", output.dwStatus); + ok(status == 0, "got %#lx\n", status); + if (!output.pSample) goto skip_abgr32; + + hr = IMFSample_GetBufferByIndex(output.pSample, 0, &buffer); + ok(hr == S_OK, "got %#lx\n", hr); + hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer); + ok(hr == S_OK, "got %#lx\n", hr); + + hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&tex2d); + ok(hr == S_OK, "got %#lx\n", hr); + memset(&desc, 0xcc, sizeof(desc)); + ID3D11Texture2D_GetDesc(tex2d, &desc); + ok(desc.Format == DXGI_FORMAT_R8G8B8A8_UNORM, "got %#x.\n", desc.Format); + ok(!desc.Usage, "got %u.\n", desc.Usage); + ok(desc.BindFlags == D3D11_BIND_RENDER_TARGET, "got %#x.\n", desc.BindFlags); + ok(!desc.CPUAccessFlags, "got %#x.\n", desc.CPUAccessFlags); + ok(!desc.MiscFlags, "got %#x.\n", desc.MiscFlags); + ok(desc.MipLevels == 1, "git %u.\n", desc.MipLevels); + ok(desc.Width == set_width, "got %u.\n", desc.Width); + ok(desc.Height == set_height, "got %u.\n", desc.Height); + + ID3D11Texture2D_Release(tex2d); + IMFDXGIBuffer_Release(dxgi_buffer); + IMFMediaBuffer_Release(buffer); + + hr = MFCreateCollection(&output_samples); + ok(hr == S_OK, "MFCreateCollection returned %#lx\n", hr); + + hr = IMFCollection_AddElement(output_samples, (IUnknown *)output.pSample); + ok(hr == S_OK, "AddElement returned %#lx\n", hr); + IMFSample_Release(output.pSample); + + ret = check_mf_sample_collection(output_samples, &output_sample_desc_abgr32_crop, L"abgr32frame-crop.bmp"); + todo_wine /* FIXME: video process vertically flips the frame... */ + ok(ret <= 8 /* NVIDIA needs 5, AMD needs 8 */, "got %lu%% diff\n", ret); + + IMFCollection_Release(output_samples); + + +skip_abgr32: hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_SET_D3D_MANAGER, 0); ok(hr == S_OK, "got %#lx\n", hr);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfreadwrite/tests/mfplat.c | 41 ++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index b51c9739afe..b819b2238e9 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -48,6 +48,7 @@ DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); #include "wine/test.h"
DEFINE_MEDIATYPE_GUID(MFVideoFormat_TEST,MAKEFOURCC('T','E','S','T')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_ABGR32,D3DFMT_A8B8G8R8);
#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) @@ -2503,7 +2504,8 @@ static HRESULT WINAPI test_decoder_SetOutputType(IMFTransform *iface, DWORD id, HRESULT hr;
if (type && SUCCEEDED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)) - && IsEqualGUID(&subtype, &MFVideoFormat_RGB32)) + && (IsEqualGUID(&subtype, &MFVideoFormat_RGB32) + || IsEqualGUID(&subtype, &MFVideoFormat_ABGR32))) return MF_E_INVALIDMEDIATYPE;
if (flags & MFT_SET_TYPE_TEST_ONLY) @@ -3101,6 +3103,12 @@ static void test_source_reader_transforms_d3d9(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(value == 0, "got %u.\n", value); IMFAttributes_Release(attributes); + + hr = IMFTransform_GetOutputCurrentType(video_processor, 0, &media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_media_type(media_type, rgb32_expect_desc, -1); + IMFMediaType_Release(media_type); + IMFTransform_Release(video_processor);
hr = IMFSourceReaderEx_GetTransformForStream(reader_ex, 0, 0, NULL, &test_decoder); @@ -3281,6 +3289,22 @@ static void test_source_reader_transforms_d3d11(void) ATTR_UINT32(MF_MT_INTERLACE_MODE, 2, .todo = TRUE), {0}, }; + static const struct attribute_desc abgr32_stream_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_ABGR32), + {0}, + }; + static const struct attribute_desc abgr32_expect_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_ABGR32), + ATTR_RATIO(MF_MT_FRAME_SIZE, 96, 96), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_COMPRESSED, 0, .todo = TRUE), + ATTR_UINT32(MF_MT_INTERLACE_MODE, 2, .todo = TRUE), + {0}, + }; const MFT_REGISTER_TYPE_INFO output_info[] = { {MFMediaType_Video, MFVideoFormat_NV12}, @@ -3389,6 +3413,21 @@ static void test_source_reader_transforms_d3d11(void) IMFMediaType_Release(media_type); ok(!test_decoder_got_d3d_manager, "d3d manager received\n");
+ hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(media_type, abgr32_stream_type_desc, -1); + hr = IMFSourceReader_SetCurrentMediaType(reader, 0, NULL, media_type); + todo_wine ok(hr == S_OK || broken(hr == MF_E_INVALIDMEDIATYPE) /* needs a GPU */, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(media_type); + + if (hr == S_OK) + { + hr = IMFSourceReader_GetCurrentMediaType(reader, 0, &media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_media_type(media_type, abgr32_expect_desc, -1); + IMFMediaType_Release(media_type); + } + hr = MFCreateMediaType(&media_type); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); init_media_type(media_type, rgb32_stream_type_desc, -1);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/transform.c | 14 +++++++------- dlls/winegstreamer/main.c | 2 ++ dlls/winegstreamer/mfplat.c | 2 ++ dlls/winegstreamer/quartz_parser.c | 6 ++++++ dlls/winegstreamer/unixlib.h | 1 + dlls/winegstreamer/video_processor.c | 3 +++ dlls/winegstreamer/wg_format.c | 3 +++ 7 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 97f8c8358ff..e7d8f924b70 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -773,9 +773,9 @@ static void check_mft_set_output_type_required_(int line, IMFTransform *transfor ok_(__FILE__, line)(!ref, "Release returned %lu\n", ref); }
-#define check_mft_set_output_type(a, b, c) check_mft_set_output_type_(__LINE__, a, b, c, FALSE, FALSE) +#define check_mft_set_output_type(a, b, c) check_mft_set_output_type_(__LINE__, a, b, c, FALSE) static void check_mft_set_output_type_(int line, IMFTransform *transform, const struct attribute_desc *attributes, - HRESULT expect_hr, BOOL todo_test, BOOL todo) + HRESULT expect_hr, BOOL todo) { IMFMediaType *media_type; HRESULT hr; @@ -785,7 +785,6 @@ static void check_mft_set_output_type_(int line, IMFTransform *transform, const init_media_type(media_type, attributes, -1);
hr = IMFTransform_SetOutputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY); - todo_wine_if(todo_test) ok_(__FILE__, line)(hr == expect_hr, "SetOutputType returned %#lx.\n", hr); hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); todo_wine_if(todo) @@ -7942,6 +7941,7 @@ static void test_video_processor(void) for (; k < ARRAY_SIZE(expect_available_outputs); k++) if (IsEqualGUID(&expect_available_outputs[k], &guid)) break; + todo_wine_if(IsEqualGUID(&guid, &MFVideoFormat_ABGR32)) /* enumerated on purpose on Wine */ ok(k < ARRAY_SIZE(expect_available_outputs), "got subtype %s\n", debugstr_guid(&guid));
ret = IMFMediaType_Release(media_type); @@ -7962,7 +7962,7 @@ static void test_video_processor(void) hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_ABGR32); ok(hr == S_OK, "got %#lx\n", hr); hr = IMFTransform_SetOutputType(transform, 0, media_type, 0); - ok(hr == MF_E_INVALIDMEDIATYPE, "got %#lx\n", hr); + todo_wine ok(hr == MF_E_INVALIDMEDIATYPE, "got %#lx\n", hr); IMFMediaType_Release(media_type);
/* MFVideoFormat_RGB32 output format works */ @@ -9292,7 +9292,7 @@ static void test_video_processor_with_dxgi_manager(void) hr = IMFMediaType_SetUINT64(type, &MF_MT_FRAME_SIZE, (UINT64)96 << 32 | 96); ok(hr == S_OK, "got %#lx\n", hr); hr = IMFTransform_SetOutputType(transform, 0, type, 0); - todo_wine ok(hr == S_OK, "got %#lx\n", hr); + ok(hr == S_OK, "got %#lx\n", hr); IMFMediaType_Release(type);
@@ -9445,7 +9445,7 @@ static void test_video_processor_with_dxgi_manager(void) /* check RGB32 output aperture cropping with D3D buffers */
check_mft_set_input_type(transform, nv12_with_aperture); - check_mft_set_output_type_(__LINE__, transform, rgb32_no_aperture, S_OK, FALSE, TRUE); + check_mft_set_output_type_(__LINE__, transform, rgb32_no_aperture, S_OK, TRUE);
load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len); /* skip BMP header and RGB data from the dump */ @@ -9513,7 +9513,7 @@ skip_rgb32: /* check ABGR32 output with D3D buffers */
check_mft_set_input_type(transform, nv12_with_aperture); - check_mft_set_output_type_(__LINE__, transform, abgr32_no_aperture, S_OK, TRUE, TRUE); + check_mft_set_output_type_(__LINE__, transform, abgr32_no_aperture, S_OK, TRUE);
load_resource(L"nv12frame.bmp", &nv12frame_data, &nv12frame_data_len); /* skip BMP header and RGB data from the dump */ diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 91397da8f69..eaa980e7ba2 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -699,6 +699,7 @@ unsigned int wg_format_get_stride(const struct wg_format *format)
case WG_VIDEO_FORMAT_BGRA: case WG_VIDEO_FORMAT_BGRx: + case WG_VIDEO_FORMAT_RGBA: return width * 4;
case WG_VIDEO_FORMAT_BGR: @@ -734,6 +735,7 @@ bool wg_video_format_is_rgb(enum wg_video_format format) case WG_VIDEO_FORMAT_BGR: case WG_VIDEO_FORMAT_RGB15: case WG_VIDEO_FORMAT_RGB16: + case WG_VIDEO_FORMAT_RGBA: return true;
default: diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index 879ea0707fc..71a91c4ddfb 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -41,6 +41,7 @@ DEFINE_GUID(DMOVideoFormat_RGB8,D3DFMT_P8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf DEFINE_MEDIATYPE_GUID(MFAudioFormat_RAW_AAC,WAVE_FORMAT_RAW_AAC1); DEFINE_MEDIATYPE_GUID(MFVideoFormat_VC1S,MAKEFOURCC('V','C','1','S')); DEFINE_MEDIATYPE_GUID(MFVideoFormat_IV50,MAKEFOURCC('I','V','5','0')); +DEFINE_MEDIATYPE_GUID(MFVideoFormat_ABGR32,D3DFMT_A8B8G8R8); DEFINE_GUID(MEDIASUBTYPE_WMV_Unknown, 0x7ce12ca9,0xbfbf,0x43d9,0x9d,0x00,0x82,0xb8,0xed,0x54,0x31,0x6b);
struct class_factory @@ -442,6 +443,7 @@ video_formats[] = {&MFVideoFormat_RGB24, WG_VIDEO_FORMAT_BGR}, {&MFVideoFormat_RGB555, WG_VIDEO_FORMAT_RGB15}, {&MFVideoFormat_RGB565, WG_VIDEO_FORMAT_RGB16}, + {&MFVideoFormat_ABGR32, WG_VIDEO_FORMAT_RGBA}, {&MFVideoFormat_AYUV, WG_VIDEO_FORMAT_AYUV}, {&MFVideoFormat_I420, WG_VIDEO_FORMAT_I420}, {&MFVideoFormat_IYUV, WG_VIDEO_FORMAT_I420}, diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 2c9fb896b1e..51a4a0153cf 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -27,6 +27,7 @@
#include <limits.h> #include "dvdmedia.h" +#include "d3d9types.h" #include "mmreg.h" #include "ks.h" #include "wmcodecdsp.h" @@ -39,6 +40,7 @@ static const GUID MEDIASUBTYPE_CVID = {mmioFOURCC('c','v','i','d'), 0x0000, 0x00 static const GUID MEDIASUBTYPE_VC1S = {mmioFOURCC('V','C','1','S'), 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; static const GUID MEDIASUBTYPE_MP3 = {WAVE_FORMAT_MPEGLAYER3, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; static const GUID MEDIASUBTYPE_WMV_Unknown = {0x7ce12ca9, 0xbfbf, 0x43d9, {0x9d, 0x00, 0x82, 0xb8, 0xed, 0x54, 0x31, 0x6b}}; +DEFINE_GUID(MEDIASUBTYPE_ABGR32,D3DFMT_A8B8G8R8,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
struct parser { @@ -349,6 +351,7 @@ static unsigned int wg_format_get_max_size_video_raw(enum wg_video_format format case WG_VIDEO_FORMAT_BGRA: case WG_VIDEO_FORMAT_BGRx: case WG_VIDEO_FORMAT_AYUV: + case WG_VIDEO_FORMAT_RGBA: return width * height * 4;
case WG_VIDEO_FORMAT_BGR: @@ -478,6 +481,7 @@ static const GUID *wg_video_format_get_mediasubtype(enum wg_video_format format) case WG_VIDEO_FORMAT_BGR: return &MEDIASUBTYPE_RGB24; case WG_VIDEO_FORMAT_RGB15: return &MEDIASUBTYPE_RGB555; case WG_VIDEO_FORMAT_RGB16: return &MEDIASUBTYPE_RGB565; + case WG_VIDEO_FORMAT_RGBA: return &MEDIASUBTYPE_ABGR32; case WG_VIDEO_FORMAT_AYUV: return &MEDIASUBTYPE_AYUV; case WG_VIDEO_FORMAT_I420: return &MEDIASUBTYPE_I420; case WG_VIDEO_FORMAT_NV12: return &MEDIASUBTYPE_NV12; @@ -506,6 +510,7 @@ static DWORD wg_video_format_get_compression(enum wg_video_format format) case WG_VIDEO_FORMAT_BGR: return BI_RGB; case WG_VIDEO_FORMAT_RGB15: return BI_RGB; case WG_VIDEO_FORMAT_RGB16: return BI_BITFIELDS; + case WG_VIDEO_FORMAT_RGBA: return BI_RGB; case WG_VIDEO_FORMAT_AYUV: return mmioFOURCC('A','Y','U','V'); case WG_VIDEO_FORMAT_I420: return mmioFOURCC('I','4','2','0'); case WG_VIDEO_FORMAT_NV12: return mmioFOURCC('N','V','1','2'); @@ -529,6 +534,7 @@ static WORD wg_video_format_get_depth(enum wg_video_format format) case WG_VIDEO_FORMAT_BGR: return 24; case WG_VIDEO_FORMAT_RGB15: return 16; case WG_VIDEO_FORMAT_RGB16: return 16; + case WG_VIDEO_FORMAT_RGBA: return 32; case WG_VIDEO_FORMAT_AYUV: return 32; case WG_VIDEO_FORMAT_I420: return 12; case WG_VIDEO_FORMAT_NV12: return 12; diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index a169cac55dd..a90b5950417 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -68,6 +68,7 @@ enum wg_video_format WG_VIDEO_FORMAT_BGR, WG_VIDEO_FORMAT_RGB15, WG_VIDEO_FORMAT_RGB16, + WG_VIDEO_FORMAT_RGBA,
WG_VIDEO_FORMAT_AYUV, WG_VIDEO_FORMAT_I420, diff --git a/dlls/winegstreamer/video_processor.c b/dlls/winegstreamer/video_processor.c index 0fedfb8451e..6cc504727a9 100644 --- a/dlls/winegstreamer/video_processor.c +++ b/dlls/winegstreamer/video_processor.c @@ -28,6 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat); WINE_DECLARE_DEBUG_CHANNEL(winediag);
+extern GUID MFVideoFormat_ABGR32; + static const GUID *const input_types[] = { &MFVideoFormat_IYUV, @@ -66,6 +68,7 @@ static const GUID *const output_types[] = &MFVideoFormat_AYUV, &MFVideoFormat_RGB555, &MFVideoFormat_RGB565, + &MFVideoFormat_ABGR32, };
struct video_processor diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index b28dc3f22ec..ec239142339 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -145,6 +145,8 @@ static enum wg_video_format wg_video_format_from_gst(GstVideoFormat format) return WG_VIDEO_FORMAT_RGB15; case GST_VIDEO_FORMAT_RGB16: return WG_VIDEO_FORMAT_RGB16; + case GST_VIDEO_FORMAT_RGBA: + return WG_VIDEO_FORMAT_RGBA; case GST_VIDEO_FORMAT_AYUV: return WG_VIDEO_FORMAT_AYUV; case GST_VIDEO_FORMAT_I420: @@ -568,6 +570,7 @@ static GstVideoFormat wg_video_format_to_gst(enum wg_video_format format) case WG_VIDEO_FORMAT_BGR: return GST_VIDEO_FORMAT_BGR; case WG_VIDEO_FORMAT_RGB15: return GST_VIDEO_FORMAT_RGB15; case WG_VIDEO_FORMAT_RGB16: return GST_VIDEO_FORMAT_RGB16; + case WG_VIDEO_FORMAT_RGBA: return GST_VIDEO_FORMAT_RGBA; case WG_VIDEO_FORMAT_AYUV: return GST_VIDEO_FORMAT_AYUV; case WG_VIDEO_FORMAT_I420: return GST_VIDEO_FORMAT_I420; case WG_VIDEO_FORMAT_NV12: return GST_VIDEO_FORMAT_NV12;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfreadwrite/reader.c | 13 +++++++++++++ dlls/mfreadwrite/tests/mfplat.c | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index a9d25848e7b..f4491438e3d 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -41,6 +41,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_ABGR32, D3DFMT_A8B8G8R8); + struct stream_response { struct list entry; @@ -2036,6 +2038,17 @@ static HRESULT source_reader_create_transform(struct source_reader *reader, BOOL entry->min_buffer_size = max(entry->min_buffer_size, bytes_per_second); }
+ if (IsEqualGUID(&out_type.guidMajorType, &MFMediaType_Video) && IsEqualGUID(&out_type.guidSubtype, &MFVideoFormat_ABGR32) + && IsEqualGUID(&category, &MFT_CATEGORY_VIDEO_PROCESSOR)) + { + /* The video processor isn't registered for MFVideoFormat_ABGR32, and native even only supports that format when + * D3D-enabled, we still want to instantiate a video processor in such case, so fixup the subtype for MFTEnumEx. + */ + WARN("Fixing up MFVideoFormat_ABGR32 subtype for the video processor\n"); + out_type.guidSubtype = MFVideoFormat_RGB32; + } + + count = 0; if (SUCCEEDED(hr = MFTEnumEx(category, 0, &in_type, allow_processor ? NULL : &out_type, &activates, &count))) { diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index b819b2238e9..b6981479a1b 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -3417,7 +3417,7 @@ static void test_source_reader_transforms_d3d11(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); init_media_type(media_type, abgr32_stream_type_desc, -1); hr = IMFSourceReader_SetCurrentMediaType(reader, 0, NULL, media_type); - todo_wine ok(hr == S_OK || broken(hr == MF_E_INVALIDMEDIATYPE) /* needs a GPU */, "Unexpected hr %#lx.\n", hr); + ok(hr == S_OK || broken(hr == MF_E_INVALIDMEDIATYPE) /* needs a GPU */, "Unexpected hr %#lx.\n", hr); IMFMediaType_Release(media_type);
if (hr == S_OK)
Should be good now, sorry again.