mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-20 03:23:07 +00:00
Use ring buffers for audio and video handling to remove the last large allocations that were happening very frequently
This commit is contained in:
parent
a39f4c5eab
commit
8c9d0d171c
@ -12,9 +12,14 @@ public class AudioDepacketizer {
|
||||
private LinkedBlockingQueue<ByteBufferDescriptor> decodedUnits =
|
||||
new LinkedBlockingQueue<ByteBufferDescriptor>(DU_LIMIT);
|
||||
|
||||
// Direct submit state
|
||||
private AudioRenderer directSubmitRenderer;
|
||||
private byte[] directSubmitData;
|
||||
|
||||
// Non-direct submit state
|
||||
private byte[][] pcmRing;
|
||||
private int ringIndex;
|
||||
|
||||
// Sequencing state
|
||||
private short lastSequenceNumber;
|
||||
|
||||
@ -24,6 +29,9 @@ public class AudioDepacketizer {
|
||||
if (directSubmitRenderer != null) {
|
||||
this.directSubmitData = new byte[OpusDecoder.getMaxOutputShorts()*2];
|
||||
}
|
||||
else {
|
||||
pcmRing = new byte[DU_LIMIT][OpusDecoder.getMaxOutputShorts()*2];
|
||||
}
|
||||
}
|
||||
|
||||
private void decodeData(byte[] data, int off, int len)
|
||||
@ -36,11 +44,11 @@ public class AudioDepacketizer {
|
||||
decodeLen = OpusDecoder.decode(data, off, len, directSubmitData);
|
||||
}
|
||||
else {
|
||||
pcmData = new byte[OpusDecoder.getMaxOutputShorts()*2];
|
||||
pcmData = pcmRing[ringIndex];
|
||||
decodeLen = OpusDecoder.decode(data, off, len, pcmData);
|
||||
ringIndex = (ringIndex + 1) % DU_LIMIT;
|
||||
}
|
||||
|
||||
|
||||
if (decodeLen > 0) {
|
||||
// Return value of decode is frames (shorts) decoded per channel
|
||||
decodeLen *= 2*OpusDecoder.getChannelCount();
|
||||
|
@ -24,8 +24,14 @@ public class VideoStream {
|
||||
|
||||
public static final int FIRST_FRAME_TIMEOUT = 5000;
|
||||
public static final int RTP_RECV_BUFFER = 128 * 1024;
|
||||
|
||||
public static final int MAX_PACKET_SIZE = 1050;
|
||||
|
||||
// The ring size MUST be greater than or equal to
|
||||
// the maximum number of packets in a fully
|
||||
// presentable frame
|
||||
public static final int VIDEO_RING_SIZE = 192;
|
||||
|
||||
private InetAddress host;
|
||||
private DatagramSocket rtp;
|
||||
private Socket firstFrameSocket;
|
||||
@ -211,22 +217,36 @@ public class VideoStream {
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
ByteBufferDescriptor desc = new ByteBufferDescriptor(new byte[MAX_PACKET_SIZE], 0, MAX_PACKET_SIZE);
|
||||
DatagramPacket packet = new DatagramPacket(desc.data, desc.length);
|
||||
ByteBufferDescriptor ring[] = new ByteBufferDescriptor[VIDEO_RING_SIZE];
|
||||
int ringIndex = 0;
|
||||
|
||||
// Preinitialize the ring buffer
|
||||
for (int i = 0; i < VIDEO_RING_SIZE; i++) {
|
||||
ring[i] = new ByteBufferDescriptor(new byte[MAX_PACKET_SIZE], 0, MAX_PACKET_SIZE);
|
||||
}
|
||||
|
||||
ByteBufferDescriptor desc;
|
||||
DatagramPacket packet = new DatagramPacket(new byte[1], 1); // Placeholder array
|
||||
while (!isInterrupted())
|
||||
{
|
||||
try {
|
||||
// Pull the next buffer in the ring and reset it
|
||||
desc = ring[ringIndex];
|
||||
desc.length = MAX_PACKET_SIZE;
|
||||
desc.offset = 0;
|
||||
|
||||
// Read the video data off the network
|
||||
packet.setData(desc.data, desc.offset, desc.length);
|
||||
rtp.receive(packet);
|
||||
|
||||
// Submit video data to the depacketizer
|
||||
desc.length = packet.getLength();
|
||||
depacketizer.addInputData(new RtpPacket(desc));
|
||||
desc.reinitialize(new byte[MAX_PACKET_SIZE], 0, MAX_PACKET_SIZE);
|
||||
packet.setData(desc.data, desc.offset, desc.length);
|
||||
ringIndex = (ringIndex + 1) % VIDEO_RING_SIZE;
|
||||
} catch (IOException e) {
|
||||
listener.connectionTerminated(e);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user