Works on fixing issues with Jitsi VideoBridge telephony conferencing.

cusax-fix
Lyubomir Marinov 13 years ago
parent e1b4deac80
commit 7c06bcf4f8

@ -105,8 +105,11 @@ public ConferenceFocusPanel(
addFocusPeerPanel();
this.focusPeer.addCallPeerConferenceListener(focusPeerListener);
this.focusPeer.addConferenceMembersSoundLevelListener(
focusPeerListener);
if (ConferencePeerPanel.isSoundLevelIndicatorEnabled())
{
this.focusPeer.addConferenceMembersSoundLevelListener(
focusPeerListener);
}
for (ConferenceMember conferenceMember
: this.focusPeer.getConferenceMembers())
@ -565,11 +568,12 @@ public void soundLevelChanged(ConferenceMembersSoundLevelEvent ev)
Map<ConferenceMember, Integer> levels = ev.getLevels();
// focusPeerPanel
String address = focusPeerPanel.getCallPeerContactAddress();
for(Map.Entry<ConferenceMember, Integer> e : levels.entrySet())
{
ConferenceMember key = e.getKey();
Integer value = e.getValue();
String address = focusPeerPanel.getCallPeerContactAddress();
if(CallManager.addressesAreEqual(key.getAddress(), address))
{

@ -8,6 +8,7 @@
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
@ -27,8 +28,9 @@
import org.jitsi.service.resources.*;
/**
* The <tt>ConferencePeerPanel</tt> renders a single <tt>ConferencePeer</tt>,
* which is not a conference focus.
* Depicts a single <tt>CallPeer</tt> who participates in a telephony conference
* and is not a focus or the local user/peer (identified by a specific
* <tt>Call</tt> instance).
*
* @author Yana Stamcheva
* @author Lyubomir Marinov
@ -90,23 +92,17 @@ public class ConferencePeerPanel
/**
* The <tt>SoundLevelListener</tt> which listens to the changes in the
* audio/sound level of the model of this instance. (If {@link #callPeer} is
* non-<tt>null</tt>, <tt>callPeer</tt> is the model of this instance.)
* audio/sound level of the model of this instance. If {@link #callPeer} is
* non-<tt>null</tt>, <tt>callPeer</tt> is the model of this instance i.e.
* <tt>soundLevelListener</tt> will be added to the audio stream of
* <tt>callPeer</tt> and will listen to local calculations of the audio
* levels of the remote peer; otherwise, {@link #call} is the model of this
* instance i.e. <tt>soundLevelListener</tt> will be added to <tt>call</tt>
* and will listen to local calculations of the audio levels of the local
* peer.
*/
private final SoundLevelListener soundLevelListener
= new SoundLevelListener()
{
/**
* Updates the sound level bar upon stream sound level changes.
*
* {@inheritDoc}
*/
public void soundLevelChanged(Object source, int level)
{
if (source.equals(participant))
updateSoundBar(level);
}
};
private final SoundLevelListenerImpl soundLevelListener
= new SoundLevelListenerImpl();
/**
* Initializes a new <tt>ConferencePeerPanel</tt> which is to depict the
@ -164,13 +160,8 @@ public ConferencePeerPanel(
resources.getColor(
"service.gui.CALL_LOCAL_USER_BACKGROUND")));
if(!GuiActivator.getConfigurationService().getBoolean(
"net.java.sip.communicator.impl.gui.main.call."
+ "DISABLE_SOUND_LEVEL_INDICATORS",
false))
{
if(isSoundLevelIndicatorEnabled())
call.addLocalUserSoundLevelListener(soundLevelListener);
}
}
/**
@ -246,13 +237,8 @@ public ConferencePeerPanel(
callPeerAdapter = new CallPeerAdapter(this.callPeer, this);
if(!GuiActivator.getConfigurationService().getBoolean(
"net.java.sip.communicator.impl.gui.main.call."
+ "DISABLE_SOUND_LEVEL_INDICATORS",
false))
{
if(isSoundLevelIndicatorEnabled())
this.callPeer.addStreamSoundLevelListener(soundLevelListener);
}
}
/**
@ -263,7 +249,11 @@ public void dispose()
if (callPeerAdapter != null)
callPeerAdapter.dispose();
if (callPeer != null)
{
callPeer.removeConferenceMembersSoundLevelListener(
soundLevelListener);
callPeer.removeStreamSoundLevelListener(soundLevelListener);
}
if (call != null)
call.removeLocalUserSoundLevelListener(soundLevelListener);
}
@ -362,6 +352,24 @@ public boolean isLocalVideoVisible()
return false;
}
/**
* Determines whether the indicator which depicts the sound/audio levels (of
* the local or remote peer in a call) is to be enabled. For example, the
* indicator may be disabled for performance-related reasons.
*
* @return <tt>true</tt> if the indicator which depicts the sound/audio
* levels (of the local or remote peer in a call) is to be enabled;
* otherwise, <tt>false</tt>
*/
static boolean isSoundLevelIndicatorEnabled()
{
return
!GuiActivator.getConfigurationService().getBoolean(
"net.java.sip.communicator.impl.gui.main.call"
+ ".DISABLE_SOUND_LEVEL_INDICATORS",
false);
}
/**
* Reloads style information.
*/
@ -752,4 +760,47 @@ public void componentResized(ComponentEvent e)
});
}
}
/**
* Implements the various types of listeners which get notified about
* changes in the sound/audio levels of the model of this
* <tt>ConferencePeerPanel</tt> and updates its sound level indicator.
*/
private class SoundLevelListenerImpl
implements ConferenceMembersSoundLevelListener,
SoundLevelListener
{
/**
* {@inheritDoc}
*/
public void soundLevelChanged(ConferenceMembersSoundLevelEvent ev)
{
/*
* If the callPeer depicted by this ConferencePeerPanel instance is
* represented as a ConferenceMember, update the sound level
* indicator of this ConferencePeerPanel instance with the specified
* sound level (value).
*/
for (Map.Entry<ConferenceMember,Integer> e
: ev.getLevels().entrySet())
{
if (CallManager.addressesAreEqual(
e.getKey().getAddress(),
callPeer.getAddress()))
{
updateSoundBar(e.getValue());
break;
}
}
}
/**
* {@inheritDoc}
*/
public void soundLevelChanged(Object source, int level)
{
if (source.equals(participant))
updateSoundBar(level);
}
}
}

@ -91,6 +91,11 @@ public boolean addContent(Content content)
return contents.contains(content) ? false : contents.add(content);
}
/**
* Returns an XML <tt>String</tt> representation of this <tt>IQ</tt>.
*
* @return an XML <tt>String</tt> representation of this <tt>IQ</tt>
*/
public String getChildElementXML()
{
StringBuilder xml = new StringBuilder();
@ -120,6 +125,16 @@ public String getChildElementXML()
return xml.toString();
}
/**
* Returns a <tt>Content</tt> from the list of <tt>Content</tt>s of this
* <tt>conference</tt> IQ which has a specific name. If no such
* <tt>Content</tt> exists, returns <tt>null</tt>.
*
* @param contentName the name of the <tt>Content</tt> to be returned
* @return a <tt>Content</tt> from the list of <tt>Content</tt>s of this
* <tt>conference</tt> IQ which has the specified <tt>contentName</tt> if
* such a <tt>Content</tt> exists; otherwise, <tt>null</tt>
*/
public Content getContent(String contentName)
{
for (Content content : getContents())
@ -128,6 +143,13 @@ public Content getContent(String contentName)
return null;
}
/**
* Returns a list of the <tt>Content</tt>s included into this
* <tt>conference</tt> IQ.
*
* @return an unmodifiable <tt>List</tt> of the <tt>Content</tt>s included
* into this <tt>conference</tt> IQ
*/
public List<Content> getContents()
{
return Collections.unmodifiableList(contents);
@ -143,6 +165,17 @@ public String getID()
return id;
}
/**
* Returns a <tt>Content</tt> from the list of <tt>Content</tt>s of this
* <tt>conference</tt> IQ which has a specific name. If no such
* <tt>Content</tt> exists at the time of the invocation of the method,
* initializes a new <tt>Content</tt> instance with the specified
* <tt>contentName</tt> and includes it into this <tt>conference</tt> IQ.
*
* @param contentName the name of the <tt>Content</tt> to be returned
* @return a <tt>Content</tt> from the list of <tt>Content</tt>s of this
* <tt>conference</tt> IQ which has the specified <tt>contentName</tt>
*/
public Content getOrCreateContent(String contentName)
{
Content content = getContent(contentName);
@ -349,6 +382,14 @@ public int getExpire()
return expire;
}
/**
* Gets the IP address (as a <tt>String</tt> value) of the host on which
* the <tt>channel</tt> represented by this instance has been allocated.
*
* @return a <tt>String</tt> value which represents the IP address of
* the host on which the <tt>channel</tt> represented by this instance
* has been allocated
*/
public String getHost()
{
return host;
@ -364,16 +405,38 @@ public String getID()
return id;
}
/**
* Gets a list of <tt>payload-type</tt> elements defined by XEP-0167:
* Jingle RTP Sessions added to this <tt>channel</tt>.
*
* @return an unmodifiable <tt>List</tt> of <tt>payload-type</tt>
* elements defined by XEP-0167: Jingle RTP Sessions added to this
* <tt>channel</tt>
*/
public List<PayloadTypePacketExtension> getPayloadTypes()
{
return Collections.unmodifiableList(payloadTypes);
}
/**
* Gets the port which has been allocated to this <tt>channel</tt> for
* the purposes of transmitting RTCP packets.
*
* @return the port which has been allocated to this <tt>channel</tt>
* for the purposes of transmitting RTCP packets
*/
public int getRTCPPort()
{
return rtcpPort;
}
/**
* Gets the port which has been allocated to this <tt>channel</tt> for
* the purposes of transmitting RTP packets.
*
* @return the port which has been allocated to this <tt>channel</tt>
* for the purposes of transmitting RTP packets
*/
public int getRTPPort()
{
return rtpPort;
@ -472,6 +535,14 @@ public void setExpire(int expire)
this.expire = expire;
}
/**
* Sets the IP address (as a <tt>String</tt> value) of the host on which
* the <tt>channel</tt> represented by this instance has been allocated.
*
* @param host a <tt>String</tt> value which represents the IP address
* of the host on which the <tt>channel</tt> represented by this
* instance has been allocated
*/
public void setHost(String host)
{
this.host = host;
@ -487,11 +558,25 @@ public void setID(String id)
this.id = id;
}
/**
* Sets the port which has been allocated to this <tt>channel</tt> for
* the purposes of transmitting RTCP packets.
*
* @param rtcpPort the port which has been allocated to this
* <tt>channel</tt> for the purposes of transmitting RTCP packets
*/
public void setRTCPPort(int rtcpPort)
{
this.rtcpPort = rtcpPort;
}
/**
* Sets the port which has been allocated to this <tt>channel</tt> for
* the purposes of transmitting RTP packets.
*
* @param rtpPort the port which has been allocated to this
* <tt>channel</tt> for the purposes of transmitting RTP packets
*/
public void setRTPPort(int rtpPort)
{
this.rtpPort = rtpPort;
@ -515,6 +600,14 @@ public void setSSRCs(long[] ssrcs)
: ssrcs.clone();
}
/**
* Appends the XML <tt>String</tt> representation of this
* <tt>Channel</tt> to a specific <tt>StringBuilder</tt>.
*
* @param xml the <tt>StringBuilder</tt> to which the XML
* <tt>String</tt> representation of this <tt>Channel</tt> is to be
* appended
*/
public void toXML(StringBuilder xml)
{
xml.append('<').append(ELEMENT_NAME);
@ -639,6 +732,18 @@ public Content(String name)
setName(name);
}
/**
* Adds a specific <tt>Channel</tt> to the list of <tt>Channel</tt>s
* included into this <tt>Content</tt>.
*
* @param channel the <tt>Channel</tt> to be included into this
* <tt>Content</tt>
* @return <tt>true</tt> if the list of <tt>Channel</tt>s included into
* this <tt>Content</tt> was modified as a result of the execution of
* the method; otherwise, <tt>false</tt>
* @throws NullPointerException if the specified <tt>channel</tt> is
* <tt>null</tt>
*/
public boolean addChannel(Channel channel)
{
if (channel == null)
@ -647,11 +752,32 @@ public boolean addChannel(Channel channel)
return channels.contains(channel) ? false : channels.add(channel);
}
/**
* Gets the <tt>Channel</tt> at a specific index/position within the
* list of <tt>Channel</tt>s included in this <tt>Content</tt>.
*
* @param channelIndex the index/position within the list of
* <tt>Channel</tt>s included in this <tt>Content</tt> of the
* <tt>Channel</tt> to be returned
* @return the <tt>Channel</tt> at the specified <tt>channelIndex</tt>
* within the list of <tt>Channel</tt>s included in this
* <tt>Content</tt>
*/
public Channel getChannel(int channelIndex)
{
return getChannels().get(channelIndex);
}
/**
* Gets a <tt>Channel</tt> which is included into this <tt>Content</tt>
* and which has a specific ID.
*
* @param channelID the ID of the <tt>Channel</tt> included into this
* <tt>Content</tt> to be returned
* @return the <tt>Channel</tt> which is included into this
* <tt>Content</tt> and which has the specified <tt>channelID</tt> if
* such a <tt>Channel</tt> exists; otherwise, <tt>null</tt>
*/
public Channel getChannel(String channelID)
{
for (Channel channel : getChannels())
@ -660,11 +786,25 @@ public Channel getChannel(String channelID)
return null;
}
/**
* Gets the number of <tt>Channel</tt>s included into/associated with
* this <tt>Content</tt>.
*
* @return the number of <tt>Channel</tt>s included into/associated with
* this <tt>Content</tt>
*/
public int getChannelCount()
{
return getChannels().size();
}
/**
* Gets a list of the <tt>Channel</tt> included into/associated with
* this <tt>Content</tt>.
*
* @return an unmodifiable <tt>List</tt> of the <tt>Channel</tt>s
* included into/associated with this <tt>Content</tt>
*/
public List<Channel> getChannels()
{
return Collections.unmodifiableList(channels);
@ -680,6 +820,16 @@ public String getName()
return name;
}
/**
* Removes a specific <tt>Channel</tt> from the list of
* <tt>Channel</tt>s included into this <tt>Content</tt>.
*
* @param channel the <tt>Channel</tt> to be excluded from this
* <tt>Content</tt>
* @return <tt>true</tt> if the list of <tt>Channel</tt>s included into
* this <tt>Content</tt> was modified as a result of the execution of
* the method; otherwise, <tt>false</tt>
*/
public boolean removeChannel(Channel channel)
{
return channels.remove(channel);
@ -701,6 +851,14 @@ public void setName(String name)
this.name = name;
}
/**
* Appends the XML <tt>String</tt> representation of this
* <tt>Content</tt> to a specific <tt>StringBuilder</tt>.
*
* @param xml the <tt>StringBuilder</tt> to which the XML
* <tt>String</tt> representation of this <tt>Content</tt> is to be
* appended
*/
public void toXML(StringBuilder xml)
{
xml.append('<').append(ELEMENT_NAME);

@ -32,6 +32,14 @@ public CobriStreamConnector(StreamConnector streamConnector)
super(streamConnector);
}
/**
* {@inheritDoc}
*
* Overrides {@link StreamConnectorDelegate#close()} in order to prevent the
* closing of the <tt>StreamConnector</tt> wrapped by this instance because
* the latter is shared and it is not clear whether no
* <tt>TransportManager</tt> is using it.
*/
@Override
public void close()
{
@ -41,6 +49,14 @@ public void close()
*/
}
/**
* {@inheritDoc}
*
* Invokes {@link #close()} on this instance when it is clear that no
* <tt>TransportManager</tt> is using it in order to release the resources
* allocated by this instance throughout its life time (that need explicit
* disposal).
*/
@Override
protected void finalize()
throws Throwable

@ -235,25 +235,39 @@ public void propertyChange(PropertyChangeEvent evt)
private final VideoListener videoStreamVideoListener
= new VideoListener()
{
public void videoAdded(VideoEvent event)
/**
* Notifies this <tt>VideoListener</tt> about a specific
* <tt>VideoEvent</tt>. Fires a new <tt>VideoEvent</tt> which has
* this <tt>CallPeerMediaHandler</tt> as its source and carries the
* same information as the specified <tt>ev</tt> i.e. translates the
* specified <tt>ev</tt> into a <tt>VideoEvent</tt> fired by this
* <tt>CallPeerMediaHandler</tt>.
*
* @param ev the <tt>VideoEvent</tt> to notify this
* <tt>VideoListener</tt> about
*/
private void onVideoEvent(VideoEvent ev)
{
VideoEvent clone = event.clone(CallPeerMediaHandler.this);
VideoEvent clone = ev.clone(CallPeerMediaHandler.this);
fireVideoEvent(clone);
if (clone.isConsumed())
event.consume();
ev.consume();
}
public void videoAdded(VideoEvent ev)
{
onVideoEvent(ev);
}
public void videoRemoved(VideoEvent event)
public void videoRemoved(VideoEvent ev)
{
// Forwarded in the same way as VIDEO_ADDED.
videoAdded(event);
onVideoEvent(ev);
}
public void videoUpdate(VideoEvent event)
public void videoUpdate(VideoEvent ev)
{
// Forwarded in the same way as VIDEO_ADDED.
videoAdded(event);
onVideoEvent(ev);
}
};
@ -779,7 +793,7 @@ public void removeVideoListener(VideoListener listener)
* <tt>null</tt> if we are trying to remove it.
*/
public void setLocalUserAudioLevelListener(
SimpleAudioLevelListener listener)
SimpleAudioLevelListener listener)
{
synchronized(localAudioLevelListenerLock)
{
@ -803,7 +817,6 @@ public void setLocalUserAudioLevelListener(
*
* @param listener the <tt>SimpleAudioLevelListener</tt> to add or
* <tt>null</tt> if we are trying to remove it.
*
*/
public void setStreamAudioLevelListener(SimpleAudioLevelListener listener)
{
@ -826,22 +839,21 @@ public void setStreamAudioLevelListener(SimpleAudioLevelListener listener)
* receiving notifications for changes in the audio levels of the remote
* participants that our peer is mixing.
*
* @param csrcAudioLevelListener the <tt>CsrcAudioLevelListener</tt> to set
* to our audio streams.
* @param listener the <tt>CsrcAudioLevelListener</tt> to set to our audio
* stream.
*/
public void setCsrcAudioLevelListener(
CsrcAudioLevelListener csrcAudioLevelListener)
public void setCsrcAudioLevelListener(CsrcAudioLevelListener listener)
{
synchronized(csrcAudioLevelListenerLock)
{
this.csrcAudioLevelListener = csrcAudioLevelListener;
this.csrcAudioLevelListener = listener;
MediaStream audioStream = getStream(MediaType.AUDIO);
if (audioStream != null)
{
((AudioMediaStream) audioStream).setCsrcAudioLevelListener(
csrcAudioLevelListener);
listener);
}
}
}

@ -134,9 +134,11 @@ protected void addCallPeer(T callPeer)
synchronized(localUserAudioLevelListenersSyncRoot)
{
// if there's someone listening for audio level events then they'd
// also like to know about the new peer. make sure always the first
// element is the one to listen for local audio events
/*
* If there's someone listening for audio level events, then they'd
* also like to know about the new peer. Make sure the first element
* is always the one to listen for local audio events.
*/
List<T> callPeers = getCallPeerList();
if ((callPeers.size() == 1) && callPeers.get(0).equals(callPeer))
@ -150,17 +152,16 @@ protected void addCallPeer(T callPeer)
}
/**
* Removes <tt>callPeer</tt> from the list of peers in this
* call. The method has no effect if there was no such peer in the
* call.
* Removes <tt>callPeer</tt> from the list of peers in this call. The method
* has no effect if there was no such peer in the call.
*
* @param evt the event containing the <tt>CallPeer</tt> leaving the call;
* also we can obtain the reason for the <tt>CallPeerChangeEvent</tt> if
* any. Use the event as cause for the call state change event..
* @param ev the event containing the <tt>CallPeer</tt> leaving the call and
* the reason (if any) for the <tt>CallPeerChangeEvent</tt>. Use the event
* as the cause for the call state change event.
*/
@SuppressWarnings("unchecked")
private void removeCallPeer(CallPeerChangeEvent evt)
{
@SuppressWarnings("unchecked")
T callPeer = (T) evt.getSourceCallPeer();
if (!doRemoveCallPeer(callPeer))
@ -180,9 +181,11 @@ private void removeCallPeer(CallPeerChangeEvent evt)
if(!callPeers.isEmpty())
{
callPeers.get(0).getMediaHandler()
.setLocalUserAudioLevelListener(
localAudioLevelDelegator);
callPeers
.get(0)
.getMediaHandler()
.setLocalUserAudioLevelListener(
localAudioLevelDelegator);
}
}
@ -356,19 +359,21 @@ public void addLocalUserSoundLevelListener(SoundLevelListener l)
if ((localUserAudioLevelListeners == null)
|| localUserAudioLevelListeners.isEmpty())
{
//if this is the first listener that's being registered with
//us, we also need to register ourselves as an audio level
//listener with the media handler. we do this so that audio
//level would only be calculated if anyone is interested in
//receiving them.
/*
* If this is the first listener that's being registered, we
* also need to register ourselves as an audio level listener
* with the MediaHandler. We do this so that audio level would
* only be calculated if anyone is interested in receiving them.
*/
Iterator<T> callPeerIter = getCallPeers();
while (callPeerIter.hasNext())
{
callPeerIter.next()
.getMediaHandler()
.setLocalUserAudioLevelListener(
localAudioLevelDelegator);
callPeerIter
.next()
.getMediaHandler()
.setLocalUserAudioLevelListener(
localAudioLevelDelegator);
}
}
@ -425,9 +430,10 @@ public void removeLocalUserSoundLevelListener(SoundLevelListener l)
while (callPeerIter.hasNext())
{
callPeerIter.next()
.getMediaHandler()
.setLocalUserAudioLevelListener(null);
callPeerIter
.next()
.getMediaHandler()
.setLocalUserAudioLevelListener(null);
}
}
}

@ -89,8 +89,10 @@ public void securityMessageReceived(
String message, String i18nMessage, int severity)
{
for (SrtpListener listener : getSrtpListeners())
{
listener.securityMessageReceived(
message, i18nMessage, severity);
}
}
public void securityTimeout(int sessionType)

Loading…
Cancel
Save