From cd8c1174fb213fe431134fda6aaf53e4721e2af3 Mon Sep 17 00:00:00 2001
From: Damian Minkov <damencho@jitsi.org>
Date: Tue, 23 Oct 2012 08:29:27 +0000
Subject: [PATCH] Handles payload type change event in receive streams.

---
 .../jitsi/impl/neomedia/MediaStreamImpl.java  | 37 +++++++++++++++++++
 .../AudioMixingPushBufferDataSource.java      | 10 +++++
 .../device/AudioMixerMediaDevice.java         | 30 +++++++++++++++
 .../neomedia/device/MediaDeviceSession.java   | 23 ++++++++++++
 4 files changed, 100 insertions(+)

diff --git a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
index f2d92499..ced31e1f 100644
--- a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
+++ b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
@@ -2400,6 +2400,43 @@ else if (event instanceof TimeoutEvent)
                 }
             }
         }
+        else if (event instanceof RemotePayloadChangeEvent)
+        {
+            ReceiveStream receiveStream = event.getReceiveStream();
+
+            if(receiveStream != null)
+            {
+                MediaDeviceSession deviceSession = getDeviceSession();
+
+                if (deviceSession != null)
+                {
+                    TranscodingDataSource transcodingDataSource
+                        = deviceSession.getTranscodingDataSource(receiveStream);
+
+                    // we receive packets, streams are active
+                    // if processor in transcoding DataSource is running
+                    // we need to recreate it by disconnect, connect
+                    // and starting again the DataSource
+                    try
+                    {
+                        transcodingDataSource.disconnect();
+                        transcodingDataSource.connect();
+                        transcodingDataSource.start();
+
+                        // as output streams of the DataSource
+                        // are recreated we need to update
+                        // mixers and everything that are using them
+                        deviceSession.playbackDataSourceChanged(
+                            receiveStream.getDataSource());
+                    }
+                    catch(IOException e)
+                    {
+                        logger.error("Error re-creating processor in " +
+                            "transcoding DataSource", e);
+                    }
+                }
+            }
+        }
     }
 
     /**
diff --git a/src/org/jitsi/impl/neomedia/conference/AudioMixingPushBufferDataSource.java b/src/org/jitsi/impl/neomedia/conference/AudioMixingPushBufferDataSource.java
index 23e030f5..a3bd62f7 100644
--- a/src/org/jitsi/impl/neomedia/conference/AudioMixingPushBufferDataSource.java
+++ b/src/org/jitsi/impl/neomedia/conference/AudioMixingPushBufferDataSource.java
@@ -107,6 +107,16 @@ public void addInputDataSource(DataSource inputDataSource)
         audioMixer.addInputDataSource(inputDataSource, this);
     }
 
+    /**
+     * The input <tt>DataSource</tt> has been updated.
+     * @param inputDataSource the <tt>DataSource</tt> that was updated.
+     */
+    public void updateInputDataSource(DataSource inputDataSource)
+    {
+        // just update the input streams
+        audioMixer.getOutputStream();
+    }
+
     /**
      * Implements {@link DataSource#connect()}. Lets the <tt>AudioMixer</tt>
      * know that one of its output <tt>PushBufferDataSources</tt> has been
diff --git a/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java b/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java
index 06d6cd3f..820c96b1 100644
--- a/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java
+++ b/src/org/jitsi/impl/neomedia/device/AudioMixerMediaDevice.java
@@ -1017,6 +1017,36 @@ protected void playbackDataSourceRemoved(DataSource playbackDataSource)
                     playbackDataSource);
         }
 
+        /**
+         * Notifies this <tt>MediaDeviceSession</tt> that a <tt>DataSource</tt>
+         * has been updated.
+         *
+         * @param playbackDataSource the <tt>DataSource</tt> which has been
+         * updated.
+         * @see MediaDeviceSession#playbackDataSourceUpdated(DataSource)
+         */
+        @Override
+        protected void playbackDataSourceUpdated(DataSource playbackDataSource)
+        {
+            super.playbackDataSourceUpdated(playbackDataSource);
+
+            DataSource captureDevice = getCaptureDevice();
+
+            /*
+             * Unwrap wrappers of the captureDevice until
+             * AudioMixingPushBufferDataSource is found.
+             */
+            if (captureDevice instanceof PushBufferDataSourceDelegate<?>)
+                captureDevice
+                    = ((PushBufferDataSourceDelegate<?>) captureDevice)
+                        .getDataSource();
+            if (captureDevice instanceof AudioMixingPushBufferDataSource)
+            {
+                ((AudioMixingPushBufferDataSource) captureDevice)
+                    .updateInputDataSource(playbackDataSource);
+            }
+        }
+
         /**
          * The method relays <tt>PropertyChangeEvent</tt>s indicating a change
          * in the SSRC_LIST in the encapsulated mixer device so that the
diff --git a/src/org/jitsi/impl/neomedia/device/MediaDeviceSession.java b/src/org/jitsi/impl/neomedia/device/MediaDeviceSession.java
index 0a684afa..c9dccff8 100644
--- a/src/org/jitsi/impl/neomedia/device/MediaDeviceSession.java
+++ b/src/org/jitsi/impl/neomedia/device/MediaDeviceSession.java
@@ -1172,6 +1172,29 @@ protected void playbackDataSourceRemoved(DataSource playbackDataSource)
     {
     }
 
+    /**
+     * Notifies this <tt>MediaDeviceSession</tt> that a <tt>DataSource</tt> has
+     * been changed on the represented <tt>MediaDevice</tt>.
+     *
+     * @param playbackDataSource the <tt>DataSource</tt> which has been added
+     * for playback on the represented <tt>MediaDevice</tt>
+     */
+    protected void playbackDataSourceUpdated(DataSource playbackDataSource)
+    {
+    }
+
+    /**
+     * Notifies this <tt>MediaDeviceSession</tt> that a <tt>DataSource</tt> has
+     * been changed on the represented <tt>MediaDevice</tt>.
+     *
+     * @param playbackDataSource the <tt>DataSource</tt> which has been added
+     * for playback on the represented <tt>MediaDevice</tt>
+     */
+    public void playbackDataSourceChanged(DataSource playbackDataSource)
+    {
+        playbackDataSourceUpdated(playbackDataSource);
+    }
+
     /**
      * Notifies this instance that a specific <tt>Player</tt> of remote content
      * has generated a <tt>ConfigureCompleteEvent</tt>. Allows extenders to
-- 
GitLab