diff --git a/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java b/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java
index 16f97feb6..2d02d5bed 100644
--- a/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java
+++ b/src/net/java/sip/communicator/impl/neomedia/MediaStreamImpl.java
@@ -17,6 +17,8 @@
import javax.media.rtp.*;
import javax.media.rtp.event.*;
+import com.sun.media.rtp.*;
+
import net.java.sip.communicator.impl.neomedia.device.*;
import net.java.sip.communicator.impl.neomedia.format.*;
import net.java.sip.communicator.impl.neomedia.transform.*;
@@ -129,12 +131,18 @@ public class MediaStreamImpl
/**
* The SSRC identifier of the party that we are exchanging media with.
*/
- private String remoteSourceID = null;
+ private long remoteSourceID = -1;
/**
* Our own SSRC identifier.
*/
- private String localSourceID = null;
+ private long localSourceID = -1;
+
+ /**
+ * The list of CSRC IDs that the remote party reported as contributing to
+ * the media they are sending toward us.
+ */
+ private long[] remoteContributingSourceIDList = new long[0];
/**
* The indicator which determines whether this MediaStream is set
@@ -164,6 +172,8 @@ public MediaStreamImpl(StreamConnector connector, MediaDevice device)
setDevice(device);
this.rtpConnector = new RTPTransformConnector(connector);
+
+
}
/**
@@ -419,8 +429,7 @@ public MediaDirection getDirection()
MediaDeviceSession deviceSession = getDeviceSession();
- return
- (deviceSession == null)
+ return (deviceSession == null)
? MediaDirection.INACTIVE
: deviceSession.getDevice().getDirection();
}
@@ -445,8 +454,7 @@ public Map getDynamicRTPPayloadTypes()
{
synchronized (dynamicRTPPayloadTypes)
{
- return
- new HashMap(dynamicRTPPayloadTypes);
+ return new HashMap(dynamicRTPPayloadTypes);
}
}
@@ -465,16 +473,15 @@ public MediaFormat getFormat()
/**
* Gets the synchronization source (SSRC) identifier of the local peer or
- * null if it is not yet known.
+ * -1 if it is not yet known.
*
* @return the synchronization source (SSRC) identifier of the local peer
- * or null if it is not yet known
+ * or -1 if it is not yet known
* @see MediaStream#getLocalSourceID()
*/
- public String getLocalSourceID()
+ public long getLocalSourceID()
{
- // TODO Auto-generated method stub
- return null;
+ return this.localSourceID;
}
/**
@@ -486,8 +493,7 @@ public String getLocalSourceID()
*/
public InetSocketAddress getRemoteControlAddress()
{
- return
- (InetSocketAddress)
+ return (InetSocketAddress)
rtpConnector.getControlSocket().getRemoteSocketAddress();
}
@@ -500,20 +506,19 @@ public InetSocketAddress getRemoteControlAddress()
*/
public InetSocketAddress getRemoteDataAddress()
{
- return
- (InetSocketAddress)
+ return (InetSocketAddress)
rtpConnector.getDataSocket().getRemoteSocketAddress();
}
/**
* Get the synchronization source (SSRC) identifier of the remote peer or
- * null if it is not yet known.
+ * -1 if it is not yet known.
*
* @return the synchronization source (SSRC) identifier of the remote
- * peer or null if it is not yet known
+ * peer or -1 if it is not yet known
* @see MediaStream#getRemoteSourceID()
*/
- public String getRemoteSourceID()
+ public long getRemoteSourceID()
{
return remoteSourceID;
}
@@ -579,9 +584,7 @@ private RTPManager getRTPManager()
//JMF inits the local SSRC upon initialize(RTPConnector) so now's
//the time to ask:
- setLocalSourceID(Long.toHexString(
- (((com.sun.media.rtp.RTPSessionMgr)
- rtpManager).getLocalSSRC())));
+ setLocalSourceID(((RTPSessionMgr)rtpManager).getLocalSSRC());
createSendStreams();
}
@@ -1256,7 +1259,7 @@ public void update(ReceiveStreamEvent event)
logger.trace("Received new ReceiveStream with ssrc "
+ receiveStream.getSSRC());
- setRemoteSourceID( Long.toHexString( receiveStream.getSSRC() ));
+ setRemoteSourceID( receiveStream.getSSRC() );
synchronized (receiveStreams)
{
@@ -1326,9 +1329,9 @@ public void update(SessionEvent event)
* @param ssrc the SSRC identifier that this stream will be using in
* outgoing RTP packets from now on.
*/
- private void setLocalSourceID(String ssrc)
+ private void setLocalSourceID(long ssrc)
{
- String oldValue = this.localSourceID;
+ Long oldValue = this.localSourceID;
this.localSourceID = ssrc;
firePropertyChange(PNAME_LOCAL_SSRC, oldValue, ssrc);
@@ -1341,11 +1344,64 @@ private void setLocalSourceID(String ssrc)
* @param ssrc the SSRC identifier that this stream will be using in
* outgoing RTP packets from now on.
*/
- private void setRemoteSourceID(String ssrc)
+ private void setRemoteSourceID(long ssrc)
{
- String oldValue = this.remoteSourceID;
+ Long oldValue = this.remoteSourceID;
this.remoteSourceID = ssrc;
firePropertyChange(PNAME_REMOTE_SSRC, oldValue, ssrc);
}
+
+ /**
+ * Returns the list of CSRC identifiers for all parties currently known
+ * to contribute to the media that this stream is sending toward its remote
+ * counter part. In other words, the method returns the list of CSRC IDs
+ * that this stream will include in outgoing RTP packets. This method will
+ * return an empty List in case this stream is not part of a mixed
+ * conference call.
+ *
+ * @return a List of CSRC IDs for parties that are currently known
+ * to contribute to the media that this stream is currently streaming or
+ * an empty List in case this MediaStream is not part of
+ * a conference call.
+ */
+ public List getLocalContributingSourceIDs()
+ {
+ List csrcList = new ArrayList();
+
+ MediaDeviceSession deviceSession = getDeviceSession();
+ if( this.deviceSession != null)
+ csrcList.addAll( deviceSession.getRemoteSSRCList() );
+
+ Iterator csrcIter = csrcList.iterator();
+
+ //in case of a conf call the mixer would return all SSRC IDs that are
+ //currently contributing including this stream's counterpart. This
+ //method is about
+ while(csrcIter.hasNext())
+ {
+ String csrc = csrcIter.next();
+
+ if (csrc.equals(getRemoteSourceID()))
+ csrcIter.remove();
+ }
+
+ return csrcList;
+ }
+
+ /**
+ * Returns the List of CSRC identifiers representing the parties
+ * contributing to the stream that we are receiving from this
+ * MediaStream's remote party.
+ *
+ * @return a List of CSRC identifiers representing the parties
+ * contributing to the stream that we are receiving from this
+ * MediaStream's remote party.
+ */
+ public List getRemoteContributingSourceIDs()
+ {
+ List csrcList = new ArrayList();
+
+ return csrcList;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/neomedia/RawPacket.java b/src/net/java/sip/communicator/impl/neomedia/RawPacket.java
index d46d5d2d8..d374bd5c6 100755
--- a/src/net/java/sip/communicator/impl/neomedia/RawPacket.java
+++ b/src/net/java/sip/communicator/impl/neomedia/RawPacket.java
@@ -6,6 +6,9 @@
*/
package net.java.sip.communicator.impl.neomedia;
+import java.math.*;
+import java.util.*;
+
/**
* When using TransformConnector, a RTP/RTCP packet is represented using
* RawPacket. RawPacket stores the buffer holding the RTP/RTCP packet, as well
@@ -19,6 +22,7 @@
*
* @author Werner Dittmann (Werner.Dittmann@t-online.de)
* @author Bing SU (nova.su@gmail.com)
+ * @author Emil Ivov
*/
public class RawPacket
{
@@ -39,6 +43,11 @@ public class RawPacket
*/
protected int length;
+ /**
+ * The size of the fixed part of the RTP header as defined by RFC 3550.
+ */
+ public static final int FIXED_HEADER_SIZE = 12;
+
/**
* Construct a RawPacket using specified value.
*
@@ -237,4 +246,100 @@ public void shrink(int len)
this.length = 0;
}
}
+
+ /**
+ * Returns the number of CSRC identifiers currently included in this packet.
+ *
+ * @return the CSRC count for this RawPacket.
+ */
+ public int getCsrcCount()
+ {
+ return (buffer[offset] & 0x0fb);
+ }
+
+ /**
+ * Replaces the existing CSRC list (even if empty) with newCsrcList
+ * and updates the CC (CSRC count) field of this RawPacket
+ * accordingly.
+ *
+ * @param newCsrcList the list of CSRC identifiers that we'd like to set for
+ * this RawPacket.
+ */
+ public void setCsrcList(long[] newCsrcList)
+ {
+ int newCsrcCount = newCsrcList.length;
+ byte[] csrcBuff = new byte[newCsrcCount * 4];
+ int csrcOffset = 0;
+
+ for(long csrc : newCsrcList)
+ {
+ csrcBuff[csrcOffset] = (byte)(csrc >> 24);
+ csrcBuff[csrcOffset+1] = (byte)(csrc >> 16);
+ csrcBuff[csrcOffset+2] = (byte)(csrc >> 8);
+ csrcBuff[csrcOffset+3] = (byte)csrc;
+
+ csrcOffset += 4;
+ }
+
+ int oldCsrcCount = getCsrcCount();
+
+ byte[] oldBuffer = this.getBuffer();
+
+ //the new buffer needs to be bigger than the new one in order to
+ //accommodate the list of CSRC IDs (unless there were more of them
+ //previously than after setting the new list).
+ byte[] newBuffer
+ = new byte[oldBuffer.length + csrcBuff.length - oldCsrcCount*4];
+
+ //copy the part up to the CSRC list
+ System.arraycopy(
+ oldBuffer, 0, newBuffer, 0, offset + FIXED_HEADER_SIZE);
+
+ //copy the new CSRC list
+ System.arraycopy( csrcBuff, 0, newBuffer,
+ offset + FIXED_HEADER_SIZE, csrcBuff.length);
+
+ //now copy the payload from the old buff and make sure we don't copy
+ //the CSRC list if there was one in the old packet
+ int payloadOffsetForOldBuff
+ = offset + FIXED_HEADER_SIZE + oldCsrcCount*4;
+
+ int payloadOffsetForNewBuff
+ = offset + FIXED_HEADER_SIZE + newCsrcCount*4;
+
+ System.arraycopy( oldBuffer, payloadOffsetForOldBuff,
+ newBuffer, payloadOffsetForNewBuff,
+ csrcBuff.length - payloadOffsetForOldBuff);
+
+ //set the new CSRC count
+ newBuffer[offset] = (byte)((newBuffer[offset] & 0xF0b)
+ & newCsrcCount);
+ }
+
+ /**
+ * Returns the list of CSRC IDs, currently encapsulated in this packet.
+ *
+ * @return an array containing the list of CSRC IDs, currently encapsulated
+ * in this packet.
+ */
+ public long[] extractCsrcList()
+ {
+ int csrcCount = getCsrcCount();
+ byte[] buffer = getBuffer();
+
+ long[] csrcList = new long[csrcCount];
+
+ int csrcStartIndex = offset + FIXED_HEADER_SIZE;
+ for (int i = 0; i < csrcCount; i++)
+ {
+ csrcList[i] = buffer[csrcStartIndex] << 24
+ & buffer[csrcStartIndex + 1] << 16
+ & buffer[csrcStartIndex + 2] << 8
+ & buffer[csrcStartIndex + 3];
+
+ csrcStartIndex += 4;
+ }
+
+ return csrcList;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/TransformEngineChain.java b/src/net/java/sip/communicator/impl/neomedia/transform/TransformEngineChain.java
index 2c545c32c..f77470783 100644
--- a/src/net/java/sip/communicator/impl/neomedia/transform/TransformEngineChain.java
+++ b/src/net/java/sip/communicator/impl/neomedia/transform/TransformEngineChain.java
@@ -116,7 +116,10 @@ public RawPacket transform(RawPacket pkt)
? engine.getRTPTransformer()
: engine.getRTCPTransformer();
- pkt = pTransformer.transform(pkt);
+ //the packet transformer may be null if for example the engine
+ //only does RTP transformations and this is an RTCP transformer.
+ if( pTransformer != null)
+ pkt = pTransformer.transform(pkt);
}
return pkt;
@@ -144,7 +147,10 @@ public RawPacket reverseTransform(RawPacket pkt)
? engine.getRTPTransformer()
: engine.getRTCPTransformer();
- pkt = pTransformer.reverseTransform(pkt);
+ //the packet transformer may be null if for example the engine
+ //only does RTP transformations and this is an RTCP transformer.
+ if( pTransformer != null)
+ pkt = pTransformer.reverseTransform(pkt);
}
return pkt;
diff --git a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyConferencingSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyConferencingSipImpl.java
index 83346ada1..c4b202ea9 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyConferencingSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/OperationSetTelephonyConferencingSipImpl.java
@@ -626,7 +626,7 @@ private void getMediaXML(CallPeerSipImpl callPeer, StringBuffer xml)
//
append(xml, "", ELEMENT_TYPE, ">");
- String srcId = stream.getRemoteSourceID();
+ String srcId = Long.toString(stream.getRemoteSourceID());
if (srcId != null)
{
diff --git a/src/net/java/sip/communicator/service/neomedia/MediaStream.java b/src/net/java/sip/communicator/service/neomedia/MediaStream.java
index c5fa7fde2..1b93e04a7 100644
--- a/src/net/java/sip/communicator/service/neomedia/MediaStream.java
+++ b/src/net/java/sip/communicator/service/neomedia/MediaStream.java
@@ -97,25 +97,25 @@ public interface MediaStream
/**
* Returns the synchronization source (SSRC) identifier of the remote
- * participant or null if that identifier is not yet known at this
+ * participant or -1 if that identifier is not yet known at this
* point.
*
* @return the synchronization source (SSRC) identifier of the remote
- * participant or null if that identifier is not yet known at this
+ * participant or -1 if that identifier is not yet known at this
* point.
*/
- public String getRemoteSourceID();
+ public long getRemoteSourceID();
/**
* Returns the synchronization source (SSRC) identifier of the local
- * participant or null if that identifier is not yet known at this
+ * participant or -1 if that identifier is not yet known at this
* point.
*
* @return the synchronization source (SSRC) identifier of the local
- * participant or null if that identifier is not yet known at this
+ * participant or -1 if that identifier is not yet known at this
* point.
*/
- public String getLocalSourceID();
+ public long getLocalSourceID();
/**
* Returns the address that this stream is sending RTCP traffic to.