mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-21 03:52:48 +00:00
Also add bitstream restrictions to Qualcomm devices to hopefully address the GS3 issue
This commit is contained in:
parent
ac5c264090
commit
b2ad259a7c
@ -48,6 +48,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
static {
|
static {
|
||||||
spsFixupBitsreamFixupDecoderPrefixes = new LinkedList<String>();
|
spsFixupBitsreamFixupDecoderPrefixes = new LinkedList<String>();
|
||||||
spsFixupBitsreamFixupDecoderPrefixes.add("omx.nvidia");
|
spsFixupBitsreamFixupDecoderPrefixes.add("omx.nvidia");
|
||||||
|
spsFixupBitsreamFixupDecoderPrefixes.add("omx.qcom");
|
||||||
|
|
||||||
spsFixupNumRefFixupDecoderPrefixes = new LinkedList<String>();
|
spsFixupNumRefFixupDecoderPrefixes = new LinkedList<String>();
|
||||||
spsFixupNumRefFixupDecoderPrefixes.add("omx.TI");
|
spsFixupNumRefFixupDecoderPrefixes.add("omx.TI");
|
||||||
@ -179,7 +180,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
if (du != null) {
|
if (du != null) {
|
||||||
if (!submitDecodeUnit(du)) {
|
if (!submitDecodeUnit(du)) {
|
||||||
// Thread was interrupted
|
// Thread was interrupted
|
||||||
depacketizer.freeDecodeUnit(du);
|
depacketizer.freeDecodeUnit(du);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -266,101 +267,101 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
inputIndex = videoDecoder.dequeueInputBuffer(100000);
|
inputIndex = videoDecoder.dequeueInputBuffer(100000);
|
||||||
} while (inputIndex < 0);
|
} while (inputIndex < 0);
|
||||||
|
|
||||||
ByteBuffer buf = videoDecoderInputBuffers[inputIndex];
|
ByteBuffer buf = videoDecoderInputBuffers[inputIndex];
|
||||||
|
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
long delta = currentTime-decodeUnit.getReceiveTimestamp();
|
long delta = currentTime-decodeUnit.getReceiveTimestamp();
|
||||||
if (delta >= 0 && delta < 300) {
|
if (delta >= 0 && delta < 300) {
|
||||||
totalTimeMs += currentTime-decodeUnit.getReceiveTimestamp();
|
totalTimeMs += currentTime-decodeUnit.getReceiveTimestamp();
|
||||||
totalFrames++;
|
totalFrames++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear old input data
|
// Clear old input data
|
||||||
buf.clear();
|
buf.clear();
|
||||||
|
|
||||||
int codecFlags = 0;
|
int codecFlags = 0;
|
||||||
int decodeUnitFlags = decodeUnit.getFlags();
|
int decodeUnitFlags = decodeUnit.getFlags();
|
||||||
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_CODEC_CONFIG) != 0) {
|
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_CODEC_CONFIG) != 0) {
|
||||||
codecFlags |= MediaCodec.BUFFER_FLAG_CODEC_CONFIG;
|
codecFlags |= MediaCodec.BUFFER_FLAG_CODEC_CONFIG;
|
||||||
}
|
}
|
||||||
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_SYNC_FRAME) != 0) {
|
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_SYNC_FRAME) != 0) {
|
||||||
codecFlags |= MediaCodec.BUFFER_FLAG_SYNC_FRAME;
|
codecFlags |= MediaCodec.BUFFER_FLAG_SYNC_FRAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_CODEC_CONFIG) != 0 &&
|
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_CODEC_CONFIG) != 0 &&
|
||||||
(needsSpsBitstreamFixup || needsSpsNumRefFixup)) {
|
(needsSpsBitstreamFixup || needsSpsNumRefFixup)) {
|
||||||
ByteBufferDescriptor header = decodeUnit.getBufferList().get(0);
|
ByteBufferDescriptor header = decodeUnit.getBufferList().get(0);
|
||||||
if (header.data[header.offset+4] == 0x67) {
|
if (header.data[header.offset+4] == 0x67) {
|
||||||
byte last = header.data[header.length+header.offset-1];
|
byte last = header.data[header.length+header.offset-1];
|
||||||
|
|
||||||
// TI OMAP4 requires a reference frame count of 1 to decode successfully
|
// TI OMAP4 requires a reference frame count of 1 to decode successfully
|
||||||
if (needsSpsNumRefFixup) {
|
if (needsSpsNumRefFixup) {
|
||||||
LimeLog.info("Fixing up num ref frames");
|
LimeLog.info("Fixing up num ref frames");
|
||||||
this.replace(header, 80, 9, new byte[] {0x40}, 3);
|
this.replace(header, 80, 9, new byte[] {0x40}, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The SPS that comes in the current H264 bytestream doesn't set bitstream_restriction_flag
|
// 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.
|
// 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.
|
// We manually modify the SPS here to speed-up decoding if the decoder was flagged as needing it.
|
||||||
int spsLength;
|
int spsLength;
|
||||||
if (needsSpsBitstreamFixup) {
|
if (needsSpsBitstreamFixup) {
|
||||||
if (!needsSpsNumRefFixup) {
|
if (!needsSpsNumRefFixup) {
|
||||||
switch (header.length) {
|
switch (header.length) {
|
||||||
case 26:
|
case 26:
|
||||||
LimeLog.info("Adding bitstream restrictions to SPS (26)");
|
LimeLog.info("Adding bitstream restrictions to SPS (26)");
|
||||||
buf.put(header.data, header.offset, 24);
|
buf.put(header.data, header.offset, 24);
|
||||||
buf.put((byte) 0x11);
|
buf.put((byte) 0x11);
|
||||||
buf.put((byte) 0xe3);
|
buf.put((byte) 0xe3);
|
||||||
buf.put((byte) 0x06);
|
buf.put((byte) 0x06);
|
||||||
buf.put((byte) 0x50);
|
buf.put((byte) 0x50);
|
||||||
spsLength = header.length + 2;
|
spsLength = header.length + 2;
|
||||||
break;
|
break;
|
||||||
case 27:
|
case 27:
|
||||||
LimeLog.info("Adding bitstream restrictions to SPS (27)");
|
LimeLog.info("Adding bitstream restrictions to SPS (27)");
|
||||||
buf.put(header.data, header.offset, 25);
|
buf.put(header.data, header.offset, 25);
|
||||||
buf.put((byte) 0x04);
|
buf.put((byte) 0x04);
|
||||||
buf.put((byte) 0x78);
|
buf.put((byte) 0x78);
|
||||||
buf.put((byte) 0xc1);
|
buf.put((byte) 0xc1);
|
||||||
buf.put((byte) 0x94);
|
buf.put((byte) 0x94);
|
||||||
spsLength = header.length + 2;
|
spsLength = header.length + 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LimeLog.warning("Unknown SPS of length "+header.length);
|
LimeLog.warning("Unknown SPS of length "+header.length);
|
||||||
buf.put(header.data, header.offset, header.length);
|
|
||||||
spsLength = header.length;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Set bitstream restrictions to only buffer single frame
|
|
||||||
// (starts 9 bits before stop bit and 6 bits earlier because of the shortening above)
|
|
||||||
this.replace(header, header.length*8+Integer.numberOfLeadingZeros(last & - last)%8-9-6, 2, BITSTREAM_RESTRICTIONS, 3*8);
|
|
||||||
buf.put(header.data, header.offset, header.length);
|
buf.put(header.data, header.offset, header.length);
|
||||||
spsLength = header.length;
|
spsLength = header.length;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Set bitstream restrictions to only buffer single frame
|
||||||
|
// (starts 9 bits before stop bit and 6 bits earlier because of the shortening above)
|
||||||
|
this.replace(header, header.length*8+Integer.numberOfLeadingZeros(last & - last)%8-9-6, 2, BITSTREAM_RESTRICTIONS, 3*8);
|
||||||
buf.put(header.data, header.offset, header.length);
|
buf.put(header.data, header.offset, header.length);
|
||||||
spsLength = header.length;
|
spsLength = header.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
videoDecoder.queueInputBuffer(inputIndex,
|
|
||||||
0, spsLength,
|
|
||||||
currentTime * 1000, codecFlags);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
buf.put(header.data, header.offset, header.length);
|
||||||
|
spsLength = header.length;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy data from our buffer list into the input buffer
|
videoDecoder.queueInputBuffer(inputIndex,
|
||||||
for (ByteBufferDescriptor desc : decodeUnit.getBufferList())
|
0, spsLength,
|
||||||
{
|
currentTime * 1000, codecFlags);
|
||||||
buf.put(desc.data, desc.offset, desc.length);
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
videoDecoder.queueInputBuffer(inputIndex,
|
// Copy data from our buffer list into the input buffer
|
||||||
0, decodeUnit.getDataLength(),
|
for (ByteBufferDescriptor desc : decodeUnit.getBufferList())
|
||||||
currentTime * 1000, codecFlags);
|
{
|
||||||
|
buf.put(desc.data, desc.offset, desc.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
videoDecoder.queueInputBuffer(inputIndex,
|
||||||
|
0, decodeUnit.getDataLength(),
|
||||||
|
currentTime * 1000, codecFlags);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user