From c9e5230e37ca489126755f24a676e071fd4fc40f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 22 Jun 2014 17:06:28 -0700 Subject: [PATCH] Allow configuration of maximum packet size --- .../limelight/nvstream/StreamConfiguration.java | 14 ++++++++++++++ .../nvstream/av/video/VideoDepacketizer.java | 6 ++++-- .../limelight/nvstream/av/video/VideoPacket.java | 6 ++++-- .../limelight/nvstream/av/video/VideoStream.java | 10 +++++----- .../com/limelight/nvstream/rtsp/SdpGenerator.java | 2 +- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/moonlight-common/src/com/limelight/nvstream/StreamConfiguration.java b/moonlight-common/src/com/limelight/nvstream/StreamConfiguration.java index 33789db0..33159953 100644 --- a/moonlight-common/src/com/limelight/nvstream/StreamConfiguration.java +++ b/moonlight-common/src/com/limelight/nvstream/StreamConfiguration.java @@ -4,12 +4,22 @@ public class StreamConfiguration { private int width, height; private int refreshRate; private int bitrate; + private int maxPacketSize; public StreamConfiguration(int width, int height, int refreshRate, int bitrate) { this.width = width; this.height = height; this.refreshRate = refreshRate; this.bitrate = bitrate; + this.maxPacketSize = 1024; + } + + public StreamConfiguration(int width, int height, int refreshRate, int bitrate, int maxPacketSize) { + this.width = width; + this.height = height; + this.refreshRate = refreshRate; + this.bitrate = bitrate; + this.maxPacketSize = maxPacketSize; } public int getWidth() { @@ -27,4 +37,8 @@ public class StreamConfiguration { public int getBitrate() { return bitrate; } + + public int getMaxPacketSize() { + return maxPacketSize; + } } diff --git a/moonlight-common/src/com/limelight/nvstream/av/video/VideoDepacketizer.java b/moonlight-common/src/com/limelight/nvstream/av/video/VideoDepacketizer.java index db4c3102..dfde336f 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/video/VideoDepacketizer.java +++ b/moonlight-common/src/com/limelight/nvstream/av/video/VideoDepacketizer.java @@ -29,13 +29,15 @@ public class VideoDepacketizer { private ByteBufferDescriptor cachedSpecialDesc = new ByteBufferDescriptor(null, 0, 0); private ConnectionStatusListener controlListener; + private int nominalPacketSize; private static final int DU_LIMIT = 15; private LinkedBlockingQueue decodedUnits = new LinkedBlockingQueue(DU_LIMIT); - public VideoDepacketizer(ConnectionStatusListener controlListener) + public VideoDepacketizer(ConnectionStatusListener controlListener, int nominalPacketSize) { this.controlListener = controlListener; + this.nominalPacketSize = nominalPacketSize; } private void clearAvcFrameState() @@ -175,7 +177,7 @@ public class VideoDepacketizer { // Runt packets get decoded using the slow path // These packets stand alone so there's no need to verify // sequencing before submitting - if (cachedReassemblyDesc.length < 968) { + if (cachedReassemblyDesc.length < nominalPacketSize - VideoPacket.HEADER_SIZE) { addInputDataSlow(packet, cachedReassemblyDesc); return; } diff --git a/moonlight-common/src/com/limelight/nvstream/av/video/VideoPacket.java b/moonlight-common/src/com/limelight/nvstream/av/video/VideoPacket.java index cebdc707..618da91c 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/video/VideoPacket.java +++ b/moonlight-common/src/com/limelight/nvstream/av/video/VideoPacket.java @@ -22,6 +22,8 @@ public class VideoPacket { public static final int FLAG_EOF = 0x2; public static final int FLAG_SOF = 0x4; + public static final int HEADER_SIZE = 56; + public VideoPacket(byte[] buffer) { this.buffer = new ByteBufferDescriptor(buffer, 0, buffer.length); @@ -39,7 +41,7 @@ public class VideoPacket { streamPacketIndex = byteBuffer.getInt(); // Data offset without the RTP header - dataOffset = 56; + dataOffset = HEADER_SIZE; // Update descriptor length buffer.length = length; @@ -59,7 +61,7 @@ public class VideoPacket { streamPacketIndex = byteBuffer.getInt(); // Data offset includes the RTP header - dataOffset = RtpPacket.HEADER_SIZE + 56; + dataOffset = RtpPacket.HEADER_SIZE + HEADER_SIZE; // Update descriptor length buffer.length = length; diff --git a/moonlight-common/src/com/limelight/nvstream/av/video/VideoStream.java b/moonlight-common/src/com/limelight/nvstream/av/video/VideoStream.java index 75967226..90a16ec0 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/video/VideoStream.java +++ b/moonlight-common/src/com/limelight/nvstream/av/video/VideoStream.java @@ -13,6 +13,7 @@ import java.util.LinkedList; import com.limelight.nvstream.NvConnectionListener; import com.limelight.nvstream.StreamConfiguration; import com.limelight.nvstream.av.ConnectionStatusListener; +import com.limelight.nvstream.av.RtpPacket; public class VideoStream { public static final int RTP_PORT = 47998; @@ -22,8 +23,6 @@ public class VideoStream { public static final int FIRST_FRAME_TIMEOUT = 5000; public static final int RTP_RECV_BUFFER = 256 * 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 @@ -96,7 +95,7 @@ public class VideoStream { private void readFirstFrame() throws IOException { - byte[] firstFrame = new byte[MAX_PACKET_SIZE]; + byte[] firstFrame = new byte[streamConfig.getMaxPacketSize()]; firstFrameSocket = new Socket(); firstFrameSocket.setSoTimeout(FIRST_FRAME_TIMEOUT); @@ -139,7 +138,7 @@ public class VideoStream { decRend.setup(streamConfig.getWidth(), streamConfig.getHeight(), 60, renderTarget, drFlags); - depacketizer = new VideoDepacketizer(avConnListener); + depacketizer = new VideoDepacketizer(avConnListener, streamConfig.getMaxPacketSize()); } } @@ -183,8 +182,9 @@ public class VideoStream { int ringIndex = 0; // Preinitialize the ring buffer + int requiredBufferSize = streamConfig.getMaxPacketSize() + RtpPacket.HEADER_SIZE; for (int i = 0; i < VIDEO_RING_SIZE; i++) { - ring[i] = new VideoPacket(new byte[MAX_PACKET_SIZE]); + ring[i] = new VideoPacket(new byte[requiredBufferSize]); } byte[] buffer; diff --git a/moonlight-common/src/com/limelight/nvstream/rtsp/SdpGenerator.java b/moonlight-common/src/com/limelight/nvstream/rtsp/SdpGenerator.java index 5253f95e..6537ed93 100644 --- a/moonlight-common/src/com/limelight/nvstream/rtsp/SdpGenerator.java +++ b/moonlight-common/src/com/limelight/nvstream/rtsp/SdpGenerator.java @@ -139,7 +139,7 @@ public class SdpGenerator { addSessionAttribute(config, "x-nv-video[0].vbvMultiplier", "100"); addSessionAttribute(config, "x-nv-video[0].slicesPerFrame", "4"); addSessionAttribute(config, "x-nv-video[0].numTemporalLayers", "0"); - addSessionAttribute(config, "x-nv-video[0].packetSize", "1024"); + addSessionAttribute(config, "x-nv-video[0].packetSize", ""+sc.getMaxPacketSize()); addSessionAttribute(config, "x-nv-video[0].enableSubframeEncoding", "0"); addSessionAttribute(config, "x-nv-video[0].refPicInvalidation", "1"); addSessionAttribute(config, "x-nv-video[0].pingBackIntervalMs", "3000");