mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-07-24 15:40:47 +00:00
Add UI elements and backend code for manually overriding the default decoder choice. Redraw at the specified refresh rate.
This commit is contained in:
@@ -1,29 +1,9 @@
|
||||
package com.limelight.binding;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import com.limelight.binding.audio.AndroidAudioRenderer;
|
||||
import com.limelight.binding.video.AndroidCpuDecoderRenderer;
|
||||
import com.limelight.binding.video.MediaCodecDecoderRenderer;
|
||||
import com.limelight.nvstream.av.audio.AudioRenderer;
|
||||
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
||||
|
||||
public class PlatformBinding {
|
||||
public static VideoDecoderRenderer chooseDecoderRenderer() {
|
||||
if (Build.HARDWARE.equals("goldfish")) {
|
||||
// Emulator - don't render video (it's slow!)
|
||||
return null;
|
||||
}
|
||||
else if (MediaCodecDecoderRenderer.findSafeDecoder() != null) {
|
||||
// Hardware decoding
|
||||
return new MediaCodecDecoderRenderer();
|
||||
}
|
||||
else {
|
||||
// Software decoding
|
||||
return new AndroidCpuDecoderRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDeviceName() {
|
||||
String deviceName = android.os.Build.MODEL;
|
||||
deviceName = deviceName.replace(" ", "");
|
||||
|
||||
@@ -78,8 +78,8 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(int width, int height, Object renderTarget, int drFlags) {
|
||||
this.targetFps = 30;
|
||||
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
||||
this.targetFps = redrawRate;
|
||||
|
||||
int perfLevel = findOptimalPerformanceLevel();
|
||||
int threadCount;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.limelight.binding.video;
|
||||
|
||||
import com.limelight.nvstream.av.DecodeUnit;
|
||||
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
||||
|
||||
public class ConfigurableDecoderRenderer implements VideoDecoderRenderer {
|
||||
|
||||
private VideoDecoderRenderer decoderRenderer;
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
decoderRenderer.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
||||
if ((drFlags & VideoDecoderRenderer.FLAG_FORCE_HARDWARE_DECODING) != 0 ||
|
||||
((drFlags & VideoDecoderRenderer.FLAG_FORCE_SOFTWARE_DECODING) == 0 &&
|
||||
MediaCodecDecoderRenderer.findSafeDecoder() != null)) {
|
||||
decoderRenderer = new MediaCodecDecoderRenderer();
|
||||
}
|
||||
else {
|
||||
decoderRenderer = new AndroidCpuDecoderRenderer();
|
||||
}
|
||||
decoderRenderer.setup(width, height, redrawRate, renderTarget, drFlags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
decoderRenderer.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
decoderRenderer.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean submitDecodeUnit(DecodeUnit du) {
|
||||
return decoderRenderer.submitDecodeUnit(du);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
||||
private ByteBuffer[] videoDecoderInputBuffers;
|
||||
private MediaCodec videoDecoder;
|
||||
private Thread rendererThread;
|
||||
private int redrawRate;
|
||||
|
||||
public static final List<String> blacklistedDecoderPrefixes;
|
||||
|
||||
@@ -71,14 +72,20 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(int width, int height, Object renderTarget, int drFlags) {
|
||||
videoDecoder = MediaCodec.createByCodecName(findSafeDecoder().getName());
|
||||
MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", width, height);
|
||||
|
||||
videoDecoder.configure(videoFormat, ((SurfaceHolder)renderTarget).getSurface(), null, 0);
|
||||
|
||||
videoDecoder.setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
|
||||
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
||||
this.redrawRate = redrawRate;
|
||||
|
||||
MediaCodecInfo safeDecoder = findSafeDecoder();
|
||||
if (safeDecoder != null) {
|
||||
videoDecoder = MediaCodec.createByCodecName(safeDecoder.getName());
|
||||
}
|
||||
else {
|
||||
videoDecoder = MediaCodec.createDecoderByType("video/avc");
|
||||
}
|
||||
|
||||
MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", width, height);
|
||||
videoDecoder.configure(videoFormat, ((SurfaceHolder)renderTarget).getSurface(), null, 0);
|
||||
videoDecoder.setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
|
||||
videoDecoder.start();
|
||||
|
||||
videoDecoderInputBuffers = videoDecoder.getInputBuffers();
|
||||
@@ -112,7 +119,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
||||
|
||||
if (currentTimeUs() >= nextFrameTimeUs) {
|
||||
render = true;
|
||||
nextFrameTimeUs = computePresentationTime(60);
|
||||
nextFrameTimeUs = computePresentationTime(redrawRate);
|
||||
}
|
||||
|
||||
videoDecoder.releaseOutputBuffer(outIndex, render);
|
||||
|
||||
Reference in New Issue
Block a user