Allow configuration of maximum packet size

This commit is contained in:
Cameron Gutman 2014-06-22 17:06:28 -07:00
parent 86e2657613
commit c9e5230e37
5 changed files with 28 additions and 10 deletions

View File

@ -4,12 +4,22 @@ public class StreamConfiguration {
private int width, height; private int width, height;
private int refreshRate; private int refreshRate;
private int bitrate; private int bitrate;
private int maxPacketSize;
public StreamConfiguration(int width, int height, int refreshRate, int bitrate) { public StreamConfiguration(int width, int height, int refreshRate, int bitrate) {
this.width = width; this.width = width;
this.height = height; this.height = height;
this.refreshRate = refreshRate; this.refreshRate = refreshRate;
this.bitrate = bitrate; 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() { public int getWidth() {
@ -27,4 +37,8 @@ public class StreamConfiguration {
public int getBitrate() { public int getBitrate() {
return bitrate; return bitrate;
} }
public int getMaxPacketSize() {
return maxPacketSize;
}
} }

View File

@ -29,13 +29,15 @@ public class VideoDepacketizer {
private ByteBufferDescriptor cachedSpecialDesc = new ByteBufferDescriptor(null, 0, 0); private ByteBufferDescriptor cachedSpecialDesc = new ByteBufferDescriptor(null, 0, 0);
private ConnectionStatusListener controlListener; private ConnectionStatusListener controlListener;
private int nominalPacketSize;
private static final int DU_LIMIT = 15; private static final int DU_LIMIT = 15;
private LinkedBlockingQueue<DecodeUnit> decodedUnits = new LinkedBlockingQueue<DecodeUnit>(DU_LIMIT); private LinkedBlockingQueue<DecodeUnit> decodedUnits = new LinkedBlockingQueue<DecodeUnit>(DU_LIMIT);
public VideoDepacketizer(ConnectionStatusListener controlListener) public VideoDepacketizer(ConnectionStatusListener controlListener, int nominalPacketSize)
{ {
this.controlListener = controlListener; this.controlListener = controlListener;
this.nominalPacketSize = nominalPacketSize;
} }
private void clearAvcFrameState() private void clearAvcFrameState()
@ -175,7 +177,7 @@ public class VideoDepacketizer {
// Runt packets get decoded using the slow path // Runt packets get decoded using the slow path
// These packets stand alone so there's no need to verify // These packets stand alone so there's no need to verify
// sequencing before submitting // sequencing before submitting
if (cachedReassemblyDesc.length < 968) { if (cachedReassemblyDesc.length < nominalPacketSize - VideoPacket.HEADER_SIZE) {
addInputDataSlow(packet, cachedReassemblyDesc); addInputDataSlow(packet, cachedReassemblyDesc);
return; return;
} }

View File

@ -22,6 +22,8 @@ public class VideoPacket {
public static final int FLAG_EOF = 0x2; public static final int FLAG_EOF = 0x2;
public static final int FLAG_SOF = 0x4; public static final int FLAG_SOF = 0x4;
public static final int HEADER_SIZE = 56;
public VideoPacket(byte[] buffer) public VideoPacket(byte[] buffer)
{ {
this.buffer = new ByteBufferDescriptor(buffer, 0, buffer.length); this.buffer = new ByteBufferDescriptor(buffer, 0, buffer.length);
@ -39,7 +41,7 @@ public class VideoPacket {
streamPacketIndex = byteBuffer.getInt(); streamPacketIndex = byteBuffer.getInt();
// Data offset without the RTP header // Data offset without the RTP header
dataOffset = 56; dataOffset = HEADER_SIZE;
// Update descriptor length // Update descriptor length
buffer.length = length; buffer.length = length;
@ -59,7 +61,7 @@ public class VideoPacket {
streamPacketIndex = byteBuffer.getInt(); streamPacketIndex = byteBuffer.getInt();
// Data offset includes the RTP header // Data offset includes the RTP header
dataOffset = RtpPacket.HEADER_SIZE + 56; dataOffset = RtpPacket.HEADER_SIZE + HEADER_SIZE;
// Update descriptor length // Update descriptor length
buffer.length = length; buffer.length = length;

View File

@ -13,6 +13,7 @@ import java.util.LinkedList;
import com.limelight.nvstream.NvConnectionListener; import com.limelight.nvstream.NvConnectionListener;
import com.limelight.nvstream.StreamConfiguration; import com.limelight.nvstream.StreamConfiguration;
import com.limelight.nvstream.av.ConnectionStatusListener; import com.limelight.nvstream.av.ConnectionStatusListener;
import com.limelight.nvstream.av.RtpPacket;
public class VideoStream { public class VideoStream {
public static final int RTP_PORT = 47998; 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 FIRST_FRAME_TIMEOUT = 5000;
public static final int RTP_RECV_BUFFER = 256 * 1024; 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 ring size MUST be greater than or equal to
// the maximum number of packets in a fully // the maximum number of packets in a fully
// presentable frame // presentable frame
@ -96,7 +95,7 @@ public class VideoStream {
private void readFirstFrame() throws IOException private void readFirstFrame() throws IOException
{ {
byte[] firstFrame = new byte[MAX_PACKET_SIZE]; byte[] firstFrame = new byte[streamConfig.getMaxPacketSize()];
firstFrameSocket = new Socket(); firstFrameSocket = new Socket();
firstFrameSocket.setSoTimeout(FIRST_FRAME_TIMEOUT); firstFrameSocket.setSoTimeout(FIRST_FRAME_TIMEOUT);
@ -139,7 +138,7 @@ public class VideoStream {
decRend.setup(streamConfig.getWidth(), streamConfig.getHeight(), decRend.setup(streamConfig.getWidth(), streamConfig.getHeight(),
60, renderTarget, drFlags); 60, renderTarget, drFlags);
depacketizer = new VideoDepacketizer(avConnListener); depacketizer = new VideoDepacketizer(avConnListener, streamConfig.getMaxPacketSize());
} }
} }
@ -183,8 +182,9 @@ public class VideoStream {
int ringIndex = 0; int ringIndex = 0;
// Preinitialize the ring buffer // Preinitialize the ring buffer
int requiredBufferSize = streamConfig.getMaxPacketSize() + RtpPacket.HEADER_SIZE;
for (int i = 0; i < VIDEO_RING_SIZE; i++) { 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; byte[] buffer;

View File

@ -139,7 +139,7 @@ public class SdpGenerator {
addSessionAttribute(config, "x-nv-video[0].vbvMultiplier", "100"); addSessionAttribute(config, "x-nv-video[0].vbvMultiplier", "100");
addSessionAttribute(config, "x-nv-video[0].slicesPerFrame", "4"); addSessionAttribute(config, "x-nv-video[0].slicesPerFrame", "4");
addSessionAttribute(config, "x-nv-video[0].numTemporalLayers", "0"); 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].enableSubframeEncoding", "0");
addSessionAttribute(config, "x-nv-video[0].refPicInvalidation", "1"); addSessionAttribute(config, "x-nv-video[0].refPicInvalidation", "1");
addSessionAttribute(config, "x-nv-video[0].pingBackIntervalMs", "3000"); addSessionAttribute(config, "x-nv-video[0].pingBackIntervalMs", "3000");