mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-19 19:13:03 +00:00
Add a workaround for the Nexus 9 dropping frames with the new renderer
This commit is contained in:
parent
42c65f4f16
commit
7ce29e3a09
@ -27,10 +27,11 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
|
|||||||
private ByteBuffer[] videoDecoderInputBuffers;
|
private ByteBuffer[] videoDecoderInputBuffers;
|
||||||
private MediaCodec videoDecoder;
|
private MediaCodec videoDecoder;
|
||||||
private Thread rendererThread;
|
private Thread rendererThread;
|
||||||
private boolean needsSpsBitstreamFixup, isExynos4;
|
private final boolean needsSpsBitstreamFixup, isExynos4;
|
||||||
private VideoDepacketizer depacketizer;
|
private VideoDepacketizer depacketizer;
|
||||||
private boolean adaptivePlayback;
|
private final boolean adaptivePlayback;
|
||||||
private int initialWidth, initialHeight;
|
private int initialWidth, initialHeight;
|
||||||
|
private final int dequeueOutputBufferTimeout;
|
||||||
|
|
||||||
private boolean needsBaselineSpsHack;
|
private boolean needsBaselineSpsHack;
|
||||||
private SeqParameterSet savedSps;
|
private SeqParameterSet savedSps;
|
||||||
@ -55,12 +56,17 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
|
|||||||
}
|
}
|
||||||
if (decoder == null) {
|
if (decoder == null) {
|
||||||
// This case is handled later in setup()
|
// This case is handled later in setup()
|
||||||
|
needsSpsBitstreamFixup = false;
|
||||||
|
isExynos4 = false;
|
||||||
|
adaptivePlayback = false;
|
||||||
|
dequeueOutputBufferTimeout = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoderName = decoder.getName();
|
decoderName = decoder.getName();
|
||||||
|
|
||||||
// Set decoder-specific attributes
|
// Set decoder-specific attributes
|
||||||
|
dequeueOutputBufferTimeout = MediaCodecHelper.getOptimalOutputBufferDequeueTimeout(decoderName, decoder);
|
||||||
adaptivePlayback = MediaCodecHelper.decoderSupportsAdaptivePlayback(decoderName, decoder);
|
adaptivePlayback = MediaCodecHelper.decoderSupportsAdaptivePlayback(decoderName, decoder);
|
||||||
needsSpsBitstreamFixup = MediaCodecHelper.decoderNeedsSpsBitstreamRestrictions(decoderName, decoder);
|
needsSpsBitstreamFixup = MediaCodecHelper.decoderNeedsSpsBitstreamRestrictions(decoderName, decoder);
|
||||||
needsBaselineSpsHack = MediaCodecHelper.decoderNeedsBaselineSpsHack(decoderName, decoder);
|
needsBaselineSpsHack = MediaCodecHelper.decoderNeedsBaselineSpsHack(decoderName, decoder);
|
||||||
@ -145,7 +151,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
|
|||||||
while (!isInterrupted()) {
|
while (!isInterrupted()) {
|
||||||
try {
|
try {
|
||||||
// Try to output a frame
|
// Try to output a frame
|
||||||
int outIndex = videoDecoder.dequeueOutputBuffer(info, 50000);
|
int outIndex = videoDecoder.dequeueOutputBuffer(info, dequeueOutputBufferTimeout);
|
||||||
if (outIndex >= 0) {
|
if (outIndex >= 0) {
|
||||||
long presentationTimeUs = info.presentationTimeUs;
|
long presentationTimeUs = info.presentationTimeUs;
|
||||||
int lastIndex = outIndex;
|
int lastIndex = outIndex;
|
||||||
@ -189,7 +195,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
rendererThread.setName("Video - Renderer (MediaCodec)");
|
rendererThread.setName("Video - Renderer (MediaCodec)");
|
||||||
rendererThread.setPriority(Thread.MAX_PRIORITY);
|
rendererThread.setPriority(Thread.NORM_PRIORITY + 2);
|
||||||
rendererThread.start();
|
rendererThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,16 @@ public class MediaCodecHelper {
|
|||||||
private static final List<String> spsFixupBitstreamFixupDecoderPrefixes;
|
private static final List<String> spsFixupBitstreamFixupDecoderPrefixes;
|
||||||
private static final List<String> whitelistedAdaptiveResolutionPrefixes;
|
private static final List<String> whitelistedAdaptiveResolutionPrefixes;
|
||||||
private static final List<String> baselineProfileHackPrefixes;
|
private static final List<String> baselineProfileHackPrefixes;
|
||||||
|
private static final List<String> fastOutputPollPrefixes;
|
||||||
|
|
||||||
|
private static final int FAST_OUTPUT_POLL_US = 3; // 3 us
|
||||||
|
private static final int NORMAL_OUTPUT_POLL_US = 50000; // 50 ms
|
||||||
|
|
||||||
|
static {
|
||||||
|
fastOutputPollPrefixes = new LinkedList<String>();
|
||||||
|
fastOutputPollPrefixes.add("omx.nvidia");
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
preferredDecoders = new LinkedList<String>();
|
preferredDecoders = new LinkedList<String>();
|
||||||
}
|
}
|
||||||
@ -97,6 +106,20 @@ public class MediaCodecHelper {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getOptimalOutputBufferDequeueTimeout(String decoderName, MediaCodecInfo decoderInfo) {
|
||||||
|
// This concept of "fast output polling" is a workaround for certain devices that are powerful enough
|
||||||
|
// that the governor overzealously reduces the clockspeed of the CPU enough that it causes frames to be
|
||||||
|
// lost. This (at least) affects the Denver Tegra K1 running Android 5.0. To simplify things, I've simply
|
||||||
|
// set all Tegra devices to use fast polling.
|
||||||
|
if (isDecoderInList(fastOutputPollPrefixes, decoderName)) {
|
||||||
|
LimeLog.info("Decoder "+decoderName+" requires fast output polling");
|
||||||
|
return FAST_OUTPUT_POLL_US;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return NORMAL_OUTPUT_POLL_US;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean decoderNeedsSpsBitstreamRestrictions(String decoderName, MediaCodecInfo decoderInfo) {
|
public static boolean decoderNeedsSpsBitstreamRestrictions(String decoderName, MediaCodecInfo decoderInfo) {
|
||||||
return isDecoderInList(spsFixupBitstreamFixupDecoderPrefixes, decoderName);
|
return isDecoderInList(spsFixupBitstreamFixupDecoderPrefixes, decoderName);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user