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; } }