Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ac1cb6d56b | |||
| dfbffea0fc | |||
| 7ae9c993f1 | |||
| 91d739f8d6 | |||
| f0c625d85c | |||
| b5f5e73076 | |||
| 1fb5eff7f1 | |||
| 5116cfd141 | |||
| e53a1f90b0 | |||
| 766c9628b0 | |||
| 6a4abdd74c | |||
| fc8bc5ba1e | |||
| 0fde5d44c0 | |||
| dc6b5a3d49 | |||
| 396522f249 | |||
| 86ab39e4ca | |||
| a4c9cb0e55 | |||
| e6c6feac10 | |||
| ca0aee58ab | |||
| 6391f2c43d | |||
| 32171bb70c | |||
| fd6675a3a3 | |||
| 9d883978a8 | |||
| 1aae65575c | |||
| c5d58e1aab | |||
| 56394471fa |
+5
-5
@@ -7,8 +7,8 @@ android {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
|
||||
versionName "9.7.1"
|
||||
versionCode = 241
|
||||
versionName "9.7.6"
|
||||
versionCode = 246
|
||||
}
|
||||
|
||||
flavorDimensions "root"
|
||||
@@ -114,10 +114,10 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.64'
|
||||
implementation 'org.bouncycastle:bcpkix-jdk15on:1.64'
|
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.66'
|
||||
implementation 'org.bouncycastle:bcpkix-jdk15on:1.66'
|
||||
implementation 'org.jcodec:jcodec:0.2.3'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.10'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.12'
|
||||
implementation 'com.squareup.okio:okio:1.17.5'
|
||||
implementation 'org.jmdns:jmdns:3.5.5'
|
||||
}
|
||||
|
||||
@@ -126,6 +126,15 @@
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.limelight.AppView" />
|
||||
|
||||
<!-- Special metadata for NVIDIA Shield devices to prevent input buffering
|
||||
and most importantly, opt out of mouse acceleration while streaming -->
|
||||
<meta-data
|
||||
android:name="com.nvidia.immediateInput"
|
||||
android:value="true" />
|
||||
<meta-data
|
||||
android:name="com.nvidia.rawCursorInput"
|
||||
android:value="true" />
|
||||
</activity>
|
||||
|
||||
<service
|
||||
|
||||
@@ -113,7 +113,7 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
return;
|
||||
}
|
||||
|
||||
appGridAdapter.updateHiddenApps(hiddenAppIds);
|
||||
appGridAdapter.updateHiddenApps(hiddenAppIds, true);
|
||||
|
||||
// Now make the binder visible. We must do this after appGridAdapter
|
||||
// is set to prevent us from reaching updateUiWithServerinfo() and
|
||||
@@ -314,7 +314,7 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
Service.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
private void updateHiddenApps() {
|
||||
private void updateHiddenApps(boolean hideImmediately) {
|
||||
HashSet<String> hiddenAppIdStringSet = new HashSet<>();
|
||||
|
||||
for (Integer hiddenAppId : hiddenAppIds) {
|
||||
@@ -326,7 +326,7 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
.putStringSet(uuidString, hiddenAppIdStringSet)
|
||||
.apply();
|
||||
|
||||
appGridAdapter.updateHiddenApps(hiddenAppIds);
|
||||
appGridAdapter.updateHiddenApps(hiddenAppIds, hideImmediately);
|
||||
}
|
||||
|
||||
private void populateAppGridWithCache() {
|
||||
@@ -481,7 +481,7 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
// Transitioning shown to hidden
|
||||
hiddenAppIds.add(app.app.getAppId());
|
||||
}
|
||||
updateHiddenApps();
|
||||
updateHiddenApps(false);
|
||||
return true;
|
||||
|
||||
case CREATE_SHORTCUT_ID:
|
||||
|
||||
@@ -1596,6 +1596,10 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
message = getResources().getString(R.string.no_video_received_error);
|
||||
break;
|
||||
|
||||
case MoonBridge.ML_ERROR_NO_VIDEO_FRAME:
|
||||
message = getResources().getString(R.string.no_frame_received_error);
|
||||
break;
|
||||
|
||||
default:
|
||||
message = getResources().getString(R.string.conn_terminated_msg);
|
||||
break;
|
||||
|
||||
@@ -40,6 +40,12 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
|
||||
private static final int MINIMUM_BUTTON_DOWN_TIME_MS = 25;
|
||||
|
||||
private static final int EMULATING_SPECIAL = 0x1;
|
||||
private static final int EMULATING_SELECT = 0x2;
|
||||
|
||||
private static final int EMULATED_SPECIAL_UP_DELAY_MS = 100;
|
||||
private static final int EMULATED_SELECT_UP_DELAY_MS = 30;
|
||||
|
||||
private final Vector2d inputVector = new Vector2d();
|
||||
|
||||
private final SparseArray<InputDeviceContext> inputDeviceContexts = new SparseArray<>();
|
||||
@@ -461,6 +467,14 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
context.vibrator = dev.getVibrator();
|
||||
}
|
||||
|
||||
// Detect if the gamepad has Mode and Select buttons according to the Android key layouts.
|
||||
// We do this first because other codepaths below may override these defaults.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
boolean[] buttons = dev.hasKeys(KeyEvent.KEYCODE_BUTTON_MODE, KeyEvent.KEYCODE_BUTTON_SELECT, KeyEvent.KEYCODE_BACK, 0);
|
||||
context.hasMode = buttons[0];
|
||||
context.hasSelect = buttons[1] || buttons[2];
|
||||
}
|
||||
|
||||
context.leftStickXAxis = MotionEvent.AXIS_X;
|
||||
context.leftStickYAxis = MotionEvent.AXIS_Y;
|
||||
if (getMotionRangeForJoystickAxis(dev, context.leftStickXAxis) != null &&
|
||||
@@ -519,6 +533,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
// The old DS4 driver uses RX and RY for triggers
|
||||
context.leftTriggerAxis = MotionEvent.AXIS_RX;
|
||||
context.rightTriggerAxis = MotionEvent.AXIS_RY;
|
||||
|
||||
// DS4 has Select and Mode buttons (possibly mapped non-standard)
|
||||
context.hasSelect = true;
|
||||
context.hasMode = true;
|
||||
}
|
||||
else {
|
||||
// If it's not a non-standard DS4 controller, it's probably an Xbox controller or
|
||||
@@ -600,6 +618,8 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
context.backIsStart = true;
|
||||
context.modeIsSelect = true;
|
||||
context.triggerDeadzone = 0.30f;
|
||||
context.hasSelect = true;
|
||||
context.hasMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,6 +637,8 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
if (!hasStartKey[0] && !hasStartKey[1]) {
|
||||
context.backIsStart = true;
|
||||
context.modeIsSelect = true;
|
||||
context.hasSelect = true;
|
||||
context.hasMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -625,14 +647,26 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
context.triggerDeadzone = 0.30f;
|
||||
}
|
||||
// SHIELD controllers will use small stick deadzones
|
||||
else if (devName.contains("SHIELD")) {
|
||||
else if (devName.contains("SHIELD") || devName.contains("NVIDIA Controller")) {
|
||||
context.leftStickDeadzoneRadius = 0.07f;
|
||||
context.rightStickDeadzoneRadius = 0.07f;
|
||||
|
||||
// The big Nvidia button on the Shield controllers acts like a Search button. It
|
||||
// summons the Google Assistant on the Shield TV. On my Pixel 4, it seems to do
|
||||
// nothing, so we can hijack it to act like a mode button.
|
||||
if (devName.contains("NVIDIA Controller v01.03") || devName.contains("NVIDIA Controller v01.04")) {
|
||||
context.searchIsMode = true;
|
||||
context.hasMode = true;
|
||||
}
|
||||
}
|
||||
// The Serval has a couple of unknown buttons that are start and select. It also has
|
||||
// a back button which we want to ignore since there's already a select button.
|
||||
else if (devName.contains("Razer Serval")) {
|
||||
context.isServal = true;
|
||||
|
||||
// Serval has Select and Mode buttons (possibly mapped non-standard)
|
||||
context.hasMode = true;
|
||||
context.hasSelect = true;
|
||||
}
|
||||
// The Xbox One S Bluetooth controller has some mappings that need fixing up.
|
||||
// However, Microsoft released a firmware update with no change to VID/PID
|
||||
@@ -643,6 +677,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
else if (devName.equals("Xbox Wireless Controller")) {
|
||||
if (gasRange == null) {
|
||||
context.isNonStandardXboxBtController = true;
|
||||
|
||||
// Xbox One S has Select and Mode buttons (possibly mapped non-standard)
|
||||
context.hasMode = true;
|
||||
context.hasSelect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1018,6 +1056,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
// Emulate the select button with mode
|
||||
return KeyEvent.KEYCODE_BUTTON_SELECT;
|
||||
}
|
||||
else if (context.searchIsMode && keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||
// Emulate the mode button with search
|
||||
return KeyEvent.KEYCODE_BUTTON_MODE;
|
||||
}
|
||||
|
||||
return keyCode;
|
||||
}
|
||||
@@ -1416,6 +1458,41 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if we're emulating the select button
|
||||
if ((context.emulatingButtonFlags & ControllerHandler.EMULATING_SELECT) != 0)
|
||||
{
|
||||
// If either start or LB is up, select comes up too
|
||||
if ((context.inputMap & ControllerPacket.PLAY_FLAG) == 0 ||
|
||||
(context.inputMap & ControllerPacket.LB_FLAG) == 0)
|
||||
{
|
||||
context.inputMap &= ~ControllerPacket.BACK_FLAG;
|
||||
|
||||
context.emulatingButtonFlags &= ~ControllerHandler.EMULATING_SELECT;
|
||||
|
||||
try {
|
||||
Thread.sleep(EMULATED_SELECT_UP_DELAY_MS);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we're emulating the special button
|
||||
if ((context.emulatingButtonFlags & ControllerHandler.EMULATING_SPECIAL) != 0)
|
||||
{
|
||||
// If either start or select and RB is up, the special button comes up too
|
||||
if ((context.inputMap & ControllerPacket.PLAY_FLAG) == 0 ||
|
||||
((context.inputMap & ControllerPacket.BACK_FLAG) == 0 &&
|
||||
(context.inputMap & ControllerPacket.RB_FLAG) == 0))
|
||||
{
|
||||
context.inputMap &= ~ControllerPacket.SPECIAL_BUTTON_FLAG;
|
||||
|
||||
context.emulatingButtonFlags &= ~ControllerHandler.EMULATING_SPECIAL;
|
||||
|
||||
try {
|
||||
Thread.sleep(EMULATED_SPECIAL_UP_DELAY_MS);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
sendControllerInputPacket(context);
|
||||
|
||||
if (context.pendingExit && context.inputMap == 0) {
|
||||
@@ -1444,6 +1521,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_BUTTON_MODE:
|
||||
context.hasMode = true;
|
||||
context.inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_START:
|
||||
@@ -1455,6 +1533,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BACK:
|
||||
case KeyEvent.KEYCODE_BUTTON_SELECT:
|
||||
context.hasSelect = true;
|
||||
context.inputMap |= ControllerPacket.BACK_FLAG;
|
||||
break;
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
@@ -1535,6 +1614,43 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
context.pendingExit = true;
|
||||
}
|
||||
|
||||
// Start+LB acts like select for controllers with one button
|
||||
if (!context.hasSelect) {
|
||||
if (context.inputMap == (ControllerPacket.PLAY_FLAG | ControllerPacket.LB_FLAG) ||
|
||||
(context.inputMap == ControllerPacket.PLAY_FLAG &&
|
||||
SystemClock.uptimeMillis() - context.lastLbUpTime <= MAXIMUM_BUMPER_UP_DELAY_MS))
|
||||
{
|
||||
context.inputMap &= ~(ControllerPacket.PLAY_FLAG | ControllerPacket.LB_FLAG);
|
||||
context.inputMap |= ControllerPacket.BACK_FLAG;
|
||||
|
||||
context.emulatingButtonFlags |= ControllerHandler.EMULATING_SELECT;
|
||||
}
|
||||
}
|
||||
|
||||
// If there is a physical select button, we'll use Start+Select as the special button combo
|
||||
// otherwise we'll use Start+RB.
|
||||
if (!context.hasMode) {
|
||||
if (context.hasSelect) {
|
||||
if (context.inputMap == (ControllerPacket.PLAY_FLAG | ControllerPacket.BACK_FLAG)) {
|
||||
context.inputMap &= ~(ControllerPacket.PLAY_FLAG | ControllerPacket.BACK_FLAG);
|
||||
context.inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG;
|
||||
|
||||
context.emulatingButtonFlags |= ControllerHandler.EMULATING_SPECIAL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (context.inputMap == (ControllerPacket.PLAY_FLAG | ControllerPacket.RB_FLAG) ||
|
||||
(context.inputMap == ControllerPacket.PLAY_FLAG &&
|
||||
SystemClock.uptimeMillis() - context.lastRbUpTime <= MAXIMUM_BUMPER_UP_DELAY_MS))
|
||||
{
|
||||
context.inputMap &= ~(ControllerPacket.PLAY_FLAG | ControllerPacket.RB_FLAG);
|
||||
context.inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG;
|
||||
|
||||
context.emulatingButtonFlags |= ControllerHandler.EMULATING_SPECIAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We don't need to send repeat key down events, but the platform
|
||||
// sends us events that claim to be repeats but they're from different
|
||||
// devices, so we just send them all and deal with some duplicates.
|
||||
@@ -1676,10 +1792,15 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
public boolean isServal;
|
||||
public boolean backIsStart;
|
||||
public boolean modeIsSelect;
|
||||
public boolean searchIsMode;
|
||||
public boolean ignoreBack;
|
||||
public boolean hasJoystickAxes;
|
||||
public boolean pendingExit;
|
||||
|
||||
public int emulatingButtonFlags = 0;
|
||||
public boolean hasSelect;
|
||||
public boolean hasMode;
|
||||
|
||||
// Used for OUYA bumper state tracking since they force all buttons
|
||||
// up when the OUYA button goes down. We watch the last time we get
|
||||
// a bumper up and compare that to our maximum delay when we receive
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.os.SystemClock;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -270,7 +271,7 @@ public class AnalogStick extends VirtualControllerElement {
|
||||
// We also release the deadzone if the user keeps the stick pressed for a bit to allow
|
||||
// them to make precise movements.
|
||||
stick_state = (stick_state == STICK_STATE.MOVED_ACTIVE ||
|
||||
System.currentTimeMillis() - timeLastClick > timeoutDeadzone ||
|
||||
SystemClock.uptimeMillis() - timeLastClick > timeoutDeadzone ||
|
||||
movement_radius > radius_dead_zone) ?
|
||||
STICK_STATE.MOVED_ACTIVE : STICK_STATE.MOVED_IN_DEAD_ZONE;
|
||||
|
||||
@@ -311,7 +312,7 @@ public class AnalogStick extends VirtualControllerElement {
|
||||
stick_state = STICK_STATE.MOVED_IN_DEAD_ZONE;
|
||||
// check for double click
|
||||
if (lastClickState == CLICK_STATE.SINGLE &&
|
||||
timeLastClick + timeoutDoubleClick > System.currentTimeMillis()) {
|
||||
timeLastClick + timeoutDoubleClick > SystemClock.uptimeMillis()) {
|
||||
click_state = CLICK_STATE.DOUBLE;
|
||||
notifyOnDoubleClick();
|
||||
} else {
|
||||
@@ -319,7 +320,7 @@ public class AnalogStick extends VirtualControllerElement {
|
||||
notifyOnClick();
|
||||
}
|
||||
// reset last click timestamp
|
||||
timeLastClick = System.currentTimeMillis();
|
||||
timeLastClick = SystemClock.uptimeMillis();
|
||||
// set item pressed and update
|
||||
setPressed(true);
|
||||
break;
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.media.MediaFormat;
|
||||
import android.media.MediaCodec.BufferInfo;
|
||||
import android.media.MediaCodec.CodecException;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Range;
|
||||
import android.view.SurfaceHolder;
|
||||
|
||||
@@ -410,7 +411,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
//
|
||||
if (initialException != null) {
|
||||
// This isn't the first time we've had an exception processing video
|
||||
if (System.currentTimeMillis() - initialExceptionTimestamp >= EXCEPTION_REPORT_DELAY_MS) {
|
||||
if (SystemClock.uptimeMillis() - initialExceptionTimestamp >= EXCEPTION_REPORT_DELAY_MS) {
|
||||
// It's been over 3 seconds and we're still getting exceptions. Throw the original now.
|
||||
if (!reportedCrash) {
|
||||
reportedCrash = true;
|
||||
@@ -427,7 +428,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
else {
|
||||
initialException = new RendererException(this, e);
|
||||
}
|
||||
initialExceptionTimestamp = System.currentTimeMillis();
|
||||
initialExceptionTimestamp = SystemClock.uptimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -637,7 +638,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
}
|
||||
|
||||
if (lastFrameNumber == 0) {
|
||||
activeWindowVideoStats.measurementStartTimestamp = System.currentTimeMillis();
|
||||
activeWindowVideoStats.measurementStartTimestamp = SystemClock.uptimeMillis();
|
||||
} else if (frameNumber != lastFrameNumber && frameNumber != lastFrameNumber + 1) {
|
||||
// We can receive the same "frame" multiple times if it's an IDR frame.
|
||||
// In that case, each frame start NALU is submitted independently.
|
||||
@@ -649,7 +650,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
lastFrameNumber = frameNumber;
|
||||
|
||||
// Flip stats windows roughly every second
|
||||
if (System.currentTimeMillis() >= activeWindowVideoStats.measurementStartTimestamp + 1000) {
|
||||
if (SystemClock.uptimeMillis() >= activeWindowVideoStats.measurementStartTimestamp + 1000) {
|
||||
if (prefs.enablePerfOverlay) {
|
||||
VideoStats lastTwo = new VideoStats();
|
||||
lastTwo.add(lastWindowVideoStats);
|
||||
@@ -682,7 +683,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
globalVideoStats.add(activeWindowVideoStats);
|
||||
lastWindowVideoStats.copy(activeWindowVideoStats);
|
||||
activeWindowVideoStats.clear();
|
||||
activeWindowVideoStats.measurementStartTimestamp = System.currentTimeMillis();
|
||||
activeWindowVideoStats.measurementStartTimestamp = SystemClock.uptimeMillis();
|
||||
}
|
||||
|
||||
activeWindowVideoStats.totalFramesReceived++;
|
||||
|
||||
@@ -153,9 +153,15 @@ public class MediaCodecHelper {
|
||||
whitelistedHevcDecoders.add("omx.mtk");
|
||||
}
|
||||
|
||||
// Amlogic requires 1 reference frame for HEVC to avoid hanging. Since it's been years
|
||||
// since GFE added support for maxNumReferenceFrames, we'll just enable all Amlogic SoCs
|
||||
// running Android 9 or later. HEVC is much lower latency than H.264 on Sabrina (S905X2).
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
whitelistedHevcDecoders.add("omx.amlogic");
|
||||
}
|
||||
|
||||
// These theoretically have good HEVC decoding capabilities (potentially better than
|
||||
// their AVC decoders), but haven't been tested enough
|
||||
//whitelistedHevcDecoders.add("omx.amlogic");
|
||||
//whitelistedHevcDecoders.add("omx.rk");
|
||||
|
||||
// Let's see if HEVC decoders are finally stable with C2
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.limelight.binding.video;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
class VideoStats {
|
||||
|
||||
long decoderTimeMs;
|
||||
@@ -24,7 +26,7 @@ class VideoStats {
|
||||
this.measurementStartTimestamp = other.measurementStartTimestamp;
|
||||
}
|
||||
|
||||
assert other.measurementStartTimestamp <= this.measurementStartTimestamp;
|
||||
assert other.measurementStartTimestamp >= this.measurementStartTimestamp;
|
||||
}
|
||||
|
||||
void copy(VideoStats other) {
|
||||
@@ -50,7 +52,7 @@ class VideoStats {
|
||||
}
|
||||
|
||||
VideoStatsFps getFps() {
|
||||
float elapsed = (System.currentTimeMillis() - this.measurementStartTimestamp) / (float) 1000;
|
||||
float elapsed = (SystemClock.uptimeMillis() - this.measurementStartTimestamp) / (float) 1000;
|
||||
|
||||
VideoStatsFps fps = new VideoStatsFps();
|
||||
if (elapsed > 0) {
|
||||
|
||||
@@ -4,8 +4,10 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -38,6 +40,7 @@ import android.net.NetworkCapabilities;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
@@ -134,6 +137,18 @@ public class ComputerManagerService extends Service {
|
||||
dbManager.updateComputer(existingComputer);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
// If the active address is a site-local address (RFC 1918),
|
||||
// then use STUN to populate the external address field if
|
||||
// it's not set already.
|
||||
if (details.remoteAddress == null) {
|
||||
InetAddress addr = InetAddress.getByName(details.activeAddress);
|
||||
if (addr.isSiteLocalAddress()) {
|
||||
populateExternalAddress(details);
|
||||
}
|
||||
}
|
||||
} catch (UnknownHostException ignored) {}
|
||||
|
||||
dbManager.updateComputer(details);
|
||||
}
|
||||
}
|
||||
@@ -162,7 +177,7 @@ public class ComputerManagerService extends Service {
|
||||
LimeLog.warning(tuple.computer.name + " is offline (try " + offlineCount + ")");
|
||||
offlineCount++;
|
||||
} else {
|
||||
tuple.lastSuccessfulPollMs = System.currentTimeMillis();
|
||||
tuple.lastSuccessfulPollMs = SystemClock.elapsedRealtime();
|
||||
offlineCount = 0;
|
||||
}
|
||||
}
|
||||
@@ -193,7 +208,7 @@ public class ComputerManagerService extends Service {
|
||||
synchronized (pollingTuples) {
|
||||
for (PollingTuple tuple : pollingTuples) {
|
||||
// Enforce the poll data TTL
|
||||
if (System.currentTimeMillis() - tuple.lastSuccessfulPollMs > POLL_DATA_TTL_MS) {
|
||||
if (SystemClock.elapsedRealtime() - tuple.lastSuccessfulPollMs > POLL_DATA_TTL_MS) {
|
||||
LimeLog.info("Timing out polled state for "+tuple.computer.name);
|
||||
tuple.computer.state = ComputerDetails.State.UNKNOWN;
|
||||
}
|
||||
|
||||
@@ -48,19 +48,28 @@ public class AppGridAdapter extends GenericGridAdapter<AppView.AppObject> {
|
||||
updateLayoutWithPreferences(context, prefs);
|
||||
}
|
||||
|
||||
public void updateHiddenApps(Set<Integer> newHiddenAppIds) {
|
||||
public void updateHiddenApps(Set<Integer> newHiddenAppIds, boolean hideImmediately) {
|
||||
this.hiddenAppIds.clear();
|
||||
this.hiddenAppIds.addAll(newHiddenAppIds);
|
||||
|
||||
// Reconstruct the itemList with the new hidden app set
|
||||
itemList.clear();
|
||||
for (AppView.AppObject app : allApps) {
|
||||
app.isHidden = hiddenAppIds.contains(app.app.getAppId());
|
||||
if (hideImmediately) {
|
||||
// Reconstruct the itemList with the new hidden app set
|
||||
itemList.clear();
|
||||
for (AppView.AppObject app : allApps) {
|
||||
app.isHidden = hiddenAppIds.contains(app.app.getAppId());
|
||||
|
||||
if (!app.isHidden || showHiddenApps) {
|
||||
itemList.add(app);
|
||||
if (!app.isHidden || showHiddenApps) {
|
||||
itemList.add(app);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Just update the isHidden state to show the correct UI indication
|
||||
for (AppView.AppObject app : allApps) {
|
||||
app.isHidden = hiddenAppIds.contains(app.app.getAppId());
|
||||
}
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ public class MoonBridge {
|
||||
|
||||
public static final int ML_ERROR_GRACEFUL_TERMINATION = 0;
|
||||
public static final int ML_ERROR_NO_VIDEO_TRAFFIC = -100;
|
||||
public static final int ML_ERROR_NO_VIDEO_FRAME = -101;
|
||||
|
||||
public static final int ML_PORT_INDEX_TCP_47984 = 0;
|
||||
public static final int ML_PORT_INDEX_TCP_47989 = 1;
|
||||
|
||||
@@ -14,6 +14,8 @@ import android.widget.LinearLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
// Based on a Stack Overflow example: http://stackoverflow.com/questions/1974193/slider-on-my-preferencescreen
|
||||
public class SeekBarPreference extends DialogPreference
|
||||
{
|
||||
@@ -30,6 +32,8 @@ public class SeekBarPreference extends DialogPreference
|
||||
private final int maxValue;
|
||||
private final int minValue;
|
||||
private final int stepSize;
|
||||
private final int keyStepSize;
|
||||
private final int divisor;
|
||||
private int currentValue;
|
||||
|
||||
public SeekBarPreference(Context context, AttributeSet attrs) {
|
||||
@@ -59,6 +63,8 @@ public class SeekBarPreference extends DialogPreference
|
||||
maxValue = attrs.getAttributeIntValue(ANDROID_SCHEMA_URL, "max", 100);
|
||||
minValue = attrs.getAttributeIntValue(SEEKBAR_SCHEMA_URL, "min", 1);
|
||||
stepSize = attrs.getAttributeIntValue(SEEKBAR_SCHEMA_URL, "step", 1);
|
||||
divisor = attrs.getAttributeIntValue(SEEKBAR_SCHEMA_URL, "divisor", 1);
|
||||
keyStepSize = attrs.getAttributeIntValue(SEEKBAR_SCHEMA_URL, "keyStep", 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,7 +107,14 @@ public class SeekBarPreference extends DialogPreference
|
||||
return;
|
||||
}
|
||||
|
||||
String t = String.valueOf(value);
|
||||
String t;
|
||||
if (divisor != 1) {
|
||||
float floatValue = roundedValue / (float)divisor;
|
||||
t = String.format((Locale)null, "%.1f", floatValue);
|
||||
}
|
||||
else {
|
||||
t = String.valueOf(value);
|
||||
}
|
||||
valueText.setText(suffix == null ? t : t.concat(suffix.length() > 1 ? " "+suffix : suffix));
|
||||
}
|
||||
|
||||
@@ -119,6 +132,9 @@ public class SeekBarPreference extends DialogPreference
|
||||
}
|
||||
|
||||
seekBar.setMax(maxValue);
|
||||
if (keyStepSize != 0) {
|
||||
seekBar.setKeyProgressIncrement(keyStepSize);
|
||||
}
|
||||
seekBar.setProgress(currentValue);
|
||||
|
||||
return layout;
|
||||
@@ -128,6 +144,9 @@ public class SeekBarPreference extends DialogPreference
|
||||
protected void onBindDialogView(View v) {
|
||||
super.onBindDialogView(v);
|
||||
seekBar.setMax(maxValue);
|
||||
if (keyStepSize != 0) {
|
||||
seekBar.setKeyProgressIncrement(keyStepSize);
|
||||
}
|
||||
seekBar.setProgress(currentValue);
|
||||
}
|
||||
|
||||
|
||||
Submodule app/src/main/jni/moonlight-core/moonlight-common-c updated: f2c1d03d8e...4f42188c1f
@@ -121,7 +121,6 @@
|
||||
<string name="summary_fps_list">Erhöhen für einen gleichmäßigeren Video-Stream. Verringern um auf langsameren Geräten eine bessere Performance zu erzielen.</string>
|
||||
<string name="title_seekbar_bitrate">Video bitrate</string>
|
||||
<string name="summary_seekbar_bitrate">Erhöhen für einen schärferen Video-Stream. Verringern um auf langsameren Geräten eine bessere Performance zu erzielen.</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_unlock_fps">Alle Bildwiederholungsraten freigeben</string>
|
||||
<string name="summary_unlock_fps">Streaming mit 90 oder 120 FPS reduziert gegebenfalls die Latenz auf High-End Geräten, für jedoch zu Crashes oder Lag auf Geräten die dies nicht untersützen können.</string>
|
||||
<string name="title_checkbox_stretch_video">Video auf den ganzen Bildschirm ausdehnen</string>
|
||||
|
||||
@@ -88,7 +88,6 @@
|
||||
<string name="summary_resolution_list">Establecer unos valores demasiado altos puede causar lag o cierres inesperados</string>
|
||||
<string name="title_seekbar_bitrate">Seleccionar bitrate de vídeo</string>
|
||||
<string name="summary_seekbar_bitrate">Usa bitrate bajo para reducir "parpadeo". Incrementa el bitrate para mayor calidad de imagen.</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_checkbox_stretch_video">Ajustar vídeo a pantalla completa</string>
|
||||
<string name="title_checkbox_disable_warnings">Desactivar mensajes de advertencia</string>
|
||||
<string name="summary_checkbox_disable_warnings">Desactivar mensajes de advertencia en pantalla durante la transmisión</string>
|
||||
|
||||
@@ -19,6 +19,15 @@
|
||||
<string name="pcview_menu_send_wol">Envoyer la requête Wake-On-LAN</string>
|
||||
<string name="pcview_menu_delete_pc">Supprimer PC</string>
|
||||
<string name="pcview_menu_details">Voir les détails</string>
|
||||
|
||||
<!-- Network test strings -->
|
||||
<string name="nettest_title_waiting">Test de la connexion réseau</string>
|
||||
<string name="nettest_text_waiting">Moonlight teste votre connexion réseau pour déterminer si NVIDIA GameStream est bloqué.\n\nCela peut prendre quelques secondes.</string>
|
||||
<string name="nettest_title_done">Test du réseau terminé</string>
|
||||
<string name="nettest_text_success">Votre réseau ne semble pas bloquer Moonlight. Si vous avez encore de la difficulté à vous connecter, vérifiez les paramètres du pare-feu de votre PC.\n\nSi vous essayez de diffuser sur Internet, installez l\'outil d\'hébergement Internet Moonlight sur votre PC et exécutez le testeur de streaming Internet inclus pour vérifier la connexion Internet de votre PC.</string>
|
||||
<string name="nettest_text_inconclusive">Le test réseau n’a pas pu être effectué car aucun des serveurs de test de connexion Moonlight n’était accessible. Vérifiez votre connexion Internet ou réessayez plus tard.</string>
|
||||
<string name="nettest_text_failure">La connexion réseau actuelle de votre appareil semble bloquer Moonlight. Le streaming sur Internet peut ne pas fonctionner lorsqu’il est connecté à ce réseau.\n\nLes ports réseau suivants ont été bloqués:\n</string>
|
||||
<string name="nettest_text_blocked">La connexion réseau actuelle de votre appareil bloque Moonlight. Le streaming sur Internet peut ne pas fonctionner lorsqu’il est connecté à ce réseau.</string>
|
||||
|
||||
<!-- Pair messages -->
|
||||
<string name="pairing">Appariement…</string>
|
||||
@@ -122,12 +131,8 @@
|
||||
<string name="summary_fps_list">Augmenter pour un flux vidéo plus lisse. Diminution pour de meilleures performances sur les périphériques bas de gamme.</string>
|
||||
<string name="title_seekbar_bitrate">Sélectionnez le bitrate vidéo à obtenir</string>
|
||||
<string name="summary_seekbar_bitrate">Bitrate inférieur pour réduire la saccade. Augmentez le bitrate pour augmenter la qualité de l\'image.</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_unlock_fps">Débloquer tous les taux d\'images possibles</string>
|
||||
<string name="summary_unlock_fps">La diffusion en continu à 90 ou 120 FPS peut réduire la latence sur les périphériques haut de gamme, mais peut provoquer des retards ou des blocages sur les périphériques qui ne peuvent \pas le prendre en charge</string>
|
||||
<string name="title_checkbox_stretch_video">Étirez la vidéo en plein écran</string>
|
||||
<string name="title_checkbox_disable_warnings">Désactiver les messages d\'avertissement</string>
|
||||
<string name="summary_checkbox_disable_warnings">Désactiver les messages d\'avertissement de connexion à l\'écran pendant le streaming</string>
|
||||
<string name="title_checkbox_enable_pip">Activer le mode observateur dans l\'image</string>
|
||||
<string name="summary_checkbox_enable_pip">Permet de visualiser le flux (sans le contrôleur) tout en multitâche</string>
|
||||
|
||||
@@ -136,6 +141,8 @@
|
||||
<string name="summary_audio_config_list">Activer le son surround 5.1 ou 7.1 pour les systèmes home cinéma</string>
|
||||
|
||||
<string name="category_input_settings">Paramètres d\'entrée</string>
|
||||
<string name="title_checkbox_touchscreen_trackpad">Utilisez l\'écran tactile comme trackpad</string>
|
||||
<string name="summary_checkbox_touchscreen_trackpad">S\'il est activé, l\'écran tactile agit comme un trackpad. S\'il est désactivé, l\'écran tactile contrôle directement le curseur de la souris.</string>
|
||||
<string name="title_checkbox_multi_controller">Prise en charge de plusieurs contrôleurs</string>
|
||||
<string name="summary_checkbox_multi_controller">Lorsqu\'elle n\'est pas cochée, tous les contrôleurs sont regroupés</string>
|
||||
<string name="title_checkbox_vibrate_fallback">Emuler support vibration de secours</string>
|
||||
@@ -150,6 +157,8 @@
|
||||
<string name="summary_checkbox_mouse_emulation">Appuyez longuement sur le bouton Start pour faire basculer la manette de jeu en mode souris.</string>
|
||||
<string name="title_checkbox_mouse_nav_buttons">Activer les boutons de la souris arrière et avant</string>
|
||||
<string name="summary_checkbox_mouse_nav_buttons">L\' activation de cette option peut entraîner un clic droit sur certains périphériques.</string>
|
||||
<string name="title_checkbox_flip_face_buttons">Boutons de face inversé</string>
|
||||
<string name="summary_checkbox_flip_face_buttons">Commute les boutons de face A/B et X/Y pour les manettes de jeu et les commandes à l\'écran</string>
|
||||
|
||||
<string name="category_on_screen_controls_settings">Paramètres des contrôles à l\'écran</string>
|
||||
<string name="title_checkbox_show_onscreen_controls">Afficher les commandes à l\'écran</string>
|
||||
@@ -181,7 +190,10 @@
|
||||
<string name="summary_checkbox_host_audio">Lire l\'audio de l\'ordinateur et de ce périphérique</string>
|
||||
|
||||
<string name="category_advanced_settings">Réglages avancés</string>
|
||||
<string name="title_disable_frame_drop">Désactiver la suppression d\'image</string>
|
||||
<string name="title_unlock_fps">Débloquez toutes les fréquences d\'images possibles</string>
|
||||
<string name="summary_unlock_fps">Le streaming à 90 ou 120 FPS peut réduire la latence sur les appareils haut de gamme, mais peut entraîner un décalage ou une instabilité sur les appareils qui ne peuvent pas le prendre en charge</string>
|
||||
<string name="summary_checkbox_disable_warnings">Désactiver les messages d\'avertissement de connexion à l\'écran pendant la diffusion</string>
|
||||
<string name="title_disable_frame_drop">Ne jamais laisser tomber les frames</string>
|
||||
<string name="summary_disable_frame_drop">Peut réduire les micro-saccades sur certains appareils, mais peut augmenter la latence</string>
|
||||
<string name="title_video_format">Modifier les paramètres H.265</string>
|
||||
<string name="summary_video_format">H.265 réduit les besoins en bande passante vidéo mais nécessite un périphérique très récent</string>
|
||||
@@ -189,5 +201,6 @@
|
||||
<string name="summary_enable_hdr">Diffuser du HDR lorsque le jeu et le processeur graphique du PC le prennent en charge. HDR nécessite un GPU série GTX 1000 ou une version ultérieure.</string>
|
||||
<string name="title_enable_perf_overlay">Activer la superposition de performance</string>
|
||||
<string name="summary_enable_perf_overlay">Afficher une superposition à l\'écran avec des informations de performance en temps réel pendant la lecture en continu</string>
|
||||
|
||||
<string name="title_enable_post_stream_toast">Afficher le message de latence après la diffusion en continu</string>
|
||||
<string name="summary_enable_post_stream_toast">Afficher un message d’informations de latence après la fin du flux</string>
|
||||
</resources>
|
||||
|
||||
@@ -105,7 +105,6 @@
|
||||
<string name="summary_resolution_list">Valori troppo elevati possono causare lag o crash</string>
|
||||
<string name="title_seekbar_bitrate">Velocità di trasmissione video</string>
|
||||
<string name="summary_seekbar_bitrate">Abbassa la velocità di trasmissione per ridurre lo stuttering; alzala per migliorare la qualità dell\'immagine</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_checkbox_stretch_video">Forza video a schermo intero</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>
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
<string name="summary_resolution_list">品質が高いほどラグとクラッシュが発生しやすくなります</string>
|
||||
<string name="title_seekbar_bitrate">映像のビットレート</string>
|
||||
<string name="summary_seekbar_bitrate">ビットレートを低くすればカクつきが抑制され、高くすれば画質が向上します</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_checkbox_stretch_video">映像を全画面に拡大</string>
|
||||
<string name="title_checkbox_disable_warnings">警告を無効化</string>
|
||||
<string name="summary_checkbox_disable_warnings">ストリーミング中に画面に警告メッセージを表示しない</string>
|
||||
|
||||
@@ -99,7 +99,6 @@
|
||||
<string name="summary_resolution_list">세팅 값이 자신의 PC 성능보다 너무 높으면 렉이나 깨짐을 유발할 수 있습니다.</string>
|
||||
<string name="title_seekbar_bitrate">비트레이트 타겟 지정</string>
|
||||
<string name="summary_seekbar_bitrate">낮은 비트레이트는 끊김을 줄이고, 높은 비트레이트는 품질을 높입니다.</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_checkbox_stretch_video">전체 화면으로 렌더링 스크린 늘이기</string>
|
||||
<string name="title_checkbox_disable_warnings">경고 메세지 끄기</string>
|
||||
<string name="summary_checkbox_disable_warnings">화면 상의 연결 경고 메세지를 스트리밍 중에 비활성화합니다.</string>
|
||||
|
||||
@@ -88,7 +88,6 @@
|
||||
<string name="summary_resolution_list">Te hoge instellingen kunnen crashes en haperingen veroorzaken.</string>
|
||||
<string name="title_seekbar_bitrate">Selecteer doel video bitsnelheid</string>
|
||||
<string name="summary_seekbar_bitrate">Verlaag bitsnelheid om haperingen te verminderen. Verhoog de bitsnelheid voor een betere videokwaliteit.</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_checkbox_stretch_video">Rek video uit tot volledig scherm</string>
|
||||
<string name="title_checkbox_disable_warnings">Verberg waarschuwingsberichten</string>
|
||||
<string name="summary_checkbox_disable_warnings">Verberg on-screen verbindingswaarschuwingen tijdens het streamen</string>
|
||||
|
||||
@@ -120,7 +120,6 @@
|
||||
<string name="summary_fps_list">Crește-o pentru a îmbunătăți fluiditatea imaginilor. Descrește-o pentru dispozitive neperformante sau conexiune slabă.</string>
|
||||
<string name="title_seekbar_bitrate">Rata de biți</string>
|
||||
<string name="summary_seekbar_bitrate">Crește-o pentru a îmbunătăți calitatea imaginilor. Descrește-o pentru dispozitive neperformante sau conexiune slabă.</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_unlock_fps">Deblochează toate ratele de cadre posibile</string>
|
||||
<string name="summary_unlock_fps">Fluxul video de rate mai mari poate reduce latența folosind dispozitive performante, dar poate introduce erori daca nu sunt suportate.</string>
|
||||
<string name="title_checkbox_stretch_video">Întindeți video pe ecranul complet</string>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="audio_config_names">
|
||||
<item>Стерео</item>
|
||||
<item>5.1 Объёмный звук</item>
|
||||
<item>7.1 Объёмный звук</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="decoder_names">
|
||||
<item>Автоматический выбор декодера</item>
|
||||
<item>Принудительное программное декодирование</item>
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
<string name="pcview_menu_send_wol">Отправить Wake-On-LAN запрос</string>
|
||||
<string name="pcview_menu_delete_pc">Удалить PC</string>
|
||||
|
||||
<!-- Network test strings -->
|
||||
<string name="nettest_title_waiting">Тестирование Сетевого Подключения</string>
|
||||
<string name="nettest_text_waiting">Moonlight тестирует ваше сетевое подключение, чтобы определить, заблокирован ли NVIDIA GameStream.\n\nЭто может занять некоторое время…</string>
|
||||
<string name="nettest_title_done">Тестирование Подключения Завершено</string>
|
||||
<string name="nettest_text_success">Ваша сеть не блокирует Moonlight. Если у вас всё ещё есть проблемы с соединением, проверьте настройки брандмауэра на компьютере.\n\nЕсли вы пытаетесь транслировать через интернет, установите Moonlight Internet Hosting Tool на ваш компьютер и запустите установленный Internet Streaming Tester, чтобы проверить Интернет-соединение на вашем компьютере.</string>
|
||||
<string name="nettest_text_inconclusive">Тестирование подключения не может быть выполнено, потому что сервера тестирования подключения Moonlight не доступны. Проверьте ваше Интернет-соединение или повторите попытку позже.</string>
|
||||
<string name="nettest_text_failure">Похоже, что текущее сетевое подключение вашего устройства блокирует Moonlight. Трансляция через Интернет может не работать при подключении к этой сети.\n\nСледующие сетевые порты были заблокированы:\n</string>
|
||||
|
||||
<!-- Pair messages -->
|
||||
<string name="pairing">Создание пары…</string>
|
||||
<string name="pair_pc_offline">Компьютер выключен или находится не в сети</string>
|
||||
@@ -90,12 +98,13 @@
|
||||
<string name="summary_resolution_list">Выбор слишком высокого значеня для своего устройства может вызвать тормоза или вылеты</string>
|
||||
<string name="title_seekbar_bitrate">Выберите битрейт видео</string>
|
||||
<string name="summary_seekbar_bitrate">Низкий битрейт уменьшит зависания. Увеличение битрейта улучшит качество изображения.</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_checkbox_stretch_video">Растягивать видео на весь экран</string>
|
||||
<string name="title_checkbox_disable_warnings">Отключить сообщения с предупреждениями</string>
|
||||
<string name="summary_checkbox_disable_warnings">Выключить экранные предупреждения о соединении во время трансляции</string>
|
||||
|
||||
<string name="category_audio_settings">Аудио Настройки</string>
|
||||
<string name="title_audio_config_list">Настройка объёмного звука</string>
|
||||
<string name="summary_audio_config_list">Включить объёмный звук 5.1 или 7.1 для систем домашнего кинотеатра</string>
|
||||
|
||||
<string name="title_checkbox_multi_controller">Поддержка нескольких контроллеров</string>
|
||||
<string name="summary_checkbox_multi_controller">Когда отключена, все контроллеры определяются как один</string>
|
||||
@@ -103,6 +112,8 @@
|
||||
<string name="suffix_seekbar_deadzone">%</string>
|
||||
<string name="title_checkbox_xb1_driver">Драйвер контроллеров Xbox 360/One</string>
|
||||
<string name="summary_checkbox_xb1_driver">Включить встроенный USB драйвер для устройств без собственной поддержки контроллеров Xbox</string>
|
||||
<string name="title_checkbox_flip_face_buttons">Перевернуть кнопки A/B и X/Y</string>
|
||||
<string name="summary_checkbox_flip_face_buttons">Меняет местами кнопки A/B и X/Y на геймпадах и экранных кнопках</string>
|
||||
|
||||
<string name="category_ui_settings">Настройки Интерфейса</string>
|
||||
<string name="title_language_list">Язык</string>
|
||||
@@ -124,6 +135,8 @@
|
||||
<string name="summary_checkbox_show_onscreen_controls">Отображать оверлей виртуального контроллера на сенсорном экране</string>
|
||||
<string name="title_only_l3r3">Показывать только L3 и R3</string>
|
||||
<string name="summary_only_l3r3">Скрывать все экранные кнопки кроме L3 и R3</string>
|
||||
<string name="summary_osc_opacity">Сделать экранные кнопки более/менее прозрачными</string>
|
||||
<string name="dialog_title_osc_opacity">Изменить прозрачность</string>
|
||||
<string name="scut_deleted_pc">PC удален</string>
|
||||
<string name="scut_not_paired">PC не сопряжен</string>
|
||||
<string name="help_loading_title">Просмотр Помощи</string>
|
||||
@@ -152,12 +165,16 @@
|
||||
<string name="summary_disable_frame_drop">Может уменьшить микрозависания на некоторых устройствах, но также увеличить задержку</string>
|
||||
<string name="title_enable_hdr">Включить HDR (Экспериментально)</string>
|
||||
<string name="summary_enable_hdr">Транслировать в HDR если игра и GPU компьютера поддерживают это. HDR требует видеокарты GTX 1000 серии или более новой.</string>
|
||||
<string name="title_enable_post_stream_toast">Показывать отчёт о задержке после трансляции</string>
|
||||
<string name="summary_enable_post_stream_toast">Отобразить сообщение с информацией о задержке после окончания трансляции.</string>
|
||||
|
||||
<string name="title_checkbox_vibrate_osc">Включить вибрацию</string>
|
||||
<string name="title_fps_list">Частота кадров</string>
|
||||
<string name="applist_menu_details">Детали</string>
|
||||
<string name="applist_menu_scut">Создать ярлык</string>
|
||||
<string name="category_input_settings">Настройки ввода</string>
|
||||
<string name="title_checkbox_touchscreen_trackpad">Использовать сенсор как тачпад</string>
|
||||
<string name="summary_checkbox_touchscreen_trackpad">Если включено, сенсор выступает в роли тачпада. Если отключено, сенсор напрямую контролирует курсор мыши.</string>
|
||||
<string name="delete_pc_msg">Вы уверены что хотите удалить этот PC?</string>
|
||||
<string name="pcview_menu_details">Детали</string>
|
||||
<string name="poor_connection_msg">Слабое соединение с PC</string>
|
||||
|
||||
@@ -90,7 +90,6 @@
|
||||
<string name="summary_resolution_list">Вибір занадто високого значеня для свого пристрою може викликати гальма або вильоти</string>
|
||||
<string name="title_seekbar_bitrate">Виберіть бітрейт відео</string>
|
||||
<string name="summary_seekbar_bitrate">Низький бітрейт зменшить зависання. Збільшення бітрейта поліпшить якість зображення.</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_checkbox_stretch_video">Розтягувати відео на весь екран</string>
|
||||
<string name="title_checkbox_disable_warnings">Відключити повідомлення з попередженнями</string>
|
||||
<string name="summary_checkbox_disable_warnings">Вимкнути екранні попередження про з\'єднання під час трансляції</string>
|
||||
|
||||
@@ -122,7 +122,6 @@
|
||||
<string name="summary_fps_list"> 高帧数提升视频流流畅度。 \n 低帧数提升在低端设备中的串流体验。</string>
|
||||
<string name="title_seekbar_bitrate"> 视频码率 </string>
|
||||
<string name="summary_seekbar_bitrate"> 高码率提升图像质量。 \n 低码率提升在较慢网络中的串流体验。 </string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_unlock_fps"> 解锁所有可用帧数 </string>
|
||||
<string name="summary_unlock_fps"> 以90或120帧串流可能会减少在高端设备上的网络延迟,但会在不支持的设备上造成卡顿或崩溃。 </string>
|
||||
<string name="title_checkbox_stretch_video"> 将画面拉伸至全屏 </string>
|
||||
|
||||
@@ -122,7 +122,6 @@
|
||||
<string name="summary_fps_list"> 高幀數提升視頻流流暢度。 \n 低幀數提升在低端設備中的串流體驗。</string>
|
||||
<string name="title_seekbar_bitrate"> 視頻碼率 </string>
|
||||
<string name="summary_seekbar_bitrate"> 高碼率提升圖像品質。 \n 低碼率提升在較慢網路中的串流體驗。 </string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="title_unlock_fps"> 解鎖所有可用幀數 </string>
|
||||
<string name="summary_unlock_fps"> 以90或120幀串流可能會減少在高端設備上的網路延遲,但會在不支援的設備上造成卡頓或崩潰。 </string>
|
||||
<string name="title_checkbox_stretch_video"> 將畫面拉伸至全屏 </string>
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
<string name="unable_to_pin_shortcut">Your current launcher does not allow for creating pinned shortcuts.</string>
|
||||
<string name="video_decoder_init_failed">Video decoder failed to initialize. Your device may not support the selected resolution or frame rate.</string>
|
||||
<string name="no_video_received_error">No video received from host. Check the host PC\'s firewall and port forwarding rules.</string>
|
||||
<string name="no_frame_received_error">Your network connection isn\'t performing well. Reduce your video bitrate setting or try a faster connection.</string>
|
||||
|
||||
<!-- Start application messages -->
|
||||
<string name="conn_establishing_title">Establishing Connection</string>
|
||||
@@ -138,7 +139,7 @@
|
||||
<string name="summary_fps_list">Increase for a smoother video stream. Decrease for better performance on lower end devices.</string>
|
||||
<string name="title_seekbar_bitrate">Video bitrate</string>
|
||||
<string name="summary_seekbar_bitrate">Increase for better image quality. Decrease to improve performance on slower connections.</string>
|
||||
<string name="suffix_seekbar_bitrate">Kbps</string>
|
||||
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
|
||||
<string name="title_checkbox_stretch_video">Stretch video to full-screen</string>
|
||||
|
||||
<string name="category_audio_settings">Audio Settings</string>
|
||||
|
||||
@@ -22,10 +22,12 @@
|
||||
android:key="seekbar_bitrate_kbps"
|
||||
android:dialogMessage="@string/summary_seekbar_bitrate"
|
||||
seekbar:min="500"
|
||||
android:max="150000"
|
||||
seekbar:step="500"
|
||||
android:max="100000"
|
||||
seekbar:keyStep="1000"
|
||||
seekbar:divisor="1000"
|
||||
android:summary="@string/summary_seekbar_bitrate"
|
||||
android:text="@string/suffix_seekbar_bitrate"
|
||||
android:text="@string/suffix_seekbar_bitrate_mbps"
|
||||
android:title="@string/title_seekbar_bitrate" />
|
||||
<CheckBoxPreference
|
||||
android:key="checkbox_stretch_video"
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ buildscript {
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
- Hiding games now only takes effect after returning to the app list
|
||||
- Display a warning if the connection is too unstable to stream
|
||||
- Increase maximum bitrate to 150 Mbps for Ethernet-connected devices
|
||||
- Update Russian and French translations
|
||||
@@ -0,0 +1 @@
|
||||
- Improved connection reliability
|
||||
@@ -0,0 +1 @@
|
||||
- Improved performance on Google TV Chromecast and other newer Amlogic devices by using HEVC by default
|
||||
@@ -0,0 +1,3 @@
|
||||
- Gamepad button combos to emulate missing Select and Guide buttons have been reintroduced
|
||||
- For gamepads without a Select button, LB+Start will trigger the Select button and RB+Start will trigger the Guide button
|
||||
- For gamepads with a Select button, Start+Select will trigger the Guide button
|
||||
@@ -0,0 +1 @@
|
||||
- Enabled raw mouse input on the Nvidia Shield TV to avoid mouse acceleration
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
#Thu May 28 11:41:09 PDT 2020
|
||||
#Mon Oct 12 13:42:18 CDT 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
||||
|
||||
Reference in New Issue
Block a user