diff options
4 files changed, 119 insertions, 5 deletions
diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java index fcba602..95a5bca 100644 --- a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java @@ -92,6 +92,18 @@ public class MediaServiceImpl = new ArrayList<MediaDeviceImpl>(); /** + * A {@link Map} that binds indicates whatever preferences this + * media service implementation may have for the RTP payload type numbers + * that get dynamically assigned to {@link MediaFormat}s with no static + * payload type. The method is useful for formats such as "telephone-event" + * for example that is statically assigned the 101 payload type by some + * legacy systems. Signalling protocol implementations such as SIP and XMPP + * should make sure that, whenever this is possible, they assign to formats + * the dynamic payload type returned in this {@link Map}. + */ + private static Map<MediaFormat, Byte> dynamicPayloadTypePreferences; + + /** * Creates a new <tt>MediaStream</tt> instance which will use the specified * <tt>MediaDevice</tt> for both capture and playback of media exchanged * via the specified <tt>StreamConnector</tt>. @@ -531,4 +543,32 @@ public class MediaServiceImpl } return best; } + + /** + * Returns a {@link Map} that binds indicates whatever preferences this + * media service implementation may have for the RTP payload type numbers + * that get dynamically assigned to {@link MediaFormat}s with no static + * payload type. The method is useful for formats such as "telephone-event" + * for example that is statically assigned the 101 payload type by some + * legacy systems. Signalling protocol implementations such as SIP and XMPP + * should make sure that, whenever this is possible, they assign to formats + * the dynamic payload type returned in this {@link Map}. + * + * @return a {@link Map} binding some formats to a preferred dynamic RTP + * payload type number. + */ + public Map<MediaFormat, Byte> getDynamicPayloadTypePreferences() + { + if(dynamicPayloadTypePreferences == null) + { + dynamicPayloadTypePreferences = new HashMap<MediaFormat, Byte>(); + + MediaFormat telephoneEvent + = MediaUtils.getMediaFormat("telephone-event", 8000); + + dynamicPayloadTypePreferences.put(telephoneEvent, (byte)101); + } + + return dynamicPayloadTypePreferences; + } } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java index 111e734..80b330a 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java @@ -14,7 +14,6 @@ import java.util.*; import javax.net.ssl.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.ProxyInfo.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.jabberconstants.*; import net.java.sip.communicator.util.*; @@ -1080,7 +1079,7 @@ public class ProtocolProviderServiceJabberImpl fireRegistrationStateChanged( getRegistrationState(), regState, reason, null); - + if(regState == RegistrationState.UNREGISTERED || regState == RegistrationState.CONNECTION_FAILED) { diff --git a/src/net/java/sip/communicator/service/neomedia/MediaService.java b/src/net/java/sip/communicator/service/neomedia/MediaService.java index a8ab154..62c6320 100644 --- a/src/net/java/sip/communicator/service/neomedia/MediaService.java +++ b/src/net/java/sip/communicator/service/neomedia/MediaService.java @@ -132,4 +132,19 @@ public interface MediaService * @return default screen device */ public ScreenDevice getDefaultScreenDevice(); + + /** + * Returns a {@link Map} that binds indicates whatever preferences the + * media service implementation may have for the RTP payload type numbers + * that get dynamically assigned to {@link MediaFormat}s with no static + * payload type. The method is useful for formats such as "telephone-event" + * for example that is statically assigned the 101 payload type by some + * legacy systems. Signalling protocol implementations such as SIP and XMPP + * should make sure that, whenever this is possible, they assign to formats + * the dynamic payload type returned in this {@link Map}. + * + * @return a {@link Map} binding some formats to a preferred dynamic RTP + * payload type number. + */ + public Map<MediaFormat, Byte> getDynamicPayloadTypePreferences(); } diff --git a/src/net/java/sip/communicator/service/protocol/media/DynamicPayloadTypeRegistry.java b/src/net/java/sip/communicator/service/protocol/media/DynamicPayloadTypeRegistry.java index 15594c6..1ddf42d 100644 --- a/src/net/java/sip/communicator/service/protocol/media/DynamicPayloadTypeRegistry.java +++ b/src/net/java/sip/communicator/service/protocol/media/DynamicPayloadTypeRegistry.java @@ -7,6 +7,7 @@ package net.java.sip.communicator.service.protocol.media; import java.util.*; +import java.util.Map.*; import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.neomedia.format.*; @@ -82,10 +83,26 @@ public class DynamicPayloadTypeRegistry } } - //hey, we already had this one, let's return it ;) + //seems like we haven't allocated a payload type for this format yet. + //lets try to do so now. if (payloadType == null) { - payloadType = nextPayloadTypeNumber(); + //first, let's check whether there's a particular PT number that + //this format would like to have (e.g. "telephone-event" generally + //loves to be called "101"). + Byte preferredPT = getPreferredDynamicPayloadType(format); + + if(preferredPT != null && findFormat(preferredPT) == null) + { + //the format has a preference and it's free + payloadType = preferredPT; + } + else + { + //the format does not have a preferred PT number or it isn't + //free. + payloadType = nextPayloadTypeNumber(); + } payloadTypeMappings.put(format, payloadType); } @@ -93,6 +110,22 @@ public class DynamicPayloadTypeRegistry } /** + * Returns the payload type number that <tt>format</tt> would like to use if + * possible and <tt>null</tt> if there is no such preference. + * + * @param format the {@link MediaFormat} whose preferred dynamic PT number + * we are trying to obtain. + * + * @return the payload type number that <tt>format</tt> would like to use if + * possible and <tt>null</tt> if there is no such preference. + */ + private Byte getPreferredDynamicPayloadType(MediaFormat format) + { + return ProtocolMediaActivator.getMediaService() + .getDynamicPayloadTypePreferences().get(format); + } + + /** * Adds the specified <tt>format</tt> to <tt>payloadType</tt> mapping to * the list of mappings known to this registry. The method is meant for * use primarily when handling incoming media descriptions, methods @@ -176,7 +209,8 @@ public class DynamicPayloadTypeRegistry byte payloadType = nextDynamicPayloadType++; - if(findFormat(payloadType) == null) + if(findFormat(payloadType) == null + && findFormatWithPreference(payloadType) == null) return payloadType; //if we get here then that means that the number we obtained by @@ -186,6 +220,32 @@ public class DynamicPayloadTypeRegistry } /** + * Returns the {@link MediaFormat} with the specified + * <tt>payloadTypePreference</tt> or <tt>null</tt> if no {@link MediaFormat} + * has claimed this payload type number as preferred. + * + * @param payloadTypePreference the dynamic payload type number that we + * are trying to determine as being claimed as preferred or not by a + * media format. + * + * @return the {@link MediaFormat} with the specified + * <tt>payloadTypePreference</tt> or <tt>null</tt> if no {@link MediaFormat} + * has claimed this payload type number as preferred. + */ + private MediaFormat findFormatWithPreference(Byte payloadTypePreference) + { + for(Entry<MediaFormat, Byte> entry + : ProtocolMediaActivator.getMediaService() + .getDynamicPayloadTypePreferences().entrySet()) + { + if(entry.getValue() == payloadTypePreference) + return entry.getKey(); + } + + return null; + } + + /** * Returns a copy of all mappings currently registered in this registry. * * @return a copy of all mappings currently registered in this registry. |