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 7db02978..24fb457a 100644
--- a/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java
+++ b/app/src/main/java/com/limelight/binding/video/MediaCodecDecoderRenderer.java
@@ -456,8 +456,8 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
numFramesOut++;
- // Render the latest frame now if frame pacing is off
- if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_OFF) {
+ // Render the latest frame now if frame pacing isn't in balanced mode
+ if (prefs.framePacing != PreferenceConfiguration.FRAME_PACING_BALANCED) {
// Get the last output buffer in the queue
while ((outIndex = videoDecoder.dequeueOutputBuffer(info, 0)) >= 0) {
videoDecoder.releaseOutputBuffer(lastIndex, false);
@@ -468,19 +468,31 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
presentationTimeUs = info.presentationTimeUs;
}
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- // Use a PTS that will cause this frame to be dropped if another comes in within
- // the same V-sync period
- videoDecoder.releaseOutputBuffer(lastIndex, System.nanoTime());
+ if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_MAX_SMOOTHNESS) {
+ // In max smoothness 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);
+ }
+ else {
+ videoDecoder.releaseOutputBuffer(lastIndex, true);
+ }
}
else {
- videoDecoder.releaseOutputBuffer(lastIndex, true);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ // Use a PTS that will cause this frame to be dropped if another comes in within
+ // the same V-sync period
+ videoDecoder.releaseOutputBuffer(lastIndex, System.nanoTime());
+ }
+ else {
+ videoDecoder.releaseOutputBuffer(lastIndex, true);
+ }
}
activeWindowVideoStats.totalFramesRendered++;
}
else {
- // For the frame pacing case, the Choreographer callback will handle rendering.
+ // For balanced frame pacing case, the Choreographer callback will handle rendering.
// We just put all frames into the output buffer queue and let it handle things.
// Discard the oldest buffer if we've exceeded our limit.
@@ -570,9 +582,9 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
public void start() {
startRendererThread();
- // Start Choreographer callbacks for rendering with frame pacing enabled
+ // Start Choreographer callbacks for rendering with frame pacing in balanced mode
// NB: This must be done on a thread with a looper!
- if (prefs.framePacing != PreferenceConfiguration.FRAME_PACING_OFF) {
+ if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_BALANCED) {
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
@Override
@@ -594,7 +606,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
}
// Halt further Choreographer callbacks
- if (prefs.framePacing != PreferenceConfiguration.FRAME_PACING_OFF) {
+ if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_BALANCED) {
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
@Override
diff --git a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java
index 93111e91..34fa435d 100644
--- a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java
+++ b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java
@@ -78,8 +78,9 @@ public class PreferenceConfiguration {
public static final int AUTOSELECT_H265 = 0;
public static final int FORCE_H265_OFF = 1;
- public static final int FRAME_PACING_OFF = 0;
- public static final int FRAME_PACING_ON = 1;
+ 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 String RES_360P = "640x360";
public static final String RES_480P = "854x480";
@@ -276,16 +277,23 @@ public class PreferenceConfiguration {
boolean legacyNeverDropFrames = prefs.getBoolean(LEGACY_DISABLE_FRAME_DROP_PREF_STRING, false);
prefs.edit()
.remove(LEGACY_DISABLE_FRAME_DROP_PREF_STRING)
- .putString(FRAME_PACING_PREF_STRING, legacyNeverDropFrames ? "smoothness" : "latency")
+ .putString(FRAME_PACING_PREF_STRING, legacyNeverDropFrames ? "balanced" : "latency")
.apply();
}
String str = prefs.getString(FRAME_PACING_PREF_STRING, DEFAULT_FRAME_PACING);
if (str.equals("latency")) {
- return FRAME_PACING_OFF;
+ return FRAME_PACING_MIN_LATENCY;
+ }
+ else if (str.equals("balanced")) {
+ return FRAME_PACING_BALANCED;
+ }
+ else if (str.equals("smoothness")) {
+ return FRAME_PACING_MAX_SMOOTHNESS;
}
else {
- return FRAME_PACING_ON;
+ // Should never get here
+ return FRAME_PACING_MIN_LATENCY;
}
}
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index fe245807..2ddf3a10 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -97,10 +97,12 @@
- @string/pacing_latency
+ - @string/pacing_balanced
- @string/pacing_smoothness
- latency
+ - balanced
- smoothness
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 99c67d9f..f4f6f8b1 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -250,6 +250,7 @@
Video frame pacing
Specify how to balance video latency and smoothness
- Prefer Lowest Latency
- Prefer Smoothest Video
+ Prefer lowest latency
+ Balanced
+ Prefer smoothest video (may significantly increase latency)