Fixes issues with video conferences such as adding peers and allowing non-focus peers to start their video first.

cusax-fix
Lyubomir Marinov 14 years ago
parent 9b808b2b7c
commit ebc08c2075

@ -433,7 +433,7 @@
<!-- make and deploy target used in intellij idea -->
<target name="make-and-deploy"
depends="compile,package,deploy-os-specific-bundles"
depends="make,deploy-os-specific-bundles"
description="make and deploy target used in intellij idea"/>
<!-- Determines the Jitsi version if any-->

@ -211,20 +211,19 @@ public CallToggleButtonModel(Call call)
public synchronized void actionPerformed(ActionEvent event)
{
if(!spawnActionInNewThread)
if(spawnActionInNewThread)
{
buttonPressed();
return;
}
if (runner == null)
{
runner = new Thread(this, LocalVideoButton.class.getName());
runner.setDaemon(true);
if (runner == null)
{
runner = new Thread(this, LocalVideoButton.class.getName());
runner.setDaemon(true);
setEnabled(false);
runner.start();
setEnabled(false);
runner.start();
}
}
else
buttonPressed();
}
public void run()

@ -325,14 +325,10 @@ public static void enableLocalVideo(Call call, boolean enable)
public static boolean isLocalVideoEnabled(Call call)
{
OperationSetVideoTelephony telephony
= call.getProtocolProvider()
.getOperationSet(OperationSetVideoTelephony.class);
if (telephony != null
&& telephony.isLocalVideoAllowed(call))
return true;
= call.getProtocolProvider().getOperationSet(
OperationSetVideoTelephony.class);
return false;
return (telephony != null) && telephony.isLocalVideoAllowed(call);
}
/**
@ -343,8 +339,8 @@ public static boolean isLocalVideoEnabled(Call call)
* @param contact the contact to call to
*/
public static void createDesktopSharing(
ProtocolProviderService protocolProvider,
String contact)
ProtocolProviderService protocolProvider,
String contact)
{
// If the user presses cancel on the desktop sharing warning then we
// have nothing more to do here.
@ -352,16 +348,16 @@ public static void createDesktopSharing(
return;
MediaService mediaService = GuiActivator.getMediaService();
List<MediaDevice> desktopDevices = mediaService.getDevices(
MediaType.VIDEO, MediaUseCase.DESKTOP);
List<MediaDevice> desktopDevices
= mediaService.getDevices(MediaType.VIDEO, MediaUseCase.DESKTOP);
int deviceNumber = desktopDevices.size();
if (deviceNumber == 1)
{
createDesktopSharing(
protocolProvider, contact, desktopDevices.get(0));
protocolProvider,
contact,
desktopDevices.get(0));
}
else if (deviceNumber > 1)
{
@ -369,11 +365,11 @@ else if (deviceNumber > 1)
= new SelectScreenDialog(desktopDevices);
selectDialog.setVisible(true);
if (selectDialog.getSelectedDevice() != null)
createDesktopSharing( protocolProvider,
contact,
selectDialog.getSelectedDevice());
createDesktopSharing(
protocolProvider,
contact,
selectDialog.getSelectedDevice());
}
}
@ -1848,7 +1844,7 @@ private static class EnableLocalVideoThread
{
private final Call call;
private boolean enable;
private final boolean enable;
/**
* Creates the enable local video call thread.
@ -1878,20 +1874,16 @@ public void run()
{
getActiveCallContainer(call).setDesktopSharingButtonSelected(
false);
JFrame frame = DesktopSharingFrame.getFrameForCall(call);
if(frame != null)
{
frame.dispose();
}
}
try
{
telephony.setLocalVideoAllowed(
call,
enable);
telephony.setLocalVideoAllowed(call, enable);
enableSucceeded = true;
}
catch (OperationFailedException ex)

@ -149,9 +149,10 @@ public class CallPanel
/**
* The conference button.
*/
private SIPCommButton conferenceButton = new SIPCommButton(
ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG),
ImageLoader.getImage(ImageLoader.ADD_TO_CALL_BUTTON));
private SIPCommButton conferenceButton
= new SIPCommButton(
ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG),
ImageLoader.getImage(ImageLoader.ADD_TO_CALL_BUTTON));
/**
* Chat button.
@ -266,9 +267,7 @@ public CallPanel(Call call, CallContainer callWindow)
// the focus state of each call peer.
Iterator<? extends CallPeer> callPeers = call.getCallPeers();
while (callPeers.hasNext())
{
callPeers.next().addCallPeerConferenceListener(this);
}
// Initializes all buttons and common panels.
init();
@ -417,9 +416,7 @@ public void actionPerformed(ActionEvent evt)
else if (buttonName.equals(DIAL_BUTTON))
{
if (dialpadDialog == null)
{
dialpadDialog = this.getDialpadDialog();
}
if(!dialpadDialog.isVisible())
{
@ -445,10 +442,7 @@ else if (buttonName.equals(DIAL_BUTTON))
}
else if (buttonName.equals(CONFERENCE_BUTTON))
{
ConferenceInviteDialog inviteDialog
= new ConferenceInviteDialog(call);
inviteDialog.setVisible(true);
new ConferenceInviteDialog(call).setVisible(true);
}
else if (buttonName.equals(CHAT_BUTTON))
{
@ -706,8 +700,8 @@ public void enableButtons(boolean enable)
ProtocolProviderService protocolProvider
= call.getProtocolProvider();
if (protocolProvider.getOperationSet(
OperationSetVideoTelephony.class) != null)
if (protocolProvider.getOperationSet(OperationSetVideoTelephony.class)
!= null)
{
videoButton.setEnabled(enable);
}
@ -724,7 +718,8 @@ public void enableButtons(boolean enable)
}
if (protocolProvider.getOperationSet(
OperationSetAdvancedTelephony.class) != null)
OperationSetAdvancedTelephony.class)
!= null)
{
transferCallButton.setEnabled(enable);
}
@ -808,22 +803,18 @@ public void callPeerRemoved(CallPeerEvent evt)
callPeer.removeCallPeerConferenceListener(this);
Timer timer = new Timer(5000,
new RemovePeerPanelListener(callPeer));
Timer timer = new Timer(5000, new RemovePeerPanelListener(callPeer));
timer.setRepeats(false);
timer.start();
// The call is finished when that last peer is removed.
if (call.getCallPeerCount() == 0)
{
this.stopCallTimer();
}
}
public void callStateChanged(CallChangeEvent evt)
{
}
{}
/**
* Updates <tt>CallPeer</tt> related components to fit the new focus state.
@ -1002,7 +993,7 @@ public String getCallTitle()
private class RemovePeerPanelListener
implements ActionListener
{
private CallPeer peer;
private final CallPeer peer;
public RemovePeerPanelListener(CallPeer peer)
{
@ -1112,15 +1103,29 @@ public void refreshContainer()
// whole window to freeze.
// We check also if the vertical scroll bar is visible in order to
// correctly pack the window when a peer is removed.
boolean isScrollBarVisible = (callPanel instanceof ConferenceCallPanel)
&& ((ConferenceCallPanel) callPanel).getVerticalScrollBar() != null
&& ((ConferenceCallPanel) callPanel).getVerticalScrollBar()
.isVisible();
if (!isScrollBarVisible
|| getHeight()
< GraphicsEnvironment.getLocalGraphicsEnvironment()
.getMaximumWindowBounds().height)
boolean isScrollBarVisible;
if (callPanel instanceof ConferenceCallPanel)
{
Component scrollBar
= ((ConferenceCallPanel) callPanel).getVerticalScrollBar();
isScrollBarVisible = ((scrollBar != null) && scrollBar.isVisible());
}
else
isScrollBarVisible = false;
/*
* Repacking should be done only when the callWindow is not high enough
* to not have a vertical scroll bar and there is still room left to
* expand its height without going out of the screen.
*/
if (isScrollBarVisible
&& (getHeight()
< GraphicsEnvironment
.getLocalGraphicsEnvironment()
.getMaximumWindowBounds()
.height))
callWindow.pack();
else
repaint();
@ -1195,11 +1200,6 @@ private void updateCurrentCallPanel(JComponent callPanel)
*/
private void removeOneToOneSpecificComponents()
{
// If we want to enable video in conference calls we need to comment
// these lines.
if (videoButton.isSelected())
videoButton.doClick();
// Disable desktop sharing.
if (desktopSharingButton.isSelected())
desktopSharingButton.doClick();

@ -20,7 +20,6 @@
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
import net.java.sip.communicator.util.swing.transparent.*;
/**
* The <tt>UIVideoHandler</tt> is meant to handle all video related events.
@ -337,13 +336,11 @@ else if (event.getNewValue().equals(MediaDirection.SENDRECV))
if (CallManager.isDesktopSharingEnabled(call))
{
callContainer.setDesktopSharingButtonSelected(true);
if (CallManager.isRegionDesktopSharingEnabled(call))
{
TransparentFrame frame = DesktopSharingFrame
.createTransparentFrame(call, false);
frame.setVisible(true);
DesktopSharingFrame
.createTransparentFrame(call, false)
.setVisible(true);
}
}
else if (CallManager.isLocalVideoEnabled(call))
@ -630,7 +627,6 @@ private void handleLocalVideoStreamingChange(
{
if (videoTelephony == null)
return;
if (callPeer == null || callPeer.getCall() == null)
return;

@ -126,20 +126,6 @@ public ConferenceCallPanel(CallPanel callPanel, Call c)
scrollPane.setOpaque(false);
scrollPane.getViewport().setOpaque(false);
this.addLocalCallPeer();
Iterator<? extends CallPeer> iterator = this.call.getCallPeers();
while (iterator.hasNext())
this.addCallPeerPanel(iterator.next());
iterator = this.call.getCrossProtocolCallPeers();
while (iterator.hasNext())
{
this.addCallPeerPanel(iterator.next());
}
scrollPane.setBorder(null);
/*
* The scrollPane seems to receive only a few pixels of width at times
@ -161,6 +147,22 @@ public ConferenceCallPanel(CallPanel callPanel, Call c)
add(scrollPane, scrollPaneGridBagConstraints);
addVideoContainer();
/*
* XXX Call addCallPeerPanel(CallPeer) after calling addVideoContainer()
* because the video may already be flowing between the CallPeers.
* Otherwise, the videos of the remote CallPeers will not be shown.
*/
addLocalCallPeer();
Iterator<? extends CallPeer> iterator;
iterator = this.call.getCallPeers();
while (iterator.hasNext())
addCallPeerPanel(iterator.next());
iterator = this.call.getCrossProtocolCallPeers();
while (iterator.hasNext())
addCallPeerPanel(iterator.next());
}
/**
@ -220,7 +222,7 @@ public void componentAdded(ContainerEvent e)
}
/*
* When the first visual/videoComponent gets added, this
* When the first visual/video Component gets added, this
* videoContainer is still not accommodated by the frame
* size because it has just become visible. So try to resize
* the frame to accommodate this videoContainer.
@ -574,6 +576,17 @@ public void ensureSize(Component component, int width, int height)
{
Frame frame = CallPeerRendererUtils.getFrame(component);
/*
* CallPanel creates ConferenceCallPanel and then adds it to the UI
* hierarchy. If the associated Call has just become a conference focus
* and the UI is being updated to reflect the change, the existing
* CallPeer of the Call may cause this method to be called and then this
* ConferenceCallPanel will not have an associated Frame at the time.
* But callPanel will (likely) have one.
*/
if ((frame == null) && (callPanel != null))
frame = CallPeerRendererUtils.getFrame(callPanel);
if (frame == null)
return;
else if ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH)

@ -13,8 +13,12 @@
import net.java.sip.communicator.service.neomedia.*;
/**
* Provides a base/default implementation of <tt>RTPConnector</tt> which has
* factory methods for its control and data input and output streams and has an
* associated <tt>StreamConnector</tt>.
*
* @author Bing SU (nova.su@gmail.com)
* @author Lubomir Marinov
* @author Lyubomir Marinov
*/
public abstract class AbstractRTPConnector
implements RTPConnector
@ -95,13 +99,11 @@ public void close()
dataOutputStream.close();
dataOutputStream = null;
}
if (controlOutputStream != null)
{
controlOutputStream.close();
controlOutputStream = null;
}
if (dataInputStream != null)
{
dataInputStream.close();

@ -348,11 +348,12 @@ public void addRTPExtension(byte extensionID, RTPExtension rtpExtension)
{
super.addRTPExtension(extensionID, rtpExtension);
if ( RTPExtension.CSRC_AUDIO_LEVEL_URN
.equals(rtpExtension.getURI().toString()))
if (RTPExtension.CSRC_AUDIO_LEVEL_URN.equals(
rtpExtension.getURI().toString()))
{
getCsrcEngine().setCsrcAudioLevelAudioLevelExtensionID(
extensionID, rtpExtension.getDirection());
extensionID,
rtpExtension.getDirection());
}
}

@ -332,12 +332,11 @@ protected void configureRTPManagerBufferControl(
private TransformEngineChain createTransformEngineChain()
{
ArrayList<TransformEngine> engineChain
= new ArrayList<TransformEngine>(3);
= new ArrayList<TransformEngine>(4);
// CSRCs and audio levels
if (csrcEngine == null)
csrcEngine = new CsrcTransformEngine(this);
engineChain.add(csrcEngine);
// DTMF
@ -347,7 +346,7 @@ private TransformEngineChain createTransformEngineChain()
engineChain.add(dtmfEngine);
// RTCP Statistics
if(statisticsEngine == null)
if (statisticsEngine == null)
statisticsEngine = new StatisticsEngine(this);
engineChain.add(statisticsEngine);
@ -503,7 +502,7 @@ public void close()
srtpControl.cleanup();
if(csrcEngine != null)
if (csrcEngine != null)
{
csrcEngine.stop();
csrcEngine = null;
@ -515,7 +514,7 @@ public void close()
if (rtpManager != null)
{
if(logger.isInfoEnabled())
if (logger.isInfoEnabled())
printFlowStatistics(rtpManager);
rtpManager.removeReceiveStreamListener(this);
@ -843,7 +842,6 @@ private void doSetTarget(MediaStreamTarget target)
}
else
targetIsSet = true;
if (targetIsSet)
{
rtpConnectorTarget = target;
@ -859,6 +857,7 @@ private void doSetTarget(MediaStreamTarget target)
+ target);
}
}
/**
* Gets the <tt>MediaDevice</tt> that this stream uses to play back and
* capture media.
@ -1095,8 +1094,6 @@ private StreamRTPManager getRTPManager()
if (bc != null)
configureRTPManagerBufferControl(rtpManager, bc);
//Emil: if you replace this method with another init method make
//sure you check that the line below still works.
rtpManager.initialize(rtpConnector);
/*
@ -1256,74 +1253,74 @@ public void setConnector(StreamConnector connector)
if (connector == null)
throw new NullPointerException("connector");
if (rtpConnector != null)
{
// Is the StreamConnector really changing?
if (rtpConnector.getConnector() == connector)
return;
}
AbstractRTPConnector oldValue = rtpConnector;
if(connector.getProtocol() == StreamConnector.Protocol.UDP)
// Is the StreamConnector really changing?
if ((oldValue != null) && (oldValue.getConnector() == connector))
return;
switch (connector.getProtocol())
{
case UDP:
rtpConnector
= new RTPTransformUDPConnector(connector)
{
@Override
protected TransformUDPOutputStream createDataOutputStream()
throws IOException
{
TransformUDPOutputStream dataOutputStream
= super.createDataOutputStream();
@Override
protected TransformUDPOutputStream createDataOutputStream()
throws IOException
{
TransformUDPOutputStream dataOutputStream
= super.createDataOutputStream();
if (dataOutputStream != null)
configureDataOutputStream(dataOutputStream);
return dataOutputStream;
}
if (dataOutputStream != null)
configureDataOutputStream(dataOutputStream);
return dataOutputStream;
}
@Override
protected TransformUDPInputStream createDataInputStream()
throws IOException
{
TransformUDPInputStream dataInputStream
= super.createDataInputStream();
@Override
protected TransformUDPInputStream createDataInputStream()
throws IOException
{
TransformUDPInputStream dataInputStream
= super.createDataInputStream();
if (dataInputStream != null)
configureDataInputStream(dataInputStream);
return dataInputStream;
}
};
}
else if(connector.getProtocol() == StreamConnector.Protocol.TCP)
{
if (dataInputStream != null)
configureDataInputStream(dataInputStream);
return dataInputStream;
}
};
break;
case TCP:
rtpConnector
= new RTPTransformTCPConnector(connector)
{
@Override
protected TransformTCPOutputStream createDataOutputStream()
throws IOException
{
TransformTCPOutputStream dataOutputStream
= super.createDataOutputStream();
@Override
protected TransformTCPOutputStream createDataOutputStream()
throws IOException
{
TransformTCPOutputStream dataOutputStream
= super.createDataOutputStream();
if (dataOutputStream != null)
configureDataOutputStream(dataOutputStream);
return dataOutputStream;
}
if (dataOutputStream != null)
configureDataOutputStream(dataOutputStream);
return dataOutputStream;
}
@Override
protected TransformTCPInputStream createDataInputStream()
throws IOException
{
TransformTCPInputStream dataInputStream
= super.createDataInputStream();
@Override
protected TransformTCPInputStream createDataInputStream()
throws IOException
{
TransformTCPInputStream dataInputStream
= super.createDataInputStream();
if (dataInputStream != null)
configureDataInputStream(dataInputStream);
return dataInputStream;
}
};
if (dataInputStream != null)
configureDataInputStream(dataInputStream);
return dataInputStream;
}
};
break;
default:
throw new IllegalArgumentException("connector");
}
rtpConnectorChanged(oldValue, rtpConnector);
@ -1362,7 +1359,7 @@ public void setDevice(MediaDevice device)
startedDirection = deviceSession.getStartedDirection();
deviceSession.removePropertyChangeListener(
deviceSessionPropertyChangeListener);
deviceSessionPropertyChangeListener);
// keep player active
deviceSession.setDisposePlayerOnClose(
@ -1738,10 +1735,13 @@ private void startSendStreams()
{
try
{
DataSource sendStreamDataSource
= sendStream.getDataSource();
// TODO Are we sure we want to connect here?
sendStream.getDataSource().connect();
sendStreamDataSource.connect();
sendStream.start();
sendStream.getDataSource().start();
sendStreamDataSource.start();
if (logger.isTraceEnabled())
{
@ -1752,8 +1752,7 @@ private void startSendStreams()
}
catch (IOException ioe)
{
logger
.warn("Failed to start stream " + sendStream, ioe);
logger.warn("Failed to start stream " + sendStream, ioe);
}
}
}
@ -2371,6 +2370,9 @@ private void printFlowStatistics(StreamRTPManager rtpManager)
*/
public void setRTPTranslator(RTPTranslator rtpTranslator)
{
this.rtpTranslator = rtpTranslator;
if (this.rtpTranslator != rtpTranslator)
{
this.rtpTranslator = rtpTranslator;
}
}
}

@ -441,17 +441,37 @@ public void removeSessionListener(
// TODO Auto-generated method stub
}
/**
* Notifies this <tt>ReceiveStreamListener</tt> about a specific event
* related to a <tt>ReceiveStream</tt>.
*
* @param event a <tt>ReceiveStreamEvent</tt> which contains the specifics
* of the event this <tt>ReceiveStreamListener</tt> is being notified about
* @see ReceiveStreamListener#update(ReceiveStreamEvent)
*/
public void update(ReceiveStreamEvent event)
{
StreamRTPManagerDesc streamRTPManagerDesc
= findStreamRTPManagerDescByReceiveSSRC(
event.getReceiveStream().getSSRC(),
null);
/*
* Because NullPointerException was seen during testing, be thorough
* with the null checks.
*/
if (event != null)
{
ReceiveStream receiveStream = event.getReceiveStream();
if (streamRTPManagerDesc != null)
for (ReceiveStreamListener listener
: streamRTPManagerDesc.getReceiveStreamListeners())
listener.update(event);
if (receiveStream != null)
{
StreamRTPManagerDesc streamRTPManagerDesc
= findStreamRTPManagerDescByReceiveSSRC(
receiveStream.getSSRC(),
null);
if (streamRTPManagerDesc != null)
for (ReceiveStreamListener listener
: streamRTPManagerDesc.getReceiveStreamListeners())
listener.update(event);
}
}
}
private static class OutputDataStreamDesc

@ -598,13 +598,29 @@ public Component createLocalVisualComponent()
* it to the currently registered VideoListeners in a VideoEvent after
* returning from the call.
*/
Component localVisualComponent;
synchronized (localPlayerSyncRoot)
{
if (localPlayer == null)
localPlayer = createLocalPlayer();
return
(localPlayer == null) ? null : getVisualComponent(localPlayer);
localVisualComponent
= (localPlayer == null)
? null
: getVisualComponent(localPlayer);
}
/*
* If the local visual/video Component exists at this time, it has
* likely been created by a previous call to this method. However, the
* caller may still depend on a VIDEO_ADDED event being fired for it.
*/
if (localVisualComponent != null)
fireVideoEvent(
VideoEvent.VIDEO_ADDED,
localVisualComponent,
VideoEvent.LOCAL,
false);
return localVisualComponent;
}
/**

@ -190,7 +190,6 @@ public void setCsrcAudioLevelAudioLevelExtensionID(byte extID,
{
this.csrcAudioLevelExtID = extID;
this.audioLevelDirection = dir;
}
/**

@ -8,6 +8,7 @@
import net.java.sip.communicator.impl.neomedia.*;
import net.java.sip.communicator.impl.neomedia.transform.*;
import net.java.sip.communicator.service.neomedia.format.*;
import net.java.sip.communicator.util.*;
import net.sf.fmj.media.rtp.*;
@ -112,17 +113,18 @@ public RawPacket transform(RawPacket pkt)
lost = feedback.getNumLost();
// As sender reports are send on every 5 seconds
// print every 4th packet, on every 20 seconds
// As sender reports are sent on every 5 seconds, print
// every 4th packet, on every 20 seconds.
if(numberOfSenderReports % 4 != 1)
return pkt;
StringBuilder buff = new StringBuilder(RTP_STAT_PREFIX);
MediaFormat mediaStreamFormat = mediaStream.getFormat();
buff.append("Sending a report for ")
.append(mediaStream.getFormat() != null ?
mediaStream.getFormat().getMediaType()
: "")
.append(mediaStreamFormat != null
? mediaStreamFormat.getMediaType()
: "")
.append(" stream SSRC:")
.append(feedback.getSSRC())
.append(" [packet count:")

@ -289,26 +289,30 @@ public CallPeerJabberImpl initiateSession(
// if this was the first peer we added in this call then the call is
// new and we also need to notify everyone of its creation.
if(getCallPeerCount() == 1 && getCallGroup() == null)
CallGroup callGroup = getCallGroup();
if ((getCallPeerCount() == 1) && (callGroup == null))
{
parentOpSet.fireCallEvent(CallEvent.CALL_INITIATED, this);
}
else if(getCallGroup() != null)
else if (callGroup != null)
{
// only TelephonyConferencing OperationSet should know about it
CallEvent cEvent = new CallEvent(this, CallEvent.CALL_INITIATED);
AbstractOperationSetTelephonyConferencing<?,?,?,?,?> opSet =
(AbstractOperationSetTelephonyConferencing<?,?,?,?,?>)
getProtocolProvider().getOperationSet(
OperationSetTelephonyConferencing.class);
if(opSet != null)
opSet.outgoingCallCreated(cEvent);
CallEvent event = new CallEvent(this, CallEvent.CALL_INITIATED);
AbstractOperationSetTelephonyConferencing<?,?,?,?,?> opSet
= (AbstractOperationSetTelephonyConferencing<?,?,?,?,?>)
getProtocolProvider()
.getOperationSet(
OperationSetTelephonyConferencing.class);
if (opSet != null)
opSet.outgoingCallCreated(event);
}
CallPeerMediaHandlerJabberImpl mediaHandler
= callPeer.getMediaHandler();
/* enable video if it is a videocall */
/* enable video if it is a video call */
mediaHandler.setLocalVideoTransmissionEnabled(localVideoAllowed);
/* enable remote-control if it is a desktop sharing session */
mediaHandler.setLocalInputEvtAware(localInputEvtAware);
@ -320,22 +324,19 @@ else if(getCallGroup() != null)
// if initializing session fails, set peer to failed
boolean sessionInitiated = false;
try
{
callPeer.initiateSession(sessionInitiateExtensions);
sessionInitiated = true;
return callPeer;
}
finally
{
// if initialization throws an exception
if(!sessionInitiated)
{
if (!sessionInitiated)
callPeer.setState(CallPeerState.FAILED);
}
}
return callPeer;
}
/**

@ -449,17 +449,19 @@ else if(di != null)
// initiate call
try
{
if(isGingle)
if (isGingle)
{
logger.info("initiate Gingle call");
CallGTalkImpl callGTalk = new CallGTalkImpl(this);
MediaUseCase useCase = call.getMediaUseCase();
boolean isVideo = call.isLocalVideoAllowed(useCase);
callGTalk.setCallGroup(call.getCallGroup());
callGTalk.setCallGroup(call.getCallGroup());
callGTalk.setLocalVideoAllowed(isVideo, useCase);
peer = callGTalk.initiateGTalkSession(fullCalleeURI,
sessionInitiateExtensions);
peer
= callGTalk.initiateGTalkSession(
fullCalleeURI,
sessionInitiateExtensions);
}
else if(di != null)
{

@ -22,7 +22,7 @@
* by the associated protocol provider to be capabilities possessed by the
* Jabber <tt>Contact</tt> in question.
*
* @author Lubomir Marinov
* @author Lyubomir Marinov
* @author Yana Stamcheva
*/
public class OperationSetContactCapabilitiesJabberImpl
@ -318,14 +318,7 @@ private <U extends OperationSet> U getOperationSet(String jid,
* should fail anyway).
*/
if (!online)
{
if (OFFLINE_OPERATION_SETS.contains(opsetClass))
return opset;
else
{
return null;
}
}
return OFFLINE_OPERATION_SETS.contains(opsetClass) ? opset : null;
/*
* If we know the features required for the support of opsetClass, check
@ -351,19 +344,20 @@ private <U extends OperationSet> U getOperationSet(String jid,
{
if(CAPS_OPERATION_SETS_TO_FEATURES.containsKey(opsetClass))
{
String[] extFeatures =
CAPS_OPERATION_SETS_TO_FEATURES.get(
opsetClass);
String[] extFeatures
= CAPS_OPERATION_SETS_TO_FEATURES.get(opsetClass);
// test GTalk
if(!parentProvider.isGTalkTesting())
if (!parentProvider.isGTalkTesting())
{
opset = null;
}
else
if((extFeatures == null) || ((extFeatures.length != 0) &&
!parentProvider.isExtFeatureListSupported(jid,
extFeatures)))
else if((extFeatures == null)
|| ((extFeatures.length != 0)
&& !parentProvider
.isExtFeatureListSupported(
jid,
extFeatures)))
{
opset = null;
}

@ -123,7 +123,7 @@ protected void notifyAll(Call call)
/**
* Notifies all CallPeer associated with and established in a
* specific call has occurred
* @param call the <tt>Call</tt>
*
* @param callPeer the <tt>CallPeer</tt>
*/
private void notify(CallPeer callPeer)
@ -461,8 +461,10 @@ protected CallPeer inviteCalleeToCall(
{
if (!wasConferenceFocus && call.isConferenceFocus())
{
// reinvite other peers if any, to inform them that from now
// it is a conference call
/*
* Re-INVITE existing CallPeers to inform them that from now
* the specified call is a conference call.
*/
Iterator<CallPeerJabberImpl> callPeerIter = call.getCallPeers();
while (callPeerIter.hasNext())
@ -473,10 +475,15 @@ protected CallPeer inviteCalleeToCall(
}
}
CoinPacketExtension confInfo = new CoinPacketExtension(true);
return getBasicTelephony().createOutgoingCall(
call, calleeAddress,
Arrays.asList(new PacketExtension[] { confInfo }));
return
getBasicTelephony().createOutgoingCall(
call,
calleeAddress,
Arrays.asList(
new PacketExtension[]
{
new CoinPacketExtension(true)
}));
}
/**

@ -132,12 +132,16 @@ protected Call createOutgoingVideoCall(String calleeAddress)
/* enable video */
call.setLocalVideoAllowed(true, getMediaUseCase());
CallPeer callPeer =
basicTelephony.createOutgoingCall(call, calleeAddress);
// if call is a Google Talk ones, return the CallGTalkImpl
CallPeer callPeer
= basicTelephony.createOutgoingCall(call, calleeAddress);
return callPeer.getCall() == call ? call : callPeer.getCall();
/*
* XXX OperationSetBasicTelephonyJabberImpl#createOutgoingCall(
* CallJabberImpl, String) may have replaced the CallJabberImpl instance
* created above with a CallGTalkImpl instance.
*/
return callPeer.getCall();
}
/**

@ -46,7 +46,7 @@
*
* @author Damian Minkov
* @author Symphorien Wanko
* @author Lubomir Marinov
* @author Lyubomir Marinov
* @author Yana Stamcheva
* @author Emil Ivov
*/
@ -2433,13 +2433,15 @@ public SecurityAuthority getAuthority()
*/
public boolean isGTalkTesting()
{
return (Boolean.getBoolean("gtalktesting") ||
JabberActivator.getConfigurationService().getBoolean(
"net.java.sip.communicator.impl.protocol.jabber.gtalktesting"
, false) ||
accountID.getAccountPropertyBoolean(
ProtocolProviderFactory.IS_USE_GOOGLE_ICE,
true));
return
Boolean.getBoolean("gtalktesting")
|| JabberActivator.getConfigurationService().getBoolean(
"net.java.sip.communicator.impl.protocol.jabber"
+ ".gtalktesting",
false)
|| accountID.getAccountPropertyBoolean(
ProtocolProviderFactory.IS_USE_GOOGLE_ICE,
true);
}
UserCredentials getUserCredentials()

@ -16,7 +16,7 @@
* order to make it easier for implementers to provide complete solutions while
* focusing on protocol-specific details.
*
* @author Lubomir Marinov
* @author Lyubomir Marinov
*/
public abstract class AbstractProtocolProviderService
implements ProtocolProviderService
@ -128,11 +128,8 @@ public void fireRegistrationStateChanged( RegistrationState oldState,
if (logger.isDebugEnabled())
logger.debug(
"Dispatching "
+ event
+ " to "
+ listeners.length
+ " listeners.");
"Dispatching " + event + " to " + listeners.length
+ " listeners.");
for (RegistrationStateChangeListener listener : listeners)
try
@ -141,7 +138,6 @@ public void fireRegistrationStateChanged( RegistrationState oldState,
}
catch (Throwable throwable)
{
/*
* The registration state has already changed and we're not
* using the RegistrationStateChangeListeners to veto the change
@ -153,7 +149,10 @@ public void fireRegistrationStateChanged( RegistrationState oldState,
if (throwable instanceof ThreadDeath)
throw (ThreadDeath) throwable;
logger.error(
"An error occurred while executing RegistrationStateChangeLister#registrationStateChanged(RegistrationStateChangeEvent) of "
"An error occurred while executing "
+ "RegistrationStateChangeListener"
+ "#registrationStateChanged"
+ "(RegistrationStateChangeEvent) of "
+ listener,
throwable);
}
@ -188,9 +187,10 @@ public <T extends OperationSet> T getOperationSet(Class<T> opsetClass)
*/
public String getProtocolDisplayName()
{
String displayName =
getAccountID().getAccountPropertyString(
ProtocolProviderFactory.PROTOCOL);
String displayName
= getAccountID().getAccountPropertyString(
ProtocolProviderFactory.PROTOCOL);
return (displayName == null) ? getProtocolName() : displayName;
}

@ -182,7 +182,7 @@ public void removeVideoListener(CallPeer peer, VideoListener listener)
* @param allowed <tt>true</tt> if local video transmission is allowed and
* <tt>false</tt> otherwise.
*
* @throws OperationFailedException if video initialization fails.
* @throws OperationFailedException if video initialization fails.
*/
public void setLocalVideoAllowed(Call call, boolean allowed)
throws OperationFailedException

@ -1261,12 +1261,16 @@ protected MediaStream initStream(StreamConnector connector,
logger.trace("The media types of device and format differ.");
// check whether a control already exists
SrtpControl control
= srtpControls.size() > 0
? srtpControls.get(
new MediaTypeSrtpControl(
mediaType,
srtpControls.firstKey().srtpControlType))
: null;
MediaService mediaService
= ProtocolMediaActivator.getMediaService();
SrtpControl control = srtpControls.size() > 0 ?
srtpControls.get(new MediaTypeSrtpControl(mediaType,
srtpControls.firstKey().srtpControlType)) : null;
if(control == null)
{
// this creates the default control, currently ZRTP without

@ -380,7 +380,19 @@ public RTPTranslator getRTPTranslator(MediaType mediaType)
{
RTPTranslator rtpTranslator = null;
if (isConferenceFocus() && MediaType.VIDEO.equals(mediaType))
/*
* XXX The conferenceAudioMixer is created even when this Call is not a
* conference focus in order to enable additional functionality.
* Similarly, the videoRTPTranslator is created even when this Call is
* not a conference focus in order to enable this Call to turn into a
* conference focus at a later time. More specifically, MediaStreamImpl
* is unable to accommodate an RTPTranslator after it has created its
* RTPManager. Yet again like conferenceAudioMixer, we'd better not try
* to use it on Android at this time because of performance issues that
* may arise.
*/
if (MediaType.VIDEO.equals(mediaType)
&& (!OSUtils.IS_ANDROID || isConferenceFocus()))
{
if (videoRTPTranslator == null)
{
@ -504,16 +516,20 @@ public MediaDevice getDefaultDevice(MediaType mediaType)
switch (mediaType)
{
case AUDIO:
/*
* TODO AudioMixer leads to very poor audio quality on Android so do
* not use it unless it is really really necessary.
*/
if ((conferenceAudioMixer == null)
&& (device != null)
/*
* TODO AudioMixer leads to very poor audio quality on
* Android so do not use it unless it is really really
* necessary.
*/
&& (!OSUtils.IS_ANDROID || isConferenceFocus())
// we can use audio mixer only if we
// have capture device (device can send)
&& (device.getDirection().allowsSending()))
/*
* We can use the AudioMixer only if the device is able to
* capture (because the AudioMixer will push when the
* capture device pushes).
*/
&& device.getDirection().allowsSending())
conferenceAudioMixer = mediaService.createMixer(device);
if (conferenceAudioMixer != null)
device = conferenceAudioMixer;
@ -745,10 +761,7 @@ public MediaUseCase getMediaUseCase()
*/
public boolean isLocalVideoAllowed(MediaUseCase useCase)
{
if (mediaUseCase.equals(useCase))
return localVideoAllowed;
else
return false;
return mediaUseCase.equals(useCase) && localVideoAllowed;
}
/**
@ -1069,7 +1082,7 @@ public void callAdded(CallGroupEvent evt)
CallPeer p = peers.next();
getCrossProtocolCallPeersVector().add(p);
fireCallPeerEvent(p, CallPeerEvent.CALL_PEER_ADDED);
this.setConferenceFocus(true);
setConferenceFocus(true);
}
}

Loading…
Cancel
Save