diff options
author | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2009-10-31 13:11:28 +0000 |
---|---|---|
committer | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2009-10-31 13:11:28 +0000 |
commit | b66402a5d554373dcbaaea5a96f00d12a36c4a84 (patch) | |
tree | 6a436c1b4437005eab3ed4c76d8988e5dda15142 | |
parent | 5196a50d385bb11463cc5b1aa4b61037b365a7f5 (diff) | |
download | jitsi-b66402a5d554373dcbaaea5a96f00d12a36c4a84.zip jitsi-b66402a5d554373dcbaaea5a96f00d12a36c4a84.tar.gz jitsi-b66402a5d554373dcbaaea5a96f00d12a36c4a84.tar.bz2 |
Fixes MediaFormats which don't have assigned RTP payload types by RFC 3551 yet they were implemented with hard-coded RTP payload types. Modifies the Neomedia ConfigurationForm to display the encoding names and the clock rates of the MediaFormats instead of their JMF-specific encodings. Introduces MediaService#getFormatFactory().
12 files changed, 516 insertions, 486 deletions
diff --git a/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java b/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java index 36b8f5c..5ed3c49 100644 --- a/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/AudioMediaStreamImpl.java @@ -41,8 +41,8 @@ public class AudioMediaStreamImpl * * @see #registerCustomCodecFormats(RTPManager) */ - private static final Format[] CUSTOM_CODEC_FORMATS - = new Format[] + private static final AudioFormat[] CUSTOM_CODEC_FORMATS + = new AudioFormat[] { /* * these formats are specific, since RTP uses format numbers @@ -142,7 +142,7 @@ public class AudioMediaStreamImpl && formatsRegisteredOnce) return; - for (Format format : CUSTOM_CODEC_FORMATS) + for (AudioFormat format : CUSTOM_CODEC_FORMATS) { logger.debug("registering format " + format + " with RTP manager"); @@ -156,7 +156,9 @@ public class AudioMediaStreamImpl .addFormat( format, MediaUtils - .jmfEncodingToRtpPayloadType(format.getEncoding())); + .getRTPPayloadType( + format.getEncoding(), + format.getSampleRate())); } formatsRegisteredOnce = true; diff --git a/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java b/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java index e7525a7..db6470a 100644 --- a/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java +++ b/src/net/java/sip/communicator/impl/neomedia/EncodingConfigurationTableModel.java @@ -11,6 +11,9 @@ import java.util.*; import javax.swing.table.*;
import net.java.sip.communicator.impl.neomedia.codec.*;
+import net.java.sip.communicator.impl.neomedia.format.*;
+import net.java.sip.communicator.service.neomedia.*;
+import net.java.sip.communicator.service.neomedia.format.*;
/**
* @author Lubomir Marinov
@@ -18,28 +21,30 @@ import net.java.sip.communicator.impl.neomedia.codec.*; public class EncodingConfigurationTableModel
extends AbstractTableModel
{
- public static final int AUDIO = DeviceConfigurationComboBoxModel.AUDIO;
-
- private static final String[] NO_ENCODINGS = new String[0];
-
- public static final int VIDEO = DeviceConfigurationComboBoxModel.VIDEO;
-
private final EncodingConfiguration encodingConfiguration;
- private String[] encodings;
+ private MediaFormat[] encodings;
- private final int type;
+ private final MediaType type;
public EncodingConfigurationTableModel(
EncodingConfiguration encodingConfiguration, int type)
{
if (encodingConfiguration == null)
throw new IllegalArgumentException("encodingConfiguration");
- if ((type != AUDIO) && (type != VIDEO))
- throw new IllegalArgumentException("type");
-
this.encodingConfiguration = encodingConfiguration;
- this.type = type;
+
+ switch (type)
+ {
+ case DeviceConfigurationComboBoxModel.AUDIO:
+ this.type = MediaType.AUDIO;
+ break;
+ case DeviceConfigurationComboBoxModel.VIDEO:
+ this.type = MediaType.VIDEO;
+ break;
+ default:
+ throw new IllegalArgumentException("type");
+ }
}
public Class<?> getColumnClass(int columnIndex)
@@ -53,49 +58,39 @@ public class EncodingConfigurationTableModel return 2;
}
- private String[] getEncodings()
+ private MediaFormat[] getEncodings()
{
if (encodings != null)
return encodings;
- String[] availableEncodings;
- switch (type)
- {
- case AUDIO:
- availableEncodings =
- encodingConfiguration.getAvailableAudioEncodings();
- break;
- case VIDEO:
- availableEncodings =
- encodingConfiguration.getAvailableVideoEncodings();
- break;
- default:
- throw new IllegalStateException("type");
- }
+ MediaFormat[] availableEncodings
+ = encodingConfiguration.getAvailableEncodings(type);
final int encodingCount = availableEncodings.length;
if (encodingCount < 1)
- encodings = NO_ENCODINGS;
+ encodings = MediaUtils.EMPTY_MEDIA_FORMATS;
else
{
- encodings = new String[encodingCount];
+ encodings = new MediaFormat[encodingCount];
System
.arraycopy(availableEncodings, 0, encodings, 0, encodingCount);
- Arrays.sort(encodings, 0, encodingCount, new Comparator<String>()
- {
- public int compare(String encoding0, String encoding1)
+ Arrays
+ .sort(encodings, 0, encodingCount, new Comparator<MediaFormat>()
{
- return encodingConfiguration.getPriority(encoding1) -
- encodingConfiguration.getPriority(encoding0);
- }
- });
+ public int compare(MediaFormat format0, MediaFormat format1)
+ {
+ return
+ encodingConfiguration.getPriority(format1)
+ - encodingConfiguration.getPriority(format0);
+ }
+ });
}
return encodings;
}
private int[] getPriorities()
{
- String[] encodings = getEncodings();
+ MediaFormat[] encodings = getEncodings();
final int count = encodings.length;
int[] priorities = new int[count];
for (int i = 0; i < count; i++)
@@ -113,13 +108,21 @@ public class EncodingConfigurationTableModel public Object getValueAt(int rowIndex, int columnIndex)
{
- String encoding = getEncodings()[rowIndex];
+ MediaFormat encoding = getEncodings()[rowIndex];
switch (columnIndex)
{
case 0:
return (encodingConfiguration.getPriority(encoding) > 0);
case 1:
- return MediaUtils.rtpPayloadTypeToJmfEncoding(encoding);
+ if (MediaType.VIDEO.equals(encoding.getMediaType())
+ && (VideoMediaFormatImpl.DEFAULT_CLOCK_RATE
+ == encoding.getClockRate()))
+ return encoding.getEncoding();
+ else
+ return
+ encoding.getEncoding()
+ + "/"
+ + ((long) encoding.getClockRate());
default:
return null;
}
@@ -151,7 +154,7 @@ public class EncodingConfigurationTableModel priorities[nextRowIndex] = priorities.length - rowIndex;
setPriorities(priorities);
- String swap = encodings[rowIndex];
+ MediaFormat swap = encodings[rowIndex];
encodings[rowIndex] = encodings[nextRowIndex];
encodings[nextRowIndex] = swap;
diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaConfigurationPanel.java b/src/net/java/sip/communicator/impl/neomedia/MediaConfigurationPanel.java index a5bd81b..2165942 100644 --- a/src/net/java/sip/communicator/impl/neomedia/MediaConfigurationPanel.java +++ b/src/net/java/sip/communicator/impl/neomedia/MediaConfigurationPanel.java @@ -1,6 +1,6 @@ /*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
- *
+ *
* Distributable under LGPL license. See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.neomedia;
@@ -59,14 +59,14 @@ public class MediaConfigurationPanel * Because the creation of the preview is asynchronous, it's possible to
* request the preview of one and the same device multiple times. Which may
* lead to failures because of, for example, busy devices and/or resources
- * (as is the case with LTI-CIVIL and video4linux2).
+ * (as is the case with LTI-CIVIL and video4linux2).
* </p>
*/
private CaptureDeviceInfo videoDeviceInPreview;
/**
* The <code>Player</code> depicting the preview of the currently selected
- * <code>CaptureDeviceInfo</code>.
+ * <code>CaptureDeviceInfo</code>.
*/
private Player videoPlayerInPreview;
@@ -100,37 +100,56 @@ public class MediaConfigurationPanel }
}
- private void createPortAudioControls(Container portAudioPanel)
+ private void createPortAudioControls(
+ JPanel portAudioPanel, JPanel parentPanel)
{
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+ constraints.anchor = GridBagConstraints.NORTHWEST;
+ constraints.gridx = 0;
+ constraints.weightx = 0;
+ constraints.weighty = 0;
+ constraints.gridy = 0;
+
+ portAudioPanel.add(new JLabel(getLabelText(
+ DeviceConfigurationComboBoxModel.AUDIO_CAPTURE)), constraints);
+ constraints.gridy = 1;
portAudioPanel.add(new JLabel(getLabelText(
- DeviceConfigurationComboBoxModel.AUDIO_CAPTURE)));
+ DeviceConfigurationComboBoxModel.AUDIO_PLAYBACK)), constraints);
+ constraints.gridy = 2;
+ portAudioPanel.add(new JLabel(getLabelText(
+ DeviceConfigurationComboBoxModel.AUDIO_NOTIFY)), constraints);
+
+ constraints.weightx = 1;
+ constraints.gridx = 1;
+ constraints.gridy = 0;
JComboBox captureCombo = new JComboBox();
captureCombo.setEditable(false);
captureCombo.setModel(
new DeviceConfigurationComboBoxModel(
mediaService.getDeviceConfiguration(),
DeviceConfigurationComboBoxModel.AUDIO_CAPTURE));
- portAudioPanel.add(captureCombo);
+ portAudioPanel.add(captureCombo, constraints);
- portAudioPanel.add(new JLabel(getLabelText(
- DeviceConfigurationComboBoxModel.AUDIO_PLAYBACK)));
+ constraints.gridy = 1;
JComboBox playbackCombo = new JComboBox();
playbackCombo.setEditable(false);
playbackCombo.setModel(
new DeviceConfigurationComboBoxModel(
mediaService.getDeviceConfiguration(),
DeviceConfigurationComboBoxModel.AUDIO_PLAYBACK));
- portAudioPanel.add(playbackCombo);
+ portAudioPanel.add(playbackCombo, constraints);
- portAudioPanel.add(new JLabel(getLabelText(
- DeviceConfigurationComboBoxModel.AUDIO_NOTIFY)));
+ constraints.gridy = 2;
JComboBox notifyCombo = new JComboBox();
notifyCombo.setEditable(false);
notifyCombo.setModel(
new DeviceConfigurationComboBoxModel(
mediaService.getDeviceConfiguration(),
DeviceConfigurationComboBoxModel.AUDIO_NOTIFY));
- portAudioPanel.add(notifyCombo);
+ portAudioPanel.add(notifyCombo, constraints);
+ parentPanel.setBorder(
+ BorderFactory.createTitledBorder("Devices"));
}
private Component createControls(int type)
@@ -148,11 +167,13 @@ public class MediaConfigurationPanel * input audio device, output audio device and audio device for playback
* of notifications.
*/
- final Container portAudioPanel;
+ final JPanel portAudioPanel;
+ final JPanel portAudioParentPanel;
if (type == DeviceConfigurationComboBoxModel.AUDIO)
{
portAudioPanel
- = new TransparentPanel(new GridLayout(3, 2, HGAP, VGAP));
+ = new TransparentPanel(new GridBagLayout());
+ portAudioParentPanel = new TransparentPanel(new BorderLayout());
comboBox.addItemListener(new ItemListener()
{
@@ -163,11 +184,13 @@ public class MediaConfigurationPanel if(DeviceConfiguration
.AUDIO_SYSTEM_PORTAUDIO.equals(e.getItem()))
{
- createPortAudioControls(portAudioPanel);
+ createPortAudioControls(
+ portAudioPanel, portAudioParentPanel);
}
else
{
portAudioPanel.removeAll();
+ portAudioParentPanel.setBorder(null);
revalidate();
repaint();
@@ -175,12 +198,16 @@ public class MediaConfigurationPanel }
}
});
- if (DeviceConfiguration
- .AUDIO_SYSTEM_PORTAUDIO.equals(comboBox.getSelectedItem()))
- createPortAudioControls(portAudioPanel);
+ if(comboBox
+ .getSelectedItem()
+ .equals(DeviceConfiguration.AUDIO_SYSTEM_PORTAUDIO))
+ createPortAudioControls(portAudioPanel, portAudioParentPanel);
}
else
+ {
portAudioPanel = null;
+ portAudioParentPanel = null;
+ }
JLabel label = new JLabel(getLabelText(type));
label.setDisplayedMnemonic(getDisplayedMnemonic(type));
@@ -197,19 +224,22 @@ public class MediaConfigurationPanel firstConstraints.weightx = 1;
firstContainer.add(comboBox, firstConstraints);
+ Container secondContainer =
+ new TransparentPanel(new GridLayout(1, 0, HGAP, VGAP));
+
+ // if creating controls for audio will add devices panel
+ // otherwise it is video controls and will add preview panel
if (portAudioPanel != null)
{
- firstConstraints.gridx = 0;
- firstConstraints.gridy = 1;
- firstConstraints.weightx = 1;
- firstConstraints.gridwidth = 2;
- firstConstraints.insets = new Insets(VGAP, 0, 0, 0);
- firstContainer.add(portAudioPanel, firstConstraints);
+ // add portAudioPanel in new panel on north, as for some reason
+ // anchor = GridBagConstraints.NORTHWEST doesn't work
+ // and all components are vertically centered
+ portAudioParentPanel.add(portAudioPanel, BorderLayout.NORTH);
+ secondContainer.add(portAudioParentPanel);
}
+ else
+ secondContainer.add(createPreview(type, comboBox));
- Container secondContainer =
- new TransparentPanel(new GridLayout(1, 0, HGAP, VGAP));
- secondContainer.add(createPreview(type, comboBox));
secondContainer.add(createEncodingControls(type));
Container container = new TransparentPanel(new GridBagLayout());
@@ -378,12 +408,9 @@ public class MediaConfigurationPanel final Container preview;
if (type == DeviceConfigurationComboBoxModel.VIDEO)
{
- JLabel noPreview
- = new JLabel(
- NeomediaActivator
- .getResources()
- .getI18NString(
- "impl.media.configform.NO_PREVIEW"));
+ JLabel noPreview =
+ new JLabel(NeomediaActivator.getResources().getI18NString(
+ "impl.media.configform.NO_PREVIEW"));
noPreview.setHorizontalAlignment(SwingConstants.CENTER);
noPreview.setVerticalAlignment(SwingConstants.CENTER);
@@ -480,15 +507,11 @@ public class MediaConfigurationPanel switch (type)
{
case DeviceConfigurationComboBoxModel.AUDIO:
- return
- NeomediaActivator
- .getResources()
- .getI18nMnemonic("impl.media.configform.AUDIO");
+ return NeomediaActivator.getResources().getI18nMnemonic(
+ "impl.media.configform.AUDIO");
case DeviceConfigurationComboBoxModel.VIDEO:
- return
- NeomediaActivator
- .getResources()
- .getI18nMnemonic("impl.media.configform.VIDEO");
+ return NeomediaActivator.getResources().getI18nMnemonic(
+ "impl.media.configform.VIDEO");
default:
throw new IllegalArgumentException("type");
}
@@ -499,30 +522,20 @@ public class MediaConfigurationPanel switch (type)
{
case DeviceConfigurationComboBoxModel.AUDIO:
- return
- NeomediaActivator
- .getResources()
- .getI18NString("impl.media.configform.AUDIO");
+ return NeomediaActivator.getResources().getI18NString(
+ "impl.media.configform.AUDIO");
case DeviceConfigurationComboBoxModel.AUDIO_CAPTURE:
- return
- NeomediaActivator
- .getResources()
- .getI18NString("impl.media.configform.AUDIO_IN");
+ return NeomediaActivator.getResources().getI18NString(
+ "impl.media.configform.AUDIO_IN");
case DeviceConfigurationComboBoxModel.AUDIO_NOTIFY:
- return
- NeomediaActivator
- .getResources()
- .getI18NString("impl.media.configform.AUDIO_NOTIFY");
+ return NeomediaActivator.getResources().getI18NString(
+ "impl.media.configform.AUDIO_NOTIFY");
case DeviceConfigurationComboBoxModel.AUDIO_PLAYBACK:
- return
- NeomediaActivator
- .getResources()
- .getI18NString("impl.media.configform.AUDIO_OUT");
+ return NeomediaActivator.getResources().getI18NString(
+ "impl.media.configform.AUDIO_OUT");
case DeviceConfigurationComboBoxModel.VIDEO:
- return
- NeomediaActivator
- .getResources()
- .getI18NString("impl.media.configform.VIDEO");
+ return NeomediaActivator.getResources().getI18NString(
+ "impl.media.configform.VIDEO");
default:
throw new IllegalArgumentException("type");
}
diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java index 3edf4a6..2443b9e 100644 --- a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java @@ -12,8 +12,10 @@ import javax.media.*; import net.java.sip.communicator.impl.neomedia.codec.*; import net.java.sip.communicator.impl.neomedia.device.*; +import net.java.sip.communicator.impl.neomedia.format.*; import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.neomedia.device.*; +import net.java.sip.communicator.service.neomedia.format.*; /** * Implements <tt>MediaService</tt> for JMF. @@ -61,6 +63,13 @@ public class MediaServiceImpl = new EncodingConfiguration(); /** + * The <tt>MediaFormatFactory</tt> through which <tt>MediaFormat</tt> + * instances may be created for the purposes of working with the + * <tt>MediaStream</tt>s created by this <tt>MediaService</tt>. + */ + private MediaFormatFactory formatFactory; + + /** * The list of video <tt>MediaDevice</tt>s reported by this instance when * its {@link MediaService#getDevices(MediaType)} method is called with an * argument {@link MediaType#VIDEO}. @@ -229,6 +238,23 @@ public class MediaServiceImpl } /** + * Gets the <tt>MediaFormatFactory</tt> through which <tt>MediaFormat</tt> + * instances may be created for the purposes of working with the + * <tt>MediaStream</tt>s created by this <tt>MediaService</tt>. + * + * @return the <tt>MediaFormatFactory</tt> through which + * <tt>MediaFormat</tt> instances may be created for the purposes of working + * with the <tt>MediaStream</tt>s created by this <tt>MediaService</tt> + * @see MediaService#getFormatFactory() + */ + public MediaFormatFactory getFormatFactory() + { + if (formatFactory == null) + formatFactory = new MediaFormatFactoryImpl(); + return formatFactory; + } + + /** * Starts this <tt>MediaService</tt> implementation and thus makes it * operational. */ 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; - } } diff --git a/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java b/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java index 8dcad68..a520f14 100644 --- a/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java @@ -17,6 +17,7 @@ import javax.media.rtp.*; import net.java.sip.communicator.impl.neomedia.codec.*; import net.java.sip.communicator.impl.neomedia.device.*; +import net.java.sip.communicator.impl.neomedia.format.*; import net.java.sip.communicator.service.neomedia.*; import net.java.sip.communicator.service.neomedia.device.*; import net.java.sip.communicator.service.neomedia.event.*; @@ -339,7 +340,10 @@ public class VideoMediaStreamImpl rtpManager .addFormat( format, - MediaUtils.jmfEncodingToRtpPayloadType(format.getEncoding())); + MediaUtils + .getRTPPayloadType( + format.getEncoding(), + VideoMediaFormatImpl.DEFAULT_CLOCK_RATE)); formatsRegisteredOnce = true; } diff --git a/src/net/java/sip/communicator/impl/neomedia/codec/EncodingConfiguration.java b/src/net/java/sip/communicator/impl/neomedia/codec/EncodingConfiguration.java index f842b77..41efd68 100644 --- a/src/net/java/sip/communicator/impl/neomedia/codec/EncodingConfiguration.java +++ b/src/net/java/sip/communicator/impl/neomedia/codec/EncodingConfiguration.java @@ -10,16 +10,19 @@ import java.io.*; import java.util.*; import javax.media.*; -import javax.sdp.*; import net.java.sip.communicator.impl.neomedia.*; +import net.java.sip.communicator.impl.neomedia.format.*; import net.java.sip.communicator.service.configuration.*; +import net.java.sip.communicator.service.neomedia.*; +import net.java.sip.communicator.service.neomedia.format.*; import net.java.sip.communicator.util.*; /** * Simple configuration of encoding priorities. * * @author Damian Minkov + * @author Lubomir Marinov */ public class EncodingConfiguration { @@ -28,51 +31,11 @@ public class EncodingConfiguration private static final String PROP_SDP_PREFERENCE = "net.java.sip.communicator.impl.media.sdppref"; - /** - * SDP Codes of all video formats that JMF supports. - */ - private final String[] availableVideoEncodings = new String[] - { - Integer.toString(Constants.H264_RTP_SDP), - // javax.media.format.VideoFormat.H263_RTP - Integer.toString(SdpConstants.H263), - // javax.media.format.VideoFormat.JPEG_RTP - Integer.toString(SdpConstants.JPEG), - // javax.media.format.VideoFormat.H261_RTP - Integer.toString(SdpConstants.H261) - }; + private final Set<MediaFormat> supportedVideoEncodings = + new TreeSet<MediaFormat>(new EncodingComparator()); - /** - * SDP Codes of all audio formats that JMF supports. - */ - private final String[] availableAudioEncodings = new String[] - { - // ILBC - Integer.toString(97), - // javax.media.format.AudioFormat.G723_RTP - Integer.toString(SdpConstants.G723), - // javax.media.format.AudioFormat.GSM_RTP; - Integer.toString(SdpConstants.GSM), - // javax.media.format.AudioFormat.ULAW_RTP; - Integer.toString(SdpConstants.PCMU), - // javax.media.format.AudioFormat.DVI_RTP; - Integer.toString(SdpConstants.DVI4_8000), - // javax.media.format.AudioFormat.DVI_RTP; - Integer.toString(SdpConstants.DVI4_16000), - // javax.media.format.AudioFormat.ALAW; - Integer.toString(SdpConstants.PCMA), - Integer.toString(110), - // javax.media.format.AudioFormat.G728_RTP; - Integer.toString(SdpConstants.G728), - // javax.media.format.AudioFormat.G729_RTP - Integer.toString(SdpConstants.G729) - }; - - private final Set<String> supportedVideoEncodings = - new TreeSet<String>(new EncodingComparator()); - - private final Set<String> supportedAudioEncodings = - new TreeSet<String>(new EncodingComparator()); + private final Set<MediaFormat> supportedAudioEncodings = + new TreeSet<MediaFormat>(new EncodingComparator()); /** * That's where we keep format preferences matching SDP formats to integers. @@ -81,8 +44,8 @@ public class EncodingConfiguration * would be decorelated and other components (such as the UI) should present * them separately. */ - private final Map<String, Integer> encodingPreferences = - new Hashtable<String, Integer>(); + private final Map<MediaFormat, Integer> encodingPreferences = + new Hashtable<MediaFormat, Integer>(); /** * The indicator which determines whether the G.729 codec is enabled. @@ -91,7 +54,7 @@ public class EncodingConfiguration * some countries and is licensed by * <a href="http://www.sipro.com">SIPRO Lab Telecom</a>. */ - private static final boolean G729 = false; + public static final boolean G729 = false; private static final String[] CUSTOM_CODECS = { @@ -146,23 +109,24 @@ public class EncodingConfiguration { // first init default preferences // video - setEncodingPreference(Constants.H264_RTP_SDP, 1100); - setEncodingPreference(SdpConstants.H263, 1000); - setEncodingPreference(SdpConstants.JPEG, 950); - setEncodingPreference(SdpConstants.H261, 800); + setEncodingPreference("H264", VideoMediaFormatImpl.DEFAULT_CLOCK_RATE, 1100); + setEncodingPreference("H263", VideoMediaFormatImpl.DEFAULT_CLOCK_RATE, 1000); + setEncodingPreference("JPEG", VideoMediaFormatImpl.DEFAULT_CLOCK_RATE, 950); + setEncodingPreference("H261", VideoMediaFormatImpl.DEFAULT_CLOCK_RATE, 800); // audio - setEncodingPreference(SdpConstants.PCMU, 650); - setEncodingPreference(SdpConstants.PCMA, 600); - setEncodingPreference(97, 500); - setEncodingPreference(SdpConstants.GSM, 450); - setEncodingPreference(110, 350); - setEncodingPreference(SdpConstants.DVI4_8000, 300); - setEncodingPreference(SdpConstants.DVI4_16000, 250); - setEncodingPreference(SdpConstants.G723, 150); - setEncodingPreference(SdpConstants.G728, 100); - if (G729) - setEncodingPreference(SdpConstants.G729, 50); + setEncodingPreference("PCMU", 8000, 650); + setEncodingPreference("PCMA", 8000, 600); + setEncodingPreference("iLBC", 8000, 500); + setEncodingPreference("GSM", 8000, 450); + setEncodingPreference("speex", 8000, 352); + setEncodingPreference("speex", 16000, 351); + setEncodingPreference("speex", 32000, 350); + setEncodingPreference("DVI4", 8000, 300); + setEncodingPreference("DVI4", 16000, 250); + setEncodingPreference("G723", 8000, 150); + setEncodingPreference("G728", 8000, 100); + setEncodingPreference("G729", 8000, 50); // now override with those that are specified by the user. ConfigurationService confService @@ -174,24 +138,48 @@ public class EncodingConfiguration for (String pName : sdpPreferences) { String prefStr = confService.getString(pName); - String fmtName = - pName.substring(pName.lastIndexOf('.') + 1).replaceAll("sdp", - ""); + String fmtName + = pName + .substring(pName.lastIndexOf('.') + 1) + .replaceAll("sdp", ""); int preference = -1; - int fmt = -1; + String encoding; + double clockRate; try { preference = Integer.parseInt(prefStr); - fmt = Integer.parseInt(fmtName); + + int encodingClockRateSeparator = fmtName.lastIndexOf('/'); + + if (encodingClockRateSeparator > -1) + { + encoding = fmtName.substring(0, encodingClockRateSeparator); + clockRate + = Double + .parseDouble( + fmtName + .substring(encodingClockRateSeparator + 1)); + } + else + { + encoding = fmtName; + clockRate = -1; + } } - catch (NumberFormatException exc) + catch (NumberFormatException nfe) { - logger.warn("Failed to parse format (" + fmtName - + ") or preference(" + prefStr + ").", exc); + logger + .warn( + "Failed to parse format (" + + fmtName + + ") or preference(" + + prefStr + + ").", + nfe); continue; } - setEncodingPreference(fmt, preference); + setEncodingPreference(encoding, clockRate, preference); } // now update the arrays so that they are returned by order of @@ -205,26 +193,26 @@ public class EncodingConfiguration */ private void updateSupportedEncodings() { - for (String ac : availableAudioEncodings) + for (MediaFormat format : getAvailableEncodings(MediaType.AUDIO)) { - Integer pref1 = encodingPreferences.get(ac); + Integer pref1 = encodingPreferences.get(format); int pref1IntValue = (pref1 == null) ? 0 : pref1; if (pref1IntValue > 0) - supportedAudioEncodings.add(ac); + supportedAudioEncodings.add(format); else - supportedAudioEncodings.remove(ac); + supportedAudioEncodings.remove(format); } - for (String ac : availableVideoEncodings) + for (MediaFormat format : getAvailableEncodings(MediaType.VIDEO)) { - Integer pref1 = encodingPreferences.get(ac); + Integer pref1 = encodingPreferences.get(format); int pref1IntValue = (pref1 == null) ? 0 : pref1; if (pref1IntValue > 0) - supportedVideoEncodings.add(ac); + supportedVideoEncodings.add(format); else - supportedVideoEncodings.remove(ac); + supportedVideoEncodings.remove(format); } } @@ -232,10 +220,11 @@ public class EncodingConfiguration * Updates the codecs in the set according preferences in * encodingPreferences. If value is "0" the codec is disabled. */ - public String[] updateEncodings(List<String> encs) + public MediaFormat[] updateEncodings(List<MediaFormat> encs) { - Set<String> result = new TreeSet<String>(new EncodingComparator()); - for (String c : encs) + Set<MediaFormat> result + = new TreeSet<MediaFormat>(new EncodingComparator()); + for (MediaFormat c : encs) { Integer pref1 = encodingPreferences.get(c); int pref1IntValue = (pref1 == null) ? 0 : pref1; @@ -244,7 +233,7 @@ public class EncodingConfiguration result.add(c); } - return result.toArray(new String[result.size()]); + return result.toArray(new MediaFormat[result.size()]); } /** @@ -254,11 +243,15 @@ public class EncodingConfiguration * encodings to those of audio encodings. * * @param encoding the SDP int of the encoding whose pref we're setting. + * @param clockRate * @param pref a positive int indicating the preference for that encoding. */ - private void setEncodingPreference(int encoding, int pref) + private void setEncodingPreference(String encoding, double clockRate, int pref) { - this.encodingPreferences.put(Integer.toString(encoding), pref); + MediaFormat mediaFormat = MediaUtils.getMediaFormat(encoding, clockRate); + + if (mediaFormat != null) + encodingPreferences.put(mediaFormat, pref); } /** @@ -271,18 +264,25 @@ public class EncodingConfiguration * pref we're setting. * @param priority a positive int indicating the preference for that encoding. */ - public void setPriority(String encoding, int priority) + public void setPriority(MediaFormat encoding, int priority) { - this.encodingPreferences.put(encoding, priority); + encodingPreferences.put(encoding, priority); // save the settings - NeomediaActivator.getConfigurationService().setProperty( - PROP_SDP_PREFERENCE + ".sdp" + encoding, priority); + NeomediaActivator + .getConfigurationService() + .setProperty( + PROP_SDP_PREFERENCE + + ".sdp" + + encoding.getEncoding() + + "/" + + ((long) encoding.getClockRate()), + priority); updateSupportedEncodings(); } - public int getPriority(String encoding) + public int getPriority(MediaFormat encoding) { /* @@ -407,26 +407,29 @@ public class EncodingConfiguration + currentPackagePrefix); } - public String[] getAvailableVideoEncodings() - { - return availableVideoEncodings; - } - - public String[] getAvailableAudioEncodings() + public MediaFormat[] getAvailableEncodings(MediaType type) { - return availableAudioEncodings; + return MediaUtils.getMediaFormats(type); } - public String[] getSupportedVideoEncodings() + public MediaFormat[] getSupportedEncodings(MediaType type) { - return supportedVideoEncodings - .toArray(new String[supportedVideoEncodings.size()]); - } + Set<MediaFormat> supportedEncodings; - public String[] getSupportedAudioEncodings() - { - return supportedAudioEncodings - .toArray(new String[supportedAudioEncodings.size()]); + switch (type) + { + case AUDIO: + supportedEncodings = supportedAudioEncodings; + break; + case VIDEO: + supportedEncodings = supportedVideoEncodings; + break; + default: + return MediaUtils.EMPTY_MEDIA_FORMATS; + } + return + supportedEncodings + .toArray(new MediaFormat[supportedEncodings.size()]); } /** @@ -442,7 +445,7 @@ public class EncodingConfiguration * format has been assigned a preference higher, equal to, or * greater than the one of the second. */ - private int compareEncodingPreferences(String enc1, String enc2) + private int compareEncodingPreferences(MediaFormat enc1, MediaFormat enc2) { Integer pref1 = encodingPreferences.get(enc1); int pref1IntValue = (pref1 == null) ? 0 : pref1; @@ -458,9 +461,9 @@ public class EncodingConfiguration * encodingPreferences. */ private class EncodingComparator - implements Comparator<String> + implements Comparator<MediaFormat> { - public int compare(String s1, String s2) + public int compare(MediaFormat s1, MediaFormat s2) { return compareEncodingPreferences(s1, s2); } diff --git a/src/net/java/sip/communicator/impl/neomedia/device/CaptureMediaDevice.java b/src/net/java/sip/communicator/impl/neomedia/device/CaptureMediaDevice.java index cf10dee..7f26ed4 100644 --- a/src/net/java/sip/communicator/impl/neomedia/device/CaptureMediaDevice.java +++ b/src/net/java/sip/communicator/impl/neomedia/device/CaptureMediaDevice.java @@ -334,39 +334,16 @@ public class CaptureMediaDevice */ public List<MediaFormat> getSupportedFormats() { - MediaType mediaType = getMediaType(); EncodingConfiguration encodingConfiguration - = NeomediaActivator.getMediaServiceImpl().getEncodingConfiguration(); - String[] supportedEncodings; - - switch (mediaType) - { - case AUDIO: - supportedEncodings - = encodingConfiguration.getSupportedAudioEncodings(); - break; - case VIDEO: - supportedEncodings - = encodingConfiguration.getSupportedVideoEncodings(); - break; - default: - supportedEncodings = null; - break; - } - + = NeomediaActivator + .getMediaServiceImpl().getEncodingConfiguration(); + MediaFormat[] supportedEncodings + = encodingConfiguration.getSupportedEncodings(getMediaType()); List<MediaFormat> supportedFormats = new ArrayList<MediaFormat>(); if (supportedEncodings != null) - for (String supportedPayloadType : supportedEncodings) - { - MediaFormat[] supportedFormatsForPayloadType - = MediaUtils - .rtpPayloadTypeToMediaFormats(supportedPayloadType); - - for (MediaFormat supportedFormatForPayloadType - :supportedFormatsForPayloadType) - supportedFormats.add(supportedFormatForPayloadType); - } + for (MediaFormat supportedEncoding : supportedEncodings) + supportedFormats.add(supportedEncoding); return supportedFormats; } diff --git a/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatFactoryImpl.java b/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatFactoryImpl.java index f1249de7..b66f5f0 100644 --- a/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatFactoryImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatFactoryImpl.java @@ -31,7 +31,7 @@ public class MediaFormatFactoryImpl */ public AudioMediaFormat createAudioMediaFormat(String encoding) { - for (MediaFormat format : MediaUtils.encodingToMediaFormats(encoding)) + for (MediaFormat format : MediaUtils.getMediaFormats(encoding)) if (format instanceof AudioMediaFormat) return (AudioMediaFormat) format; @@ -52,7 +52,7 @@ public class MediaFormatFactoryImpl String encoding, double clockRate) { - for (MediaFormat format : MediaUtils.encodingToMediaFormats(encoding)) + for (MediaFormat format : MediaUtils.getMediaFormats(encoding)) if ((format instanceof AudioMediaFormat) && (format.getClockRate() == clockRate)) return (AudioMediaFormat) format; @@ -79,7 +79,7 @@ public class MediaFormatFactoryImpl double clockRate, int channels) { - for (MediaFormat format : MediaUtils.encodingToMediaFormats(encoding)) + for (MediaFormat format : MediaUtils.getMediaFormats(encoding)) if ((format instanceof AudioMediaFormat) && (format.getClockRate() == clockRate)) { @@ -113,7 +113,7 @@ public class MediaFormatFactoryImpl double clockRate, Map<String, String> formatParams) { - for (MediaFormat format : MediaUtils.encodingToMediaFormats(encoding)) + for (MediaFormat format : MediaUtils.getMediaFormats(encoding)) if ((format instanceof AudioMediaFormat) && (format.getClockRate() == clockRate) && MediaFormatImpl @@ -150,7 +150,7 @@ public class MediaFormatFactoryImpl int channels, Map<String, String> formatParams) { - for (MediaFormat format : MediaUtils.encodingToMediaFormats(encoding)) + for (MediaFormat format : MediaUtils.getMediaFormats(encoding)) if ((format instanceof AudioMediaFormat) && (format.getClockRate() == clockRate)) { @@ -183,7 +183,7 @@ public class MediaFormatFactoryImpl */ public VideoMediaFormat createVideoMediaFormat(String encoding) { - for (MediaFormat format : MediaUtils.encodingToMediaFormats(encoding)) + for (MediaFormat format : MediaUtils.getMediaFormats(encoding)) if (format instanceof VideoMediaFormat) return (VideoMediaFormat) format; @@ -204,7 +204,7 @@ public class MediaFormatFactoryImpl String encoding, double clockRate) { - for (MediaFormat format : MediaUtils.encodingToMediaFormats(encoding)) + for (MediaFormat format : MediaUtils.getMediaFormats(encoding)) if ((format instanceof VideoMediaFormat) && (format.getClockRate() == clockRate)) return (VideoMediaFormat) format; diff --git a/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java b/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java index 940ea3a..4012ac6 100644 --- a/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/format/MediaFormatImpl.java @@ -45,7 +45,7 @@ public abstract class MediaFormatImpl<T extends Format> */ public static MediaFormat createInstance(Format format) { - MediaFormat mediaFormat = MediaUtils.formatToMediaFormat(format); + MediaFormat mediaFormat = MediaUtils.getMediaFormat(format); if (mediaFormat == null) { @@ -312,7 +312,7 @@ public abstract class MediaFormatImpl<T extends Format> */ public int getRTPPayloadType() { - return MediaUtils.jmfEncodingToRtpPayloadType(getJMFEncoding()); + return MediaUtils.getRTPPayloadType(getJMFEncoding(), getClockRate()); } /** diff --git a/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java b/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java index 7558724..1789982 100644 --- a/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java +++ b/src/net/java/sip/communicator/impl/neomedia/format/VideoMediaFormatImpl.java @@ -28,7 +28,7 @@ public class VideoMediaFormatImpl * The default value of the <tt>clockRate</tt> property of * <tt>VideoMediaFormatImpl</tt>. */ - private static final double DEFAULT_CLOCK_RATE = 90000; + public static final double DEFAULT_CLOCK_RATE = 90000; /** * The clock rate of this <tt>VideoMediaFormat</tt>. diff --git a/src/net/java/sip/communicator/service/neomedia/MediaService.java b/src/net/java/sip/communicator/service/neomedia/MediaService.java index dc34da1..e5f1fba 100644 --- a/src/net/java/sip/communicator/service/neomedia/MediaService.java +++ b/src/net/java/sip/communicator/service/neomedia/MediaService.java @@ -9,6 +9,7 @@ package net.java.sip.communicator.service.neomedia; import java.util.*; import net.java.sip.communicator.service.neomedia.device.*; +import net.java.sip.communicator.service.neomedia.format.*; /** * The <tt>MediaService</tt> service is meant to be a wrapper of media libraries @@ -57,4 +58,15 @@ public interface MediaService */ public MediaStream createMediaStream(StreamConnector connector, MediaDevice device); + + /** + * Gets the <tt>MediaFormatFactory</tt> through which <tt>MediaFormat</tt> + * instances may be created for the purposes of working with the + * <tt>MediaStream</tt>s created by this <tt>MediaService</tt>. + * + * @return the <tt>MediaFormatFactory</tt> through which + * <tt>MediaFormat</tt> instances may be created for the purposes of working + * with the <tt>MediaStream</tt>s created by this <tt>MediaService</tt> + */ + public MediaFormatFactory getFormatFactory(); } |