mirror of
https://github.com/moonlight-stream/moonlight-embedded.git
synced 2026-04-23 00:26:42 +00:00
Set number of reference frames in SPS to 1 as fix for newer firmwares using new bitstream replacement code
This commit is contained in:
@@ -12,7 +12,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class OmxDecoderRenderer implements VideoDecoderRenderer {
|
public class OmxDecoderRenderer implements VideoDecoderRenderer {
|
||||||
|
|
||||||
private final static int BITSTREAM_RESTRICTIONS = (int) 0xF1832C00l;
|
private final static byte[] BITSTREAM_RESTRICTIONS = new byte[] {(byte) 0xF1, (byte) 0x83, 0x2C, 0x00};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
||||||
@@ -41,30 +41,13 @@ public class OmxDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
List<ByteBufferDescriptor> units = decodeUnit.getBufferList();
|
List<ByteBufferDescriptor> units = decodeUnit.getBufferList();
|
||||||
|
|
||||||
ByteBufferDescriptor header = units.get(0);
|
ByteBufferDescriptor header = units.get(0);
|
||||||
if (header.data[header.offset+4] == 0x67) {
|
if (header.data[header.offset+4] == 0x67) {
|
||||||
|
//Set number of reference frames back to 1 as it's the minimum for bitstream restrictions
|
||||||
|
this.replace(header, 80, 9, new byte[] {0x40}, 3);
|
||||||
|
|
||||||
|
//Set bitstream restrictions to only buffer single frame
|
||||||
byte last = header.data[header.length+header.offset-1];
|
byte last = header.data[header.length+header.offset-1];
|
||||||
//Start bit before stop bit
|
this.replace(header, header.length*8+Integer.numberOfLeadingZeros(last & - last)%8-9, 2, BITSTREAM_RESTRICTIONS, 3*8);
|
||||||
int shift = (Integer.numberOfLeadingZeros(last & - last) - 1)%8;
|
|
||||||
int bitstream_restriction = BITSTREAM_RESTRICTIONS >>> shift;
|
|
||||||
boolean twoBytes = shift==7;
|
|
||||||
int index = header.length - (twoBytes?2:1);
|
|
||||||
|
|
||||||
header.length += twoBytes?1:2;
|
|
||||||
if (Integer.numberOfTrailingZeros(bitstream_restriction) < 8)
|
|
||||||
header.length++;
|
|
||||||
|
|
||||||
byte[] newArray = new byte[header.length];
|
|
||||||
System.arraycopy(header.data, header.offset, newArray, 0, header.length-1);
|
|
||||||
|
|
||||||
newArray[index] = (byte) (((int) header.data[index + header.offset] & 0xFF) | (bitstream_restriction >>> 24));
|
|
||||||
newArray[index+1] = (byte) ((twoBytes?((int) header.data[index+1 + header.offset] & 0xFF):0) | (bitstream_restriction >>> 16));
|
|
||||||
newArray[index+2] = (byte) (bitstream_restriction >>> 8);
|
|
||||||
|
|
||||||
if (Integer.numberOfTrailingZeros(bitstream_restriction) < 8)
|
|
||||||
newArray[index+3] = (byte) (bitstream_restriction);
|
|
||||||
|
|
||||||
header.data = newArray;
|
|
||||||
header.offset = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<units.size();i++) {
|
for (int i=0;i<units.size();i++) {
|
||||||
@@ -81,4 +64,73 @@ public class OmxDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
return CAPABILITY_DIRECT_SUBMIT;
|
return CAPABILITY_DIRECT_SUBMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace bits in array
|
||||||
|
* @param source array in which bits should be replaced
|
||||||
|
* @param srcOffset offset in bits where replacement should take place
|
||||||
|
* @param srcLength length in bits of data that should be replaced
|
||||||
|
* @param data data array with the the replacement data
|
||||||
|
* @param dataLength length of replacement data in bits
|
||||||
|
*/
|
||||||
|
public void replace(ByteBufferDescriptor source, int srcOffset, int srcLength, byte[] data, int dataLength) {
|
||||||
|
//Add 7 to always round up
|
||||||
|
int length = (source.length*8-srcLength+dataLength+7)/8;
|
||||||
|
byte dest[] = new byte[length];
|
||||||
|
|
||||||
|
int bitOffset = srcOffset%8;
|
||||||
|
int byteOffset = srcOffset/8;
|
||||||
|
|
||||||
|
//Copy the first bytes
|
||||||
|
System.arraycopy(source.data, source.offset, dest, 0, byteOffset);
|
||||||
|
|
||||||
|
int byteLength = (bitOffset+dataLength+7)/8;
|
||||||
|
int bitTrailing = 8 - (srcOffset+dataLength) % 8;
|
||||||
|
for (int i=0;i<byteLength;i++) {
|
||||||
|
byte result = 0;
|
||||||
|
if (i != 0)
|
||||||
|
result = (byte) (data[i-1] << 8-bitOffset);
|
||||||
|
else if (bitOffset > 0)
|
||||||
|
result = (byte) (source.data[byteOffset+source.offset] & (0xFF << 8-bitOffset));
|
||||||
|
|
||||||
|
if (i == 0 || i != byteLength-1) {
|
||||||
|
byte moved = (byte) ((data[i]&0xFF) >>> bitOffset);
|
||||||
|
result |= moved;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == byteLength-1 && bitTrailing > 0) {
|
||||||
|
int sourceOffset = srcOffset+srcLength/8;
|
||||||
|
int bitMove = (dataLength-srcLength)%8;
|
||||||
|
if (bitMove<0) {
|
||||||
|
result |= (byte) (source.data[sourceOffset+source.offset] << -bitMove & (0xFF >>> bitTrailing));
|
||||||
|
result |= (byte) (source.data[sourceOffset+1+source.offset] << -bitMove & (0xFF >>> 8+bitMove));
|
||||||
|
} else {
|
||||||
|
byte moved = (byte) ((source.data[sourceOffset+source.offset]&0xFF) >>> bitOffset);
|
||||||
|
result |= moved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dest[i+byteOffset] = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Source offset
|
||||||
|
byteOffset += srcLength/8;
|
||||||
|
bitOffset = (srcOffset+dataLength-srcLength)%8;
|
||||||
|
|
||||||
|
//Offset in destination
|
||||||
|
int destOffset = (srcOffset+dataLength)/8;
|
||||||
|
|
||||||
|
for (int i=1;i<source.length-byteOffset;i++) {
|
||||||
|
byte result = 0;
|
||||||
|
result = (byte) (source.data[byteOffset+i-1+source.offset] << 8-bitOffset);
|
||||||
|
byte moved = (byte) ((source.data[byteOffset+i+source.offset]&0xFF) >>> bitOffset);
|
||||||
|
result ^= moved;
|
||||||
|
|
||||||
|
dest[i+destOffset] = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
source.data = dest;
|
||||||
|
source.offset = 0;
|
||||||
|
source.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user