Nikolay Sivov : evr/presenter: Set frame size and aperture attributes for mixer output type.

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


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

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

evr/presenter: Set frame size and aperture attributes for mixer output type.

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

---

 dlls/evr/presenter.c |  36 ++++++++++++--
 dlls/evr/tests/evr.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 163 insertions(+), 5 deletions(-)

diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c
index f0733f6f060..5701eb17bd3 100644
--- a/dlls/evr/presenter.c
+++ b/dlls/evr/presenter.c
@@ -306,17 +306,43 @@ static HRESULT video_presenter_set_media_type(struct video_presenter *presenter,
 
 static HRESULT video_presenter_invalidate_media_type(struct video_presenter *presenter)
 {
-    IMFMediaType *media_type;
+    IMFMediaType *media_type, *candidate_type;
     unsigned int idx = 0;
+    UINT64 frame_size;
+    MFVideoArea aperture;
+    RECT rect;
     HRESULT hr;
 
+    if (FAILED(hr = MFCreateMediaType(&media_type)))
+        return hr;
+
     video_presenter_get_native_video_size(presenter);
 
-    while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(presenter->mixer, 0, idx++, &media_type)))
+    rect = presenter->dst_rect;
+    if (rect.left == 0 && rect.right == 0 && rect.bottom == 0 && rect.top == 0)
+    {
+        rect.right = presenter->native_size.cx;
+        rect.bottom = presenter->native_size.cy;
+    }
+
+    aperture.Area.cx = rect.right - rect.left;
+    aperture.Area.cy = rect.bottom - rect.top;
+    aperture.OffsetX.value = 0;
+    aperture.OffsetX.fract = 0;
+    aperture.OffsetY.value = 0;
+    aperture.OffsetY.fract = 0;
+    frame_size = (UINT64)aperture.Area.cx << 32 | aperture.Area.cy;
+
+    while (SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(presenter->mixer, 0, idx++, &candidate_type)))
     {
         /* FIXME: check that d3d device supports this format */
 
-        /* FIXME: potentially adjust frame size */
+        if (FAILED(hr = IMFMediaType_CopyAllItems(candidate_type, (IMFAttributes *)media_type)))
+            WARN("Failed to clone a media type, hr %#x.\n", hr);
+        IMFMediaType_Release(candidate_type);
+
+        IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, frame_size);
+        IMFMediaType_SetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)&aperture, sizeof(aperture));
 
         hr = IMFTransform_SetOutputType(presenter->mixer, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
 
@@ -326,12 +352,12 @@ static HRESULT video_presenter_invalidate_media_type(struct video_presenter *pre
         if (SUCCEEDED(hr))
             hr = IMFTransform_SetOutputType(presenter->mixer, 0, media_type, 0);
 
-        IMFMediaType_Release(media_type);
-
         if (SUCCEEDED(hr))
             break;
     }
 
+    IMFMediaType_Release(media_type);
+
     return hr;
 }
 
diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c
index 2740f2263f0..31434bde43a 100644
--- a/dlls/evr/tests/evr.c
+++ b/dlls/evr/tests/evr.c
@@ -2072,6 +2072,137 @@ todo_wine {
     IMFVideoPresenter_Release(presenter);
 }
 
+static void get_output_aperture(IMFTransform *mixer, SIZE *frame_size, MFVideoArea *aperture)
+{
+    IMFMediaType *media_type;
+    UINT64 size;
+    HRESULT hr;
+
+    memset(frame_size, 0xcc, sizeof(*frame_size));
+    memset(aperture, 0xcc, sizeof(*aperture));
+
+    hr = IMFTransform_GetOutputCurrentType(mixer, 0, &media_type);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &size);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    frame_size->cx = size >> 32;
+    frame_size->cy = size;
+
+    hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)aperture, sizeof(*aperture), NULL);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    IMFMediaType_Release(media_type);
+}
+
+static void test_presenter_media_type(void)
+{
+    IMFTopologyServiceLookupClient *lookup_client;
+    IMFVideoPresenter *presenter;
+    struct test_host host;
+    IMFMediaType *input_type;
+    IDirect3DDeviceManager9 *manager;
+    HRESULT hr;
+    IMFTransform *mixer;
+    IDirect3D9 *d3d;
+    IDirect3DDevice9 *device;
+    unsigned int token;
+    SIZE frame_size;
+    HWND window;
+    MFVideoArea aperture;
+    IMFVideoDisplayControl *display_control;
+    RECT dst;
+
+    window = create_window();
+    d3d = Direct3DCreate9(D3D_SDK_VERSION);
+    ok(!!d3d, "Failed to create a D3D object.\n");
+    if (!(device = create_device(d3d, window)))
+    {
+        skip("Failed to create a D3D device, skipping tests.\n");
+        goto done;
+    }
+
+    hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
+    ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
+
+    hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
+    ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
+
+    input_type = create_video_type(&MFVideoFormat_RGB32);
+
+    hr = IMFMediaType_SetUINT64(input_type, &MF_MT_FRAME_SIZE, (UINT64)100 << 32 | 50);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = IMFMediaType_SetUINT32(input_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFTransform_SetInputType(mixer, 0, input_type, 0);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    init_test_host(&host, mixer, presenter);
+
+    hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    get_output_aperture(mixer, &frame_size, &aperture);
+    ok(frame_size.cx == 100 && frame_size.cy == 50, "Unexpected frame size %u x %u.\n", frame_size.cx, frame_size.cy);
+    ok(aperture.Area.cx == 100 && aperture.Area.cy == 50, "Unexpected size %u x %u.\n", aperture.Area.cx, aperture.Area.cy);
+    ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
+            "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
+
+    SetRect(&dst, 1, 2, 200, 300);
+    hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    get_output_aperture(mixer, &frame_size, &aperture);
+todo_wine {
+    ok(frame_size.cx == 199 && frame_size.cy == 298, "Unexpected frame size %u x %u.\n", frame_size.cx, frame_size.cy);
+    ok(aperture.Area.cx == 199 && aperture.Area.cy == 298, "Unexpected size %u x %u.\n", aperture.Area.cx, aperture.Area.cy);
+}
+    ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
+            "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
+
+    hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, MFVideoARMode_None);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    get_output_aperture(mixer, &frame_size, &aperture);
+todo_wine {
+    ok(frame_size.cx == 199 && frame_size.cy == 298, "Unexpected frame size %u x %u.\n", frame_size.cx, frame_size.cy);
+    ok(aperture.Area.cx == 199 && aperture.Area.cy == 298, "Unexpected size %u x %u.\n", aperture.Area.cx, aperture.Area.cy);
+}
+    ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
+            "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
+
+    IMFVideoDisplayControl_Release(display_control);
+    IMFVideoPresenter_Release(presenter);
+    IMFTransform_Release(mixer);
+
+done:
+    IDirect3D9_Release(d3d);
+    DestroyWindow(window);
+}
+
 static void test_mixer_output_rectangle(void)
 {
     IMFVideoMixerControl *mixer_control;
@@ -2574,6 +2705,7 @@ START_TEST(evr)
     test_presenter_ar_mode();
     test_presenter_video_window();
     test_presenter_quality_control();
+    test_presenter_media_type();
     test_mixer_output_rectangle();
     test_mixer_zorder();
     test_mixer_samples();




More information about the wine-cvs mailing list