From 917cffcd5d02f4382b4bc6cca50efeba3192a9f4 Mon Sep 17 00:00:00 2001 From: fritsch Date: Sat, 12 Sep 2015 12:23:51 +0200 Subject: [PATCH 1/2] AdjustRefreshrate: Switch to higher resolution depending on source dims v2: Unify logging v3: incorporate width difference into decision v4: Simplify the code v5: Prefer non double refresh if res matches v6: Compare with desktop resolution as original res v7: Fix usage of RES_DESKTOP --- .../VideoPlayer/VideoRenderers/BaseRenderer.cpp | 45 +++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp index c0b6f44..2ea2c2d 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp @@ -222,11 +222,20 @@ void CBaseRenderer::FindResolutionFromFpsMatch(float fps, float& weight) RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RESOLUTION current, float& weight) { RESOLUTION_INFO curr = g_graphicsContext.GetResInfo(current); + RESOLUTION orig_res = CDisplaySettings::GetInstance().GetCurrentResolution(); + + if (orig_res <= RES_DESKTOP) + orig_res = RES_DESKTOP; + + RESOLUTION_INFO orig = g_graphicsContext.GetResInfo(orig_res); float fRefreshRate = fps; float last_diff = fRefreshRate; + float curr_diff = std::abs(m_sourceWidth - curr.iScreenWidth); + float loop_diff = 0.0f; + // Find closest refresh rate for (size_t i = (int)RES_DESKTOP; i < CDisplaySettings::GetInstance().ResolutionInfoSize(); i++) { @@ -239,7 +248,23 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES || info.iScreen != curr.iScreen || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK) || info.fRefreshRate < (fRefreshRate * multiplier / 1.001) - 0.001) - continue; + { + // evaluate all higher modes and evalute them + // concerning dimension and refreshrate weight + // skip lower resolutions + if ((m_sourceWidth < orig.iScreenWidth) // orig res large enough + || (info.iScreenWidth < orig.iScreenWidth)) // new res is smaller + { + continue; + } + } + + // Allow switching to larger resolution: + // e.g. if m_sourceWidth == 3840 and we have a 3840 mode - use this one + // if it has a matching fps mode, which is evaluated below + + loop_diff = std::abs(m_sourceWidth - info.iScreenWidth); + curr_diff = std::abs(m_sourceWidth - curr.iScreenWidth); // For 3D choose the closest refresh rate if(CONF_FLAGS_STEREO_MODE_MASK(m_iFlags)) @@ -260,6 +285,9 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES int c_weight = MathUtils::round_int(RefreshWeight(curr.fRefreshRate, fRefreshRate * multiplier) * 1000.0); int i_weight = MathUtils::round_int(RefreshWeight(info.fRefreshRate, fRefreshRate * multiplier) * 1000.0); + RESOLUTION current_bak = current; + RESOLUTION_INFO curr_bak = curr; + // Closer the better, prefer higher refresh rate if the same if ((i_weight < c_weight) || (i_weight == c_weight && info.fRefreshRate > curr.fRefreshRate)) @@ -267,6 +295,21 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES current = (RESOLUTION)i; curr = info; } + // use case 1080p50 vs 3840x2160@25 for 3840@25 content + // prefer the higher resolution of 3840 + if (i_weight == c_weight && (loop_diff < curr_diff)) + { + current = (RESOLUTION)i; + curr = info; + } + // same as above but iterating with 3840@25 set and overwritten + // by e.g. 1080@50 - restore backup in that case + // to give priority to the better matching width + if (i_weight == c_weight && (loop_diff > curr_diff)) + { + current = current_bak; + curr = curr_bak; + } } } -- 1.9.1 From 352f591c2de89ef28bb3665950e9c4118539231c Mon Sep 17 00:00:00 2001 From: fritsch Date: Sun, 13 Sep 2015 18:48:01 +0200 Subject: [PATCH 2/2] AdjustRefreshrate: Don't switch from progressive to interlaced (squash me) --- xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp index 2ea2c2d..6479a16 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp @@ -253,7 +253,8 @@ RESOLUTION CBaseRenderer::FindClosestResolution(float fps, float multiplier, RES // concerning dimension and refreshrate weight // skip lower resolutions if ((m_sourceWidth < orig.iScreenWidth) // orig res large enough - || (info.iScreenWidth < orig.iScreenWidth)) // new res is smaller + || (info.iScreenWidth < orig.iScreenWidth) // new res is smaller + || (info.dwFlags & D3DPRESENTFLAG_MODEMASK) != (curr.dwFlags & D3DPRESENTFLAG_MODEMASK)) // don't switch to interlaced modes { continue; } -- 1.9.1