From dc85ddb3f9f27be54856b9895b0060c33b7cb9f5 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 8 May 2022 15:20:08 -0500 Subject: [PATCH] Reintroduce option of using old frame pacing algorithm using capped FPS --- app/src/main/java/com/limelight/Game.java | 24 ++++++++++++++++++- .../video/MediaCodecDecoderRenderer.java | 5 ++-- .../preferences/PreferenceConfiguration.java | 6 ++++- app/src/main/res/values/arrays.xml | 2 ++ app/src/main/res/values/strings.xml | 1 + 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/limelight/Game.java b/app/src/main/java/com/limelight/Game.java index efeae15a..1498efaa 100644 --- a/app/src/main/java/com/limelight/Game.java +++ b/app/src/main/java/com/limelight/Game.java @@ -389,6 +389,28 @@ public class Game extends Activity implements SurfaceHolder.Callback, float displayRefreshRate = prepareDisplayForRendering(); LimeLog.info("Display refresh rate: "+displayRefreshRate); + // If the user requested frame pacing using a capped FPS, we will need to change our + // desired FPS setting here in accordance with the active display refresh rate. + int roundedRefreshRate = Math.round(displayRefreshRate); + int chosenFrameRate = prefConfig.fps; + if (prefConfig.framePacing == PreferenceConfiguration.FRAME_PACING_CAP_FPS) { + if (prefConfig.fps >= roundedRefreshRate) { + if (prefConfig.unlockFps) { + // Use frame drops when rendering above the screen frame rate + prefConfig.framePacing = PreferenceConfiguration.FRAME_PACING_BALANCED; + LimeLog.info("Using drop mode for FPS > Hz"); + } else if (roundedRefreshRate <= 49) { + // Let's avoid clearly bogus refresh rates and fall back to legacy rendering + prefConfig.framePacing = PreferenceConfiguration.FRAME_PACING_BALANCED; + LimeLog.info("Bogus refresh rate: " + roundedRefreshRate); + } + else { + chosenFrameRate = roundedRefreshRate - 1; + LimeLog.info("Adjusting FPS target for screen to " + chosenFrameRate); + } + } + } + boolean vpnActive = NetHelper.isActiveNetworkVpn(this); if (vpnActive) { LimeLog.info("Detected active network is a VPN"); @@ -397,7 +419,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, StreamConfiguration config = new StreamConfiguration.Builder() .setResolution(prefConfig.width, prefConfig.height) .setLaunchRefreshRate(prefConfig.fps) - .setRefreshRate(prefConfig.fps) + .setRefreshRate(chosenFrameRate) .setApp(new NvApp(appName != null ? appName : "app", appId, appSupportsHdr)) .setBitrate(prefConfig.bitrate) .setEnableSops(prefConfig.enableSops) diff --git a/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java b/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java index 108b8ce9..6fe54098 100644 --- a/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java +++ b/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java @@ -468,8 +468,9 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C presentationTimeUs = info.presentationTimeUs; } - if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_MAX_SMOOTHNESS) { - // In max smoothness mode, we want to never drop frames + if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_MAX_SMOOTHNESS || + prefs.framePacing == PreferenceConfiguration.FRAME_PACING_CAP_FPS) { + // In max smoothness or cap FPS mode, we want to never drop frames if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // Use a PTS that will cause this frame to never be dropped videoDecoder.releaseOutputBuffer(lastIndex, 0); diff --git a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java index 34fa435d..b928f29b 100644 --- a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java +++ b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java @@ -80,7 +80,8 @@ public class PreferenceConfiguration { public static final int FRAME_PACING_MIN_LATENCY = 0; public static final int FRAME_PACING_BALANCED = 1; - public static final int FRAME_PACING_MAX_SMOOTHNESS = 2; + public static final int FRAME_PACING_CAP_FPS = 2; + public static final int FRAME_PACING_MAX_SMOOTHNESS = 3; public static final String RES_360P = "640x360"; public static final String RES_480P = "854x480"; @@ -288,6 +289,9 @@ public class PreferenceConfiguration { else if (str.equals("balanced")) { return FRAME_PACING_BALANCED; } + else if (str.equals("cap-fps")) { + return FRAME_PACING_CAP_FPS; + } else if (str.equals("smoothness")) { return FRAME_PACING_MAX_SMOOTHNESS; } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 2ddf3a10..cd334e44 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -98,11 +98,13 @@ @string/pacing_latency @string/pacing_balanced + @string/pacing_balanced_alt @string/pacing_smoothness latency balanced + cap-fps smoothness diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f4f6f8b1..cc49d25f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -252,5 +252,6 @@ Specify how to balance video latency and smoothness Prefer lowest latency Balanced + Balanced with FPS cap (may perform better on certain devices) Prefer smoothest video (may significantly increase latency)