Revision: 18714
Author: oleg.kulikoff
Date: Wed Jun 1 00:45:39 2011
Log: Issue 2463: CNF mode
http://code.google.com/p/mobicents/source/detail?r=18714
Modified:
/trunk/servers/media/chassis/src/main/java/org/mobicents/media/server/connection/BaseConnection.java
/trunk/servers/media/chassis/src/main/java/org/mobicents/media/server/connection/Channel.java
/trunk/servers/media/chassis/src/main/java/org/mobicents/media/server/connection/Connections.java
=======================================
---
/trunk/servers/media/chassis/src/main/java/org/mobicents/media/server/connection/BaseConnection.java
Wed May 18 19:03:44 2011
+++
/trunk/servers/media/chassis/src/main/java/org/mobicents/media/server/connection/BaseConnection.java
Wed Jun 1 00:45:39 2011
@@ -110,8 +110,8 @@
heartBeat = new HeartBeat(scheduler);
//intialize media channels
- audioChannel = new Channel(connections, MediaType.AUDIO, new
AudioMixer(scheduler), new Splitter(scheduler));
- videoChannel = new Channel(connections, MediaType.AUDIO, new
VideoMixer(scheduler), new Splitter(scheduler));
+ audioChannel = new Channel(this, connections, MediaType.AUDIO, new
AudioMixer(scheduler), new Splitter(scheduler));
+ videoChannel = new Channel(this, connections, MediaType.AUDIO, new
VideoMixer(scheduler), new Splitter(scheduler));
//create sdp template
audioFormats = getRTPMap(audioChannel, AVProfile.audio);
=======================================
---
/trunk/servers/media/chassis/src/main/java/org/mobicents/media/server/connection/Channel.java
Tue May 3 01:28:55 2011
+++
/trunk/servers/media/chassis/src/main/java/org/mobicents/media/server/connection/Channel.java
Wed Jun 1 00:45:39 2011
@@ -43,6 +43,7 @@
*/
public class Channel {
+ private BaseConnection connection;
private MediaType mediaType;
protected Mixer mixer;
@@ -57,9 +58,11 @@
private SendOnlyMode sendOnly;
private SendRecvMode send_recv;
private NetworkLoopMode network_loop;
+ private CnfMode cnfMode;
private Mode mode;
- public Channel(Connections connections, MediaType mediaType, Mixer
mixer, Splitter splitter) throws Exception {
+ public Channel(BaseConnection connection, Connections connections,
MediaType mediaType, Mixer mixer, Splitter splitter) throws Exception {
+ this.connection = connection;
this.mediaType = mediaType;
//create mixer and assign intermediate format
@@ -82,6 +85,7 @@
sendOnly = new SendOnlyMode(connections);
send_recv = new SendRecvMode(sendOnly, recvOnly);
network_loop = new NetworkLoopMode();
+ cnfMode = new CnfMode(connection, connections, sendOnly, recvOnly);
}
protected Formats getFormats() {
@@ -158,6 +162,8 @@
return sendOnly;
case SEND_RECV:
return send_recv;
+ case CONFERENCE:
+ return cnfMode;
case NETWORK_LOOPBACK:
return network_loop;
case INACTIVE:
@@ -484,6 +490,40 @@
}
+ /**
+ * Conference mode
+ */
+ private class CnfMode extends Mode {
+
+ private Connections connections;
+ private BaseConnection connection;
+
+ private SendRecvMode sendRecv;
+
+ public CnfMode(BaseConnection connection, Connections connections,
SendOnlyMode sendOnly, RecvOnlyMode recvOnly) {
+ this.connection = connection;
+ this.connections = connections;
+ sendRecv = new SendRecvMode(sendOnly, recvOnly);
+ }
+
+ @Override
+ public ConnectionMode getID() {
+ return ConnectionMode.CONFERENCE;
+ }
+
+ @Override
+ public void activate() throws FormatNotSupportedException {
+ connections.addToConference(connection);
+ sendRecv.activate();
+ }
+
+ @Override
+ public void deactivate() {
+ connections.removeFromConference(connection);
+ sendRecv.deactivate();
+ }
+
+ }
/**
* Implements connection's check points
*/
=======================================
---
/trunk/servers/media/chassis/src/main/java/org/mobicents/media/server/connection/Connections.java
Fri May 6 04:30:58 2011
+++
/trunk/servers/media/chassis/src/main/java/org/mobicents/media/server/connection/Connections.java
Wed Jun 1 00:45:39 2011
@@ -82,6 +82,11 @@
//video channel joining connections with endpoint
protected Channel videoChannel;
+ /**
+ * active local channels
+ */
+ private ArrayList<LocalChannel> localChannels = new ArrayList();
+
//intermediate audio and video formats.
private Formats audioFormats = new Formats();
private Formats videoFormats = new Formats();
@@ -339,6 +344,31 @@
}
}
+ protected void addToConference(BaseConnection connection) {
+ for (BaseConnection c : activeConnections) {
+ if (c.getMode(MediaType.AUDIO) == ConnectionMode.CONFERENCE) {
+ LocalChannel channel = new LocalChannel();
+ channel.join(connection, c);
+ localChannels.add(channel);
+ }
+ }
+ }
+
+ protected void removeFromConference(BaseConnection connection) {
+ LocalChannel channel = null;
+ for (LocalChannel c : localChannels) {
+ if (c.match(connection)) {
+ channel = c;
+ break;
+ }
+ }
+
+ if (channel != null) {
+ localChannels.remove(channel);
+ channel.unjoin();
+ }
+ }
+
/**
* Reads data from specified check point.
*
@@ -367,7 +397,7 @@
}
/**
- * Transmission channel
+ * Transmission channel between connections and endpoint
*/
protected class Channel {
protected Mixer mixer;
@@ -744,4 +774,60 @@
return String.format("frame=%d, bytes=%d", frames, bytes);
}
}
-}
+
+ /**
+ * Channel for joining connections in CNF mode.
+ */
+ private class LocalChannel {
+ private Party party1 = new Party();
+ private Party party2 = new Party();
+
+ private PipeImpl audioRxPipe = new PipeImpl();
+ private PipeImpl audioTxPipe = new PipeImpl();
+
+ private void join(BaseConnection connection1, BaseConnection
connection2) {
+ party1.connection = connection1;
+ party2.connection = connection2;
+
+ party1.source = connection1.audioChannel.splitter.newOutput();
+ party2.sink = connection2.audioChannel.mixer.newInput();
+
+ audioRxPipe.connect(party2.sink);
+ audioRxPipe.connect(party1.source);
+
+ party2.source = connection2.audioChannel.splitter.newOutput();
+ party1.sink = connection1.audioChannel.mixer.newInput();
+
+ audioTxPipe.connect(party1.sink);
+ audioTxPipe.connect(party2.source);
+
+ audioRxPipe.start();
+ audioTxPipe.start();
+ }
+
+ public boolean match(BaseConnection connection) {
+ return connection == party1.connection || connection ==
party2.connection;
+ }
+
+ public void unjoin() {
+ audioTxPipe.stop();
+ audioTxPipe.stop();
+
+ party1.release();
+ party2.release();
+ }
+
+ private class Party {
+ private BaseConnection connection;
+ private MediaSource source;
+ private MediaSink sink;
+
+ private void release() {
+ connection.audioChannel.splitter.release(source);
+ connection.audioChannel.mixer.release(sink);
+ }
+ }
+ }
+
+
+}