mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-22 12:33:02 +00:00
Add option to unlock FPS
This commit is contained in:
parent
9ed49730d4
commit
9cd2ce1309
@ -344,8 +344,13 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
// Hopefully, we can get rid of this once someone comes up with a better way
|
// Hopefully, we can get rid of this once someone comes up with a better way
|
||||||
// to track the state of the pipeline and time frames.
|
// to track the state of the pipeline and time frames.
|
||||||
int roundedRefreshRate = Math.round(displayRefreshRate);
|
int roundedRefreshRate = Math.round(displayRefreshRate);
|
||||||
if (!prefConfig.disableFrameDrop && prefConfig.fps >= roundedRefreshRate) {
|
if ((!prefConfig.disableFrameDrop || prefConfig.unlockFps) && prefConfig.fps >= roundedRefreshRate) {
|
||||||
if (roundedRefreshRate <= 49) {
|
if (prefConfig.unlockFps) {
|
||||||
|
// Use frame drops when rendering above the screen frame rate
|
||||||
|
decoderRenderer.enableLegacyFrameDropRendering();
|
||||||
|
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
|
// Let's avoid clearly bogus refresh rates and fall back to legacy rendering
|
||||||
decoderRenderer.enableLegacyFrameDropRendering();
|
decoderRenderer.enableLegacyFrameDropRendering();
|
||||||
LimeLog.info("Bogus refresh rate: "+roundedRefreshRate);
|
LimeLog.info("Bogus refresh rate: "+roundedRefreshRate);
|
||||||
|
@ -34,6 +34,7 @@ public class PreferenceConfiguration {
|
|||||||
private static final String BIND_ALL_USB_STRING = "checkbox_usb_bind_all";
|
private static final String BIND_ALL_USB_STRING = "checkbox_usb_bind_all";
|
||||||
private static final String MOUSE_EMULATION_STRING = "checkbox_mouse_emulation";
|
private static final String MOUSE_EMULATION_STRING = "checkbox_mouse_emulation";
|
||||||
private static final String MOUSE_NAV_BUTTONS_STRING = "checkbox_mouse_nav_buttons";
|
private static final String MOUSE_NAV_BUTTONS_STRING = "checkbox_mouse_nav_buttons";
|
||||||
|
static final String UNLOCK_FPS_STRING = "checkbox_unlock_fps";
|
||||||
|
|
||||||
static final String DEFAULT_RESOLUTION = "720p";
|
static final String DEFAULT_RESOLUTION = "720p";
|
||||||
static final String DEFAULT_FPS = "60";
|
static final String DEFAULT_FPS = "60";
|
||||||
@ -56,6 +57,7 @@ public class PreferenceConfiguration {
|
|||||||
private static final boolean DEFAULT_BIND_ALL_USB = false;
|
private static final boolean DEFAULT_BIND_ALL_USB = false;
|
||||||
private static final boolean DEFAULT_MOUSE_EMULATION = true;
|
private static final boolean DEFAULT_MOUSE_EMULATION = true;
|
||||||
private static final boolean DEFAULT_MOUSE_NAV_BUTTONS = false;
|
private static final boolean DEFAULT_MOUSE_NAV_BUTTONS = false;
|
||||||
|
private static final boolean DEFAULT_UNLOCK_FPS = false;
|
||||||
|
|
||||||
public static final int FORCE_H265_ON = -1;
|
public static final int FORCE_H265_ON = -1;
|
||||||
public static final int AUTOSELECT_H265 = 0;
|
public static final int AUTOSELECT_H265 = 0;
|
||||||
@ -76,6 +78,7 @@ public class PreferenceConfiguration {
|
|||||||
public boolean bindAllUsb;
|
public boolean bindAllUsb;
|
||||||
public boolean mouseEmulation;
|
public boolean mouseEmulation;
|
||||||
public boolean mouseNavButtons;
|
public boolean mouseNavButtons;
|
||||||
|
public boolean unlockFps;
|
||||||
|
|
||||||
private static int getHeightFromResolutionString(String resString) {
|
private static int getHeightFromResolutionString(String resString) {
|
||||||
if (resString.equalsIgnoreCase("360p")) {
|
if (resString.equalsIgnoreCase("360p")) {
|
||||||
@ -208,6 +211,7 @@ public class PreferenceConfiguration {
|
|||||||
.remove(FPS_PREF_STRING)
|
.remove(FPS_PREF_STRING)
|
||||||
.remove(VIDEO_FORMAT_PREF_STRING)
|
.remove(VIDEO_FORMAT_PREF_STRING)
|
||||||
.remove(ENABLE_HDR_PREF_STRING)
|
.remove(ENABLE_HDR_PREF_STRING)
|
||||||
|
.remove(UNLOCK_FPS_STRING)
|
||||||
.apply();
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,6 +313,7 @@ public class PreferenceConfiguration {
|
|||||||
config.bindAllUsb = prefs.getBoolean(BIND_ALL_USB_STRING, DEFAULT_BIND_ALL_USB);
|
config.bindAllUsb = prefs.getBoolean(BIND_ALL_USB_STRING, DEFAULT_BIND_ALL_USB);
|
||||||
config.mouseEmulation = prefs.getBoolean(MOUSE_EMULATION_STRING, DEFAULT_MOUSE_EMULATION);
|
config.mouseEmulation = prefs.getBoolean(MOUSE_EMULATION_STRING, DEFAULT_MOUSE_EMULATION);
|
||||||
config.mouseNavButtons = prefs.getBoolean(MOUSE_NAV_BUTTONS_STRING, DEFAULT_MOUSE_NAV_BUTTONS);
|
config.mouseNavButtons = prefs.getBoolean(MOUSE_NAV_BUTTONS_STRING, DEFAULT_MOUSE_NAV_BUTTONS);
|
||||||
|
config.unlockFps = prefs.getBoolean(UNLOCK_FPS_STRING, DEFAULT_UNLOCK_FPS);
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.media.MediaCodecInfo;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.os.Handler;
|
||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceCategory;
|
import android.preference.PreferenceCategory;
|
||||||
@ -24,6 +25,12 @@ import com.limelight.utils.UiHelper;
|
|||||||
public class StreamSettings extends Activity {
|
public class StreamSettings extends Activity {
|
||||||
private PreferenceConfiguration previousPrefs;
|
private PreferenceConfiguration previousPrefs;
|
||||||
|
|
||||||
|
void reloadSettings() {
|
||||||
|
getFragmentManager().beginTransaction().replace(
|
||||||
|
R.id.stream_settings, new SettingsFragment()
|
||||||
|
).commit();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@ -33,9 +40,7 @@ public class StreamSettings extends Activity {
|
|||||||
UiHelper.setLocale(this);
|
UiHelper.setLocale(this);
|
||||||
|
|
||||||
setContentView(R.layout.activity_stream_settings);
|
setContentView(R.layout.activity_stream_settings);
|
||||||
getFragmentManager().beginTransaction().replace(
|
reloadSettings();
|
||||||
R.id.stream_settings, new SettingsFragment()
|
|
||||||
).commit();
|
|
||||||
|
|
||||||
UiHelper.notifyNewRootView(this);
|
UiHelper.notifyNewRootView(this);
|
||||||
}
|
}
|
||||||
@ -58,9 +63,17 @@ public class StreamSettings extends Activity {
|
|||||||
|
|
||||||
public static class SettingsFragment extends PreferenceFragment {
|
public static class SettingsFragment extends PreferenceFragment {
|
||||||
|
|
||||||
private static void removeValue(ListPreference pref, String value) {
|
private void setValue(String preferenceKey, String value) {
|
||||||
|
ListPreference pref = (ListPreference) findPreference(preferenceKey);
|
||||||
|
|
||||||
|
pref.setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeValue(String preferenceKey, String value, Runnable onMatched) {
|
||||||
int matchingCount = 0;
|
int matchingCount = 0;
|
||||||
|
|
||||||
|
ListPreference pref = (ListPreference) findPreference(preferenceKey);
|
||||||
|
|
||||||
// Count the number of matching entries we'll be removing
|
// Count the number of matching entries we'll be removing
|
||||||
for (CharSequence seq : pref.getEntryValues()) {
|
for (CharSequence seq : pref.getEntryValues()) {
|
||||||
if (seq.toString().equalsIgnoreCase(value)) {
|
if (seq.toString().equalsIgnoreCase(value)) {
|
||||||
@ -83,15 +96,34 @@ public class StreamSettings extends Activity {
|
|||||||
outIndex++;
|
outIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pref.getValue().equalsIgnoreCase(value)) {
|
||||||
|
onMatched.run();
|
||||||
|
}
|
||||||
|
|
||||||
// Update the preference with the new list
|
// Update the preference with the new list
|
||||||
pref.setEntries(entries);
|
pref.setEntries(entries);
|
||||||
pref.setEntryValues(entryValues);
|
pref.setEntryValues(entryValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void resetBitrateToDefault(SharedPreferences prefs, String res, String fps) {
|
||||||
|
if (res == null) {
|
||||||
|
res = prefs.getString(PreferenceConfiguration.RESOLUTION_PREF_STRING, PreferenceConfiguration.DEFAULT_RESOLUTION);
|
||||||
|
}
|
||||||
|
if (fps == null) {
|
||||||
|
fps = prefs.getString(PreferenceConfiguration.FPS_PREF_STRING, PreferenceConfiguration.DEFAULT_FPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs.edit()
|
||||||
|
.putInt(PreferenceConfiguration.BITRATE_PREF_STRING,
|
||||||
|
PreferenceConfiguration.getDefaultBitrate(res, fps))
|
||||||
|
.apply();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.preferences);
|
addPreferencesFromResource(R.xml.preferences);
|
||||||
PreferenceScreen screen = getPreferenceScreen();
|
PreferenceScreen screen = getPreferenceScreen();
|
||||||
|
|
||||||
@ -195,34 +227,69 @@ public class StreamSettings extends Activity {
|
|||||||
|
|
||||||
LimeLog.info("Maximum resolution slot: "+maxSupportedResW);
|
LimeLog.info("Maximum resolution slot: "+maxSupportedResW);
|
||||||
|
|
||||||
ListPreference resPref = (ListPreference) findPreference(PreferenceConfiguration.RESOLUTION_PREF_STRING);
|
|
||||||
if (maxSupportedResW != 0) {
|
if (maxSupportedResW != 0) {
|
||||||
if (maxSupportedResW < 3840) {
|
if (maxSupportedResW < 3840) {
|
||||||
// 4K is unsupported
|
// 4K is unsupported
|
||||||
removeValue(resPref, "4K");
|
removeValue(PreferenceConfiguration.RESOLUTION_PREF_STRING, "4K", new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SettingsFragment.this.getActivity());
|
||||||
|
setValue(PreferenceConfiguration.RESOLUTION_PREF_STRING, "1440p");
|
||||||
|
resetBitrateToDefault(prefs, null, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (maxSupportedResW < 2560) {
|
if (maxSupportedResW < 2560) {
|
||||||
// 1440p is unsupported
|
// 1440p is unsupported
|
||||||
removeValue(resPref, "1440p");
|
removeValue(PreferenceConfiguration.RESOLUTION_PREF_STRING, "1440p", new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SettingsFragment.this.getActivity());
|
||||||
|
setValue(PreferenceConfiguration.RESOLUTION_PREF_STRING, "1080p");
|
||||||
|
resetBitrateToDefault(prefs, null, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (maxSupportedResW < 1920) {
|
if (maxSupportedResW < 1920) {
|
||||||
// 1080p is unsupported
|
// 1080p is unsupported
|
||||||
removeValue(resPref, "1080p");
|
removeValue(PreferenceConfiguration.RESOLUTION_PREF_STRING, "1080p", new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SettingsFragment.this.getActivity());
|
||||||
|
setValue(PreferenceConfiguration.RESOLUTION_PREF_STRING, "720p");
|
||||||
|
resetBitrateToDefault(prefs, null, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// Never remove 720p
|
// Never remove 720p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListPreference fpsPref = (ListPreference) findPreference(PreferenceConfiguration.FPS_PREF_STRING);
|
if (!PreferenceConfiguration.readPreferences(this.getActivity()).unlockFps) {
|
||||||
// We give some extra room in case the FPS is rounded down
|
// We give some extra room in case the FPS is rounded down
|
||||||
if (maxSupportedFps < 118) {
|
if (maxSupportedFps < 118) {
|
||||||
removeValue(fpsPref, "120");
|
removeValue(PreferenceConfiguration.FPS_PREF_STRING, "120", new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SettingsFragment.this.getActivity());
|
||||||
|
setValue(PreferenceConfiguration.FPS_PREF_STRING, "90");
|
||||||
|
resetBitrateToDefault(prefs, null, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (maxSupportedFps < 88) {
|
||||||
|
// 1080p is unsupported
|
||||||
|
removeValue(PreferenceConfiguration.FPS_PREF_STRING, "90", new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SettingsFragment.this.getActivity());
|
||||||
|
setValue(PreferenceConfiguration.FPS_PREF_STRING, "60");
|
||||||
|
resetBitrateToDefault(prefs, null, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Never remove 30 FPS or 60 FPS
|
||||||
}
|
}
|
||||||
if (maxSupportedFps < 88) {
|
|
||||||
// 1080p is unsupported
|
|
||||||
removeValue(fpsPref, "90");
|
|
||||||
}
|
|
||||||
// Never remove 30 FPS or 60 FPS
|
|
||||||
|
|
||||||
// Remove HDR preference for devices below Nougat
|
// Remove HDR preference for devices below Nougat
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||||
@ -263,12 +330,7 @@ public class StreamSettings extends Activity {
|
|||||||
String valueStr = (String) newValue;
|
String valueStr = (String) newValue;
|
||||||
|
|
||||||
// Write the new bitrate value
|
// Write the new bitrate value
|
||||||
prefs.edit()
|
resetBitrateToDefault(prefs, valueStr, null);
|
||||||
.putInt(PreferenceConfiguration.BITRATE_PREF_STRING,
|
|
||||||
PreferenceConfiguration.getDefaultBitrate(valueStr,
|
|
||||||
prefs.getString(PreferenceConfiguration.FPS_PREF_STRING,
|
|
||||||
PreferenceConfiguration.DEFAULT_FPS)))
|
|
||||||
.apply();
|
|
||||||
|
|
||||||
// Allow the original preference change to take place
|
// Allow the original preference change to take place
|
||||||
return true;
|
return true;
|
||||||
@ -281,12 +343,24 @@ public class StreamSettings extends Activity {
|
|||||||
String valueStr = (String) newValue;
|
String valueStr = (String) newValue;
|
||||||
|
|
||||||
// Write the new bitrate value
|
// Write the new bitrate value
|
||||||
prefs.edit()
|
resetBitrateToDefault(prefs, null, valueStr);
|
||||||
.putInt(PreferenceConfiguration.BITRATE_PREF_STRING,
|
|
||||||
PreferenceConfiguration.getDefaultBitrate(
|
// Allow the original preference change to take place
|
||||||
prefs.getString(PreferenceConfiguration.RESOLUTION_PREF_STRING, PreferenceConfiguration.DEFAULT_RESOLUTION),
|
return true;
|
||||||
valueStr))
|
}
|
||||||
.apply();
|
});
|
||||||
|
findPreference(PreferenceConfiguration.UNLOCK_FPS_STRING).setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
// HACK: We need to let the preference change succeed before reinitializing to ensure
|
||||||
|
// it's reflected in the new layout.
|
||||||
|
final Handler h = new Handler();
|
||||||
|
h.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
((StreamSettings)SettingsFragment.this.getActivity()).reloadSettings();
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
|
||||||
// Allow the original preference change to take place
|
// Allow the original preference change to take place
|
||||||
return true;
|
return true;
|
||||||
|
@ -175,6 +175,8 @@
|
|||||||
<string name="summary_disable_frame_drop">May reduce micro-stuttering on some devices, but can increase latency</string>
|
<string name="summary_disable_frame_drop">May reduce micro-stuttering on some devices, but can increase latency</string>
|
||||||
<string name="title_video_format">Change H.265 settings</string>
|
<string name="title_video_format">Change H.265 settings</string>
|
||||||
<string name="summary_video_format">H.265 lowers video bandwidth requirements but requires a very recent device</string>
|
<string name="summary_video_format">H.265 lowers video bandwidth requirements but requires a very recent device</string>
|
||||||
|
<string name="title_unlock_fps">Unlock all FPS values</string>
|
||||||
|
<string name="summary_unlock_fps">Streaming at 90 or 120 FPS may reduce latency on high-end devices but can cause lag or crashes on devices that can\'t support it</string>
|
||||||
<string name="title_enable_hdr">Enable HDR (Experimental)</string>
|
<string name="title_enable_hdr">Enable HDR (Experimental)</string>
|
||||||
<string name="summary_enable_hdr">Stream HDR when the game and PC GPU support it. HDR requires a GTX 1000 series GPU or later.</string>
|
<string name="summary_enable_hdr">Stream HDR when the game and PC GPU support it. HDR requires a GTX 1000 series GPU or later.</string>
|
||||||
|
|
||||||
|
@ -140,6 +140,11 @@
|
|||||||
android:entryValues="@array/video_format_values"
|
android:entryValues="@array/video_format_values"
|
||||||
android:summary="@string/summary_video_format"
|
android:summary="@string/summary_video_format"
|
||||||
android:defaultValue="auto" />
|
android:defaultValue="auto" />
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="checkbox_unlock_fps"
|
||||||
|
android:title="@string/title_unlock_fps"
|
||||||
|
android:summary="@string/summary_unlock_fps"
|
||||||
|
android:defaultValue="false" />
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="checkbox_disable_frame_drop"
|
android:key="checkbox_disable_frame_drop"
|
||||||
android:title="@string/title_disable_frame_drop"
|
android:title="@string/title_disable_frame_drop"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user