diff --git a/src/org/jitsi/impl/neomedia/device/VideoMediaDeviceSession.java b/src/org/jitsi/impl/neomedia/device/VideoMediaDeviceSession.java index e04891c684f453c6a93343917048372bb5a90d55..2b5d7ef90c61cfb61ba704855949f1cce02f5495 100644 --- a/src/org/jitsi/impl/neomedia/device/VideoMediaDeviceSession.java +++ b/src/org/jitsi/impl/neomedia/device/VideoMediaDeviceSession.java @@ -41,6 +41,7 @@ * @author Lyubomir Marinov * @author Sebastien Vincent * @author Hristo Terezov + * @author Boris Grozev */ public class VideoMediaDeviceSession extends MediaDeviceSession @@ -706,7 +707,7 @@ public void paint(Graphics g) * @param player the <tt>Player</tt> to dispose of * @see MediaDeviceSession#disposePlayer(Player) */ - private void disposeLocalPlayer(Player player) + protected void disposeLocalPlayer(Player player) { /* * The player is being disposed so let the (interested) listeners know @@ -1682,7 +1683,6 @@ protected Format setProcessorFormat( } } - if (keyFrameControl != null) encoder.setKeyFrameControl(keyFrameControl); @@ -1822,7 +1822,7 @@ protected void startedDirectionChanged( synchronized (localPlayerSyncRoot) { - localPlayer = this.localPlayer; + localPlayer = getLocalPlayer(); } if (newValue.allowsSending()) { @@ -1898,6 +1898,20 @@ else if (state > Processor.Configured) } } + /** + * Return the <tt>Player</tt> instance which provides the local visual/video + * <tt>Component</tt>. + * @return the <tt>Player</tt> instance which provides the local visual/video + * <tt>Component</tt>. + */ + protected Player getLocalPlayer() + { + synchronized (localPlayerSyncRoot) + { + return localPlayer; + } + } + /** * Extends <tt>SwScale</tt> in order to provide scaling with high quality * to a specific <tt>Player</tt> of remote video. diff --git a/src/org/jitsi/impl/neomedia/device/VideoTranslatorMediaDevice.java b/src/org/jitsi/impl/neomedia/device/VideoTranslatorMediaDevice.java index fcb977fd1429a4716aef3b504885762c8d9d4af4..d2fb6643c94b00a057c4d0c945322e0ce4c38611 100644 --- a/src/org/jitsi/impl/neomedia/device/VideoTranslatorMediaDevice.java +++ b/src/org/jitsi/impl/neomedia/device/VideoTranslatorMediaDevice.java @@ -6,7 +6,9 @@ */ package org.jitsi.impl.neomedia.device; +import java.awt.*; import java.util.*; +import java.util.List; import javax.media.*; import javax.media.protocol.*; @@ -17,6 +19,7 @@ import org.jitsi.service.neomedia.codec.*; import org.jitsi.service.neomedia.device.*; import org.jitsi.service.neomedia.format.*; +import org.jitsi.util.event.*; /** * Implements a <tt>MediaDevice</tt> which is to be used in video conferencing @@ -24,10 +27,12 @@ * * @author Lyubomir Marinov * @author Hristo Terezov + * @author Boris Grozev */ public class VideoTranslatorMediaDevice extends AbstractMediaDevice - implements MediaDeviceWrapper + implements MediaDeviceWrapper, + VideoListener { /** * The <tt>MediaDevice</tt> which this instance enables to be used in a @@ -36,11 +41,11 @@ public class VideoTranslatorMediaDevice private final MediaDeviceImpl device; /** - * The <tt>MediaDeviceSession</tt> of {@link #device} the + * The <tt>VideoMediaDeviceSession</tt> of {@link #device} the * <tt>outputDataSource</tt> of which is the <tt>captureDevice</tt> of * {@link #streamDeviceSessions}. */ - private MediaDeviceSession deviceSession; + private VideoMediaDeviceSession deviceSession; /** * The <tt>MediaStreamMediaDeviceSession</tt>s sharing the @@ -76,16 +81,18 @@ private synchronized void close( MediaStreamMediaDeviceSession streamDeviceSession) { streamDeviceSessions.remove(streamDeviceSession); - if(deviceSession instanceof VideoMediaDeviceSession) + if(deviceSession != null) { - ((VideoMediaDeviceSession)deviceSession) - .removeRTCPFeedbackCreateListner( + deviceSession.removeRTCPFeedbackCreateListner( streamDeviceSession); } if (streamDeviceSessions.isEmpty()) { if(deviceSession != null) + { + deviceSession.removeVideoListener(this); deviceSession.close(); + } deviceSession = null; } else @@ -121,16 +128,16 @@ protected synchronized DataSource createOutputDataSource() streamDeviceSession.getStartedDirection()); } - deviceSession = device.createSession(); - if(deviceSession instanceof VideoMediaDeviceSession) + MediaDeviceSession newDeviceSession = device.createSession(); + if(newDeviceSession instanceof VideoMediaDeviceSession) { - VideoMediaDeviceSession videoMediaDeviceSession - = (VideoMediaDeviceSession) deviceSession; + deviceSession = (VideoMediaDeviceSession)newDeviceSession; + deviceSession.addVideoListener(this); for (MediaStreamMediaDeviceSession streamDeviceSession : streamDeviceSessions) { - videoMediaDeviceSession.addRTCPFeedbackCreateListner( + deviceSession.addRTCPFeedbackCreateListner( streamDeviceSession); } } @@ -289,6 +296,57 @@ private synchronized void updateDeviceSessionStartedDirection() deviceSession.stop(stopDirection); } + /** + * {@inheritDoc} + * + * Forwards <tt>event</tt>, to each of the managed + * <tt>MediaStreamMediaDeviceSession</tt> instances. The event is expected + * to come from <tt>this.deviceSession</tt>, since <tt>this</tt> is + * registered there as a <tt>VideoListener</tt>. + */ + @Override + public void videoAdded(VideoEvent event) + { + for (MediaStreamMediaDeviceSession sds : streamDeviceSessions) + { + sds.fireVideoEvent(event, false); + } + } + + /** + * {@inheritDoc} + * + * Forwards <tt>event</tt>, to each of the managed + * <tt>MediaStreamMediaDeviceSession</tt> instances. The event is expected + * to come from <tt>this.deviceSession</tt>, since <tt>this</tt> is + * registered there as a <tt>VideoListener</tt>. + */ + @Override + public void videoRemoved(VideoEvent event) + { + for (MediaStreamMediaDeviceSession sds : streamDeviceSessions) + { + sds.fireVideoEvent(event, false); + } + } + + /** + * {@inheritDoc} + * + * Forwards <tt>event</tt>, to each of the managed + * <tt>MediaStreamMediaDeviceSession</tt> instances. The event is expected + * to come from <tt>this.deviceSession</tt>, since <tt>this</tt> is + * registered there as a <tt>VideoListener</tt>. + */ + @Override + public void videoUpdate(VideoEvent event) + { + for (MediaStreamMediaDeviceSession sds : streamDeviceSessions) + { + sds.fireVideoEvent(event, false); + } + } + /** * Represents the use of this <tt>VideoTranslatorMediaDevice</tt> by a * <tt>MediaStream</tt>. @@ -395,11 +453,9 @@ public DataSource getOutputDataSource() public void setConnector(AbstractRTPConnector rtpConnector) { super.setConnector(rtpConnector); - if(deviceSession != null - && deviceSession instanceof VideoMediaDeviceSession) + if(deviceSession != null) { - ((VideoMediaDeviceSession) deviceSession) - .addRTCPFeedbackCreateListner(this); + deviceSession.addRTCPFeedbackCreateListner(this); } } @@ -423,5 +479,65 @@ protected void startedDirectionChanged( VideoTranslatorMediaDevice.this .updateDeviceSessionStartedDirection(); } + + /** + * {@inheritDoc} + * Returns the local visual <tt>Component</tt> for this + * <tt>MediaStreamMediaDeviceSession</tt>, which, if present, is + * maintained in <tt>this.deviceSession</tt>. + */ + @Override + public Component getLocalVisualComponent() + { + if (deviceSession != null) + return deviceSession.getLocalVisualComponent(); + return null; + } + + /** + * {@inheritDoc} + * + * Creates, if necessary, the local visual <tt>Component</tt> depicting + * the video being streamed from the local peer to a remote peer. The + * <tt>Component</tt> is provided by the single <tt>Player</tt> + * instance, which is maintained for this + * <tt>VideoTranslatorMediaDevice</tt> and is managed by + * <tt>this.deviceSession</tt>. + */ + @Override + protected Component createLocalVisualComponent() + { + if (deviceSession != null) + return deviceSession.createLocalVisualComponent(); + return null; + } + + /** + * {@inheritDoc} + * + * Returns the <tt>Player</tt> instance which provides the local + * visual/video <tt>Component</tt>. A single <tt>Player</tt> is + * maintained for this <tt>VideoTranslatorMediaDevice</tt>, and it is + * managed by <tt>this.deviceSession</tt>. + */ + @Override + protected Player getLocalPlayer() + { + if (deviceSession != null) + return deviceSession.getLocalPlayer(); + return null; + } + + /** + * {@inheritDoc} + * + * Does nothing, because there is no <tt>Player</tt> associated with + * this <tt>MediaStreamMediaDeviceSession</tt> and therefore nothing to + * dispose of. + * @param player the <tt>Player</tt> to dispose of. + */ + @Override + protected void disposeLocalPlayer(Player player){} + } }