mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-10-20 15:27:18 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69c7b5a0d5 | ||
|
|
d1ad3115fa | ||
|
|
770af402a4 | ||
|
|
3236c0b93a | ||
|
|
51aacc3f38 | ||
|
|
397c6f46f9 | ||
|
|
d00f78f859 | ||
|
|
29fec2e0de | ||
|
|
88d28665ef | ||
|
|
de1f4da258 | ||
|
|
7985be57ab | ||
|
|
a835e7aaa2 | ||
|
|
c4dc5eb9e1 | ||
|
|
db758f386e | ||
|
|
3fb3eefa94 | ||
|
|
2d6c756e70 | ||
|
|
03e965d449 | ||
|
|
4cea483a87 |
No files matched your search
+2
-2
@@ -11,8 +11,8 @@ android {
|
|||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 21
|
targetSdkVersion 21
|
||||||
|
|
||||||
versionName "3.0.1"
|
versionName "3.0.2"
|
||||||
versionCode = 47
|
versionCode = 48
|
||||||
}
|
}
|
||||||
|
|
||||||
productFlavors {
|
productFlavors {
|
||||||
|
|||||||
Binary file not shown.
@@ -171,6 +171,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
VideoDecoderRenderer.CAPABILITY_ADAPTIVE_RESOLUTION) != 0)
|
VideoDecoderRenderer.CAPABILITY_ADAPTIVE_RESOLUTION) != 0)
|
||||||
.enableLocalAudioPlayback(prefConfig.playHostAudio)
|
.enableLocalAudioPlayback(prefConfig.playHostAudio)
|
||||||
.setMaxPacketSize(remote ? 1024 : 1292)
|
.setMaxPacketSize(remote ? 1024 : 1292)
|
||||||
|
.setRemote(remote)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Initialize the connection
|
// Initialize the connection
|
||||||
|
|||||||
@@ -527,6 +527,7 @@ public class PcView extends Activity {
|
|||||||
|
|
||||||
if (details.equals(computer.details)) {
|
if (details.equals(computer.details)) {
|
||||||
pcGridAdapter.removeComputer(computer);
|
pcGridAdapter.removeComputer(computer);
|
||||||
|
pcGridAdapter.notifyDataSetChanged();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ public class ControllerHandler {
|
|||||||
private static final int EMULATED_SELECT_UP_DELAY_MS = 30;
|
private static final int EMULATED_SELECT_UP_DELAY_MS = 30;
|
||||||
|
|
||||||
private Vector2d inputVector = new Vector2d();
|
private Vector2d inputVector = new Vector2d();
|
||||||
private Vector2d normalizedInputVector = new Vector2d();
|
|
||||||
|
|
||||||
private HashMap<String, ControllerMapping> mappings = new HashMap<String, ControllerMapping>();
|
private HashMap<String, ControllerMapping> mappings = new HashMap<String, ControllerMapping>();
|
||||||
|
|
||||||
@@ -236,6 +235,11 @@ public class ControllerHandler {
|
|||||||
mapping.isRemote = true;
|
mapping.isRemote = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// NYKO Playpad has a fake hat that mimics the left stick for some reason
|
||||||
|
else if (devName.contains("NYKO PLAYPAD")) {
|
||||||
|
mapping.hatXAxis = -1;
|
||||||
|
mapping.hatYAxis = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LimeLog.info("Analog stick deadzone: "+mapping.leftStickDeadzoneRadius+" "+mapping.rightStickDeadzoneRadius);
|
LimeLog.info("Analog stick deadzone: "+mapping.leftStickDeadzoneRadius+" "+mapping.rightStickDeadzoneRadius);
|
||||||
@@ -374,60 +378,40 @@ public class ControllerHandler {
|
|||||||
|
|
||||||
return keyCode;
|
return keyCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Vector2d populateCachedVector(float x, float y) {
|
||||||
|
// Reinitialize our cached Vector2d object
|
||||||
|
inputVector.initialize(x, y);
|
||||||
|
return inputVector;
|
||||||
|
}
|
||||||
|
|
||||||
private Vector2d handleDeadZone(float x, float y, float deadzoneRadius) {
|
private void handleDeadZone(Vector2d stickVector, float deadzoneRadius) {
|
||||||
// Reinitialize our cached Vector2d object
|
if (stickVector.getMagnitude() <= deadzoneRadius) {
|
||||||
inputVector.initialize(x, y);
|
// Deadzone
|
||||||
|
stickVector.initialize(0, 0);
|
||||||
if (inputVector.getMagnitude() <= deadzoneRadius) {
|
|
||||||
// Deadzone -- return the zero vector
|
|
||||||
return Vector2d.ZERO;
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
/*
|
|
||||||
FIXME: We're not normalizing here because we let the computer handle the deadzones.
|
|
||||||
Normalizing can make the deadzones larger than they should be after the computer also
|
|
||||||
evaluates the deadzone
|
|
||||||
|
|
||||||
// Scale the input based on the distance from the deadzone
|
// We're not normalizing here because we let the computer handle the deadzones.
|
||||||
inputVector.getNormalized(normalizedInputVector);
|
// Normalizing can make the deadzones larger than they should be after the computer also
|
||||||
normalizedInputVector.scalarMultiply((inputVector.getMagnitude() - deadzoneRadius) / (1.0f - deadzoneRadius));
|
// evaluates the deadzone.
|
||||||
|
}
|
||||||
// Bound the X value to -1.0 to 1.0
|
|
||||||
if (normalizedInputVector.getX() > 1.0f) {
|
|
||||||
normalizedInputVector.setX(1.0f);
|
|
||||||
}
|
|
||||||
else if (normalizedInputVector.getX() < -1.0f) {
|
|
||||||
normalizedInputVector.setX(-1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bound the Y value to -1.0 to 1.0
|
|
||||||
if (normalizedInputVector.getY() > 1.0f) {
|
|
||||||
normalizedInputVector.setY(1.0f);
|
|
||||||
}
|
|
||||||
else if (normalizedInputVector.getY() < -1.0f) {
|
|
||||||
normalizedInputVector.setY(-1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
return normalizedInputVector;
|
|
||||||
*/
|
|
||||||
|
|
||||||
return inputVector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleAxisSet(ControllerMapping mapping, float lsX, float lsY, float rsX,
|
private void handleAxisSet(ControllerMapping mapping, float lsX, float lsY, float rsX,
|
||||||
float rsY, float lt, float rt, float hatX, float hatY) {
|
float rsY, float lt, float rt, float hatX, float hatY) {
|
||||||
|
|
||||||
if (mapping.leftStickXAxis != -1 && mapping.leftStickYAxis != -1) {
|
if (mapping.leftStickXAxis != -1 && mapping.leftStickYAxis != -1) {
|
||||||
Vector2d leftStickVector = handleDeadZone(lsX, lsY, mapping.leftStickDeadzoneRadius);
|
Vector2d leftStickVector = populateCachedVector(lsX, lsY);
|
||||||
|
|
||||||
|
handleDeadZone(leftStickVector, mapping.leftStickDeadzoneRadius);
|
||||||
|
|
||||||
leftStickX = (short) (leftStickVector.getX() * 0x7FFE);
|
leftStickX = (short) (leftStickVector.getX() * 0x7FFE);
|
||||||
leftStickY = (short) (-leftStickVector.getY() * 0x7FFE);
|
leftStickY = (short) (-leftStickVector.getY() * 0x7FFE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapping.rightStickXAxis != -1 && mapping.rightStickYAxis != -1) {
|
if (mapping.rightStickXAxis != -1 && mapping.rightStickYAxis != -1) {
|
||||||
Vector2d rightStickVector = handleDeadZone(rsX, rsY, mapping.rightStickDeadzoneRadius);
|
Vector2d rightStickVector = populateCachedVector(rsX, rsY);
|
||||||
|
|
||||||
|
handleDeadZone(rightStickVector, mapping.rightStickDeadzoneRadius);
|
||||||
|
|
||||||
rightStickX = (short) (rightStickVector.getX() * 0x7FFE);
|
rightStickX = (short) (rightStickVector.getX() * 0x7FFE);
|
||||||
rightStickY = (short) (-rightStickVector.getY() * 0x7FFE);
|
rightStickY = (short) (-rightStickVector.getY() * 0x7FFE);
|
||||||
@@ -475,32 +459,9 @@ public class ControllerHandler {
|
|||||||
ControllerMapping mapping = getMappingForDevice(event.getDevice());
|
ControllerMapping mapping = getMappingForDevice(event.getDevice());
|
||||||
float lsX = 0, lsY = 0, rsX = 0, rsY = 0, rt = 0, lt = 0, hatX = 0, hatY = 0;
|
float lsX = 0, lsY = 0, rsX = 0, rsY = 0, rt = 0, lt = 0, hatX = 0, hatY = 0;
|
||||||
|
|
||||||
// Replay the full history before getting the current values
|
// We purposefully ignore the historical values in the motion event as it makes
|
||||||
for (int i = 0; i < event.getHistorySize(); i++) {
|
// the controller feel sluggish for some users.
|
||||||
if (mapping.leftStickXAxis != -1 && mapping.leftStickYAxis != -1) {
|
|
||||||
lsX = event.getHistoricalAxisValue(mapping.leftStickXAxis, i);
|
|
||||||
lsY = event.getHistoricalAxisValue(mapping.leftStickYAxis, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapping.rightStickXAxis != -1 && mapping.rightStickYAxis != -1) {
|
|
||||||
rsX = event.getHistoricalAxisValue(mapping.rightStickXAxis, i);
|
|
||||||
rsY = event.getHistoricalAxisValue(mapping.rightStickYAxis, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapping.leftTriggerAxis != -1 && mapping.rightTriggerAxis != -1) {
|
|
||||||
lt = event.getHistoricalAxisValue(mapping.leftTriggerAxis, i);
|
|
||||||
rt = event.getHistoricalAxisValue(mapping.rightTriggerAxis, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapping.hatXAxis != -1 && mapping.hatYAxis != -1) {
|
|
||||||
hatX = event.getHistoricalAxisValue(MotionEvent.AXIS_HAT_X, i);
|
|
||||||
hatY = event.getHistoricalAxisValue(MotionEvent.AXIS_HAT_Y, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleAxisSet(mapping, lsX, lsY, rsX, rsY, lt, rt, hatX, hatY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now handle the current set of values
|
|
||||||
if (mapping.leftStickXAxis != -1 && mapping.leftStickYAxis != -1) {
|
if (mapping.leftStickXAxis != -1 && mapping.leftStickYAxis != -1) {
|
||||||
lsX = event.getAxisValue(mapping.leftStickXAxis);
|
lsX = event.getAxisValue(mapping.leftStickXAxis);
|
||||||
lsY = event.getAxisValue(mapping.leftStickYAxis);
|
lsY = event.getAxisValue(mapping.leftStickYAxis);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.limelight.binding.input.evdev;
|
package com.limelight.binding.input.evdev;
|
||||||
|
|
||||||
import java.io.IOException;
|
import android.os.Build;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -11,31 +11,33 @@ public class EvdevReader {
|
|||||||
static {
|
static {
|
||||||
System.loadLibrary("evdev_reader");
|
System.loadLibrary("evdev_reader");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void patchSeLinuxPolicies() {
|
||||||
|
//
|
||||||
|
// FIXME: We REALLY shouldn't being changing permissions on the input devices like this.
|
||||||
|
// We should probably do something clever with a separate daemon and talk via a localhost
|
||||||
|
// socket. We don't return the SELinux policies back to default after we're done which I feel
|
||||||
|
// bad about, but we do chmod the input devices back so I don't think any additional attack surface
|
||||||
|
// remains opened after streaming other than listing the /dev/input directory which you wouldn't
|
||||||
|
// normally be able to do with SELinux enforcing on Lollipop.
|
||||||
|
//
|
||||||
|
// We need to modify SELinux policies to allow us to capture input devices on Lollipop and possibly other
|
||||||
|
// more restrictive ROMs. Per Chainfire's SuperSU documentation, the supolicy binary is provided on
|
||||||
|
// 4.4 and later to do live SELinux policy changes.
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
EvdevShell shell = EvdevShell.getInstance();
|
||||||
|
shell.runCommand("supolicy --live \"allow untrusted_app input_device dir getattr\" " +
|
||||||
|
"\"allow untrusted_app input_device chr_file { open read write ioctl }\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Requires root to chmod /dev/input/eventX
|
// Requires root to chmod /dev/input/eventX
|
||||||
public static boolean setPermissions(String[] files, int octalPermissions) {
|
public static void setPermissions(String[] files, int octalPermissions) {
|
||||||
ProcessBuilder builder = new ProcessBuilder("su");
|
EvdevShell shell = EvdevShell.getInstance();
|
||||||
|
|
||||||
try {
|
for (String file : files) {
|
||||||
Process p = builder.start();
|
shell.runCommand(String.format((Locale)null, "chmod %o %s", octalPermissions, file));
|
||||||
|
}
|
||||||
OutputStream stdin = p.getOutputStream();
|
|
||||||
for (String file : files) {
|
|
||||||
stdin.write(String.format((Locale)null, "chmod %o %s\n", octalPermissions, file).getBytes("UTF-8"));
|
|
||||||
}
|
|
||||||
stdin.write("exit\n".getBytes("UTF-8"));
|
|
||||||
stdin.flush();
|
|
||||||
|
|
||||||
p.waitFor();
|
|
||||||
p.destroy();
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the fd to be passed to other function or -1 on error
|
// Returns the fd to be passed to other function or -1 on error
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package com.limelight.binding.input.evdev;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class EvdevShell {
|
||||||
|
private OutputStream stdin;
|
||||||
|
private InputStream stdout;
|
||||||
|
private Process shell;
|
||||||
|
private final String uuidString = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
private static final EvdevShell globalShell = new EvdevShell();
|
||||||
|
|
||||||
|
public static EvdevShell getInstance() {
|
||||||
|
return globalShell;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startShell() {
|
||||||
|
ProcessBuilder builder = new ProcessBuilder("su");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Redirect stderr to stdout
|
||||||
|
builder.redirectErrorStream(true);
|
||||||
|
shell = builder.start();
|
||||||
|
|
||||||
|
stdin = shell.getOutputStream();
|
||||||
|
stdout = shell.getInputStream();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// This is unexpected
|
||||||
|
e.printStackTrace();
|
||||||
|
|
||||||
|
// Kill the shell if it spawned
|
||||||
|
if (stdin != null) {
|
||||||
|
try {
|
||||||
|
stdin.close();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
stdin = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stdout != null) {
|
||||||
|
try {
|
||||||
|
stdout.close();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
stdout = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shell != null) {
|
||||||
|
shell.destroy();
|
||||||
|
shell = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runCommand(String command) {
|
||||||
|
if (shell == null) {
|
||||||
|
// Shell never started
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Write the command followed by an echo with our UUID
|
||||||
|
stdin.write((command+'\n').getBytes("UTF-8"));
|
||||||
|
stdin.write(("echo "+uuidString+'\n').getBytes("UTF-8"));
|
||||||
|
stdin.flush();
|
||||||
|
|
||||||
|
// This is the only command in flight so we can use a scanner
|
||||||
|
// without worrying about it eating too many characters
|
||||||
|
Scanner scanner = new Scanner(stdout);
|
||||||
|
while (scanner.hasNext()) {
|
||||||
|
if (scanner.next().contains(uuidString)) {
|
||||||
|
// Our command ran
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopShell() throws InterruptedException {
|
||||||
|
boolean exitWritten = false;
|
||||||
|
|
||||||
|
if (shell == null) {
|
||||||
|
// Shell never started
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
stdin.write("exit\n".getBytes("UTF-8"));
|
||||||
|
exitWritten = true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
// We'll destroy the process without
|
||||||
|
// waiting for it to terminate since
|
||||||
|
// we don't know whether our exit command made it
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exitWritten) {
|
||||||
|
try {
|
||||||
|
shell.waitFor();
|
||||||
|
} finally {
|
||||||
|
shell.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
shell.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,8 @@ public class EvdevWatcher {
|
|||||||
private boolean ungrabbed = false;
|
private boolean ungrabbed = false;
|
||||||
private EvdevListener listener;
|
private EvdevListener listener;
|
||||||
private Thread startThread;
|
private Thread startThread;
|
||||||
|
|
||||||
|
private static boolean patchedSeLinuxPolicies = false;
|
||||||
|
|
||||||
private FileObserver observer = new FileObserver(PATH, FileObserver.CREATE | FileObserver.DELETE) {
|
private FileObserver observer = new FileObserver(PATH, FileObserver.CREATE | FileObserver.DELETE) {
|
||||||
@Override
|
@Override
|
||||||
@@ -117,6 +119,15 @@ public class EvdevWatcher {
|
|||||||
startThread = new Thread() {
|
startThread = new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
// Initialize the root shell
|
||||||
|
EvdevShell.getInstance().startShell();
|
||||||
|
|
||||||
|
// Patch SELinux policies (if needed)
|
||||||
|
if (!patchedSeLinuxPolicies) {
|
||||||
|
EvdevReader.patchSeLinuxPolicies();
|
||||||
|
patchedSeLinuxPolicies = true;
|
||||||
|
}
|
||||||
|
|
||||||
// List all files and allow us access
|
// List all files and allow us access
|
||||||
File[] files = rundownWithPermissionsChange(0666);
|
File[] files = rundownWithPermissionsChange(0666);
|
||||||
|
|
||||||
@@ -139,7 +150,12 @@ public class EvdevWatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Giveup eventX permissions
|
// Giveup eventX permissions
|
||||||
rundownWithPermissionsChange(066);
|
rundownWithPermissionsChange(0660);
|
||||||
|
|
||||||
|
// Kill the root shell
|
||||||
|
try {
|
||||||
|
EvdevShell.getInstance().stopShell();
|
||||||
|
} catch (InterruptedException e) {}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
startThread.start();
|
startThread.start();
|
||||||
|
|||||||
@@ -410,6 +410,23 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
|
|||||||
spsBuf.position(header.offset+5);
|
spsBuf.position(header.offset+5);
|
||||||
|
|
||||||
SeqParameterSet sps = SeqParameterSet.read(spsBuf);
|
SeqParameterSet sps = SeqParameterSet.read(spsBuf);
|
||||||
|
|
||||||
|
// Some decoders rely on H264 level to decide how many buffers are needed
|
||||||
|
// Since we only need one frame buffered, we'll set the level as low as we can
|
||||||
|
// for known resolution combinations
|
||||||
|
if (initialWidth == 1280 && initialHeight == 720) {
|
||||||
|
// Max 5 buffered frames at 1280x720x60
|
||||||
|
LimeLog.info("Patching level_idc to 32");
|
||||||
|
sps.level_idc = 32;
|
||||||
|
}
|
||||||
|
else if (initialWidth == 1920 && initialHeight == 1080) {
|
||||||
|
// Max 4 buffered frames at 1920x1080x64
|
||||||
|
LimeLog.info("Patching level_idc to 42");
|
||||||
|
sps.level_idc = 42;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Leave the profile alone (currently 5.0)
|
||||||
|
}
|
||||||
|
|
||||||
// TI OMAP4 requires a reference frame count of 1 to decode successfully. Exynos 4
|
// TI OMAP4 requires a reference frame count of 1 to decode successfully. Exynos 4
|
||||||
// also requires this fixup.
|
// also requires this fixup.
|
||||||
|
|||||||
@@ -355,6 +355,12 @@ public class ComputerManagerService extends Service {
|
|||||||
|
|
||||||
private boolean pollComputer(ComputerDetails details, boolean localFirst) {
|
private boolean pollComputer(ComputerDetails details, boolean localFirst) {
|
||||||
ComputerDetails polledDetails;
|
ComputerDetails polledDetails;
|
||||||
|
|
||||||
|
// If the local address is routable across the Internet,
|
||||||
|
// always consider this PC remote to be conservative
|
||||||
|
if (details.localIp.equals(details.remoteIp)) {
|
||||||
|
localFirst = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (localFirst) {
|
if (localFirst) {
|
||||||
polledDetails = tryPollIp(details, details.localIp);
|
polledDetails = tryPollIp(details, details.localIp);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class PreferenceConfiguration {
|
|||||||
private static final int BITRATE_DEFAULT_720_30 = 5;
|
private static final int BITRATE_DEFAULT_720_30 = 5;
|
||||||
private static final int BITRATE_DEFAULT_720_60 = 10;
|
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_30 = 10;
|
||||||
private static final int BITRATE_DEFAULT_1080_60 = 30;
|
private static final int BITRATE_DEFAULT_1080_60 = 20;
|
||||||
|
|
||||||
private static final String DEFAULT_RES_FPS = "720p60";
|
private static final String DEFAULT_RES_FPS = "720p60";
|
||||||
private static final String DEFAULT_DECODER = "auto";
|
private static final String DEFAULT_DECODER = "auto";
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
<string name="summary_seekbar_bitrate">Abbassa il bitrate per ridurre lo stuttering; alza il bitrate per aumenteare la qualità dell\'immagine</string>
|
<string name="summary_seekbar_bitrate">Abbassa il bitrate per ridurre lo stuttering; alza il bitrate per aumenteare la qualità dell\'immagine</string>
|
||||||
<string name="suffix_seekbar_bitrate">Mbps</string>
|
<string name="suffix_seekbar_bitrate">Mbps</string>
|
||||||
<string name="title_checkbox_stretch_video">Forza video in full-screen</string>
|
<string name="title_checkbox_stretch_video">Forza video in full-screen</string>
|
||||||
<string name="title_checkbox_disable_warnings">Disabilita i messaggi di warning</string>
|
<string name="title_checkbox_disable_warnings">Disabilita messaggi di warning</string>
|
||||||
<string name="summary_checkbox_disable_warnings">Disabilita i messaggi di warning sullo schermo durante lo streaming</string>
|
<string name="summary_checkbox_disable_warnings">Disabilita i messaggi di warning sullo schermo durante lo streaming</string>
|
||||||
|
|
||||||
<string name="category_gamepad_settings">Impostazioni Gamepad</string>
|
<string name="category_gamepad_settings">Impostazioni Gamepad</string>
|
||||||
@@ -102,5 +102,5 @@
|
|||||||
|
|
||||||
<string name="category_advanced_settings">Impostazioni Avanzate</string>
|
<string name="category_advanced_settings">Impostazioni Avanzate</string>
|
||||||
<string name="title_decoder_list">Cambia decoder</string>
|
<string name="title_decoder_list">Cambia decoder</string>
|
||||||
<string name="summary_decoder_list">Il decoder software può aumentare la latenza video quando si usano impostazioni streaming basse</string>
|
<string name="summary_decoder_list">Il decoder software può ridurre la latenza video quando si usano impostazioni streaming basse</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in new issue
Block a user