From 59f3337a394271cf729977a77fefb9950cf460d7 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 7 Oct 2020 11:40:21 +0300 Subject: [PATCH] evr/presenter: Update cached native size on format negotiation. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/evr/presenter.c | 118 +++++++++++++++++++++++++++++++-------------------- dlls/evr/tests/evr.c | 2 - 2 files changed, 71 insertions(+), 49 deletions(-) diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index ba9e09c4e3e..ecfa9234426 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -103,6 +103,58 @@ static struct video_presenter *impl_from_IMFGetService(IMFGetService *iface) return CONTAINING_RECORD(iface, struct video_presenter, IMFGetService_iface); } +static unsigned int get_gcd(unsigned int a, unsigned int b) +{ + unsigned int m; + + while (b) + { + m = a % b; + a = b; + b = m; + } + + return a; +} + +static void video_presenter_get_native_video_size(struct video_presenter *presenter) +{ + IMFMediaType *media_type; + UINT64 frame_size = 0; + + memset(&presenter->native_size, 0, sizeof(presenter->native_size)); + memset(&presenter->native_ratio, 0, sizeof(presenter->native_ratio)); + + if (!presenter->mixer) + return; + + if (FAILED(IMFTransform_GetInputCurrentType(presenter->mixer, 0, &media_type))) + return; + + if (SUCCEEDED(IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size))) + { + unsigned int gcd; + + presenter->native_size.cx = frame_size >> 32; + presenter->native_size.cy = frame_size; + + if ((gcd = get_gcd(presenter->native_size.cx, presenter->native_size.cy))) + { + presenter->native_ratio.cx = presenter->native_size.cx / gcd; + presenter->native_ratio.cy = presenter->native_size.cy / gcd; + } + } + + IMFMediaType_Release(media_type); +} + +static HRESULT video_presenter_invalidate_media_type(struct video_presenter *presenter) +{ + video_presenter_get_native_video_size(presenter); + + return S_OK; +} + static HRESULT WINAPI video_presenter_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj) { struct video_presenter *presenter = impl_from_IUnknown(iface); @@ -277,9 +329,26 @@ static HRESULT WINAPI video_presenter_OnClockSetRate(IMFVideoPresenter *iface, M static HRESULT WINAPI video_presenter_ProcessMessage(IMFVideoPresenter *iface, MFVP_MESSAGE_TYPE message, ULONG_PTR param) { - FIXME("%p, %d, %lu.\n", iface, message, param); + struct video_presenter *presenter = impl_from_IMFVideoPresenter(iface); + HRESULT hr; - return E_NOTIMPL; + TRACE("%p, %d, %lu.\n", iface, message, param); + + EnterCriticalSection(&presenter->cs); + + switch (message) + { + case MFVP_MESSAGE_INVALIDATEMEDIATYPE: + hr = video_presenter_invalidate_media_type(presenter); + break; + default: + FIXME("Unsupported message %u.\n", message); + hr = E_NOTIMPL; + } + + LeaveCriticalSection(&presenter->cs); + + return hr; } static HRESULT WINAPI video_presenter_GetCurrentMediaType(IMFVideoPresenter *iface, IMFVideoMediaType **media_type) @@ -379,51 +448,6 @@ static void video_presenter_set_mixer_rect(struct video_presenter *presenter) } } -static unsigned int get_gcd(unsigned int a, unsigned int b) -{ - unsigned int m; - - while (b) - { - m = a % b; - a = b; - b = m; - } - - return a; -} - -static void video_presenter_get_native_video_size(struct video_presenter *presenter) -{ - IMFMediaType *media_type; - UINT64 frame_size = 0; - - memset(&presenter->native_size, 0, sizeof(presenter->native_size)); - memset(&presenter->native_ratio, 0, sizeof(presenter->native_ratio)); - - if (!presenter->mixer) - return; - - if (FAILED(IMFTransform_GetInputCurrentType(presenter->mixer, 0, &media_type))) - return; - - if (SUCCEEDED(IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size))) - { - unsigned int gcd; - - presenter->native_size.cx = frame_size >> 32; - presenter->native_size.cy = frame_size; - - if ((gcd = get_gcd(presenter->native_size.cx, presenter->native_size.cy))) - { - presenter->native_ratio.cx = presenter->native_size.cx / gcd; - presenter->native_ratio.cy = presenter->native_size.cy / gcd; - } - } - - IMFMediaType_Release(media_type); -} - static HRESULT video_presenter_attach_mixer(struct video_presenter *presenter, IMFTopologyServiceLookup *service_lookup) { IMFVideoDeviceID *device_id; diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 39d2ed72a06..e7eabc5971a 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -1640,12 +1640,10 @@ static void test_presenter_native_video_size(void) /* Negotiating types updates native video size. */ hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0); -todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); -todo_wine ok(size.cx == 320 && size.cy == 240, "Unexpected size %u x %u.\n", size.cx, size.cy); ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */, "Unexpected ratio %u x %u.\n", ratio.cx, ratio.cy); -- 2.11.4.GIT