Nikolay Sivov : evr/presenter: Add aspect ratio preserving scaling.

Alexandre Julliard julliard at winehq.org
Tue Nov 24 17:01:44 CST 2020


Module: wine
Branch: master
Commit: c06e7ba7299827d1a876a58676b51597a2560a41
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c06e7ba7299827d1a876a58676b51597a2560a41

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue Nov 24 18:12:46 2020 +0300

evr/presenter: Add aspect ratio preserving scaling.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/evr/presenter.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c
index 5701eb17bd3..9b7fb5f6f67 100644
--- a/dlls/evr/presenter.c
+++ b/dlls/evr/presenter.c
@@ -426,10 +426,27 @@ static HRESULT video_presenter_get_sample_surface(IMFSample *sample, IDirect3DSu
     return hr;
 }
 
+static void scale_rect(RECT *rect, unsigned int width, unsigned int height, const MFVideoNormalizedRect *scale)
+{
+    if (rect->left == 0.0f && rect->top == 0.0f && rect->right == 1.0f && rect->bottom == 1.0f)
+    {
+        SetRect(rect, 0, 0, width, height);
+    }
+    else
+    {
+        rect->left = width * scale->left;
+        rect->right = width * scale->right;
+        rect->top = height * scale->top;
+        rect->bottom = height * scale->bottom;
+    }
+}
+
 static void video_presenter_sample_present(struct video_presenter *presenter, IMFSample *sample)
 {
     IDirect3DSurface9 *surface, *backbuffer;
     IDirect3DDevice9 *device;
+    D3DSURFACE_DESC desc;
+    RECT dst, src;
     HRESULT hr;
 
     if (!presenter->swapchain)
@@ -450,7 +467,39 @@ static void video_presenter_sample_present(struct video_presenter *presenter, IM
 
     IDirect3DSwapChain9_GetDevice(presenter->swapchain, &device);
     IDirect3DDevice9_StretchRect(device, surface, NULL, backbuffer, NULL, D3DTEXF_POINT);
-    IDirect3DSwapChain9_Present(presenter->swapchain, NULL, NULL, NULL, NULL, 0);
+
+    IDirect3DSurface9_GetDesc(surface, &desc);
+    scale_rect(&src, desc.Width, desc.Height, &presenter->src_rect);
+
+    IDirect3DSurface9_GetDesc(backbuffer, &desc);
+    SetRect(&dst, 0, 0, desc.Width, desc.Height);
+
+    if (presenter->ar_mode & MFVideoARMode_PreservePicture)
+    {
+        unsigned int src_width = src.right - src.left, src_height = src.bottom - src.top;
+        unsigned int dst_width = dst.right - dst.left, dst_height = dst.bottom - dst.top;
+
+        if (src_width * dst_height > dst_width * src_height)
+        {
+            /* src is "wider" than dst. */
+            unsigned int dst_center = (dst.top + dst.bottom) / 2;
+            unsigned int scaled_height = src_height * dst_width / src_width;
+
+            dst.top = dst_center - scaled_height / 2;
+            dst.bottom = dst.top + scaled_height;
+        }
+        else if (src_width * dst_height < dst_width * src_height)
+        {
+            /* src is "taller" than dst. */
+            unsigned int dst_center = (dst.left + dst.right) / 2;
+            unsigned int scaled_width = src_width * dst_height / src_height;
+
+            dst.left = dst_center - scaled_width / 2;
+            dst.right = dst.left + scaled_width;
+        }
+    }
+
+    IDirect3DSwapChain9_Present(presenter->swapchain, &src, &dst, NULL, NULL, 0);
 
     IDirect3DDevice9_Release(device);
     IDirect3DSurface9_Release(backbuffer);




More information about the wine-cvs mailing list