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