diff --git a/src/main/java/org/jitsi/videobridge/VideoChannel.java b/src/main/java/org/jitsi/videobridge/VideoChannel.java index b4c7b20099..0c9423bd50 100644 --- a/src/main/java/org/jitsi/videobridge/VideoChannel.java +++ b/src/main/java/org/jitsi/videobridge/VideoChannel.java @@ -108,6 +108,16 @@ public class VideoChannel private int receiveSimulcastLayer = SimulcastStream.SIMULCAST_LAYER_ORDER_BASE; // Integer.MAX_VALUE; + /** + * A map of source ssrc to last accepted sequence number + */ + private final Map ssrcToLastAcceptedSeqNumber= new HashMap<>(); + + /** + * A map of source ssrc to the delta since the last accepted sequence number + */ + private final Map ssrcToDeltaSinceLastAcceptedSeqNumber = new HashMap<>(); + /** * Updates the values of the property inLastN of all * VideoChannels in the Content of a specific @@ -498,14 +508,49 @@ boolean rtpTranslatorWillWrite( byte[] buffer, int offset, int length, Channel source) { - boolean accept = true; + // XXX(gp) we could potentially move this into a TransformEngine. + boolean accept = lastNController.isForwarded(source); + int seqNumber = RawPacket.getSequenceNumber(buffer, offset, length); + Long ssrc = RawPacket.getSSRCAsLong(buffer, offset, length); - if (data && (source != null)) + if (accept) + { + // overwrite the sequence number (if needed) + int delta = 0; + if (ssrcToDeltaSinceLastAcceptedSeqNumber.containsKey(ssrc)) + { + delta = ssrcToDeltaSinceLastAcceptedSeqNumber.get(ssrc); + } + int newSequenceNumber = RTPUtils.subtractNumber(seqNumber, delta); + RawPacket.setSequenceNumber(buffer, offset, newSequenceNumber); + int highestSentSequenceNumber = newSequenceNumber; + if (ssrcToLastAcceptedSeqNumber.containsKey(ssrc)) + { + highestSentSequenceNumber = ssrcToLastAcceptedSeqNumber.get(ssrc); + } + if (RTPUtils.sequenceNumberDiff(newSequenceNumber, highestSentSequenceNumber) >= 0) + { + ssrcToLastAcceptedSeqNumber.put(ssrc, newSequenceNumber); + } + } + else { - // XXX(gp) we could potentially move this into a TransformEngine. - accept = lastNController.isForwarded(source); + // update the delta (if needed) + if (ssrcToLastAcceptedSeqNumber.containsKey(ssrc)) + { + int lastSeqNo = ssrcToLastAcceptedSeqNumber.get(ssrc); + int delta = RTPUtils.subtractNumber(seqNumber, lastSeqNo); + int lastDelta = delta; + if (ssrcToDeltaSinceLastAcceptedSeqNumber.containsKey(ssrc)) + { + lastDelta = ssrcToDeltaSinceLastAcceptedSeqNumber.get(ssrc); + } + if (RTPUtils.sequenceNumberDiff(delta, lastDelta) >= 0) + { + ssrcToDeltaSinceLastAcceptedSeqNumber.put(ssrc, delta); + } + } } - return accept; }