diff --git a/moonlight-common/src/com/limelight/nvstream/av/RtpPacket.java b/moonlight-common/src/com/limelight/nvstream/av/RtpPacket.java index c14b56ad..b6ce3eff 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/RtpPacket.java +++ b/moonlight-common/src/com/limelight/nvstream/av/RtpPacket.java @@ -67,4 +67,22 @@ public class RtpPacket implements RtpPacketFields { { bb.reinitialize(buffer.data, buffer.offset+headerSize, buffer.length-headerSize); } + + @Override + public int referencePacket() { + // There's no circular buffer for audio packets so this is a no-op + return 0; + } + + @Override + public int dereferencePacket() { + // There's no circular buffer for audio packets so this is a no-op + return 0; + } + + @Override + public int getRefCount() { + // There's no circular buffer for audio packets so this is a no-op + return 0; + } } diff --git a/moonlight-common/src/com/limelight/nvstream/av/RtpPacketFields.java b/moonlight-common/src/com/limelight/nvstream/av/RtpPacketFields.java index c1b4356a..6ee26c15 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/RtpPacketFields.java +++ b/moonlight-common/src/com/limelight/nvstream/av/RtpPacketFields.java @@ -4,4 +4,10 @@ public interface RtpPacketFields { public byte getPacketType(); public short getRtpSequenceNumber(); + + public int referencePacket(); + + public int dereferencePacket(); + + public int getRefCount(); } diff --git a/moonlight-common/src/com/limelight/nvstream/av/RtpReorderQueue.java b/moonlight-common/src/com/limelight/nvstream/av/RtpReorderQueue.java index 6e45fe89..a50d310a 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/RtpReorderQueue.java +++ b/moonlight-common/src/com/limelight/nvstream/av/RtpReorderQueue.java @@ -68,6 +68,9 @@ public class RtpReorderQueue { oldestQueuedEntry = entry; } + // Add a reference to the packet while it's in the queue + packet.referencePacket(); + if (head) { queue.addFirst(entry); } @@ -111,6 +114,11 @@ public class RtpReorderQueue { return lowestSeqEntry; } + private void removeEntry(RtpQueueEntry entry) { + queue.remove(entry); + entry.packet.dereferencePacket(); + } + private RtpQueueEntry validateQueueConstraints() { if (queue.isEmpty()) { return null; @@ -121,14 +129,14 @@ public class RtpReorderQueue { // Check that the queue's time constraint is satisfied if (TimeHelper.getMonotonicMillis() - oldestQueuedTime > maxQueueTime) { LimeLog.info("Discarding RTP packet queued for too long: "+(TimeHelper.getMonotonicMillis() - oldestQueuedTime)); - queue.remove(oldestQueuedEntry); + removeEntry(oldestQueuedEntry); needsUpdate = true; } // Check that the queue's size constraint is satisfied if (queue.size() == maxSize) { LimeLog.info("Discarding RTP packet after queue overgrowth"); - queue.remove(oldestQueuedEntry); + removeEntry(oldestQueuedEntry); needsUpdate = true; } @@ -203,6 +211,8 @@ public class RtpReorderQueue { } } + // This function returns a referenced packet. The caller must dereference + // the packet when it is finished. public RtpPacketFields getQueuedPacket() { RtpQueueEntry queuedEntry = null; diff --git a/moonlight-common/src/com/limelight/nvstream/av/audio/AudioStream.java b/moonlight-common/src/com/limelight/nvstream/av/audio/AudioStream.java index 5afd34b9..0ed54518 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/audio/AudioStream.java +++ b/moonlight-common/src/com/limelight/nvstream/av/audio/AudioStream.java @@ -219,6 +219,7 @@ public class AudioStream { if (queueStatus == RtpReorderQueue.RtpQueueStatus.QUEUED_PACKETS_READY) { while ((queuedPacket = (RtpPacket) rtpQueue.getQueuedPacket()) != null) { depacketizer.decodeInputData(queuedPacket); + queuedPacket.dereferencePacket(); } } } diff --git a/moonlight-common/src/com/limelight/nvstream/av/video/VideoPacket.java b/moonlight-common/src/com/limelight/nvstream/av/video/VideoPacket.java index 7ea73968..dbf4108e 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/video/VideoPacket.java +++ b/moonlight-common/src/com/limelight/nvstream/av/video/VideoPacket.java @@ -115,7 +115,7 @@ public class VideoPacket implements RtpPacketFields { return rtpSequenceNumber; } - int referencePacket() { + public int referencePacket() { if (useAtomicRefCount) { return duAtomicRefCount.incrementAndGet(); } @@ -124,7 +124,7 @@ public class VideoPacket implements RtpPacketFields { } } - int dereferencePacket() { + public int dereferencePacket() { if (useAtomicRefCount) { return duAtomicRefCount.decrementAndGet(); } @@ -133,7 +133,7 @@ public class VideoPacket implements RtpPacketFields { } } - int getRefCount() { + public int getRefCount() { if (useAtomicRefCount) { return duAtomicRefCount.get(); } 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 2aaeccdd..6a80e2c8 100644 --- a/moonlight-common/src/com/limelight/nvstream/av/video/VideoStream.java +++ b/moonlight-common/src/com/limelight/nvstream/av/video/VideoStream.java @@ -222,6 +222,7 @@ public class VideoStream { // The packet queue now has packets ready while ((queuedPacket = (VideoPacket) rtpQueue.getQueuedPacket()) != null) { depacketizer.addInputData(queuedPacket); + queuedPacket.dereferencePacket(); } }