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);
+            }
+        }
+    }
+
+
+}

Reply via email to