[PATCH 4/5] evr/mixer: Add partial implementation of sample processing.

Nikolay Sivov nsivov at codeweavers.com
Mon Nov 9 06:02:43 CST 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/evr/mixer.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 63 insertions(+), 2 deletions(-)

diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c
index a60da623f64..bbaf68ab870 100644
--- a/dlls/evr/mixer.c
+++ b/dlls/evr/mixer.c
@@ -1163,6 +1163,65 @@ static HRESULT video_mixer_get_d3d_device(struct video_mixer *mixer, IDirect3DDe
     return hr;
 }
 
+static void video_mixer_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_mixer_render(struct video_mixer *mixer, IDirect3DSurface9 *rt)
+{
+    DXVA2_VideoSample samples[1] = { 0 };
+    DXVA2_VideoProcessBltParams params = { 0 };
+    MFVideoNormalizedRect zoom_rect;
+    struct input_stream *stream;
+    IDirect3DSurface9 *surface;
+    D3DSURFACE_DESC desc;
+    HRESULT hr;
+
+    IDirect3DSurface9_GetDesc(rt, &desc);
+
+    if (FAILED(IMFAttributes_GetBlob(mixer->attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&zoom_rect,
+            sizeof(zoom_rect), NULL)))
+    {
+        zoom_rect.left = zoom_rect.top = 0.0f;
+        zoom_rect.right = zoom_rect.bottom = 1.0f;
+    }
+
+    video_mixer_scale_rect(&params.TargetRect, desc.Width, desc.Height, &zoom_rect);
+
+    /* FIXME: for now only handle reference stream. */
+
+    video_mixer_get_input(mixer, 0, &stream);
+
+    if (FAILED(hr = video_mixer_get_sample_surface(stream->sample, &surface)))
+    {
+        WARN("Failed to get source surface, hr %#x.\n", hr);
+        return;
+    }
+
+    IDirect3DSurface9_GetDesc(surface, &desc);
+
+    samples[0].SrcSurface = surface;
+    SetRect(&samples[0].SrcRect, 0, 0, desc.Width, desc.Height);
+    video_mixer_scale_rect(&samples[0].DstRect, desc.Width, desc.Height, &stream->rect);
+
+    if (FAILED(hr = IDirectXVideoProcessor_VideoProcessBlt(mixer->processor, rt, &params, samples, 1, NULL)))
+        WARN("Failed to process samples, hr %#x.\n", hr);
+
+    IDirect3DSurface9_Release(surface);
+}
+
 static HRESULT WINAPI video_mixer_transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
         MFT_OUTPUT_DATA_BUFFER *buffers, DWORD *status)
 {
@@ -1197,13 +1256,15 @@ static HRESULT WINAPI video_mixer_transform_ProcessOutput(IMFTransform *iface, D
                 }
             }
 
-            /* FIXME: for now discard input */
+            if (SUCCEEDED(hr))
+                video_mixer_render(mixer, surface);
 
             if (SUCCEEDED(hr))
             {
                 for (i = 0; i < mixer->input_count; ++i)
                 {
-                    IMFSample_Release(mixer->inputs[i].sample);
+                    if (mixer->inputs[i].sample)
+                        IMFSample_Release(mixer->inputs[i].sample);
                     mixer->inputs[i].sample = NULL;
                     video_mixer_request_sample(mixer, i);
                 }
-- 
2.28.0




More information about the wine-devel mailing list