diff --git a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
index ced31e1f2d229c5128c103e1aa4c56be7e70b123..4145f3b5107b50e19af1c044e4aa5c9e60511afc 100644
--- a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
+++ b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
@@ -25,6 +25,7 @@
 import org.jitsi.impl.neomedia.transform.*;
 import org.jitsi.impl.neomedia.transform.csrc.*;
 import org.jitsi.impl.neomedia.transform.dtmf.*;
+import org.jitsi.impl.neomedia.transform.pt.*;
 import org.jitsi.impl.neomedia.transform.rtcp.*;
 import org.jitsi.impl.neomedia.transform.zrtp.*;
 import org.jitsi.service.neomedia.*;
@@ -223,6 +224,11 @@ else if (MediaDeviceSession.SSRC_LIST.equals(propertyName))
      */
     private MediaStreamStatsImpl mediaStreamStatsImpl;
 
+    /**
+     * Engine chain overriding payload type if needed.
+     */
+    private PayloadTypeTransformEngine ptTransformEngine;
+
     /**
      * Initializes a new <tt>MediaStreamImpl</tt> instance which will use the
      * specified <tt>MediaDevice</tt> for both capture and playback of media.
@@ -373,6 +379,12 @@ private TransformEngineChain createTransformEngineChain()
             statisticsEngine = new StatisticsEngine(this);
         engineChain.add(statisticsEngine);
 
+        // here comes the override payload type transformer
+        // as it changes headers of packets, need to go before encryption
+        if(ptTransformEngine == null)
+            ptTransformEngine = new PayloadTypeTransformEngine();
+        engineChain.add(ptTransformEngine);
+
         // SRTP
         engineChain.add(srtpControl.getTransformEngine());
 
@@ -2845,4 +2857,24 @@ public FECDecoderControl getFecDecoderControl(ReceiveStream receiveStream)
         }
         return null;
     }
+
+    /**
+     * 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)
+    {
+        if(ptTransformEngine != null)
+            ptTransformEngine.setPTMappingOverride(mappingOverride);
+    }
 }
diff --git a/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java b/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java
new file mode 100644
index 0000000000000000000000000000000000000000..298deadaa11dc67af469eef383df1e91b91cff90
--- /dev/null
+++ b/src/org/jitsi/impl/neomedia/transform/pt/PayloadTypeTransformEngine.java
@@ -0,0 +1,116 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package org.jitsi.impl.neomedia.transform.pt;
+
+import org.jitsi.impl.neomedia.*;
+import org.jitsi.impl.neomedia.transform.*;
+
+import java.util.*;
+
+/**
+ * We use this engine to change payload types of outgoing RTP packets if needed.
+ * 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.
+ *
+ * @author Damian Minkov
+ */
+public class PayloadTypeTransformEngine
+    implements TransformEngine,
+               PacketTransformer
+{
+    /**
+     * The mapping we use to override payloads. By default it is empty
+     * 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>();
+
+    /**
+     * Checks if there are any override mappings, if no setting just pass
+     * through the packet.
+     * If the <tt>RawPacket</tt> payload has entry in mappings to override,
+     * we override packet payload type.
+     *
+     * @param pkt the RTP <tt>RawPacket</tt> that we check for need to change
+     * payload type.
+     *
+     * @return the updated <tt>RawPacket</tt> instance containing the changed
+     * payload type.
+     */
+    public RawPacket transform(RawPacket pkt)
+    {
+        if(mappingOverride.isEmpty())
+            return pkt;
+
+        Byte newPT = mappingOverride.get(pkt.getPayloadType());
+        if(newPT != null)
+            pkt.setPayload(newPT);
+
+        return pkt;
+    }
+
+    /**
+     * Do nothing just passes the incoming packet.
+     *
+     * @param pkt the RTP <tt>RawPacket</tt> that we will pass through.
+     *
+     * @return the same <tt>RawPacket</tt> that is passing through.
+     */
+    public RawPacket reverseTransform(RawPacket pkt)
+    {
+        return pkt;
+    }
+
+    /**
+     * Closes this <tt>PacketTransformer</tt> i.e. releases the resources
+     * allocated by it and prepares it for garbage collection.
+     */
+    public void close()
+    {
+    }
+
+    /**
+     * Returns a reference to this class since it is performing RTP
+     * transformations in here.
+     *
+     * @return a reference to <tt>this</tt> instance of the
+     * <tt>PayloadTypeTransformEngine</tt>.
+     */
+    public PacketTransformer getRTPTransformer()
+    {
+        return this;
+    }
+
+    /**
+     * Always returns <tt>null</tt> since this engine does not require any
+     * RTCP transformations.
+     *
+     * @return <tt>null</tt> since this engine does not require any
+     * RTCP transformations.
+     */
+    public PacketTransformer getRTCPTransformer()
+    {
+        return null;
+    }
+
+    /**
+     * 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.
+     */
+    public void setPTMappingOverride(Map<Byte, Byte> mappingOverride)
+    {
+        if(mappingOverride != null)
+            this.mappingOverride = mappingOverride;
+    }
+}
diff --git a/src/org/jitsi/service/neomedia/MediaStream.java b/src/org/jitsi/service/neomedia/MediaStream.java
index 6ace1dca63f2f5917e750af8e1297f5853dd4c8a..479104d15cf41381037b3fc8911c8137d1ab8e4d 100644
--- a/src/org/jitsi/service/neomedia/MediaStream.java
+++ b/src/org/jitsi/service/neomedia/MediaStream.java
@@ -237,6 +237,22 @@ 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 or updates an association in this <tt>MediaStream</tt> mapping the
      * specified <tt>extensionID</tt> to <tt>rtpExtension</tt> and enabling or