[PATCH v4 0/8] MR10549: iyuv_32: Implement Decompression
This MR adds I420 "decompression" functionality to the `iyuv_32.dll`. -- v4: iyuv_32: Implement IYUV_Decompress. iyuv_32: Implement IYUV_DecompressBegin. iyuv_32: Implement IYUV_Open. iyuv_32: Implement IYUV_DecompressGetFormat. iyuv_32: Implement IYUV_DecompressQuery. iyuv_32: Implement IYUV_GetInfo. winegstreamer: Add winegstreamer_create_color_converter. iyuv_32/tests: Fix a read overrun. https://gitlab.winehq.org/wine/wine/-/merge_requests/10549
From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/iyuv_32/tests/iyuv_32.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dlls/iyuv_32/tests/iyuv_32.c b/dlls/iyuv_32/tests/iyuv_32.c index 97572411e6e..912503f426f 100644 --- a/dlls/iyuv_32/tests/iyuv_32.c +++ b/dlls/iyuv_32/tests/iyuv_32.c @@ -297,6 +297,7 @@ static void test_decompress(DWORD handler) DWORD res, diff; BYTE *i420_data; HRSRC resource; + DWORD bmp_len; HIC hic; BITMAPINFOHEADER i420_info = @@ -322,8 +323,9 @@ static void test_decompress(DWORD handler) resource = FindResourceW(NULL, L"i420frame.bmp", (const WCHAR *)RT_RCDATA); i420_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); - i420_data += *(DWORD *)(i420_data + 2); - i420_info.biSizeImage = SizeofResource(GetModuleHandleW(NULL), resource); + bmp_len = *(DWORD *)(i420_data + 2); + i420_data += bmp_len; + i420_info.biSizeImage = SizeofResource(GetModuleHandleW(NULL), resource) - bmp_len; hic = ICOpen(ICTYPE_VIDEO, handler, ICMODE_DECOMPRESS); ok(!!hic, "Failed to open codec.\n"); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10549
From: Brendan McGrath <bmcgrath@codeweavers.com> This is a exported function that wraps the color_convert_create function. --- dlls/winegstreamer/color_convert.c | 16 ++++++++++++++++ dlls/winegstreamer/winegstreamer.spec | 1 + 2 files changed, 17 insertions(+) diff --git a/dlls/winegstreamer/color_convert.c b/dlls/winegstreamer/color_convert.c index 697cd6fcd4c..5d9e5f1c0a9 100644 --- a/dlls/winegstreamer/color_convert.c +++ b/dlls/winegstreamer/color_convert.c @@ -1038,3 +1038,19 @@ HRESULT color_convert_create(IUnknown *outer, IUnknown **out) TRACE("Created %p\n", *out); return S_OK; } + +HRESULT WINAPI winegstreamer_create_color_converter(IMFTransform **out) +{ + IUnknown *unknown; + HRESULT hr; + + TRACE("out %p.\n", out); + + if (!init_gstreamer()) + return E_FAIL; + + if (FAILED(hr = color_convert_create(NULL, &unknown))) + return hr; + + return IUnknown_QueryInterface(unknown, &IID_IMFTransform, (void**)out); +} diff --git a/dlls/winegstreamer/winegstreamer.spec b/dlls/winegstreamer/winegstreamer.spec index 095f75a0865..69eed004b78 100644 --- a/dlls/winegstreamer/winegstreamer.spec +++ b/dlls/winegstreamer/winegstreamer.spec @@ -4,3 +4,4 @@ @ stdcall -private DllUnregisterServer() @ stdcall winegstreamer_create_wm_sync_reader(ptr ptr) @ stdcall winegstreamer_create_video_decoder(ptr) +@ stdcall winegstreamer_create_color_converter(ptr) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10549
From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/iyuv_32/Makefile.in | 3 ++- dlls/iyuv_32/iyuv.c | 26 +++++++++++++++++++++++--- dlls/iyuv_32/iyuv_32.rc | 29 +++++++++++++++++++++++++++++ dlls/iyuv_32/iyuv_private.h | 27 +++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 dlls/iyuv_32/iyuv_32.rc create mode 100644 dlls/iyuv_32/iyuv_private.h diff --git a/dlls/iyuv_32/Makefile.in b/dlls/iyuv_32/Makefile.in index 6b9b11569b1..c386ec9b924 100644 --- a/dlls/iyuv_32/Makefile.in +++ b/dlls/iyuv_32/Makefile.in @@ -2,4 +2,5 @@ MODULE = iyuv_32.dll IMPORTS = user32 mfplat ole32 SOURCES = \ - iyuv.c + iyuv.c \ + iyuv_32.rc diff --git a/dlls/iyuv_32/iyuv.c b/dlls/iyuv_32/iyuv.c index e114fde50e0..c4899c64652 100644 --- a/dlls/iyuv_32/iyuv.c +++ b/dlls/iyuv_32/iyuv.c @@ -31,19 +31,23 @@ #include "vfw.h" #include "wmcodecdsp.h" +#include "iyuv_private.h" #include "wine/debug.h" #define COBJMACROS #include "mfapi.h" #include "mferror.h" -#include "mfobjects.h" #include "mfidl.h" +#include "mfobjects.h" #include "mftransform.h" WINE_DEFAULT_DEBUG_CHANNEL(iyuv_32); static HINSTANCE IYUV_32_module; +#define FOURCC_IYUV mmioFOURCC('I', 'Y', 'U', 'V') +#define IYUV_MAGIC FOURCC_IYUV + static LRESULT IYUV_Open(const ICINFO *icinfo) { FIXME("DRV_OPEN %p\n", icinfo); @@ -81,9 +85,25 @@ static LRESULT IYUV_Decompress(IMFTransform *transform, const ICDECOMPRESS *para static LRESULT IYUV_GetInfo(ICINFO *icinfo, DWORD size) { - FIXME("ICM_GETINFO %p %lu\n", icinfo, size); + TRACE("ICM_GETINFO %p %lu\n", icinfo, size); - return ICERR_UNSUPPORTED; + if (!icinfo) + return sizeof(ICINFO); + if (size < sizeof(ICINFO)) + return 0; + + icinfo->dwSize = sizeof(ICINFO); + icinfo->fccType = ICTYPE_VIDEO; + icinfo->fccHandler = IYUV_MAGIC; + icinfo->dwFlags = 0; + icinfo->dwVersion = 0; + icinfo->dwVersionICM = ICVERSION; + + LoadStringW(IYUV_32_module, IDS_NAME, icinfo->szName, ARRAY_SIZE(icinfo->szName)); + LoadStringW(IYUV_32_module, IDS_DESCRIPTION, icinfo->szDescription, ARRAY_SIZE(icinfo->szDescription)); + /* msvfw32 will fill icinfo->szDriver for us */ + + return sizeof(ICINFO); } /*********************************************************************** diff --git a/dlls/iyuv_32/iyuv_32.rc b/dlls/iyuv_32/iyuv_32.rc new file mode 100644 index 00000000000..a9705a2bd76 --- /dev/null +++ b/dlls/iyuv_32/iyuv_32.rc @@ -0,0 +1,29 @@ +/* + * Copyright 2026 Brendan McGrath for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "iyuv_private.h" + +#pragma makedep po + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +STRINGTABLE +{ + IDS_NAME "IYUV codec" + IDS_DESCRIPTION "IYUV codec" +} diff --git a/dlls/iyuv_32/iyuv_private.h b/dlls/iyuv_32/iyuv_private.h new file mode 100644 index 00000000000..cf2d392dc44 --- /dev/null +++ b/dlls/iyuv_32/iyuv_private.h @@ -0,0 +1,27 @@ +/* + * Copyright 2026 Brendan McGrath for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __IYUV_PRIVATE_H +#define __IYUV_PRIVATE_H + +#include "windef.h" + +#define IDS_NAME 100 +#define IDS_DESCRIPTION 101 + +#endif /* __IYUV_PRIVATE_H */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10549
From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/iyuv_32/iyuv.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/dlls/iyuv_32/iyuv.c b/dlls/iyuv_32/iyuv.c index c4899c64652..bd7b3be31cd 100644 --- a/dlls/iyuv_32/iyuv.c +++ b/dlls/iyuv_32/iyuv.c @@ -45,9 +45,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(iyuv_32); static HINSTANCE IYUV_32_module; +#define FOURCC_I420 mmioFOURCC('I', '4', '2', '0') #define FOURCC_IYUV mmioFOURCC('I', 'Y', 'U', 'V') #define IYUV_MAGIC FOURCC_IYUV +#define compare_fourcc(fcc1, fcc2) (((fcc1) ^ (fcc2)) & ~0x20202020) + static LRESULT IYUV_Open(const ICINFO *icinfo) { FIXME("DRV_OPEN %p\n", icinfo); @@ -57,9 +60,41 @@ static LRESULT IYUV_Open(const ICINFO *icinfo) static LRESULT IYUV_DecompressQuery(const BITMAPINFOHEADER *in, const BITMAPINFOHEADER *out) { - FIXME("ICM_DECOMPRESS_QUERY %p %p\n", in, out); + TRACE("in->planes = %d\n", in->biPlanes); + TRACE("in->bpp = %d\n", in->biBitCount); + TRACE("in->height = %ld\n", in->biHeight); + TRACE("in->width = %ld\n", in->biWidth); + TRACE("in->compr = %#lx\n", in->biCompression); - return ICERR_UNSUPPORTED; + if (compare_fourcc(in->biCompression, FOURCC_I420) && compare_fourcc(in->biCompression, FOURCC_IYUV)) + { + TRACE("can't do %#lx decompression\n", in->biCompression); + return ICERR_BADFORMAT; + } + + if (!in->biHeight || !in->biWidth) + return ICERR_BADFORMAT; + + /* output must be same dimensions as input */ + if (out) + { + TRACE("out->planes = %d\n", out->biPlanes); + TRACE("out->bpp = %d\n", out->biBitCount); + TRACE("out->height = %ld\n", out->biHeight); + TRACE("out->width = %ld\n", out->biWidth); + TRACE("out->compr = %#lx\n", out->biCompression); + + if (out->biCompression != BI_RGB) + return ICERR_BADFORMAT; + + if (out->biBitCount != 24 && out->biBitCount != 16 && out->biBitCount != 8) + return ICERR_BADFORMAT; + + if (in->biWidth != out->biWidth || in->biHeight != out->biHeight) + return ICERR_BADFORMAT; + } + + return ICERR_OK; } static LRESULT IYUV_DecompressGetFormat(BITMAPINFOHEADER *in, BITMAPINFOHEADER *out) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10549
From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/iyuv_32/iyuv.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/dlls/iyuv_32/iyuv.c b/dlls/iyuv_32/iyuv.c index bd7b3be31cd..0f1a5611f63 100644 --- a/dlls/iyuv_32/iyuv.c +++ b/dlls/iyuv_32/iyuv.c @@ -99,9 +99,25 @@ static LRESULT IYUV_DecompressQuery(const BITMAPINFOHEADER *in, const BITMAPINFO static LRESULT IYUV_DecompressGetFormat(BITMAPINFOHEADER *in, BITMAPINFOHEADER *out) { - FIXME("ICM_DECOMPRESS_GETFORMAT %p %p\n", in, out); + TRACE("ICM_DECOMPRESS_GETFORMAT %p %p\n", in, out); - return ICERR_UNSUPPORTED; + if (compare_fourcc(in->biCompression, FOURCC_I420) && compare_fourcc(in->biCompression, FOURCC_IYUV)) + return ICERR_BADFORMAT; + + if (out) + { + memset(out, 0, sizeof(*out)); + out->biSize = sizeof(BITMAPINFOHEADER); + out->biWidth = in->biWidth; + out->biHeight = abs(in->biHeight); + out->biCompression = BI_RGB; + out->biPlanes = 1; + out->biBitCount = 24; + out->biSizeImage = out->biWidth * out->biHeight * 3; + return ICERR_OK; + } + + return sizeof(*out); } static LRESULT IYUV_DecompressBegin(IMFTransform *transform, const BITMAPINFOHEADER *in, const BITMAPINFOHEADER *out) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10549
From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/iyuv_32/Makefile.in | 2 +- dlls/iyuv_32/iyuv.c | 17 ++++++++++------- dlls/iyuv_32/iyuv_private.h | 6 ++++++ dlls/iyuv_32/tests/iyuv_32.c | 3 --- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/dlls/iyuv_32/Makefile.in b/dlls/iyuv_32/Makefile.in index c386ec9b924..e5a261b973f 100644 --- a/dlls/iyuv_32/Makefile.in +++ b/dlls/iyuv_32/Makefile.in @@ -1,5 +1,5 @@ MODULE = iyuv_32.dll -IMPORTS = user32 mfplat ole32 +IMPORTS = user32 mfplat ole32 winegstreamer SOURCES = \ iyuv.c \ diff --git a/dlls/iyuv_32/iyuv.c b/dlls/iyuv_32/iyuv.c index 0f1a5611f63..111d6fd1d2d 100644 --- a/dlls/iyuv_32/iyuv.c +++ b/dlls/iyuv_32/iyuv.c @@ -34,12 +34,7 @@ #include "iyuv_private.h" #include "wine/debug.h" -#define COBJMACROS -#include "mfapi.h" #include "mferror.h" -#include "mfidl.h" -#include "mfobjects.h" -#include "mftransform.h" WINE_DEFAULT_DEBUG_CHANNEL(iyuv_32); @@ -53,9 +48,17 @@ static HINSTANCE IYUV_32_module; static LRESULT IYUV_Open(const ICINFO *icinfo) { - FIXME("DRV_OPEN %p\n", icinfo); + IMFTransform *transform; - return 0; + TRACE("DRV_OPEN %p\n", icinfo); + + if (icinfo && compare_fourcc(icinfo->fccType, ICTYPE_VIDEO)) + return 0; + + if (FAILED(winegstreamer_create_color_converter(&transform))) + transform = NULL; + + return (LRESULT)transform; } static LRESULT IYUV_DecompressQuery(const BITMAPINFOHEADER *in, const BITMAPINFOHEADER *out) diff --git a/dlls/iyuv_32/iyuv_private.h b/dlls/iyuv_32/iyuv_private.h index cf2d392dc44..694f89799d5 100644 --- a/dlls/iyuv_32/iyuv_private.h +++ b/dlls/iyuv_32/iyuv_private.h @@ -21,6 +21,12 @@ #include "windef.h" +#define COBJMACROS +#include "mfapi.h" +#include "mftransform.h" + +HRESULT WINAPI winegstreamer_create_color_converter(IMFTransform **out); + #define IDS_NAME 100 #define IDS_DESCRIPTION 101 diff --git a/dlls/iyuv_32/tests/iyuv_32.c b/dlls/iyuv_32/tests/iyuv_32.c index 912503f426f..e886fcae683 100644 --- a/dlls/iyuv_32/tests/iyuv_32.c +++ b/dlls/iyuv_32/tests/iyuv_32.c @@ -458,10 +458,7 @@ START_TEST(iyuv_32) int i; hic = ICLocate(ICTYPE_VIDEO, FOURCC_I420, &in, NULL, ICMODE_DECOMPRESS); - todo_wine ok(!!hic, "Failed to locate iyuv codec\n"); - if (!hic) - return; ICClose(hic); for (i = 0; i < ARRAY_SIZE(handler); i++) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10549
From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/iyuv_32/iyuv.c | 61 ++++++++++++++++++++++++++++++++++-- dlls/iyuv_32/tests/iyuv_32.c | 6 ---- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/dlls/iyuv_32/iyuv.c b/dlls/iyuv_32/iyuv.c index 111d6fd1d2d..c69040e70b1 100644 --- a/dlls/iyuv_32/iyuv.c +++ b/dlls/iyuv_32/iyuv.c @@ -46,6 +46,11 @@ static HINSTANCE IYUV_32_module; #define compare_fourcc(fcc1, fcc2) (((fcc1) ^ (fcc2)) & ~0x20202020) +static inline UINT64 make_uint64(UINT32 high, UINT32 low) +{ + return ((UINT64)high << 32) | low; +} + static LRESULT IYUV_Open(const ICINFO *icinfo) { IMFTransform *transform; @@ -125,9 +130,61 @@ static LRESULT IYUV_DecompressGetFormat(BITMAPINFOHEADER *in, BITMAPINFOHEADER * static LRESULT IYUV_DecompressBegin(IMFTransform *transform, const BITMAPINFOHEADER *in, const BITMAPINFOHEADER *out) { - FIXME("ICM_DECOMPRESS_BEGIN %p %p %p\n", transform, in, out); + IMFMediaType *input_type, *output_type; + LRESULT r = ICERR_INTERNAL; + const GUID *output_subtype; + LONG stride, depth; + + TRACE("transform %p, in %p, out %p.\n", transform, in, out); + + if (!transform) + return ICERR_BADPARAM; + + if (out->biBitCount == 24) + output_subtype = &MFVideoFormat_RGB24; + else if (out->biBitCount == 16) + output_subtype = &MFVideoFormat_RGB555; + else if (out->biBitCount == 8) + output_subtype = &MFVideoFormat_RGB8; + else + return ICERR_BADFORMAT; - return ICERR_UNSUPPORTED; + depth = out->biBitCount / 8; + stride = -((out->biWidth * depth + 3) & ~3); + + if (FAILED(MFCreateMediaType(&input_type))) + return ICERR_INTERNAL; + + if (FAILED(MFCreateMediaType(&output_type))) + { + IMFMediaType_Release(input_type); + return ICERR_INTERNAL; + } + + if (FAILED(IMFMediaType_SetGUID(input_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video)) || + FAILED(IMFMediaType_SetGUID(input_type, &MF_MT_SUBTYPE, &MFVideoFormat_I420))) + goto done; + if (FAILED(IMFMediaType_SetUINT64(input_type, &MF_MT_FRAME_SIZE, make_uint64(in->biWidth, in->biHeight)))) + goto done; + + if (FAILED(IMFMediaType_SetGUID(output_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video)) || + FAILED(IMFMediaType_SetGUID(output_type, &MF_MT_SUBTYPE, output_subtype))) + goto done; + if (FAILED(IMFMediaType_SetUINT64(output_type, &MF_MT_FRAME_SIZE, make_uint64(out->biWidth, out->biHeight)))) + goto done; + if (FAILED(IMFMediaType_SetUINT32(output_type, &MF_MT_DEFAULT_STRIDE, stride))) + goto done; + + if (FAILED(IMFTransform_SetInputType(transform, 0, input_type, 0)) || + FAILED(IMFTransform_SetOutputType(transform, 0, output_type, 0))) + goto done; + + r = ICERR_OK; + +done: + IMFMediaType_Release(input_type); + IMFMediaType_Release(output_type); + return r; } static LRESULT IYUV_Decompress(IMFTransform *transform, const ICDECOMPRESS *params) diff --git a/dlls/iyuv_32/tests/iyuv_32.c b/dlls/iyuv_32/tests/iyuv_32.c index e886fcae683..a58e944a67d 100644 --- a/dlls/iyuv_32/tests/iyuv_32.c +++ b/dlls/iyuv_32/tests/iyuv_32.c @@ -269,7 +269,6 @@ static void test_formats(DWORD handler) out.biCompression = BI_RGB; out.biBitCount = 24; res = ICDecompressBegin(hic, &in, &out); - todo_wine ok(res == ICERR_OK, "Got %ld.\n", res); res = ICDecompressEnd(hic); @@ -331,12 +330,8 @@ static void test_decompress(DWORD handler) ok(!!hic, "Failed to open codec.\n"); res = ICDecompressBegin(hic, &i420_info, &rgb_info); - todo_wine ok(res == ICERR_OK, "Got %ld.\n", res); - if (res != ICERR_OK) - goto skip_decompression_tests; - res = ICDecompress(hic, 0, &i420_info, i420_data, &rgb_info, rgb_data); todo_wine ok(res == ICERR_OK, "Got %ld.\n", res); @@ -356,7 +351,6 @@ static void test_decompress(DWORD handler) todo_wine ok(diff == 0, "Got %lu%% difference.\n", diff); -skip_decompression_tests: res = ICClose(hic); ok(res == ICERR_OK, "Got %ld.\n", res); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10549
From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/iyuv_32/iyuv.c | 71 +++++++++++++++++++++++++++++++++++- dlls/iyuv_32/tests/iyuv_32.c | 2 - 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/dlls/iyuv_32/iyuv.c b/dlls/iyuv_32/iyuv.c index c69040e70b1..e0b9dec58c8 100644 --- a/dlls/iyuv_32/iyuv.c +++ b/dlls/iyuv_32/iyuv.c @@ -189,9 +189,76 @@ done: static LRESULT IYUV_Decompress(IMFTransform *transform, const ICDECOMPRESS *params) { - FIXME("ICM_DECOMPRESS %p %p\n", transform, params); + IMFSample *in_sample = NULL, *out_sample = NULL; + IMFMediaBuffer *in_buf = NULL, *out_buf = NULL; + MFT_OUTPUT_DATA_BUFFER mft_buf; + LRESULT r = ICERR_INTERNAL; + DWORD mft_status; + BYTE *data; + + TRACE("transform %p, params %p.\n", transform, params); + + if (FAILED(MFCreateSample(&in_sample))) + return ICERR_INTERNAL; + + if (FAILED(MFCreateMemoryBuffer(params->lpbiInput->biSizeImage, &in_buf))) + goto done; + + if (FAILED(IMFSample_AddBuffer(in_sample, in_buf))) + goto done; + + if (FAILED(MFCreateSample(&out_sample))) + goto done; + + if (FAILED(MFCreateMemoryBuffer(params->lpbiOutput->biSizeImage, &out_buf))) + goto done; + + if (FAILED(IMFSample_AddBuffer(out_sample, out_buf))) + goto done; + + if (FAILED(IMFMediaBuffer_Lock(in_buf, &data, NULL, NULL))) + goto done; + + memcpy(data, params->lpInput, params->lpbiInput->biSizeImage); - return ICERR_UNSUPPORTED; + if (FAILED(IMFMediaBuffer_Unlock(in_buf))) + goto done; + + if (FAILED(IMFMediaBuffer_SetCurrentLength(in_buf, params->lpbiInput->biSizeImage))) + goto done; + + if (FAILED(IMFTransform_ProcessInput(transform, 0, in_sample, 0))) + goto done; + + memset(&mft_buf, 0, sizeof(mft_buf)); + mft_buf.pSample = out_sample; + + if (SUCCEEDED(IMFTransform_ProcessOutput(transform, 0, 1, &mft_buf, &mft_status))) + { + LONG depth = params->lpbiOutput->biBitCount / 8; + LONG width = params->lpbiOutput->biWidth * depth; + LONG stride = (width + 3) & ~3; + + if (FAILED(IMFMediaBuffer_Lock(out_buf, &data, NULL, NULL))) + goto done; + + MFCopyImage(params->lpOutput, stride, data, stride, width, params->lpbiOutput->biHeight); + + IMFMediaBuffer_Unlock(out_buf); + r = ICERR_OK; + } + +done: + if (in_buf) + IMFMediaBuffer_Release(in_buf); + if (in_sample) + IMFSample_Release(in_sample); + if (out_buf) + IMFMediaBuffer_Release(out_buf); + if (out_sample) + IMFSample_Release(out_sample); + + return r; } static LRESULT IYUV_GetInfo(ICINFO *icinfo, DWORD size) diff --git a/dlls/iyuv_32/tests/iyuv_32.c b/dlls/iyuv_32/tests/iyuv_32.c index a58e944a67d..b11abb4de45 100644 --- a/dlls/iyuv_32/tests/iyuv_32.c +++ b/dlls/iyuv_32/tests/iyuv_32.c @@ -333,7 +333,6 @@ static void test_decompress(DWORD handler) ok(res == ICERR_OK, "Got %ld.\n", res); res = ICDecompress(hic, 0, &i420_info, i420_data, &rgb_info, rgb_data); - todo_wine ok(res == ICERR_OK, "Got %ld.\n", res); res = ICDecompressEnd(hic); ok(res == ICERR_OK, "Got %ld.\n", res); @@ -348,7 +347,6 @@ static void test_decompress(DWORD handler) for (unsigned int i = 0; i < rgb_info.biSizeImage; ++i) diff += abs((int)rgb_data[i] - (int)expect_rgb_data[i]); diff = diff * 100 / 256 / rgb_info.biSizeImage; - todo_wine ok(diff == 0, "Got %lu%% difference.\n", diff); res = ICClose(hic); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10549
On Sun Apr 5 23:14:04 2026 +0000, Brendan McGrath wrote:
The pipeline is still failing with the following test: ```xml <testcase classname="iyuv_32:iyuv_32" name="iyuv_32:iyuv_32 status -1073741819" file="dlls/iyuv_32/tests/iyuv_32.c" assertions="0" time="0.105000"> <system-out>Test exited with status -1073741819</system-out> <failure/> </testcase> ``` -1073741819 is 0xC0000005, which is `STATUS_ACCESS_VIOLATION`. But I can't recreate this locally, and the tests pass find on the testbot: https://testbot.winehq.org/JobDetails.pl?Key=162427 Is there a way to get additional detail about this failure? It took a couple of days, but it did eventually dawn on me that the build pipeline probably includes the artifacts used for testing. It did. And running locally I was able to recreate and then fix the issue. The decompression test was providing the wrong value for the I420 image length resulting in a read overrun.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10549#note_135078
On Sun Apr 5 23:11:18 2026 +0000, Brendan McGrath wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/10549/diffs?diff_id=258158&start_sha=1891c48f8e22f087bc746b42aac63bd1b15b039c#30f26154602482476fa8e38926f7fccae30ad784_103_100) OK, thanks. That is better. Done.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10549#note_135079
On Sun Apr 5 23:11:18 2026 +0000, Brendan McGrath wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/10549/diffs?diff_id=258158&start_sha=1891c48f8e22f087bc746b42aac63bd1b15b039c#30f26154602482476fa8e38926f7fccae30ad784_243_236) OK, thanks again. This is now treated as an error.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10549#note_135080
On Sun Apr 5 23:11:19 2026 +0000, Brendan McGrath wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/10549/diffs?diff_id=258158&start_sha=1891c48f8e22f087bc746b42aac63bd1b15b039c#30f26154602482476fa8e38926f7fccae30ad784_263_250) OK. Done. Thank you.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10549#note_135081
On Fri Apr 3 03:07:33 2026 +0000, Anton Baskanov wrote:
Another approach would be to move all the VFW code to `winegstreamer` and create something like `vfw_transform` which exposes a `winegstreamer_vfw_driver_proc`. The VFW codec dlls would then become thin wrappers around it and most of the code would be shared between them. I think there is enough differences between `IYUV` and `IR50` that we're going to need separate code paths somewhere. So I think putting that in their own DLLs makes sense. And eventually, something as simple as I420 decompression could end up having a lighter implementation outside of `winegstreamer`.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10549#note_135082
v4: - Fix over-read bug in the decompression test (which fixes the pipeline) - Refactor an if/else check in QueryDecompression - Treat `MF_E_TRANSFORM_STREAM_CHANGE` and `MF_E_TRANSFORM_NEED_MORE_INPUT` as errors - Rebase to master -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10549#note_135083
1/8 has a whitespace error. 3/8: ``` +#define FOURCC_IYUV mmioFOURCC('I', 'Y', 'U', 'V') +#define IYUV_MAGIC FOURCC_IYUV ``` Why do you need both of those macros? ``` + LoadStringW(IYUV_32_module, IDS_NAME, icinfo->szName, ARRAY_SIZE(icinfo->szName)); + LoadStringW(IYUV_32_module, IDS_DESCRIPTION, icinfo->szDescription, ARRAY_SIZE(icinfo->szDescription)); ``` I suppose the other drivers do this too, but I'm not convinced it's useful. 7/8: ``` + stride = -((out->biWidth * depth + 3) & ~3); ``` That should depend on the sign of the height. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10549#note_135160
participants (3)
-
Brendan McGrath -
Brendan McGrath (@redmcg) -
Elizabeth Figura (@zfigura)