Commits work in progress on refactorying the call-related user interface for the purposes of audio and video telephony conferencing over single or multiple protocols and Jitsi VideoBridge.

cusax-fix
Lyubomir Marinov 13 years ago
parent f7f9ef15e7
commit 055882473a

@ -722,6 +722,7 @@ private void doUpdateViewFromModelInEventDispatchThread()
boolean isConference = isConference();
boolean isVideo = CallManager.isVideoStreaming(callConference);
CallPeer callPeer = null;
boolean validateAndRepaint = false;
if (callPanel != null)
{
@ -770,6 +771,7 @@ private void doUpdateViewFromModelInEventDispatchThread()
if (removeCallPanel)
{
remove(callPanel);
validateAndRepaint = true;
try
{
((CallRenderer) callPanel).dispose();
@ -814,15 +816,39 @@ private void doUpdateViewFromModelInEventDispatchThread()
}
}
if (callPanel != null)
{
add(callPanel, BorderLayout.CENTER);
validateAndRepaint = true;
}
}
/*
* The center of this view is occupied by callPanel and we have just
* updated it. The bottom of this view is dedicated to settingsPanel so
* we have to update it as well.
*/
updateSettingsPanelInEventDispatchThread(false);
try
{
/*
* The center of this view is occupied by callPanel and we have just
* updated it. The bottom of this view is dedicated to settingsPanel
* so we have to update it as well.
*/
updateSettingsPanelInEventDispatchThread(false);
}
finally
{
/*
* It seems that AWT/Swing does not validate and/or repaint this
* Container (enough) and, consequently, its display may not update
* itself with an up-to-date drawing of the current callPanel.
*/
if (validateAndRepaint)
{
if (isDisplayable())
{
validate();
repaint();
}
else
doLayout();
}
}
}
/**

@ -1161,9 +1161,6 @@ private void updateViewFromModelInEventDispatchThread()
}
this.localVideo = localVideo;
}
center.validate();
center.repaint();
}
}
}

@ -96,17 +96,17 @@ protected void callConferenceCallsPropertyChange(PropertyChangeEvent ev)
}
/**
* Notifies this instance about a change in the value of the
* <tt>videoSsrc</tt> property of a <tt>ConferenceMember</tt>. Changing the
* value in question means that a visual <tt>Component</tt> displaying video
* may be associated or dissociated with the <tt>ConferenceMember</tt>.
* Notifies this instance about a change in the value of a video-related
* property of a <tt>ConferenceMember</tt>. Changing such a value means that
* a visual <tt>Component</tt> displaying video may be associated or
* dissociated with the <tt>ConferenceMember</tt>.
*
* @param ev a <tt>PropertyChangeEvent</tt> which specifies the
* <tt>ConferenceMember</tt> whose <tt>videoSsrc</tt> property value changed
* and the old and new values of the property in question
* <tt>ConferenceMember</tt> whose video-related property value changed, the
* name of the property whose value changed, and the old and new values of
* the property in question
*/
protected void conferenceMemberVideoSsrcPropertyChange(
PropertyChangeEvent ev)
protected void conferenceMemberVideoPropertyChange(PropertyChangeEvent ev)
{
notifyObservers(ev);
}
@ -488,10 +488,12 @@ public void propertyChange(PropertyChangeEvent ev)
}
}
else if (ConferenceMember.VIDEO_SSRC_PROPERTY_NAME.equals(
propertyName))
propertyName)
|| ConferenceMember.VIDEO_STATUS_PROPERTY_NAME.equals(
propertyName))
{
if (ev.getSource() instanceof ConferenceMember)
conferenceMemberVideoSsrcPropertyChange(ev);
conferenceMemberVideoPropertyChange(ev);
}
else if (OperationSetVideoTelephony.LOCAL_VIDEO_STREAMING.equals(
propertyName))

@ -326,14 +326,16 @@ protected void updateViewFromModel()
/**
* Updates the <tt>ConferenceCallPeerRenderer</tt> which is to depict a
* specific <tt>CallPeer</tt>.
* specific <tt>CallPeer</tt>. Invoked by
* {@link #updateViewFromModelInEventDispatchThread()} in the AWT event
* dispatching thread.
*
* @param callPeer the <tt>CallPeer</tt> whose depicting
* <tt>ConferenceCallPeerPanel</tt> is to be updated. The <tt>null</tt>
* value is used to indicate the local peer.
* @see #updateViewFromModel(ConferenceCallPeerRenderer, CallPeer)
*/
private void updateViewFromModel(CallPeer callPeer)
protected void updateViewFromModel(CallPeer callPeer)
{
ConferenceCallPeerRenderer oldCallPeerPanel
= callPeerPanels.get(callPeer);
@ -399,7 +401,7 @@ protected abstract ConferenceCallPeerRenderer updateViewFromModel(
*/
protected void updateViewFromModelInEventDispatchThread()
{
/* Update the view of the local peer. */
/* Update the view of the local peer/user. */
updateViewFromModel(null);
List<CallPeer> callPeers = callConference.getCallPeers();

@ -66,6 +66,13 @@ public void update(Observable o, Object arg)
*/
private final VideoContainer videoContainer;
/**
* The set of visual <tt>Component</tt>s displaying video streaming between
* the local peer/user and the remote peers which are depicted by this
* instance.
*/
private final Set<Component> videos = new HashSet<Component>();
/**
* Initializes a new <tt>VideoConferenceCallPanel</tt> instance which is to
* be used by a specific <tt>CallPanel</tt> to depict a specific
@ -573,7 +580,28 @@ else if (cmcParticipant == conferenceMember)
{
if (cmc.getParticipant() == conferenceMember)
{
if (cmc.toBeRemoved)
/*
* It is possible to have a ConferenceMember who is
* sending video but we just do not have the SSRC of
* that video to associate the video with the
* ConferenceMember. In such a case, we may be depicting
* the ConferenceMember twice: once with video without a
* ConferenceMember and once with a ConferenceMember
* without video. This will surely be the case at the
* time of this writing with non-focus participants in a
* telephony conference hosted on a Jitsi VideoBridge.
* Such a display is undesirable. If the
* conferenceMember is known to send video, we will not
* display it until we associated it with a video. This
* way, if a ConferenceMember is not sending video, we
* will depict it and we can be sure that no video
* without a ConferenceMember association will be
* depicting it a second time.
*/
if (cmc.toBeRemoved
&& !conferenceMember
.getVideoStatus()
.allowsSending())
{
cmc.setVideo(null);
cmc.toBeRemoved = false;
@ -613,7 +641,6 @@ else if (cmcParticipant == conferenceMember)
}
}
@Override
protected ConferenceCallPeerRenderer updateViewFromModel(
ConferenceCallPeerRenderer callPeerPanel,
CallPeer callPeer)
@ -748,6 +775,96 @@ protected ConferenceCallPeerRenderer updateViewFromModel(
return callPeerPanel;
}
@Override
protected void updateViewFromModelInEventDispatchThread()
{
/*
* Determine the set of visual Components displaying video streaming
* between the local peer/user and the remote peers which are to be
* depicted by this instance.
*/
Component localVideo = null;
Set<Component> videos = new HashSet<Component>();
for (Call call : callConference.getCalls())
{
OperationSetVideoTelephony videoTelephony
= call.getProtocolProvider().getOperationSet(
OperationSetVideoTelephony.class);
if (videoTelephony == null)
continue;
Iterator<? extends CallPeer> callPeerIter = call.getCallPeers();
while (callPeerIter.hasNext())
{
CallPeer callPeer = callPeerIter.next();
if (uiVideoHandler.isLocalVideoVisible()
&& (localVideo == null))
{
try
{
localVideo
= videoTelephony.getLocalVisualComponent(callPeer);
}
catch (OperationFailedException ofe)
{
/*
* We'll just try to get the local video through another
* CallPeer then.
*/
}
if (localVideo != null)
videos.add(localVideo);
}
List<Component> callPeerRemoteVideos
= videoTelephony.getVisualComponents(callPeer);
videos.addAll(callPeerRemoteVideos);
}
}
/*
* Remove the Components of this view which are no longer present in the
* model.
*/
Iterator<Component> thisVideoIter = this.videos.iterator();
while (thisVideoIter.hasNext())
{
Component thisVideo = thisVideoIter.next();
if (!videos.contains(thisVideo))
{
thisVideoIter.remove();
videoContainer.remove(thisVideo);
}
/*
* If a video is known to be depicted by this view and is still
* present in the model, then we could remove it from the set of
* videos present in the model in order to prevent going through the
* procedure of adding it to this view. However, we choose to play
* on the safe side.
*/
}
/*
* Add the Components of the model which are not depicted by this view.
*/
for (Component video : videos)
{
if (!UIVideoHandler2.isAncestor(videoContainer, video))
{
this.videos.add(video);
videoContainer.add(video, VideoLayout.CENTER_REMOTE);
}
}
}
@Override
protected void viewForModelAdded(
ConferenceCallPeerRenderer callPeerPanel,

@ -164,7 +164,7 @@ private List<MediaPacketExtension> getMedia(
= new MediaPacketExtension(Long.toString(i));
long srcId
= remote
? stream.getRemoteSourceID()
? getRemoteSourceID(callPeer, mediaType)
: stream.getLocalSourceID();
if (srcId != -1)
@ -172,7 +172,10 @@ private List<MediaPacketExtension> getMedia(
ext.setType(mediaType.toString());
MediaDirection direction = stream.getDirection();
MediaDirection direction
= remote
? getRemoteDirection(callPeer, mediaType)
: stream.getDirection();
if (direction == null)
direction = MediaDirection.INACTIVE;
@ -290,7 +293,7 @@ private IQ getConferenceInfo(CallPeerJabberImpl callPeer, int version)
iq.setEntity(getBasicTelephony().getProtocolProvider().getOurJID());
iq.setVersion(version);
iq.setState(StateType.full);
iq.setSID(callPeer.getSID());
iq.setSID(callPeerSID);
// conference-description
iq.addExtension(new DescriptionPacketExtension());

@ -453,7 +453,7 @@ private void getMediaXML(
long srcId
= remote
? stream.getRemoteSourceID()
? getRemoteSourceID(callPeer, mediaType)
: stream.getLocalSourceID();
if (srcId != -1)
@ -465,7 +465,10 @@ private void getMediaXML(
append(xml, "</", ELEMENT_SRC_ID, ">");
}
MediaDirection direction = stream.getDirection();
MediaDirection direction
= remote
? getRemoteDirection(callPeer, mediaType)
: stream.getDirection();
if (direction == null)
direction = MediaDirection.INACTIVE;

@ -6,6 +6,9 @@
*/
package net.java.sip.communicator.service.protocol;
import java.util.*;
import org.jitsi.service.neomedia.*;
import org.jitsi.util.event.*;
/**
@ -75,6 +78,12 @@ public class AbstractConferenceMember
*/
private long audioSsrc = -1;
/**
* The status in both directions of the audio RTP stream from the point of
* view of this <tt>ConferenceMember</tt>.
*/
private MediaDirection audioStatus = MediaDirection.INACTIVE;
/**
* The <tt>CallPeer</tt> which is the conference focus of this
* <tt>ConferenceMember</tt>.
@ -98,6 +107,12 @@ public class AbstractConferenceMember
*/
private long videoSsrc = -1;
/**
* The status in both directions of the video RTP stream from the point of
* view of this <tt>ConferenceMember</tt>.
*/
private MediaDirection videoStatus = MediaDirection.INACTIVE;
/**
* Creates an instance of <tt>AbstractConferenceMember</tt> by specifying
* the corresponding <tt>conferenceFocusCallPeer</tt>, to which this member
@ -142,6 +157,14 @@ public long getAudioSsrc()
return audioSsrc;
}
/**
* {@inheritDoc}
*/
public MediaDirection getAudioStatus()
{
return audioStatus;
}
/**
* {@inheritDoc}
*
@ -191,6 +214,56 @@ public long getVideoSsrc()
return videoSsrc;
}
/**
* {@inheritDoc}
*/
public MediaDirection getVideoStatus()
{
return videoStatus;
}
private static long parseMediaSssrc(Object value)
{
long ssrc;
if (value == null)
ssrc = -1;
else if (value instanceof Long)
ssrc = ((Long) value).longValue();
else
{
String str = value.toString();
if ((str == null) || (str.length() == 0))
ssrc = -1;
else
ssrc = Long.parseLong(str);
}
return ssrc;
}
private static MediaDirection parseMediaStatus(Object value)
{
MediaDirection status;
if (value == null)
status = MediaDirection.INACTIVE;
else if (value instanceof MediaDirection)
status = (MediaDirection) value;
else
{
String str = value.toString();
if ((str == null) || (str.length() == 0))
status = MediaDirection.INACTIVE;
else
status = MediaDirection.parseString(str);
}
return status;
}
/**
* Sets the audio SSRC identifier of this member.
*
@ -198,7 +271,41 @@ public long getVideoSsrc()
*/
public void setAudioSsrc(long ssrc)
{
this.audioSsrc = ssrc;
if (this.audioSsrc != ssrc)
{
long oldValue = this.audioSsrc;
this.audioSsrc = ssrc;
firePropertyChange(
AUDIO_SSRC_PROPERTY_NAME,
oldValue, this.audioSsrc);
}
}
/**
* Sets the status in both directions of the audio RTP stream from the point
* of view of this <tt>ConferenceMember</tt>.
*
* @param status the status in both directions of the audio RTP stream from
* the point of view of this <tt>ConferenceMember</tt>. If <tt>null</tt>,
* the method executes as if {@link MediaDirection#INACTIVE}. was specified.
*/
public void setAudioStatus(MediaDirection status)
{
if (status == null)
status = MediaDirection.INACTIVE;
if (this.audioStatus != status)
{
MediaDirection oldValue = this.audioStatus;
this.audioStatus = status;
firePropertyChange(
AUDIO_STATUS_PROPERTY_NAME,
oldValue, this.audioStatus);
}
}
/**
@ -258,6 +365,60 @@ else if (PENDING.equalsIgnoreCase(endpointStatus))
setState(state);
}
public boolean setProperties(Map<String, Object> properties)
{
boolean changed = false;
for (Map.Entry<String, Object> entry : properties.entrySet())
{
String key = entry.getKey();
Object value = entry.getValue();
if (AUDIO_SSRC_PROPERTY_NAME.equals(key))
{
long ssrc = parseMediaSssrc(value);
if (getAudioSsrc() != ssrc)
{
setAudioSsrc(ssrc);
changed = true;
}
}
else if (AUDIO_STATUS_PROPERTY_NAME.equals(key))
{
MediaDirection status = parseMediaStatus(value);
if (!getAudioStatus().equals(status))
{
setAudioStatus(status);
changed = true;
}
}
else if (VIDEO_SSRC_PROPERTY_NAME.equals(key))
{
long ssrc = parseMediaSssrc(value);
if (getVideoSsrc() != ssrc)
{
setVideoSsrc(ssrc);
changed = true;
}
}
else if (VIDEO_STATUS_PROPERTY_NAME.equals(key))
{
MediaDirection status = parseMediaStatus(value);
if (!getVideoStatus().equals(status))
{
setVideoStatus(status);
changed = true;
}
}
}
return changed;
}
/**
* Sets the state of the device and signaling session of this
* <tt>ConferenceMember</tt> in the conference and fires a new
@ -298,4 +459,29 @@ public void setVideoSsrc(long ssrc)
oldValue, this.videoSsrc);
}
}
/**
* Sets the status in both directions of the video RTP stream from the point
* of view of this <tt>ConferenceMember</tt>.
*
* @param status the status in both directions of the video RTP stream from
* the point of view of this <tt>ConferenceMember</tt>. If <tt>null</tt>,
* the method executes as if {@link MediaDirection#INACTIVE}. was specified.
*/
public void setVideoStatus(MediaDirection status)
{
if (status == null)
status = MediaDirection.INACTIVE;
if (this.videoStatus != status)
{
MediaDirection oldValue = this.videoStatus;
this.videoStatus = status;
firePropertyChange(
VIDEO_STATUS_PROPERTY_NAME,
oldValue, this.videoStatus);
}
}
}

@ -8,6 +8,8 @@
import java.beans.*;
import org.jitsi.service.neomedia.*;
/**
* Represents a member and its details in a telephony conference managed by a
* <tt>CallPeer</tt> in its role as a conference focus.
@ -16,6 +18,20 @@
*/
public interface ConferenceMember
{
/**
* The name of the property of <tt>ConferenceMember</tt> which specifies the
* SSRC of the audio content/RTP stream sent by the respective
* <tt>ConferenceMember</tt> in the conference.
*/
public static final String AUDIO_SSRC_PROPERTY_NAME = "audioSsrc";
/**
* The name of the property of <tt>ConferenceMember</tt> which specifies the
* status of the audio RTP stream from the point of view of the
* <tt>ConferenceMember</tt>.
*/
public static final String AUDIO_STATUS_PROPERTY_NAME = "audioStatus";
/**
* The name of the property of <tt>ConferenceMember</tt> which specifies the
* user-friendly display name of the respective <tt>ConferenceMember</tt> in
@ -37,6 +53,13 @@ public interface ConferenceMember
*/
public static final String VIDEO_SSRC_PROPERTY_NAME = "videoSsrc";
/**
* The name of the property of <tt>ConferenceMember</tt> which specifies the
* status of the video RTP stream from the point of view of the
* <tt>ConferenceMember</tt>.
*/
public static final String VIDEO_STATUS_PROPERTY_NAME = "videoStatus";
/**
* Adds a specific <tt>PropertyChangeListener</tt> to the list of
* listeners interested in and notified about changes in the values of the
@ -75,6 +98,16 @@ public interface ConferenceMember
*/
public long getAudioSsrc();
/**
* Gets the status in both directions of the audio RTP stream from the point
* of view of this <tt>ConferenceMember</tt>.
*
* @return a <tt>MediaDIrection</tt> which represents the status in both
* directions of the audio RTP stream from the point of view of this
* <tt>ConferenceMember</tt>
*/
public MediaDirection getAudioStatus();
/**
* Gets the <tt>CallPeer</tt> which is the conference focus of this
* <tt>ConferenceMember</tt>.
@ -115,6 +148,16 @@ public interface ConferenceMember
*/
public long getVideoSsrc();
/**
* Gets the status in both directions of the video RTP stream from the point
* of view of this <tt>ConferenceMember</tt>.
*
* @return a <tt>MediaDIrection</tt> which represents the status in both
* directions of the video RTP stream from the point of view of this
* <tt>ConferenceMember</tt>
*/
public MediaDirection getVideoStatus();
/**
* Removes a specific <tt>PropertyChangeListener</tt> from the list of
* listeners interested in and notified about changes in the values of the

@ -397,23 +397,12 @@ public OperationSetBasicTelephonyT getBasicTelephony()
return basicTelephony;
}
/**
* Reads the text content of the <tt>src-id</tt> XML element of a
* <tt>media</tt> XML element of a specific <tt>endpoint</tt> XML element.
*
* @param endpoint an XML <tt>Node</tt> which represents the
* <tt>endpoint</tt> XML element from which to get the text content of a
* <tt>src-id</tt> XML element of a <tt>media</tt> XML element
* @param mediaType the type of the media to get the <tt>src-id</tt> of
* @return the text content of the <tt>src-id</tt> XML element of the
* <tt>media</tt> XML element of the specified <tt>endpoint</tt> XML element
* if any; otherwise, <tt>null</tt>
*/
private String getEndpointMediaSrcId(Node endpoint, MediaType mediaType)
private void getEndpointMediaProperties(
Node endpoint,
Map<String, Object> properties)
{
NodeList endpointChildList = endpoint.getChildNodes();
int endpoingChildCount = endpointChildList.getLength();
String mediaTypeStr = mediaType.toString();
for (int endpointChildIndex = 0;
endpointChildIndex < endpoingChildCount;
@ -426,6 +415,7 @@ private String getEndpointMediaSrcId(Node endpoint, MediaType mediaType)
NodeList mediaChildList = endpointChild.getChildNodes();
int mediaChildCount = mediaChildList.getLength();
String srcId = null;
String status = null;
String type = null;
for (int mediaChildIndex = 0;
@ -436,24 +426,33 @@ private String getEndpointMediaSrcId(Node endpoint, MediaType mediaType)
String mediaChildName = mediaChild.getNodeName();
if (ELEMENT_SRC_ID.equals(mediaChildName))
{
srcId = mediaChild.getTextContent();
if (mediaTypeStr.equalsIgnoreCase(type))
return srcId;
}
else if (ELEMENT_STATUS.equals(mediaChildName))
status = mediaChild.getTextContent();
else if (ELEMENT_TYPE.equals(mediaChildName))
{
type = mediaChild.getTextContent();
if ((srcId != null)
&& mediaTypeStr.equalsIgnoreCase(type))
{
return srcId;
}
}
}
if (MediaType.AUDIO.toString().equalsIgnoreCase(type))
{
properties.put(
ConferenceMember.AUDIO_SSRC_PROPERTY_NAME,
srcId);
properties.put(
ConferenceMember.AUDIO_STATUS_PROPERTY_NAME,
status);
}
else if (MediaType.VIDEO.toString().equalsIgnoreCase(type))
{
properties.put(
ConferenceMember.VIDEO_SSRC_PROPERTY_NAME,
srcId);
properties.put(
ConferenceMember.VIDEO_STATUS_PROPERTY_NAME,
status);
}
}
}
return null;
}
/**
@ -483,6 +482,110 @@ private String getEndpointStatus(Node endpoint)
return null;
}
/**
* Gets the <tt>MediaDirection</tt> of the media RTP stream of a specific
* <tt>CallPeer</tt> with a specific <tt>MediaType</tt> from the point of
* view of the remote peer.
*
* @param callPeer
* @param mediaType
* @return the <tt>MediaDirection</tt> of the media RTP stream of a specific
* <tt>CallPeer</tt> with a specific <tt>MediaType</tt> from the point of
* view of the remote peer
*/
protected MediaDirection getRemoteDirection(
MediaAwareCallPeer<?,?,?> callPeer,
MediaType mediaType)
{
MediaStream stream = callPeer.getMediaHandler().getStream(mediaType);
MediaDirection remoteDirection;
if (stream != null)
{
remoteDirection = stream.getDirection();
if (remoteDirection != null)
remoteDirection = remoteDirection.getReverseDirection();
}
else
remoteDirection = null;
return null;
}
/**
* Gets the remote SSRC to be reported in the conference-info XML for a
* specific <tt>CallPeer</tt>'s media of a specific <tt>MediaType</tt>.
*
* @param callPeer the <tt>CallPeer</tt> whose remote SSRC for the media of
* the specified <tt>mediaType</tt> is to be returned
* @param mediaType the <tt>MediaType</tt> of the specified
* <tt>callPeer</tt>'s media whose remote SSRC is to be returned
* @return the remote SSRC to be reported in the conference-info XML for the
* specified <tt>callPeer</tt>'s media of the specified <tt>mediaType</tt>
*/
protected long getRemoteSourceID(
MediaAwareCallPeer<?,?,?> callPeer,
MediaType mediaType)
{
MediaStream stream = callPeer.getMediaHandler().getStream(mediaType);
long remoteSourceID;
if (stream != null)
{
remoteSourceID = stream.getRemoteSourceID();
if (remoteSourceID != -1)
{
/*
* TODO Technically, we are detecting conflicts within a Call
* while we should be detecting them within the whole
* CallConference.
*/
MediaAwareCall<?,?,?> call = callPeer.getCall();
if (call != null)
{
for (MediaAwareCallPeer<?,?,?> aCallPeer
: call.getCallPeerList())
{
if (aCallPeer != callPeer)
{
MediaStream aStream
= aCallPeer.getMediaHandler().getStream(
mediaType);
/*
* When the Jitsi VideoBridge server-side technology
* is utilized by the local peer/user to host a
* telephony conference, one and the same
* MediaStream instance will be shared by the
* CallPeers. This will definitely lead to a
* conflict.
*/
if (aStream == stream)
{
remoteSourceID = -1;
break;
}
else
{
long aRemoteSourceID
= stream.getRemoteSourceID();
if (aRemoteSourceID == remoteSourceID)
{
remoteSourceID = -1;
break;
}
}
}
}
}
}
}
else
remoteSourceID = -1;
return remoteSourceID;
}
/**
* Notifies this <tt>CallListener</tt> that a specific incoming
* <tt>Call</tt> has been received.
@ -703,6 +806,8 @@ private void setConferenceInfoDocument(
{
NodeList userList = usersList.item(0).getChildNodes();
int userCount = userList.getLength();
Map<String, Object> conferenceMemberProperties
= new HashMap<String, Object>();
for (int userIndex = 0; userIndex < userCount; userIndex++)
{
@ -759,9 +864,19 @@ private void setConferenceInfoDocument(
int userChildCount = userChildList.getLength();
String displayName = null;
String endpointStatus = null;
String audioSsrc = null;
String videoSsrc = null;
conferenceMemberProperties.put(
ConferenceMember.AUDIO_SSRC_PROPERTY_NAME,
null);
conferenceMemberProperties.put(
ConferenceMember.AUDIO_STATUS_PROPERTY_NAME,
null);
conferenceMemberProperties.put(
ConferenceMember.VIDEO_SSRC_PROPERTY_NAME,
null);
conferenceMemberProperties.put(
ConferenceMember.VIDEO_STATUS_PROPERTY_NAME,
null);
for (int userChildIndex = 0;
userChildIndex < userChildCount;
userChildIndex++)
@ -774,39 +889,17 @@ private void setConferenceInfoDocument(
else if (ELEMENT_ENDPOINT.equals(userChildName))
{
endpointStatus = getEndpointStatus(userChild);
audioSsrc
= getEndpointMediaSrcId(
userChild,
MediaType.AUDIO);
videoSsrc
= getEndpointMediaSrcId(
userChild,
MediaType.VIDEO);
getEndpointMediaProperties(
userChild,
conferenceMemberProperties);
}
}
existingConferenceMember.setDisplayName(displayName);
existingConferenceMember.setEndpointStatus(endpointStatus);
if (audioSsrc != null)
{
long newSsrc = Long.parseLong(audioSsrc);
if (existingConferenceMember.getAudioSsrc() != newSsrc)
{
changed = true;
existingConferenceMember.setAudioSsrc(newSsrc);
}
}
if (videoSsrc != null)
{
long newSsrc = Long.parseLong(videoSsrc);
if (existingConferenceMember.getVideoSsrc() != newSsrc)
{
changed = true;
existingConferenceMember.setVideoSsrc(newSsrc);
}
}
changed
= existingConferenceMember.setProperties(
conferenceMemberProperties);
if (addConferenceMember)
callPeer.addConferenceMember(existingConferenceMember);

Loading…
Cancel
Save