From c916d30cd526ae8632a05c50db4b6809eb6492fb Mon Sep 17 00:00:00 2001 From: fritsch Date: Sat, 12 Sep 2015 12:23:51 +0200 Subject: [PATCH] AdjustRefreshrate: Switch to higher resolution depending on source dims v2: Unify logging v3: incorporate width difference into decision --- .../VideoPlayer/VideoRenderers/BaseRenderer.cpp | 36 ++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp index c0b6f44..92322ab 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/BaseRenderer.cpp @@ -222,11 +222,14 @@ 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_INFO orig = curr; 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 +242,28 @@ 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; + { + // 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 + // We only switch up if source is > current resolution + + loop_diff = std::abs(m_sourceWidth - info.iScreenWidth); + curr_diff = std::abs(m_sourceWidth - curr.iScreenWidth); + + if ((m_sourceWidth > curr.iScreenWidth) // curr resolution might still be too low + && (info.iScreenWidth > curr.iScreenWidth)) + { + CLog::Log(LOGDEBUG, "Found a better matching resolution class: (%d,%d) diff: %lf", info.iScreenWidth, info.iScreenHeight, loop_diff); + } + else if ((m_sourceWidth > orig.iScreenWidth) // might be a better candidate to not have to scale, e.g. 3840 source and 3840 mode + && (loop_diff < curr_diff)) + { + CLog::Log(LOGDEBUG, "Found a better matching resolution class (2): (%d,%d) diff: %lf, Current: %s", info.iScreenWidth, info.iScreenHeight, loop_diff, curr.strMode.c_str()); + } + else + continue; + } // For 3D choose the closest refresh rate if(CONF_FLAGS_STEREO_MODE_MASK(m_iFlags)) @@ -267,6 +291,14 @@ 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 + else if (i_weight == c_weight && (loop_diff < curr_diff)) + { + CLog::Log(LOGDEBUG, "Changed to resolution: %s cause of lower diff: %lf", info.strMode.c_str(), loop_diff); + current = (RESOLUTION)i; + curr = info; + } } } -- 1.9.1