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 7653708d5..d2805480d 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandler.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerMediaHandler.java
@@ -54,6 +54,11 @@ public class CallPeerMediaHandler
*/
public static final String AUDIO_REMOTE_SSRC = "AUDIO_REMOTE_SSRC";
+ /**
+ * The constant which signals that a SSRC value is unknown.
+ */
+ static final long SSRC_UNKNOWN = -1;
+
/**
* The name of the CallPeerMediaHandler property which specifies
* the local SSRC of its video MediaStream.
@@ -131,12 +136,12 @@ public class CallPeerMediaHandler
/**
* The last-known local SSRC of {@link #audioStream}.
*/
- private long audioLocalSSRC = -1;
+ private long audioLocalSSRC = SSRC_UNKNOWN;
/**
* The last-known remote SSRC of {@link #audioStream}.
*/
- private long audioRemoteSSRC = -1;
+ private long audioRemoteSSRC = SSRC_UNKNOWN;
/**
* The RTP/RTCP socket couple that this media handler should use to send
@@ -152,12 +157,12 @@ public class CallPeerMediaHandler
/**
* The last-known local SSRC of {@link #videoStream}.
*/
- private long videoLocalSSRC = -1;
+ private long videoLocalSSRC = SSRC_UNKNOWN;
/**
* The last-known remote SSRC of {@link #videoStream}.
*/
- private long videoRemoteSSRC = -1;
+ private long videoRemoteSSRC = SSRC_UNKNOWN;
/**
* The PropertyChangeListener which listens to changes in the
@@ -1642,6 +1647,18 @@ private void setAudioRemoteSSRC(long audioRemoteSSRC)
}
}
+ /**
+ * Gets the last-known remote SSRC of the audio MediaStream of this
+ * instance.
+ *
+ * @return the last-known remote SSRC of the audio MediaStream of
+ * this instance
+ */
+ long getAudioRemoteSSRC()
+ {
+ return audioRemoteSSRC;
+ }
+
/**
* Sets the RTP media stream that this instance uses to stream audio to a
* specific AudioMediaStream.
@@ -1676,7 +1693,7 @@ private void setAudioStream(AudioMediaStream audioStream)
audioRemoteSSRC = this.audioStream.getRemoteSourceID();
}
else
- audioLocalSSRC = audioRemoteSSRC = -1;
+ audioLocalSSRC = audioRemoteSSRC = SSRC_UNKNOWN;
setAudioLocalSSRC(audioLocalSSRC);
setAudioRemoteSSRC(audioRemoteSSRC);
@@ -1772,7 +1789,7 @@ private void setVideoStream(VideoMediaStream videoStream)
newVisualComponent = this.videoStream.getVisualComponent();
}
else
- videoLocalSSRC = videoRemoteSSRC = -1;
+ videoLocalSSRC = videoRemoteSSRC = SSRC_UNKNOWN;
setVideoLocalSSRC(videoLocalSSRC);
setVideoRemoteSSRC(videoRemoteSSRC);
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 2fc3d78c3..0a737a3fb 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/CallPeerSipImpl.java
@@ -163,7 +163,7 @@ public CallPeerSipImpl(Address peerAddress,
setJainSipProvider(sourceProvider);
//create the uid
- this.peerID = String.valueOf( System.currentTimeMillis())
+ this.peerID = String.valueOf(System.currentTimeMillis())
+ String.valueOf(hashCode());
// we listen fr events when the call will become focus or not
@@ -1809,20 +1809,20 @@ public void removeConferenceMembersSoundLevelListener(
*/
public void audioLevelsReceived(long[][] audioLevels)
{
- if ( getConferenceMemberCount() == 0 )
+ if (getConferenceMemberCount() == 0)
return;
Map levelsMap
= new HashMap();
- for (int i = 0; i < audioLevels.length; i++ )
+ for (int i = 0; i < audioLevels.length; i++)
{
ConferenceMember mmbr = findConferenceMember(audioLevels[i][0]);
if (mmbr == null)
continue;
-
- levelsMap.put(mmbr, (int)audioLevels[i][1]);
+ else
+ levelsMap.put(mmbr, (int)audioLevels[i][1]);
}
ConferenceMembersSoundLevelEvent evt
@@ -1830,11 +1830,12 @@ public void audioLevelsReceived(long[][] audioLevels)
synchronized( conferenceMemberAudioLevelListeners)
{
- for (int i = 0; i < conferenceMemberAudioLevelListeners.size(); i++)
- {
- conferenceMemberAudioLevelListeners.get(i)
- .soundLevelChanged(evt);
- }
+ int conferenceMemberAudioLevelListenerCount
+ = conferenceMemberAudioLevelListeners.size();
+
+ for (int i = 0; i < conferenceMemberAudioLevelListenerCount; i++)
+ conferenceMemberAudioLevelListeners
+ .get(i).soundLevelChanged(evt);
}
}
@@ -1886,11 +1887,10 @@ public void securityTurnedOff(int sessionType)
// If this event has been triggered because of a call end event and the
// call is already ended we don't need to alert the user for
// security off.
- if(getCall() != null
- && !getCall().getCallState().equals(CallState.CALL_ENDED))
- {
+ Call call = getCall();
+
+ if((call != null) && !call.getCallState().equals(CallState.CALL_ENDED))
fireCallPeerSecurityOffEvent(sessionType);
- }
}
/**
@@ -1931,7 +1931,7 @@ public void conferenceFocusChanged(CallPeerConferenceEvent evt)
*/
public void conferenceMemberAdded(CallPeerConferenceEvent conferenceEvent)
{
- if (isConferenceFocus() && getConferenceMemberCount() >= 3)
+ if (getConferenceMemberCount() > 2)
{
// this peer is now a conference focus with more than three
// participants. This means that the this peer is mixing and sending
@@ -1980,6 +1980,29 @@ public void conferenceMemberRemoved(CallPeerConferenceEvent conferenceEvent)
*/
public void audioLevelChanged(int newLevel)
{
+ /*
+ * If we're in a conference in which this CallPeer is the focus and
+ * we're the only member in it besides the focus, we will not receive
+ * audio levels in the RTP and our media will instead measure the audio
+ * levels of the received media. In order to make the UI oblivious of
+ * the difference, we have to translate the event to the appropriate
+ * type of listener.
+ */
+ if (isConferenceFocus() && (getConferenceMemberCount() < 3))
+ {
+ long audioRemoteSSRC = getMediaHandler().getAudioRemoteSSRC();
+
+ if (audioRemoteSSRC != CallPeerMediaHandler.SSRC_UNKNOWN)
+ {
+ long[][] audioLevels = new long[1][2];
+ audioLevels[0][0] = audioRemoteSSRC;
+ audioLevels[0][1] = newLevel;
+
+ audioLevelsReceived(audioLevels);
+ return;
+ }
+ }
+
synchronized( streamAudioLevelListeners )
{
if (streamAudioLevelListeners.size() > 0)
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java b/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java
index 0a7e129f3..80ee2d7dd 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java
+++ b/src/net/java/sip/communicator/service/protocol/AbstractCallPeer.java
@@ -501,7 +501,7 @@ public ConferenceMember[] getConferenceMembers()
synchronized (this.conferenceMembers)
{
- int conferenceMemberCount = this.conferenceMembers.size();
+ int conferenceMemberCount = getConferenceMemberCount();
if (conferenceMemberCount <= 0)
conferenceMembers = NO_CONFERENCE_MEMBERS;
@@ -523,7 +523,7 @@ public ConferenceMember[] getConferenceMembers()
*/
public int getConferenceMemberCount()
{
- return conferenceMembers.size();
+ return isConferenceFocus() ? conferenceMembers.size() : 0;
}
/**
@@ -705,16 +705,17 @@ protected void fireCallPeerConferenceEvent(
*/
protected ConferenceMember findConferenceMember(long ssrc)
{
- synchronized ( conferenceMembers)
+ synchronized (conferenceMembers)
{
- for ( int i = 0; i < conferenceMembers.size(); i++)
+ int conferenceMemberCount = conferenceMembers.size();
+
+ for (int i = 0; i < conferenceMemberCount; i++)
{
ConferenceMember mmbr = conferenceMembers.get(i);
if (mmbr.getSSRC() == ssrc)
return mmbr;
}
-
return null;
}
}