mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-10-20 15:27:18 +00:00
Implement a custom resolution chooser. It doesn't really work now due to GFE failing to change the resolution to one matching the expected aspect ratio
This commit is contained in:
1 parent
3a0c1db168
commit
5e45aeb70b
7 files changed
+306
-93
No files matched your search
@@ -5,7 +5,9 @@ import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public class PreferenceConfiguration {
|
||||
static final String RES_FPS_PREF_STRING = "list_resolution_fps";
|
||||
static final String RESX_PREF_STRING = "resolution_x";
|
||||
static final String RESY_PREF_STRING = "resolution_y";
|
||||
private static final String FPS_PREF_STRING = "fps";
|
||||
private static final String DECODER_PREF_STRING = "list_decoders";
|
||||
static final String BITRATE_PREF_STRING = "seekbar_bitrate";
|
||||
private static final String STRETCH_PREF_STRING = "checkbox_stretch_video";
|
||||
@@ -21,10 +23,12 @@ public class PreferenceConfiguration {
|
||||
private static final int BITRATE_DEFAULT_720_60 = 10;
|
||||
private static final int BITRATE_DEFAULT_1080_30 = 10;
|
||||
private static final int BITRATE_DEFAULT_1080_60 = 20;
|
||||
private static final int BITRATE_DEFAULT_MAX = 35;
|
||||
|
||||
private static final String DEFAULT_RES_FPS = "720p60";
|
||||
private static final int DEFAULT_RESX = 1280;
|
||||
private static final int DEFAULT_RESY = 720;
|
||||
private static final String DEFAULT_FPS = "60";
|
||||
private static final String DEFAULT_DECODER = "auto";
|
||||
private static final int DEFAULT_BITRATE = BITRATE_DEFAULT_720_60;
|
||||
private static final boolean DEFAULT_STRETCH = false;
|
||||
private static final boolean DEFAULT_SOPS = true;
|
||||
private static final boolean DEFAULT_DISABLE_TOASTS = false;
|
||||
@@ -45,49 +49,40 @@ public class PreferenceConfiguration {
|
||||
public String language;
|
||||
public boolean listMode, smallIconMode;
|
||||
|
||||
public static int getDefaultBitrate(String resFpsString) {
|
||||
if (resFpsString.equals("720p30")) {
|
||||
return BITRATE_DEFAULT_720_30;
|
||||
}
|
||||
else if (resFpsString.equals("720p60")) {
|
||||
return BITRATE_DEFAULT_720_60;
|
||||
}
|
||||
else if (resFpsString.equals("1080p30")) {
|
||||
return BITRATE_DEFAULT_1080_30;
|
||||
}
|
||||
else if (resFpsString.equals("1080p60")) {
|
||||
return BITRATE_DEFAULT_1080_60;
|
||||
}
|
||||
else {
|
||||
// Should never get here
|
||||
return DEFAULT_BITRATE;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean getDefaultSmallMode(Context context) {
|
||||
// Use small mode on anything smaller than a 7" tablet
|
||||
return context.getResources().getConfiguration().smallestScreenWidthDp < 600;
|
||||
}
|
||||
|
||||
private static int getFpsInt(SharedPreferences prefs) {
|
||||
try {
|
||||
return Integer.parseInt(prefs.getString(FPS_PREF_STRING, DEFAULT_FPS));
|
||||
} catch (NumberFormatException e) {
|
||||
return Integer.parseInt(DEFAULT_FPS);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getDefaultBitrate(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
String str = prefs.getString(RES_FPS_PREF_STRING, DEFAULT_RES_FPS);
|
||||
if (str.equals("720p30")) {
|
||||
long width = prefs.getInt(RESX_PREF_STRING, DEFAULT_RESX);
|
||||
long height = prefs.getInt(RESY_PREF_STRING, DEFAULT_RESY);
|
||||
|
||||
long product = width * height * getFpsInt(prefs);
|
||||
if (product <= 1280 * 720 * 30) {
|
||||
return BITRATE_DEFAULT_720_30;
|
||||
}
|
||||
else if (str.equals("720p60")) {
|
||||
else if (product <= 1280 * 720 * 60) {
|
||||
return BITRATE_DEFAULT_720_60;
|
||||
}
|
||||
else if (str.equals("1080p30")) {
|
||||
else if (product <= 1920 * 1080 * 30) {
|
||||
return BITRATE_DEFAULT_1080_30;
|
||||
}
|
||||
else if (str.equals("1080p60")) {
|
||||
else if (product <= 1920 * 1080 * 60) {
|
||||
return BITRATE_DEFAULT_1080_60;
|
||||
}
|
||||
else {
|
||||
// Should never get here
|
||||
return DEFAULT_BITRATE;
|
||||
return BITRATE_DEFAULT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,33 +110,9 @@ public class PreferenceConfiguration {
|
||||
PreferenceConfiguration config = new PreferenceConfiguration();
|
||||
|
||||
config.bitrate = prefs.getInt(BITRATE_PREF_STRING, getDefaultBitrate(context));
|
||||
String str = prefs.getString(RES_FPS_PREF_STRING, DEFAULT_RES_FPS);
|
||||
if (str.equals("720p30")) {
|
||||
config.width = 1280;
|
||||
config.height = 720;
|
||||
config.fps = 30;
|
||||
}
|
||||
else if (str.equals("720p60")) {
|
||||
config.width = 1280;
|
||||
config.height = 720;
|
||||
config.fps = 60;
|
||||
}
|
||||
else if (str.equals("1080p30")) {
|
||||
config.width = 1920;
|
||||
config.height = 1080;
|
||||
config.fps = 30;
|
||||
}
|
||||
else if (str.equals("1080p60")) {
|
||||
config.width = 1920;
|
||||
config.height = 1080;
|
||||
config.fps = 60;
|
||||
}
|
||||
else {
|
||||
// Should never get here
|
||||
config.width = 1280;
|
||||
config.height = 720;
|
||||
config.fps = 60;
|
||||
}
|
||||
config.width = prefs.getInt(RESX_PREF_STRING, DEFAULT_RESX);
|
||||
config.height = prefs.getInt(RESY_PREF_STRING, DEFAULT_RESY);
|
||||
config.fps = getFpsInt(prefs);
|
||||
|
||||
config.decoder = getDecoderValue(context);
|
||||
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
package com.limelight.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.DialogPreference;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.limelight.R;
|
||||
|
||||
public class ResolutionPreference extends DialogPreference {
|
||||
private RadioButton a4_3;
|
||||
private RadioButton a16_9;
|
||||
private RadioButton a16_10;
|
||||
private SeekBar resolutionSeekBar;
|
||||
private TextView resolutionText;
|
||||
|
||||
private int resolutionX;
|
||||
private int resolutionY;
|
||||
|
||||
public ResolutionPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
setDialogLayoutResource(R.layout.dialog_resolution);
|
||||
setPositiveButtonText(android.R.string.ok);
|
||||
setNegativeButtonText(android.R.string.cancel);
|
||||
|
||||
setDialogIcon(null);
|
||||
}
|
||||
|
||||
private int getPreferenceState() {
|
||||
int checkboxState;
|
||||
int sliderState;
|
||||
|
||||
if (a4_3.isChecked()) {
|
||||
checkboxState = 1;
|
||||
}
|
||||
else if (a16_10.isChecked()) {
|
||||
checkboxState = 2;
|
||||
}
|
||||
else {
|
||||
checkboxState = 0;
|
||||
}
|
||||
|
||||
sliderState = resolutionSeekBar.getProgress();
|
||||
|
||||
return checkboxState << 24 | sliderState;
|
||||
}
|
||||
|
||||
private void setPreferenceState(int state) {
|
||||
int checkboxState;
|
||||
int sliderState;
|
||||
|
||||
checkboxState = state >> 24;
|
||||
sliderState = state & 0x00FFFFFF;
|
||||
|
||||
a4_3.setChecked(false);
|
||||
a16_10.setChecked(false);
|
||||
a16_9.setChecked(false);
|
||||
|
||||
if (checkboxState == 1) {
|
||||
a4_3.setChecked(true);
|
||||
}
|
||||
else if (checkboxState == 2) {
|
||||
a16_10.setChecked(true);
|
||||
}
|
||||
else {
|
||||
a16_9.setChecked(true);
|
||||
}
|
||||
|
||||
resolutionSeekBar.setProgress(sliderState);
|
||||
}
|
||||
|
||||
private void updateResolution() {
|
||||
double aspectFactor;
|
||||
int step = resolutionSeekBar.getProgress() + 1;
|
||||
|
||||
if (a4_3.isChecked()) {
|
||||
aspectFactor = 4.0/3.0;
|
||||
|
||||
switch (step) {
|
||||
case 1:
|
||||
// 640x480
|
||||
resolutionY = 480;
|
||||
break;
|
||||
case 2:
|
||||
// 800x600
|
||||
resolutionY = 600;
|
||||
break;
|
||||
case 3:
|
||||
// 1024x768
|
||||
resolutionY = 768;
|
||||
break;
|
||||
case 4:
|
||||
// 1600x1200
|
||||
resolutionY = 1200;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (a16_9.isChecked()) {
|
||||
aspectFactor = 16.0/9.0;
|
||||
|
||||
switch (step) {
|
||||
case 1:
|
||||
// 1280x720
|
||||
resolutionY = 720;
|
||||
break;
|
||||
case 2:
|
||||
// 1920x1080
|
||||
resolutionY = 1080;
|
||||
break;
|
||||
case 3:
|
||||
// 2560x1440
|
||||
resolutionY = 1440;
|
||||
break;
|
||||
case 4:
|
||||
// 3840x2160
|
||||
resolutionY = 2160;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else /* if (a16_10.isChecked() */ {
|
||||
aspectFactor = 16.0/10.0;
|
||||
|
||||
switch (step) {
|
||||
case 1:
|
||||
// 1280x800
|
||||
resolutionY = 800;
|
||||
break;
|
||||
case 2:
|
||||
// 1920x1200
|
||||
resolutionY = 1200;
|
||||
break;
|
||||
case 3:
|
||||
// 2560x1600
|
||||
resolutionY = 1600;
|
||||
break;
|
||||
case 4:
|
||||
// 3840x2400
|
||||
resolutionY = 2400;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
resolutionX = (int)(resolutionY * aspectFactor);
|
||||
|
||||
resolutionText.setText(resolutionX+"x"+resolutionY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDialogClosed(boolean positiveResult) {
|
||||
if (positiveResult) {
|
||||
SharedPreferences.Editor e = getPreferenceManager().getSharedPreferences().edit();
|
||||
e.putInt(PreferenceConfiguration.RESX_PREF_STRING, resolutionX);
|
||||
e.putInt(PreferenceConfiguration.RESY_PREF_STRING, resolutionY);
|
||||
persistInt(getPreferenceState());
|
||||
e.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View onCreateDialogView() {
|
||||
View v = super.onCreateDialogView();
|
||||
|
||||
a4_3 = (RadioButton) v.findViewById(R.id.aspect_4_3);
|
||||
a16_9 = (RadioButton) v.findViewById(R.id.aspect_16_9);
|
||||
a16_10 = (RadioButton) v.findViewById(R.id.aspect_16_10);
|
||||
resolutionText = (TextView) v.findViewById(R.id.resolutionText);
|
||||
resolutionSeekBar = (SeekBar) v.findViewById(R.id.resolutionSeekbar);
|
||||
|
||||
CompoundButton.OnCheckedChangeListener ccListener = new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
updateResolution();
|
||||
}
|
||||
};
|
||||
a4_3.setOnCheckedChangeListener(ccListener);
|
||||
a16_9.setOnCheckedChangeListener(ccListener);
|
||||
a16_10.setOnCheckedChangeListener(ccListener);
|
||||
|
||||
resolutionSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
updateResolution();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
|
||||
// Check the correct checkbox
|
||||
setPreferenceState(getPersistedInt(0));
|
||||
|
||||
// Set initial resolution value
|
||||
updateResolution();
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
@@ -51,26 +51,6 @@ public class StreamSettings extends Activity {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
|
||||
// Add a listener to the FPS and resolution preference
|
||||
// so the bitrate can be auto-adjusted
|
||||
Preference pref = findPreference(PreferenceConfiguration.RES_FPS_PREF_STRING);
|
||||
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SettingsFragment.this.getActivity());
|
||||
String valueStr = (String) newValue;
|
||||
|
||||
// Write the new bitrate value
|
||||
prefs.edit()
|
||||
.putInt(PreferenceConfiguration.BITRATE_PREF_STRING,
|
||||
PreferenceConfiguration.getDefaultBitrate(valueStr))
|
||||
.apply();
|
||||
|
||||
// Allow the original preference change to take place
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user