/** * Returns the SSRC paired with <tt>ssrc</tt> in an FID source-group, if any. If none is found, * returns -1. * * @return the SSRC paired with <tt>ssrc</tt> in an FID source-group, if any. If none is found, * returns -1. */ private long getPrimarySsrc(RawPacket pkt) { MediaStreamTrackReceiver receiver = channel.getStream().getMediaStreamTrackReceiver(); if (receiver == null) { if (logger.isDebugEnabled()) { logger.debug("Dropping an incoming RTX packet from an unknown source."); } return -1; } RTPEncoding encoding = receiver.resolveRTPEncoding(pkt); if (encoding == null) { if (logger.isDebugEnabled()) { logger.debug("Dropping an incoming RTX packet from an unknown source."); } return -1; } return encoding.getPrimarySSRC(); }
/** * Removes the RTX encapsulation from a packet. * * @param pkt the packet to remove the RTX encapsulation from. * @return the original media packet represented by {@code pkt}, or null if we couldn't * reconstruct the original packet. */ private RawPacket deRtx(RawPacket pkt) { boolean success = false; if (pkt.getPayloadLength() - pkt.getPaddingSize() < 2) { // We need at least 2 bytes to read the OSN field. if (logger.isDebugEnabled()) { logger.debug("Dropping an incoming RTX packet with padding only: " + pkt); } return null; } long mediaSsrc = getPrimarySsrc(pkt); if (mediaSsrc != -1) { if (rtxAssociatedPayloadType != -1) { int osn = pkt.getOriginalSequenceNumber(); // Remove the RTX header by moving the RTP header two bytes // right. byte[] buf = pkt.getBuffer(); int off = pkt.getOffset(); System.arraycopy(buf, off, buf, off + 2, pkt.getHeaderLength()); pkt.setOffset(off + 2); pkt.setLength(pkt.getLength() - 2); pkt.setSSRC((int) mediaSsrc); pkt.setSequenceNumber(osn); pkt.setPayloadType(rtxAssociatedPayloadType); success = true; } else { logger.warn( "RTX packet received, but no APT is defined. Packet " + "SSRC " + pkt.getSSRCAsLong() + ", associated media" + " SSRC " + mediaSsrc); } } // If we failed to handle the RTX packet, drop it. return success ? pkt : null; }