Compare commits

..

6 Commits

Author SHA1 Message Date
Cameron Gutman 37ddccde0c Version 5.6.7 2018-02-14 18:39:04 -08:00
Cameron Gutman ffc59c6bd6 Update moonlight-common to fix pairing timeout issue 2018-02-14 18:34:45 -08:00
Cameron Gutman 88f84a0c12 Version 5.6.6 2018-02-10 17:21:36 -08:00
Cameron Gutman 03ecf3e5ac Fix crash on Knox devices with USB blocking policies 2018-02-10 16:56:01 -08:00
Cameron Gutman 617c8582b4 Fix crash on MediaTek PAL Android TVs 2018-02-10 16:42:45 -08:00
Cameron Gutman ef3b28295b Update dependency versions 2018-02-05 18:38:23 -08:00
8 changed files with 83 additions and 36 deletions
+5 -5
View File
@@ -11,8 +11,8 @@ android {
minSdkVersion 16
targetSdkVersion 27
versionName "5.6.5"
versionCode = 145
versionName "5.6.7"
versionCode = 147
}
flavorDimensions "root"
@@ -99,9 +99,9 @@ android {
}
dependencies {
implementation 'org.bouncycastle:bcprov-jdk15on:1.57'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.57'
implementation files('libs/jcodec-0.1.9-patched.jar')
implementation 'org.bouncycastle:bcprov-jdk15on:1.59'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.59'
implementation 'org.jcodec:jcodec:0.2.3'
implementation project(':moonlight-common')
}
Binary file not shown.
+14 -6
View File
@@ -329,13 +329,21 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// Hopefully, we can get rid of this once someone comes up with a better way
// to track the state of the pipeline and time frames.
int roundedRefreshRate = Math.round(displayRefreshRate);
if (roundedRefreshRate <= 49) {
// Let's avoid clearly bogus refresh rates
roundedRefreshRate = 60;
}
if (!prefConfig.disableFrameDrop && prefConfig.fps >= roundedRefreshRate) {
prefConfig.fps = roundedRefreshRate - 1;
LimeLog.info("Adjusting FPS target for screen to "+prefConfig.fps);
if (roundedRefreshRate <= 49) {
// Let's avoid clearly bogus refresh rates and fall back to legacy rendering
decoderRenderer.enableLegacyFrameDropRendering();
LimeLog.info("Bogus refresh rate: "+roundedRefreshRate);
}
// HACK: Avoid crashing on some MTK devices
else if (roundedRefreshRate == 50 && decoderRenderer.is49FpsBlacklisted()) {
// Use the old rendering strategy on these broken devices
decoderRenderer.enableLegacyFrameDropRendering();
}
else {
prefConfig.fps = roundedRefreshRate - 1;
LimeLog.info("Adjusting FPS target for screen to "+prefConfig.fps);
}
}
StreamConfiguration config = new StreamConfiguration.Builder()
@@ -14,8 +14,10 @@ import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.view.InputDevice;
import android.widget.Toast;
import com.limelight.LimeLog;
import com.limelight.R;
import java.util.ArrayList;
@@ -121,7 +123,17 @@ public class UsbDriverService extends Service implements UsbDriverListener {
// Do we have permission yet?
if (!usbManager.hasPermission(device)) {
// Let's ask for permission
usbManager.requestPermission(device, PendingIntent.getBroadcast(UsbDriverService.this, 0, new Intent(ACTION_USB_PERMISSION), 0));
try {
// This function is not documented as throwing any exceptions (denying access
// is indicated by calling the PendingIntent with a false result). However,
// Samsung Knox has some policies which block this request, but rather than
// just returning a false result or returning 0 enumerated devices,
// they throw an undocumented SecurityException from this call, crashing
// the whole app. :(
usbManager.requestPermission(device, PendingIntent.getBroadcast(UsbDriverService.this, 0, new Intent(ACTION_USB_PERMISSION), 0));
} catch (SecurityException e) {
Toast.makeText(this, this.getText(R.string.error_usb_prohibited), Toast.LENGTH_LONG).show();
}
return;
}
@@ -56,6 +56,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
private int consecutiveCrashCount;
private String glRenderer;
private boolean foreground = true;
private boolean legacyFrameDropRendering = false;
private boolean needsBaselineSpsHack;
private SeqParameterSet savedSps;
@@ -191,6 +192,15 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
return avcDecoder != null;
}
public boolean is49FpsBlacklisted() {
return avcDecoder != null && MediaCodecHelper.decoderBlacklistedFor49Fps(avcDecoder.getName());
}
public void enableLegacyFrameDropRendering() {
LimeLog.info("Legacy frame drop rendering enabled");
legacyFrameDropRendering = true;
}
public boolean isHevcMain10Hdr10Supported() {
if (hevcDecoder == null) {
return false;
@@ -410,7 +420,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
}
// Render the last buffer
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !legacyFrameDropRendering) {
// Use a PTS that will cause this frame to never be dropped if frame dropping
// is disabled
videoDecoder.releaseOutputBuffer(lastIndex, 0);
@@ -633,15 +643,15 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
// High Profile which allows the decoder to assume there will be no B-frames and
// reduce delay and buffering accordingly. Some devices (Marvell, Exynos 4) don't
// like it so we only set them on devices that are confirmed to benefit from it.
if (sps.profile_idc == 100 && constrainedHighProfile) {
if (sps.profileIdc == 100 && constrainedHighProfile) {
LimeLog.info("Setting constraint set flags for constrained high profile");
sps.constraint_set_4_flag = true;
sps.constraint_set_5_flag = true;
sps.constraintSet4Flag = true;
sps.constraintSet5Flag = true;
}
else {
// Force the constraints unset otherwise (some may be set by default)
sps.constraint_set_4_flag = false;
sps.constraint_set_5_flag = false;
sps.constraintSet4Flag = false;
sps.constraintSet5Flag = false;
}
}
@@ -706,12 +716,12 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
if (initialWidth == 1280 && initialHeight == 720) {
// Max 5 buffered frames at 1280x720x60
LimeLog.info("Patching level_idc to 32");
sps.level_idc = 32;
sps.levelIdc = 32;
}
else if (initialWidth == 1920 && initialHeight == 1080) {
// Max 4 buffered frames at 1920x1080x64
LimeLog.info("Patching level_idc to 42");
sps.level_idc = 42;
sps.levelIdc = 42;
}
else {
// Leave the profile alone (currently 5.0)
@@ -729,14 +739,14 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
// where we've enabled reference frame invalidation.
if (!refFrameInvalidationActive) {
LimeLog.info("Patching num_ref_frames in SPS");
sps.num_ref_frames = 1;
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.
sps.vuiParams.video_signal_type_present_flag = false;
sps.vuiParams.colour_description_present_flag = false;
sps.vuiParams.chroma_loc_info_present_flag = false;
sps.vuiParams.videoSignalTypePresentFlag = false;
sps.vuiParams.colourDescriptionPresentFlag = false;
sps.vuiParams.chromaLocInfoPresentFlag = false;
if ((needsSpsBitstreamFixup || isExynos4) && !refFrameInvalidationActive) {
// The SPS that comes in the current H264 bytestream doesn't set bitstream_restriction_flag
@@ -746,22 +756,22 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
if (sps.vuiParams.bitstreamRestriction == null) {
LimeLog.info("Adding bitstream restrictions");
sps.vuiParams.bitstreamRestriction = new VUIParameters.BitstreamRestriction();
sps.vuiParams.bitstreamRestriction.motion_vectors_over_pic_boundaries_flag = true;
sps.vuiParams.bitstreamRestriction.log2_max_mv_length_horizontal = 16;
sps.vuiParams.bitstreamRestriction.log2_max_mv_length_vertical = 16;
sps.vuiParams.bitstreamRestriction.num_reorder_frames = 0;
sps.vuiParams.bitstreamRestriction.motionVectorsOverPicBoundariesFlag = true;
sps.vuiParams.bitstreamRestriction.log2MaxMvLengthHorizontal = 16;
sps.vuiParams.bitstreamRestriction.log2MaxMvLengthVertical = 16;
sps.vuiParams.bitstreamRestriction.numReorderFrames = 0;
}
else {
LimeLog.info("Patching bitstream restrictions");
}
// Some devices throw errors if max_dec_frame_buffering < num_ref_frames
sps.vuiParams.bitstreamRestriction.max_dec_frame_buffering = sps.num_ref_frames;
// Some devices throw errors if maxDecFrameBuffering < numRefFrames
sps.vuiParams.bitstreamRestriction.maxDecFrameBuffering = sps.numRefFrames;
// These values are the defaults for the fields, but they are more aggressive
// than what GFE sends in 2.5.11, but it doesn't seem to cause picture problems.
sps.vuiParams.bitstreamRestriction.max_bytes_per_pic_denom = 2;
sps.vuiParams.bitstreamRestriction.max_bits_per_mb_denom = 1;
sps.vuiParams.bitstreamRestriction.maxBytesPerPicDenom = 2;
sps.vuiParams.bitstreamRestriction.maxBitsPerMbDenom = 1;
// log2_max_mv_length_horizontal and log2_max_mv_length_vertical are set to more
// conservative values by GFE 2.5.11. We'll let those values stand.
@@ -775,7 +785,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
// If we need to hack this SPS to say we're baseline, do so now
if (needsBaselineSpsHack) {
LimeLog.info("Hacking SPS to baseline");
sps.profile_idc = 66;
sps.profileIdc = 66;
savedSps = sps;
}
@@ -930,7 +940,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
inputBuffer.put(new byte[]{0x00, 0x00, 0x00, 0x01, 0x67});
// Switch the H264 profile back to high
savedSps.profile_idc = 100;
savedSps.profileIdc = 100;
// Patch the SPS constraint flags
doProfileSpecificSpsPatching(savedSps);
@@ -36,6 +36,7 @@ public class MediaCodecHelper {
private static final List<String> whitelistedHevcDecoders;
private static final List<String> refFrameInvalidationAvcPrefixes;
private static final List<String> refFrameInvalidationHevcPrefixes;
private static final List<String> blacklisted49FpsDecoderPrefixes;
private static boolean isLowEndSnapdragon = false;
private static boolean initialized = false;
@@ -153,6 +154,17 @@ public class MediaCodecHelper {
// Qualcomm is currently the only decoders in this group.
}
static {
blacklisted49FpsDecoderPrefixes = new LinkedList<>();
// We see a bunch of crashes on MediaTek Android TVs running
// at 49 FPS (PAL 50 Hz - 1). Blacklist this frame rate for
// these devices and hope they fix it in Oreo.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
blacklisted49FpsDecoderPrefixes.add("omx.mtk");
}
}
private static String getAdrenoVersionString(String glRenderer) {
glRenderer = glRenderer.toLowerCase().trim();
@@ -271,7 +283,7 @@ public class MediaCodecHelper {
public static long getMonotonicMillis() {
return System.nanoTime() / 1000000L;
}
public static boolean decoderSupportsAdaptivePlayback(MediaCodecInfo decoderInfo) {
// Possibly enable adaptive playback on KitKat and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
@@ -312,6 +324,10 @@ public class MediaCodecHelper {
return isDecoderInList(baselineProfileHackPrefixes, decoderName);
}
public static boolean decoderBlacklistedFor49Fps(String decoderName) {
return isDecoderInList(blacklisted49FpsDecoderPrefixes, decoderName);
}
public static boolean decoderSupportsRefFrameInvalidationAvc(String decoderName, int videoHeight) {
// Reference frame invalidation is broken on low-end Snapdragon SoCs at 1080p.
if (videoHeight > 720 && isLowEndSnapdragon) {
+1
View File
@@ -51,6 +51,7 @@
<string name="message_decoding_error">Moonlight has crashed due to a problem with this device\'s video decoder. Try adjusting the streaming settings if the crashes continue.</string>
<string name="title_decoding_reset">Video Settings Reset</string>
<string name="message_decoding_reset">Your device\'s video decoder continues to crash at your selected streaming settings. Your streaming settings have been reset to default.</string>
<string name="error_usb_prohibited">USB access is prohibited by your device administrator. Check your Knox or MDM settings.</string>
<!-- Start application messages -->
<string name="conn_establishing_title">Establishing Connection</string>