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){}
+
     }
 }