Package net.java.sip.communicator.impl.neomedia

Source Code of net.java.sip.communicator.impl.neomedia.MediaConfigurationImpl$ResolutionCellRenderer

/*
* Jitsi, 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;

import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.media.*;
import javax.media.MediaException;
import javax.media.protocol.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
import net.java.sip.communicator.util.swing.TransparentPanel;

import org.jitsi.impl.neomedia.*;
import org.jitsi.impl.neomedia.device.*;
import org.jitsi.service.configuration.*;
import org.jitsi.service.neomedia.*;
import org.jitsi.service.neomedia.codec.*;
import org.jitsi.service.neomedia.device.*;
import org.jitsi.service.neomedia.event.*;
import org.jitsi.service.resources.*;
import org.jitsi.util.swing.*;

/**
* @author Lyubomir Marinov
* @author Damian Minkov
* @author Yana Stamcheva
* @author Boris Grozev
*/
public class MediaConfigurationImpl implements MediaConfigurationService
{
    /**
     * The <tt>Logger</tt> used by the <tt>MediaConfigurationServiceImpl</tt>
     * class for logging output.
     */
    private static final Logger logger
        = Logger.getLogger(MediaConfigurationImpl.class);

    /**
     * The <tt>MediaService</tt> implementation used by
     * <tt>MediaConfigurationImpl</tt>.
     */
    private static final MediaServiceImpl mediaService
        = NeomediaActivator.getMediaServiceImpl();

    /**
     * The preferred width of all panels.
     */
    private final static int WIDTH = 350;

    /**
     * Indicates if the Devices settings configuration tab
     * should be disabled, i.e. not visible to the user.
     */
    private static final String DEVICES_DISABLED_PROP
        = "net.java.sip.communicator.impl.neomedia.devicesconfig.DISABLED";

    /**
     * Indicates if the Audio/Video encodings configuration tab
     * should be disabled, i.e. not visible to the user.
     */
    private static final String ENCODINGS_DISABLED_PROP
        = "net.java.sip.communicator.impl.neomedia.encodingsconfig.DISABLED";

     /**
     * Indicates if the Video/More Settings configuration tab
     * should be disabled, i.e. not visible to the user.
     */
    private static final String VIDEO_MORE_SETTINGS_DISABLED_PROP
        = "net.java.sip.communicator.impl.neomedia.videomoresettingsconfig.DISABLED";

    /**
     * Returns the audio configuration panel.
     *
     * @return the audio configuration panel
     */
    public Component createAudioConfigPanel()
    {
        return createControls(DeviceConfigurationComboBoxModel.AUDIO);
    }

    /**
     * Returns the video configuration panel.
     *
     * @return the video configuration panel
     */
    public Component createVideoConfigPanel()
    {
        return createControls(DeviceConfigurationComboBoxModel.VIDEO);
    }

    private static void createAudioPreview(
            final AudioSystem audioSystem,
            final JComboBox comboBox,
            final SoundLevelIndicator soundLevelIndicator)
    {
        final ActionListener captureComboActionListener
            = new ActionListener()
            {
                private final SimpleAudioLevelListener audioLevelListener
                    = new SimpleAudioLevelListener()
                    {
                        public void audioLevelChanged(int level)
                        {
                            soundLevelIndicator.updateSoundLevel(level);
                        }
                    };

                private AudioMediaDeviceSession deviceSession;

                private final BufferTransferHandler transferHandler
                    = new BufferTransferHandler()
                    {
                        public void transferData(PushBufferStream stream)
                        {
                            try
                            {
                                stream.read(transferHandlerBuffer);
                            }
                            catch (IOException ioe)
                            {
                            }
                        }
                    };

                private final Buffer transferHandlerBuffer = new Buffer();

                public void actionPerformed(ActionEvent event)
                {
                    setDeviceSession(null);

                    CaptureDeviceInfo cdi;

                    if (comboBox == null)
                    {
                        cdi
                            = soundLevelIndicator.isShowing()
                                ? audioSystem.getDevice(
                                        AudioSystem.CAPTURE_INDEX)
                                : null;
                    }
                    else
                    {
                        Object selectedItem
                            = soundLevelIndicator.isShowing()
                                ? comboBox.getSelectedItem()
                                : null;

                        cdi
                            = (selectedItem
                                    instanceof
                                        DeviceConfigurationComboBoxModel
                                            .CaptureDevice)
                                ? ((DeviceConfigurationComboBoxModel
                                            .CaptureDevice)
                                        selectedItem)
                                    .info
                                : null;
                    }

                    if (cdi != null)
                    {
                        for (MediaDevice md
                                : mediaService.getDevices(
                                        MediaType.AUDIO,
                                        MediaUseCase.ANY))
                        {
                            if (md instanceof AudioMediaDeviceImpl)
                            {
                                AudioMediaDeviceImpl amd
                                    = (AudioMediaDeviceImpl) md;

                                if (cdi.equals(amd.getCaptureDeviceInfo()))
                                {
                                    try
                                    {
                                        MediaDeviceSession deviceSession
                                            = amd.createSession();
                                        boolean setDeviceSession = false;

                                        try
                                        {
                                            if (deviceSession
                                                    instanceof
                                                        AudioMediaDeviceSession)
                                            {
                                                setDeviceSession(
                                                    (AudioMediaDeviceSession)
                                                        deviceSession);
                                                setDeviceSession = true;
                                            }
                                        }
                                        finally
                                        {
                                            if (!setDeviceSession)
                                                deviceSession.close();
                                        }
                                    }
                                    catch (Throwable t)
                                    {
                                        if (t instanceof ThreadDeath)
                                            throw (ThreadDeath) t;
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }

                private void setDeviceSession(
                        AudioMediaDeviceSession deviceSession)
                {
                    if (this.deviceSession == deviceSession)
                        return;

                    if (this.deviceSession != null)
                    {
                        try
                        {
                            this.deviceSession.close();
                        }
                        finally
                        {
                            this.deviceSession.setLocalUserAudioLevelListener(
                                    null);
                            soundLevelIndicator.resetSoundLevel();
                        }
                    }

                    this.deviceSession = deviceSession;

                    if (this.deviceSession != null)
                    {
                        this.deviceSession.setContentDescriptor(
                                new ContentDescriptor(ContentDescriptor.RAW));
                        this.deviceSession.setLocalUserAudioLevelListener(
                                audioLevelListener);
                        this.deviceSession.start(MediaDirection.SENDONLY);

                        try
                        {
                            DataSource dataSource
                                = this.deviceSession.getOutputDataSource();

                            dataSource.connect();

                            PushBufferStream[] streams
                                = ((PushBufferDataSource) dataSource)
                                    .getStreams();

                            for (PushBufferStream stream : streams)
                                stream.setTransferHandler(transferHandler);

                            dataSource.start();
                        }
                        catch (Throwable t)
                        {
                            if (t instanceof ThreadDeath)
                                throw (ThreadDeath) t;
                            else
                                setDeviceSession(null);
                        }
                    }
                }
            };

        if (comboBox != null)
            comboBox.addActionListener(captureComboActionListener);

        soundLevelIndicator.addHierarchyListener(
                new HierarchyListener()
                {
                    public void hierarchyChanged(HierarchyEvent event)
                    {
                        if ((event.getChangeFlags()
                                    & HierarchyEvent.SHOWING_CHANGED)
                                != 0)
                        {
                            SwingUtilities.invokeLater(
                                    new Runnable()
                                    {
                                        public void run()
                                        {
                                            captureComboActionListener
                                                .actionPerformed(null);
                                        }
                                    });
                        }
                    }
                });
    }
    /**
     * Creates the UI controls which are to control the details of a specific
     * <tt>AudioSystem</tt>.
     *
     * @param audioSystem the <tt>AudioSystem</tt> for which the UI controls to
     * control its details are to be created
     * @param container the <tt>JComponent</tt> into which the UI controls which
     * are to control the details of the specified <tt>audioSystem</tt> are to
     * be added
     */
    public static void createAudioSystemControls(
            AudioSystem audioSystem,
            JComponent container)
    {
        GridBagConstraints constraints = new GridBagConstraints();

        constraints.anchor = GridBagConstraints.NORTHWEST;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.weighty = 0;

        int audioSystemFeatures = audioSystem.getFeatures();
        boolean featureNotifyAndPlaybackDevices
            = ((audioSystemFeatures
                    & AudioSystem.FEATURE_NOTIFY_AND_PLAYBACK_DEVICES)
                != 0);

        constraints.gridx = 0;
        constraints.insets = new Insets(3, 0, 3, 3);
        constraints.weightx = 0;

        constraints.gridy = 0;
        container.add(new JLabel(getLabelText(
            DeviceConfigurationComboBoxModel.AUDIO_CAPTURE)), constraints);
        if (featureNotifyAndPlaybackDevices)
        {
            constraints.gridy = 2;
            container.add(new JLabel(getLabelText(
                DeviceConfigurationComboBoxModel.AUDIO_PLAYBACK)), constraints);
            constraints.gridy = 3;
            container.add(new JLabel(getLabelText(
                DeviceConfigurationComboBoxModel.AUDIO_NOTIFY)), constraints);
        }

        constraints.gridx = 1;
        constraints.insets = new Insets(3, 3, 3, 0);
        constraints.weightx = 1;

        JComboBox captureCombo = null;

        if (featureNotifyAndPlaybackDevices)
        {
            captureCombo = new JComboBox();
            captureCombo.setEditable(false);
            captureCombo.setModel(
                    new DeviceConfigurationComboBoxModel(
                            captureCombo,
                            mediaService.getDeviceConfiguration(),
                            DeviceConfigurationComboBoxModel.AUDIO_CAPTURE));
            constraints.gridy = 0;
            container.add(captureCombo, constraints);
        }

        int anchor = constraints.anchor;
        SoundLevelIndicator capturePreview
            = new SoundLevelIndicator(
                    SimpleAudioLevelListener.MIN_LEVEL,
                    SimpleAudioLevelListener.MAX_LEVEL);

        constraints.anchor = GridBagConstraints.CENTER;
        constraints.gridy = (captureCombo == null) ? 0 : 1;
        container.add(capturePreview, constraints);
        constraints.anchor = anchor;

        constraints.gridy = GridBagConstraints.RELATIVE;

        if (featureNotifyAndPlaybackDevices)
        {
            JComboBox playbackCombo = new JComboBox();

            playbackCombo.setEditable(false);
            playbackCombo.setModel(
                    new DeviceConfigurationComboBoxModel(
                            captureCombo,
                            mediaService.getDeviceConfiguration(),
                            DeviceConfigurationComboBoxModel.AUDIO_PLAYBACK));
            container.add(playbackCombo, constraints);

            JComboBox notifyCombo = new JComboBox();

            notifyCombo.setEditable(false);
            notifyCombo.setModel(
                    new DeviceConfigurationComboBoxModel(
                            captureCombo,
                            mediaService.getDeviceConfiguration(),
                            DeviceConfigurationComboBoxModel.AUDIO_NOTIFY));
            container.add(notifyCombo, constraints);
        }

        if ((AudioSystem.FEATURE_ECHO_CANCELLATION & audioSystemFeatures) != 0)
        {
            final SIPCommCheckBox echoCancelCheckBox
                = new SIPCommCheckBox(
                        NeomediaActivator.getResources().getI18NString(
                                "impl.media.configform.ECHOCANCEL"));

            /*
             * First set the selected one, then add the listener in order to
             * avoid saving the value when using the default one and only
             * showing to user without modification.
             */
            echoCancelCheckBox.setSelected(
                    mediaService.getDeviceConfiguration().isEchoCancel());
            echoCancelCheckBox.addItemListener(
                    new ItemListener()
                    {
                        public void itemStateChanged(ItemEvent e)
                        {
                            mediaService.getDeviceConfiguration().setEchoCancel(
                                    echoCancelCheckBox.isSelected());
                        }
                    });
            container.add(echoCancelCheckBox, constraints);
        }

        if ((AudioSystem.FEATURE_DENOISE & audioSystemFeatures) != 0)
        {
            final SIPCommCheckBox denoiseCheckBox
                = new SIPCommCheckBox(
                        NeomediaActivator.getResources().getI18NString(
                                "impl.media.configform.DENOISE"));

            /*
             * First set the selected one, then add the listener in order to
             * avoid saving the value when using the default one and only
             * showing to user without modification.
             */
            denoiseCheckBox.setSelected(
                    mediaService.getDeviceConfiguration().isDenoise());
            denoiseCheckBox.addItemListener(
                    new ItemListener()
                    {
                        public void itemStateChanged(ItemEvent e)
                        {
                            mediaService.getDeviceConfiguration().setDenoise(
                                    denoiseCheckBox.isSelected());
                        }
                    });
            container.add(denoiseCheckBox, constraints);
        }

        createAudioPreview(audioSystem, captureCombo, capturePreview);
    }

    /**
     * Creates basic controls for a type (AUDIO or VIDEO).
     *
     * @param type the type.
     * @return the build Component.
     */
    private static Component createBasicControls(final int type)
    {
        final JComboBox deviceComboBox = new JComboBox();

        deviceComboBox.setEditable(false);
        deviceComboBox.setModel(
                new DeviceConfigurationComboBoxModel(
                        deviceComboBox,
                        mediaService.getDeviceConfiguration(),
                        type));

        JLabel deviceLabel = new JLabel(getLabelText(type));

        deviceLabel.setDisplayedMnemonic(getDisplayedMnemonic(type));
        deviceLabel.setLabelFor(deviceComboBox);

        final Container devicePanel
            = new TransparentPanel(new FlowLayout(FlowLayout.CENTER));

        devicePanel.setMaximumSize(new Dimension(WIDTH, 25));
        devicePanel.add(deviceLabel);
        devicePanel.add(deviceComboBox);

        final JPanel deviceAndPreviewPanel
            = new TransparentPanel(new BorderLayout());
        int preferredDeviceAndPreviewPanelHeight;

        switch (type)
        {
        case DeviceConfigurationComboBoxModel.AUDIO:
            preferredDeviceAndPreviewPanelHeight = 225;
            break;
        case DeviceConfigurationComboBoxModel.VIDEO:
            preferredDeviceAndPreviewPanelHeight = 305;
            break;
        default:
            preferredDeviceAndPreviewPanelHeight = 0;
            break;
        }
        if (preferredDeviceAndPreviewPanelHeight > 0)
            deviceAndPreviewPanel.setPreferredSize(
                    new Dimension(WIDTH, preferredDeviceAndPreviewPanelHeight));
        deviceAndPreviewPanel.add(devicePanel, BorderLayout.NORTH);

        final ActionListener deviceComboBoxActionListener
            = new ActionListener()
            {
                public void actionPerformed(ActionEvent event)
                {
                    boolean revalidateAndRepaint = false;

                    for (int i = deviceAndPreviewPanel.getComponentCount() - 1;
                            i >= 0;
                            i--)
                    {
                        Component c = deviceAndPreviewPanel.getComponent(i);

                        if (c != devicePanel)
                        {
                            deviceAndPreviewPanel.remove(i);
                            revalidateAndRepaint = true;
                        }
                    }

                    Component preview = null;

                    if ((deviceComboBox.getSelectedItem() != null)
                            && deviceComboBox.isShowing())
                    {
                        preview = createPreview(type, deviceComboBox,
                            deviceAndPreviewPanel.getPreferredSize());
                    }

                    if (preview != null)
                    {
                        deviceAndPreviewPanel.add(preview, BorderLayout.CENTER);
                        revalidateAndRepaint = true;
                    }

                    if (revalidateAndRepaint)
                    {
                        deviceAndPreviewPanel.revalidate();
                        deviceAndPreviewPanel.repaint();
                    }
                }
            };

        deviceComboBox.addActionListener(deviceComboBoxActionListener);
        /*
         * We have to initialize the controls to reflect the configuration
         * at the time of creating this instance. Additionally, because the
         * video preview will stop when it and its associated controls
         * become unnecessary, we have to restart it when the mentioned
         * controls become necessary again. We'll address the two goals
         * described by pretending there's a selection in the video combo
         * box when the combo box in question becomes displayable.
         */
        deviceComboBox.addHierarchyListener(
                new HierarchyListener()
                {
                    public void hierarchyChanged(HierarchyEvent event)
                    {
                        if ((event.getChangeFlags()
                                    & HierarchyEvent.SHOWING_CHANGED)
                                != 0)
                        {
                            SwingUtilities.invokeLater(
                                    new Runnable()
                                    {
                                        public void run()
                                        {
                                            deviceComboBoxActionListener
                                                .actionPerformed(null);
                                        }
                                    });
                        }
                    }
                });

        return deviceAndPreviewPanel;
    }

    /**
     * Creates all the controls (including encoding) for a type(AUDIO or VIDEO)
     *
     * @param type the type.
     * @return the build Component.
     */
    private Component createControls(int type)
    {
        ConfigurationService cfg = NeomediaActivator.getConfigurationService();
        SIPCommTabbedPane container = new SIPCommTabbedPane();
        ResourceManagementService res = NeomediaActivator.getResources();

        if((cfg == null) || !cfg.getBoolean(DEVICES_DISABLED_PROP, false))
        {
            container.insertTab(
                res.getI18NString("impl.media.configform.DEVICES"),
                null,
                createBasicControls(type),
                null,
                0);
        }
        if((cfg == null) || !cfg.getBoolean(ENCODINGS_DISABLED_PROP, false))
        {
            container.insertTab(
                res.getI18NString("impl.media.configform.ENCODINGS"),
                null,
                createEncodingControls(type, null),
                null,
                1);
        }
        if ((type == DeviceConfigurationComboBoxModel.VIDEO)
                && ((cfg == null)
                        || !cfg.getBoolean(
                                VIDEO_MORE_SETTINGS_DISABLED_PROP,
                                false)))
        {
            container.insertTab(
                res.getI18NString("impl.media.configform.VIDEO_MORE_SETTINGS"),
                null,
                createVideoAdvancedSettings(),
                null,
                2);
        }
        return container;
    }

    /**
     * Returns a component for encodings configuration for the given
     * <tt>mediaType</tt>
     *
     * @param mediaType Either <tt>MediaType.AUDIO</tt> or
     * <tt>MediaType.VIDEO</tt>
     * @param encodingConfiguration The <tt>EncodingConfiguration</tt> instance
     * to use. If null, it will use the current encoding configuration from
     * the media service.
     * @return The component for encodings configuration.
     */
    public Component createEncodingControls(
            MediaType mediaType,
            EncodingConfiguration encodingConfiguration)
    {
        if(encodingConfiguration == null)
        {
            encodingConfiguration
                = mediaService.getCurrentEncodingConfiguration();
        }

        int deviceConfigurationComboBoxModelType;

        switch (mediaType)
        {
        case AUDIO:
            deviceConfigurationComboBoxModelType
                = DeviceConfigurationComboBoxModel.AUDIO;
            break;
        case VIDEO:
            deviceConfigurationComboBoxModelType
                = DeviceConfigurationComboBoxModel.VIDEO;
            break;
        default:
            throw new IllegalArgumentException("mediaType");
        }

        return
            createEncodingControls(
                    deviceConfigurationComboBoxModelType,
                    encodingConfiguration);
    }

    /**
     * Creates Component for the encodings of type(AUDIO or VIDEO).
     *
     * @param type the type, either DeviceConfigurationComboBoxModel.AUDIO or
     * DeviceConfigurationComboBoxModel.AUDIO
     * @param encodingConfiguration The <tt>EncodingConfiguration</tt> instance
     * to use. If null, it will use the current encoding configuration from
     * the media service.
     * @return the component.
     */
    private Component createEncodingControls(int type,
            EncodingConfiguration encodingConfiguration)
    {
        if(encodingConfiguration == null)
        {
            encodingConfiguration
                    = mediaService.getCurrentEncodingConfiguration();
        }

        ResourceManagementService resources = NeomediaActivator.getResources();
        String key;

        final JTable table = new JTable();
        table.setShowGrid(false);
        table.setTableHeader(null);

        key = "impl.media.configform.UP";
        final JButton upButton = new JButton(resources.getI18NString(key));
        upButton.setMnemonic(resources.getI18nMnemonic(key));
        upButton.setOpaque(false);

        key = "impl.media.configform.DOWN";
        final JButton downButton = new JButton(resources.getI18NString(key));
        downButton.setMnemonic(resources.getI18nMnemonic(key));
        downButton.setOpaque(false);

        Container buttonBar = new TransparentPanel(new GridLayout(0, 1));
        buttonBar.add(upButton);
        buttonBar.add(downButton);

        Container parentButtonBar = new TransparentPanel(new BorderLayout());
        parentButtonBar.add(buttonBar, BorderLayout.NORTH);

        Container container = new TransparentPanel(new BorderLayout());
        container.setPreferredSize(new Dimension(WIDTH, 100));
        container.setMaximumSize(new Dimension(WIDTH, 100));

        container.add(new JScrollPane(table), BorderLayout.CENTER);
        container.add(parentButtonBar, BorderLayout.EAST);

        table.setModel(new EncodingConfigurationTableModel(type,
                encodingConfiguration));
        /*
         * 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;

                move(table, up);
            }
        };
        upButton.addActionListener(buttonListener);
        downButton.addActionListener(buttonListener);

        return container;
    }

    /**
     * Creates preview for the (video) device in the video container.
     *
     * @param device the device
     * @param videoContainer the video container
     * @throws IOException a problem accessing the device
     * @throws MediaException a problem getting preview
     */
    private static void createVideoPreview(
            CaptureDeviceInfo device,
            JComponent videoContainer)
        throws IOException,
               MediaException
    {
        videoContainer.removeAll();

        videoContainer.revalidate();
        videoContainer.repaint();

        if (device == null)
            return;

        for (MediaDevice mediaDevice
                : mediaService.getDevices(MediaType.VIDEO, MediaUseCase.ANY))
        {
            if(((MediaDeviceImpl) mediaDevice).getCaptureDeviceInfo().equals(
                    device))
            {
                Dimension videoContainerSize = videoContainer.getPreferredSize();
                Component preview
                    = (Component)
                        mediaService.getVideoPreviewComponent(
                                mediaDevice,
                                videoContainerSize.width,
                                videoContainerSize.height);

                if (preview != null)
                    videoContainer.add(preview);
                break;
            }
        }
    }

    /**
     * Create preview component.
     * @param type type
     * @param comboBox the options.
     * @param prefSize the preferred size
     * @return the component.
     */
    private static Component createPreview(int type, final JComboBox comboBox,
                                           Dimension prefSize)
    {
        JComponent preview = null;

        if (type == DeviceConfigurationComboBoxModel.AUDIO)
        {
            Object selectedItem = comboBox.getSelectedItem();

            if (selectedItem instanceof AudioSystem)
            {
                AudioSystem audioSystem = (AudioSystem) selectedItem;

                if (!NoneAudioSystem.LOCATOR_PROTOCOL.equalsIgnoreCase(
                        audioSystem.getLocatorProtocol()))
                {
                    preview = new TransparentPanel(new GridBagLayout());
                    createAudioSystemControls(audioSystem, preview);
                }
            }
        }
        else if (type == DeviceConfigurationComboBoxModel.VIDEO)
        {
            JLabel noPreview
                = new JLabel(
                        NeomediaActivator.getResources().getI18NString(
                                "impl.media.configform.NO_PREVIEW"));

            noPreview.setHorizontalAlignment(SwingConstants.CENTER);
            noPreview.setVerticalAlignment(SwingConstants.CENTER);

            preview = createVideoContainer(noPreview);
            preview.setPreferredSize(prefSize);

            Object selectedItem = comboBox.getSelectedItem();
            CaptureDeviceInfo device = null;
            if (selectedItem
                    instanceof
                        DeviceConfigurationComboBoxModel.CaptureDevice)
                device
                    = ((DeviceConfigurationComboBoxModel.CaptureDevice)
                            selectedItem)
                        .info;

            Exception exception;
            try
            {
                createVideoPreview(device, preview);
                exception = null;
            }
            catch (IOException ex)
            {
                exception = ex;
            }
            catch (MediaException ex)
            {
                exception = ex;
            }
            if (exception != null)
            {
                logger.error(
                    "Failed to create preview for device " + device,
                    exception);
                device = null;
            }
        }

        return preview;
    }

    /**
     * Creates the video container.
     * @param noVideoComponent the container component.
     * @return the video container.
     */
    private static JComponent createVideoContainer(Component noVideoComponent)
    {
        return new VideoContainer(noVideoComponent, false);
    }

    /**
     * The mnemonic for a type.
     * @param type audio or video type.
     * @return the mnemonic.
     */
    private static char getDisplayedMnemonic(int type)
    {
        switch (type)
        {
        case DeviceConfigurationComboBoxModel.AUDIO:
            return NeomediaActivator.getResources().getI18nMnemonic(
                "impl.media.configform.AUDIO");
        case DeviceConfigurationComboBoxModel.VIDEO:
            return NeomediaActivator.getResources().getI18nMnemonic(
                "impl.media.configform.VIDEO");
        default:
            throw new IllegalArgumentException("type");
        }
    }

    /**
     * A label for a type.
     * @param type the type.
     * @return the label.
     */
    private static String getLabelText(int type)
    {
        switch (type)
        {
        case DeviceConfigurationComboBoxModel.AUDIO:
            return NeomediaActivator.getResources().getI18NString(
                "impl.media.configform.AUDIO");
        case DeviceConfigurationComboBoxModel.AUDIO_CAPTURE:
            return NeomediaActivator.getResources().getI18NString(
                "impl.media.configform.AUDIO_IN");
        case DeviceConfigurationComboBoxModel.AUDIO_NOTIFY:
            return NeomediaActivator.getResources().getI18NString(
                "impl.media.configform.AUDIO_NOTIFY");
        case DeviceConfigurationComboBoxModel.AUDIO_PLAYBACK:
            return NeomediaActivator.getResources().getI18NString(
                "impl.media.configform.AUDIO_OUT");
        case DeviceConfigurationComboBoxModel.VIDEO:
            return NeomediaActivator.getResources().getI18NString(
                "impl.media.configform.VIDEO");
        default:
            throw new IllegalArgumentException("type");
        }
    }

    /**
     * Used to move encoding options.
     *
     * @param table the table with encodings
     * @param up move direction.
     */
    private static void move(JTable table, boolean up)
    {
        int index
            = ((EncodingConfigurationTableModel) table.getModel()).move(
                    table.getSelectedRow(),
                    up);

        table.getSelectionModel().setSelectionInterval(index, index);
    }

    /**
     * Creates the video advanced settings.
     *
     * @return video advanced settings panel.
     */
    private static Component createVideoAdvancedSettings()
    {
        ResourceManagementService resources = NeomediaActivator.getResources();

        final DeviceConfiguration deviceConfig =
            mediaService.getDeviceConfiguration();

        TransparentPanel centerPanel =
            new TransparentPanel(new GridBagLayout());
        centerPanel.setMaximumSize(new Dimension(WIDTH, 150));

        JButton resetDefaultsButton = new JButton(
            resources.getI18NString(
                    "impl.media.configform.VIDEO_RESET"));
        JPanel resetButtonPanel = new TransparentPanel(
                new FlowLayout(FlowLayout.RIGHT));
        resetButtonPanel.add(resetDefaultsButton);

        final JPanel centerAdvancedPanel
            = new TransparentPanel(new BorderLayout());
        centerAdvancedPanel.add(centerPanel, BorderLayout.NORTH);
        centerAdvancedPanel.add(resetButtonPanel, BorderLayout.SOUTH);

        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.anchor = GridBagConstraints.NORTHWEST;
        constraints.insets = new Insets(5, 5, 0, 0);
        constraints.gridx = 0;
        constraints.weightx = 0;
        constraints.weighty = 0;
        constraints.gridy = 0;

        centerPanel.add(new JLabel(
            resources.getI18NString("impl.media.configform.VIDEO_RESOLUTION")),
            constraints);
        constraints.gridy = 1;
        constraints.insets = new Insets(0, 0, 0, 0);
        final JCheckBox frameRateCheck = new SIPCommCheckBox(
            resources.getI18NString("impl.media.configform.VIDEO_FRAME_RATE"));
        centerPanel.add(frameRateCheck, constraints);
        constraints.gridy = 2;
        constraints.insets = new Insets(5, 5, 0, 0);
        centerPanel.add(new JLabel(
            resources.getI18NString(
                    "impl.media.configform.VIDEO_PACKETS_POLICY")),
            constraints);

        constraints.weightx = 1;
        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.insets = new Insets(5, 0, 0, 5);
        Object[] resolutionValues
            = new Object[DeviceConfiguration.SUPPORTED_RESOLUTIONS.length + 1];
        System.arraycopy(DeviceConfiguration.SUPPORTED_RESOLUTIONS, 0,
                        resolutionValues, 1,
                        DeviceConfiguration.SUPPORTED_RESOLUTIONS.length);
        final JComboBox sizeCombo = new JComboBox(resolutionValues);
        sizeCombo.setRenderer(new ResolutionCellRenderer());
        sizeCombo.setEditable(false);
        centerPanel.add(sizeCombo, constraints);

        // default value is 20
        final JSpinner frameRate = new JSpinner(new SpinnerNumberModel(
            20, 5, 30, 1));
        frameRate.addChangeListener(new ChangeListener()
        {
            public void stateChanged(ChangeEvent e)
            {
                deviceConfig.setFrameRate(
                        ((SpinnerNumberModel)frameRate.getModel())
                            .getNumber().intValue());
            }
        });
        constraints.gridy = 1;
        constraints.insets = new Insets(0, 0, 0, 5);
        centerPanel.add(frameRate, constraints);

        frameRateCheck.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                if(frameRateCheck.isSelected())
                {
                    deviceConfig.setFrameRate(
                        ((SpinnerNumberModel)frameRate.getModel())
                            .getNumber().intValue());
                }
                else // unlimited framerate
                    deviceConfig.setFrameRate(-1);

                frameRate.setEnabled(frameRateCheck.isSelected());
            }
        });

        final JSpinner videoMaxBandwidth = new JSpinner(new SpinnerNumberModel(
            deviceConfig.getVideoMaxBandwidth(),
            1, Integer.MAX_VALUE, 1));
        videoMaxBandwidth.addChangeListener(new ChangeListener()
        {
            public void stateChanged(ChangeEvent e)
            {
                deviceConfig.setVideoMaxBandwidth(
                        ((SpinnerNumberModel)videoMaxBandwidth.getModel())
                            .getNumber().intValue());
            }
        });
        constraints.gridx = 1;
        constraints.gridy = 2;
        constraints.insets = new Insets(0, 0, 5, 5);
        centerPanel.add(videoMaxBandwidth, constraints);

        resetDefaultsButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                // reset to defaults
                sizeCombo.setSelectedIndex(0);
                frameRateCheck.setSelected(false);
                frameRate.setEnabled(false);
                frameRate.setValue(20);
                // unlimited framerate
                deviceConfig.setFrameRate(-1);
                videoMaxBandwidth.setValue(
                        DeviceConfiguration.DEFAULT_VIDEO_MAX_BANDWIDTH);
            }
        });

        // load selected value or auto
        Dimension videoSize = deviceConfig.getVideoSize();

        if((videoSize.getHeight() != DeviceConfiguration.DEFAULT_VIDEO_HEIGHT)
                && (videoSize.getWidth()
                        != DeviceConfiguration.DEFAULT_VIDEO_WIDTH))
            sizeCombo.setSelectedItem(deviceConfig.getVideoSize());
        else
            sizeCombo.setSelectedIndex(0);
        sizeCombo.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                Dimension selectedVideoSize
                    = (Dimension) sizeCombo.getSelectedItem();

                if(selectedVideoSize == null)
                {
                    // the auto value, default one
                    selectedVideoSize
                        = new Dimension(
                                DeviceConfiguration.DEFAULT_VIDEO_WIDTH,
                                DeviceConfiguration.DEFAULT_VIDEO_HEIGHT);
                }
                deviceConfig.setVideoSize(selectedVideoSize);
            }
        });

        frameRateCheck.setSelected(
            deviceConfig.getFrameRate()
                != DeviceConfiguration.DEFAULT_VIDEO_FRAMERATE);
        frameRate.setEnabled(frameRateCheck.isSelected());

        if(frameRate.isEnabled())
            frameRate.setValue(deviceConfig.getFrameRate());

        return centerAdvancedPanel;
    }

    /**
     * Returns the <tt>MediaService</tt> instance.
     *
     * @return the <tt>MediaService</tt> instance
     */
    public MediaService getMediaService()
    {
        return mediaService;
    }

    /**
     * Renders the available resolutions in the combo box.
     */
    private static class ResolutionCellRenderer
        extends DefaultListCellRenderer
    {
        /**
         * The serialization version number of the
         * <tt>ResolutionCellRenderer</tt> class. Defined to the value of
         * <tt>0</tt> because the <tt>ResolutionCellRenderer</tt> instances do
         * not have state of their own.
         */
        private static final long serialVersionUID = 0L;

        /**
         * Sets readable text describing the resolution if the selected
         * value is null we return the string "Auto".
         *
         * @param list
         * @param value
         * @param index
         * @param isSelected
         * @param cellHasFocus
         * @return Component
         */
        @Override
        public Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus)
        {
            // call super to set backgrounds and fonts
            super.getListCellRendererComponent(
                    list,
                    value,
                    index,
                    isSelected,
                    cellHasFocus);

            // now just change the text
            if(value == null)
                setText("Auto");
            else if(value instanceof Dimension)
            {
                Dimension d = (Dimension)value;

                setText(((int) d.getWidth()) + "x" + ((int) d.getHeight()));
            }
            return this;
        }
    }
}
TOP

Related Classes of net.java.sip.communicator.impl.neomedia.MediaConfigurationImpl$ResolutionCellRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.