diff --git a/src/org/jitsi/impl/neomedia/device/AbstractMediaDevice.java b/src/org/jitsi/impl/neomedia/device/AbstractMediaDevice.java index b9149907f940330f3f97e7d0365e6b9cb1e7c8d6..f7a711363f54e24315d59450417ca05e85ff1b42 100644 --- a/src/org/jitsi/impl/neomedia/device/AbstractMediaDevice.java +++ b/src/org/jitsi/impl/neomedia/device/AbstractMediaDevice.java @@ -66,16 +66,59 @@ public void connect(DataSource captureDevice) */ protected abstract DataSource createOutputDataSource(); + /** + * Initializes a new <tt>Processor</tt> instance which is to be used to play + * back media on this <tt>MediaDevice</tt>. Allows extenders to, for + * example, disable the playback on this <tt>MediaDevice</tt> by completely + * overriding and returning <tt>null</tt>. + * + * @param dataSource the <tt>DataSource</tt> which is to be played back by + * the new <tt>Processor</tt> instance + * @return a new <tt>Processor</tt> instance which is to be used to play + * back the media provided by the specified <tt>dataSource</tt> or + * <tt>null</tt> if the specified <tt>dataSource</tt> is to not be played + * back + * @throws Exception if an exception is thrown by + * {@link DataSource#connect()}, + * {@link Manager#createProcessor(DataSource)}, or + * {@link DataSource#disconnect()} + */ + protected Processor createPlayer(DataSource dataSource) + throws Exception + { + Processor player = null; + + // A Player is documented to be created on a connected DataSource. + dataSource.connect(); + try + { + player = Manager.createProcessor(dataSource); + } + finally + { + if (player == null) + dataSource.disconnect(); + } + return player; + } + /** * Initializes a new <tt>Renderer</tt> instance which is to play back media - * on this <tt>MediaDevice</tt>. + * on this <tt>MediaDevice</tt>. Allows extenders to initialize a specific + * <tt>Renderer</tt> instance. The implementation of + * <tt>AbstractMediaDevice</tt> returns <tt>null</tt> which means that it is + * left to FMJ to choose a suitable <tt>Renderer</tt> irrespective of this + * <tt>MediaDevice</tt>. * * @return a new <tt>Renderer</tt> instance which is to play back media on * this <tt>MediaDevice</tt> or <tt>null</tt> if a suitable * <tt>Renderer</tt> is to be chosen irrespective of this * <tt>MediaDevice</tt> */ - public abstract Renderer createRenderer(); + protected Renderer createRenderer() + { + return null; + } /** * Creates a new <tt>MediaDeviceSession</tt> instance which is to represent diff --git a/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceImpl.java b/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceImpl.java index de37e5f69eaebd1700fb5442c6b7af7b85744ff0..33b1cc82290fe98883985d4364d7d9791e95a84c 100644 --- a/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceImpl.java +++ b/src/org/jitsi/impl/neomedia/device/AudioMediaDeviceImpl.java @@ -191,16 +191,18 @@ protected void connect( } /** - * Initializes a new <tt>Renderer</tt> instance which is to play back media - * on this <tt>MediaDevice</tt>. + * {@inheritDoc} * - * @return a new <tt>Renderer</tt> instance which is to play back media on - * this <tt>MediaDevice</tt> or <tt>null</tt> if a suitable - * <tt>Renderer</tt> is to be chosen irrespective of this - * <tt>MediaDevice</tt> + * Tries to delegate the initialization of a new <tt>Renderer</tt> instance + * to the <tt>AudioSystem</tt> which provides the <tt>CaptureDevice</tt> of + * this instance. This way both the capture and the playback are given a + * chance to happen within the same <tt>AudioSystem</tt>. If the discovery + * of the delegate fails, the implementation of <tt>MediaDeviceImpl</tt> is + * executed and it currently leaves it to FMJ to choose a <tt>Renderer</tt> + * irrespective of this <tt>MediaDevice</tt>. */ @Override - public Renderer createRenderer() + protected Renderer createRenderer() { Renderer renderer = null; diff --git a/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java b/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java index 23fc9f2612720e5a824e21d4dfe417260b85f700..06d6cd3fd5ce08bcefad2e3ae2969a8f745901f8 100644 --- a/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java +++ b/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java @@ -205,15 +205,28 @@ public AudioMixingPushBufferDataSource createOutputDataSource() } /** - * Initializes a new <tt>Renderer</tt> instance which is to play back media - * on this <tt>MediaDevice</tt>. + * {@inheritDoc} * - * @return a new <tt>Renderer</tt> instance which is to play back media on - * this <tt>MediaDevice</tt> or <tt>null</tt> if a suitable - * <tt>Renderer</tt> is to be chosen irrespective of this - * <tt>MediaDevice</tt> + * Delegates to the {@link AbstractMediaDevice#createPlayer(DataSource)} + * implementation of the <tt>MediaDevice</tt> on which this instance enables + * mixing i.e. {@link #getWrappedDevice()}. */ - public Renderer createRenderer() + @Override + protected Processor createPlayer(DataSource dataSource) + throws Exception + { + return device.createPlayer(dataSource); + } + + /** + * {@inheritDoc} + * + * Delegates to the {@link AbstractMediaDevice#createRenderer()} + * implementation of the <tt>MediaDevice</tt> on which this instance enables + * mixing i.e. {@link #getWrappedDevice()}. + */ + @Override + protected Renderer createRenderer() { return device.createRenderer(); } @@ -650,6 +663,20 @@ protected DataSource createCaptureDevice() return getAudioMixer().getLocalOutputDataSource(); } + /** + * {@inheritDoc} + */ + @Override + protected Player createPlayer(DataSource dataSource) + { + /* + * TODO AudioMixerMediaDevice wraps a MediaDevice so + * AudioMixerMediaDeviceSession should wrap a MediaDeviceSession of + * that same wrapped MediaDevice. + */ + return super.createPlayer(dataSource); + } + /** * Sets <tt>listener</tt> as the list of listeners that will receive * notifications of audio level event changes in the data arriving from diff --git a/src/org/jitsi/impl/neomedia/device/MediaDeviceImpl.java b/src/org/jitsi/impl/neomedia/device/MediaDeviceImpl.java index 0eb501d80be463383fe6a59a23822876c518a852..d05de0816b36a6156142c185875143729016452f 100644 --- a/src/org/jitsi/impl/neomedia/device/MediaDeviceImpl.java +++ b/src/org/jitsi/impl/neomedia/device/MediaDeviceImpl.java @@ -167,20 +167,6 @@ protected DataSource createOutputDataSource() : null; } - /** - * Initializes a new <tt>Renderer</tt> instance which is to play back media - * on this <tt>MediaDevice</tt>. - * - * @return a new <tt>Renderer</tt> instance which is to play back media on - * this <tt>MediaDevice</tt> or <tt>null</tt> if a suitable - * <tt>Renderer</tt> is to be chosen irrespective of this - * <tt>MediaDevice</tt> - */ - public Renderer createRenderer() - { - return null; - } - /** * Creates a new <tt>CaptureDevice</tt> which traces calls to a specific * <tt>CaptureDevice</tt> for debugging purposes. diff --git a/src/org/jitsi/impl/neomedia/device/MediaDeviceSession.java b/src/org/jitsi/impl/neomedia/device/MediaDeviceSession.java index b16f9352084009f162d537bdd367e60bfbd82056..bdc66b95e8be9c30f9214d67f88d8b0947895df8 100644 --- a/src/org/jitsi/impl/neomedia/device/MediaDeviceSession.java +++ b/src/org/jitsi/impl/neomedia/device/MediaDeviceSession.java @@ -430,36 +430,13 @@ protected Player createPlayer(DataSource dataSource) Processor player = null; Throwable exception = null; - // A Player is documented to be created on a connected DataSource. try { - dataSource.connect(); + player = getDevice().createPlayer(dataSource); } - catch (IOException ioex) + catch (Exception ex) { - // TODO - exception = ioex; - } - if (exception != null) - { - logger.error( - "Failed to connect to " - + MediaStreamImpl.toString(dataSource), - exception); - return player; - } - - try - { - player = Manager.createProcessor(dataSource); - } - catch (IOException ioe) - { - exception = ioe; - } - catch (NoPlayerException npe) - { - exception = npe; + exception = ex; } if (exception != null) { @@ -468,7 +445,7 @@ protected Player createPlayer(DataSource dataSource) + MediaStreamImpl.toString(dataSource), exception); } - else + else if (player != null) { /* * We cannot wait for the Player to get configured (e.g. with @@ -477,6 +454,7 @@ protected Player createPlayer(DataSource dataSource) * media (e.g. abnormally stopped), it will leave us blocked. */ if (playerControllerListener == null) + { playerControllerListener = new ControllerListener() { @@ -495,20 +473,20 @@ public void controllerUpdate(ControllerEvent event) playerControllerUpdate(event); } }; + } player.addControllerListener(playerControllerListener); player.configure(); if (logger.isTraceEnabled()) + { logger.trace( "Created Player with hashCode " + player.hashCode() + " for " + MediaStreamImpl.toString(dataSource)); + } } - if (player == null) - dataSource.disconnect(); - return player; } @@ -939,12 +917,13 @@ public DataSource getOutputDataSource() { outputDataSource = processor.getDataOutput(); if (logger.isTraceEnabled() && (outputDataSource != null)) - logger - .trace( + { + logger.trace( "Processor with hashCode " + processor.hashCode() + " provided " + MediaStreamImpl.toString(outputDataSource)); + } /* * Whoever wants the outputDataSource, they expect it to be started diff --git a/src/org/jitsi/impl/neomedia/device/VideoTranslatorMediaDevice.java b/src/org/jitsi/impl/neomedia/device/VideoTranslatorMediaDevice.java index 647e40da553a497be90a1c7f383f308f030e07ac..b0653a77d8bcf875acaae37f3e5e536fbd07a4a9 100644 --- a/src/org/jitsi/impl/neomedia/device/VideoTranslatorMediaDevice.java +++ b/src/org/jitsi/impl/neomedia/device/VideoTranslatorMediaDevice.java @@ -123,20 +123,6 @@ protected synchronized DataSource createOutputDataSource() : deviceSession.getOutputDataSource(); } - /** - * Initializes a new <tt>Renderer</tt> instance which is to play back media - * on this <tt>MediaDevice</tt>. - * - * @return a new <tt>Renderer</tt> instance which is to play back media on - * this <tt>MediaDevice</tt> or <tt>null</tt> if a suitable - * <tt>Renderer</tt> is to be chosen irrespective of this - * <tt>MediaDevice</tt> - */ - public Renderer createRenderer() - { - return null; - } - /** * Creates a new <tt>MediaDeviceSession</tt> instance which is to represent * the use of this <tt>MediaDevice</tt> by a <tt>MediaStream</tt>.