Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ac721a35b | ||
|
|
e49b1c92a2 | ||
|
|
db4295bf83 | ||
|
|
824c37f9d5 | ||
|
|
acf4426952 | ||
|
|
e8c50342ab | ||
|
|
598995de3b | ||
|
|
01cf0cc649 | ||
|
|
fa560f462f | ||
|
|
f6e40118a9 | ||
|
|
fe7148dbd4 | ||
|
|
60de065836 | ||
|
|
6f82f82abb |
No files matched your search
@@ -5,16 +5,18 @@ apply plugin: 'com.android.application'
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 26
|
compileSdkVersion 26
|
||||||
buildToolsVersion '26.0.0'
|
buildToolsVersion '26.0.1'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 26
|
targetSdkVersion 26
|
||||||
|
|
||||||
versionName "5.1"
|
versionName "5.1.2"
|
||||||
versionCode = 128
|
versionCode = 130
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flavorDimensions "root"
|
||||||
|
|
||||||
productFlavors {
|
productFlavors {
|
||||||
root {
|
root {
|
||||||
// Android O has native mouse capture, so don't show the rooted
|
// Android O has native mouse capture, so don't show the rooted
|
||||||
@@ -25,6 +27,8 @@ android {
|
|||||||
ndk {
|
ndk {
|
||||||
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64", "mips", "mips64"
|
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64", "mips", "mips64"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dimension "root"
|
||||||
}
|
}
|
||||||
|
|
||||||
nonRoot {
|
nonRoot {
|
||||||
@@ -32,6 +36,8 @@ android {
|
|||||||
ndk {
|
ndk {
|
||||||
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64", "mips", "mips64"
|
abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64", "mips", "mips64"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dimension "root"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,10 +60,9 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'org.bouncycastle:bcprov-jdk15on:1.52'
|
implementation 'org.bouncycastle:bcprov-jdk15on:1.52'
|
||||||
compile 'org.bouncycastle:bcpkix-jdk15on:1.52'
|
implementation 'org.bouncycastle:bcpkix-jdk15on:1.52'
|
||||||
compile files('libs/jcodec-0.1.9-patched.jar')
|
implementation files('libs/jcodec-0.1.9-patched.jar')
|
||||||
|
|
||||||
debugCompile project(path:':moonlight-common', configuration:'debug')
|
implementation project(':moonlight-common')
|
||||||
releaseCompile project(path:':moonlight-common', configuration:'release')
|
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,8 @@
|
|||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:isGame="true"
|
android:isGame="true"
|
||||||
android:banner="@drawable/atv_banner"
|
android:banner="@drawable/atv_banner"
|
||||||
android:icon="@drawable/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
|
|
||||||
<!-- Samsung multi-window support -->
|
<!-- Samsung multi-window support -->
|
||||||
|
|||||||
|
After Width: | Height: | Size: 58 KiB |
@@ -214,7 +214,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
// Initialize the MediaCodec helper before creating the decoder
|
// Initialize the MediaCodec helper before creating the decoder
|
||||||
MediaCodecHelper.initializeWithContext(this);
|
MediaCodecHelper.initializeWithContext(this);
|
||||||
|
|
||||||
decoderRenderer = new MediaCodecDecoderRenderer(prefConfig.videoFormat, prefConfig.bitrate);
|
decoderRenderer = new MediaCodecDecoderRenderer(prefConfig.videoFormat, prefConfig.bitrate, prefConfig.batterySaver);
|
||||||
|
|
||||||
// Display a message to the user if H.265 was forced on but we still didn't find a decoder
|
// Display a message to the user if H.265 was forced on but we still didn't find a decoder
|
||||||
if (prefConfig.videoFormat == PreferenceConfiguration.FORCE_H265_ON && !decoderRenderer.isHevcSupported()) {
|
if (prefConfig.videoFormat == PreferenceConfiguration.FORCE_H265_ON && !decoderRenderer.isHevcSupported()) {
|
||||||
@@ -944,6 +944,16 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
displayedFailureDialog = true;
|
displayedFailureDialog = true;
|
||||||
LimeLog.severe(stage+" failed: "+errorCode);
|
LimeLog.severe(stage+" failed: "+errorCode);
|
||||||
|
|
||||||
|
// If video initialization failed and the surface is still valid, display extra information for the user
|
||||||
|
if (stage.contains("video") && streamView.getHolder().getSurface().isValid()) {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Toast.makeText(Game.this, "Video decoder failed to initialize. Your device may not support the selected resolution.", Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Dialog.displayDialog(this, getResources().getString(R.string.conn_error_title),
|
Dialog.displayDialog(this, getResources().getString(R.string.conn_error_title),
|
||||||
getResources().getString(R.string.conn_error_msg)+" "+stage, true);
|
getResources().getString(R.string.conn_error_msg)+" "+stage, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.limelight.binding.audio;
|
package com.limelight.binding.audio;
|
||||||
|
|
||||||
|
import android.media.AudioAttributes;
|
||||||
import android.media.AudioFormat;
|
import android.media.AudioFormat;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.AudioTrack;
|
import android.media.AudioTrack;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
import com.limelight.nvstream.av.audio.AudioRenderer;
|
import com.limelight.nvstream.av.audio.AudioRenderer;
|
||||||
@@ -12,10 +14,58 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
|||||||
|
|
||||||
private AudioTrack track;
|
private AudioTrack track;
|
||||||
|
|
||||||
|
private AudioTrack createAudioTrack(int channelConfig, int bufferSize, boolean lowLatency) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
return new AudioTrack(AudioManager.STREAM_MUSIC,
|
||||||
|
48000,
|
||||||
|
channelConfig,
|
||||||
|
AudioFormat.ENCODING_PCM_16BIT,
|
||||||
|
bufferSize,
|
||||||
|
AudioTrack.MODE_STREAM);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AudioAttributes.Builder attributesBuilder = new AudioAttributes.Builder()
|
||||||
|
.setUsage(AudioAttributes.USAGE_GAME);
|
||||||
|
AudioFormat format = new AudioFormat.Builder()
|
||||||
|
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
|
||||||
|
.setSampleRate(48000)
|
||||||
|
.setChannelMask(channelConfig)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||||
|
// Use FLAG_LOW_LATENCY on L through N
|
||||||
|
if (lowLatency) {
|
||||||
|
attributesBuilder.setFlags(AudioAttributes.FLAG_LOW_LATENCY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
AudioTrack.Builder trackBuilder = new AudioTrack.Builder()
|
||||||
|
.setAudioFormat(format)
|
||||||
|
.setAudioAttributes(attributesBuilder.build())
|
||||||
|
.setTransferMode(AudioTrack.MODE_STREAM)
|
||||||
|
.setBufferSizeInBytes(bufferSize);
|
||||||
|
|
||||||
|
// Use PERFORMANCE_MODE_LOW_LATENCY on O and later
|
||||||
|
if (lowLatency) {
|
||||||
|
trackBuilder.setPerformanceMode(AudioTrack.PERFORMANCE_MODE_LOW_LATENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return trackBuilder.build();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new AudioTrack(attributesBuilder.build(),
|
||||||
|
format,
|
||||||
|
bufferSize,
|
||||||
|
AudioTrack.MODE_STREAM,
|
||||||
|
AudioManager.AUDIO_SESSION_ID_GENERATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int setup(int audioConfiguration) {
|
public int setup(int audioConfiguration) {
|
||||||
int channelConfig;
|
int channelConfig;
|
||||||
int bufferSize;
|
|
||||||
int bytesPerFrame;
|
int bytesPerFrame;
|
||||||
|
|
||||||
switch (audioConfiguration)
|
switch (audioConfiguration)
|
||||||
@@ -38,44 +88,76 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
|||||||
// do this on many devices and it lowers audio latency.
|
// do this on many devices and it lowers audio latency.
|
||||||
// We'll try the small buffer size first and if it fails,
|
// We'll try the small buffer size first and if it fails,
|
||||||
// use the recommended larger buffer size.
|
// use the recommended larger buffer size.
|
||||||
try {
|
|
||||||
// Buffer two frames of audio if possible
|
|
||||||
bufferSize = bytesPerFrame * 2;
|
|
||||||
|
|
||||||
track = new AudioTrack(AudioManager.STREAM_MUSIC,
|
for (int i = 0; i < 4; i++) {
|
||||||
48000,
|
boolean lowLatency;
|
||||||
channelConfig,
|
int bufferSize;
|
||||||
AudioFormat.ENCODING_PCM_16BIT,
|
|
||||||
bufferSize,
|
|
||||||
AudioTrack.MODE_STREAM);
|
|
||||||
track.play();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Try to release the AudioTrack if we got far enough
|
|
||||||
try {
|
|
||||||
if (track != null) {
|
|
||||||
track.release();
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {}
|
|
||||||
|
|
||||||
// Now try the larger buffer size
|
// We will try:
|
||||||
bufferSize = Math.max(AudioTrack.getMinBufferSize(48000,
|
// 1) Small buffer, low latency mode
|
||||||
|
// 2) Large buffer, low latency mode
|
||||||
|
// 3) Small buffer, standard mode
|
||||||
|
// 4) Large buffer, standard mode
|
||||||
|
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
lowLatency = true;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
lowLatency = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unreachable
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
case 2:
|
||||||
|
bufferSize = bytesPerFrame * 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case 3:
|
||||||
|
// Try the larger buffer size
|
||||||
|
bufferSize = Math.max(AudioTrack.getMinBufferSize(48000,
|
||||||
channelConfig,
|
channelConfig,
|
||||||
AudioFormat.ENCODING_PCM_16BIT),
|
AudioFormat.ENCODING_PCM_16BIT),
|
||||||
bytesPerFrame * 2);
|
bytesPerFrame * 2);
|
||||||
|
|
||||||
// Round to next frame
|
// Round to next frame
|
||||||
bufferSize = (((bufferSize + (bytesPerFrame - 1)) / bytesPerFrame) * bytesPerFrame);
|
bufferSize = (((bufferSize + (bytesPerFrame - 1)) / bytesPerFrame) * bytesPerFrame);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unreachable
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
track = new AudioTrack(AudioManager.STREAM_MUSIC,
|
// Skip low latency options if hardware sample rate isn't 48000Hz
|
||||||
48000,
|
if (AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC) != 48000 && lowLatency) {
|
||||||
channelConfig,
|
continue;
|
||||||
AudioFormat.ENCODING_PCM_16BIT,
|
}
|
||||||
bufferSize,
|
|
||||||
AudioTrack.MODE_STREAM);
|
try {
|
||||||
track.play();
|
track = createAudioTrack(channelConfig, bufferSize, lowLatency);
|
||||||
|
track.play();
|
||||||
|
|
||||||
|
// Successfully created working AudioTrack. We're done here.
|
||||||
|
LimeLog.info("Audio track configuration: "+bufferSize+" "+lowLatency);
|
||||||
|
break;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Try to release the AudioTrack if we got far enough
|
||||||
|
try {
|
||||||
|
if (track != null) {
|
||||||
|
track.release();
|
||||||
|
track = null;
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LimeLog.info("Audio track buffer size: "+bufferSize);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
private boolean needsBaselineSpsHack;
|
private boolean needsBaselineSpsHack;
|
||||||
private SeqParameterSet savedSps;
|
private SeqParameterSet savedSps;
|
||||||
|
|
||||||
|
private RendererException initialException;
|
||||||
|
private long initialExceptionTimestamp;
|
||||||
|
private static final int EXCEPTION_REPORT_DELAY_MS = 3000;
|
||||||
|
|
||||||
private long lastTimestampUs;
|
private long lastTimestampUs;
|
||||||
private long decoderTimeMs;
|
private long decoderTimeMs;
|
||||||
private long totalTimeMs;
|
private long totalTimeMs;
|
||||||
@@ -105,12 +109,18 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
this.renderTarget = renderTarget;
|
this.renderTarget = renderTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MediaCodecDecoderRenderer(int videoFormat, int bitrate) {
|
public MediaCodecDecoderRenderer(int videoFormat, int bitrate, boolean batterySaver) {
|
||||||
//dumpDecoders();
|
//dumpDecoders();
|
||||||
|
|
||||||
this.bitrate = bitrate;
|
this.bitrate = bitrate;
|
||||||
|
|
||||||
spinnerThreads = new Thread[Runtime.getRuntime().availableProcessors()];
|
// Disable spinner threads in battery saver mode
|
||||||
|
if (batterySaver) {
|
||||||
|
spinnerThreads = new Thread[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
spinnerThreads = new Thread[Runtime.getRuntime().availableProcessors()];
|
||||||
|
}
|
||||||
|
|
||||||
avcDecoder = findAvcDecoder();
|
avcDecoder = findAvcDecoder();
|
||||||
if (avcDecoder != null) {
|
if (avcDecoder != null) {
|
||||||
@@ -294,13 +304,31 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only throw if the surface is still around and we're not stopping
|
// Only throw if we're not stopping
|
||||||
if (!stopping && renderTarget.getSurface().isValid()) {
|
if (!stopping) {
|
||||||
if (buf != null || codecFlags != 0) {
|
//
|
||||||
throw new RendererException(this, e, buf, codecFlags);
|
// There seems to be a race condition with decoder/surface teardown causing some
|
||||||
|
// decoders to to throw IllegalStateExceptions even before 'stopping' is set.
|
||||||
|
// To workaround this while allowing real exceptions to propagate, we will eat the
|
||||||
|
// first exception. If we are still receiving exceptions 3 seconds later, we will
|
||||||
|
// throw the original exception again.
|
||||||
|
//
|
||||||
|
if (initialException != null) {
|
||||||
|
// This isn't the first time we've had an exception processing video
|
||||||
|
if (System.currentTimeMillis() - initialExceptionTimestamp >= EXCEPTION_REPORT_DELAY_MS) {
|
||||||
|
// It's been over 3 seconds and we're still getting exceptions. Throw the original now.
|
||||||
|
throw initialException;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new RendererException(this, e);
|
// This is the first exception we've hit
|
||||||
|
if (buf != null || codecFlags != 0) {
|
||||||
|
initialException = new RendererException(this, e, buf, codecFlags);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
initialException = new RendererException(this, e);
|
||||||
|
}
|
||||||
|
initialExceptionTimestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,7 +339,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
BufferInfo info = new BufferInfo();
|
BufferInfo info = new BufferInfo();
|
||||||
while (!isInterrupted()) {
|
while (!stopping) {
|
||||||
try {
|
try {
|
||||||
// Try to output a frame
|
// Try to output a frame
|
||||||
int outIndex = videoDecoder.dequeueOutputBuffer(info, 50000);
|
int outIndex = videoDecoder.dequeueOutputBuffer(info, 50000);
|
||||||
@@ -369,7 +397,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
public void run() {
|
public void run() {
|
||||||
// This thread exists to keep the CPU at a higher DVFS state on devices
|
// This thread exists to keep the CPU at a higher DVFS state on devices
|
||||||
// where the governor scales clock speed sporadically, causing dropped frames.
|
// where the governor scales clock speed sporadically, causing dropped frames.
|
||||||
while (!isInterrupted()) {
|
while (!stopping) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(0, 1);
|
Thread.sleep(0, 1);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@@ -418,17 +446,21 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
startSpinnerThreads();
|
startSpinnerThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !!! May be called even if setup()/start() fails !!!
|
||||||
public void prepareForStop() {
|
public void prepareForStop() {
|
||||||
// Let the decoding code know to ignore codec exceptions now
|
// Let the decoding code know to ignore codec exceptions now
|
||||||
stopping = true;
|
stopping = true;
|
||||||
|
|
||||||
|
// Halt the rendering thread
|
||||||
|
if (rendererThread != null) {
|
||||||
|
rendererThread.interrupt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
stopping = true;
|
// May be called already, but we'll call it now to be safe
|
||||||
|
prepareForStop();
|
||||||
// Halt the rendering thread
|
|
||||||
rendererThread.interrupt();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Invalidate pending decode buffers
|
// Invalidate pending decode buffers
|
||||||
@@ -653,13 +685,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
inputBufferIndex = dequeueInputBuffer();
|
inputBufferIndex = dequeueInputBuffer();
|
||||||
if (inputBufferIndex < 0) {
|
if (inputBufferIndex < 0) {
|
||||||
// We're being torn down now
|
// We're being torn down now
|
||||||
return MoonBridge.DR_OK;
|
return MoonBridge.DR_NEED_IDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = getEmptyInputBuffer(inputBufferIndex);
|
buf = getEmptyInputBuffer(inputBufferIndex);
|
||||||
if (buf == null) {
|
if (buf == null) {
|
||||||
// We're being torn down now
|
// We're being torn down now
|
||||||
return MoonBridge.DR_OK;
|
return MoonBridge.DR_NEED_IDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the annex B header
|
// Write the annex B header
|
||||||
@@ -687,13 +719,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
inputBufferIndex = dequeueInputBuffer();
|
inputBufferIndex = dequeueInputBuffer();
|
||||||
if (inputBufferIndex < 0) {
|
if (inputBufferIndex < 0) {
|
||||||
// We're being torn down now
|
// We're being torn down now
|
||||||
return MoonBridge.DR_OK;
|
return MoonBridge.DR_NEED_IDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = getEmptyInputBuffer(inputBufferIndex);
|
buf = getEmptyInputBuffer(inputBufferIndex);
|
||||||
if (buf == null) {
|
if (buf == null) {
|
||||||
// We're being torn down now
|
// We're being torn down now
|
||||||
return MoonBridge.DR_OK;
|
return MoonBridge.DR_NEED_IDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsBaselineSpsHack) {
|
if (needsBaselineSpsHack) {
|
||||||
@@ -726,13 +758,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
inputBufferIndex = dequeueInputBuffer();
|
inputBufferIndex = dequeueInputBuffer();
|
||||||
if (inputBufferIndex < 0) {
|
if (inputBufferIndex < 0) {
|
||||||
// We're being torn down now
|
// We're being torn down now
|
||||||
return MoonBridge.DR_OK;
|
return MoonBridge.DR_NEED_IDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = getEmptyInputBuffer(inputBufferIndex);
|
buf = getEmptyInputBuffer(inputBufferIndex);
|
||||||
if (buf == null) {
|
if (buf == null) {
|
||||||
// We're being torn down now
|
// We're being torn down now
|
||||||
return MoonBridge.DR_OK;
|
return MoonBridge.DR_NEED_IDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we get the PPS, submit the VPS and SPS together with
|
// When we get the PPS, submit the VPS and SPS together with
|
||||||
@@ -751,13 +783,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
inputBufferIndex = dequeueInputBuffer();
|
inputBufferIndex = dequeueInputBuffer();
|
||||||
if (inputBufferIndex < 0) {
|
if (inputBufferIndex < 0) {
|
||||||
// We're being torn down now
|
// We're being torn down now
|
||||||
return MoonBridge.DR_OK;
|
return MoonBridge.DR_NEED_IDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = getEmptyInputBuffer(inputBufferIndex);
|
buf = getEmptyInputBuffer(inputBufferIndex);
|
||||||
if (buf == null) {
|
if (buf == null) {
|
||||||
// We're being torn down now
|
// We're being torn down now
|
||||||
return MoonBridge.DR_OK;
|
return MoonBridge.DR_NEED_IDR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -900,6 +932,13 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
|
|
||||||
str += "Is Exynos 4: "+renderer.isExynos4+"\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";
|
str += "Full decoder dump:\n";
|
||||||
try {
|
try {
|
||||||
str += MediaCodecHelper.dumpDecoders();
|
str += MediaCodecHelper.dumpDecoders();
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ public class PreferenceConfiguration {
|
|||||||
private static final String USB_DRIVER_PREF_SRING = "checkbox_usb_driver";
|
private static final String USB_DRIVER_PREF_SRING = "checkbox_usb_driver";
|
||||||
private static final String VIDEO_FORMAT_PREF_STRING = "video_format";
|
private static final String VIDEO_FORMAT_PREF_STRING = "video_format";
|
||||||
private static final String ONSCREEN_CONTROLLER_PREF_STRING = "checkbox_show_onscreen_controls";
|
private static final String ONSCREEN_CONTROLLER_PREF_STRING = "checkbox_show_onscreen_controls";
|
||||||
|
private static final String BATTERY_SAVER_PREF_STRING = "checkbox_battery_saver";
|
||||||
|
|
||||||
private static final int BITRATE_DEFAULT_720_30 = 5;
|
private static final int BITRATE_DEFAULT_720_30 = 5;
|
||||||
private static final int BITRATE_DEFAULT_720_60 = 10;
|
private static final int BITRATE_DEFAULT_720_60 = 10;
|
||||||
@@ -45,6 +46,7 @@ public class PreferenceConfiguration {
|
|||||||
private static final boolean DEFAULT_USB_DRIVER = true;
|
private static final boolean DEFAULT_USB_DRIVER = true;
|
||||||
private static final String DEFAULT_VIDEO_FORMAT = "auto";
|
private static final String DEFAULT_VIDEO_FORMAT = "auto";
|
||||||
private static final boolean ONSCREEN_CONTROLLER_DEFAULT = false;
|
private static final boolean ONSCREEN_CONTROLLER_DEFAULT = false;
|
||||||
|
private static final boolean DEFAULT_BATTERY_SAVER = false;
|
||||||
|
|
||||||
public static final int FORCE_H265_ON = -1;
|
public static final int FORCE_H265_ON = -1;
|
||||||
public static final int AUTOSELECT_H265 = 0;
|
public static final int AUTOSELECT_H265 = 0;
|
||||||
@@ -58,6 +60,7 @@ public class PreferenceConfiguration {
|
|||||||
public String language;
|
public String language;
|
||||||
public boolean listMode, smallIconMode, multiController, enable51Surround, usbDriver;
|
public boolean listMode, smallIconMode, multiController, enable51Surround, usbDriver;
|
||||||
public boolean onscreenController;
|
public boolean onscreenController;
|
||||||
|
public boolean batterySaver;
|
||||||
|
|
||||||
public static int getDefaultBitrate(String resFpsString) {
|
public static int getDefaultBitrate(String resFpsString) {
|
||||||
if (resFpsString.equals("720p30")) {
|
if (resFpsString.equals("720p30")) {
|
||||||
@@ -188,6 +191,7 @@ public class PreferenceConfiguration {
|
|||||||
config.enable51Surround = prefs.getBoolean(ENABLE_51_SURROUND_PREF_STRING, DEFAULT_ENABLE_51_SURROUND);
|
config.enable51Surround = prefs.getBoolean(ENABLE_51_SURROUND_PREF_STRING, DEFAULT_ENABLE_51_SURROUND);
|
||||||
config.usbDriver = prefs.getBoolean(USB_DRIVER_PREF_SRING, DEFAULT_USB_DRIVER);
|
config.usbDriver = prefs.getBoolean(USB_DRIVER_PREF_SRING, DEFAULT_USB_DRIVER);
|
||||||
config.onscreenController = prefs.getBoolean(ONSCREEN_CONTROLLER_PREF_STRING, ONSCREEN_CONTROLLER_DEFAULT);
|
config.onscreenController = prefs.getBoolean(ONSCREEN_CONTROLLER_PREF_STRING, ONSCREEN_CONTROLLER_DEFAULT);
|
||||||
|
config.batterySaver = prefs.getBoolean(BATTERY_SAVER_PREF_STRING, DEFAULT_BATTERY_SAVER);
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 19 KiB |
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_pc_scut_background"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_pc_scut_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_pc_scut_background"/>
|
||||||
|
<foreground android:drawable="@mipmap/ic_pc_scut_foreground"/>
|
||||||
|
</adaptive-icon>
|
||||||
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 715 B |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 471 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 816 B |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="ic_launcher_background">#565C64</color>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="ic_pc_scut_background">#FFFFFF</color>
|
||||||
|
</resources>
|
||||||
@@ -104,6 +104,8 @@
|
|||||||
<string name="title_checkbox_stretch_video">Stretch video to full-screen</string>
|
<string name="title_checkbox_stretch_video">Stretch video to full-screen</string>
|
||||||
<string name="title_checkbox_disable_warnings">Disable warning messages</string>
|
<string name="title_checkbox_disable_warnings">Disable warning messages</string>
|
||||||
<string name="summary_checkbox_disable_warnings">Disable on-screen connection warning messages while streaming</string>
|
<string name="summary_checkbox_disable_warnings">Disable on-screen connection warning messages while streaming</string>
|
||||||
|
<string name="title_checkbox_battery_saver">Battery saver</string>
|
||||||
|
<string name="summary_checkbox_battery_saver">Uses less battery, but may increase stuttering</string>
|
||||||
|
|
||||||
<string name="category_audio_settings">Audio Settings</string>
|
<string name="category_audio_settings">Audio Settings</string>
|
||||||
<string name="title_checkbox_51_surround">Enable 5.1 surround sound</string>
|
<string name="title_checkbox_51_surround">Enable 5.1 surround sound</string>
|
||||||
|
|||||||
@@ -21,9 +21,9 @@
|
|||||||
android:title="@string/title_checkbox_stretch_video"
|
android:title="@string/title_checkbox_stretch_video"
|
||||||
android:defaultValue="false" />
|
android:defaultValue="false" />
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="checkbox_disable_warnings"
|
android:key="checkbox_battery_saver"
|
||||||
android:title="@string/title_checkbox_disable_warnings"
|
android:title="@string/title_checkbox_battery_saver"
|
||||||
android:summary="@string/summary_checkbox_disable_warnings"
|
android:summary="@string/summary_checkbox_battery_saver"
|
||||||
android:defaultValue="false" />
|
android:defaultValue="false" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory android:title="@string/category_audio_settings">
|
<PreferenceCategory android:title="@string/category_audio_settings">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
classpath 'com.android.tools.build:gradle:3.0.0-beta2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#Thu Mar 02 18:32:01 PST 2017
|
#Sat Aug 12 15:52:56 PDT 2017
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-rc-1-all.zip
|
||||||