mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-20 03:23:07 +00:00
Add additional information to total frame latency and RendererException
This commit is contained in:
parent
7f1fe5f520
commit
babd92c8c0
@ -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);
|
decoderRenderer = new MediaCodecDecoderRenderer(prefConfig.videoFormat, prefConfig.bitrate);
|
||||||
|
|
||||||
// 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()) {
|
||||||
|
@ -23,6 +23,7 @@ import android.view.SurfaceHolder;
|
|||||||
public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||||
|
|
||||||
private static final boolean USE_FRAME_RENDER_TIME = false;
|
private static final boolean USE_FRAME_RENDER_TIME = false;
|
||||||
|
private static final boolean FRAME_RENDER_TIME_ONLY = USE_FRAME_RENDER_TIME && false;
|
||||||
|
|
||||||
// Used on versions < 5.0
|
// Used on versions < 5.0
|
||||||
private ByteBuffer[] legacyInputBuffers;
|
private ByteBuffer[] legacyInputBuffers;
|
||||||
@ -54,6 +55,11 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
private long decoderTimeMs;
|
private long decoderTimeMs;
|
||||||
private long totalTimeMs;
|
private long totalTimeMs;
|
||||||
private int totalFrames;
|
private int totalFrames;
|
||||||
|
private int frameLossEvents;
|
||||||
|
private int framesLost;
|
||||||
|
private int lastFrameNumber;
|
||||||
|
private int refreshRate;
|
||||||
|
private int bitrate;
|
||||||
|
|
||||||
private int numSpsIn;
|
private int numSpsIn;
|
||||||
private int numPpsIn;
|
private int numPpsIn;
|
||||||
@ -99,9 +105,11 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
this.renderTarget = renderTarget;
|
this.renderTarget = renderTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MediaCodecDecoderRenderer(int videoFormat) {
|
public MediaCodecDecoderRenderer(int videoFormat, int bitrate) {
|
||||||
//dumpDecoders();
|
//dumpDecoders();
|
||||||
|
|
||||||
|
this.bitrate = bitrate;
|
||||||
|
|
||||||
spinnerThreads = new Thread[Runtime.getRuntime().availableProcessors()];
|
spinnerThreads = new Thread[Runtime.getRuntime().availableProcessors()];
|
||||||
|
|
||||||
avcDecoder = findAvcDecoder();
|
avcDecoder = findAvcDecoder();
|
||||||
@ -160,6 +168,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
this.initialWidth = width;
|
this.initialWidth = width;
|
||||||
this.initialHeight = height;
|
this.initialHeight = height;
|
||||||
this.videoFormat = format;
|
this.videoFormat = format;
|
||||||
|
this.refreshRate = redrawRate;
|
||||||
|
|
||||||
String mimeType;
|
String mimeType;
|
||||||
String selectedDecoderName;
|
String selectedDecoderName;
|
||||||
@ -533,18 +542,34 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public int submitDecodeUnit(byte[] frameData, int frameLength) {
|
public int submitDecodeUnit(byte[] frameData, int frameLength, int frameNumber, long receiveTimeMs) {
|
||||||
totalFrames++;
|
totalFrames++;
|
||||||
|
|
||||||
|
// We can receive the same "frame" multiple times if it's an IDR frame.
|
||||||
|
// In that case, each frame start NALU is submitted independently.
|
||||||
|
if (frameNumber != lastFrameNumber && frameNumber != lastFrameNumber + 1) {
|
||||||
|
framesLost += frameNumber - lastFrameNumber - 1;
|
||||||
|
frameLossEvents++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastFrameNumber = frameNumber;
|
||||||
|
|
||||||
int inputBufferIndex;
|
int inputBufferIndex;
|
||||||
ByteBuffer buf;
|
ByteBuffer buf;
|
||||||
|
|
||||||
long timestampUs = System.nanoTime() / 1000;
|
long timestampUs = System.nanoTime() / 1000;
|
||||||
|
|
||||||
|
if (!FRAME_RENDER_TIME_ONLY) {
|
||||||
|
// Count time from first packet received to decode start
|
||||||
|
totalTimeMs += (timestampUs / 1000) - receiveTimeMs;
|
||||||
|
}
|
||||||
|
|
||||||
if (timestampUs <= lastTimestampUs) {
|
if (timestampUs <= lastTimestampUs) {
|
||||||
// We can't submit multiple buffers with the same timestamp
|
// We can't submit multiple buffers with the same timestamp
|
||||||
// so bump it up by one before queuing
|
// so bump it up by one before queuing
|
||||||
timestampUs = lastTimestampUs + 1;
|
timestampUs = lastTimestampUs + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastTimestampUs = timestampUs;
|
lastTimestampUs = timestampUs;
|
||||||
|
|
||||||
int codecFlags = 0;
|
int codecFlags = 0;
|
||||||
@ -878,8 +903,11 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
str += "AVC Decoder: "+((renderer.avcDecoder != null) ? renderer.avcDecoder.getName():"(none)")+"\n";
|
str += "AVC Decoder: "+((renderer.avcDecoder != null) ? renderer.avcDecoder.getName():"(none)")+"\n";
|
||||||
str += "HEVC Decoder: "+((renderer.hevcDecoder != null) ? renderer.hevcDecoder.getName():"(none)")+"\n";
|
str += "HEVC Decoder: "+((renderer.hevcDecoder != null) ? renderer.hevcDecoder.getName():"(none)")+"\n";
|
||||||
str += "Initial video dimensions: "+renderer.initialWidth+"x"+renderer.initialHeight+"\n";
|
str += "Initial video dimensions: "+renderer.initialWidth+"x"+renderer.initialHeight+"\n";
|
||||||
|
str += "FPS target: "+renderer.refreshRate+"\n";
|
||||||
|
str += "Bitrate: "+renderer.bitrate+" Mbps \n";
|
||||||
str += "In stats: "+renderer.numVpsIn+", "+renderer.numSpsIn+", "+renderer.numPpsIn+"\n";
|
str += "In stats: "+renderer.numVpsIn+", "+renderer.numSpsIn+", "+renderer.numPpsIn+"\n";
|
||||||
str += "Total frames: "+renderer.totalFrames+"\n";
|
str += "Total frames: "+renderer.totalFrames+"\n";
|
||||||
|
str += "Frame losses: "+renderer.framesLost+" in "+frameLossEvents+" loss events\n";
|
||||||
str += "Average end-to-end client latency: "+getAverageEndToEndLatency()+"ms\n";
|
str += "Average end-to-end client latency: "+getAverageEndToEndLatency()+"ms\n";
|
||||||
str += "Average hardware decoder latency: "+getAverageDecoderLatency()+"ms\n";
|
str += "Average hardware decoder latency: "+getAverageDecoderLatency()+"ms\n";
|
||||||
|
|
||||||
@ -895,13 +923,6 @@ 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();
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 4e0bffc0b3c3ec5a0b74c01ae84f4bd69cff52d7
|
Subproject commit 369a0ded4820c0cb3950c09f6279099d38944ffc
|
Loading…
x
Reference in New Issue
Block a user