Implements a ConfigurationForm which allows configuring the MediaService.

cusax-fix
Lyubomir Marinov 17 years ago
parent ca841c75cc
commit 296d1e0f1b

@ -777,7 +777,7 @@
bundle-fileaccess-slick,bundle-media,bundle-media-slick,
bundle-resource-manager,bundle-resources-defaultpack,
bundle-protocol,bundle-icq,bundle-icq-slick,bundle-mock,bundle-smacklib,
bundle-jabber,bundle-jabber-slick,bundle-swing-ui,bundle-ui-service,
bundle-jabber,bundle-jabber-slick,bundle-swing-common,bundle-swing-ui,bundle-ui-service,
bundle-msn,bundle-msn-slick,bundle-yahoo,bundle-yahoo-slick,
bundle-contactlist,meta-contactlist,meta-contactlist-slick,
bundle-plugin-icqaccregwizz,bundle-plugin-jabberaccregwizz,
@ -958,6 +958,8 @@
prefix="net/java/sip/communicator/service/media"/>
<zipfileset dir="${dest}/net/java/sip/communicator/impl/media"
prefix="net/java/sip/communicator/impl/media"/>
<zipfileset dir="${resources}/images/impl/media"
prefix="resources/images/impl/media"/>
<zipfileset src="${lib.win.noinst}/jmf.jar" prefix=""/>
<zipfileset src="${lib.win.noinst}/sound.jar" prefix=""/>
<zipfileset src="${lib.noinst}/nist-sdp-1.0.jar" prefix=""/>
@ -979,6 +981,8 @@
prefix="net/java/sip/communicator/service/media"/>
<zipfileset dir="${dest}/net/java/sip/communicator/impl/media"
prefix="net/java/sip/communicator/impl/media"/>
<zipfileset dir="${resources}/images/impl/media"
prefix="resources/images/impl/media"/>
<zipfileset src="${lib.lin.noinst}/jmf.jar" prefix=""/>
<zipfileset src="${lib.noinst}/nist-sdp-1.0.jar" prefix=""/>
<zipfileset src="${lib.noinst}/jspeex.jar" prefix=""/>
@ -999,6 +1003,8 @@
prefix="net/java/sip/communicator/service/media"/>
<zipfileset dir="${dest}/net/java/sip/communicator/impl/media"
prefix="net/java/sip/communicator/impl/media"/>
<zipfileset dir="${resources}/images/impl/media"
prefix="resources/images/impl/media"/>
<zipfileset src="${lib.mac.noinst}/jmf.jar" prefix=""/>
<zipfileset src="${lib.noinst}/nist-sdp-1.0.jar" prefix=""/>
<zipfileset src="${lib.noinst}/jspeex.jar" prefix=""/>
@ -1301,6 +1307,16 @@ javax.swing.event, javax.swing.border"/>
</jar>
</target>
<!-- BUNDLE-SWING-COMMON -->
<target name="bundle-swing-common">
<!-- Common/generic Swing additions not specific to SIP Communicator. -->
<jar compress="false" destfile="${bundles.dest}/swing-common.jar"
manifest="${src}/net/java/sip/communicator/swing/swing.common.manifest.mf">
<zipfileset dir="${dest}/net/java/sip/communicator/swing"
prefix="net/java/sip/communicator/swing"/>
</jar>
</target>
<!-- BUNDLE-SWING-UI -->
<target name="bundle-swing-ui">
<!-- Bundle sip-communicator's UI.-->

@ -83,7 +83,8 @@ felix.auto.start.45= \
reference:file:sc-bundles/argdelegation-service.jar \
reference:file:sc-bundles/version.jar \
reference:file:sc-bundles/version-impl.jar \
reference:file:sc-bundles/branding.jar
reference:file:sc-bundles/branding.jar \
reference:file:sc-bundles/swing-common.jar
felix.auto.start.49= \
reference:file:sc-bundles/zrtp4j.jar \

@ -427,3 +427,5 @@ soundIcon=resources/images/plugin/notificationconfiguration/soundIcon.png
activatedIcon=resources/images/plugin/notificationconfiguration/activeIcon.png
desactivatedIcon=resources/images/plugin/notificationconfiguration/desactivatedIcon.png
foldericon=resources/images/plugin/notificationconfiguration/folder.png
MediaConfigurationForm_icon=resources/images/impl/media/media.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

@ -748,3 +748,10 @@ sasUnsecuredAtPeerRequestTooltip=Call unsecured at peer request
# Profiler4J
profiler=Profiler4j
MediaConfigurationForm_title=Media
MediaConfigurationPanel_audio=&Audio:
MediaConfigurationPanel_down=&Down
MediaConfigurationPanel_encodings=&Encodings:
MediaConfigurationPanel_up=&Up
MediaConfigurationPanel_video=&Video:

@ -1,22 +1,29 @@
/*
* 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.gui.customcontrols;
import java.awt.*;
import javax.swing.*;
/**
* @author Yana Stamcheva
*/
public class TransparentPanel
extends JPanel
{
public TransparentPanel ()
public TransparentPanel()
{
super();
this.setOpaque(false);
}
public TransparentPanel (LayoutManager layoutManager)
public TransparentPanel(LayoutManager layout)
{
super(layoutManager);
super(layout);
this.setOpaque(false);
}

@ -18,6 +18,7 @@
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.swing.*;
import net.java.sip.communicator.util.*;
/**
@ -227,94 +228,9 @@ public void hierarchyChanged(HierarchyEvent event)
* <code>Component</code> at a time and, in the absence of such a
* <code>Component</code>, displays <code>noVideoComponent</code>
*/
private Container createVideoContainer(final Component noVideoComponent)
private Container createVideoContainer(Component noVideoComponent)
{
final ContainerListener containerListener = new ContainerListener()
{
/*
* Since the videoContainer displays either noVideoComponent or a
* single visual Component which represents video, ensures the last
* Component added to the Container is the only Component it
* contains i.e. noVideoComponent goes away when the video is
* displayed and the video goes away when noVideoComponent is
* displayed.
*/
public void componentAdded(ContainerEvent event)
{
Container container = event.getContainer();
Component local =
((VideoLayout) container.getLayout()).getLocal();
Component added = event.getChild();
if ((local != null) && (added == local))
return;
Component[] components = container.getComponents();
boolean validate = false;
for (int i = 0; i < components.length; i++)
{
Component component = components[i];
if ((component != added) && (component != local))
{
container.remove(component);
validate = true;
}
}
if (validate)
container.validate();
}
/*
* Displays noVideoComponent when there is no visual Component which
* represents video to be displayed.
*/
public void componentRemoved(ContainerEvent event)
{
Container container = event.getContainer();
if ((container.getComponentCount() <= 0)
|| (((VideoLayout) container.getLayout()).getRemote() == null))
{
container.add(noVideoComponent, VideoLayout.REMOTE);
container.validate();
}
}
};
Container videoContainer = new TransparentPanel(new VideoLayout())
{
/*
* Ensures noVideoComponent is displayed even when the clients of
* the videoContainer invoke its #removeAll() to remove their
* previous visual Components representing video. Just adding
* noVideoComponent upon ContainerEvent#COMPONENT_REMOVED when there
* is no other Component left in the Container will cause an
* infinite loop because Container#removeAll() will detect that a
* new Component has been added while dispatching the event and will
* then try to remove the new Component.
*/
public void removeAll()
{
removeContainerListener(containerListener);
try
{
super.removeAll();
}
finally
{
addContainerListener(containerListener);
containerListener.componentRemoved(new ContainerEvent(this,
ContainerEvent.COMPONENT_REMOVED, null));
}
}
};
videoContainer.addContainerListener(containerListener);
videoContainer.add(noVideoComponent, VideoLayout.REMOTE);
return videoContainer;
return new VideoContainer(noVideoComponent);
}
/**

@ -39,5 +39,6 @@ Import-Package: org.osgi.framework,
javax.swing.undo,
javax.swing.border,
net.java.sip.communicator.service.audionotifier,
net.java.sip.communicator.swing,
org.jdesktop.jdic.desktop,
say.swing

@ -11,6 +11,7 @@
import java.net.*;
import java.text.*;
import java.util.*;
import javax.media.*;
import javax.media.control.*;
import javax.media.format.*;

@ -0,0 +1,209 @@
/*
* 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.media;
import java.util.*;
import javax.media.*;
import javax.swing.*;
import javax.swing.event.*;
import net.java.sip.communicator.impl.media.device.*;
/**
* @author Lubomir Marinov
*/
public class DeviceConfigurationComboBoxModel
implements ComboBoxModel
{
public static class CaptureDevice
{
public final CaptureDeviceInfo info;
public CaptureDevice(CaptureDeviceInfo info)
{
if (info == null)
throw new IllegalArgumentException("info");
this.info = info;
}
public String toString()
{
return info.getName();
}
}
public static final int AUDIO = 1;
private static final CaptureDevice[] NO_CAPTURE_DEVICES =
new CaptureDevice[0];
public static final int VIDEO = 2;
private final DeviceConfiguration deviceConfiguration;
private CaptureDevice[] devices;
private final List<ListDataListener> listeners =
new ArrayList<ListDataListener>();
private final int type;
public DeviceConfigurationComboBoxModel(
DeviceConfiguration deviceConfiguration, int type)
{
if (deviceConfiguration == null)
throw new IllegalArgumentException("deviceConfiguration");
if ((type != AUDIO) && (type != VIDEO))
throw new IllegalArgumentException("type");
this.deviceConfiguration = deviceConfiguration;
this.type = type;
}
public void addListDataListener(ListDataListener listener)
{
if (listener == null)
throw new IllegalArgumentException("listener");
if (!listeners.contains(listener))
listeners.add(listener);
}
protected void fireContentsChanged(int index0, int index1)
{
ListDataListener[] listeners =
this.listeners.toArray(new ListDataListener[this.listeners.size()]);
ListDataEvent event =
new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index0,
index1);
for (int i = 0; i < listeners.length; i++)
{
listeners[i].contentsChanged(event);
}
}
private DeviceConfiguration getDeviceConfiguration()
{
return deviceConfiguration;
}
private CaptureDevice[] getDevices()
{
if (devices != null)
return devices;
DeviceConfiguration deviceConfiguration = getDeviceConfiguration();
CaptureDeviceInfo[] infos;
switch (type)
{
case AUDIO:
infos = deviceConfiguration.getAvailableAudioCaptureDevices();
break;
case VIDEO:
infos = deviceConfiguration.getAvailableVideoCaptureDevices();
break;
default:
throw new IllegalStateException("type");
}
final int deviceCount = infos.length;
if (deviceCount < 1)
devices = NO_CAPTURE_DEVICES;
else
{
devices = new CaptureDevice[deviceCount];
for (int i = 0; i < deviceCount; i++)
{
devices[i] = new CaptureDevice(infos[i]);
}
}
return devices;
}
public Object getElementAt(int index)
{
return getDevices()[index];
}
private CaptureDevice getSelectedDevice()
{
DeviceConfiguration deviceConfiguration = getDeviceConfiguration();
CaptureDeviceInfo info;
switch (type)
{
case AUDIO:
info = deviceConfiguration.getAudioCaptureDevice();
break;
case VIDEO:
info = deviceConfiguration.getVideoCaptureDevice();
break;
default:
throw new IllegalStateException("type");
}
CaptureDevice[] devices = getDevices();
for (int i = 0; i < devices.length; i++)
{
CaptureDevice device = devices[i];
if (device.info.equals(info))
{
return device;
}
}
return null;
}
public Object getSelectedItem()
{
return getSelectedDevice();
}
public int getSize()
{
return getDevices().length;
}
public void removeListDataListener(ListDataListener listener)
{
if (listener == null)
throw new IllegalArgumentException("listener");
listeners.remove(listener);
}
private void setSelectedDevice(CaptureDevice device)
{
// We cannot clear the selection of DeviceConfiguration.
if (device == null)
return;
CaptureDevice selectedDevice = getSelectedDevice();
if (selectedDevice != device)
{
DeviceConfiguration deviceConfiguration = getDeviceConfiguration();
switch (type)
{
case AUDIO:
deviceConfiguration.setAudioCaptureDevice(device.info);
break;
case VIDEO:
deviceConfiguration.setVideoCaptureDevice(device.info);
break;
}
fireContentsChanged(-1, -1);
}
}
public void setSelectedItem(Object item)
{
setSelectedDevice((CaptureDevice) item);
}
}

@ -0,0 +1,187 @@
/*
* 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.media;
import java.util.*;
import javax.swing.table.*;
import net.java.sip.communicator.impl.media.codec.*;
/**
* @author Lubomir Marinov
*/
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 final int 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;
}
public Class<?> getColumnClass(int columnIndex)
{
return (columnIndex == 0) ? Boolean.class : super
.getColumnClass(columnIndex);
}
public int getColumnCount()
{
return 2;
}
private String[] 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");
}
final int encodingCount = availableEncodings.length;
if (encodingCount < 1)
encodings = NO_ENCODINGS;
else
{
encodings = new String[encodingCount];
System
.arraycopy(availableEncodings, 0, encodings, 0, encodingCount);
Arrays.sort(encodings, 0, encodingCount, new Comparator<String>()
{
public int compare(String encoding0, String encoding1)
{
if (encodingConfiguration.getPriority(encoding0) > encodingConfiguration
.getPriority(encoding1))
return -1;
return encoding0.compareTo(encoding1);
}
});
}
return encodings;
}
private int[] getPriorities()
{
String[] encodings = getEncodings();
final int count = encodings.length;
int[] priorities = new int[count];
for (int i = 0; i < count; i++)
{
int priority = encodingConfiguration.getPriority(encodings[i]);
priorities[i] = (priority > 0) ? (count - i) : 0;
}
return priorities;
}
public int getRowCount()
{
return getEncodings().length;
}
public Object getValueAt(int rowIndex, int columnIndex)
{
String encoding = getEncodings()[rowIndex];
switch (columnIndex)
{
case 0:
return Boolean
.valueOf(encodingConfiguration.getPriority(encoding) > 0);
case 1:
return MediaUtils.sdpToJmfEncoding(encoding);
default:
return null;
}
}
public boolean isCellEditable(int rowIndex, int columnIndex)
{
return (columnIndex == 0);
}
public void move(int rowIndex, boolean up)
{
if (up)
{
if (rowIndex <= 0)
throw new IllegalArgumentException("rowIndex");
move(rowIndex - 1, false);
return;
}
if (rowIndex >= (getRowCount() - 1))
throw new IllegalArgumentException("rowIndex");
int[] priorities = getPriorities();
final int nextRowIndex = rowIndex + 1;
if (priorities[rowIndex] > 0)
priorities[rowIndex] = priorities.length - nextRowIndex;
if (priorities[nextRowIndex] > 0)
priorities[nextRowIndex] = priorities.length - rowIndex;
setPriorities(priorities);
String swap = encodings[rowIndex];
encodings[rowIndex] = encodings[nextRowIndex];
encodings[nextRowIndex] = swap;
fireTableRowsUpdated(rowIndex, nextRowIndex);
}
private void setPriorities(int[] priorities)
{
final int count = encodings.length;
if (priorities.length != count)
throw new IllegalArgumentException("priorities");
for (int i = 0; i < count; i++)
encodingConfiguration.setPriority(encodings[i], priorities[i]);
}
public void setValueAt(Object value, int rowIndex, int columnIndex)
{
if ((columnIndex == 0) && (value instanceof Boolean))
{
int[] priorities = getPriorities();
priorities[rowIndex] =
((Boolean) value) ? (priorities.length - rowIndex) : 0;
setPriorities(priorities);
fireTableCellUpdated(rowIndex, columnIndex);
}
}
}

@ -6,14 +6,15 @@
*/
package net.java.sip.communicator.impl.media;
import org.osgi.framework.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.service.configuration.*;
import net.java.sip.communicator.service.netaddr.*;
import java.util.*;
import net.java.sip.communicator.service.media.*;
import net.java.sip.communicator.service.fileaccess.*;
import net.java.sip.communicator.service.gui.ConfigurationForm;
import net.java.sip.communicator.service.media.*;
import net.java.sip.communicator.service.netaddr.*;
import net.java.sip.communicator.service.resources.*;
import net.java.sip.communicator.util.*;
import org.osgi.framework.*;
/**
* Invoke "Service Binder" to parse the service XML and register
@ -25,7 +26,7 @@
public class MediaActivator
implements BundleActivator
{
private Logger logger = Logger.getLogger(MediaActivator.class.getName());
private final Logger logger = Logger.getLogger(MediaActivator.class.getName());
private static MediaServiceImpl mediaServiceImpl = null;
@ -34,6 +35,7 @@ public class MediaActivator
private static NetworkAddressManagerService networkAddressManagerService
= null;
private static FileAccessService fileAccessService = null;
private static ResourceManagementService resources;
private ServiceRegistration mediaServiceRegistration = null;
@ -51,22 +53,21 @@ public void start(BundleContext context)
throws Exception
{
logger.debug("Started.");
this.bundleContext = context;
Hashtable hashtable = new Hashtable();
mediaServiceImpl = new MediaServiceImpl();
MediaActivator.bundleContext = context;
//load all icq providers
// MediaService
mediaServiceImpl = new MediaServiceImpl();
mediaServiceImpl.start();
//reg the icq account man.
mediaServiceRegistration = context.registerService(
MediaService.class.getName(),
mediaServiceImpl,
hashtable);
mediaServiceRegistration =
context.registerService(MediaService.class.getName(),
mediaServiceImpl, null);
logger.debug("Media Service ... [REGISTERED]");
// MediaConfigurationForm
context.registerService(ConfigurationForm.class.getName(),
new MediaConfigurationForm(), null);
}
/**
@ -132,6 +133,13 @@ public static FileAccessService getFileAccessService()
return fileAccessService;
}
public static ResourceManagementService getResources()
{
if (resources == null)
resources =
ResourceManagementServiceUtils.getService(bundleContext);
return resources;
}
/**
* Returns a reference to the bundle context that we were started with.

@ -0,0 +1,38 @@
/*
* 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.media;
import net.java.sip.communicator.service.gui.*;
/**
* @author Lubomir Marinov
*/
public class MediaConfigurationForm
implements ConfigurationForm
{
public Object getForm()
{
return new MediaConfigurationPanel();
}
public byte[] getIcon()
{
return MediaActivator.getResources().getImageInBytes(
"MediaConfigurationForm_icon");
}
public int getIndex()
{
return -1;
}
public String getTitle()
{
return MediaActivator.getResources().getI18NString(
"MediaConfigurationForm_title");
}
}

@ -0,0 +1,429 @@
/*
* 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.media;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.media.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import net.java.sip.communicator.service.media.*;
import net.java.sip.communicator.service.resources.*;
import net.java.sip.communicator.swing.*;
import net.java.sip.communicator.util.*;
import org.osgi.framework.*;
/**
* @author Lubomir Marinov
*/
public class MediaConfigurationPanel
extends JPanel
{
private static final int HGAP = 5;
private static final int VGAP = 5;
private static MediaServiceImpl getMediaService()
{
BundleContext bundleContext = MediaActivator.getBundleContext();
ServiceReference serviceReference =
bundleContext.getServiceReference(MediaService.class.getName());
return (serviceReference == null) ? null
: (MediaServiceImpl) bundleContext.getService(serviceReference);
}
private final Logger logger =
Logger.getLogger(MediaConfigurationPanel.class);
private final MediaServiceImpl mediaService = getMediaService();
public MediaConfigurationPanel()
{
super(new GridLayout(0, 1, HGAP, VGAP));
int[] types =
new int[]
{ DeviceConfigurationComboBoxModel.AUDIO,
DeviceConfigurationComboBoxModel.VIDEO };
for (int i = 0; i < types.length; i++)
add(createControls(types[i]));
}
private void controllerUpdateForPreview(ControllerEvent event,
Container videoContainer)
{
if (event instanceof RealizeCompleteEvent)
{
Player player = (Player) event.getSourceController();
Component video = player.getVisualComponent();
showPreview(videoContainer, video, player);
}
}
private Component createControls(int type)
{
final JComboBox comboBox = new JComboBox();
comboBox.setEditable(false);
JLabel label = new JLabel(getLabelText(type));
label.setDisplayedMnemonic(getDisplayedMnemonic(type));
label.setLabelFor(comboBox);
final JComponent preview;
ActionListener comboBoxListener = null;
if (type == DeviceConfigurationComboBoxModel.VIDEO)
{
JLabel noPreview =
new JLabel(MediaActivator.getResources().getI18NString(
"MediaConfigurationPanel_noPreview"));
noPreview.setHorizontalAlignment(SwingConstants.CENTER);
noPreview.setVerticalAlignment(SwingConstants.CENTER);
preview = createVideoContainer(noPreview);
Dimension previewSize = new Dimension(150, 150);
preview.setMaximumSize(previewSize);
preview.setMinimumSize(previewSize);
preview.setPreferredSize(previewSize);
comboBoxListener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
Object selection = comboBox.getSelectedItem();
CaptureDeviceInfo device = null;
if (selection instanceof DeviceConfigurationComboBoxModel.CaptureDevice)
{
device =
((DeviceConfigurationComboBoxModel.CaptureDevice) selection).info;
}
createPreview(device, preview);
}
};
comboBox.addActionListener(comboBoxListener);
} else
preview = null;
Container deviceContainer = new JPanel(new GridBagLayout());
GridBagConstraints deviceConstraints = new GridBagConstraints();
deviceConstraints.anchor = GridBagConstraints.NORTHWEST;
deviceConstraints.gridx = 0;
deviceConstraints.gridy = 0;
deviceConstraints.weightx = 0;
deviceContainer.add(label, deviceConstraints);
deviceConstraints.gridx = 1;
deviceConstraints.weightx = 1;
deviceContainer.add(comboBox, deviceConstraints);
if (preview != null)
{
deviceConstraints.gridx = 2;
deviceConstraints.weightx = 0;
deviceContainer.add(preview, deviceConstraints);
}
comboBox.setModel(new DeviceConfigurationComboBoxModel(mediaService
.getDeviceConfiguration(), type));
if (comboBoxListener != null)
comboBoxListener.actionPerformed(null);
Container container = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.weightx = 1;
constraints.weighty = 0;
container.add(deviceContainer, constraints);
constraints.fill = GridBagConstraints.BOTH;
constraints.gridy = 1;
constraints.weighty = 1;
container.add(createEncodingControls(type), constraints);
return container;
}
private Component createEncodingControls(int type)
{
ResourceManagementService resources = MediaActivator.getResources();
String key;
final JTable table = new JTable();
table.setFillsViewportHeight(true);
table.setShowGrid(false);
table.setTableHeader(null);
key = "MediaConfigurationPanel_encodings";
JLabel label = new JLabel(resources.getI18NString(key));
label.setDisplayedMnemonic(resources.getI18nMnemonic(key));
label.setLabelFor(table);
key = "MediaConfigurationPanel_up";
final JButton upButton = new JButton(resources.getI18NString(key));
upButton.setMnemonic(resources.getI18nMnemonic(key));
key = "MediaConfigurationPanel_down";
final JButton downButton = new JButton(resources.getI18NString(key));
downButton.setMnemonic(resources.getI18nMnemonic(key));
Container buttonBar = new JPanel(new GridLayout(0, 1));
buttonBar.add(upButton);
buttonBar.add(downButton);
Container container = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.anchor = GridBagConstraints.NORTHWEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.gridwidth = 2;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.weightx = 0;
constraints.weighty = 0;
container.add(label, constraints);
constraints.anchor = GridBagConstraints.CENTER;
constraints.fill = GridBagConstraints.BOTH;
constraints.gridwidth = 1;
constraints.gridx = 0;
constraints.gridy = 1;
constraints.weightx = 1;
constraints.weighty = 1;
container.add(new JScrollPane(table), constraints);
constraints.anchor = GridBagConstraints.NORTHEAST;
constraints.fill = GridBagConstraints.NONE;
constraints.gridwidth = 1;
constraints.gridx = 1;
constraints.gridy = 1;
constraints.weightx = 0;
constraints.weighty = 0;
container.add(buttonBar, constraints);
table.setModel(new EncodingConfigurationTableModel(mediaService
.getEncodingConfiguration(), type));
/*
* The first column contains the check boxes which enable/disable their
* associated encodings and it doesn't make sense to make it wider than
* the check boxes.
*/
TableColumnModel tableColumnModel = table.getColumnModel();
TableColumn tableColumn = tableColumnModel.getColumn(0);
tableColumn.setMaxWidth(tableColumn.getMinWidth());
ListSelectionListener tableSelectionListener =
new ListSelectionListener()
{
public void valueChanged(ListSelectionEvent event)
{
if (table.getSelectedRowCount() == 1)
{
int selectedRow = table.getSelectedRow();
if (selectedRow > -1)
{
upButton.setEnabled(selectedRow > 0);
downButton.setEnabled(selectedRow < (table
.getRowCount() - 1));
return;
}
}
upButton.setEnabled(false);
downButton.setEnabled(false);
}
};
table.getSelectionModel().addListSelectionListener(
tableSelectionListener);
tableSelectionListener.valueChanged(null);
ActionListener buttonListener = new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
Object source = event.getSource();
boolean up;
if (source == upButton)
up = true;
else if (source == downButton)
up = false;
else
return;
((EncodingConfigurationTableModel) table.getModel()).move(table
.getSelectedRow(), up);
}
};
upButton.addActionListener(buttonListener);
downButton.addActionListener(buttonListener);
return container;
}
private void createPreview(CaptureDeviceInfo device,
final Container videoContainer)
{
videoContainer.removeAll();
if (device == null)
return;
Player player = null;
Exception exception = null;
try
{
player = Manager.createPlayer(device.getLocator());
}
catch (IOException ex)
{
exception = ex;
}
catch (NoPlayerException ex)
{
exception = ex;
}
if (exception != null)
{
logger.error("Failed to create preview for device " + device,
exception);
return;
}
player.addControllerListener(new ControllerListener()
{
public void controllerUpdate(ControllerEvent event)
{
controllerUpdateForPreview(event, videoContainer);
}
});
player.start();
}
private JComponent createVideoContainer(Component noVideoComponent)
{
return new VideoContainer(noVideoComponent);
}
private void disposePlayer(Player player)
{
player.stop();
player.deallocate();
player.close();
}
private char getDisplayedMnemonic(int type)
{
switch (type)
{
case DeviceConfigurationComboBoxModel.AUDIO:
return MediaActivator.getResources().getI18nMnemonic(
"MediaConfigurationPanel_audio");
case DeviceConfigurationComboBoxModel.VIDEO:
return MediaActivator.getResources().getI18nMnemonic(
"MediaConfigurationPanel_video");
default:
throw new IllegalArgumentException("type");
}
}
private String getLabelText(int type)
{
switch (type)
{
case DeviceConfigurationComboBoxModel.AUDIO:
return MediaActivator.getResources().getI18NString(
"MediaConfigurationPanel_audio");
case DeviceConfigurationComboBoxModel.VIDEO:
return MediaActivator.getResources().getI18NString(
"MediaConfigurationPanel_video");
default:
throw new IllegalArgumentException("type");
}
}
private void showPreview(final Container previewContainer,
final Component preview, final Player player)
{
if (!SwingUtilities.isEventDispatchThread())
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
showPreview(previewContainer, preview, player);
}
});
return;
}
previewContainer.removeAll();
if (preview != null)
{
HierarchyListener hierarchyListener = new HierarchyListener()
{
private Window window;
private WindowListener windowListener;
public void dispose()
{
if (windowListener != null)
{
if (window != null)
{
window.removeWindowListener(windowListener);
window = null;
}
windowListener = null;
}
preview.removeHierarchyListener(this);
disposePlayer(player);
}
public void hierarchyChanged(HierarchyEvent event)
{
if ((event.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0)
{
if (preview.isDisplayable())
{
if (windowListener == null)
{
window =
SwingUtilities.windowForComponent(preview);
if (window != null)
{
windowListener = new WindowAdapter()
{
public void windowClosing(
WindowEvent event)
{
dispose();
}
};
window.addWindowListener(windowListener);
}
}
}
else
{
dispose();
}
}
}
};
preview.addHierarchyListener(hierarchyListener);
previewContainer.add(preview);
}
else
disposePlayer(player);
}
}

@ -14,11 +14,9 @@
import javax.media.control.*;
import javax.media.format.*;
import javax.media.protocol.*;
import javax.sdp.*;
import net.java.sip.communicator.impl.media.codec.*;
import net.java.sip.communicator.impl.media.device.*;
import net.java.sip.communicator.service.configuration.*;
import net.java.sip.communicator.service.media.MediaException;
import net.java.sip.communicator.util.*;

@ -1,3 +1,9 @@
/*
* 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.media.codec;
import java.io.*;
@ -25,7 +31,7 @@ public class EncodingConfiguration
/**
* SDP Codes of all video formats that JMF supports.
*/
private String[] availableVideoEncodings = new String[]
private final String[] availableVideoEncodings = new String[]
{ Integer.toString(Constants.H264_RTP_SDP),
// javax.media.format.VideoFormat.H263_RTP
Integer.toString(SdpConstants.H263),
@ -37,7 +43,7 @@ public class EncodingConfiguration
/**
* SDP Codes of all audio formats that JMF supports.
*/
private String[] availableAudioEncodings = new String[]
private final String[] availableAudioEncodings = new String[]
{
// ILBC
Integer.toString(97),
@ -60,10 +66,10 @@ public class EncodingConfiguration
// Integer.toString(SdpConstants.G729)
};
private TreeSet<String> suportedVideoEncodings =
private final Set<String> suportedVideoEncodings =
new TreeSet<String>(new EncodingComparator());
private TreeSet<String> suportedAudioEncodings =
private final Set<String> suportedAudioEncodings =
new TreeSet<String>(new EncodingComparator());
/**
@ -73,13 +79,10 @@ public class EncodingConfiguration
* would be decorelated and other components (such as the UI) should present
* them separately.
*/
private final Hashtable<String, Integer> encodingPreferences =
private final Map<String, Integer> encodingPreferences =
new Hashtable<String, Integer>();
/**
*
*/
private static String[] customCodecs =
private static final String[] customCodecs =
new String[]
{
FMJConditionals.FMJ_CODECS ? "net.sf.fmj.media.codec.audio.alaw.Encoder"
@ -101,7 +104,7 @@ public class EncodingConfiguration
/**
* Custom Packages provided by Sip-Communicator
*/
private static String[] customPackages = new String[]
private static final String[] customPackages = new String[]
{ // datasource for low latency ALSA input
"net.java.sip.communicator.impl", "net.sf.fmj" };
@ -144,10 +147,8 @@ private void initializeFormatPreferences()
List<String> sdpPreferences =
confService.getPropertyNamesByPrefix(PROP_SDP_PREFERENCE, false);
Iterator<String> sdpPreferencesIter = sdpPreferences.iterator();
while (sdpPreferencesIter.hasNext())
for (String pName : sdpPreferences)
{
String pName = sdpPreferencesIter.next();
String prefStr = confService.getString(pName);
String fmtName =
pName.substring(pName.lastIndexOf('.') + 1).replaceAll("sdp",
@ -206,19 +207,16 @@ private void updateSupportedEncodings()
suportedVideoEncodings.remove(ac);
}
}
/**
* Updates the codecs in the set according preferences in
* encodingPreferences. If value is "0" the codec is disabled.
*/
public String[] updateEncodings(List<String> encs)
{
TreeSet<String> result = new TreeSet<String>(new EncodingComparator());
Iterator<String> iter = encs.iterator();
while (iter.hasNext())
{
String c = (String) iter.next();
Set<String> result = new TreeSet<String>(new EncodingComparator());
for (String c : encs)
{
Integer pref1 = encodingPreferences.get(c);
int pref1IntValue = (pref1 == null) ? 0 : pref1.intValue();
@ -279,6 +277,11 @@ public void setPriority(String encoding, int priority)
updateSupportedEncodings();
}
public int getPriority(String encoding)
{
return encodingPreferences.get(encoding);
}
/**
* Register in JMF the custom codecs we provide
*/
@ -360,7 +363,7 @@ private void registerCustomPackages()
// list is always short
if (!currentPackagePrefix.contains(className))
{
currentPackagePrefix.addElement(className);
currentPackagePrefix.add(className);
logger.debug("Adding package : " + className);
}
}
@ -426,6 +429,5 @@ public int compare(String s1, String s2)
{
return compareEncodingPreferences(s1, s2);
}
}
}

@ -4,35 +4,37 @@ Bundle-Description: A bundle that offers Media capture and presentation capabili
Bundle-Vendor: sip-communicator.org
Bundle-Version: 0.0.1
Import-Package: org.osgi.framework,
net.java.sip.communicator.service.configuration,
net.java.sip.communicator.service.configuration.event,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.event,
net.java.sip.communicator.util,
net.java.sip.communicator.service.netaddr,
org.bouncycastle.jce.provider,
org.xml.sax,
javax.crypto,
javax.crypto.interfaces,
javax.crypto.spec,
javax.imageio,
javax.sound,
javax.sound.sampled,
javax.swing,
javax.swing.event,
javax.swing.border,
javax.imageio,
javax.swing.event,
javax.swing.table,
net.java.sip.communicator.service.configuration,
net.java.sip.communicator.service.configuration.event,
net.java.sip.communicator.service.fileaccess,
net.java.sip.communicator.service.gui,
net.java.sip.communicator.service.netaddr,
net.java.sip.communicator.service.protocol,
net.java.sip.communicator.service.protocol.event,
net.java.sip.communicator.service.resources,
javax.sound,
javax.sound.sampled,
net.java.sip.communicator.swing,
net.java.sip.communicator.util,
quicktime,
quicktime.std.sg,
quicktime.qd,
quicktime.util,
quicktime.std.image,
javax.crypto,
javax.crypto.spec,
javax.crypto.interfaces,
org.xml.sax,
org.bouncycastle.jce.provider,
gnu.java.zrtp,
gnu.java.zrtp.zidfile,
gnu.java.zrtp.packets,
gnu.java.zrtp.utils,
gnu.java.zrtp.packets
gnu.java.zrtp.zidfile
Export-Package: net.java.sip.communicator.service.media,
net.java.sip.communicator.service.media.event,
net.java.sip.communicator.impl.media,

@ -4,7 +4,7 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.call;
package net.java.sip.communicator.swing;
import java.awt.*;

@ -0,0 +1,114 @@
/*
* 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.swing;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* @author Lubomir Marinov
*/
public class VideoContainer
extends JPanel
{
private final ContainerListener containerListener = new ContainerListener()
{
/*
* Since the videoContainer displays either noVideoComponent or a single
* visual Component which represents video, ensures the last Component
* added to the Container is the only Component it contains i.e.
* noVideoComponent goes away when the video is displayed and the video
* goes away when noVideoComponent is displayed.
*/
public void componentAdded(ContainerEvent event)
{
Container container = event.getContainer();
Component local = ((VideoLayout) container.getLayout()).getLocal();
Component added = event.getChild();
if ((local != null) && (added == local))
return;
Component[] components = container.getComponents();
boolean validate = false;
for (int i = 0; i < components.length; i++)
{
Component component = components[i];
if ((component != added) && (component != local))
{
container.remove(component);
validate = true;
}
}
if (validate)
container.validate();
};
/*
* Displays noVideoComponent when there is no visual Component which
* represents video to be displayed.
*/
public void componentRemoved(ContainerEvent event)
{
Container container = event.getContainer();
if ((container.getComponentCount() <= 0)
|| (((VideoLayout) container.getLayout()).getRemote() == null))
{
container.add(noVideoComponent, VideoLayout.REMOTE);
container.validate();
}
}
};
private final Component noVideoComponent;
public VideoContainer(Component noVideoComponent)
{
super(new VideoLayout());
this.noVideoComponent = noVideoComponent;
addContainerListener(containerListener);
add(noVideoComponent, VideoLayout.REMOTE);
}
public Component add(Component comp)
{
add(comp, VideoLayout.REMOTE);
return comp;
}
/*
* Ensures noVideoComponent is displayed even when the clients of the
* videoContainer invoke its #removeAll() to remove their previous visual
* Components representing video. Just adding noVideoComponent upon
* ContainerEvent#COMPONENT_REMOVED when there is no other Component left in
* the Container will cause an infinite loop because Container#removeAll()
* will detect that a new Component has been added while dispatching the
* event and will then try to remove the new Component.
*/
public void removeAll()
{
removeContainerListener(containerListener);
try
{
super.removeAll();
}
finally
{
addContainerListener(containerListener);
containerListener.componentRemoved(new ContainerEvent(this,
ContainerEvent.COMPONENT_REMOVED, null));
}
}
}

@ -4,7 +4,7 @@
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.gui.main.call;
package net.java.sip.communicator.swing;
import java.awt.*;

@ -0,0 +1,6 @@
Bundle-Name: Swing Common
Bundle-Description: Common/generic Swing additions not specific to SIP Communicator
Bundle-Vendor: sip-communicator.org
Bundle-Version: 0.0.1
Import-Package: javax.swing
Export-Package: net.java.sip.communicator.swing
Loading…
Cancel
Save