mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-06-17 14:21:08 +00:00
Only use SPS hack on Tegra devices
This commit is contained in:
@@ -21,8 +21,10 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
private MediaCodec videoDecoder;
|
private MediaCodec videoDecoder;
|
||||||
private Thread rendererThread;
|
private Thread rendererThread;
|
||||||
private int redrawRate;
|
private int redrawRate;
|
||||||
|
private boolean needsSpsFixup;
|
||||||
|
|
||||||
public static final List<String> blacklistedDecoderPrefixes;
|
public static final List<String> blacklistedDecoderPrefixes;
|
||||||
|
public static final List<String> spsFixupDecoderPrefixes;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
blacklistedDecoderPrefixes = new LinkedList<String>();
|
blacklistedDecoderPrefixes = new LinkedList<String>();
|
||||||
@@ -31,6 +33,24 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
blacklistedDecoderPrefixes.add("AVCDecoder");
|
blacklistedDecoderPrefixes.add("AVCDecoder");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
spsFixupDecoderPrefixes = new LinkedList<String>();
|
||||||
|
spsFixupDecoderPrefixes.add("omx.nvidia");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean decoderNeedsSpsFixup(String decoderName) {
|
||||||
|
for (String badPrefix : spsFixupDecoderPrefixes) {
|
||||||
|
if (decoderName.length() >= badPrefix.length()) {
|
||||||
|
String prefix = decoderName.substring(0, badPrefix.length());
|
||||||
|
if (prefix.equalsIgnoreCase(badPrefix)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static MediaCodecInfo findSafeDecoder() {
|
public static MediaCodecInfo findSafeDecoder() {
|
||||||
|
|
||||||
for (int i = 0; i < MediaCodecList.getCodecCount(); i++) {
|
for (int i = 0; i < MediaCodecList.getCodecCount(); i++) {
|
||||||
@@ -76,9 +96,14 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
MediaCodecInfo safeDecoder = findSafeDecoder();
|
MediaCodecInfo safeDecoder = findSafeDecoder();
|
||||||
if (safeDecoder != null) {
|
if (safeDecoder != null) {
|
||||||
videoDecoder = MediaCodec.createByCodecName(safeDecoder.getName());
|
videoDecoder = MediaCodec.createByCodecName(safeDecoder.getName());
|
||||||
|
needsSpsFixup = decoderNeedsSpsFixup(safeDecoder.getName());
|
||||||
|
if (needsSpsFixup) {
|
||||||
|
System.out.println("Decoder "+safeDecoder.getName()+" needs SPS fixup");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
videoDecoder = MediaCodec.createDecoderByType("video/avc");
|
videoDecoder = MediaCodec.createDecoderByType("video/avc");
|
||||||
|
needsSpsFixup = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", width, height);
|
MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", width, height);
|
||||||
@@ -173,6 +198,48 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
// Clear old input data
|
// Clear old input data
|
||||||
buf.clear();
|
buf.clear();
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
// We manually modify the SPS here to speed-up decoding if the decoder was flagged as needing it.
|
||||||
|
if (needsSpsFixup) {
|
||||||
|
ByteBufferDescriptor header = decodeUnit.getBufferList().get(0);
|
||||||
|
// Check for SPS NALU type
|
||||||
|
if (header.data[header.offset+4] == 0x67) {
|
||||||
|
int spsLength;
|
||||||
|
|
||||||
|
switch (header.length) {
|
||||||
|
case 26:
|
||||||
|
System.out.println("Modifying SPS (26)");
|
||||||
|
buf.put(header.data, header.offset, 24);
|
||||||
|
buf.put((byte) 0x11);
|
||||||
|
buf.put((byte) 0xe3);
|
||||||
|
buf.put((byte) 0x06);
|
||||||
|
buf.put((byte) 0x50);
|
||||||
|
spsLength = header.length + 2;
|
||||||
|
break;
|
||||||
|
case 27:
|
||||||
|
System.out.println("Modifying SPS (27)");
|
||||||
|
buf.put(header.data, header.offset, 25);
|
||||||
|
buf.put((byte) 0x04);
|
||||||
|
buf.put((byte) 0x78);
|
||||||
|
buf.put((byte) 0xc1);
|
||||||
|
buf.put((byte) 0x94);
|
||||||
|
spsLength = header.length + 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.out.println("Unknown SPS of length "+header.length);
|
||||||
|
buf.put(header.data, header.offset, header.length);
|
||||||
|
spsLength = header.length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
videoDecoder.queueInputBuffer(inputIndex,
|
||||||
|
0, spsLength,
|
||||||
|
0, decodeUnit.getFlags());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Copy data from our buffer list into the input buffer
|
// Copy data from our buffer list into the input buffer
|
||||||
for (ByteBufferDescriptor desc : decodeUnit.getBufferList())
|
for (ByteBufferDescriptor desc : decodeUnit.getBufferList())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user