mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-10-23 08:30:32 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abc4123c52 | ||
|
|
26f8c0842e | ||
|
|
d430d83ba8 | ||
|
|
a52f189fb1 | ||
|
|
dc1045b69e | ||
|
|
3a89dbf4ab | ||
|
|
d69b4eca1e | ||
|
|
568bba82f0 | ||
|
|
b52e6c88ec | ||
|
|
720595091e | ||
|
|
fe929c8e58 | ||
|
|
9ecec1eb3c |
No files matched your search
+3
-3
@@ -11,8 +11,8 @@ android {
|
|||||||
minSdk 16
|
minSdk 16
|
||||||
targetSdk 34
|
targetSdk 34
|
||||||
|
|
||||||
versionName "12.0"
|
versionName "12.0.1"
|
||||||
versionCode = 311
|
versionCode = 312
|
||||||
|
|
||||||
// Generate native debug symbols to allow Google Play to symbolicate our native crashes
|
// Generate native debug symbols to allow Google Play to symbolicate our native crashes
|
||||||
ndk.debugSymbolLevel = 'FULL'
|
ndk.debugSymbolLevel = 'FULL'
|
||||||
@@ -143,5 +143,5 @@ dependencies {
|
|||||||
implementation 'com.squareup.okio:okio:1.17.5'
|
implementation 'com.squareup.okio:okio:1.17.5'
|
||||||
// 3.5.8 requires minSdk 19, uses StandardCharsets.UTF_8 internally
|
// 3.5.8 requires minSdk 19, uses StandardCharsets.UTF_8 internally
|
||||||
implementation 'org.jmdns:jmdns:3.5.7'
|
implementation 'org.jmdns:jmdns:3.5.7'
|
||||||
implementation 'com.github.cgutman:ShieldControllerExtensions:1.0'
|
implementation 'com.github.cgutman:ShieldControllerExtensions:1.0.1'
|
||||||
}
|
}
|
||||||
@@ -486,7 +486,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
.setMaxPacketSize(1392)
|
.setMaxPacketSize(1392)
|
||||||
.setRemoteConfiguration(StreamConfiguration.STREAM_CFG_AUTO) // NvConnection will perform LAN and VPN detection
|
.setRemoteConfiguration(StreamConfiguration.STREAM_CFG_AUTO) // NvConnection will perform LAN and VPN detection
|
||||||
.setHevcBitratePercentageMultiplier(75)
|
.setHevcBitratePercentageMultiplier(75)
|
||||||
.setAv1BitratePercentageMultiplier(60)
|
.setAv1BitratePercentageMultiplier(75)
|
||||||
.setSupportedVideoFormats(supportedVideoFormats)
|
.setSupportedVideoFormats(supportedVideoFormats)
|
||||||
.setAttachedGamepadMask(gamepadMask)
|
.setAttachedGamepadMask(gamepadMask)
|
||||||
.setClientRefreshRateX100((int)(displayRefreshRate * 100))
|
.setClientRefreshRateX100((int)(displayRefreshRate * 100))
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
|
|
||||||
private static final int EMULATING_SPECIAL = 0x1;
|
private static final int EMULATING_SPECIAL = 0x1;
|
||||||
private static final int EMULATING_SELECT = 0x2;
|
private static final int EMULATING_SELECT = 0x2;
|
||||||
|
private static final int EMULATING_TOUCHPAD = 0x4;
|
||||||
|
|
||||||
private static final short MAX_GAMEPADS = 16; // Limited by bits in activeGamepadMask
|
private static final short MAX_GAMEPADS = 16; // Limited by bits in activeGamepadMask
|
||||||
|
|
||||||
@@ -2494,6 +2495,19 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if we're emulating the touchpad button
|
||||||
|
if ((context.emulatingButtonFlags & ControllerHandler.EMULATING_TOUCHPAD) != 0)
|
||||||
|
{
|
||||||
|
// If either select or LB is up, touchpad comes up too
|
||||||
|
if ((context.inputMap & ControllerPacket.BACK_FLAG) == 0 ||
|
||||||
|
(context.inputMap & ControllerPacket.LB_FLAG) == 0)
|
||||||
|
{
|
||||||
|
context.inputMap &= ~ControllerPacket.TOUCHPAD_FLAG;
|
||||||
|
|
||||||
|
context.emulatingButtonFlags &= ~ControllerHandler.EMULATING_TOUCHPAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sendControllerInputPacket(context);
|
sendControllerInputPacket(context);
|
||||||
|
|
||||||
if (context.pendingExit && context.inputMap == 0) {
|
if (context.pendingExit && context.inputMap == 0) {
|
||||||
@@ -2685,6 +2699,18 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
context.emulatingButtonFlags |= ControllerHandler.EMULATING_SELECT;
|
context.emulatingButtonFlags |= ControllerHandler.EMULATING_SELECT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (context.needsClickpadEmulation) {
|
||||||
|
// Select+LB acts like the clickpad when we're faking a PS4 controller for motion support
|
||||||
|
if (context.inputMap == (ControllerPacket.BACK_FLAG | ControllerPacket.LB_FLAG) ||
|
||||||
|
(context.inputMap == ControllerPacket.BACK_FLAG &&
|
||||||
|
event.getEventTime() - context.lastLbUpTime <= MAXIMUM_BUMPER_UP_DELAY_MS))
|
||||||
|
{
|
||||||
|
context.inputMap &= ~(ControllerPacket.BACK_FLAG | ControllerPacket.LB_FLAG);
|
||||||
|
context.inputMap |= ControllerPacket.TOUCHPAD_FLAG;
|
||||||
|
|
||||||
|
context.emulatingButtonFlags |= ControllerHandler.EMULATING_TOUCHPAD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If there is a physical select button, we'll use Start+Select as the special button combo
|
// If there is a physical select button, we'll use Start+Select as the special button combo
|
||||||
// otherwise we'll use Start+RB.
|
// otherwise we'll use Start+RB.
|
||||||
@@ -2914,6 +2940,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
public boolean hasMode;
|
public boolean hasMode;
|
||||||
public boolean hasPaddles;
|
public boolean hasPaddles;
|
||||||
public boolean hasShare;
|
public boolean hasShare;
|
||||||
|
public boolean needsClickpadEmulation;
|
||||||
|
|
||||||
// Used for OUYA bumper state tracking since they force all buttons
|
// 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
|
// up when the OUYA button goes down. We watch the last time we get
|
||||||
@@ -2984,7 +3011,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte type = MoonBridge.LI_CTYPE_UNKNOWN;
|
byte type;
|
||||||
switch (inputDevice.getVendorId()) {
|
switch (inputDevice.getVendorId()) {
|
||||||
case 0x045e: // Microsoft
|
case 0x045e: // Microsoft
|
||||||
type = MoonBridge.LI_CTYPE_XBOX;
|
type = MoonBridge.LI_CTYPE_XBOX;
|
||||||
@@ -3067,10 +3094,18 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
capabilities |= MoonBridge.LI_CCAP_GYRO;
|
capabilities |= MoonBridge.LI_CCAP_GYRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override the detected controller type if we're emulating motion sensors on an Xbox controller
|
byte reportedType;
|
||||||
if (type != MoonBridge.LI_CTYPE_PS && sensorManager != null) {
|
if (type != MoonBridge.LI_CTYPE_PS && sensorManager != null) {
|
||||||
|
// Override the detected controller type if we're emulating motion sensors on an Xbox controller
|
||||||
Toast.makeText(activityContext, activityContext.getResources().getText(R.string.toast_controller_type_changed), Toast.LENGTH_LONG).show();
|
Toast.makeText(activityContext, activityContext.getResources().getText(R.string.toast_controller_type_changed), Toast.LENGTH_LONG).show();
|
||||||
type = MoonBridge.LI_CTYPE_UNKNOWN;
|
reportedType = MoonBridge.LI_CTYPE_UNKNOWN;
|
||||||
|
|
||||||
|
// Remember that we should enable the clickpad emulation combo (Select+LB) for this device
|
||||||
|
needsClickpadEmulation = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Report the true type to the host PC if we're not emulating motion sensors
|
||||||
|
reportedType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can perform basic rumble with any vibrator
|
// We can perform basic rumble with any vibrator
|
||||||
@@ -3093,7 +3128,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
}
|
}
|
||||||
|
|
||||||
conn.sendControllerArrivalEvent((byte)controllerNumber, getActiveControllerMask(),
|
conn.sendControllerArrivalEvent((byte)controllerNumber, getActiveControllerMask(),
|
||||||
type, supportedButtonFlags, capabilities);
|
reportedType, supportedButtonFlags, capabilities);
|
||||||
|
|
||||||
// After reporting arrival to the host, send initial battery state and begin monitoring
|
// After reporting arrival to the host, send initial battery state and begin monitoring
|
||||||
backgroundThreadHandler.post(batteryStateUpdateRunnable);
|
backgroundThreadHandler.post(batteryStateUpdateRunnable);
|
||||||
@@ -3123,6 +3158,9 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
|||||||
this.sensorManager = deviceSensorManager;
|
this.sensorManager = deviceSensorManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy state initialized in reportControllerArrival()
|
||||||
|
this.needsClickpadEmulation = oldContext.needsClickpadEmulation;
|
||||||
|
|
||||||
// Re-enable sensors on the new context
|
// Re-enable sensors on the new context
|
||||||
enableSensors();
|
enableSensors();
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.limelight.binding.video;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
@@ -48,11 +49,10 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
private MediaCodecInfo hevcDecoder;
|
private MediaCodecInfo hevcDecoder;
|
||||||
private MediaCodecInfo av1Decoder;
|
private MediaCodecInfo av1Decoder;
|
||||||
|
|
||||||
private byte[] vpsBuffer;
|
private final ArrayList<byte[]> vpsBuffers = new ArrayList<>();
|
||||||
private byte[] spsBuffer;
|
private final ArrayList<byte[]> spsBuffers = new ArrayList<>();
|
||||||
private byte[] ppsBuffer;
|
private final ArrayList<byte[]> ppsBuffers = new ArrayList<>();
|
||||||
private boolean submittedCsd;
|
private boolean submittedCsd;
|
||||||
private boolean submitCsdNextCall;
|
|
||||||
private byte[] currentHdrMetadata;
|
private byte[] currentHdrMetadata;
|
||||||
|
|
||||||
private int nextInputBufferIndex = -1;
|
private int nextInputBufferIndex = -1;
|
||||||
@@ -544,10 +544,9 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
|
|
||||||
// After reconfiguration, we must resubmit CSD buffers
|
// After reconfiguration, we must resubmit CSD buffers
|
||||||
submittedCsd = false;
|
submittedCsd = false;
|
||||||
submitCsdNextCall = false;
|
vpsBuffers.clear();
|
||||||
vpsBuffer = null;
|
spsBuffers.clear();
|
||||||
spsBuffer = null;
|
ppsBuffers.clear();
|
||||||
ppsBuffer = null;
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
// This will contain the actual accepted input format attributes
|
// This will contain the actual accepted input format attributes
|
||||||
@@ -1414,6 +1413,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
activeWindowVideoStats.frameLossEvents++;
|
activeWindowVideoStats.frameLossEvents++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset CSD data for each IDR frame
|
||||||
|
if (lastFrameNumber != frameNumber && frameType == MoonBridge.FRAME_TYPE_IDR) {
|
||||||
|
vpsBuffers.clear();
|
||||||
|
spsBuffers.clear();
|
||||||
|
ppsBuffers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
lastFrameNumber = frameNumber;
|
lastFrameNumber = frameNumber;
|
||||||
|
|
||||||
// Flip stats windows roughly every second
|
// Flip stats windows roughly every second
|
||||||
@@ -1462,250 +1468,270 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
activeWindowVideoStats.measurementStartTimestamp = SystemClock.uptimeMillis();
|
activeWindowVideoStats.measurementStartTimestamp = SystemClock.uptimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
long timestampUs;
|
boolean csdSubmittedForThisFrame = false;
|
||||||
int codecFlags = 0;
|
|
||||||
|
|
||||||
// H264 SPS
|
// IDR frames require special handling for CSD buffer submission
|
||||||
if (decodeUnitType == MoonBridge.BUFFER_TYPE_SPS && (videoFormat & MoonBridge.VIDEO_FORMAT_MASK_H264) != 0) {
|
if (frameType == MoonBridge.FRAME_TYPE_IDR) {
|
||||||
numSpsIn++;
|
// H264 SPS
|
||||||
|
if (decodeUnitType == MoonBridge.BUFFER_TYPE_SPS && (videoFormat & MoonBridge.VIDEO_FORMAT_MASK_H264) != 0) {
|
||||||
|
numSpsIn++;
|
||||||
|
|
||||||
ByteBuffer spsBuf = ByteBuffer.wrap(decodeUnitData);
|
ByteBuffer spsBuf = ByteBuffer.wrap(decodeUnitData);
|
||||||
int startSeqLen = decodeUnitData[2] == 0x01 ? 3 : 4;
|
int startSeqLen = decodeUnitData[2] == 0x01 ? 3 : 4;
|
||||||
|
|
||||||
// Skip to the start of the NALU data
|
// Skip to the start of the NALU data
|
||||||
spsBuf.position(startSeqLen + 1);
|
spsBuf.position(startSeqLen + 1);
|
||||||
|
|
||||||
// The H264Utils.readSPS function safely handles
|
// The H264Utils.readSPS function safely handles
|
||||||
// Annex B NALUs (including NALUs with escape sequences)
|
// Annex B NALUs (including NALUs with escape sequences)
|
||||||
SeqParameterSet sps = H264Utils.readSPS(spsBuf);
|
SeqParameterSet sps = H264Utils.readSPS(spsBuf);
|
||||||
|
|
||||||
// Some decoders rely on H264 level to decide how many buffers are needed
|
// 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
|
// Since we only need one frame buffered, we'll set the level as low as we can
|
||||||
// for known resolution combinations. Reference frame invalidation may need
|
// for known resolution combinations. Reference frame invalidation may need
|
||||||
// these, so leave them be for those decoders.
|
// these, so leave them be for those decoders.
|
||||||
if (!refFrameInvalidationActive) {
|
if (!refFrameInvalidationActive) {
|
||||||
if (initialWidth <= 720 && initialHeight <= 480 && refreshRate <= 60) {
|
if (initialWidth <= 720 && initialHeight <= 480 && refreshRate <= 60) {
|
||||||
// Max 5 buffered frames at 720x480x60
|
// Max 5 buffered frames at 720x480x60
|
||||||
LimeLog.info("Patching level_idc to 31");
|
LimeLog.info("Patching level_idc to 31");
|
||||||
sps.levelIdc = 31;
|
sps.levelIdc = 31;
|
||||||
}
|
}
|
||||||
else if (initialWidth <= 1280 && initialHeight <= 720 && refreshRate <= 60) {
|
else if (initialWidth <= 1280 && initialHeight <= 720 && refreshRate <= 60) {
|
||||||
// Max 5 buffered frames at 1280x720x60
|
// Max 5 buffered frames at 1280x720x60
|
||||||
LimeLog.info("Patching level_idc to 32");
|
LimeLog.info("Patching level_idc to 32");
|
||||||
sps.levelIdc = 32;
|
sps.levelIdc = 32;
|
||||||
}
|
}
|
||||||
else if (initialWidth <= 1920 && initialHeight <= 1080 && refreshRate <= 60) {
|
else if (initialWidth <= 1920 && initialHeight <= 1080 && refreshRate <= 60) {
|
||||||
// Max 4 buffered frames at 1920x1080x64
|
// Max 4 buffered frames at 1920x1080x64
|
||||||
LimeLog.info("Patching level_idc to 42");
|
LimeLog.info("Patching level_idc to 42");
|
||||||
sps.levelIdc = 42;
|
sps.levelIdc = 42;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Leave the profile alone (currently 5.0)
|
// Leave the profile alone (currently 5.0)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TI OMAP4 requires a reference frame count of 1 to decode successfully. Exynos 4
|
|
||||||
// also requires this fixup.
|
|
||||||
//
|
|
||||||
// I'm doing this fixup for all devices because I haven't seen any devices that
|
|
||||||
// this causes issues for. At worst, it seems to do nothing and at best it fixes
|
|
||||||
// issues with video lag, hangs, and crashes.
|
|
||||||
//
|
|
||||||
// It does break reference frame invalidation, so we will not do that for decoders
|
|
||||||
// where we've enabled reference frame invalidation.
|
|
||||||
if (!refFrameInvalidationActive) {
|
|
||||||
LimeLog.info("Patching num_ref_frames in SPS");
|
|
||||||
sps.numRefFrames = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GFE 2.5.11 changed the SPS to add additional extensions. Some devices don't like these
|
|
||||||
// so we remove them here on old devices unless these devices also support HEVC.
|
|
||||||
// See getPreferredColorSpace() for further information.
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O &&
|
|
||||||
sps.vuiParams != null &&
|
|
||||||
hevcDecoder == null &&
|
|
||||||
av1Decoder == null) {
|
|
||||||
sps.vuiParams.videoSignalTypePresentFlag = false;
|
|
||||||
sps.vuiParams.colourDescriptionPresentFlag = false;
|
|
||||||
sps.vuiParams.chromaLocInfoPresentFlag = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some older devices used to choke on a bitstream restrictions, so we won't provide them
|
|
||||||
// unless explicitly whitelisted. For newer devices, leave the bitstream restrictions present.
|
|
||||||
if (needsSpsBitstreamFixup || isExynos4 || Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
// The SPS that comes in the current H264 bytestream doesn't set bitstream_restriction_flag
|
|
||||||
// or max_dec_frame_buffering which increases decoding latency on Tegra.
|
|
||||||
|
|
||||||
// If the encoder didn't include VUI parameters in the SPS, add them now
|
|
||||||
if (sps.vuiParams == null) {
|
|
||||||
LimeLog.info("Adding VUI parameters");
|
|
||||||
sps.vuiParams = new VUIParameters();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GFE 2.5.11 started sending bitstream restrictions
|
// TI OMAP4 requires a reference frame count of 1 to decode successfully. Exynos 4
|
||||||
if (sps.vuiParams.bitstreamRestriction == null) {
|
// also requires this fixup.
|
||||||
LimeLog.info("Adding bitstream restrictions");
|
//
|
||||||
sps.vuiParams.bitstreamRestriction = new VUIParameters.BitstreamRestriction();
|
// I'm doing this fixup for all devices because I haven't seen any devices that
|
||||||
sps.vuiParams.bitstreamRestriction.motionVectorsOverPicBoundariesFlag = true;
|
// this causes issues for. At worst, it seems to do nothing and at best it fixes
|
||||||
sps.vuiParams.bitstreamRestriction.maxBytesPerPicDenom = 2;
|
// issues with video lag, hangs, and crashes.
|
||||||
sps.vuiParams.bitstreamRestriction.maxBitsPerMbDenom = 1;
|
//
|
||||||
sps.vuiParams.bitstreamRestriction.log2MaxMvLengthHorizontal = 16;
|
// It does break reference frame invalidation, so we will not do that for decoders
|
||||||
sps.vuiParams.bitstreamRestriction.log2MaxMvLengthVertical = 16;
|
// where we've enabled reference frame invalidation.
|
||||||
sps.vuiParams.bitstreamRestriction.numReorderFrames = 0;
|
if (!refFrameInvalidationActive) {
|
||||||
}
|
LimeLog.info("Patching num_ref_frames in SPS");
|
||||||
else {
|
sps.numRefFrames = 1;
|
||||||
LimeLog.info("Patching bitstream restrictions");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some devices throw errors if maxDecFrameBuffering < numRefFrames
|
// GFE 2.5.11 changed the SPS to add additional extensions. Some devices don't like these
|
||||||
sps.vuiParams.bitstreamRestriction.maxDecFrameBuffering = sps.numRefFrames;
|
// so we remove them here on old devices unless these devices also support HEVC.
|
||||||
|
// See getPreferredColorSpace() for further information.
|
||||||
// These values are the defaults for the fields, but they are more aggressive
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O &&
|
||||||
// than what GFE sends in 2.5.11, but it doesn't seem to cause picture problems.
|
sps.vuiParams != null &&
|
||||||
// We'll leave these alone for "modern" devices just in case they care.
|
hevcDecoder == null &&
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
av1Decoder == null) {
|
||||||
sps.vuiParams.bitstreamRestriction.maxBytesPerPicDenom = 2;
|
sps.vuiParams.videoSignalTypePresentFlag = false;
|
||||||
sps.vuiParams.bitstreamRestriction.maxBitsPerMbDenom = 1;
|
sps.vuiParams.colourDescriptionPresentFlag = false;
|
||||||
|
sps.vuiParams.chromaLocInfoPresentFlag = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// log2_max_mv_length_horizontal and log2_max_mv_length_vertical are set to more
|
// Some older devices used to choke on a bitstream restrictions, so we won't provide them
|
||||||
// conservative values by GFE 2.5.11. We'll let those values stand.
|
// unless explicitly whitelisted. For newer devices, leave the bitstream restrictions present.
|
||||||
}
|
if (needsSpsBitstreamFixup || isExynos4 || Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
else if (sps.vuiParams != null) {
|
// The SPS that comes in the current H264 bytestream doesn't set bitstream_restriction_flag
|
||||||
// Devices that didn't/couldn't get bitstream restrictions before GFE 2.5.11
|
// or max_dec_frame_buffering which increases decoding latency on Tegra.
|
||||||
// will continue to not receive them now
|
|
||||||
sps.vuiParams.bitstreamRestriction = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we need to hack this SPS to say we're baseline, do so now
|
// If the encoder didn't include VUI parameters in the SPS, add them now
|
||||||
if (needsBaselineSpsHack) {
|
if (sps.vuiParams == null) {
|
||||||
LimeLog.info("Hacking SPS to baseline");
|
LimeLog.info("Adding VUI parameters");
|
||||||
sps.profileIdc = 66;
|
sps.vuiParams = new VUIParameters();
|
||||||
savedSps = sps;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Patch the SPS constraint flags
|
// GFE 2.5.11 started sending bitstream restrictions
|
||||||
doProfileSpecificSpsPatching(sps);
|
if (sps.vuiParams.bitstreamRestriction == null) {
|
||||||
|
LimeLog.info("Adding bitstream restrictions");
|
||||||
|
sps.vuiParams.bitstreamRestriction = new VUIParameters.BitstreamRestriction();
|
||||||
|
sps.vuiParams.bitstreamRestriction.motionVectorsOverPicBoundariesFlag = true;
|
||||||
|
sps.vuiParams.bitstreamRestriction.maxBytesPerPicDenom = 2;
|
||||||
|
sps.vuiParams.bitstreamRestriction.maxBitsPerMbDenom = 1;
|
||||||
|
sps.vuiParams.bitstreamRestriction.log2MaxMvLengthHorizontal = 16;
|
||||||
|
sps.vuiParams.bitstreamRestriction.log2MaxMvLengthVertical = 16;
|
||||||
|
sps.vuiParams.bitstreamRestriction.numReorderFrames = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LimeLog.info("Patching bitstream restrictions");
|
||||||
|
}
|
||||||
|
|
||||||
// The H264Utils.writeSPS function safely handles
|
// Some devices throw errors if maxDecFrameBuffering < numRefFrames
|
||||||
// Annex B NALUs (including NALUs with escape sequences)
|
sps.vuiParams.bitstreamRestriction.maxDecFrameBuffering = sps.numRefFrames;
|
||||||
ByteBuffer escapedNalu = H264Utils.writeSPS(sps, decodeUnitLength);
|
|
||||||
|
|
||||||
// Batch this to submit together with PPS
|
// These values are the defaults for the fields, but they are more aggressive
|
||||||
spsBuffer = new byte[startSeqLen + 1 + escapedNalu.limit()];
|
// than what GFE sends in 2.5.11, but it doesn't seem to cause picture problems.
|
||||||
System.arraycopy(decodeUnitData, 0, spsBuffer, 0, startSeqLen + 1);
|
// We'll leave these alone for "modern" devices just in case they care.
|
||||||
escapedNalu.get(spsBuffer, startSeqLen + 1, escapedNalu.limit());
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||||
return MoonBridge.DR_OK;
|
sps.vuiParams.bitstreamRestriction.maxBytesPerPicDenom = 2;
|
||||||
}
|
sps.vuiParams.bitstreamRestriction.maxBitsPerMbDenom = 1;
|
||||||
else if (decodeUnitType == MoonBridge.BUFFER_TYPE_VPS) {
|
}
|
||||||
numVpsIn++;
|
|
||||||
|
|
||||||
// Batch this to submit together with SPS and PPS per AOSP docs
|
// log2_max_mv_length_horizontal and log2_max_mv_length_vertical are set to more
|
||||||
vpsBuffer = new byte[decodeUnitLength];
|
// conservative values by GFE 2.5.11. We'll let those values stand.
|
||||||
System.arraycopy(decodeUnitData, 0, vpsBuffer, 0, decodeUnitLength);
|
}
|
||||||
return MoonBridge.DR_OK;
|
else if (sps.vuiParams != null) {
|
||||||
}
|
// Devices that didn't/couldn't get bitstream restrictions before GFE 2.5.11
|
||||||
// Only the HEVC SPS hits this path (H.264 is handled above)
|
// will continue to not receive them now
|
||||||
else if (decodeUnitType == MoonBridge.BUFFER_TYPE_SPS) {
|
sps.vuiParams.bitstreamRestriction = null;
|
||||||
numSpsIn++;
|
|
||||||
|
|
||||||
// Batch this to submit together with VPS and PPS per AOSP docs
|
|
||||||
spsBuffer = new byte[decodeUnitLength];
|
|
||||||
System.arraycopy(decodeUnitData, 0, spsBuffer, 0, decodeUnitLength);
|
|
||||||
return MoonBridge.DR_OK;
|
|
||||||
}
|
|
||||||
else if (decodeUnitType == MoonBridge.BUFFER_TYPE_PPS) {
|
|
||||||
numPpsIn++;
|
|
||||||
|
|
||||||
// If this is the first CSD blob or we aren't supporting
|
|
||||||
// fused IDR frames, we will submit the CSD blob in a
|
|
||||||
// separate input buffer.
|
|
||||||
if (!submittedCsd || !fusedIdrFrame) {
|
|
||||||
if (!fetchNextInputBuffer()) {
|
|
||||||
return MoonBridge.DR_NEED_IDR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we get the PPS, submit the VPS and SPS together with
|
// If we need to hack this SPS to say we're baseline, do so now
|
||||||
// the PPS, as required by AOSP docs on use of MediaCodec.
|
if (needsBaselineSpsHack) {
|
||||||
if (vpsBuffer != null) {
|
LimeLog.info("Hacking SPS to baseline");
|
||||||
nextInputBuffer.put(vpsBuffer);
|
sps.profileIdc = 66;
|
||||||
}
|
savedSps = sps;
|
||||||
if (spsBuffer != null) {
|
|
||||||
nextInputBuffer.put(spsBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the CSD blob
|
// Patch the SPS constraint flags
|
||||||
codecFlags |= MediaCodec.BUFFER_FLAG_CODEC_CONFIG;
|
doProfileSpecificSpsPatching(sps);
|
||||||
timestampUs = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Batch this to submit together with the next I-frame
|
|
||||||
ppsBuffer = new byte[decodeUnitLength];
|
|
||||||
System.arraycopy(decodeUnitData, 0, ppsBuffer, 0, decodeUnitLength);
|
|
||||||
|
|
||||||
// Next call will be I-frame data
|
// The H264Utils.writeSPS function safely handles
|
||||||
submitCsdNextCall = true;
|
// Annex B NALUs (including NALUs with escape sequences)
|
||||||
|
ByteBuffer escapedNalu = H264Utils.writeSPS(sps, decodeUnitLength);
|
||||||
|
|
||||||
|
// Construct the patched SPS
|
||||||
|
byte[] naluBuffer = new byte[startSeqLen + 1 + escapedNalu.limit()];
|
||||||
|
System.arraycopy(decodeUnitData, 0, naluBuffer, 0, startSeqLen + 1);
|
||||||
|
escapedNalu.get(naluBuffer, startSeqLen + 1, escapedNalu.limit());
|
||||||
|
|
||||||
|
// Batch this to submit together with other CSD per AOSP docs
|
||||||
|
spsBuffers.add(naluBuffer);
|
||||||
return MoonBridge.DR_OK;
|
return MoonBridge.DR_OK;
|
||||||
}
|
}
|
||||||
}
|
else if (decodeUnitType == MoonBridge.BUFFER_TYPE_VPS) {
|
||||||
else {
|
numVpsIn++;
|
||||||
if (frameHostProcessingLatency != 0) {
|
|
||||||
if (activeWindowVideoStats.minHostProcessingLatency != 0) {
|
// Batch this to submit together with other CSD per AOSP docs
|
||||||
activeWindowVideoStats.minHostProcessingLatency = (char) Math.min(activeWindowVideoStats.minHostProcessingLatency, frameHostProcessingLatency);
|
byte[] naluBuffer = new byte[decodeUnitLength];
|
||||||
} else {
|
System.arraycopy(decodeUnitData, 0, naluBuffer, 0, decodeUnitLength);
|
||||||
activeWindowVideoStats.minHostProcessingLatency = frameHostProcessingLatency;
|
vpsBuffers.add(naluBuffer);
|
||||||
|
return MoonBridge.DR_OK;
|
||||||
|
}
|
||||||
|
// Only the HEVC SPS hits this path (H.264 is handled above)
|
||||||
|
else if (decodeUnitType == MoonBridge.BUFFER_TYPE_SPS) {
|
||||||
|
numSpsIn++;
|
||||||
|
|
||||||
|
// Batch this to submit together with other CSD per AOSP docs
|
||||||
|
byte[] naluBuffer = new byte[decodeUnitLength];
|
||||||
|
System.arraycopy(decodeUnitData, 0, naluBuffer, 0, decodeUnitLength);
|
||||||
|
spsBuffers.add(naluBuffer);
|
||||||
|
return MoonBridge.DR_OK;
|
||||||
|
}
|
||||||
|
else if (decodeUnitType == MoonBridge.BUFFER_TYPE_PPS) {
|
||||||
|
numPpsIn++;
|
||||||
|
|
||||||
|
// Batch this to submit together with other CSD per AOSP docs
|
||||||
|
byte[] naluBuffer = new byte[decodeUnitLength];
|
||||||
|
System.arraycopy(decodeUnitData, 0, naluBuffer, 0, decodeUnitLength);
|
||||||
|
ppsBuffers.add(naluBuffer);
|
||||||
|
return MoonBridge.DR_OK;
|
||||||
|
}
|
||||||
|
else if ((videoFormat & (MoonBridge.VIDEO_FORMAT_MASK_H264 | MoonBridge.VIDEO_FORMAT_MASK_H265)) != 0) {
|
||||||
|
// If this is the first CSD blob or we aren't supporting fused IDR frames, we will
|
||||||
|
// submit the CSD blob in a separate input buffer for each IDR frame.
|
||||||
|
if (!submittedCsd || !fusedIdrFrame) {
|
||||||
|
if (!fetchNextInputBuffer()) {
|
||||||
|
return MoonBridge.DR_NEED_IDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit all CSD when we receive the first non-CSD blob in an IDR frame
|
||||||
|
for (byte[] vpsBuffer : vpsBuffers) {
|
||||||
|
nextInputBuffer.put(vpsBuffer);
|
||||||
|
}
|
||||||
|
for (byte[] spsBuffer : spsBuffers) {
|
||||||
|
nextInputBuffer.put(spsBuffer);
|
||||||
|
}
|
||||||
|
for (byte[] ppsBuffer : ppsBuffers) {
|
||||||
|
nextInputBuffer.put(ppsBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!queueNextInputBuffer(0, MediaCodec.BUFFER_FLAG_CODEC_CONFIG)) {
|
||||||
|
return MoonBridge.DR_NEED_IDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember that we already submitted CSD for this frame, so we don't do it
|
||||||
|
// again in the fused IDR case below.
|
||||||
|
csdSubmittedForThisFrame = true;
|
||||||
|
|
||||||
|
// Remember that we submitted CSD globally for this MediaCodec instance
|
||||||
|
submittedCsd = true;
|
||||||
|
|
||||||
|
if (needsBaselineSpsHack) {
|
||||||
|
needsBaselineSpsHack = false;
|
||||||
|
|
||||||
|
if (!replaySps()) {
|
||||||
|
return MoonBridge.DR_NEED_IDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
LimeLog.info("SPS replay complete");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
activeWindowVideoStats.framesWithHostProcessingLatency += 1;
|
|
||||||
}
|
}
|
||||||
activeWindowVideoStats.maxHostProcessingLatency = (char) Math.max(activeWindowVideoStats.maxHostProcessingLatency, frameHostProcessingLatency);
|
}
|
||||||
activeWindowVideoStats.totalHostProcessingLatency += frameHostProcessingLatency;
|
|
||||||
|
|
||||||
activeWindowVideoStats.totalFramesReceived++;
|
if (frameHostProcessingLatency != 0) {
|
||||||
activeWindowVideoStats.totalFrames++;
|
if (activeWindowVideoStats.minHostProcessingLatency != 0) {
|
||||||
|
activeWindowVideoStats.minHostProcessingLatency = (char) Math.min(activeWindowVideoStats.minHostProcessingLatency, frameHostProcessingLatency);
|
||||||
if (!FRAME_RENDER_TIME_ONLY) {
|
} else {
|
||||||
// Count time from first packet received to enqueue time as receive time
|
activeWindowVideoStats.minHostProcessingLatency = frameHostProcessingLatency;
|
||||||
// We will count DU queue time as part of decoding, because it is directly
|
|
||||||
// caused by a slow decoder.
|
|
||||||
activeWindowVideoStats.totalTimeMs += enqueueTimeMs - receiveTimeMs;
|
|
||||||
}
|
}
|
||||||
|
activeWindowVideoStats.framesWithHostProcessingLatency += 1;
|
||||||
|
}
|
||||||
|
activeWindowVideoStats.maxHostProcessingLatency = (char) Math.max(activeWindowVideoStats.maxHostProcessingLatency, frameHostProcessingLatency);
|
||||||
|
activeWindowVideoStats.totalHostProcessingLatency += frameHostProcessingLatency;
|
||||||
|
|
||||||
if (!fetchNextInputBuffer()) {
|
activeWindowVideoStats.totalFramesReceived++;
|
||||||
return MoonBridge.DR_NEED_IDR;
|
activeWindowVideoStats.totalFrames++;
|
||||||
}
|
|
||||||
|
|
||||||
if (submitCsdNextCall) {
|
if (!FRAME_RENDER_TIME_ONLY) {
|
||||||
if (vpsBuffer != null) {
|
// Count time from first packet received to enqueue time as receive time
|
||||||
|
// We will count DU queue time as part of decoding, because it is directly
|
||||||
|
// caused by a slow decoder.
|
||||||
|
activeWindowVideoStats.totalTimeMs += enqueueTimeMs - receiveTimeMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fetchNextInputBuffer()) {
|
||||||
|
return MoonBridge.DR_NEED_IDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int codecFlags = 0;
|
||||||
|
|
||||||
|
if (frameType == MoonBridge.FRAME_TYPE_IDR) {
|
||||||
|
codecFlags |= MediaCodec.BUFFER_FLAG_SYNC_FRAME;
|
||||||
|
|
||||||
|
// If we are using fused IDR frames, submit the CSD with each IDR frame
|
||||||
|
if (fusedIdrFrame && !csdSubmittedForThisFrame) {
|
||||||
|
for (byte[] vpsBuffer : vpsBuffers) {
|
||||||
nextInputBuffer.put(vpsBuffer);
|
nextInputBuffer.put(vpsBuffer);
|
||||||
}
|
}
|
||||||
if (spsBuffer != null) {
|
for (byte[] spsBuffer : spsBuffers) {
|
||||||
nextInputBuffer.put(spsBuffer);
|
nextInputBuffer.put(spsBuffer);
|
||||||
}
|
}
|
||||||
if (ppsBuffer != null) {
|
for (byte[] ppsBuffer : ppsBuffers) {
|
||||||
nextInputBuffer.put(ppsBuffer);
|
nextInputBuffer.put(ppsBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
submitCsdNextCall = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameType == MoonBridge.FRAME_TYPE_IDR) {
|
|
||||||
codecFlags |= MediaCodec.BUFFER_FLAG_SYNC_FRAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
timestampUs = enqueueTimeMs * 1000;
|
|
||||||
|
|
||||||
if (timestampUs <= lastTimestampUs) {
|
|
||||||
// We can't submit multiple buffers with the same timestamp
|
|
||||||
// so bump it up by one before queuing
|
|
||||||
timestampUs = lastTimestampUs + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastTimestampUs = timestampUs;
|
|
||||||
|
|
||||||
numFramesIn++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long timestampUs = enqueueTimeMs * 1000;
|
||||||
|
if (timestampUs <= lastTimestampUs) {
|
||||||
|
// We can't submit multiple buffers with the same timestamp
|
||||||
|
// so bump it up by one before queuing
|
||||||
|
timestampUs = lastTimestampUs + 1;
|
||||||
|
}
|
||||||
|
lastTimestampUs = timestampUs;
|
||||||
|
|
||||||
|
numFramesIn++;
|
||||||
|
|
||||||
if (decodeUnitLength > nextInputBuffer.limit() - nextInputBuffer.position()) {
|
if (decodeUnitLength > nextInputBuffer.limit() - nextInputBuffer.position()) {
|
||||||
IllegalArgumentException exception = new IllegalArgumentException(
|
IllegalArgumentException exception = new IllegalArgumentException(
|
||||||
"Decode unit length "+decodeUnitLength+" too large for input buffer "+nextInputBuffer.limit());
|
"Decode unit length "+decodeUnitLength+" too large for input buffer "+nextInputBuffer.limit());
|
||||||
@@ -1723,20 +1749,6 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
|
|||||||
return MoonBridge.DR_NEED_IDR;
|
return MoonBridge.DR_NEED_IDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((codecFlags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
|
|
||||||
submittedCsd = true;
|
|
||||||
|
|
||||||
if (needsBaselineSpsHack) {
|
|
||||||
needsBaselineSpsHack = false;
|
|
||||||
|
|
||||||
if (!replaySps()) {
|
|
||||||
return MoonBridge.DR_NEED_IDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
LimeLog.info("SPS replay complete");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return MoonBridge.DR_OK;
|
return MoonBridge.DR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -503,6 +503,15 @@ public class PreferenceConfiguration {
|
|||||||
prefs.edit().putBoolean(SMALL_ICONS_PREF_STRING, getDefaultSmallMode(context)).apply();
|
prefs.edit().putBoolean(SMALL_ICONS_PREF_STRING, getDefaultSmallMode(context)).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!prefs.contains(GAMEPAD_MOTION_SENSORS_PREF_STRING) && Build.VERSION.SDK_INT == Build.VERSION_CODES.S) {
|
||||||
|
// Android 12 has a nasty bug that causes crashes when the app touches the InputDevice's
|
||||||
|
// associated InputDeviceSensorManager (just calling getSensorManager() is enough).
|
||||||
|
// As a workaround, we will override the default value for the gamepad motion sensor
|
||||||
|
// option to disabled on Android 12 to reduce the impact of this bug.
|
||||||
|
// https://cs.android.com/android/_/android/platform/frameworks/base/+/8970010a5e9f3dc5c069f56b4147552accfcbbeb
|
||||||
|
prefs.edit().putBoolean(GAMEPAD_MOTION_SENSORS_PREF_STRING, false).apply();
|
||||||
|
}
|
||||||
|
|
||||||
// This must happen after the preferences migration to ensure the preferences are populated
|
// This must happen after the preferences migration to ensure the preferences are populated
|
||||||
config.bitrate = prefs.getInt(BITRATE_PREF_STRING, prefs.getInt(BITRATE_PREF_OLD_STRING, 0) * 1000);
|
config.bitrate = prefs.getInt(BITRATE_PREF_STRING, prefs.getInt(BITRATE_PREF_OLD_STRING, 0) * 1000);
|
||||||
if (config.bitrate == 0) {
|
if (config.bitrate == 0) {
|
||||||
|
|||||||
Submodule app/src/main/jni/moonlight-core/moonlight-common-c updated: 5e844aad08...c86f49ee7f.
@@ -79,7 +79,7 @@
|
|||||||
<string name="conn_terminated_title">Verbindung beendet</string>
|
<string name="conn_terminated_title">Verbindung beendet</string>
|
||||||
<string name="conn_terminated_msg">Die Verbindung wurde beendet</string>
|
<string name="conn_terminated_msg">Die Verbindung wurde beendet</string>
|
||||||
<!-- General strings -->
|
<!-- General strings -->
|
||||||
<string name="ip_hint">IP-Adresse des GeForce Host</string>
|
<string name="ip_hint">IP-Adresse des GeForce Hosts</string>
|
||||||
<string name="searching_pc">Suche nach Hosts auf denen GeForce Experience aktiv ist…
|
<string name="searching_pc">Suche nach Hosts auf denen GeForce Experience aktiv ist…
|
||||||
\n
|
\n
|
||||||
\nStelle sicher, dass GameStream in den GeForce Experience SHIELD-Einstellungen aktiviert ist.</string>
|
\nStelle sicher, dass GameStream in den GeForce Experience SHIELD-Einstellungen aktiviert ist.</string>
|
||||||
@@ -261,4 +261,13 @@
|
|||||||
<string name="frame_conversion_error">Der Host-PC hat einen schwerwiegenden Videocodierungsfehler gemeldet.
|
<string name="frame_conversion_error">Der Host-PC hat einen schwerwiegenden Videocodierungsfehler gemeldet.
|
||||||
\n
|
\n
|
||||||
\nVersuchen Sie, den HDR-Modus zu deaktivieren, die Streaming-Auflösung zu ändern oder die Bildschirmauflösung des Host-PCs zu ändern.</string>
|
\nVersuchen Sie, den HDR-Modus zu deaktivieren, die Streaming-Auflösung zu ändern oder die Bildschirmauflösung des Host-PCs zu ändern.</string>
|
||||||
|
<string name="title_native_fps_dialog">Native FPS Warnung</string>
|
||||||
|
<string name="videoformat_av1always">Immer AV1 verwenden (Experimentell)</string>
|
||||||
|
<string name="title_checkbox_gamepad_motion_sensors">Erlaube Benutzen von Gamepad Bewegungssensoren</string>
|
||||||
|
<string name="videoformat_h264always">Immer H.264 verwenden</string>
|
||||||
|
<string name="fps_suffix_fps">FPS</string>
|
||||||
|
<string name="category_gamepad_settings">Gamepad Einstellungen</string>
|
||||||
|
<string name="pair_pairing_help">Wenn dein Host PC Sunshine verwendet, navigiere zur Sunshine Web UI und gebe dort die PIN ein.</string>
|
||||||
|
<string name="title_checkbox_gamepad_touchpad_as_mouse">Die Maus immer mit dem Touchpad steuern</string>
|
||||||
|
<string name="perf_overlay_hostprocessinglatency">Host Verarbeitungslatenz min/max/avg: %1$.1f/%2$.1f/%3$.1f ms</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<string name="pair_already_in_progress">Accoppiamento già in corso</string>
|
<string name="pair_already_in_progress">Accoppiamento già in corso</string>
|
||||||
<!-- WOL messages -->
|
<!-- WOL messages -->
|
||||||
<string name="wol_pc_online">PC già avviato</string>
|
<string name="wol_pc_online">PC già avviato</string>
|
||||||
<string name="wol_no_mac">Impossibile risvegliare il PC perché GFE non ha inviato nessun indirizzo MAC</string>
|
<string name="wol_no_mac">Impossibile risvegliare il PC perché non è stato salvato nessun indirizzo MAC</string>
|
||||||
<string name="wol_waking_pc">Risveglio PC…</string>
|
<string name="wol_waking_pc">Risveglio PC…</string>
|
||||||
<string name="wol_waking_msg">Il PC potrebbe impiegare qualche secondo per risvegliarsi.
|
<string name="wol_waking_msg">Il PC potrebbe impiegare qualche secondo per risvegliarsi.
|
||||||
Se non succede niente, assicurati che l\'opzione Wake-On-LAN sia configurata correttamente.
|
Se non succede niente, assicurati che l\'opzione Wake-On-LAN sia configurata correttamente.
|
||||||
@@ -60,8 +60,9 @@
|
|||||||
<string name="conn_terminated_msg">La connessione è stata interrotta</string>
|
<string name="conn_terminated_msg">La connessione è stata interrotta</string>
|
||||||
<!-- General strings -->
|
<!-- General strings -->
|
||||||
<string name="ip_hint">Indirizzo IP del PC</string>
|
<string name="ip_hint">Indirizzo IP del PC</string>
|
||||||
<string name="searching_pc">Ricerca di PC con GameStream avviato…\n\n
|
<string name="searching_pc">Ricerca di PC nella rete locale…
|
||||||
Assicurati che GameStream sia abilitato nelle impostazioni SHIELD di GeForce Experience.</string>
|
\n
|
||||||
|
\n Assicurati che Sunshine sia avviato o che GameStream sia abilitato nelle impostazioni SHIELD di GeForce Experience.</string>
|
||||||
<string name="yes">Sì</string>
|
<string name="yes">Sì</string>
|
||||||
<string name="no">No</string>
|
<string name="no">No</string>
|
||||||
<string name="lost_connection">Connessione con il PC persa</string>
|
<string name="lost_connection">Connessione con il PC persa</string>
|
||||||
@@ -133,10 +134,10 @@
|
|||||||
<string name="category_advanced_settings">Impostazioni avanzate</string>
|
<string name="category_advanced_settings">Impostazioni avanzate</string>
|
||||||
<string name="title_disable_frame_drop">Non saltare i fotogrammi</string>
|
<string name="title_disable_frame_drop">Non saltare i fotogrammi</string>
|
||||||
<string name="summary_disable_frame_drop">Potrebbe ridurre il micro-stuttering su alcuni dispositivi, ma può aumentare la latenza</string>
|
<string name="summary_disable_frame_drop">Potrebbe ridurre il micro-stuttering su alcuni dispositivi, ma può aumentare la latenza</string>
|
||||||
<string name="title_video_format">Modifica impostazioni HEVC</string>
|
<string name="title_video_format">Modifica impostazioni del codec</string>
|
||||||
<string name="summary_video_format">HEVC riduce i requisiti di larghezza di banda video ma richiede un dispositivo molto recente</string>
|
<string name="summary_video_format">I nuovi codec possono ridurre i requisiti di larghezza di banda video se il tuo dispositivo li supporta. La scelta del codec può essere ignorata se non è supportato dal software dell\'host o dalla GPU.</string>
|
||||||
<string name="title_enable_hdr">Abilita HDR (sperimentale)</string>
|
<string name="title_enable_hdr">Abilita HDR (sperimentale)</string>
|
||||||
<string name="summary_enable_hdr">Utilizza l\'HDR quando il gioco e la scheda video del PC lo supportano. L\'HDR richiede una scheda video serie GTX 1000 o sucessive.</string>
|
<string name="summary_enable_hdr">Utilizza l\'HDR quando il gioco e la scheda video del PC lo supportano. L\'HDR richiede una scheda video col supporto dell\'encoding HEVC Main 10.</string>
|
||||||
<string name="suffix_osc_opacity">%</string>
|
<string name="suffix_osc_opacity">%</string>
|
||||||
<string name="pcview_menu_header_online">Online</string>
|
<string name="pcview_menu_header_online">Online</string>
|
||||||
<string name="scut_pc_not_found">PC non trovato</string>
|
<string name="scut_pc_not_found">PC non trovato</string>
|
||||||
@@ -161,7 +162,7 @@
|
|||||||
<string name="perf_overlay_dectime">Tempo medio di decodifica: %1$.2f ms</string>
|
<string name="perf_overlay_dectime">Tempo medio di decodifica: %1$.2f ms</string>
|
||||||
<string name="perf_overlay_streamdetails">Flusso video: %1$s %2$.2f FPS</string>
|
<string name="perf_overlay_streamdetails">Flusso video: %1$s %2$.2f FPS</string>
|
||||||
<string name="nettest_title_waiting">Prova della Connessione di Rete</string>
|
<string name="nettest_title_waiting">Prova della Connessione di Rete</string>
|
||||||
<string name="nettest_text_waiting">Moonlight sta testando la tua connessione di rete per controllare se NVIDIA GameStream sia bloccato.
|
<string name="nettest_text_waiting">Moonlight sta testando la tua connessione di rete per controllare se ogni porta richiesta sia bloccata.
|
||||||
\n
|
\n
|
||||||
\nPotrebbero volerci alcuni secondi…</string>
|
\nPotrebbero volerci alcuni secondi…</string>
|
||||||
<string name="nettest_title_done">Test della Rete Completato</string>
|
<string name="nettest_title_done">Test della Rete Completato</string>
|
||||||
@@ -226,18 +227,16 @@
|
|||||||
<string name="no_frame_received_error">La tua connessione di rete non sta funzionando bene. Riduci il bitrate video o prova ad usare una connessione più veloce.</string>
|
<string name="no_frame_received_error">La tua connessione di rete non sta funzionando bene. Riduci il bitrate video o prova ad usare una connessione più veloce.</string>
|
||||||
<string name="early_termination_error">Qualcosa è andato storto sul PC sorgente mentre la trasmissione veniva avviata.
|
<string name="early_termination_error">Qualcosa è andato storto sul PC sorgente mentre la trasmissione veniva avviata.
|
||||||
\n
|
\n
|
||||||
\nAssicurati di non avere nessun contenuto protetto da DRM aperto sul PC sorgente. Puoi anche provare a spengere e riaccendere il PC sorgente.
|
\nAssicurati di non avere nessun contenuto protetto da DRM aperto sul PC sorgente. Puoi anche provare a spengere e riaccendere il PC sorgente.</string>
|
||||||
\n
|
|
||||||
\nSe il problema persiste, prova a installare di nuovo i driver della scheda video e GeForce Experience.</string>
|
|
||||||
<string name="summary_unlock_fps">Trasmettere a 90 o 120 FPS potrebbe ridurre il ritardo su dispositivi di fascia alta, ma può provocare ritardi i instabilità sui dispositivi che non lo supportano</string>
|
<string name="summary_unlock_fps">Trasmettere a 90 o 120 FPS potrebbe ridurre il ritardo su dispositivi di fascia alta, ma può provocare ritardi i instabilità sui dispositivi che non lo supportano</string>
|
||||||
<string name="summary_enable_post_stream_toast">Molstra un messaggio con informazioni sulla latenza dopo che la trasmissione è conclusa</string>
|
<string name="summary_enable_post_stream_toast">Molstra un messaggio con informazioni sulla latenza dopo che la trasmissione è conclusa</string>
|
||||||
<string name="text_native_res_dialog">Le impostazioni di risoluzione nativa non sono ufficialmente supportate da GeForce Experience, quindi non cambierà automaticamente la risoluzione del monitor del computer sorgente. Dovrai cambiarla manualmente all\'interno del gioco.
|
<string name="text_native_res_dialog">Le impostazioni di risoluzione nativa e/o di FPS possono non essere supportate dal server per lo streaming. Dovrai aggiungerle manualmente all\'interno delle impostazioni del PC o del server.
|
||||||
\n
|
\n
|
||||||
\nSe scegli di create una risoluzione personalizzata nel Pannello di Controllo NVIDIA per copiare la risoluzione del tuo dispositivo, assicurati di aver letto e capito il messaggio di attenzione di NVIDIA a proposito dei possibili danni al monitor, all\'instabilità del PC e altri potenziali problemi.
|
\nSe scegli di create una risoluzione personalizzata nel Pannello di Controllo NVIDIA per copiare la risoluzione dello schermo, assicurati di aver letto e capito il messaggio di attenzione di NVIDIA a proposito dei possibili danni al monitor, all\'instabilità del PC e altri potenziali problemi.
|
||||||
\n
|
\n
|
||||||
\nNon saremo responsabili per qualsiasi problema risultante dalla creazione di una risoluzione personalizzata sul tuo PC.
|
\nNon saremo responsabili per qualsiasi problema risultante dalla creazione di una risoluzione personalizzata sul tuo PC.
|
||||||
\n
|
\n
|
||||||
\nInfine, il tuo dispositivo o PC sorgente potrebbero non supportare la trasmissione alla risoluzione nativa. Se ciò non funzionasse sul tuo dispositivo, sfortunatamente non ci sono altre soluzioni.</string>
|
\nPuò capitare che il tuo monitor potrebbe non supportare una risoluzione dello schermo richiesta. In questo caso, prova a impostare un monitor virtuale. Infine, se il tuo dispositivo o PC sorgente non supportano la trasmissione ad una specifica risoluzione dello schermo o della frequenza di aggiornamento, sfortunatamente non ci sono altre soluzioni.</string>
|
||||||
<string name="perf_overlay_incomingfps">Frame rate in ingresso dalla rete: %1$.2f FPS</string>
|
<string name="perf_overlay_incomingfps">Frame rate in ingresso dalla rete: %1$.2f FPS</string>
|
||||||
<string name="perf_overlay_renderingfps">Frame rate renderizzato: %1$.2f FPS</string>
|
<string name="perf_overlay_renderingfps">Frame rate renderizzato: %1$.2f FPS</string>
|
||||||
<string name="perf_overlay_netdrops">Frame scartati dalla tua connessione di rete: %1$.2f%%</string>
|
<string name="perf_overlay_netdrops">Frame scartati dalla tua connessione di rete: %1$.2f%%</string>
|
||||||
@@ -264,4 +263,20 @@
|
|||||||
<string name="title_checkbox_reduce_refresh_rate">Consenti riduzione della frequenza di aggiornamento</string>
|
<string name="title_checkbox_reduce_refresh_rate">Consenti riduzione della frequenza di aggiornamento</string>
|
||||||
<string name="summary_full_range">Ciò causerà la perdita di dettagli in aree chiare e scure se il dispositivo non visualizza correttamente i contenuti video a gamma completa.</string>
|
<string name="summary_full_range">Ciò causerà la perdita di dettagli in aree chiare e scure se il dispositivo non visualizza correttamente i contenuti video a gamma completa.</string>
|
||||||
<string name="title_full_range">Forza video full range (sperimentale)</string>
|
<string name="title_full_range">Forza video full range (sperimentale)</string>
|
||||||
|
<string name="title_native_fps_dialog">Avviso FPS nativi</string>
|
||||||
|
<string name="videoformat_av1always">Preferisci AV1 (Sperimentale)</string>
|
||||||
|
<string name="pcview_menu_eol">Terminazione del servizio NVIDIA GameStream</string>
|
||||||
|
<string name="title_checkbox_gamepad_motion_sensors">Permetti l\'uso dei sensori giroscopici del gamepad</string>
|
||||||
|
<string name="summary_checkbox_gamepad_touchpad_as_mouse">Forza l\'input del touchpad del gamepad a controllare il mouse dell\'host, anche quando si sta emulando un gamepad col touchpad.</string>
|
||||||
|
<string name="toast_controller_type_changed">Il tipo di gamepad potrebbe cambiare se è attiva l\'emulazione dei sensori giroscopici</string>
|
||||||
|
<string name="summary_checkbox_gamepad_motion_sensors">Abilita per gli host supportati la trasmissione dei dati dai sensori giroscopici quando si simula un gamepad con sensori giroscopici. Disabilitandolo può ridurre il consumo di batteria e la rete richiesta per lo stream se i sensori giroscopici non vengono utilizzati nel gioco.</string>
|
||||||
|
<string name="summary_checkbox_gamepad_motion_fallback">Usa i sensori giroscopici integrati nel tuo dispositivo se il tuo gamepad non possiede i sensori giroscopici o non sono compatibili con la tua versione Android.
|
||||||
|
\nNota: Abilitare questa opzione farà apparire il tuo gamepad come un controller Playstation all\'host.</string>
|
||||||
|
<string name="videoformat_h264always">Preferisci H.264</string>
|
||||||
|
<string name="fps_suffix_fps">FPS</string>
|
||||||
|
<string name="category_gamepad_settings">Impostazioni del gamepad</string>
|
||||||
|
<string name="title_checkbox_gamepad_motion_fallback">Emula il supporto dei sensori giroscopici del gamepad</string>
|
||||||
|
<string name="pair_pairing_help">Se il tuo PC host sta eseguendo Sunshine, vai nella pagina web locale di Sunshine ed inserisci il PIN.</string>
|
||||||
|
<string name="title_checkbox_gamepad_touchpad_as_mouse">Controlla sempre il mouse col touchpad</string>
|
||||||
|
<string name="perf_overlay_hostprocessinglatency">Latenza di codifica da parte dell\'host min/max/average: %1$.1f/%2$.1f/%3$.1f ms</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- Added Select+L1 gamepad button combo to act as the touchpad button when emulating a PS4 controller using built-in device motion sensors
|
||||||
|
- Disabled gamepad motion sensors by default on Android 12 as a workaround for an Android 12 bug that randomly crashes Moonlight
|
||||||
|
- Fixed analog sticks not centering properly in rare cases
|
||||||
|
- Adjusted bitrate handling of AV1 to be consistent with HEVC
|
||||||
|
- Fixed handling of some unusual H.264 and HEVC streams
|
||||||
Reference in new issue
Block a user