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 c75014a9..0fb70f7d 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/video/VideoDepacketizer.java +++ b/moonlight-common/src/com/limelight/nvstream/av/video/VideoDepacketizer.java @@ -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 decodedUnits; + private AbstractPopulatedBufferList 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(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(DU_LIMIT, factory); + } + else { + decodedUnits = new AtomicPopulatedBufferList(DU_LIMIT, factory); + } } private void dropAvcFrameState() 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 2b99439d..2fc5272f 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/video/VideoStream.java +++ b/moonlight-common/src/com/limelight/nvstream/av/video/VideoStream.java @@ -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;