diff --git a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java index 4145f3b5107b50e19af1c044e4aa5c9e60511afc..662adf1f98f2cad71a3dc9048b996aa14d0f3a47 100644 --- a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java +++ b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java @@ -2859,22 +2859,25 @@ public FECDecoderControl getFecDecoderControl(ReceiveStream receiveStream) } /** - * Adds additional RTP payload mappings that will override the ones in the - * "dynamicPayloadTypes" map for outgoing packets. This is necessary so - * that we can support the RFC3264 case where the answerer has the right - * to declare what payload type mappings it wants to receive even if they - * are different from those in the offer. RFC3264 claims this is for - * support of legacy protocols such as H.323 but we've been bumping with - * a number of cases where multi-component pure SIP systems also need to - * behave this way. - * The <tt>Map<Byte, Byte></tt> maps source payload to payload to use - * for packets when sending. - * @param mappingOverride <tt>Map<Byte, Byte></tt> that maps - * source payload to payload to use for packets when sending. - */ - public void setPTMappingOverrides(Map<Byte, Byte> mappingOverride) + * Adds an additional RTP payload mapping that will overriding one that + * we've set with {@link addDynamicRTPPayloadType(byte, MediaFormat)}. + * This is necessary so that we can support the RFC3264 case where the + * answerer has the right to declare what payload type mappings it wants to + * receive RTP packets with even if they are different from those in the + * offer. RFC3264 claims this is for support of legacy protocols such as + * H.323 but we've been bumping with a number of cases where multi-component + * pure SIP systems also need to behave this way. + * <p> + * + * @param originalPt the payload type that we are overriding + * @param overloadPt the payload type that we are overriging it with + */ + public void addDynamicRTPPayloadTypeOverride(byte originalPt, + byte overloadPt) { if(ptTransformEngine != null) - ptTransformEngine.setPTMappingOverride(mappingOverride); + { + ptTransformEngine.addPTMappingOverride(originalPt, overloadPt); + } } } diff --git a/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java index 298deadaa11dc67af469eef383df1e91b91cff90..d05427f2401eedc0f8c691339e7d850892dc339c 100644 --- a/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java +++ b/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java @@ -31,7 +31,13 @@ public class PayloadTypeTransformEngine * and we do nothing, packets are passed through without modification. * Maps source payload to target payload. */ - private Map<Byte, Byte> mappingOverride = new HashMap<Byte, Byte>(); + private Map<Byte, Byte> mappingOverrides = new HashMap<Byte, Byte>(); + + /** + * This map is a copy of <tt>mappingOverride</tt> that we use durig actual + * transformation + */ + private Map<Byte, Byte> mappingOverridesCopy = null; /** * Checks if there are any override mappings, if no setting just pass @@ -47,10 +53,10 @@ public class PayloadTypeTransformEngine */ public RawPacket transform(RawPacket pkt) { - if(mappingOverride.isEmpty()) + if(mappingOverridesCopy == null || mappingOverridesCopy.isEmpty()) return pkt; - Byte newPT = mappingOverride.get(pkt.getPayloadType()); + Byte newPT = mappingOverridesCopy.get(pkt.getPayloadType()); if(newPT != null) pkt.setPayload(newPT); @@ -102,15 +108,29 @@ public PacketTransformer getRTCPTransformer() } /** - * Adds additional RTP payload mappings used to override the outgoing - * payload type. The <tt>Map<Byte, Byte></tt> maps source payload to - * payload to use for packets when sending. - * @param mappingOverride <tt>Map<Byte, Byte></tt> that maps - * source payload to payload to use for packets when sending. + * Adds an additional RTP payload type mapping used to override the payload + * type of outgoing RTP packets. If an override for <tt>originalPT<tt/>, + * was already being overridden, this call is simply going to update the + * override to the new one. + * <p> + * This method creates a copy of the local overriding map so that mapping + * overrides could be set during a call (e.g. after a SIP re-INVITE) in a + * thread-safe way without using synchronization. + * + * @param originalPt the payload type that we are overriding + * @param overloadPt the payload type that we are overriging it with */ - public void setPTMappingOverride(Map<Byte, Byte> mappingOverride) + + public void addPTMappingOverride(byte originalPt, byte overloadPt) { - if(mappingOverride != null) - this.mappingOverride = mappingOverride; + if (mappingOverrides.containsKey(originalPt) + && mappingOverrides.get(originalPt) == overloadPt) + { + return; + } + + mappingOverrides.put(originalPt, overloadPt); + + mappingOverridesCopy = new HashMap(mappingOverrides); } } diff --git a/src/org/jitsi/service/neomedia/MediaStream.java b/src/org/jitsi/service/neomedia/MediaStream.java index 479104d15cf41381037b3fc8911c8137d1ab8e4d..c2892691096a2e21a1a59acdc8e7948ab55acce0 100644 --- a/src/org/jitsi/service/neomedia/MediaStream.java +++ b/src/org/jitsi/service/neomedia/MediaStream.java @@ -238,20 +238,21 @@ public void addDynamicRTPPayloadType( public Map<Byte, MediaFormat> getDynamicRTPPayloadTypes(); /** - * Adds additional RTP payload mappings that will override the ones in the - * "dynamicPayloadTypes" map for outgoing packets. This is necessary so - * that we can support the RFC3264 case where the answerer has the right - * to declare what payload type mappings it wants to receive even if they - * are different from those in the offer. RFC3264 claims this is for - * support of legacy protocols such as H.323 but we've been bumping with - * a number of cases where multi-component pure SIP systems also need to - * behave this way. - * The <tt>Map<Byte, Byte></tt> maps source payload to payload to use - * for packets when sending. - * @param mappingOverride <tt>Map<Byte, Byte></tt> that maps - * source payload to payload to use for packets when sending. - */ - public void setPTMappingOverrides(Map<Byte, Byte> mappingOverride); + * Adds an additional RTP payload mapping that will overriding one that + * we've set with {@link addDynamicRTPPayloadType(byte, MediaFormat)}. + * This is necessary so that we can support the RFC3264 case where the + * answerer has the right to declare what payload type mappings it wants to + * receive RTP packets with even if they are different from those in the + * offer. RFC3264 claims this is for support of legacy protocols such as + * H.323 but we've been bumping with a number of cases where multi-component + * pure SIP systems also need to behave this way. + * <p> + * + * @param originalPt the payload type that we are overriding + * @param overloadPt the payload type that we are overriging it with + */ + public void addDynamicRTPPayloadTypeOverride(byte originalPt, + byte overloadPt); /** * Adds or updates an association in this <tt>MediaStream</tt> mapping the