
org.jitsi.impl.neomedia.device.MediaDeviceImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of libjitsi Show documentation
Show all versions of libjitsi Show documentation
libjitsi is an advanced Java media library for secure real-time audio/video
communication
The newest version!
/*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jitsi.impl.neomedia.device;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.List;
import javax.media.*;
import javax.media.control.*;
import javax.media.protocol.*;
import org.jitsi.impl.neomedia.*;
import org.jitsi.impl.neomedia.format.*;
import org.jitsi.impl.neomedia.jmfext.media.protocol.*;
import org.jitsi.impl.neomedia.protocol.*;
import org.jitsi.service.neomedia.*;
import org.jitsi.service.neomedia.codec.*;
import org.jitsi.service.neomedia.device.*;
import org.jitsi.service.neomedia.format.*;
import org.jitsi.utils.*;
import org.jitsi.utils.logging.*;
/**
* Implements MediaDevice for the JMF CaptureDevice.
*
* @author Lyubomir Marinov
* @author Emil Ivov
*/
public class MediaDeviceImpl
extends AbstractMediaDevice
{
/**
* The Logger used by MediaDeviceImpl and its instances
* for logging output.
*/
private static final Logger logger
= Logger.getLogger(MediaDeviceImpl.class);
/**
* Creates a new CaptureDevice which traces calls to a specific
* CaptureDevice for debugging purposes.
*
* @param captureDevice the CaptureDevice which is to have its
* calls traced for debugging output
* @param logger the Logger to be used for logging the trace
* messages
* @return a new CaptureDevice which traces the calls to the
* specified captureDevice
*/
public static CaptureDevice createTracingCaptureDevice(
CaptureDevice captureDevice,
final Logger logger)
{
if (captureDevice instanceof PushBufferDataSource)
captureDevice
= new CaptureDeviceDelegatePushBufferDataSource(
captureDevice)
{
@Override
public void connect()
throws IOException
{
super.connect();
if (logger.isTraceEnabled())
logger
.trace(
"Connected "
+ MediaDeviceImpl
.toString(this.captureDevice));
}
@Override
public void disconnect()
{
super.disconnect();
if (logger.isTraceEnabled())
logger
.trace(
"Disconnected "
+ MediaDeviceImpl
.toString(this.captureDevice));
}
@Override
public void start()
throws IOException
{
super.start();
if (logger.isTraceEnabled())
logger
.trace(
"Started "
+ MediaDeviceImpl
.toString(this.captureDevice));
}
@Override
public void stop()
throws IOException
{
super.stop();
if (logger.isTraceEnabled())
logger
.trace(
"Stopped "
+ MediaDeviceImpl
.toString(this.captureDevice));
}
};
return captureDevice;
}
/**
* Returns a human-readable representation of a specific
* CaptureDevice in the form of a String value.
*
* @param captureDevice the CaptureDevice to get a human-readable
* representation of
* @return a String value which gives a human-readable
* representation of the specified captureDevice
*/
private static String toString(CaptureDevice captureDevice)
{
StringBuffer str = new StringBuffer();
str.append("CaptureDevice with hashCode ");
str.append(captureDevice.hashCode());
str.append(" and captureDeviceInfo ");
CaptureDeviceInfo captureDeviceInfo
= captureDevice.getCaptureDeviceInfo();
MediaLocator mediaLocator = null;
if (captureDeviceInfo != null)
{
mediaLocator = captureDeviceInfo.getLocator();
}
str.append((mediaLocator == null) ? captureDeviceInfo : mediaLocator);
return str.toString();
}
/**
* The CaptureDeviceInfo of the device that this instance is
* representing.
*/
private final CaptureDeviceInfo captureDeviceInfo;
/**
* The MediaType of this instance and the CaptureDevice
* that it wraps.
*/
private final MediaType mediaType;
/**
* Initializes a new MediaDeviceImpl 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 MediaDeviceImpl(
CaptureDeviceInfo captureDeviceInfo,
MediaType mediaType)
{
if (captureDeviceInfo == null)
throw new NullPointerException("captureDeviceInfo");
if (mediaType == null)
throw new NullPointerException("mediaType");
this.captureDeviceInfo = captureDeviceInfo;
this.mediaType = mediaType;
}
/**
* Initializes a new MediaDeviceImpl instance with a specific
* MediaType and with MediaDirection which does not allow
* sending.
*
* @param mediaType the MediaType of the new instance
*/
public MediaDeviceImpl(MediaType mediaType)
{
this.captureDeviceInfo = null;
this.mediaType = mediaType;
}
/**
* Creates the JMF CaptureDevice this instance represents and
* provides an implementation of MediaDevice for.
*
* @return the JMF CaptureDevice this instance represents and
* provides an implementation of MediaDevice for; null
* if the creation fails
*/
protected CaptureDevice createCaptureDevice()
{
CaptureDevice captureDevice = null;
if (getDirection().allowsSending())
{
CaptureDeviceInfo captureDeviceInfo = getCaptureDeviceInfo();
Throwable exception = null;
try
{
captureDevice
= (CaptureDevice)
Manager.createDataSource(
captureDeviceInfo.getLocator());
}
catch (IOException ioe)
{
exception = ioe;
}
catch (NoDataSourceException ndse)
{
exception = ndse;
}
if (exception != null)
{
logger.error(
"Failed to create CaptureDevice"
+ " from CaptureDeviceInfo "
+ captureDeviceInfo,
exception);
}
else
{
if (captureDevice instanceof AbstractPullBufferCaptureDevice)
{
((AbstractPullBufferCaptureDevice) captureDevice)
.setCaptureDeviceInfo(captureDeviceInfo);
}
// Try to enable tracing on captureDevice.
if (logger.isTraceEnabled())
{
captureDevice
= createTracingCaptureDevice(captureDevice, logger);
}
}
}
return captureDevice;
}
/**
* Creates a DataSource instance for this MediaDevice
* which gives access to the captured media.
*
* @return a DataSource instance which gives access to the media
* captured by this MediaDevice
* @see AbstractMediaDevice#createOutputDataSource()
*/
@Override
protected DataSource createOutputDataSource()
{
return
getDirection().allowsSending()
? (DataSource) createCaptureDevice()
: null;
}
/**
* Gets the CaptureDeviceInfo of the JMF CaptureDevice
* represented by this instance.
*
* @return the CaptureDeviceInfo of the CaptureDevice
* represented by this instance
*/
public CaptureDeviceInfo getCaptureDeviceInfo()
{
return captureDeviceInfo;
}
/**
* Gets the protocol of the MediaLocator of the
* CaptureDeviceInfo represented by this instance.
*
* @return the protocol of the MediaLocator of the
* CaptureDeviceInfo represented by this instance
*/
public String getCaptureDeviceInfoLocatorProtocol()
{
CaptureDeviceInfo cdi = getCaptureDeviceInfo();
if (cdi != null)
{
MediaLocator locator = cdi.getLocator();
if (locator != null)
return locator.getProtocol();
}
return null;
}
/**
* Returns the MediaDirection supported by this device.
*
* @return {@link MediaDirection#SENDONLY} if this is a read-only device,
* {@link MediaDirection#RECVONLY} if this is a write-only device or
* {@link MediaDirection#SENDRECV} if this MediaDevice can both
* capture and render media
* @see MediaDevice#getDirection()
*/
public MediaDirection getDirection()
{
if (getCaptureDeviceInfo() != null)
return MediaDirection.SENDRECV;
else
return
MediaType.AUDIO.equals(getMediaType())
? MediaDirection.INACTIVE
: MediaDirection.RECVONLY;
}
/**
* Gets the MediaFormat in which this MediaDevice captures
* media.
*
* @return the MediaFormat in which this MediaDevice
* captures media
* @see MediaDevice#getFormat()
*/
public MediaFormat getFormat()
{
CaptureDevice captureDevice = createCaptureDevice();
if (captureDevice != null)
{
MediaType mediaType = getMediaType();
for (FormatControl formatControl
: captureDevice.getFormatControls())
{
MediaFormat format
= MediaFormatImpl.createInstance(formatControl.getFormat());
if ((format != null) && format.getMediaType().equals(mediaType))
return format;
}
}
return null;
}
/**
* Gets the MediaType that this device supports.
*
* @return {@link MediaType#AUDIO} if this is an audio device or
* {@link MediaType#VIDEO} if this is a video device
* @see MediaDevice#getMediaType()
*/
public MediaType getMediaType()
{
return mediaType;
}
/**
* Gets the list of MediaFormats supported by this
* MediaDevice and enabled in encodingConfiguration.
*
* @param encodingConfiguration the EncodingConfiguration instance
* to use
* @return the list of MediaFormats supported by this device
* and enabled in encodingConfiguration.
* @see MediaDevice#getSupportedFormats()
*/
public List getSupportedFormats(
EncodingConfiguration encodingConfiguration)
{
return getSupportedFormats(null, null, encodingConfiguration);
}
/**
* Gets the list of MediaFormats supported by this
* MediaDevice. Uses the current EncodingConfiguration
* from the media service (i.e. the global configuration).
*
* @param sendPreset the preset used to set some of the format parameters,
* used for video and settings.
* @param receivePreset the preset used to set the receive format
* parameters, used for video and settings.
* @return the list of MediaFormats supported by this device
* @see MediaDevice#getSupportedFormats()
*/
public List getSupportedFormats(
QualityPreset sendPreset,
QualityPreset receivePreset)
{
return
getSupportedFormats(
sendPreset,
receivePreset,
NeomediaServiceUtils.getMediaServiceImpl()
.getCurrentEncodingConfiguration());
}
/**
* Gets the list of MediaFormats supported by this
* MediaDevice and enabled in encodingConfiguration.
*
* @param sendPreset the preset used to set some of the format parameters,
* used for video and settings.
* @param receivePreset the preset used to set the receive format
* parameters, used for video and settings.
* @param encodingConfiguration the EncodingConfiguration instance
* to use
* @return the list of MediaFormats supported by this device
* and enabled in encodingConfiguration.
* @see MediaDevice#getSupportedFormats()
*/
public List getSupportedFormats(
QualityPreset sendPreset,
QualityPreset receivePreset,
EncodingConfiguration encodingConfiguration)
{
MediaServiceImpl mediaServiceImpl
= NeomediaServiceUtils.getMediaServiceImpl();
MediaFormat[] enabledEncodings
= encodingConfiguration.getEnabledEncodings(getMediaType());
List supportedFormats = new ArrayList();
// If there is preset, check and set the format attributes where needed.
if (enabledEncodings != null)
{
for (MediaFormat f : enabledEncodings)
{
if("h264".equalsIgnoreCase(f.getEncoding()))
{
Map advancedAttrs
= f.getAdvancedAttributes();
CaptureDeviceInfo captureDeviceInfo
= getCaptureDeviceInfo();
MediaLocator captureDeviceInfoLocator;
Dimension sendSize = null;
// change send size only for video calls
if ((captureDeviceInfo != null)
&& ((captureDeviceInfoLocator
= captureDeviceInfo.getLocator())
!= null)
&& !DeviceSystem.LOCATOR_PROTOCOL_IMGSTREAMING
.equals(captureDeviceInfoLocator.getProtocol()))
{
if (sendPreset != null)
sendSize = sendPreset.getResolution();
else
{
/*
* XXX We cannot default to any video size here
* because we do not know how this MediaDevice
* instance will be used. If the caller wanted to
* limit the video size, she would've specified an
* actual sendPreset.
*/
// sendSize
// = mediaServiceImpl
// .getDeviceConfiguration()
// .getVideoSize();
}
}
Dimension receiveSize;
// if there is specified preset, send its settings
if (receivePreset != null)
receiveSize = receivePreset.getResolution();
else
{
// or just send the max video resolution of the PC as we
// do by default
ScreenDevice screen
= mediaServiceImpl.getDefaultScreenDevice();
receiveSize
= (screen == null) ? null : screen.getSize();
}
advancedAttrs.put(
"imageattr",
MediaUtils.createImageAttr(sendSize, receiveSize));
f
= mediaServiceImpl.getFormatFactory().createMediaFormat(
f.getEncoding(),
f.getClockRate(),
f.getFormatParameters(),
advancedAttrs);
}
if (f != null)
supportedFormats.add(f);
}
}
return supportedFormats;
}
/**
* Gets a human-readable String representation of this instance.
*
* @return a String providing a human-readable representation of
* this instance
*/
@Override
public String toString()
{
CaptureDeviceInfo captureDeviceInfo = getCaptureDeviceInfo();
return
(captureDeviceInfo == null)
? super.toString()
: captureDeviceInfo.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy