mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-26 14:02:06 +01:00
STUN fix and Media Tunning
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@7610 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
cb2df91084
commit
9627fef139
9 changed files with 239 additions and 126 deletions
|
@ -100,13 +100,14 @@ public class IncomingJingleSession extends JingleSession {
|
||||||
* @param conn the XMPP connection
|
* @param conn the XMPP connection
|
||||||
* @param responder the responder
|
* @param responder the responder
|
||||||
* @param transportManager The transport manager
|
* @param transportManager The transport manager
|
||||||
|
* @param initialJingleSessionRequest the initial Jingle Session Request
|
||||||
*/
|
*/
|
||||||
protected IncomingJingleSession(XMPPConnection conn, String responder,
|
protected IncomingJingleSession(XMPPConnection conn, String responder,
|
||||||
List payloadTypes, JingleTransportManager transportManager, String sid) {
|
List payloadTypes, JingleTransportManager transportManager, JingleSessionRequest initialJingleSessionRequest) throws XMPPException {
|
||||||
|
|
||||||
super(conn, responder, conn.getUser());
|
super(conn, responder, conn.getUser());
|
||||||
|
|
||||||
setSid(sid);
|
setSid(initialJingleSessionRequest.getSessionID());
|
||||||
|
|
||||||
// Create the states...
|
// Create the states...
|
||||||
|
|
||||||
|
@ -130,6 +131,24 @@ public class IncomingJingleSession extends JingleSession {
|
||||||
setTransportNeg(new TransportNegotiator.Ice(this, resolver));
|
setTransportNeg(new TransportNegotiator.Ice(this, resolver));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Establish the default state
|
||||||
|
setState(accepting);
|
||||||
|
|
||||||
|
updatePacketListener();
|
||||||
|
|
||||||
|
Jingle packet = initialJingleSessionRequest.getJingle();
|
||||||
|
if (packet != null) {
|
||||||
|
|
||||||
|
// Initialize the session information
|
||||||
|
setSid(packet.getSid());
|
||||||
|
|
||||||
|
respond(packet);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new XMPPException(
|
||||||
|
"Session request with null Jingle packet.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,10 +158,11 @@ public class IncomingJingleSession extends JingleSession {
|
||||||
* @param responder the responder
|
* @param responder the responder
|
||||||
* @param transportManager The transport manager
|
* @param transportManager The transport manager
|
||||||
* @param jingleMediaManager The Media Manager for this Session
|
* @param jingleMediaManager The Media Manager for this Session
|
||||||
|
* @param initialJingleSessionRequest the initial Jingle Session Request
|
||||||
*/
|
*/
|
||||||
protected IncomingJingleSession(XMPPConnection conn, String responder,
|
protected IncomingJingleSession(XMPPConnection conn, String responder,
|
||||||
List payloadTypes, JingleTransportManager transportManager, JingleMediaManager jingleMediaManager, String sid) {
|
List payloadTypes, JingleTransportManager transportManager, JingleMediaManager jingleMediaManager, JingleSessionRequest initialJingleSessionRequest) throws XMPPException {
|
||||||
this(conn, responder, payloadTypes, transportManager, sid);
|
this(conn, responder, payloadTypes, transportManager, initialJingleSessionRequest);
|
||||||
this.jingleMediaManager = jingleMediaManager;
|
this.jingleMediaManager = jingleMediaManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,27 +173,6 @@ public class IncomingJingleSession extends JingleSession {
|
||||||
* @throws XMPPException
|
* @throws XMPPException
|
||||||
*/
|
*/
|
||||||
public void start(JingleSessionRequest initialJingleSessionRequest) throws XMPPException {
|
public void start(JingleSessionRequest initialJingleSessionRequest) throws XMPPException {
|
||||||
if (invalidState()) {
|
|
||||||
Jingle packet = initialJingleSessionRequest.getJingle();
|
|
||||||
if (packet != null) {
|
|
||||||
|
|
||||||
// Initialize the session information
|
|
||||||
setSid(packet.getSid());
|
|
||||||
|
|
||||||
// Establish the default state
|
|
||||||
setState(accepting);
|
|
||||||
|
|
||||||
updatePacketListener();
|
|
||||||
respond(packet);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Session request with null Jingle packet.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new IllegalStateException("Starting session without null state.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -182,7 +181,15 @@ public class IncomingJingleSession extends JingleSession {
|
||||||
* @throws XMPPException
|
* @throws XMPPException
|
||||||
*/
|
*/
|
||||||
public void start() throws XMPPException {
|
public void start() throws XMPPException {
|
||||||
start(this.getInitialSessionRequest());
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force a call acceptance. Used to accept a hooked call.
|
||||||
|
* @deprecated Avoid to use this method. Not compliance.
|
||||||
|
*/
|
||||||
|
public void accept(){
|
||||||
|
setState(active);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -649,10 +649,10 @@ public class JingleManager implements JingleSessionListener {
|
||||||
|
|
||||||
if (jingleMediaManager != null)
|
if (jingleMediaManager != null)
|
||||||
session = new IncomingJingleSession(connection, request
|
session = new IncomingJingleSession(connection, request
|
||||||
.getFrom(), payloadTypes, jingleTransportManager, jingleMediaManager, request.getSessionID());
|
.getFrom(), payloadTypes, jingleTransportManager, jingleMediaManager, request);
|
||||||
else
|
else
|
||||||
session = new IncomingJingleSession(connection, request
|
session = new IncomingJingleSession(connection, request
|
||||||
.getFrom(), payloadTypes, jingleTransportManager, request.getSessionID());
|
.getFrom(), payloadTypes, jingleTransportManager, request);
|
||||||
|
|
||||||
triggerSessionCreated(session);
|
triggerSessionCreated(session);
|
||||||
|
|
||||||
|
|
|
@ -389,21 +389,25 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
if (invalidState()) {
|
if (invalidState()) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Illegal state in dispatch packet in Session manager.");
|
"Illegal state in dispatch packet in Session manager.");
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (iq == null) {
|
if (iq == null) {
|
||||||
// If there is no input packet, then we must be inviting...
|
// If there is no input packet, then we must be inviting...
|
||||||
jout = getState().eventInvite();
|
jout = getState().eventInvite();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (iq.getType().equals(IQ.Type.ERROR)) {
|
if (iq.getType().equals(IQ.Type.ERROR)) {
|
||||||
// Process errors
|
// Process errors
|
||||||
getState().eventError(iq);
|
getState().eventError(iq);
|
||||||
} else if (iq.getType().equals(IQ.Type.RESULT)) {
|
}
|
||||||
|
else if (iq.getType().equals(IQ.Type.RESULT)) {
|
||||||
// Process ACKs
|
// Process ACKs
|
||||||
if (isExpectedId(iq.getPacketID())) {
|
if (isExpectedId(iq.getPacketID())) {
|
||||||
jout = getState().eventAck(iq);
|
jout = getState().eventAck(iq);
|
||||||
removeExpectedId(iq.getPacketID());
|
removeExpectedId(iq.getPacketID());
|
||||||
}
|
}
|
||||||
} else if (iq instanceof Jingle) {
|
}
|
||||||
|
else if (iq instanceof Jingle) {
|
||||||
// It is not an error: it is a Jingle packet...
|
// It is not an error: it is a Jingle packet...
|
||||||
Jingle jin = (Jingle) iq;
|
Jingle jin = (Jingle) iq;
|
||||||
Jingle.Action action = jin.getAction();
|
Jingle.Action action = jin.getAction();
|
||||||
|
@ -411,17 +415,22 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
if (action != null) {
|
if (action != null) {
|
||||||
if (action.equals(Jingle.Action.SESSIONACCEPT)) {
|
if (action.equals(Jingle.Action.SESSIONACCEPT)) {
|
||||||
jout = getState().eventAccept(jin);
|
jout = getState().eventAccept(jin);
|
||||||
} else if (action.equals(Jingle.Action.SESSIONINFO)) {
|
}
|
||||||
|
else if (action.equals(Jingle.Action.SESSIONINFO)) {
|
||||||
jout = getState().eventInfo(jin);
|
jout = getState().eventInfo(jin);
|
||||||
} else if (action.equals(Jingle.Action.SESSIONINITIATE)) {
|
}
|
||||||
|
else if (action.equals(Jingle.Action.SESSIONINITIATE)) {
|
||||||
if (getState() != null)
|
if (getState() != null)
|
||||||
jout = getState().eventInitiate(jin);
|
jout = getState().eventInitiate(jin);
|
||||||
} else if (action.equals(Jingle.Action.SESSIONREDIRECT)) {
|
}
|
||||||
|
else if (action.equals(Jingle.Action.SESSIONREDIRECT)) {
|
||||||
jout = getState().eventRedirect(jin);
|
jout = getState().eventRedirect(jin);
|
||||||
} else if (action.equals(Jingle.Action.SESSIONTERMINATE)) {
|
}
|
||||||
|
else if (action.equals(Jingle.Action.SESSIONTERMINATE)) {
|
||||||
jout = getState().eventTerminate(jin);
|
jout = getState().eventTerminate(jin);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
jout = errorMalformedStanza(iq);
|
jout = errorMalformedStanza(iq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -514,7 +523,8 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
jSes.addTransports(jTrans.getTransportsList());
|
jSes.addTransports(jTrans.getTransportsList());
|
||||||
|
|
||||||
response = sendFormattedJingle(iq, jSes);
|
response = sendFormattedJingle(iq, jSes);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// If we don't have a valid session message, then we must send
|
// If we don't have a valid session message, then we must send
|
||||||
// separated messages for transport and jmf...
|
// separated messages for transport and jmf...
|
||||||
if (jDesc != null) {
|
if (jDesc != null) {
|
||||||
|
@ -580,7 +590,8 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
if (jout.getTo() == null) {
|
if (jout.getTo() == null) {
|
||||||
if (iq != null) {
|
if (iq != null) {
|
||||||
jout.setTo(iq.getFrom());
|
jout.setTo(iq.getFrom());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
jout.setTo(other);
|
jout.setTo(other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -588,7 +599,8 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
if (jout.getFrom() == null) {
|
if (jout.getFrom() == null) {
|
||||||
if (iq != null) {
|
if (iq != null) {
|
||||||
jout.setFrom(iq.getTo());
|
jout.setFrom(iq.getTo());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
jout.setFrom(me);
|
jout.setFrom(me);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -681,7 +693,8 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
if (jda.size() > 1) {
|
if (jda.size() > 1) {
|
||||||
throw new XMPPException(
|
throw new XMPPException(
|
||||||
"Unsupported feature: the number of accepted content descriptions is greater than 1.");
|
"Unsupported feature: the number of accepted content descriptions is greater than 1.");
|
||||||
} else if (jda.size() == 1) {
|
}
|
||||||
|
else if (jda.size() == 1) {
|
||||||
JingleContentDescription jd = (JingleContentDescription) jda.get(0);
|
JingleContentDescription jd = (JingleContentDescription) jda.get(0);
|
||||||
if (jd.getJinglePayloadTypesCount() > 1) {
|
if (jd.getJinglePayloadTypesCount() > 1) {
|
||||||
throw new XMPPException(
|
throw new XMPPException(
|
||||||
|
@ -713,13 +726,15 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
if (jta.size() > 1) {
|
if (jta.size() > 1) {
|
||||||
throw new XMPPException(
|
throw new XMPPException(
|
||||||
"Unsupported feature: the number of accepted transports is greater than 1.");
|
"Unsupported feature: the number of accepted transports is greater than 1.");
|
||||||
} else if (jta.size() == 1) {
|
}
|
||||||
|
else if (jta.size() == 1) {
|
||||||
org.jivesoftware.smackx.packet.JingleTransport jt = (org.jivesoftware.smackx.packet.JingleTransport) jta.get(0);
|
org.jivesoftware.smackx.packet.JingleTransport jt = (org.jivesoftware.smackx.packet.JingleTransport) jta.get(0);
|
||||||
|
|
||||||
if (jt.getCandidatesCount() > 1) {
|
if (jt.getCandidatesCount() > 1) {
|
||||||
throw new XMPPException(
|
throw new XMPPException(
|
||||||
"Unsupported feature: the number of accepted transport candidates is greater than 1.");
|
"Unsupported feature: the number of accepted transport candidates is greater than 1.");
|
||||||
} else if (jt.getCandidatesCount() == 1) {
|
}
|
||||||
|
else if (jt.getCandidatesCount() == 1) {
|
||||||
JingleTransportCandidate jtc = (JingleTransportCandidate) jt
|
JingleTransportCandidate jtc = (JingleTransportCandidate) jt
|
||||||
.getCandidatesList().get(0);
|
.getCandidatesList().get(0);
|
||||||
acceptedLocalCandidate = jtc.getMediaTransport();
|
acceptedLocalCandidate = jtc.getMediaTransport();
|
||||||
|
@ -761,7 +776,8 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
if (other.initiator != null) {
|
if (other.initiator != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!initiator.equals(other.initiator)) {
|
}
|
||||||
|
else if (!initiator.equals(other.initiator)) {
|
||||||
//Todo check behavior
|
//Todo check behavior
|
||||||
// return false;
|
// return false;
|
||||||
}
|
}
|
||||||
|
@ -770,7 +786,8 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
if (other.responder != null) {
|
if (other.responder != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!responder.equals(other.responder)) {
|
}
|
||||||
|
else if (!responder.equals(other.responder)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,7 +795,8 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
if (other.sid != null) {
|
if (other.sid != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!sid.equals(other.sid)) {
|
}
|
||||||
|
else if (!sid.equals(other.sid)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,12 +940,14 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
System.out.println("Ignored Jingle(INI): " + iq.toXML());
|
System.out.println("Ignored Jingle(INI): " + iq.toXML());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// We accept some non-Jingle IQ packets: ERRORs and ACKs
|
// We accept some non-Jingle IQ packets: ERRORs and ACKs
|
||||||
if (iq.getType().equals(IQ.Type.SET)) {
|
if (iq.getType().equals(IQ.Type.SET)) {
|
||||||
System.out.println("Ignored Jingle(TYPE): " + iq.toXML());
|
System.out.println("Ignored Jingle(TYPE): " + iq.toXML());
|
||||||
return false;
|
return false;
|
||||||
} else if (iq.getType().equals(IQ.Type.GET)) {
|
}
|
||||||
|
else if (iq.getType().equals(IQ.Type.GET)) {
|
||||||
System.out.println("Ignored Jingle(TYPE): " + iq.toXML());
|
System.out.println("Ignored Jingle(TYPE): " + iq.toXML());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1049,12 +1069,12 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jingleMediaManager != null) {
|
if (jingleMediaManager != null) {
|
||||||
jingleMediaSession = jingleMediaManager.createMediaSession(pt, rc, lc);
|
|
||||||
if (jingleMediaSession != null) {
|
|
||||||
|
|
||||||
rc.removeCandidateEcho();
|
rc.removeCandidateEcho();
|
||||||
lc.removeCandidateEcho();
|
lc.removeCandidateEcho();
|
||||||
|
|
||||||
|
jingleMediaSession = jingleMediaManager.createMediaSession(pt, rc, lc);
|
||||||
|
if (jingleMediaSession != null) {
|
||||||
|
|
||||||
jingleMediaSession.startTrasmit();
|
jingleMediaSession.startTrasmit();
|
||||||
jingleMediaSession.startReceive();
|
jingleMediaSession.startReceive();
|
||||||
|
|
||||||
|
@ -1113,9 +1133,7 @@ public abstract class JingleSession extends JingleNegotiator {
|
||||||
*/
|
*/
|
||||||
public void terminate() throws XMPPException {
|
public void terminate() throws XMPPException {
|
||||||
if (isClosed()) return;
|
if (isClosed()) return;
|
||||||
//remo
|
|
||||||
System.out.println("State: " + this.getState());
|
System.out.println("State: " + this.getState());
|
||||||
Jingle result = null;
|
|
||||||
Jingle jout = new Jingle(Jingle.Action.SESSIONTERMINATE);
|
Jingle jout = new Jingle(Jingle.Action.SESSIONTERMINATE);
|
||||||
jout.setType(IQ.Type.SET);
|
jout.setType(IQ.Type.SET);
|
||||||
sendFormattedJingle(jout);
|
sendFormattedJingle(jout);
|
||||||
|
|
|
@ -21,6 +21,8 @@ package org.jivesoftware.smackx.jingle.mediaimpl.jmf;
|
||||||
|
|
||||||
import javax.media.*;
|
import javax.media.*;
|
||||||
import javax.media.control.TrackControl;
|
import javax.media.control.TrackControl;
|
||||||
|
import javax.media.control.PacketSizeControl;
|
||||||
|
import javax.media.control.BufferControl;
|
||||||
import javax.media.format.AudioFormat;
|
import javax.media.format.AudioFormat;
|
||||||
import javax.media.protocol.ContentDescriptor;
|
import javax.media.protocol.ContentDescriptor;
|
||||||
import javax.media.protocol.DataSource;
|
import javax.media.protocol.DataSource;
|
||||||
|
@ -57,7 +59,7 @@ public class AudioChannel {
|
||||||
|
|
||||||
private MediaLocator locator;
|
private MediaLocator locator;
|
||||||
private String localIpAddress;
|
private String localIpAddress;
|
||||||
private String ipAddress;
|
private String remoteIpAddress;
|
||||||
private int localPort;
|
private int localPort;
|
||||||
private int portBase;
|
private int portBase;
|
||||||
private Format format;
|
private Format format;
|
||||||
|
@ -76,30 +78,25 @@ public class AudioChannel {
|
||||||
*
|
*
|
||||||
* @param locator media locator
|
* @param locator media locator
|
||||||
* @param localIpAddress local IP address
|
* @param localIpAddress local IP address
|
||||||
* @param ipAddress remote IP address
|
* @param remoteIpAddress remote IP address
|
||||||
* @param localPort local port number
|
* @param localPort local port number
|
||||||
* @param remotePort remote port number
|
* @param remotePort remote port number
|
||||||
* @param format audio format
|
* @param format audio format
|
||||||
*/
|
*/
|
||||||
public AudioChannel(MediaLocator locator,
|
public AudioChannel(MediaLocator locator,
|
||||||
String localIpAddress,
|
String localIpAddress,
|
||||||
String ipAddress,
|
String remoteIpAddress,
|
||||||
int localPort,
|
int localPort,
|
||||||
int remotePort,
|
int remotePort,
|
||||||
Format format) {
|
Format format) {
|
||||||
|
|
||||||
this.locator = locator;
|
this.locator = locator;
|
||||||
this.localIpAddress = localIpAddress;
|
this.localIpAddress = localIpAddress;
|
||||||
this.ipAddress = ipAddress;
|
this.remoteIpAddress = remoteIpAddress;
|
||||||
this.localPort = localPort;
|
this.localPort = localPort;
|
||||||
this.portBase = remotePort;
|
this.portBase = remotePort;
|
||||||
this.format = format;
|
this.format = format;
|
||||||
|
|
||||||
// Create a processor for the specified jmf locator
|
|
||||||
String result = createProcessor();
|
|
||||||
if (result != null) {
|
|
||||||
started = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -111,8 +108,14 @@ public class AudioChannel {
|
||||||
*/
|
*/
|
||||||
public synchronized String start() {
|
public synchronized String start() {
|
||||||
if (started) return null;
|
if (started) return null;
|
||||||
|
|
||||||
|
// Create a processor for the specified jmf locator
|
||||||
|
String result = createProcessor();
|
||||||
|
if (result != null) {
|
||||||
|
started = false;
|
||||||
|
}
|
||||||
|
|
||||||
started = true;
|
started = true;
|
||||||
String result;
|
|
||||||
|
|
||||||
// Create an RTP session to transmit the output of the
|
// Create an RTP session to transmit the output of the
|
||||||
// processor to the specified IP address and port no.
|
// processor to the specified IP address and port no.
|
||||||
|
@ -121,7 +124,6 @@ public class AudioChannel {
|
||||||
processor.close();
|
processor.close();
|
||||||
processor = null;
|
processor = null;
|
||||||
started = false;
|
started = false;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the transmission
|
// Start the transmission
|
||||||
|
@ -226,6 +228,39 @@ public class AudioChannel {
|
||||||
tracks[i].setFormat(chosen);
|
tracks[i].setFormat(chosen);
|
||||||
System.err.println("Track " + i + " is set to transmit as:");
|
System.err.println("Track " + i + " is set to transmit as:");
|
||||||
System.err.println(" " + chosen);
|
System.err.println(" " + chosen);
|
||||||
|
|
||||||
|
if (tracks[i].getFormat() instanceof AudioFormat) {
|
||||||
|
int packetRate = 20;
|
||||||
|
PacketSizeControl pktCtrl = (PacketSizeControl) processor.getControl(PacketSizeControl.class.getName());
|
||||||
|
if (pktCtrl != null) {
|
||||||
|
try {
|
||||||
|
pktCtrl.setPacketSize(getPacketSize(tracks[i].getFormat(), packetRate));
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
pktCtrl.setPacketSize(80);
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tracks[i].getFormat().getEncoding().equals(AudioFormat.ULAW_RTP)) {
|
||||||
|
Codec codec[] = new Codec[3];
|
||||||
|
|
||||||
|
codec[0] = new com.ibm.media.codec.audio.rc.RCModule();
|
||||||
|
codec[1] = new com.ibm.media.codec.audio.ulaw.JavaEncoder();
|
||||||
|
codec[2] = new com.sun.media.codec.audio.ulaw.Packetizer();
|
||||||
|
((com.sun.media.codec.audio.ulaw.Packetizer) codec
|
||||||
|
[2]).setPacketSize(160);
|
||||||
|
|
||||||
|
try {
|
||||||
|
tracks[i].setCodecChain(codec);
|
||||||
|
}
|
||||||
|
catch (UnsupportedPlugInException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
atLeastOneTrack = true;
|
atLeastOneTrack = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -249,6 +284,28 @@ public class AudioChannel {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the best packet size for a given codec and a codec rate
|
||||||
|
*
|
||||||
|
* @param codecFormat
|
||||||
|
* @param milliseconds
|
||||||
|
* @return
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
*/
|
||||||
|
private int getPacketSize(Format codecFormat, int milliseconds) throws IllegalArgumentException {
|
||||||
|
String encoding = codecFormat.getEncoding();
|
||||||
|
if (encoding.equalsIgnoreCase(AudioFormat.GSM) ||
|
||||||
|
encoding.equalsIgnoreCase(AudioFormat.GSM_RTP)) {
|
||||||
|
return milliseconds * 4; // 1 byte per millisec
|
||||||
|
}
|
||||||
|
else if (encoding.equalsIgnoreCase(AudioFormat.ULAW) ||
|
||||||
|
encoding.equalsIgnoreCase(AudioFormat.ULAW_RTP)) {
|
||||||
|
return milliseconds * 8;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalArgumentException("Unknown codec type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use the RTPManager API to create sessions for each jmf
|
* Use the RTPManager API to create sessions for each jmf
|
||||||
|
@ -274,7 +331,7 @@ public class AudioChannel {
|
||||||
rtpMgrs[i] = RTPManager.newInstance();
|
rtpMgrs[i] = RTPManager.newInstance();
|
||||||
|
|
||||||
port = portBase + 2 * i;
|
port = portBase + 2 * i;
|
||||||
ipAddr = InetAddress.getByName(ipAddress);
|
ipAddr = InetAddress.getByName(remoteIpAddress);
|
||||||
|
|
||||||
localAddr = new SessionAddress(InetAddress.getByName(this.localIpAddress),
|
localAddr = new SessionAddress(InetAddress.getByName(this.localIpAddress),
|
||||||
localPort);
|
localPort);
|
||||||
|
@ -284,11 +341,17 @@ public class AudioChannel {
|
||||||
rtpMgrs[i].addReceiveStreamListener(audioReceiver);
|
rtpMgrs[i].addReceiveStreamListener(audioReceiver);
|
||||||
rtpMgrs[i].addSessionListener(audioReceiver);
|
rtpMgrs[i].addSessionListener(audioReceiver);
|
||||||
|
|
||||||
|
BufferControl bc = (BufferControl) rtpMgrs[i].getControl("javax.media.control.BufferControl");
|
||||||
|
if (bc != null) {
|
||||||
|
int bl = 160;
|
||||||
|
bc.setBufferLength(bl);
|
||||||
|
}
|
||||||
|
|
||||||
rtpMgrs[i].initialize(localAddr);
|
rtpMgrs[i].initialize(localAddr);
|
||||||
|
|
||||||
rtpMgrs[i].addTarget(destAddr);
|
rtpMgrs[i].addTarget(destAddr);
|
||||||
|
|
||||||
System.err.println("Created RTP session at " + localPort + " to: " + ipAddress + " " + port);
|
System.err.println("Created RTP session at " + localPort + " to: " + remoteIpAddress + " " + port);
|
||||||
|
|
||||||
sendStream = rtpMgrs[i].createSendStream(dataOutput, i);
|
sendStream = rtpMgrs[i].createSendStream(dataOutput, i);
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ import java.net.ServerSocket;
|
||||||
public class AudioMediaSession extends JingleMediaSession {
|
public class AudioMediaSession extends JingleMediaSession {
|
||||||
|
|
||||||
private AudioChannel audioChannel;
|
private AudioChannel audioChannel;
|
||||||
private String locator = "javasound://";
|
private String locator = "dsound://";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates
|
* Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates
|
||||||
|
@ -52,7 +52,7 @@ public class AudioMediaSession extends JingleMediaSession {
|
||||||
*/
|
*/
|
||||||
public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote,
|
public AudioMediaSession(final PayloadType payloadType, final TransportCandidate remote,
|
||||||
final TransportCandidate local) {
|
final TransportCandidate local) {
|
||||||
this(payloadType, remote, local, "javasound://");
|
this(payloadType, remote, local, "dsound://");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,7 +42,11 @@ public class BridgedTransportManager extends JingleTransportManager implements J
|
||||||
this.xmppConnection = xmppConnection;
|
this.xmppConnection = xmppConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the correspondent resolver
|
/**
|
||||||
|
* Return the correspondent resolver
|
||||||
|
* @param session correspondent Jingle Session
|
||||||
|
* @return resolver
|
||||||
|
*/
|
||||||
protected TransportResolver createResolver(JingleSession session) {
|
protected TransportResolver createResolver(JingleSession session) {
|
||||||
BridgedResolver bridgedResolver = new BridgedResolver(this.xmppConnection);
|
BridgedResolver bridgedResolver = new BridgedResolver(this.xmppConnection);
|
||||||
return bridgedResolver;
|
return bridgedResolver;
|
||||||
|
|
|
@ -176,8 +176,6 @@ public class ICEResolver extends TransportResolver {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Public Candidate From XMPP Server
|
// Get Public Candidate From XMPP Server
|
||||||
|
|
||||||
if (iceNegociator.getPublicCandidate() == null) {
|
if (iceNegociator.getPublicCandidate() == null) {
|
||||||
|
@ -234,6 +232,9 @@ public class ICEResolver extends TransportResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
this.setResolveEnd();
|
this.setResolveEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -512,6 +512,8 @@ public class RTPBridge extends IQ {
|
||||||
// Cancel the collector.
|
// Cancel the collector.
|
||||||
collector.cancel();
|
collector.cancel();
|
||||||
|
|
||||||
|
if(response == null) return null;
|
||||||
|
|
||||||
if (response.getIp() == null || response.getIp().equals("")) return null;
|
if (response.getIp() == null || response.getIp().equals("")) return null;
|
||||||
|
|
||||||
Enumeration ifaces = null;
|
Enumeration ifaces = null;
|
||||||
|
|
|
@ -21,15 +21,13 @@
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.test.SmackTestCase;
|
import org.jivesoftware.smack.test.SmackTestCase;
|
||||||
import org.jivesoftware.smackx.jingle.IncomingJingleSession;
|
import org.jivesoftware.smackx.jingle.*;
|
||||||
import org.jivesoftware.smackx.jingle.JingleManager;
|
|
||||||
import org.jivesoftware.smackx.jingle.JingleSessionRequest;
|
|
||||||
import org.jivesoftware.smackx.jingle.OutgoingJingleSession;
|
|
||||||
import org.jivesoftware.smackx.jingle.mediaimpl.jmf.JmfMediaManager;
|
import org.jivesoftware.smackx.jingle.mediaimpl.jmf.JmfMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.mediaimpl.jmf.AudioChannel;
|
import org.jivesoftware.smackx.jingle.mediaimpl.jmf.AudioChannel;
|
||||||
import org.jivesoftware.smackx.jingle.mediaimpl.jspeex.SpeexMediaManager;
|
import org.jivesoftware.smackx.jingle.mediaimpl.jspeex.SpeexMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.mediaimpl.multi.MultiMediaManager;
|
import org.jivesoftware.smackx.jingle.mediaimpl.multi.MultiMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
|
import org.jivesoftware.smackx.jingle.listeners.JingleSessionRequestListener;
|
||||||
|
import org.jivesoftware.smackx.jingle.listeners.JingleSessionStateListener;
|
||||||
import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
|
import org.jivesoftware.smackx.jingle.media.JingleMediaManager;
|
||||||
import org.jivesoftware.smackx.jingle.nat.BridgedTransportManager;
|
import org.jivesoftware.smackx.jingle.nat.BridgedTransportManager;
|
||||||
import org.jivesoftware.smackx.jingle.nat.ICETransportManager;
|
import org.jivesoftware.smackx.jingle.nat.ICETransportManager;
|
||||||
|
@ -56,7 +54,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
XMPPConnection x0 = getConnection(0);
|
XMPPConnection x0 = getConnection(0);
|
||||||
XMPPConnection x1 = getConnection(1);
|
XMPPConnection x1 = getConnection(1);
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 1; i++)
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ICETransportManager icetm0 = new ICETransportManager(x0, "jivesoftware.com", 3478);
|
ICETransportManager icetm0 = new ICETransportManager(x0, "jivesoftware.com", 3478);
|
||||||
|
@ -78,10 +76,22 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
JingleSessionRequestListener jingleSessionRequestListener = new JingleSessionRequestListener() {
|
JingleSessionRequestListener jingleSessionRequestListener = new JingleSessionRequestListener() {
|
||||||
public void sessionRequested(final JingleSessionRequest request) {
|
public void sessionRequested(final JingleSessionRequest request) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads());
|
IncomingJingleSession session = request.accept(jm1.getMediaManager().getPayloads());
|
||||||
session.start(request);
|
session.start(request);
|
||||||
|
|
||||||
|
session.addStateListener(new JingleSessionStateListener() {
|
||||||
|
public void beforeChange(JingleNegotiator.State old, JingleNegotiator.State newOne) throws JingleNegotiator.JingleException {
|
||||||
|
if (newOne instanceof IncomingJingleSession.Active) {
|
||||||
|
throw new JingleNegotiator.JingleException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void afterChanged(JingleNegotiator.State old, JingleNegotiator.State newOne) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (XMPPException e) {
|
catch (XMPPException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -96,12 +106,19 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
|
|
||||||
js0.start();
|
js0.start();
|
||||||
|
|
||||||
Thread.sleep(50000);
|
Thread.sleep(20000);
|
||||||
|
|
||||||
|
IncomingJingleSession incomingJingleSession = (IncomingJingleSession) jm1.getSession(js0.getConnection().getUser());
|
||||||
|
incomingJingleSession.removeAllStateListeners();
|
||||||
|
incomingJingleSession.accept();
|
||||||
|
|
||||||
|
Thread.sleep(15000);
|
||||||
|
|
||||||
js0.terminate();
|
js0.terminate();
|
||||||
|
|
||||||
jm1.removeJingleSessionRequestListener(jingleSessionRequestListener);
|
jm1.removeJingleSessionRequestListener(jingleSessionRequestListener);
|
||||||
|
|
||||||
Thread.sleep(6000);
|
Thread.sleep(60000);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
|
@ -139,6 +156,7 @@ public class JingleMediaTest extends SmackTestCase {
|
||||||
MultiMediaManager jingleMediaManager0 = new MultiMediaManager();
|
MultiMediaManager jingleMediaManager0 = new MultiMediaManager();
|
||||||
jingleMediaManager0.addMediaManager(new JmfMediaManager());
|
jingleMediaManager0.addMediaManager(new JmfMediaManager());
|
||||||
jingleMediaManager0.addMediaManager(new SpeexMediaManager());
|
jingleMediaManager0.addMediaManager(new SpeexMediaManager());
|
||||||
|
jingleMediaManager0.setPreferredPayloadType(jingleMediaManager0.getPayloads().get(1));
|
||||||
MultiMediaManager jingleMediaManager1 = new MultiMediaManager();
|
MultiMediaManager jingleMediaManager1 = new MultiMediaManager();
|
||||||
jingleMediaManager1.addMediaManager(new JmfMediaManager());
|
jingleMediaManager1.addMediaManager(new JmfMediaManager());
|
||||||
jingleMediaManager1.addMediaManager(new SpeexMediaManager());
|
jingleMediaManager1.addMediaManager(new SpeexMediaManager());
|
||||||
|
|
Loading…
Reference in a new issue