diff --git a/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java b/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java
index fa55ed597..715e1ebda 100644
--- a/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java
+++ b/src/net/java/sip/communicator/impl/neomedia/VideoMediaStreamImpl.java
@@ -310,6 +310,33 @@ protected boolean fireVideoEvent(
videoNotifierSupport.fireVideoEvent(type, visualComponent, origin);
}
+ /**
+ * Gets local visual Component of the local peer.
+ *
+ * @return visual Component
+ */
+ public Component createLocalVisualComponent()
+ {
+ MediaDeviceSession deviceSession = getDeviceSession();
+
+ return
+ (deviceSession instanceof VideoMediaDeviceSession)
+ ? ((VideoMediaDeviceSession) deviceSession).createLocalVisualComponent()
+ : null;
+ }
+
+ /**
+ * Dispose local visual Component of the local peer.
+ */
+ public void disposeLocalVisualComponent()
+ {
+ MediaDeviceSession deviceSession = getDeviceSession();
+ if(deviceSession instanceof VideoMediaDeviceSession)
+ {
+ ((VideoMediaDeviceSession) deviceSession).disposeLocalVisualComponent();
+ }
+ }
+
/**
* Returns a reference to the visual Component where video from the
* remote peer is being rendered or null if no video is currently
diff --git a/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java b/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java
index 7a11da63b..38141c525 100644
--- a/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java
+++ b/src/net/java/sip/communicator/impl/neomedia/device/VideoMediaDeviceSession.java
@@ -9,7 +9,9 @@
import java.awt.*;
import javax.media.*;
+import javax.media.protocol.*;
+import net.java.sip.communicator.impl.neomedia.*;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.neomedia.event.*;
import net.java.sip.communicator.util.*;
@@ -37,6 +39,11 @@ public class VideoMediaDeviceSession
private final VideoNotifierSupport videoNotifierSupport
= new VideoNotifierSupport(this);
+ /**
+ * Local Player for the local video.
+ */
+ private Player localPlayer = null;
+
/**
* Initializes a new VideoMediaDeviceSession instance which is to
* represent the work of a MediaStream with a specific video
@@ -69,6 +76,23 @@ public void addVideoListener(VideoListener listener)
videoNotifierSupport.addVideoListener(listener);
}
+ /**
+ * Creates the DataSource that this instance is to read captured
+ * media from.
+ *
+ * @return the DataSource that this instance is to read captured
+ * media from
+ */
+ @Override
+ protected DataSource createCaptureDevice()
+ {
+ /* create our DataSource as Cloneable so we can both use it
+ * to display local video and stream to remote peer
+ */
+ DataSource captureDevice = Manager.createCloneableDataSource(getDevice().createOutputDataSource());
+ return captureDevice;
+ }
+
/**
* Asserts that a specific MediaDevice is acceptable to be set as
* the MediaDevice of this instance. Makes sure that its
@@ -149,6 +173,148 @@ protected boolean fireVideoEvent(
videoNotifierSupport.fireVideoEvent(type, visualComponent, origin);
}
+ /**
+ * Get the local Player if it exists,
+ * create it otherwise
+ * @return local Player
+ */
+ private Player getLocalPlayer()
+ {
+ DataSource dataSource = ((SourceCloneable)getCaptureDevice()).createClone();
+
+ /* create local player */
+ if (localPlayer == null && dataSource != null)
+ {
+ Exception excpt = null;
+ try
+ {
+ localPlayer = Manager.createPlayer(dataSource);
+ }
+ catch (Exception ex)
+ {
+ excpt = ex;
+ }
+
+ if(excpt == null)
+ {
+ localPlayer.addControllerListener(new ControllerListener()
+ {
+ public void controllerUpdate(ControllerEvent event)
+ {
+ controllerUpdateForCreateLocalVisualComponent(event);
+ }
+ });
+ localPlayer.start();
+ }
+ else
+ {
+ logger.error("Failed to connect to "
+ + MediaStreamImpl.toString(dataSource),
+ excpt);
+ }
+ }
+
+ return localPlayer;
+ }
+
+ /**
+ * Gets notified about ControllerEvents generated by
+ * {@link #player}.
+ *
+ * @param event the ControllerEvent specifying the
+ * Controller which is the source of the event and the very type of
+ * the event
+ */
+ private void controllerUpdateForCreateLocalVisualComponent(
+ ControllerEvent controllerEvent)
+ {
+ if (controllerEvent instanceof RealizeCompleteEvent)
+ {
+ Player player = (Player) controllerEvent.getSourceController();
+ Component visualComponent = player.getVisualComponent();
+
+ if (visualComponent != null)
+ {
+ if(!fireVideoEvent(
+ VideoEvent.VIDEO_ADDED,
+ visualComponent,
+ VideoEvent.LOCAL))
+ {
+ /* no listener interrested by our event
+ * free resources
+ */
+ if(player == localPlayer)
+ {
+ localPlayer = null;
+ }
+
+ player.stop();
+ player.deallocate();
+ player.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets local visual Component of the local peer.
+ *
+ * @return visual Component
+ */
+ public Component createLocalVisualComponent()
+ {
+ Player player = getLocalPlayer();
+ return null;
+ }
+
+ /**
+ * Dispose local visual Component of the local peer.
+ */
+ public void disposeLocalVisualComponent()
+ {
+ Player player = getLocalPlayer();
+
+ if(player != null)
+ {
+ disposeLocalPlayer(player);
+ }
+ }
+
+ /**
+ * Releases the resources allocated by a specific local Player in the
+ * course of its execution and prepares it to be garbage collected. If the
+ * specified Player is rendering video, notifies the
+ * VideoListeners of this instance that its visual
+ * Component is to no longer be used by firing a
+ * {@link VideoEvent#VIDEO_REMOVED} VideoEvent.
+ *
+ * @param player the Player to dispose of
+ * @see MediaDeviceSession#disposePlayer(Player)
+ */
+ protected void disposeLocalPlayer(Player player)
+ {
+ /*
+ * The player is being disposed so let the (interested) listeners know
+ * its Player#getVisualComponent() (if any) should be released.
+ */
+ Component visualComponent = getVisualComponent(player);
+
+ if(localPlayer == player)
+ {
+ localPlayer = null;
+ }
+
+ player.stop();
+ player.deallocate();
+ player.close();
+
+ if (visualComponent != null)
+ fireVideoEvent(
+ VideoEvent.VIDEO_REMOVED,
+ visualComponent,
+ VideoEvent.LOCAL);
+ }
+
/**
* Returns the visual Component where video from the remote peer
* is being rendered or null if no video is currently rendered.
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandler.java b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandler.java
index afbc87b7a..2115301fa 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandler.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandler.java
@@ -344,8 +344,15 @@ public CallPeerMediaHandler(CallPeerSipImpl peer)
*/
public void setLocalVideoTransmissionEnabled(boolean enabled)
{
+ MediaDirection oldValue = videoDirectionUserPreference;
+ MediaDirection newValue = null;
+
videoDirectionUserPreference
= enabled ? MediaDirection.SENDRECV : MediaDirection.RECVONLY;
+
+ newValue = videoDirectionUserPreference;
+
+ firePropertyChange(OperationSetVideoTelephony.LOCAL_VIDEO_STREAMING, oldValue, newValue);
}
/**
@@ -1886,6 +1893,29 @@ protected boolean fireVideoEvent(
return consumed;
}
+ /**
+ * Gets local visual Component of the local peer.
+ *
+ * @return visual Component
+ */
+ public Component createLocalVisualComponent()
+ {
+ return (videoStream == null || !isLocalVideoTransmissionEnabled()) ? null : videoStream.createLocalVisualComponent();
+ }
+
+ /**
+ * Dispose local visual Component of the local peer.
+ *
+ * @return visual Component
+ */
+ public void disposeLocalVisualComponent()
+ {
+ if(videoStream != null)
+ {
+ videoStream.disposeLocalVisualComponent();
+ }
+ }
+
/**
* Gets the visual Component in which video from the remote peer is
* currently being rendered or null if there is currently no video
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java
index 0a737a3fb..e1dd00e97 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java
@@ -1507,9 +1507,9 @@ public void propertyChange(PropertyChangeEvent event)
listener.propertyChange(thisEvent);
}
};
-// getMediaHandler()
-// .addPropertyChangeListener(
-// mediaHandlerPropertyChangeListener);
+ getMediaHandler()
+ .addPropertyChangeListener(
+ mediaHandlerPropertyChangeListener);
}
}
}
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetVideoTelephonySipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetVideoTelephonySipImpl.java
index 5e959c16b..2de873459 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetVideoTelephonySipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetVideoTelephonySipImpl.java
@@ -89,26 +89,8 @@ public Component createLocalVisualComponent(
VideoListener listener)
throws OperationFailedException
{
- /**
- * @todo update to neomedia.
- CallSession callSession =((CallPeerSipImpl) peer).getMediaCallSession();
-
- if (callSession != null)
- {
- try
- {
- return callSession.createLocalVisualComponent(listener);
- }
- catch (MediaException ex)
- {
- throw new OperationFailedException(
- "Failed to create visual Component for local "
- +"video (capture).",
- OperationFailedException.INTERNAL_ERROR, ex);
- }
- }
- */
- return null;
+ CallPeerMediaHandler mediaHandler = ((CallPeerSipImpl) peer).getMediaHandler();
+ return mediaHandler.createLocalVisualComponent();
}
/**
@@ -122,13 +104,8 @@ public Component createLocalVisualComponent(
*/
public void disposeLocalVisualComponent(CallPeer peer, Component component)
{
- /**
- * @todo update to neomedia.
- CallSession callSession =((CallPeerSipImpl) peer).getMediaCallSession();
-
- if (callSession != null)
- callSession.disposeLocalVisualComponent(component);
- */
+ CallPeerMediaHandler mediaHandler = ((CallPeerSipImpl) peer).getMediaHandler();
+ mediaHandler.disposeLocalVisualComponent();
}
/**
diff --git a/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java b/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java
index b48b57230..b76ec1c79 100644
--- a/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java
+++ b/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java
@@ -20,6 +20,18 @@
public interface VideoMediaStream
extends MediaStream
{
+ /**
+ * Gets local visual Component of the local peer.
+ *
+ * @return visual Component
+ */
+ public Component createLocalVisualComponent();
+
+ /**
+ * Dispose local visual Component of the local peer.
+ */
+ public void disposeLocalVisualComponent();
+
/**
* Returns a reference to the visual Component where video from the
* remote peer is being rendered or null if no video is currently