aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/sip/communicator/service
diff options
context:
space:
mode:
authorYana Stamcheva <yana@jitsi.org>2012-06-25 12:54:06 +0000
committerYana Stamcheva <yana@jitsi.org>2012-06-25 12:54:06 +0000
commit51d7bf04f69968bafb4e29d376875e8d300427b4 (patch)
tree11b795b8c5b21f1eeaa073395bde1254e2bc08d2 /src/net/java/sip/communicator/service
parentd1835c8e95e65b48d0f61b97690b4a2a3cc48344 (diff)
downloadjitsi-51d7bf04f69968bafb4e29d376875e8d300427b4.zip
jitsi-51d7bf04f69968bafb4e29d376875e8d300427b4.tar.gz
jitsi-51d7bf04f69968bafb4e29d376875e8d300427b4.tar.bz2
Adds video conference interface enhancements.
Diffstat (limited to 'src/net/java/sip/communicator/service')
-rw-r--r--src/net/java/sip/communicator/service/neomedia/MediaStream.java8
-rw-r--r--src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java11
-rw-r--r--src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java2
-rw-r--r--src/net/java/sip/communicator/service/protocol/AbstractConferenceMember.java43
-rw-r--r--src/net/java/sip/communicator/service/protocol/ConferenceMember.java11
-rw-r--r--src/net/java/sip/communicator/service/protocol/OperationSetVideoTelephony.java45
-rw-r--r--src/net/java/sip/communicator/service/protocol/event/VisualComponentResolveEvent.java79
-rw-r--r--src/net/java/sip/communicator/service/protocol/event/VisualComponentResolveListener.java29
-rw-r--r--src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetVideoTelephony.java80
-rw-r--r--src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java109
10 files changed, 406 insertions, 11 deletions
diff --git a/src/net/java/sip/communicator/service/neomedia/MediaStream.java b/src/net/java/sip/communicator/service/neomedia/MediaStream.java
index bd42432..00dcc76 100644
--- a/src/net/java/sip/communicator/service/neomedia/MediaStream.java
+++ b/src/net/java/sip/communicator/service/neomedia/MediaStream.java
@@ -116,6 +116,14 @@ public interface MediaStream
public long getRemoteSourceID();
/**
+ * Gets the synchronization source (SSRC) identifiers of the remote peers.
+ *
+ * @return the synchronization source (SSRC) identifiers of the remote peers
+ * @see MediaStream#getRemoteSourceIDs()
+ */
+ public List<Long> getRemoteSourceIDs();
+
+ /**
* Returns the synchronization source (SSRC) identifier of the local
* participant or <tt>-1</tt> if that identifier is not yet known at this
* point.
diff --git a/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java b/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java
index 524da5b..851ac94 100644
--- a/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java
+++ b/src/net/java/sip/communicator/service/neomedia/VideoMediaStream.java
@@ -62,6 +62,17 @@ public interface VideoMediaStream
public List<Component> getVisualComponents();
/**
+ * Gets the visual <tt>Component</tt>s rendering the <tt>ReceiveStream</tt>
+ * corresponding to the given ssrc.
+ *
+ * @param ssrc the src-id of the receive stream, which visual
+ * <tt>Component</tt> we're looking for
+ * @return the visual <tt>Component</tt> rendering the
+ * <tt>ReceiveStream</tt> corresponding to the given ssrc
+ */
+ public Component getVisualComponent(long ssrc);
+
+ /**
* Adds a specific <tt>VideoListener</tt> to this <tt>VideoMediaStream</tt>
* in order to receive notifications when visual/video <tt>Component</tt>s
* are being added and removed.
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java b/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java
index 745bb91..7eb43a8 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java
+++ b/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java
@@ -829,7 +829,7 @@ public abstract class AbstractCallPeer<T extends Call,
{
ConferenceMember mmbr = conferenceMembers.get(i);
- if (mmbr.getSSRC() == ssrc)
+ if (mmbr.getAudioSsrc() == ssrc)
return mmbr;
}
return null;
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractConferenceMember.java b/src/net/java/sip/communicator/service/protocol/AbstractConferenceMember.java
index a3a2bc6..739a03a 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractConferenceMember.java
+++ b/src/net/java/sip/communicator/service/protocol/AbstractConferenceMember.java
@@ -44,9 +44,14 @@ public class AbstractConferenceMember
private ConferenceMemberState state = ConferenceMemberState.UNKNOWN;
/**
- * The SSRC value if transmitted by the focus of the conference.
+ * The audio SSRC value if transmitted by the focus of the conference.
*/
- private long ssrc = -1;
+ private long audioSsrc = -1;
+
+ /**
+ * The video SSRC value if transmitted by the focus of the conference.
+ */
+ private long videoSsrc = -1;
/**
* Creates an instance of <tt>AbstractConferenceMember</tt> by specifying
@@ -157,20 +162,40 @@ public class AbstractConferenceMember
/**
* Returns the SSRC value associated with this participant;
*
- * @return the ssrc
+ * @return the audio ssrc id
+ */
+ public long getAudioSsrc()
+ {
+ return audioSsrc;
+ }
+
+ /**
+ * Sets the audio SSRC identifier of this member.
+ *
+ * @param ssrc the audio SSRC ID to set for this member.
+ */
+ public void setAudioSsrc(long ssrc)
+ {
+ this.audioSsrc = ssrc;
+ }
+
+ /**
+ * Returns the SSRC value associated with this participant;
+ *
+ * @return the video ssrc id
*/
- public long getSSRC()
+ public long getVideoSsrc()
{
- return ssrc;
+ return videoSsrc;
}
/**
- * Sets the SSRC identifier of this member.
+ * Sets the video SSRC identifier of this member.
*
- * @param ssrc the SSRC ID to set for this member.
+ * @param ssrc the video SSRC ID to set for this member.
*/
- public void setSSRC(long ssrc)
+ public void setVideoSsrc(long ssrc)
{
- this.ssrc = ssrc;
+ this.videoSsrc = ssrc;
}
}
diff --git a/src/net/java/sip/communicator/service/protocol/ConferenceMember.java b/src/net/java/sip/communicator/service/protocol/ConferenceMember.java
index 1550df3..1afe8f2 100644
--- a/src/net/java/sip/communicator/service/protocol/ConferenceMember.java
+++ b/src/net/java/sip/communicator/service/protocol/ConferenceMember.java
@@ -108,5 +108,14 @@ public interface ConferenceMember
* @return the ssrc associated with the RTP stream that this participant
* is transmitting or <tt>null</tt> if this value is not currently known.
*/
- public long getSSRC();
+ public long getAudioSsrc();
+
+ /**
+ * Returns the SSRC value associated with this participant or <tt>null</tt>
+ * if the value is not currently known.;
+ *
+ * @return the ssrc associated with the RTP stream that this participant
+ * is transmitting or <tt>null</tt> if this value is not currently known.
+ */
+ public long getVideoSsrc();
}
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetVideoTelephony.java b/src/net/java/sip/communicator/service/protocol/OperationSetVideoTelephony.java
index 6870764..a6119bd 100644
--- a/src/net/java/sip/communicator/service/protocol/OperationSetVideoTelephony.java
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetVideoTelephony.java
@@ -12,6 +12,7 @@ import java.text.*;
import java.util.List;
import net.java.sip.communicator.service.neomedia.*;
+import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.event.*;
/**
@@ -287,4 +288,48 @@ public interface OperationSetVideoTelephony
* @return the implemented quality control.
*/
public QualityControl getQualityControl(CallPeer peer);
+
+ /**
+ * Adds a specific <tt>VisualComponentResolveListener</tt> to this telephony
+ * in order to receive notifications when visual/video <tt>Component</tt>s
+ * are being resolved to correspond to a particular
+ * <tt>ConferenceMember</tt>.
+ *
+ * @param callPeer the <tt>CallPeer</tt>, which visual components we're
+ * listening to
+ * @param listener the <tt>VisualComponentResolveListener</tt> to be
+ * notified when visual/video <tt>Component</tt>s are being resolved to
+ * correspond to a particular <tt>ConferenceMember</tt>.
+ */
+ public void addVisualComponentResolveListener(
+ CallPeer callPeer,
+ VisualComponentResolveListener listener);
+
+ /**
+ * Removes a <tt>VisualComponentResolveListener</tt> from this video
+ * telephony operation set, which was previously added in order to receive
+ * notifications when visual/video <tt>Component</tt>s are being resolved to
+ * be corresponding to a particular <tt>ConferenceMember</tt>.
+ *
+ * @param callPeer the <tt>CallPeer</tt>, which visual components we're
+ * listening to
+ * @param listener the <tt>VisualComponentResolveListener</tt> to be
+ * removed
+ */
+ public void removeVisualComponentResolveListener(
+ CallPeer callPeer,
+ VisualComponentResolveListener listener);
+
+ /**
+ * Returns the <tt>ConferenceMember</tt> corresponding to the given
+ * <tt>visualComponent</tt>.
+ *
+ * @param peer the parent <tt>CallPeer</tt>
+ * @param visualComponent the visual <tt>Component</tt>, which corresponding
+ * <tt>ConferenceMember</tt> we're looking for
+ * @return the <tt>ConferenceMember</tt> corresponding to the given
+ * <tt>visualComponent</tt>.
+ */
+ public ConferenceMember getConferenceMember(CallPeer peer,
+ Component visualComponent);
}
diff --git a/src/net/java/sip/communicator/service/protocol/event/VisualComponentResolveEvent.java b/src/net/java/sip/communicator/service/protocol/event/VisualComponentResolveEvent.java
new file mode 100644
index 0000000..d9479fc
--- /dev/null
+++ b/src/net/java/sip/communicator/service/protocol/event/VisualComponentResolveEvent.java
@@ -0,0 +1,79 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.service.protocol.event;
+
+import java.awt.*;
+import java.util.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * In a conference call notifies that a visual <tt>Component</tt> representing
+ * video has been resolved to be corresponding to a given
+ * <tt>ConferenceMember</tt>. The event contains information about the concerned
+ * visual component and it's corresponding member.
+ *
+ * @author Yana Stamcheva
+ */
+public class VisualComponentResolveEvent
+ extends EventObject
+{
+ /**
+ * Serial version UID.
+ */
+ private static final long serialVersionUID = 0L;
+
+ /**
+ * The visual component that has been resolved.
+ */
+ private final ConferenceMember conferenceMember;
+
+ /**
+ * The visual <tt>Component</tt> depicting video which had its availability
+ * changed and which this <tt>VideoEvent</tt> notifies about.
+ */
+ private final Component visualComponent;
+
+ /**
+ *
+ * @param source the source of the new <tt>VideoEvent</tt> and the provider
+ * of the visual <tt>Component</tt> depicting video
+ */
+ public VisualComponentResolveEvent( Object source,
+ Component visualComponent,
+ ConferenceMember resolvedMember)
+ {
+ super(source);
+
+ this.visualComponent = visualComponent;
+ this.conferenceMember = resolvedMember;
+ }
+
+ /**
+ * Gets the visual <tt>Component</tt> depicting video which had its
+ * availability changed and which this <tt>VideoEvent</tt> notifies about.
+ *
+ * @return the visual <tt>Component</tt> depicting video which had its
+ * availability changed and which this <tt>VideoEvent</tt> notifies about
+ */
+ public Component getVisualComponent()
+ {
+ return visualComponent;
+ }
+
+ /**
+ * Gets the <tt>ConferenceMember</tt> that was resolved to be corresponding
+ * to the source visual component.
+ *
+ * @return the <tt>ConferenceMember</tt> that was resolved to be
+ * corresponding to the source visual component
+ */
+ public ConferenceMember getConferenceMember()
+ {
+ return conferenceMember;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/event/VisualComponentResolveListener.java b/src/net/java/sip/communicator/service/protocol/event/VisualComponentResolveListener.java
new file mode 100644
index 0000000..c475b07
--- /dev/null
+++ b/src/net/java/sip/communicator/service/protocol/event/VisualComponentResolveListener.java
@@ -0,0 +1,29 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.service.protocol.event;
+
+import java.util.*;
+
+/**
+ * In a conference call notifies that a visual <tt>Component</tt> representing
+ * video has been resolved to be corresponding to a given
+ * <tt>ConferenceMember</tt>.
+ *
+ * @author Yana Stamcheva
+ */
+public interface VisualComponentResolveListener
+ extends EventListener
+{
+ /**
+ * Notifies that a visual <tt>Component</tt> representing video has been
+ * resolved to be corresponding to a given <tt>ConferenceMember</tt>.
+ *
+ * @param event a <tt>VisualComponentResolveEvent</tt> describing the
+ * resolved component and the corresponding <tt>ConferenceMember</tt>
+ */
+ public void visualComponentResolved(VisualComponentResolveEvent event);
+}
diff --git a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetVideoTelephony.java b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetVideoTelephony.java
index 43da709..9e9074e 100644
--- a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetVideoTelephony.java
+++ b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetVideoTelephony.java
@@ -13,6 +13,7 @@ import java.util.List;
import net.java.sip.communicator.service.neomedia.*;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.event.*;
/**
@@ -155,6 +156,41 @@ public abstract class AbstractOperationSetVideoTelephony<
}
/**
+ * Returns the <tt>ConferenceMember</tt> corresponding to the given
+ * <tt>visualComponent</tt>.
+ *
+ * @param peer the parent <tt>CallPeer</tt>
+ * @param visualComponent the visual <tt>Component</tt>, which corresponding
+ * <tt>ConferenceMember</tt> we're looking for
+ * @return the <tt>ConferenceMember</tt> corresponding to the given
+ * <tt>visualComponent</tt>.
+ */
+ @SuppressWarnings("unchecked") // work with MediaAware* in media package
+ public ConferenceMember getConferenceMember(CallPeer peer,
+ Component visualComponent)
+ {
+ VideoMediaStream peerVideoStream
+ = (VideoMediaStream) ((W)peer).getMediaHandler()
+ .getStream(MediaType.VIDEO);
+
+ if (peerVideoStream == null)
+ return null;
+
+ for (ConferenceMember member : peer.getConferenceMembers())
+ {
+ Component memberComponent = peerVideoStream
+ .getVisualComponent(member.getVideoSsrc());
+
+ if (memberComponent != null
+ && memberComponent.equals(visualComponent))
+ {
+ return member;
+ }
+ }
+ return null;
+ }
+
+ /**
* Delegates to the <tt>CallPeerMediaHandler</tt> of the specified
* <tt>CallPeer</tt> because the video is provided by it.
*
@@ -503,4 +539,48 @@ public abstract class AbstractOperationSetVideoTelephony<
delegate.videoUpdate(event);
}
}
+
+ /**
+ * Adds a specific <tt>VisualComponentResolveListener</tt> to this telephony
+ * in order to receive notifications when visual/video <tt>Component</tt>s
+ * are being resolved to correspond to a particular
+ * <tt>ConferenceMember</tt>.
+ *
+ * @param callPeer the <tt>CallPeer</tt>, which visual components we're
+ * listening to
+ * @param listener the <tt>VisualComponentResolveListener</tt> to be
+ * notified when visual/video <tt>Component</tt>s are being resolved to
+ * correspond to a particular <tt>ConferenceMember</tt>.
+ */
+ @SuppressWarnings("unchecked") // work with MediaAware* in media package
+ public void addVisualComponentResolveListener(
+ CallPeer callPeer,
+ VisualComponentResolveListener listener)
+ {
+ if (listener == null)
+ throw new NullPointerException("listener");
+
+ ((W)callPeer).getMediaHandler().addVisualComponentResolveListener(
+ listener);
+ }
+
+ /**
+ * Removes a <tt>VisualComponentResolveListener</tt> from this video
+ * telephony operation set, which was previously added in order to receive
+ * notifications when visual/video <tt>Component</tt>s are being resolved to
+ * be corresponding to a particular <tt>ConferenceMember</tt>.
+ *
+ * @param callPeer the <tt>CallPeer</tt>, which visual components we're
+ * listening to
+ * @param listener the <tt>VisualComponentResolveListener</tt> to be
+ * removed
+ */
+ @SuppressWarnings("unchecked") // work with MediaAware* in media package
+ public void removeVisualComponentResolveListener(
+ CallPeer callPeer,
+ VisualComponentResolveListener listener)
+ {
+ ((W)callPeer).getMediaHandler().removeVisualComponentResolveListener(
+ listener);
+ }
}
diff --git a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java
index a38b332..3affd16 100644
--- a/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java
+++ b/src/net/java/sip/communicator/service/protocol/media/CallPeerMediaHandler.java
@@ -17,6 +17,7 @@ import net.java.sip.communicator.service.neomedia.device.*;
import net.java.sip.communicator.service.neomedia.event.*;
import net.java.sip.communicator.service.neomedia.format.*;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.event.*;
/**
@@ -184,6 +185,18 @@ public abstract class CallPeerMediaHandler
};
/**
+ * The <tt>Object</tt> to synchronize the access to
+ * {@link #localUserAudioLevelListeners}.
+ */
+ private final Object visualComponentResolveSyncRoot = new Object();
+
+ /**
+ * The list of <tt>VisualComponentResolveListener</tt>s interested in
+ * visual component resolve events.
+ */
+ private List<VisualComponentResolveListener> visualComponentResolveListeners;
+
+ /**
* The state of this instance which may be shared with multiple other
* <tt>CallPeerMediaHandler</tt>s.
*/
@@ -1474,4 +1487,100 @@ public abstract class CallPeerMediaHandler
}
}
}
+
+ /**
+ * Adds a specific <tt>VisualComponentResolveListener</tt> to this telephony
+ * in order to receive notifications when visual/video <tt>Component</tt>s
+ * are being resolved to correspond to a particular
+ * <tt>ConferenceMember</tt>.
+ *
+ * @param listener the <tt>VisualComponentResolveListener</tt> to be
+ * notified when visual/video <tt>Component</tt>s are being resolved to
+ * correspond to a particular <tt>ConferenceMember</tt>.
+ */
+ public void addVisualComponentResolveListener(
+ VisualComponentResolveListener listener)
+ {
+ if (listener == null)
+ throw new NullPointerException("listener");
+
+ synchronized (visualComponentResolveSyncRoot)
+ {
+ if ((visualComponentResolveListeners == null)
+ || visualComponentResolveListeners.isEmpty())
+ {
+ visualComponentResolveListeners
+ = new ArrayList<VisualComponentResolveListener>();
+ }
+
+ visualComponentResolveListeners.add(listener);
+ }
+ }
+
+ /**
+ * Removes a <tt>VisualComponentResolveListener</tt> from this video
+ * telephony operation set, which was previously added in order to receive
+ * notifications when visual/video <tt>Component</tt>s are being resolved to
+ * be corresponding to a particular <tt>ConferenceMember</tt>.
+ *
+ * @param listener the <tt>VisualComponentResolveListener</tt> to be
+ * removed
+ */
+ public void removeVisualComponentResolveListener(
+ VisualComponentResolveListener listener)
+ {
+ synchronized (visualComponentResolveSyncRoot)
+ {
+ if ((visualComponentResolveListeners != null)
+ && !visualComponentResolveListeners.isEmpty())
+ {
+ visualComponentResolveListeners.remove(listener);
+ }
+ }
+ }
+
+ /**
+ * Notifies all registered <tt>VisualComponentResolveListener</tt> that a
+ * visual <tt>Component</tt> has been resolved.
+ *
+ * @param visualComponent the visual <tt>Component</tt> that has been
+ * resolved
+ * @param conferenceMember the resolved <tt>ConferenceMember</tt>
+ */
+ public void fireVisualComponentResolveEvent(
+ Component visualComponent,
+ ConferenceMember conferenceMember)
+ {
+ List<VisualComponentResolveListener> visualComponentResolveListeners;
+
+ synchronized (visualComponentResolveSyncRoot)
+ {
+ /*
+ * Since the localUserAudioLevelListeners field of this
+ * MediaAwareCall is implemented as a copy-on-write storage, just
+ * get a reference to it and it should be safe to iterate over it
+ * without ConcurrentModificationExceptions.
+ */
+ visualComponentResolveListeners
+ = this.visualComponentResolveListeners;
+ }
+
+ if (visualComponentResolveListeners != null)
+ {
+ /*
+ * Iterate over localUserAudioLevelListeners using an index rather
+ * than an Iterator in order to try to reduce the number of
+ * allocations (as the number of audio level changes is expected to
+ * be very large).
+ */
+ int visualComponentResolveListenerCount
+ = visualComponentResolveListeners.size();
+
+ for(int i = 0; i < visualComponentResolveListenerCount; i++)
+ visualComponentResolveListeners.get(i).visualComponentResolved(
+ new VisualComponentResolveEvent(this,
+ visualComponent,
+ conferenceMember));
+ }
+ }
}