From 6f05b2af8a96cdd32044c14efd81d60abb306b19 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 21 Oct 2014 19:20:54 -0400 Subject: [PATCH 1/3] Attempt to detect Exynos 4 to apply the bitstream fixup code --- decoder-errata.txt | 6 +- .../video/MediaCodecDecoderRenderer.java | 18 +++++- .../binding/video/MediaCodecHelper.java | 63 +++++++++++++++++++ 3 files changed, 82 insertions(+), 5 deletions(-) diff --git a/decoder-errata.txt b/decoder-errata.txt index a4933c57..d761f161 100644 --- a/decoder-errata.txt +++ b/decoder-errata.txt @@ -1,7 +1,7 @@ This file serves to document some of the decoder errata when using MediaCodec hardware decoders on certain devices. -1. num_ref_frames is set to 16 by NVENC which causes decoders to allocate 16+ buffers. This can cause an error on some devices. - - Affected decoders: TI OMAP4, Exynos 4 +1. num_ref_frames is set to 16 by NVENC which causes decoders to allocate 16+ buffers. This can cause an error or lag on some devices. + - Affected decoders: TI OMAP4, Allwinner A20 2. Some decoders have a huge per-frame latency with the unmodified SPS sent from NVENC. Setting max_dec_frame_buffering fixes this latency issue. - Affected decoders: NVIDIA Tegra 3 and 4 @@ -10,7 +10,7 @@ This file serves to document some of the decoder errata when using MediaCodec ha - Affected decoders: TI OMAP4 4. Some decoders require num_ref_frames=1 and max_dec_frame_buffering=1 to avoid crashing on SPS or first I-frame - - Affected decoders: Qualcomm in GS3 on 4.3+ + - Affected decoders: Qualcomm in GS3 on 4.3+, Exynos 4 at 1080p only 5. Some decoders will hang if max_dec_frame_buffering is not present - Affected decoders: MediaTek decoder in Fire HD 7 (2014) diff --git a/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java b/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java index cf91d802..0ba47678 100644 --- a/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java +++ b/src/com/limelight/binding/video/MediaCodecDecoderRenderer.java @@ -22,12 +22,13 @@ import android.media.MediaCodec.CodecException; import android.os.Build; import android.view.SurfaceHolder; +@SuppressWarnings("unused") public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { private ByteBuffer[] videoDecoderInputBuffers; private MediaCodec videoDecoder; private Thread rendererThread; - private boolean needsSpsBitstreamFixup; + private boolean needsSpsBitstreamFixup, isExynos4; private VideoDepacketizer depacketizer; private boolean adaptivePlayback; private int initialWidth, initialHeight; @@ -65,6 +66,10 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { if (needsSpsBitstreamFixup) { LimeLog.info("Decoder "+decoderName+" needs SPS bitstream restrictions fixup"); } + isExynos4 = MediaCodecHelper.isExynos4Device(); + if (isExynos4) { + LimeLog.info("Decoder "+decoderName+" is on Exynos 4"); + } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) @@ -406,7 +411,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { LimeLog.info("Patching num_ref_frames in SPS"); sps.num_ref_frames = 1; - if (needsSpsBitstreamFixup) { + if (needsSpsBitstreamFixup || isExynos4) { // 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. LimeLog.info("Adding bitstream restrictions"); @@ -512,6 +517,15 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer { str += "Buffer codec flags: "+currentCodecFlags+"\n"; } + str += "Is Exynos 4: "+renderer.isExynos4+"\n"; + + str += "/proc/cpuinfo:\n"; + try { + str += MediaCodecHelper.readCpuinfo(); + } catch (Exception e) { + str += e.getMessage(); + } + str += "Full decoder dump:\n"; try { str += MediaCodecHelper.dumpDecoders(); diff --git a/src/com/limelight/binding/video/MediaCodecHelper.java b/src/com/limelight/binding/video/MediaCodecHelper.java index f26a8be9..1e69c773 100644 --- a/src/com/limelight/binding/video/MediaCodecHelper.java +++ b/src/com/limelight/binding/video/MediaCodecHelper.java @@ -1,7 +1,11 @@ package com.limelight.binding.video; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import android.annotation.SuppressLint; import android.annotation.TargetApi; @@ -233,4 +237,63 @@ public class MediaCodecHelper { return null; } + + public static String readCpuinfo() throws Exception { + StringBuilder cpuInfo = new StringBuilder(); + BufferedReader br = new BufferedReader(new FileReader(new File("/proc/cpuinfo"))); + try { + for (;;) { + int ch = br.read(); + if (ch == -1) + break; + cpuInfo.append((char)ch); + } + + return cpuInfo.toString(); + } finally { + br.close(); + } + } + + private static boolean stringContainsIgnoreCase(String string, String substring) { + return string.toLowerCase(Locale.ENGLISH).contains(substring.toLowerCase(Locale.ENGLISH)); + } + + public static boolean isExynos4Device() { + try { + // Try reading CPU info too look for + String cpuInfo = readCpuinfo(); + + // SMDK4xxx is Exynos 4 + if (stringContainsIgnoreCase(cpuInfo, "SMDK4")) { + LimeLog.info("Found SMDK4 in /proc/cpuinfo"); + return true; + } + + // If we see "Exynos 4" also we'll count it + if (stringContainsIgnoreCase(cpuInfo, "Exynos 4")) { + LimeLog.info("Found Exynos 4 in /proc/cpuinfo"); + return true; + } + } catch (Exception e) { + e.printStackTrace(); + } + + try { + File systemDir = new File("/sys/devices/system"); + File[] files = systemDir.listFiles(); + if (files != null) { + for (File f : files) { + if (stringContainsIgnoreCase(f.getName(), "exynos4")) { + LimeLog.info("Found exynos4 in /sys/devices/system"); + return true; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return false; + } } From bc1409ba6c825c44df624e3e808449742571d10e Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 21 Oct 2014 19:24:43 -0400 Subject: [PATCH 2/3] Increment version --- AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 6aada663..f25564dc 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@  + android:versionCode="37" + android:versionName="2.5.7.1" > Date: Thu, 23 Oct 2014 01:33:20 -0400 Subject: [PATCH 3/3] fix grammar and limelight windows link --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7f00e32c..78fa612a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ #Limelight Limelight is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield. -We reverse engineered the Shield streaming software, and created a version that can be run on any Android device. +We reverse engineered the Shield streaming software and created a version that can be run on any Android device. Limelight will allow you to stream your full collection of games from your Windows PC to your Android device, -in your own home, or over the internet. +whether in your own home or over the internet. -[Limelight-pc](https://github.com/limelight-stream/limelight-pc) is also currently in development for Windows, OS X and Linux. Versions for [iOS](https://github.com/limelight-stream/limelight-ios) and [Windows Phone](https://github.com/limelight-stream/limelight-wp) are also in development. +[Limelight-pc](https://github.com/limelight-stream/limelight-pc) is also currently in development for Windows, OS X and Linux. Versions for [iOS](https://github.com/limelight-stream/limelight-ios) and [Windows and Windows Phone](https://github.com/limelight-stream/limelight-windows) are also in development. ##Features