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.DecodeUnit;
import com.limelight.nvstream.av.ConnectionStatusListener;
import com.limelight.nvstream.av.PopulatedBufferList;
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 {
@ -37,14 +39,14 @@ public class VideoDepacketizer {
private int consecutiveFrameDrops = 0;
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.nominalPacketDataLength = nominalPacketSize - VideoPacket.HEADER_SIZE;
decodedUnits = new PopulatedBufferList<DecodeUnit>(DU_LIMIT, new PopulatedBufferList.BufferFactory() {
AbstractPopulatedBufferList.BufferFactory factory = new AbstractPopulatedBufferList.BufferFactory() {
public Object createFreeBuffer() {
return new DecodeUnit();
}
@ -58,7 +60,14 @@ public class VideoDepacketizer {
}
du.clearBackingPackets();
}
});
};
if (unsynchronized) {
decodedUnits = new UnsynchronizedPopulatedBufferList<DecodeUnit>(DU_LIMIT, factory);
}
else {
decodedUnits = new AtomicPopulatedBufferList<DecodeUnit>(DU_LIMIT, factory);
}
}
private void dropAvcFrameState()

View File

@ -11,6 +11,7 @@ import java.util.LinkedList;
import com.limelight.LimeLog;
import com.limelight.nvstream.ConnectionContext;
import com.limelight.nvstream.av.ConnectionStatusListener;
import com.limelight.nvstream.av.DecodeUnit;
import com.limelight.nvstream.av.RtpPacket;
import com.limelight.nvstream.av.RtpReorderQueue;
@ -117,7 +118,8 @@ public class VideoStream {
public boolean setupDecoderRenderer(VideoDecoderRenderer decRend, Object renderTarget, int drFlags) {
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) {
try {
@ -192,6 +194,9 @@ public class VideoStream {
for (int i = 0; i < VIDEO_RING_SIZE; i++) {
ring[i] = new VideoPacket(new byte[requiredBufferSize]);
}
boolean directSubmit = (decRend != null && (decRend.getCapabilities() &
VideoDecoderRenderer.CAPABILITY_DIRECT_SUBMIT) != 0);
byte[] buffer;
DatagramPacket packet = new DatagramPacket(new byte[1], 1); // Placeholder array
@ -220,6 +225,15 @@ public class VideoStream {
depacketizer.addInputData(queuedPacket);
}
}
// 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
iterationStart = ringIndex;