This fixes some upside-down videos in Secret of Mana. The game plays a NV12 video using MF session and EVR, then calls GetCurrentImage to get the frame RGB data and display it itself.
-- v2: evr: Respect RGB format stride in GetCurrentImage. evr/tests: Test IMFVideoDisplayControl_GetCurrentImage orientation.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/evr/tests/Makefile.in | 2 + dlls/evr/tests/evr.c | 271 ++++++++++++++++++++++++++++- dlls/evr/tests/nv12frame.bmp | Bin 0 -> 50742 bytes dlls/evr/tests/resource.rc | 33 ++++ dlls/evr/tests/rgb32frame-flip.bmp | Bin 0 -> 36918 bytes dlls/evr/tests/rgb32frame.bmp | Bin 0 -> 36918 bytes 6 files changed, 301 insertions(+), 5 deletions(-) create mode 100644 dlls/evr/tests/nv12frame.bmp create mode 100644 dlls/evr/tests/resource.rc create mode 100644 dlls/evr/tests/rgb32frame-flip.bmp create mode 100644 dlls/evr/tests/rgb32frame.bmp
diff --git a/dlls/evr/tests/Makefile.in b/dlls/evr/tests/Makefile.in index c5db2226ebc..6b89635225a 100644 --- a/dlls/evr/tests/Makefile.in +++ b/dlls/evr/tests/Makefile.in @@ -3,3 +3,5 @@ IMPORTS = dxva2 mfplat mfuuid mf strmiids uuid dxguid ole32 oleaut32 evr d3d9
C_SRCS = \ evr.c + +RC_SRCS = resource.rc diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index e0cec1ba8c9..662919c7d94 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -31,6 +31,95 @@
static const WCHAR sink_id[] = L"EVR Input0";
+static void load_resource(const WCHAR *filename, const BYTE **data, DWORD *length) +{ + HRSRC resource = FindResourceW(NULL, filename, (const WCHAR *)RT_RCDATA); + ok(resource != 0, "FindResourceW failed, error %lu\n", GetLastError()); + *data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); + *length = SizeofResource(GetModuleHandleW(NULL), resource); +} + +static DWORD compare_rgb32(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) +{ + DWORD x, y, size, diff = 0, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf; + + /* skip BMP header from the dump */ + size = *(DWORD *)(expect + 2 + 2 * sizeof(DWORD)); + *length = *length + size; + expect = expect + 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]); + } + } + + size = (rect->right - rect->left) * (rect->bottom - rect->top) * 3; + return diff * 100 / 256 / size; +} + +static void dump_rgb32(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) +{ + DWORD width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf; + static const char magic[2] = "BM"; + struct + { + DWORD length; + DWORD reserved; + DWORD offset; + BITMAPINFOHEADER biHeader; + } header = + { + .length = length + sizeof(header) + 2, .offset = sizeof(header) + 2, + .biHeader = + { + .biSize = sizeof(BITMAPINFOHEADER), .biWidth = width, .biHeight = height, .biPlanes = 1, + .biBitCount = 32, .biCompression = BI_RGB, .biSizeImage = width * height * 4, + }, + }; + DWORD written; + BOOL ret; + + ret = WriteFile(output, magic, sizeof(magic), &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == sizeof(magic), "written %lu bytes\n", written); + ret = WriteFile(output, &header, sizeof(header), &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == sizeof(header), "written %lu bytes\n", written); + ret = WriteFile(output, data, length, &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == length, "written %lu bytes\n", written); +} + +#define check_rgb32_data(a, b, c, d) check_rgb32_data_(__LINE__, a, b, c, d) +static DWORD check_rgb32_data_(int line, const WCHAR *filename, const BYTE *data, DWORD length, const RECT *rect) +{ + WCHAR output_path[MAX_PATH]; + const BYTE *expect_data; + HRSRC resource; + HANDLE output; + + GetTempPathW(ARRAY_SIZE(output_path), output_path); + lstrcatW(output_path, filename); + output = CreateFileW(output_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(output != INVALID_HANDLE_VALUE, "CreateFileW failed, error %lu\n", GetLastError()); + dump_rgb32(data, length, rect, output); + trace("created %s\n", debugstr_w(output_path)); + CloseHandle(output); + + resource = FindResourceW(NULL, filename, (const WCHAR *)RT_RCDATA); + ok(resource != 0, "FindResourceW failed, error %lu\n", GetLastError()); + expect_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); + + return compare_rgb32(data, &length, rect, expect_data); +} + static void set_rect(MFVideoNormalizedRect *rect, float left, float top, float right, float bottom) { rect->left = left; @@ -2912,8 +3001,8 @@ static void test_mixer_zorder(void) IMFTransform_Release(mixer); }
-static IDirect3DSurface9 * create_surface(IDirect3DDeviceManager9 *manager, unsigned int width, - unsigned int height) +static IDirect3DSurface9 * create_surface(IDirect3DDeviceManager9 *manager, UINT fourcc, + unsigned int width, unsigned int height) { IDirectXVideoAccelerationService *service; IDirect3DSurface9 *surface = NULL; @@ -2931,7 +3020,7 @@ static IDirect3DSurface9 * create_surface(IDirect3DDeviceManager9 *manager, unsi (void **)&service); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IDirectXVideoAccelerationService_CreateSurface(service, width, height, 0, D3DFMT_A8R8G8B8, + hr = IDirectXVideoAccelerationService_CreateSurface(service, width, height, 0, fourcc, D3DPOOL_DEFAULT, 0, DXVA2_VideoProcessorRenderTarget, &surface, NULL); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
@@ -3080,7 +3169,7 @@ static void test_mixer_samples(void)
IMFSample_Release(sample);
- surface = create_surface(manager, 64, 64); + surface = create_surface(manager, D3DFMT_A8R8G8B8, 64, 64);
hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -3229,6 +3318,176 @@ done: DestroyWindow(window); }
+static void test_presenter_orientation(const GUID *subtype) +{ + IMFTopologyServiceLookupClient *lookup_client; + static const BITMAPINFOHEADER expect_header = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 96, .biHeight = 96, + .biPlanes = 1, .biBitCount = 32, + .biCompression = BI_RGB, + .biSizeImage = 96 * 96 * 4, + }; + BITMAPINFOHEADER header = {.biSize = sizeof(BITMAPINFOHEADER)}; + IMFVideoDisplayControl *display_control; + DWORD diff, data_size, frame_data_len; + IDirect3DDeviceManager9 *manager; + D3DLOCKED_RECT d3d_rect = {0}; + IMFVideoPresenter *presenter; + IDirect3DSurface9 *surface; + IMFMediaType *video_type; + const BYTE *frame_data; + struct test_host host; + IMFTransform *mixer; + LONGLONG timestamp; + IMFSample *sample; + LONG stride, ref; + HWND window; + BYTE *data; + HRESULT hr; + RECT rect; + + window = create_window(); + + hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer); + ok(hr == S_OK, "Failed to create a mixer, hr %#lx.\n", hr); + hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + init_test_host(&host, mixer, presenter); + hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFTopologyServiceLookupClient_Release(lookup_client); + + /* Configure device and media types. */ + + hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&manager); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IDirect3DDeviceManager9_Release(manager); + + video_type = create_video_type(subtype); + hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)expect_header.biWidth << 32 | expect_header.biHeight); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFTransform_SetInputType(mixer, 0, video_type, 0); + if (broken(IsEqualGUID(subtype, &MFVideoFormat_NV12) && hr == E_FAIL)) + { + win_skip("Skipping unsupported NV12 format\n"); + IMFMediaType_Release(video_type); + goto skip_tests; + } + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTransform_SetOutputType(mixer, 0, video_type, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(video_type); + + hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_BEGINSTREAMING, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + if (IsEqualGUID(subtype, &MFVideoFormat_NV12)) + { + load_resource(L"nv12frame.bmp", &frame_data, &frame_data_len); + /* skip BMP header and RGB data from the dump */ + data_size = *(DWORD *)(frame_data + 2); + frame_data_len = frame_data_len - data_size; + frame_data = frame_data + data_size; + ok(frame_data_len == 13824, "got length %lu\n", frame_data_len); + } + else + { + load_resource(L"rgb32frame.bmp", &frame_data, &frame_data_len); + /* skip BMP header from the dump */ + data_size = *(DWORD *)(frame_data + 2 + 2 * sizeof(DWORD)); + frame_data_len -= data_size; + frame_data += data_size; + ok(frame_data_len == 36864, "got length %lu\n", frame_data_len); + } + + surface = create_surface(manager, subtype->Data1, expect_header.biWidth, expect_header.biHeight); + ok(!!surface, "Failed to create input surface.\n"); + hr = IDirect3DSurface9_LockRect(surface, &d3d_rect, NULL, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (IsEqualGUID(subtype, &MFVideoFormat_RGB32)) + memcpy(d3d_rect.pBits, frame_data, frame_data_len); + else if (IsEqualGUID(subtype, &MFVideoFormat_NV12)) + { + hr = MFGetStrideForBitmapInfoHeader(subtype->Data1, expect_header.biWidth, &stride); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCopyImage(d3d_rect.pBits, d3d_rect.Pitch, frame_data, stride, expect_header.biWidth, expect_header.biHeight); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + frame_data += stride * expect_header.biHeight; + d3d_rect.pBits = (BYTE *)d3d_rect.pBits + d3d_rect.Pitch * expect_header.biHeight; + hr = MFCopyImage(d3d_rect.pBits, d3d_rect.Pitch, frame_data, stride, expect_header.biWidth, expect_header.biHeight / 2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } + hr = IDirect3DSurface9_UnlockRect(surface); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IDirect3DSurface9_Release(surface); + + hr = IMFTransform_ProcessInput(mixer, 0, sample, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_PROCESSINPUTNOTIFY, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFSample_Release(sample); + + hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFVideoDisplayControl_GetCurrentImage(display_control, &header, &data, &data_size, ×tamp); + if (hr == MF_E_INVALIDREQUEST) + { + Sleep(500); + hr = IMFVideoDisplayControl_GetCurrentImage(display_control, &header, &data, &data_size, ×tamp); + } + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFVideoDisplayControl_Release(display_control); + + ok(header.biSize == expect_header.biSize, "Unexpected biSize %#lx\n", header.biSize); + ok(header.biWidth == expect_header.biWidth, "Unexpected biWidth %#lx\n", header.biWidth); + ok(header.biHeight == expect_header.biHeight, "Unexpected biHeight %#lx\n", header.biHeight); + ok(header.biPlanes == expect_header.biPlanes, "Unexpected biPlanes %#x\n", header.biPlanes); + ok(header.biBitCount == expect_header.biBitCount, "Unexpected biBitCount %#x\n", header.biBitCount); + ok(header.biCompression == expect_header.biCompression, "Unexpected biCompression %#lx\n", header.biCompression); + ok(header.biSizeImage == expect_header.biSizeImage, "Unexpected biSizeImage %#lx\n", header.biSizeImage); + ok(header.biXPelsPerMeter == expect_header.biXPelsPerMeter, "Unexpected biXPelsPerMeter %#lx\n", header.biXPelsPerMeter); + ok(header.biYPelsPerMeter == expect_header.biYPelsPerMeter, "Unexpected biYPelsPerMeter %#lx\n", header.biYPelsPerMeter); + ok(header.biClrUsed == expect_header.biClrUsed, "Unexpected biClrUsed %#lx\n", header.biClrUsed); + ok(header.biClrImportant == expect_header.biClrImportant, "Unexpected biClrImportant %#lx\n", header.biClrImportant); + + SetRect(&rect, 0, 0, header.biWidth, header.biHeight); + diff = check_rgb32_data(L"rgb32frame-flip.bmp", data, header.biSizeImage, &rect); + todo_wine + ok(diff <= 3, "Unexpected %lu%% diff\n", diff); + CoTaskMemFree(data); + + hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_ENDSTREAMING, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + +skip_tests: + hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopologyServiceLookupClient_ReleaseServicePointers(lookup_client); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFTopologyServiceLookupClient_Release(lookup_client); + + ref = IMFTransform_Release(mixer); + ok(ref == 0, "Unexpected ref %ld\n", ref); + ref = IMFVideoPresenter_Release(presenter); + ok(ref == 0, "Unexpected ref %ld\n", ref); + + DestroyWindow(window); +} + static void test_MFIsFormatYUV(void) { static const DWORD formats[] = @@ -3332,7 +3591,7 @@ static void test_mixer_render(void) IMFMediaType_Release(output_type); IMFMediaType_Release(video_type);
- surface = create_surface(manager, 64, 64); + surface = create_surface(manager, D3DFMT_A8R8G8B8, 64, 64); ok(!!surface, "Failed to create input surface.\n");
hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample); @@ -3421,6 +3680,8 @@ START_TEST(evr) test_presenter_video_window(); test_presenter_quality_control(); test_presenter_media_type(); + test_presenter_orientation(&MFVideoFormat_NV12); + test_presenter_orientation(&MFVideoFormat_RGB32); test_presenter_shutdown(); test_mixer_output_rectangle(); test_mixer_zorder(); diff --git a/dlls/evr/tests/nv12frame.bmp b/dlls/evr/tests/nv12frame.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f37bdfc4062ef20d0f017e43147767708c51c09b GIT binary patch literal 50742 zcmeI5v5g`@5JmSgm=IQ2M*<VT`D@@}osB^Zgm4f92B9F~5C93_Oa^l^w`*);lytwp zTAI@9RwG)i`c%Dr{{H&t|GfQM{q*^BI={cpkGJ>f+qAykKQEu3&%<Hl)HAr<ZliKw zU(bGKsIZ@F;1B-{4&cAXW7P%t!(VkLLmmF(e+G}$8So$fRd+Jf;r}xIzjvpRQ_n#4 zANKX^XNK_ia8!MSKm1j9GSuNe{%7!5odN&xUv(!#9sc8g29MPl@PC>9U(Vggsb`@2 z5BqxdGeh`$II2FvAO5O48S3yK|1)^3&Vc{;uey_=4*&5#gU9L&_`gj5kNs-o)H6{1 zhkZT!nIZf=9919T4}aC240ZUA{~0`1XTX2_SKY}_hyVDW!DDp>{9mU3yX#}*)H6{1 zhkZT!nIZf=9919T4}aC240ZUA{~0`1XTX2_SKY}_hyVDW!DDp>{9mU3o9!@i>KUm1 z!@i#V%n<$_j;fFFhrjAhhC2Mm{|p|hGvGh|tL|i|!+-qG;ITRb{x8%2^{^i~^$b-1 zVPDUFW(a=|N7YC8!(VkLLmmF(e+G}$8So$fRd+Jf;XnRo@K~Jz|Ci~%`gfyF`+x6n zgBuRu01n^)4&VR|-~bNb01n^)4&Xp*2cGsdP4I2mDcKcr?2F{5`fPuk@60olE?< zEuXu6mHpe}@8ri!;RBzTK>XU)pNoB!{oCU&<i||m1D}{c{My!^qkWbA+vAVq$4ub^ zpO`@W+SZ?)eU<&&<9Fo8OyL8cm_Yp6)}M`imHpe}H{{1m;RBzTK>XU)pS69J{oCW$ z<i||m1D}{c{My!^^4GXQ00IzbN8n&zW$*U*1Nkx2wtTvidzbyY)4LP-G1Inu&YgRg z{kzl89r-cSwtV`PdzbyY)B6?qG1Inut`GMv`*){bALPeO+w$2C?p^lpPTvmX$4uMu a8TRg7_U}#~_T<M*+wv)YjT;31kHBAWY55KS
literal 0 HcmV?d00001
diff --git a/dlls/evr/tests/resource.rc b/dlls/evr/tests/resource.rc new file mode 100644 index 00000000000..79b62304303 --- /dev/null +++ b/dlls/evr/tests/resource.rc @@ -0,0 +1,33 @@ +/* + * Resources for mf test suite. + * + * Copyright 2022 Rémi Bernon 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 "windef.h" + +/* Generated from running the mf:transform tests on Windows */ +/* @makedep: rgb32frame.bmp */ +rgb32frame.bmp RCDATA rgb32frame.bmp + +/* Generated from running the mf:transform tests on Windows */ +/* @makedep: rgb32frame-flip.bmp */ +rgb32frame-flip.bmp RCDATA rgb32frame-flip.bmp + +/* Generated from running the mf:transform tests on Windows */ +/* @makedep: nv12frame.bmp */ +nv12frame.bmp RCDATA nv12frame.bmp diff --git a/dlls/evr/tests/rgb32frame-flip.bmp b/dlls/evr/tests/rgb32frame-flip.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2a089de19287f43a1b06e1a1b83e37a24a610f1a GIT binary patch literal 36918 zcmeI4JxT*n6h^-wHd=|5KZS*YD+t)yn<m)116_ixg<|Ov)F#`}QcN!hrbuv}4|M~% z-@tG)Cvbux-0<e)<Uz(Er)R@^{oaQ4{<w1S&p-$DuX_7`{_nxxeYq|I9MAv_&;Sk4 z01eOp4bT7$&;Sjrd;<^lJqF)F^gO~%^$)&-p#Pb+1-^smJ~`Eiz;_V!-wY)19pK-0 z=yZsG{5$<*pQV5L&)%@Je)^|>r=RSz(f)5W68H|H{$I2s@Et_`AFfXYzJsX$%dLsP zcM$b2eb)=&z;%HCZX3cs{@u@T=6U+3|IGcmYo~wucN@w)AMJmvPl4|s>VH>rf$t#d z|81=Zd<Rkgj~hkcJBa%KR#VUZfa?JN-8O`O{JWpw%=7e5|C#%B*G~WR?>3Zqp8n}S zbHDD|qy4MY%OAjYfd6hg!ax4|ypPd8{nP*Qzt_=cXKfxk`w#n1n>}TFE&9*d|M^S; z-$Ath{d(CR_zt4}-^-f7cM$deTs8&1gQ)*f&wWA*4z8E~?)Ceg;lG{!@ZXNdXpi{E zf3%%dn4^FCUxkjN$3Xun`@j1b34909?_aNr9f9v4>i?)r1-^r*|En?)_zt4}Rq6?7 zupQvP+m7&$|32?y^iTivzx@AT`s}RDV`u-#x&Ms6>TlnG?I7C!-eNBB9Yp=V)r%j% zcM$deRQ-eRAnLzq8iDTs|Gq<~L;U04=_mUv{nLN;hMo1(Km9xXWS^yf`p@35v;JuR EKX0Xo-v9sr
literal 0 HcmV?d00001
diff --git a/dlls/evr/tests/rgb32frame.bmp b/dlls/evr/tests/rgb32frame.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9f2ea1e5d1b2b808f3671b09c19ed6fcd090de85 GIT binary patch literal 36918 zcmeI*u}Yg^9EI^Cp-Y{_DXoJ;g<gTswR>Gccke(i!PP-=^b)K~Zl@ik*$ag_DEVIB zs5js_AC!Oc1db^3!j~V9MuH??za3ub`F7Ype(pPd-In(IXZ`m2{g*FZJ`TemmK(IQ zCTG~^_A5ijesu<a{MVrY`X8rbw*~z1ciUNqbM#OD>(H@#ALzek|36w2%MINA@47$B z4P5_^j}KzGf$Kl}_g5@8aQ)SmVz~kSxna^F{`e>TR6k4q^k2Q<<ofBK{*!*HpLP2` zZF8~Q!1X_93$fh5_5bxa70V4=|I0r|V!46q-=BUK8^OT*|2OPMuwONd|Ns3t#vlJp zek`GX`ltW5KMrrQ*_ij;{QYy=w#9M-_wUc&Z6cN%xc+<nX>*nvxc=YoC6*hw{_2lG zEH}VEH%vOjAOEDE>SyVn{;M~fTtEHOf6`C&v-D5@)f-N(-|c^?K`b}GKQ~M|#2^2p zpXz7npZ=>ioLoQs(|^)W^|SO(|J55#uHWtd=6w^(4P5`bNq_Ad78|(!AM_xW8@T>6 z_1C^(v4QKa{_H2q4e-wmlMeC6Kk29XS^B5{>J2B?Pyh6v^i%z;+yBYVTr4+m{Xe~1 zh~);Z|4&WDas$`@LPuh`f$KkPNh~+OKQ~M|#2^2ppXz7npZ=>ioLoQs(|^)W^|NmO z3w;sG4P5_w?TY0Fu75l4?_17tgEQ~_-`jOR$8rPLpL1`2%|gsDqX8PA0UDqI8lV9h MpaB}7fpQHz0TpqG-v9sr
literal 0 HcmV?d00001
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/evr/presenter.c | 3 ++- dlls/evr/tests/evr.c | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index d8bdbee3915..06592f8766e 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -1531,7 +1531,8 @@ static HRESULT WINAPI video_presenter_control_GetCurrentImage(IMFVideoDisplayCon { if (SUCCEEDED(hr = IDirect3DSurface9_LockRect(readback, &mapped_rect, NULL, D3DLOCK_READONLY))) { - memcpy(*dib, mapped_rect.pBits, *dib_size); + hr = MFCopyImage(stride < 0 ? *dib + *dib_size + stride : *dib, stride, + mapped_rect.pBits, mapped_rect.Pitch, abs(stride), surface_desc.Height); IDirect3DSurface9_UnlockRect(readback); } } diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 662919c7d94..d6fa1ad6ef1 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -3466,8 +3466,7 @@ static void test_presenter_orientation(const GUID *subtype)
SetRect(&rect, 0, 0, header.biWidth, header.biHeight); diff = check_rgb32_data(L"rgb32frame-flip.bmp", data, header.biSizeImage, &rect); - todo_wine - ok(diff <= 3, "Unexpected %lu%% diff\n", diff); + ok(diff <= 5, "Unexpected %lu%% diff\n", diff); CoTaskMemFree(data);
hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_ENDSTREAMING, 0);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=133125
Your paranoid android.
=== w1064_tsign (32 bit report) ===
evr: evr.c:3485: Test failed: Unexpected ref 1
v2: Add a test, fix +/- operator when adding negative stride, use abs(stride) for `MFCopyImage` source stride.
On Wed May 24 06:47:39 2023 +0000, eric pouech wrote:
shouldn't we optimize CopyImage then? (when src/dst stride are equal and positive)
I also think this is something that should be addressed in `MFCopyImage` if it is a performance concern.
Fwiw the test with NV12 only gets tested on w11pro64_amd / w11pro64_nv VMs, as it needs actual GPU to support such input format. I also checked locally with custom MF_MT_DEFAULT_STRIDE values in the media types, but didn't include the tests because this has absolutely no effect on the results (including with RGB32 format somehow).