Use an unsynchronized buffer list to cut down on overhead when using direct submit video renderers

This commit is contained in:
Cameron Gutman 2015-03-09 01:38:22 -05:00
parent c481841ddf
commit 1ac6439690
2 changed files with 29 additions and 6 deletions

View File

@ -7,8 +7,10 @@ import com.limelight.LimeLog;
import com.limelight.nvstream.av.ByteBufferDescriptor; import com.limelight.nvstream.av.ByteBufferDescriptor;
import com.limelight.nvstream.av.DecodeUnit; import com.limelight.nvstream.av.DecodeUnit;
import com.limelight.nvstream.av.ConnectionStatusListener; import com.limelight.nvstream.av.ConnectionStatusListener;
import com.limelight.nvstream.av.PopulatedBufferList;
import com.limelight.nvstream.av.SequenceHelper; import com.limelight.nvstream.av.SequenceHelper;
import com.limelight.nvstream.av.buffer.AbstractPopulatedBufferList;
import com.limelight.nvstream.av.buffer.AtomicPopulatedBufferList;
import com.limelight.nvstream.av.buffer.UnsynchronizedPopulatedBufferList;
public class VideoDepacketizer { public class VideoDepacketizer {
@ -37,14 +39,14 @@ public class VideoDepacketizer {
private int consecutiveFrameDrops = 0; private int consecutiveFrameDrops = 0;
private static final int DU_LIMIT = 15; private static final int DU_LIMIT = 15;
private PopulatedBufferList<DecodeUnit> decodedUnits; private AbstractPopulatedBufferList<DecodeUnit> decodedUnits;
public VideoDepacketizer(ConnectionStatusListener controlListener, int nominalPacketSize) public VideoDepacketizer(ConnectionStatusListener controlListener, int nominalPacketSize, boolean unsynchronized)
{ {
this.controlListener = controlListener; this.controlListener = controlListener;
this.nominalPacketDataLength = nominalPacketSize - VideoPacket.HEADER_SIZE; this.nominalPacketDataLength = nominalPacketSize - VideoPacket.HEADER_SIZE;
decodedUnits = new PopulatedBufferList<DecodeUnit>(DU_LIMIT, new PopulatedBufferList.BufferFactory() { AbstractPopulatedBufferList.BufferFactory factory = new AbstractPopulatedBufferList.BufferFactory() {
public Object createFreeBuffer() { public Object createFreeBuffer() {
return new DecodeUnit(); return new DecodeUnit();
} }
@ -58,7 +60,14 @@ public class VideoDepacketizer {
} }
du.clearBackingPackets(); du.clearBackingPackets();
} }
}); };
if (unsynchronized) {
decodedUnits = new UnsynchronizedPopulatedBufferList<DecodeUnit>(DU_LIMIT, factory);
}
else {
decodedUnits = new AtomicPopulatedBufferList<DecodeUnit>(DU_LIMIT, factory);
}
} }
private void dropAvcFrameState() private void dropAvcFrameState()

View File

@ -11,6 +11,7 @@ import java.util.LinkedList;
import com.limelight.LimeLog; import com.limelight.LimeLog;
import com.limelight.nvstream.ConnectionContext; import com.limelight.nvstream.ConnectionContext;
import com.limelight.nvstream.av.ConnectionStatusListener; import com.limelight.nvstream.av.ConnectionStatusListener;
import com.limelight.nvstream.av.DecodeUnit;
import com.limelight.nvstream.av.RtpPacket; import com.limelight.nvstream.av.RtpPacket;
import com.limelight.nvstream.av.RtpReorderQueue; import com.limelight.nvstream.av.RtpReorderQueue;
@ -117,7 +118,8 @@ public class VideoStream {
public boolean setupDecoderRenderer(VideoDecoderRenderer decRend, Object renderTarget, int drFlags) { public boolean setupDecoderRenderer(VideoDecoderRenderer decRend, Object renderTarget, int drFlags) {
this.decRend = decRend; this.decRend = decRend;
depacketizer = new VideoDepacketizer(avConnListener, context.streamConfig.getMaxPacketSize()); depacketizer = new VideoDepacketizer(avConnListener, context.streamConfig.getMaxPacketSize(),
decRend != null && (decRend.getCapabilities() & VideoDecoderRenderer.CAPABILITY_DIRECT_SUBMIT) != 0);
if (decRend != null) { if (decRend != null) {
try { try {
@ -193,6 +195,9 @@ public class VideoStream {
ring[i] = new VideoPacket(new byte[requiredBufferSize]); ring[i] = new VideoPacket(new byte[requiredBufferSize]);
} }
boolean directSubmit = (decRend != null && (decRend.getCapabilities() &
VideoDecoderRenderer.CAPABILITY_DIRECT_SUBMIT) != 0);
byte[] buffer; byte[] buffer;
DatagramPacket packet = new DatagramPacket(new byte[1], 1); // Placeholder array DatagramPacket packet = new DatagramPacket(new byte[1], 1); // Placeholder array
int iterationStart; int iterationStart;
@ -221,6 +226,15 @@ public class VideoStream {
} }
} }
// If the DR supports direct submission, call the direct submit callback
if (directSubmit) {
DecodeUnit du;
while ((du = depacketizer.pollNextDecodeUnit()) != null) {
decRend.directSubmitDecodeUnit(du);
}
}
// Go to the next free element in the ring // Go to the next free element in the ring
iterationStart = ringIndex; iterationStart = ringIndex;
do { do {