diff --git a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
index 6a97530907c2e327243f739fba6b8a79e7170448..feef7edb024a0cf1e5df69c416acbce2f6769623 100644
--- a/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
+++ b/src/org/jitsi/impl/neomedia/MediaStreamImpl.java
@@ -1879,7 +1879,22 @@ private void stop(MediaDirection direction)
                 && (MediaDirection.SENDRECV.equals(startedDirection)
                         || MediaDirection.SENDONLY.equals(startedDirection)))
         {
-            stopSendStreams(false);
+            /*
+             * XXX It is not very clear at the time of this writing whether the
+             * SendStreams are to be stopped or closed. On one hand, stopping a
+             * direction may be a temporary transition which relies on retaining
+             * the SSRC. On the other hand, it may be permanent. In which case,
+             * the respective ReveiveStream on the remote peer will timeout at
+             * some point in time. In the context of video conferences, when a
+             * member stops the streaming of their video without leaving the
+             * conference, they will stop their SendStreams. However, the other
+             * members will need respective BYE RTCP packets in order to know
+             * that they are to remove the associated ReceiveStreams from
+             * display. The initial version of the code here used to stop the
+             * SendStreams without closing them but, given the considerations
+             * above, it is being changed to close them in the case of video.
+             */
+            stopSendStreams(this instanceof VideoMediaStream);
 
             if (deviceSession != null)
                 deviceSession.stop(MediaDirection.SENDONLY);
@@ -1951,9 +1966,11 @@ private void stopReceiveStreams()
                 try
                 {
                     if (logger.isTraceEnabled())
+                    {
                         logger.trace(
                                 "Stopping receive stream with hashcode "
                                     + receiveStream.hashCode());
+                    }
 
                     DataSource receiveStreamDataSource
                         = receiveStream.getDataSource();
diff --git a/src/org/jitsi/impl/neomedia/RTPTranslatorImpl.java b/src/org/jitsi/impl/neomedia/RTPTranslatorImpl.java
index d03ef4efc5516e5721d70802bbeb5382eb0d9a8d..b7490c4b97f8ad2dbe4349dd3c43d0029f6833b8 100644
--- a/src/org/jitsi/impl/neomedia/RTPTranslatorImpl.java
+++ b/src/org/jitsi/impl/neomedia/RTPTranslatorImpl.java
@@ -339,6 +339,55 @@ public synchronized void initialize(
         }
     }
 
+    /**
+     * Logs information about an RTCP packet using {@link #logger} for debugging
+     * purposes.
+     *
+     * @param obj the object which is the source of the log request
+     * @param methodName the name of the method on <tt>obj</tt> which is the
+     * source of the log request
+     * @param buffer the <tt>byte</tt>s which (possibly) represent an RTCP
+     * packet to be logged for debugging purposes
+     * @param offset the position within <tt>buffer</tt> at which the valid data
+     * begins
+     * @param length the number of bytes in <tt>buffer</tt> which constitute the
+     * valid data 
+     */
+    private static void logRTCP(
+            Object obj, String methodName,
+            byte[] buffer, int offset, int length)
+    {
+        if (length > 8)
+        {
+            byte b0 = buffer[offset];
+            int v = (b0 & 0xc0) >>> 6;
+
+            if (v == 2)
+            {
+                byte b1 = buffer[offset + 1];
+                int pt = b1 & 0xff;
+
+                if (pt == 203 /* BYE */)
+                {
+                    int sc = b0 & 0x1f;
+                    long ssrc = (sc > 0) ? readInt(buffer, offset + 4) : -1;
+
+                    logger.trace(
+                            obj.getClass().getName()
+                                + '.'
+                                + methodName
+                                + ": RTCP BYE v="
+                                + v
+                                + "; pt="
+                                + pt
+                                + "; ssrc="
+                                + ssrc
+                                + ';');
+                }
+            }
+        }
+    }
+
     private int read(
             PushSourceStreamDesc streamDesc,
             byte[] buffer, int offset, int length,
@@ -372,6 +421,8 @@ private int read(
                 format = streamRTPManagerDesc.getFormat(payloadType);
             }
         }
+        else if (logger.isTraceEnabled())
+            logRTCP(this, "read", buffer, offset, read);
 
         OutputDataStreamImpl outputStream
             = data
@@ -560,23 +611,32 @@ private synchronized int doWrite(
 
                 if (streamRTPManagerDesc != exclusion)
                 {
-                    if (data && (format != null) && (length > 0))
+                    if (data)
                     {
-                        Integer payloadType
-                            = streamRTPManagerDesc.getPayloadType(format);
-
-                        if ((payloadType == null) && (exclusion != null))
-                            payloadType = exclusion.getPayloadType(format);
-                        if (payloadType != null)
+                        if ((format != null) && (length > 0))
                         {
-                            int payloadTypeByteIndex = offset + 1;
+                            Integer payloadType
+                                = streamRTPManagerDesc.getPayloadType(format);
 
-                            buffer[payloadTypeByteIndex]
-                                = (byte)
-                                    ((buffer[payloadTypeByteIndex] & 0x80)
-                                        | (payloadType & 0x7f));
+                            if ((payloadType == null) && (exclusion != null))
+                                payloadType = exclusion.getPayloadType(format);
+                            if (payloadType != null)
+                            {
+                                int payloadTypeByteIndex = offset + 1;
+
+                                buffer[payloadTypeByteIndex]
+                                    = (byte)
+                                        ((buffer[payloadTypeByteIndex] & 0x80)
+                                            | (payloadType & 0x7f));
+                            }
                         }
                     }
+                    else if (logger.isTraceEnabled())
+                    {
+                        logRTCP(
+                                this, "doWrite",
+                                buffer, offset, length);
+                    }
 
                     int streamWrite
                         = streamDesc.stream.write(buffer, offset, length);
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java
index e840d3a82b20dbaf13a9827f6e954dd0c8190f1b..c0bb159bf03ce70487e40b713dfe30582cfab3a7 100644
--- a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/portaudio/PortAudioStream.java
@@ -242,6 +242,12 @@ synchronized void setDeviceIndex(int deviceIndex)
         // DataSource#disconnect
         if (this.deviceIndex != PortAudio.paNoDevice)
         {
+            /*
+             * Just to be on the safe side, make sure #read(Buffer) is not
+             * currently executing.
+             */
+            waitWhileStreamIsBusy();
+
             if (stream != 0)
             {
                 try
@@ -420,21 +426,7 @@ public synchronized void start()
     public synchronized void stop()
         throws IOException
     {
-        boolean interrupted = false;
-
-        while (streamIsBusy)
-        {
-            try
-            {
-                wait();
-            }
-            catch (InterruptedException iex)
-            {
-                interrupted = true;
-            }
-        }
-        if (interrupted)
-            Thread.currentThread().interrupt();
+        waitWhileStreamIsBusy();
 
         try
         {
@@ -450,4 +442,28 @@ public synchronized void stop()
             throw ioex;
         }
     }
+
+    /**
+     * Waits on this instance while {@link #streamIsBusy} is equal to
+     * <tt>true</tt> i.e. until it becomes <tt>false</tt>. The method should
+     * only be called by a thread that is the owner of this object's monitor.
+     */
+    private void waitWhileStreamIsBusy()
+    {
+        boolean interrupted = false;
+
+        while ((stream != 0) && streamIsBusy)
+        {
+            try
+            {
+                wait();
+            }
+            catch (InterruptedException iex)
+            {
+                interrupted = true;
+            }
+        }
+        if (interrupted)
+            Thread.currentThread().interrupt();
+    }
 }