From ea47d25602458617b8a65c3d4d493354e320debd Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Sat, 26 Sep 2009 20:56:09 +0000 Subject: [PATCH] Implements .service.neomedia.MediaDevice for CaptureDevice and the respective part of .service.neomedia.MediaService which lists the available and the default MediaDevices. --- .../communicator/impl/media/MediaControl.java | 2 +- .../impl/neomedia/MediaServiceImpl.java | 138 +++++++++++ .../neomedia/device/CaptureMediaDevice.java | 224 ++++++++++++++++++ .../service/neomedia/device/MediaDevice.java | 12 - 4 files changed, 363 insertions(+), 13 deletions(-) create mode 100644 src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java create mode 100644 src/net/java/sip/communicator/impl/neomedia/device/CaptureMediaDevice.java diff --git a/src/net/java/sip/communicator/impl/media/MediaControl.java b/src/net/java/sip/communicator/impl/media/MediaControl.java index a0c105bca..f290e1aee 100644 --- a/src/net/java/sip/communicator/impl/media/MediaControl.java +++ b/src/net/java/sip/communicator/impl/media/MediaControl.java @@ -622,7 +622,7 @@ public void closeCaptureDevices() * @return a connected DataSource for the media specified by the * locator. */ - private DataSource createDataSource(MediaLocator locator) + public static DataSource createDataSource(MediaLocator locator) { try { logger.info("Creating datasource for:" diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java new file mode 100644 index 000000000..ea4f049b2 --- /dev/null +++ b/src/net/java/sip/communicator/impl/neomedia/MediaServiceImpl.java @@ -0,0 +1,138 @@ +/* + * 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; + +import java.util.*; + +import javax.media.*; + +import net.java.sip.communicator.impl.neomedia.device.*; +import net.java.sip.communicator.service.neomedia.*; +import net.java.sip.communicator.service.neomedia.device.*; + +/** + * @author Lubomir Marinov + */ +public class MediaServiceImpl + implements MediaService +{ + + /** + * The value of the devices property of MediaServiceImpl + * when no MediaDevices are available. Explicitly defined in order + * to reduce unnecessary allocations. + */ + private static final List EMPTY_DEVICES + = Collections.emptyList(); + + /** + * The net.java.sip.communicator.impl.media.MediaServiceImpl this + * instance delegates to for functionality it already supports in order to + * keep this instance as compatible with it as possible. + */ + private final net.java.sip.communicator.impl.media.MediaServiceImpl mediaServiceImpl; + + /** + * Initializes a new MediaServiceImpl instance which is to delegate + * to a specific + * net.java.sip.communicator.impl.media.MediaServiceImpl for + * functionality it already supports in order to keep the new instance as + * compatible with the specified mediaServiceImpl as possible. + * + * @param mediaServiceImpl the + * net.java.sip.communicator.impl.media.MediaServiceImpl the new + * instance is to delegate to + */ + public MediaServiceImpl( + net.java.sip.communicator.impl.media.MediaServiceImpl mediaServiceImpl) + { + if (mediaServiceImpl == null) + throw new NullPointerException("mediaServiceImpl"); + + this.mediaServiceImpl = mediaServiceImpl; + } + + /* + * Implements MediaService#createMediaStream(StreamConnector, MediaDevice). + */ + public MediaStream createMediaStream( + StreamConnector connector, + MediaDevice device) + { + // TODO Auto-generated method stub + return null; + } + + /* + * Implements MediaService#getDefaultDevice(MediaType). + */ + public MediaDevice getDefaultDevice(MediaType mediaType) + { + CaptureDeviceInfo captureDeviceInfo; + + switch (mediaType) + { + case AUDIO: + captureDeviceInfo + = mediaServiceImpl + .getDeviceConfiguration().getAudioCaptureDevice(); + break; + case VIDEO: + captureDeviceInfo + = mediaServiceImpl + .getDeviceConfiguration().getVideoCaptureDevice(); + break; + default: + captureDeviceInfo = null; + break; + } + + return + (captureDeviceInfo == null) + ? null + : new CaptureMediaDevice(captureDeviceInfo, mediaType); + } + + /* + * Implements MediaService#getDevices(MediaType). + */ + public List getDevices(MediaType mediaType) + { + CaptureDeviceInfo[] captureDeviceInfos; + + switch (mediaType) + { + case AUDIO: + captureDeviceInfos + = mediaServiceImpl + .getDeviceConfiguration().getAvailableAudioCaptureDevices(); + break; + case VIDEO: + captureDeviceInfos + = mediaServiceImpl + .getDeviceConfiguration().getAvailableVideoCaptureDevices(); + break; + default: + captureDeviceInfos = null; + break; + } + + List captureDevices; + + if ((captureDeviceInfos == null) || (captureDeviceInfos.length == 0)) + captureDevices = EMPTY_DEVICES; + else + { + captureDevices + = new ArrayList(captureDeviceInfos.length); + for (CaptureDeviceInfo captureDeviceInfo : captureDeviceInfos) + captureDevices + .add(new CaptureMediaDevice(captureDeviceInfo, mediaType)); + } + return captureDevices; + } +} diff --git a/src/net/java/sip/communicator/impl/neomedia/device/CaptureMediaDevice.java b/src/net/java/sip/communicator/impl/neomedia/device/CaptureMediaDevice.java new file mode 100644 index 000000000..455ac09fe --- /dev/null +++ b/src/net/java/sip/communicator/impl/neomedia/device/CaptureMediaDevice.java @@ -0,0 +1,224 @@ +/* + * 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.device; + +import java.util.*; + +import javax.media.*; +import javax.media.control.*; +import javax.media.format.*; +import javax.media.protocol.*; + +import net.java.sip.communicator.impl.media.*; +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 MediaDevice for the JMF CaptureDevice. + * + * @author Lubomir Marinov + */ +public class CaptureMediaDevice + implements MediaDevice +{ + + /** + * The JMF CaptureDevice this instance wraps and provides an + * implementation of MediaDevice for. + */ + private CaptureDevice captureDevice; + + /** + * The CaptureDeviceInfo of {@link #captureDevice}. + */ + private final CaptureDeviceInfo captureDeviceInfo; + + /** + * The MediaType of this instance and the CaptureDevice + * that it wraps. + */ + private final MediaType mediaType; + + /** + * Initializes a new CaptureMediaDevice instance which is to + * provide an implementation of MediaDevice for a specific + * CaptureDevice with a specific MediaType. + * + * @param captureDevice the JMF CaptureDevice the new instance is + * to provide an implementation of MediaDevice for + * @param mediaType the MediaType of the new instance + */ + public CaptureMediaDevice(CaptureDevice captureDevice, MediaType mediaType) + { + if (captureDevice == null) + throw new NullPointerException("captureDevice"); + if (mediaType == null) + throw new NullPointerException("mediaType"); + + this.captureDevice = captureDevice; + this.captureDeviceInfo = captureDevice.getCaptureDeviceInfo(); + this.mediaType = mediaType; + } + + /** + * Initializes a new CaptureMediaDevice instance which is to + * provide an implementation of MediaDevice for a + * CaptureDevice with a specific CaptureDeviceInfo and + * which is of a specific MediaType. + * + * @param captureDeviceInfo the CaptureDeviceInfo of the JMF + * CaptureDevice the new instance is to provide an implementation + * of MediaDevice for + * @param mediaType the MediaType of the new instance + */ + public CaptureMediaDevice( + CaptureDeviceInfo captureDeviceInfo, + MediaType mediaType) + { + if (captureDeviceInfo == null) + throw new NullPointerException("captureDeviceInfo"); + if (mediaType == null) + throw new NullPointerException("mediaType"); + + this.captureDevice = null; + this.captureDeviceInfo = captureDeviceInfo; + this.mediaType = mediaType; + } + + /** + * Gets the JMF CaptureDevice this instance wraps and provides an + * implementation of MediaDevice for. + * + * @return the JMF CaptureDevice this instance wraps and provides + * an implementation of MediaDevice for + */ + private CaptureDevice getCaptureDevice() + { + if (captureDevice == null) + captureDevice + = (CaptureDevice) + MediaControl + .createDataSource( + captureDeviceInfo.getLocator()); + return captureDevice; + } + + /* + * Implements MediaDevice#getDirection(). Because CaptureDevice can only be + * read from, returns MediaDirection#SENDONLY. + */ + public MediaDirection getDirection() + { + return MediaDirection.SENDONLY; + } + + /* + * Implements MediaDevice#getFormat(). + */ + public MediaFormat getFormat() + { + MediaType mediaType = getMediaType(); + + for (FormatControl formatControl + : getCaptureDevice().getFormatControls()) + { + MediaFormat format + = MediaFormatImpl.createInstance(formatControl.getFormat()); + + if ((format != null) && format.getMediaType().equals(mediaType)) + return format; + } + return null; + } + + /* + * Implements MediaDevice#getMediaType(). + */ + public MediaType getMediaType() + { + return mediaType; + } + + /* + * Implements MediaDevice#getSupportedFormats(). + */ + public List getSupportedFormats() + { + return + (captureDevice == null) + ? getSupportedFormats(captureDeviceInfo) + : getSupportedFormats(captureDevice); + } + + /** + * Gets the MediaFormats supported by a specific + * CaptureDevice. + * + * @param captureDevice the JMF CaptureDevice to retrieve the + * supported MediaFormats of + * @return the MediaFormats supported by the specified + * CaptureDevice + */ + private List getSupportedFormats(CaptureDevice captureDevice) + { + MediaType mediaType = getMediaType(); + Set supportedFormats = new HashSet(); + + for (FormatControl formatControl : captureDevice.getFormatControls()) + { + for (Format format : formatControl.getSupportedFormats()) + switch (mediaType) + { + case AUDIO: + if (format instanceof AudioFormat) + supportedFormats.add(format); + break; + case VIDEO: + if (format instanceof VideoFormat) + supportedFormats.add(format); + break; + } + } + + List supportedMediaFormats + = new ArrayList(supportedFormats.size()); + + for (Format format : supportedFormats) + supportedMediaFormats.add(MediaFormatImpl.createInstance(format)); + return supportedMediaFormats; + } + + /** + * Gets the MediaFormats supported by a CaptureDevice + * judging by its CaptureDeviceInfo. + * + * @param captureDeviceInfo the CaptureDeviceInfo to retrieve the + * supported MediaFormats of + * @return the MediaFormats supported by the specified + * CaptureDeviceInfo + */ + private List getSupportedFormats( + CaptureDeviceInfo captureDeviceInfo) + { + Format[] supportedFormats = captureDeviceInfo.getFormats(); + MediaType mediaType = getMediaType(); + List supportedMediaFormats + = new ArrayList(supportedFormats.length); + + for (Format format : supportedFormats) + { + MediaFormat mediaFormat = MediaFormatImpl.createInstance(format); + + if ((mediaFormat != null) + && mediaFormat.getMediaType().equals(mediaType)) + supportedMediaFormats.add(mediaFormat); + } + return supportedMediaFormats; + } +} diff --git a/src/net/java/sip/communicator/service/neomedia/device/MediaDevice.java b/src/net/java/sip/communicator/service/neomedia/device/MediaDevice.java index a53035566..89b10753f 100644 --- a/src/net/java/sip/communicator/service/neomedia/device/MediaDevice.java +++ b/src/net/java/sip/communicator/service/neomedia/device/MediaDevice.java @@ -36,18 +36,6 @@ public interface MediaDevice */ public MediaType getMediaType(); - /** - * Specifies the MediaFormat that this device should use when - * capturing data. - * - * @param format the MediaFormat that this device should use when - * capturing media. - * - * @throws IllegalArgumentException if format is not among - * MediaFormets supported by this MediaDevice. - */ - public void setFormat(MediaFormat format) throws IllegalArgumentException; - /** * Returns the MediaFormat that this device is currently set to use * when capturing data.