diff --git a/moonlight-common/src/com/limelight/nvstream/av/video/VideoDecoderRenderer.java b/moonlight-common/src/com/limelight/nvstream/av/video/VideoDecoderRenderer.java index 335c53d2..48e5a6db 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/video/VideoDecoderRenderer.java +++ b/moonlight-common/src/com/limelight/nvstream/av/video/VideoDecoderRenderer.java @@ -1,24 +1,17 @@ package com.limelight.nvstream.av.video; -import com.limelight.nvstream.av.DecodeUnit; - public interface VideoDecoderRenderer { public static final int FLAG_PREFER_QUALITY = 0x1; public static final int FLAG_FORCE_HARDWARE_DECODING = 0x2; public static final int FLAG_FORCE_SOFTWARE_DECODING = 0x4; - // SubmitDecodeUnit() is lightweight, so don't use an extra thread for decoding - public static final int CAPABILITY_DIRECT_SUBMIT = 0x1; - public int getCapabilities(); public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags); - public void start(); + public void start(VideoDepacketizer depacketizer); public void stop(); public void release(); - - public boolean submitDecodeUnit(DecodeUnit decodeUnit); } 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 32e6fc32..647afe9a 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/video/VideoDepacketizer.java +++ b/moonlight-common/src/com/limelight/nvstream/av/video/VideoDepacketizer.java @@ -28,14 +28,12 @@ public class VideoDepacketizer { private ByteBufferDescriptor cachedDesc = new ByteBufferDescriptor(null, 0, 0); private ConnectionStatusListener controlListener; - private VideoDecoderRenderer directSubmitDr; private static final int DU_LIMIT = 15; private LinkedBlockingQueue decodedUnits = new LinkedBlockingQueue(DU_LIMIT); - public VideoDepacketizer(VideoDecoderRenderer directSubmitDr, ConnectionStatusListener controlListener) + public VideoDepacketizer(ConnectionStatusListener controlListener) { - this.directSubmitDr = directSubmitDr; this.controlListener = controlListener; } @@ -68,11 +66,7 @@ public class VideoDepacketizer { // Construct the H264 decode unit DecodeUnit du = new DecodeUnit(DecodeUnit.TYPE_H264, avcFrameDataChain, avcFrameDataLength, flags, frameNumber); - if (directSubmitDr != null) { - // Submit directly to the decoder - directSubmitDr.submitDecodeUnit(du); - } - else if (!decodedUnits.offer(du)) { + if (!decodedUnits.offer(du)) { LimeLog.warning("Video decoder is too slow! Forced to drop decode units"); // Invalidate all frames from the start of the DU queue @@ -92,7 +86,7 @@ public class VideoDepacketizer { } } - public void addInputDataSlow(VideoPacket packet, ByteBufferDescriptor location) + private void addInputDataSlow(VideoPacket packet, ByteBufferDescriptor location) { while (location.length != 0) { @@ -175,7 +169,7 @@ public class VideoDepacketizer { } } - public void addInputDataFast(VideoPacket packet, ByteBufferDescriptor location, boolean firstPacket) + private void addInputDataFast(VideoPacket packet, ByteBufferDescriptor location, boolean firstPacket) { if (firstPacket) { // Setup state for the new frame @@ -340,10 +334,15 @@ public class VideoDepacketizer { addInputData(new VideoPacket(rtpPayload)); } - public DecodeUnit getNextDecodeUnit() throws InterruptedException + public DecodeUnit takeNextDecodeUnit() throws InterruptedException { return decodedUnits.take(); } + + public DecodeUnit pollNextDecodeUnit() + { + return decodedUnits.poll(); + } } class NAL { 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 61e90395..61fb517d 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/video/VideoStream.java +++ b/moonlight-common/src/com/limelight/nvstream/av/video/VideoStream.java @@ -13,7 +13,6 @@ import java.util.LinkedList; import com.limelight.nvstream.NvConnectionListener; import com.limelight.nvstream.StreamConfiguration; import com.limelight.nvstream.av.ByteBufferDescriptor; -import com.limelight.nvstream.av.DecodeUnit; import com.limelight.nvstream.av.RtpPacket; import com.limelight.nvstream.av.ConnectionStatusListener; @@ -140,12 +139,7 @@ public class VideoStream { decRend.setup(streamConfig.getWidth(), streamConfig.getHeight(), 60, renderTarget, drFlags); - if ((decRend.getCapabilities() & VideoDecoderRenderer.CAPABILITY_DIRECT_SUBMIT) != 0) { - depacketizer = new VideoDepacketizer(decRend, avConnListener); - } - else { - depacketizer = new VideoDepacketizer(null, avConnListener); - } + depacketizer = new VideoDepacketizer(avConnListener); } } @@ -173,44 +167,12 @@ public class VideoStream { // early packets startReceiveThread(); - // Start a decode thread if we're not doing direct submit - if ((decRend.getCapabilities() & VideoDecoderRenderer.CAPABILITY_DIRECT_SUBMIT) == 0) { - startDecoderThread(); - } - // Start the renderer - decRend.start(); + decRend.start(depacketizer); startedRendering = true; } } - private void startDecoderThread() - { - Thread t = new Thread() { - @Override - public void run() { - // Read the decode units generated from the RTP stream - while (!isInterrupted()) - { - DecodeUnit du; - - try { - du = depacketizer.getNextDecodeUnit(); - } catch (InterruptedException e) { - listener.connectionTerminated(e); - return; - } - - decRend.submitDecodeUnit(du); - } - } - }; - threads.add(t); - t.setName("Video - Decoder"); - t.setPriority(Thread.MAX_PRIORITY); - t.start(); - } - private void startReceiveThread() { // Receive thread