diff options
Diffstat (limited to 'src/net/java/sip/communicator/impl/neomedia/MediaUtils.java')
-rw-r--r-- | src/net/java/sip/communicator/impl/neomedia/MediaUtils.java | 454 |
1 files changed, 222 insertions, 232 deletions
diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java b/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java index 938720f..b40c701 100644 --- a/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java +++ b/src/net/java/sip/communicator/impl/neomedia/MediaUtils.java @@ -30,16 +30,14 @@ public class MediaUtils * The constant which stands for an empty array of <tt>MediaFormat</tt>s. * Explicitly defined in order to reduce unnecessary allocations. */ - private static final MediaFormat[] EMPTY_MEDIA_FORMATS = new MediaFormat[0]; + public static final MediaFormat[] EMPTY_MEDIA_FORMATS = new MediaFormat[0]; - /** - * The <tt>Map</tt> of RTP payload types (expressed as <tt>String</tt>s) to - * their well-known encoding names (in contrast to the JMF-specific - * encodings). - */ - private static final Map<String, String> rtpPayloadTypeStrToEncodings + private static final Map<String, String> jmfEncodingToEncodings = new HashMap<String, String>(); + private static final List<MediaFormat> rtpPayloadTypelessMediaFormats + = new ArrayList<MediaFormat>(); + /** * The <tt>Map</tt> of RTP payload types (expressed as <tt>String</tt>s) to * <tt>MediaFormat</tt>s. @@ -50,13 +48,13 @@ public class MediaUtils static { - mapRtpPayloadTypeToMediaFormats( + addMediaFormats( SdpConstants.PCMU, "PCMU", MediaType.AUDIO, AudioFormat.ULAW_RTP, 8000); - mapRtpPayloadTypeToMediaFormats( + addMediaFormats( SdpConstants.GSM, "GSM", MediaType.AUDIO, @@ -67,7 +65,7 @@ public class MediaUtils = new HashMap<String, String>(); g723FormatProperties.put("annexa", "no"); g723FormatProperties.put("bitrate", "6.3"); - mapRtpPayloadTypeToMediaFormats( + addMediaFormats( SdpConstants.G723, "G723", MediaType.AUDIO, @@ -75,63 +73,63 @@ public class MediaUtils g723FormatProperties, 8000); - mapRtpPayloadTypeToMediaFormats( + addMediaFormats( SdpConstants.DVI4_8000, "DVI4", MediaType.AUDIO, AudioFormat.DVI_RTP, 8000); - mapRtpPayloadTypeToMediaFormats( + addMediaFormats( SdpConstants.DVI4_16000, "DVI4", MediaType.AUDIO, AudioFormat.DVI_RTP, 16000); - mapRtpPayloadTypeToMediaFormats( + addMediaFormats( SdpConstants.PCMA, "PCMA", MediaType.AUDIO, Constants.ALAW_RTP, 8000); - mapRtpPayloadTypeToMediaFormats( - 97, - null, - MediaType.AUDIO, - Constants.ILBC_RTP); - mapRtpPayloadTypeToMediaFormats( - 98, - null, + addMediaFormats( + MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, + "iLBC", MediaType.AUDIO, - Constants.ILBC_RTP); - mapRtpPayloadTypeToMediaFormats( - 110, - null, + Constants.ILBC_RTP, + 8000); + addMediaFormats( + MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, + "speex", MediaType.AUDIO, - Constants.SPEEX_RTP); - mapRtpPayloadTypeToMediaFormats( + Constants.SPEEX_RTP, + 8000, + 16000, + 32000); + addMediaFormats( SdpConstants.G728, "G728", MediaType.AUDIO, AudioFormat.G728_RTP, 8000); - mapRtpPayloadTypeToMediaFormats( - SdpConstants.G729, - "G729", - MediaType.AUDIO, - AudioFormat.G729_RTP, - 8000); - - mapRtpPayloadTypeToMediaFormats( + if (EncodingConfiguration.G729) + addMediaFormats( + SdpConstants.G729, + "G729", + MediaType.AUDIO, + AudioFormat.G729_RTP, + 8000); + + addMediaFormats( SdpConstants.H263, "H263", MediaType.VIDEO, VideoFormat.H263_RTP); - mapRtpPayloadTypeToMediaFormats( + addMediaFormats( SdpConstants.JPEG, "JPEG", MediaType.VIDEO, VideoFormat.JPEG_RTP); - mapRtpPayloadTypeToMediaFormats( + addMediaFormats( SdpConstants.H261, "H261", MediaType.VIDEO, @@ -140,144 +138,13 @@ public class MediaUtils Map<String, String> h264FormatProperties = new HashMap<String, String>(); h264FormatProperties.put("packetization-mode", "1"); - mapRtpPayloadTypeToMediaFormats( - Constants.H264_RTP_SDP, - null, + addMediaFormats( + MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN, + "H264", MediaType.VIDEO, Constants.H264_RTP, h264FormatProperties); } - - /** - * Gets the <tt>MediaFormat</tt>s predefined in <tt>MediaUtils</tt> with a - * specific well-known encoding (name) as defined by RFC 3551 "RTP Profile - * for Audio and Video Conferences with Minimal Control". - * - * @param encoding the well-known encoding (name) to get the corresponding - * <tt>MediaFormat</tt>s of - * @return a <tt>List</tt> of <tt>MediaFormat</tt>s corresponding to the - * specified encoding (name) - */ - public static List<MediaFormat> encodingToMediaFormats(String encoding) - { - List<MediaFormat> mediaFormats = new ArrayList<MediaFormat>(); - - for (Map.Entry<String, String> rtpPayloadTypeStrToEncoding - : rtpPayloadTypeStrToEncodings.entrySet()) - if (rtpPayloadTypeStrToEncoding.getValue().equals(encoding)) - for (MediaFormat mediaFormat - : rtpPayloadTypeToMediaFormats( - rtpPayloadTypeStrToEncoding.getKey())) - mediaFormats.add(mediaFormat); - return mediaFormats; - } - - /** - * Gets a <tt>MediaFormat</tt> predefined in <tt>MediaUtils</tt> which - * represents a specific JMF <tt>Format</tt>. If there is no such - * representing <tt>MediaFormat</tt> in <tt>MediaUtils</tt>, returns - * <tt>null</tt>. - * - * @param format the JMF <tt>Format</tt> to get the <tt>MediaFormat</tt> - * representation for - * @return a <tt>MediaFormat</tt> predefined in <tt>MediaUtils</tt> which - * represents <tt>format</tt> if any; <tt>null</tt> if there is no such - * representing <tt>MediaFormat</tt> in <tt>MediaUtils</tt> - */ - public static MediaFormat formatToMediaFormat(Format format) - { - int rtpPayloadType = jmfEncodingToRtpPayloadType(format.getEncoding()); - - if (MediaFormatImpl.RTP_PAYLOAD_TYPE_UNKNOWN != rtpPayloadType) - { - for (MediaFormat mediaFormat - : rtpPayloadTypeToMediaFormats(Integer.toString(rtpPayloadType))) - { - MediaFormatImpl<? extends Format> mediaFormatImpl - = (MediaFormatImpl<? extends Format>) mediaFormat; - - if (format.matches(mediaFormatImpl.getFormat())) - return mediaFormat; - } - } - return null; - } - - /** - * Gets the well-known encoding (name) as defined in RFC 3551 "RTP Profile - * for Audio and Video Conferences with Minimal Control" corresponding to a - * given JMF-specific encoding. - * - * @param jmfEncoding the JMF encoding to get the corresponding well-known - * encoding of - * @return the well-known encoding (name) as defined in RFC 3551 "RTP - * Profile for Audio and Video Conferences with Minimal Control" - * corresponding to <tt>jmfEncoding</tt> if any; otherwise, <tt>null</tt> - */ - public static String jmfEncodingToEncoding(String jmfEncoding) - { - int rtpPayloadType = jmfEncodingToRtpPayloadType(jmfEncoding); - String encoding = null; - - if (MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN != rtpPayloadType) - encoding - = rtpPayloadTypeStrToEncodings - .get(Integer.toString(rtpPayloadType)); - return encoding; - } - - /** - * Gets the RTP payload type corresponding to a specific JMF encoding. - * - * @param jmfEncoding the JMF encoding as returned by - * {@link Format#getEncoding()} or the respective <tt>AudioFormat</tt> and - * <tt>VideoFormat</tt> encoding constants to get the corresponding RTP - * payload type of - * @return the RTP payload type corresponding to the specified JMF encoding - * if known in RFC 3551 "RTP Profile for Audio and Video Conferences with - * Minimal Control"; otherwise, {@link MediaFormat#RTP_PAYLOAD_TYPE_UNKNOWN} - */ - public static int jmfEncodingToRtpPayloadType(String jmfEncoding) - { - if (jmfEncoding == null) - return MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN; - else if (jmfEncoding.equals(AudioFormat.ULAW_RTP)) - return SdpConstants.PCMU; - else if (jmfEncoding.equals(Constants.ALAW_RTP)) - return SdpConstants.PCMA; - else if (jmfEncoding.equals(AudioFormat.GSM_RTP)) - return SdpConstants.GSM; - else if (jmfEncoding.equals(AudioFormat.G723_RTP)) - return SdpConstants.G723; - else if (jmfEncoding.equals(AudioFormat.DVI_RTP)) - return SdpConstants.DVI4_8000; - else if (jmfEncoding.equals(AudioFormat.DVI_RTP)) - return SdpConstants.DVI4_16000; - else if (jmfEncoding.equals(AudioFormat.ALAW)) - return SdpConstants.PCMA; - else if (jmfEncoding.equals(AudioFormat.G728_RTP)) - return SdpConstants.G728; - else if (jmfEncoding.equals(AudioFormat.G729_RTP)) - return SdpConstants.G729; - else if (jmfEncoding.equals(VideoFormat.H263_RTP)) - return SdpConstants.H263; - else if (jmfEncoding.equals(VideoFormat.JPEG_RTP)) - return SdpConstants.JPEG; - else if (jmfEncoding.equals(VideoFormat.H261_RTP)) - return SdpConstants.H261; - else if (jmfEncoding.equals(Constants.H264_RTP)) - return Constants.H264_RTP_SDP; - else if (jmfEncoding.equals(Constants.ILBC)) - return 97; - else if (jmfEncoding.equals(Constants.ILBC_RTP)) - return 97; - else if (jmfEncoding.equals(Constants.SPEEX)) - return 110; - else if (jmfEncoding.equals(Constants.SPEEX_RTP)) - return 110; - else - return MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN; - } /** * Adds a new mapping of a specific RTP payload type to a list of * <tt>MediaFormat</tt>s of a specific <tt>MediaType</tt>, with a specific @@ -295,14 +162,14 @@ public class MediaUtils * @param clockRates the optional list of clock rates of the * <tt>MediaFormat</tt>s to be associated with <tt>rtpPayloadType</tt> */ - private static void mapRtpPayloadTypeToMediaFormats( + private static void addMediaFormats( int rtpPayloadType, String encoding, MediaType mediaType, String jmfEncoding, double... clockRates) { - mapRtpPayloadTypeToMediaFormats( + addMediaFormats( rtpPayloadType, encoding, mediaType, @@ -330,7 +197,7 @@ public class MediaUtils * @param clockRates the optional list of clock rates of the * <tt>MediaFormat</tt>s to be associated with <tt>rtpPayloadType</tt> */ - private static void mapRtpPayloadTypeToMediaFormats( + private static void addMediaFormats( int rtpPayloadType, String encoding, MediaType mediaType, @@ -398,41 +265,193 @@ public class MediaUtils } } - int mediaFormatCount = mediaFormats.size(); - String rtpPayloadTypeStr = Integer.toString(rtpPayloadType); - - if (mediaFormatCount > 0) - rtpPayloadTypeStrToMediaFormats + if (mediaFormats.size() > 0) + { + if (MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN == rtpPayloadType) + rtpPayloadTypelessMediaFormats.addAll(mediaFormats); + else + rtpPayloadTypeStrToMediaFormats + .put( + Integer.toString(rtpPayloadType), + mediaFormats.toArray(EMPTY_MEDIA_FORMATS)); + + jmfEncodingToEncodings .put( - rtpPayloadTypeStr, - mediaFormats.toArray(new MediaFormat[mediaFormatCount])); - - /* - * If there's also a well-known encoding name for the specified RTP - * payload type, remember it as well. - */ - if (encoding != null) - rtpPayloadTypeStrToEncodings.put(rtpPayloadTypeStr, encoding); + ((MediaFormatImpl<? extends Format>) mediaFormats.get(0)) + .getJMFEncoding(), + encoding); + } } /** - * Returns the JMF encoding as specified in <tt>AudioFormat</tt> and - * <tt>VideoFormat</tt> corresponding to the specified RTP payload type. - * - * @param rtpPayloadTypeStr the RTP payload type as <tt>String</tt> to get - * the respective JMF encoding of - * @return the JMF encoding corresponding to the specified RTP payload type + * Gets a <tt>MediaFormat</tt> predefined in <tt>MediaUtils</tt> which + * represents a specific JMF <tt>Format</tt>. If there is no such + * representing <tt>MediaFormat</tt> in <tt>MediaUtils</tt>, returns + * <tt>null</tt>. + * + * @param format the JMF <tt>Format</tt> to get the <tt>MediaFormat</tt> + * representation for + * @return a <tt>MediaFormat</tt> predefined in <tt>MediaUtils</tt> which + * represents <tt>format</tt> if any; <tt>null</tt> if there is no such + * representing <tt>MediaFormat</tt> in <tt>MediaUtils</tt> */ - public static String rtpPayloadTypeToJmfEncoding(String rtpPayloadTypeStr) + public static MediaFormat getMediaFormat(Format format) { - MediaFormat[] mediaFormats - = rtpPayloadTypeStrToMediaFormats.get(rtpPayloadTypeStr); + double clockRate; - return - ((mediaFormats != null) && (mediaFormats.length > 0)) - ? ((MediaFormatImpl<? extends Format>) mediaFormats[0]) - .getJMFEncoding() - : null; + if (format instanceof AudioFormat) + clockRate = ((AudioFormat) format).getSampleRate(); + else if (format instanceof VideoFormat) + clockRate = VideoMediaFormatImpl.DEFAULT_CLOCK_RATE; + else + clockRate = Format.NOT_SPECIFIED; + + int rtpPayloadType = getRTPPayloadType(format.getEncoding(), clockRate); + + if (MediaFormatImpl.RTP_PAYLOAD_TYPE_UNKNOWN != rtpPayloadType) + { + for (MediaFormat mediaFormat + : rtpPayloadTypeToMediaFormats(Integer.toString(rtpPayloadType))) + { + MediaFormatImpl<? extends Format> mediaFormatImpl + = (MediaFormatImpl<? extends Format>) mediaFormat; + + if (format.matches(mediaFormatImpl.getFormat())) + return mediaFormat; + } + } + return null; + } + + public static MediaFormat getMediaFormat(String encoding, double clockRate) + { + for (MediaFormat format : getMediaFormats(encoding)) + if (format.getClockRate() == clockRate) + return format; + return null; + } + + /** + * Gets the <tt>MediaFormat</tt>s predefined in <tt>MediaUtils</tt> with a + * specific well-known encoding (name) as defined by RFC 3551 "RTP Profile + * for Audio and Video Conferences with Minimal Control". + * + * @param encoding the well-known encoding (name) to get the corresponding + * <tt>MediaFormat</tt>s of + * @return a <tt>List</tt> of <tt>MediaFormat</tt>s corresponding to the + * specified encoding (name) + */ + public static List<MediaFormat> getMediaFormats(String encoding) + { + String jmfEncoding = null; + + for (Map.Entry<String, String> jmfEncodingToEncoding + : jmfEncodingToEncodings.entrySet()) + if (jmfEncodingToEncoding.getValue().equals(encoding)) + { + jmfEncoding = jmfEncodingToEncoding.getKey(); + break; + } + + List<MediaFormat> mediaFormats = new ArrayList<MediaFormat>(); + + if (jmfEncoding != null) + { + for (MediaFormat[] rtpPayloadTypeMediaFormats + : rtpPayloadTypeStrToMediaFormats.values()) + for (MediaFormat rtpPayloadTypeMediaFormat + : rtpPayloadTypeMediaFormats) + if (((MediaFormatImpl<? extends Format>) + rtpPayloadTypeMediaFormat) + .getJMFEncoding().equals(jmfEncoding)) + mediaFormats.add(rtpPayloadTypeMediaFormat); + + if (mediaFormats.size() < 1) + { + for (MediaFormat rtpPayloadTypelessMediaFormat + : rtpPayloadTypelessMediaFormats) + if (((MediaFormatImpl<? extends Format>) + rtpPayloadTypelessMediaFormat) + .getJMFEncoding().equals(jmfEncoding)) + mediaFormats.add(rtpPayloadTypelessMediaFormat); + } + } + return mediaFormats; + } + + public static MediaFormat[] getMediaFormats(MediaType mediaType) + { + List<MediaFormat> mediaFormats = new ArrayList<MediaFormat>(); + + for (MediaFormat[] formats : rtpPayloadTypeStrToMediaFormats.values()) + for (MediaFormat format : formats) + if (format.getMediaType().equals(mediaType)) + mediaFormats.add(format); + for (MediaFormat format : rtpPayloadTypelessMediaFormats) + if (format.getMediaType().equals(mediaType)) + mediaFormats.add(format); + return mediaFormats.toArray(EMPTY_MEDIA_FORMATS); + } + + /** + * Gets the well-known encoding (name) as defined in RFC 3551 "RTP Profile + * for Audio and Video Conferences with Minimal Control" corresponding to a + * given JMF-specific encoding. + * + * @param jmfEncoding the JMF encoding to get the corresponding well-known + * encoding of + * @return the well-known encoding (name) as defined in RFC 3551 "RTP + * Profile for Audio and Video Conferences with Minimal Control" + * corresponding to <tt>jmfEncoding</tt> if any; otherwise, <tt>null</tt> + */ + public static String jmfEncodingToEncoding(String jmfEncoding) + { + return jmfEncodingToEncodings.get(jmfEncoding); + } + + /** + * Gets the RTP payload type corresponding to a specific JMF encoding. + * + * @param jmfEncoding the JMF encoding as returned by + * {@link Format#getEncoding()} or the respective <tt>AudioFormat</tt> and + * <tt>VideoFormat</tt> encoding constants to get the corresponding RTP + * payload type of + * @return the RTP payload type corresponding to the specified JMF encoding + * if known in RFC 3551 "RTP Profile for Audio and Video Conferences with + * Minimal Control"; otherwise, {@link MediaFormat#RTP_PAYLOAD_TYPE_UNKNOWN} + */ + public static int getRTPPayloadType(String jmfEncoding, double clockRate) + { + if (jmfEncoding == null) + return MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN; + else if (jmfEncoding.equals(AudioFormat.ULAW_RTP)) + return SdpConstants.PCMU; + else if (jmfEncoding.equals(Constants.ALAW_RTP)) + return SdpConstants.PCMA; + else if (jmfEncoding.equals(AudioFormat.GSM_RTP)) + return SdpConstants.GSM; + else if (jmfEncoding.equals(AudioFormat.G723_RTP)) + return SdpConstants.G723; + else if (jmfEncoding.equals(AudioFormat.DVI_RTP) + && (clockRate == 8000)) + return SdpConstants.DVI4_8000; + else if (jmfEncoding.equals(AudioFormat.DVI_RTP) + && (clockRate == 16000)) + return SdpConstants.DVI4_16000; + else if (jmfEncoding.equals(AudioFormat.ALAW)) + return SdpConstants.PCMA; + else if (jmfEncoding.equals(AudioFormat.G728_RTP)) + return SdpConstants.G728; + else if (jmfEncoding.equals(AudioFormat.G729_RTP)) + return SdpConstants.G729; + else if (jmfEncoding.equals(VideoFormat.H263_RTP)) + return SdpConstants.H263; + else if (jmfEncoding.equals(VideoFormat.JPEG_RTP)) + return SdpConstants.JPEG; + else if (jmfEncoding.equals(VideoFormat.H261_RTP)) + return SdpConstants.H261; + else + return MediaFormat.RTP_PAYLOAD_TYPE_UNKNOWN; } /** @@ -444,7 +463,7 @@ public class MediaUtils * @return an array of <tt>MediaFormat</tt>s corresponding to the specified * RTP payload type */ - public static MediaFormat[] rtpPayloadTypeToMediaFormats( + private static MediaFormat[] rtpPayloadTypeToMediaFormats( String rtpPayloadTypeStr) { MediaFormat[] mediaFormats @@ -455,33 +474,4 @@ public class MediaUtils ? EMPTY_MEDIA_FORMATS : mediaFormats.clone(); } - - /** - * Converts a list of RTP payload types (specified as <tt>String</tt>s) to - * a list of JMF-specific encodings (as returned by - * {@link Format#getEncoding()} or as specified by the respective - * <tt>AudioFormat</tt> and <tt>VideoFormat</tt> constants). - * - * @param rtpPayloadTypeStrings the list of RTP payload types (specified as - * <tt>String</tt>s) to be converted to a list of JMF-specific encodings - * @return a new list of JMF-specific encodings corresponding to the RTP - * payload types specified as <tt>String</tt>s by - * <tt>rtpPayloadTypeStrings</tt> - */ - public static List<String> rtpPayloadTypesToJmfEncodings( - List<String> rtpPayloadTypeStrings) - { - List<String> jmfEncodings = new ArrayList<String>(); - - if (rtpPayloadTypeStrings != null) - for (String rtpPayloadTypeStr : rtpPayloadTypeStrings) - { - String jmfEncoding - = rtpPayloadTypeToJmfEncoding(rtpPayloadTypeStr); - - if (jmfEncoding != null) - jmfEncodings.add(jmfEncoding); - } - return jmfEncodings; - } } |