From 6bb215eddf55f82318883a561cc8ecd09d9004c0 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 21 Nov 2013 16:40:27 -0500 Subject: [PATCH] Remove pooling code due to higher concurrency latency that resulted in a net loss of performance. --- src/com/limelight/Game.java | 10 ---- src/com/limelight/nvstream/NvAudioStream.java | 16 +----- src/com/limelight/nvstream/NvConnection.java | 6 -- src/com/limelight/nvstream/NvVideoStream.java | 13 +---- .../nvstream/av/AvByteBufferDescriptor.java | 1 - .../nvstream/av/AvByteBufferPool.java | 35 ------------ .../nvstream/av/AvShortBufferPool.java | 35 ------------ .../av/audio/AvAudioDepacketizer.java | 28 ++------- .../av/video/AvVideoDepacketizer.java | 57 +------------------ .../nvstream/av/video/AvVideoPacket.java | 11 ---- 10 files changed, 11 insertions(+), 201 deletions(-) delete mode 100644 src/com/limelight/nvstream/av/AvByteBufferPool.java delete mode 100644 src/com/limelight/nvstream/av/AvShortBufferPool.java diff --git a/src/com/limelight/Game.java b/src/com/limelight/Game.java index 2f4032ca..610bfd1d 100644 --- a/src/com/limelight/Game.java +++ b/src/com/limelight/Game.java @@ -4,8 +4,6 @@ import com.limelight.nvstream.NvConnection; import com.limelight.nvstream.input.NvControllerPacket; import android.app.Activity; -import android.content.ComponentCallbacks2; -import android.graphics.ImageFormat; import android.graphics.PixelFormat; import android.os.Bundle; import android.view.InputDevice; @@ -96,14 +94,6 @@ public class Game extends Activity implements OnGenericMotionListener, OnTouchLi super.onPause(); } - @Override - public void onTrimMemory(int trimLevel) { - if (trimLevel >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW) - { - conn.trim(); - } - } - @Override public boolean onKeyDown(int keyCode, KeyEvent event) { diff --git a/src/com/limelight/nvstream/NvAudioStream.java b/src/com/limelight/nvstream/NvAudioStream.java index e688b50c..efd1ecc9 100644 --- a/src/com/limelight/nvstream/NvAudioStream.java +++ b/src/com/limelight/nvstream/NvAudioStream.java @@ -10,7 +10,6 @@ import java.util.LinkedList; import java.util.concurrent.LinkedBlockingQueue; import com.limelight.nvstream.av.AvByteBufferDescriptor; -import com.limelight.nvstream.av.AvByteBufferPool; import com.limelight.nvstream.av.AvRtpPacket; import com.limelight.nvstream.av.AvShortBufferDescriptor; import com.limelight.nvstream.av.audio.AvAudioDepacketizer; @@ -34,8 +33,6 @@ public class NvAudioStream { private LinkedList threads = new LinkedList(); - private AvByteBufferPool pool = new AvByteBufferPool(1500); - private boolean aborting = false; public void abort() @@ -105,11 +102,6 @@ public class NvAudioStream { rtp.connect(InetAddress.getByName(host), RTP_PORT); } - public void trim() - { - depacketizer.trim(); - } - private void setupAudio() { int channelConfig; @@ -166,8 +158,6 @@ public class NvAudioStream { } depacketizer.decodeInputData(packet); - - pool.free(packet.getBackingBuffer()); } } }; @@ -193,8 +183,6 @@ public class NvAudioStream { } track.write(samples.data, samples.offset, samples.length); - - depacketizer.releaseBuffer(samples); } } }; @@ -208,7 +196,7 @@ public class NvAudioStream { Thread t = new Thread() { @Override public void run() { - DatagramPacket packet = new DatagramPacket(pool.allocate(), 1500); + DatagramPacket packet = new DatagramPacket(new byte[1500], 1500); AvByteBufferDescriptor desc = new AvByteBufferDescriptor(null, 0, 0); while (!isInterrupted()) @@ -228,7 +216,7 @@ public class NvAudioStream { packets.add(new AvRtpPacket(desc)); // Get a new buffer from the buffer pool - packet.setData(pool.allocate(), 0, 1500); + packet.setData(new byte[1500], 0, 1500); } } }; diff --git a/src/com/limelight/nvstream/NvConnection.java b/src/com/limelight/nvstream/NvConnection.java index 4e1b94f8..9004f428 100644 --- a/src/com/limelight/nvstream/NvConnection.java +++ b/src/com/limelight/nvstream/NvConnection.java @@ -112,12 +112,6 @@ public class NvConnection { inputStream = null; } } - - public void trim() - { - videoStream.trim(); - audioStream.trim(); - } public void start() { diff --git a/src/com/limelight/nvstream/NvVideoStream.java b/src/com/limelight/nvstream/NvVideoStream.java index e3d903d9..3ff549a1 100644 --- a/src/com/limelight/nvstream/NvVideoStream.java +++ b/src/com/limelight/nvstream/NvVideoStream.java @@ -82,15 +82,10 @@ public class NvVideoStream { threads.clear(); } - - public void trim() - { - depacketizer.trim(); - } private void readFirstFrame(String host) throws IOException { - byte[] firstFrame = depacketizer.allocatePacketBuffer(); + byte[] firstFrame = new byte[1500]; System.out.println("VID: Waiting for first frame"); firstFrameSocket = new Socket(host, FIRST_FRAME_PORT); @@ -220,8 +215,6 @@ public class NvVideoStream { } decrend.submitDecodeUnit(du); - - depacketizer.releaseDecodeUnit(du); } } }; @@ -262,7 +255,7 @@ public class NvVideoStream { Thread t = new Thread() { @Override public void run() { - DatagramPacket packet = new DatagramPacket(depacketizer.allocatePacketBuffer(), 1500); + DatagramPacket packet = new DatagramPacket(new byte[1500], 1500); AvByteBufferDescriptor desc = new AvByteBufferDescriptor(null, 0, 0); while (!isInterrupted()) @@ -282,7 +275,7 @@ public class NvVideoStream { packets.add(new AvRtpPacket(desc)); // Get a new buffer from the buffer pool - packet.setData(depacketizer.allocatePacketBuffer(), 0, 1500); + packet.setData(new byte[1500], 0, 1500); } } }; diff --git a/src/com/limelight/nvstream/av/AvByteBufferDescriptor.java b/src/com/limelight/nvstream/av/AvByteBufferDescriptor.java index b75a78ef..2d6298f1 100644 --- a/src/com/limelight/nvstream/av/AvByteBufferDescriptor.java +++ b/src/com/limelight/nvstream/av/AvByteBufferDescriptor.java @@ -4,7 +4,6 @@ public class AvByteBufferDescriptor { public byte[] data; public int offset; public int length; - public Object context; public AvByteBufferDescriptor(byte[] data, int offset, int length) { diff --git a/src/com/limelight/nvstream/av/AvByteBufferPool.java b/src/com/limelight/nvstream/av/AvByteBufferPool.java deleted file mode 100644 index a4892eaf..00000000 --- a/src/com/limelight/nvstream/av/AvByteBufferPool.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.limelight.nvstream.av; - -import java.util.LinkedList; - -public class AvByteBufferPool { - private LinkedList bufferList = new LinkedList(); - private int bufferSize; - - public AvByteBufferPool(int size) - { - this.bufferSize = size; - } - - public synchronized void purge() - { - this.bufferList = new LinkedList(); - } - - public synchronized byte[] allocate() - { - if (bufferList.isEmpty()) - { - return new byte[bufferSize]; - } - else - { - return bufferList.removeFirst(); - } - } - - public synchronized void free(byte[] buffer) - { - bufferList.addFirst(buffer); - } -} diff --git a/src/com/limelight/nvstream/av/AvShortBufferPool.java b/src/com/limelight/nvstream/av/AvShortBufferPool.java deleted file mode 100644 index 0b000483..00000000 --- a/src/com/limelight/nvstream/av/AvShortBufferPool.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.limelight.nvstream.av; - -import java.util.LinkedList; - -public class AvShortBufferPool { - private LinkedList bufferList = new LinkedList(); - private int bufferSize; - - public AvShortBufferPool(int size) - { - this.bufferSize = size; - } - - public synchronized void purge() - { - this.bufferList = new LinkedList(); - } - - public synchronized short[] allocate() - { - if (bufferList.isEmpty()) - { - return new short[bufferSize]; - } - else - { - return bufferList.removeFirst(); - } - } - - public synchronized void free(short[] buffer) - { - bufferList.addFirst(buffer); - } -} diff --git a/src/com/limelight/nvstream/av/audio/AvAudioDepacketizer.java b/src/com/limelight/nvstream/av/audio/AvAudioDepacketizer.java index 13a78f4b..b14b8381 100644 --- a/src/com/limelight/nvstream/av/audio/AvAudioDepacketizer.java +++ b/src/com/limelight/nvstream/av/audio/AvAudioDepacketizer.java @@ -5,26 +5,18 @@ import java.util.concurrent.LinkedBlockingQueue; import com.limelight.nvstream.av.AvByteBufferDescriptor; import com.limelight.nvstream.av.AvRtpPacket; import com.limelight.nvstream.av.AvShortBufferDescriptor; -import com.limelight.nvstream.av.AvShortBufferPool; public class AvAudioDepacketizer { private LinkedBlockingQueue decodedUnits = new LinkedBlockingQueue(15); - - private AvShortBufferPool pool = new AvShortBufferPool(OpusDecoder.getMaxOutputShorts()); - + // Sequencing state private short lastSequenceNumber; - - public void trim() - { - pool.purge(); - } - + private void decodeData(byte[] data, int off, int len) { // Submit this data to the decoder - short[] pcmData = pool.allocate(); + short[] pcmData = new short[OpusDecoder.getMaxOutputShorts()]; int decodeLen = OpusDecoder.decode(data, off, len, pcmData); if (decodeLen > 0) { @@ -32,14 +24,7 @@ public class AvAudioDepacketizer { decodeLen *= OpusDecoder.getChannelCount(); // Put it on the decoded queue - if (!decodedUnits.offer(new AvShortBufferDescriptor(pcmData, 0, decodeLen))) - { - pool.free(pcmData); - } - } - else { - System.out.println("decode failed: "+decodeLen); - pool.free(pcmData); + decodedUnits.offer(new AvShortBufferDescriptor(pcmData, 0, decodeLen)); } } @@ -68,11 +53,6 @@ public class AvAudioDepacketizer { decodeData(rtpPayload.data, rtpPayload.offset, rtpPayload.length); } - public void releaseBuffer(AvShortBufferDescriptor decodedData) - { - pool.free(decodedData.data); - } - public AvShortBufferDescriptor getNextDecodedData() throws InterruptedException { return decodedUnits.take(); diff --git a/src/com/limelight/nvstream/av/video/AvVideoDepacketizer.java b/src/com/limelight/nvstream/av/video/AvVideoDepacketizer.java index db1d6b01..59343212 100644 --- a/src/com/limelight/nvstream/av/video/AvVideoDepacketizer.java +++ b/src/com/limelight/nvstream/av/video/AvVideoDepacketizer.java @@ -4,7 +4,6 @@ import java.util.LinkedList; import java.util.concurrent.LinkedBlockingQueue; import com.limelight.nvstream.av.AvByteBufferDescriptor; -import com.limelight.nvstream.av.AvByteBufferPool; import com.limelight.nvstream.av.AvDecodeUnit; import com.limelight.nvstream.av.AvRtpPacket; @@ -22,49 +21,12 @@ public class AvVideoDepacketizer { private LinkedBlockingQueue decodedUnits = new LinkedBlockingQueue(); - private AvByteBufferPool pool = new AvByteBufferPool(1500); - - public byte[] allocatePacketBuffer() - { - return pool.allocate(); - } - - public void trim() - { - pool.purge(); - } - private void clearAvcNalState() { - if (avcNalDataChain != null) - { - for (AvByteBufferDescriptor avbb : avcNalDataChain) - { - AvVideoPacket packet = (AvVideoPacket) avbb.context; - - if (packet.release() == 0) { - pool.free(avbb.data); - } - } - } - avcNalDataChain = null; avcNalDataLength = 0; } - - public void releaseDecodeUnit(AvDecodeUnit decodeUnit) - { - // Remove the reference from each AvVideoPacket (freeing if okay) - for (AvByteBufferDescriptor buff : decodeUnit.getBufferList()) - { - AvVideoPacket packet = (AvVideoPacket) buff.context; - - if (packet.release() == 0) { - pool.free(buff.data); - } - } - } - + private void reassembleAvcNal() { // This is the start of a new NAL @@ -119,10 +81,7 @@ public class AvVideoDepacketizer { // Construct the H264 decode unit AvDecodeUnit du = new AvDecodeUnit(AvDecodeUnit.TYPE_H264, avcNalDataChain, avcNalDataLength, flags); - if (!decodedUnits.offer(du)) - { - releaseDecodeUnit(du); - } + decodedUnits.offer(du); // Clear old state avcNalDataChain = null; @@ -134,9 +93,6 @@ public class AvVideoDepacketizer { { AvByteBufferDescriptor location = packet.getNewPayloadDescriptor(); - // Add an initial reference - packet.addRef(); - while (location.length != 0) { // Remember the start of the NAL data in this packet @@ -214,20 +170,11 @@ public class AvVideoDepacketizer { { AvByteBufferDescriptor data = new AvByteBufferDescriptor(location.data, start, location.offset-start); - // Attach the current packet as the buffer context and increment the refcount - data.context = packet; - packet.addRef(); - // Add a buffer descriptor describing the NAL data in this packet avcNalDataChain.add(data); avcNalDataLength += location.offset-start; } } - - // If nothing useful came out of this, release the packet now - if (packet.release() == 0) { - pool.free(location.data); - } } public void addInputData(AvRtpPacket packet) diff --git a/src/com/limelight/nvstream/av/video/AvVideoPacket.java b/src/com/limelight/nvstream/av/video/AvVideoPacket.java index fde7bc54..d2bd8445 100644 --- a/src/com/limelight/nvstream/av/video/AvVideoPacket.java +++ b/src/com/limelight/nvstream/av/video/AvVideoPacket.java @@ -4,7 +4,6 @@ import com.limelight.nvstream.av.AvByteBufferDescriptor; public class AvVideoPacket { private AvByteBufferDescriptor buffer; - private int refCount; public AvVideoPacket(AvByteBufferDescriptor rtpPayload) { @@ -15,14 +14,4 @@ public class AvVideoPacket { { return new AvByteBufferDescriptor(buffer.data, buffer.offset+56, buffer.length-56); } - - public int addRef() - { - return ++refCount; - } - - public int release() - { - return --refCount; - } }