mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-20 11:33:06 +00:00
Remove unnecessary byte buffer allocations in the input path
This commit is contained in:
parent
50f8f78b8d
commit
4377808896
@ -68,12 +68,14 @@ public class ControllerPacket extends InputPacket {
|
|||||||
this.rightStickX = rightStickX;
|
this.rightStickX = rightStickX;
|
||||||
this.rightStickY = rightStickY;
|
this.rightStickY = rightStickY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] toWire()
|
@Override
|
||||||
{
|
public ByteOrder getPayloadByteOrder() {
|
||||||
ByteBuffer bb = ByteBuffer.allocate(PACKET_LENGTH).order(ByteOrder.LITTLE_ENDIAN);
|
return ByteOrder.LITTLE_ENDIAN;
|
||||||
|
}
|
||||||
bb.put(toWireHeader());
|
|
||||||
|
@Override
|
||||||
|
public void toWirePayload(ByteBuffer bb) {
|
||||||
bb.put(HEADER);
|
bb.put(HEADER);
|
||||||
bb.putShort(buttonFlags);
|
bb.putShort(buttonFlags);
|
||||||
bb.put(leftTrigger);
|
bb.put(leftTrigger);
|
||||||
@ -83,7 +85,10 @@ public class ControllerPacket extends InputPacket {
|
|||||||
bb.putShort(rightStickX);
|
bb.putShort(rightStickX);
|
||||||
bb.putShort(rightStickY);
|
bb.putShort(rightStickY);
|
||||||
bb.put(TAIL);
|
bb.put(TAIL);
|
||||||
|
}
|
||||||
return bb.array();
|
|
||||||
|
@Override
|
||||||
|
public int getPacketLength() {
|
||||||
|
return PACKET_LENGTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,10 +6,10 @@ import java.net.InetAddress;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
@ -35,6 +35,10 @@ public class ControllerStream {
|
|||||||
private Thread inputThread;
|
private Thread inputThread;
|
||||||
private LinkedBlockingQueue<InputPacket> inputQueue = new LinkedBlockingQueue<InputPacket>();
|
private LinkedBlockingQueue<InputPacket> inputQueue = new LinkedBlockingQueue<InputPacket>();
|
||||||
|
|
||||||
|
private ByteBuffer littleEndianBuffer = ByteBuffer.allocate(128).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
private ByteBuffer bigEndianBuffer = ByteBuffer.allocate(128).order(ByteOrder.BIG_ENDIAN);
|
||||||
|
private ByteBuffer sendBuffer = ByteBuffer.allocate(128).order(ByteOrder.BIG_ENDIAN);
|
||||||
|
|
||||||
public ControllerStream(InetAddress host, SecretKey riKey, int riKeyId, NvConnectionListener listener)
|
public ControllerStream(InetAddress host, SecretKey riKey, int riKeyId, NvConnectionListener listener)
|
||||||
{
|
{
|
||||||
this.host = host;
|
this.host = host;
|
||||||
@ -205,39 +209,53 @@ public class ControllerStream {
|
|||||||
return ((length + 15) / 16) * 16;
|
return ((length + 15) / 16) * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] padData(byte[] data) {
|
private static int inPlacePadData(byte[] data, int length) {
|
||||||
// This implements the PKCS7 padding algorithm
|
// This implements the PKCS7 padding algorithm
|
||||||
|
|
||||||
if ((data.length % 16) == 0) {
|
if ((length % 16) == 0) {
|
||||||
// Already a multiple of 16
|
// Already a multiple of 16
|
||||||
return data;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] padded = Arrays.copyOf(data, getPaddedSize(data.length));
|
int paddedLength = getPaddedSize(length);
|
||||||
byte paddingByte = (byte)(16 - (data.length % 16));
|
byte paddingByte = (byte)(16 - (length % 16));
|
||||||
|
|
||||||
for (int i = data.length; i < padded.length; i++) {
|
for (int i = length; i < paddedLength; i++) {
|
||||||
padded[i] = paddingByte;
|
data[i] = paddingByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
return padded;
|
return paddedLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] encryptAesInputData(byte[] data) throws Exception {
|
private int encryptAesInputData(byte[] inputData, int inputLength, byte[] outputData, int outputOffset) throws Exception {
|
||||||
return riCipher.update(padData(data));
|
int encryptedLength = inPlacePadData(inputData, inputLength);
|
||||||
|
riCipher.update(inputData, 0, encryptedLength, outputData, outputOffset);
|
||||||
|
return encryptedLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendPacket(InputPacket packet) throws IOException {
|
private void sendPacket(InputPacket packet) throws IOException {
|
||||||
byte[] toWire = packet.toWire();
|
ByteBuffer toWireBuffer;
|
||||||
|
|
||||||
|
// Choose which byte order we'll be using for converting to wire form
|
||||||
|
if (packet.getPayloadByteOrder() == ByteOrder.BIG_ENDIAN) {
|
||||||
|
toWireBuffer = bigEndianBuffer;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
toWireBuffer = littleEndianBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the packet in wire form in the byte buffer
|
||||||
|
packet.toWire(toWireBuffer);
|
||||||
|
int packetLen = packet.getPacketLength();
|
||||||
|
|
||||||
// Pad to 16 byte chunks
|
// Pad to 16 byte chunks
|
||||||
int paddedLength = getPaddedSize(toWire.length);
|
int paddedLength = getPaddedSize(packetLen);
|
||||||
|
|
||||||
// Allocate a byte buffer to represent the final packet
|
// Allocate a byte buffer to represent the final packet
|
||||||
ByteBuffer bb = ByteBuffer.allocate(4 + paddedLength);
|
sendBuffer.rewind();
|
||||||
bb.putInt(paddedLength);
|
sendBuffer.putInt(paddedLength);
|
||||||
try {
|
try {
|
||||||
bb.put(encryptAesInputData(toWire));
|
encryptAesInputData(toWireBuffer.array(), packetLen, sendBuffer.array(), 4);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Should never happen
|
// Should never happen
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -245,7 +263,7 @@ public class ControllerStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send the packet
|
// Send the packet
|
||||||
out.write(bb.array());
|
out.write(sendBuffer.array(), 0, paddedLength + 4);
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,14 +13,26 @@ public abstract class InputPacket {
|
|||||||
this.packetType = packetType;
|
this.packetType = packetType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract byte[] toWire();
|
public abstract ByteOrder getPayloadByteOrder();
|
||||||
|
|
||||||
public byte[] toWireHeader()
|
public abstract void toWirePayload(ByteBuffer bb);
|
||||||
|
|
||||||
|
public abstract int getPacketLength();
|
||||||
|
|
||||||
|
public void toWireHeader(ByteBuffer bb)
|
||||||
{
|
{
|
||||||
ByteBuffer bb = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN);
|
// We don't use putInt() here because it will be subject to the byte order
|
||||||
|
// of the byte buffer. We just write it as a big endian int.
|
||||||
bb.putInt(packetType);
|
bb.put((byte)(packetType >> 24));
|
||||||
|
bb.put((byte)(packetType >> 16));
|
||||||
return bb.array();
|
bb.put((byte)(packetType >> 8));
|
||||||
|
bb.put((byte)(packetType & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toWire(ByteBuffer bb)
|
||||||
|
{
|
||||||
|
bb.rewind();
|
||||||
|
toWireHeader(bb);
|
||||||
|
toWirePayload(bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import java.nio.ByteOrder;
|
|||||||
|
|
||||||
public class KeyboardPacket extends InputPacket {
|
public class KeyboardPacket extends InputPacket {
|
||||||
private static final int PACKET_TYPE = 0x0A;
|
private static final int PACKET_TYPE = 0x0A;
|
||||||
private static final int PACKET_LENGTH = 14;
|
public static final int PACKET_LENGTH = 14;
|
||||||
|
|
||||||
public static final byte KEY_DOWN = 0x03;
|
public static final byte KEY_DOWN = 0x03;
|
||||||
public static final byte KEY_UP = 0x04;
|
public static final byte KEY_UP = 0x04;
|
||||||
@ -14,7 +14,6 @@ public class KeyboardPacket extends InputPacket {
|
|||||||
public static final byte MODIFIER_CTRL = 0x02;
|
public static final byte MODIFIER_CTRL = 0x02;
|
||||||
public static final byte MODIFIER_ALT = 0x04;
|
public static final byte MODIFIER_ALT = 0x04;
|
||||||
|
|
||||||
|
|
||||||
short keyCode;
|
short keyCode;
|
||||||
byte keyDirection;
|
byte keyDirection;
|
||||||
byte modifier;
|
byte modifier;
|
||||||
@ -25,12 +24,14 @@ public class KeyboardPacket extends InputPacket {
|
|||||||
this.keyDirection = keyDirection;
|
this.keyDirection = keyDirection;
|
||||||
this.modifier = modifier;
|
this.modifier = modifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] toWire() {
|
public ByteOrder getPayloadByteOrder() {
|
||||||
ByteBuffer bb = ByteBuffer.allocate(PACKET_LENGTH).order(ByteOrder.LITTLE_ENDIAN);
|
return ByteOrder.LITTLE_ENDIAN;
|
||||||
|
}
|
||||||
bb.put(toWireHeader());
|
|
||||||
|
@Override
|
||||||
|
public void toWirePayload(ByteBuffer bb) {
|
||||||
bb.put(keyDirection);
|
bb.put(keyDirection);
|
||||||
bb.putShort((short)0);
|
bb.putShort((short)0);
|
||||||
bb.putShort((short)0);
|
bb.putShort((short)0);
|
||||||
@ -38,7 +39,10 @@ public class KeyboardPacket extends InputPacket {
|
|||||||
bb.put(modifier);
|
bb.put(modifier);
|
||||||
bb.put((byte)0);
|
bb.put((byte)0);
|
||||||
bb.put((byte)0);
|
bb.put((byte)0);
|
||||||
|
}
|
||||||
|
|
||||||
return bb.array();
|
@Override
|
||||||
|
public int getPacketLength() {
|
||||||
|
return PACKET_LENGTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,13 +31,18 @@ public class MouseButtonPacket extends InputPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] toWire() {
|
public ByteOrder getPayloadByteOrder() {
|
||||||
ByteBuffer bb = ByteBuffer.allocate(PACKET_LENGTH).order(ByteOrder.BIG_ENDIAN);
|
return ByteOrder.BIG_ENDIAN;
|
||||||
|
}
|
||||||
bb.put(toWireHeader());
|
|
||||||
|
@Override
|
||||||
|
public void toWirePayload(ByteBuffer bb) {
|
||||||
bb.put(buttonEventType);
|
bb.put(buttonEventType);
|
||||||
bb.putInt(mouseButton);
|
bb.putInt(mouseButton);
|
||||||
|
}
|
||||||
return bb.array();
|
|
||||||
|
@Override
|
||||||
|
public int getPacketLength() {
|
||||||
|
return PACKET_LENGTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.limelight.nvstream.input;
|
package com.limelight.nvstream.input;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
public class MouseMovePacket extends InputPacket {
|
public class MouseMovePacket extends InputPacket {
|
||||||
|
|
||||||
@ -29,14 +30,19 @@ public class MouseMovePacket extends InputPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] toWire() {
|
public ByteOrder getPayloadByteOrder() {
|
||||||
ByteBuffer bb = ByteBuffer.allocate(PACKET_LENGTH);
|
return ByteOrder.BIG_ENDIAN;
|
||||||
|
}
|
||||||
bb.put(toWireHeader());
|
|
||||||
|
@Override
|
||||||
|
public void toWirePayload(ByteBuffer bb) {
|
||||||
bb.put(HEADER);
|
bb.put(HEADER);
|
||||||
bb.putShort(deltaX);
|
bb.putShort(deltaX);
|
||||||
bb.putShort(deltaY);
|
bb.putShort(deltaY);
|
||||||
|
}
|
||||||
return bb.array();
|
|
||||||
|
@Override
|
||||||
|
public int getPacketLength() {
|
||||||
|
return PACKET_LENGTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.limelight.nvstream.input;
|
package com.limelight.nvstream.input;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
public class MouseScrollPacket extends InputPacket {
|
public class MouseScrollPacket extends InputPacket {
|
||||||
public static final int PACKET_TYPE = 0xa;
|
public static final int PACKET_TYPE = 0xa;
|
||||||
@ -17,10 +18,12 @@ public class MouseScrollPacket extends InputPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] toWire() {
|
public ByteOrder getPayloadByteOrder() {
|
||||||
ByteBuffer bb = ByteBuffer.allocate(PACKET_LENGTH);
|
return ByteOrder.BIG_ENDIAN;
|
||||||
|
}
|
||||||
bb.put(toWireHeader());
|
|
||||||
|
@Override
|
||||||
|
public void toWirePayload(ByteBuffer bb) {
|
||||||
bb.put((byte) 0x09);
|
bb.put((byte) 0x09);
|
||||||
bb.put((byte) 0);
|
bb.put((byte) 0);
|
||||||
bb.put((byte) 0);
|
bb.put((byte) 0);
|
||||||
@ -30,7 +33,10 @@ public class MouseScrollPacket extends InputPacket {
|
|||||||
bb.putShort(scroll);
|
bb.putShort(scroll);
|
||||||
|
|
||||||
bb.putShort((short) 0);
|
bb.putShort((short) 0);
|
||||||
|
}
|
||||||
return bb.array();
|
|
||||||
|
@Override
|
||||||
|
public int getPacketLength() {
|
||||||
|
return PACKET_LENGTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user