From 4bc1eb6b66140853e0dead0e86c217899228a091 Mon Sep 17 00:00:00 2001
From: Lyubomir Marinov <lyubomir.marinov@jitsi.org>
Date: Mon, 8 Dec 2014 23:26:11 +0200
Subject: [PATCH] Furthers the support for preserving Buffer flags between
 libjitsi's network and FMJ's media layers.

---
 .../neomedia/RTPConnectorInputStream.java     |  8 ++-
 .../protocol/AbstractPushBufferStream.java    |  5 ++
 .../rtp/translator/PushSourceStreamDesc.java  | 14 ++++
 .../rtp/translator/PushSourceStreamImpl.java  | 66 +++++++++++++++++--
 .../rtp/translator/RTPTranslatorImpl.java     | 11 +++-
 .../transform/srtp/SRTPCryptoContext.java     |  2 +-
 6 files changed, 97 insertions(+), 9 deletions(-)

diff --git a/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java b/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java
index cc3e65da..4c26fe9d 100755
--- a/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java
+++ b/src/org/jitsi/impl/neomedia/RTPConnectorInputStream.java
@@ -18,6 +18,7 @@
 import net.sf.fmj.media.util.*;
 
 import org.ice4j.socket.*;
+import org.jitsi.impl.neomedia.jmfext.media.protocol.*;
 import org.jitsi.impl.neomedia.protocol.*;
 import org.jitsi.service.libjitsi.*;
 import org.jitsi.service.packetlogging.*;
@@ -542,10 +543,15 @@ public long getContentLength()
      */
     public Object getControl(String controlType)
     {
-        if (PushBufferStream.class.getName().equals(controlType))
+        if (AbstractPushBufferStream.PUSH_BUFFER_STREAM_CLASS_NAME.equals(
+                controlType))
+        {
             return pushBufferStream;
+        }
         else
+        {
             return null;
+        }
     }
 
     /**
diff --git a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/AbstractPushBufferStream.java b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/AbstractPushBufferStream.java
index 7017bf75..6118f6d1 100644
--- a/src/org/jitsi/impl/neomedia/jmfext/media/protocol/AbstractPushBufferStream.java
+++ b/src/org/jitsi/impl/neomedia/jmfext/media/protocol/AbstractPushBufferStream.java
@@ -20,6 +20,11 @@ public abstract class AbstractPushBufferStream<T extends PushBufferDataSource>
     extends AbstractBufferStream<T>
     implements PushBufferStream
 {
+    /**
+     * The name of the <tt>PushBufferStream</tt> class.
+     */
+    public static final String PUSH_BUFFER_STREAM_CLASS_NAME
+        = PushBufferStream.class.getName();
 
     /**
      * The <tt>BufferTransferHandler</tt> which is notified by this
diff --git a/src/org/jitsi/impl/neomedia/rtp/translator/PushSourceStreamDesc.java b/src/org/jitsi/impl/neomedia/rtp/translator/PushSourceStreamDesc.java
index b8c45da8..380c9b53 100644
--- a/src/org/jitsi/impl/neomedia/rtp/translator/PushSourceStreamDesc.java
+++ b/src/org/jitsi/impl/neomedia/rtp/translator/PushSourceStreamDesc.java
@@ -8,6 +8,8 @@
 
 import javax.media.protocol.*;
 
+import org.jitsi.impl.neomedia.jmfext.media.protocol.*;
+
 /**
  * Describes a <tt>PushSourceStream</tt> associated with an endpoint from which
  * an <tt>RTPTranslatorImpl</tt> is translating.
@@ -33,6 +35,13 @@ class PushSourceStreamDesc
      */
     public final PushSourceStream stream;
 
+    /**
+     * The <tt>PushBufferStream</tt> control over {@link #stream}, if available,
+     * which may provide Buffer properties other than <tt>data</tt>,
+     * <tt>length</tt> and <tt>offset</tt> such as <tt>flags</tt>.
+     */
+    public final PushBufferStream streamAsPushBufferStream;
+
     /**
      * Initializes a new <tt>PushSourceStreamDesc</tt> instance which is to
      * describe a specific endpoint <tt>PushSourceStream</tt> for an
@@ -54,5 +63,10 @@ public PushSourceStreamDesc(
         this.connectorDesc = connectorDesc;
         this.stream = stream;
         this.data = data;
+
+        streamAsPushBufferStream
+            = (PushBufferStream)
+                stream.getControl(
+                        AbstractPushBufferStream.PUSH_BUFFER_STREAM_CLASS_NAME);
     }
 }
diff --git a/src/org/jitsi/impl/neomedia/rtp/translator/PushSourceStreamImpl.java b/src/org/jitsi/impl/neomedia/rtp/translator/PushSourceStreamImpl.java
index dd0a7b88..a55aab3c 100644
--- a/src/org/jitsi/impl/neomedia/rtp/translator/PushSourceStreamImpl.java
+++ b/src/org/jitsi/impl/neomedia/rtp/translator/PushSourceStreamImpl.java
@@ -10,6 +10,7 @@
 import java.util.*;
 import java.util.concurrent.*;
 
+import javax.media.*;
 import javax.media.protocol.*;
 
 import org.jitsi.impl.neomedia.*;
@@ -224,6 +225,7 @@ public int read(byte[] buffer, int offset, int length)
 
         PushSourceStreamDesc streamDesc = pkt.streamDesc;
         int read = pktLength;
+        int flags = pkt.getFlags();
 
         pkt.streamDesc = null;
         sourcePacketPool.offer(pkt);
@@ -233,7 +235,13 @@ public int read(byte[] buffer, int offset, int length)
             RTPTranslatorImpl translator = getTranslator();
 
             if (translator != null)
-                read = translator.didRead(streamDesc, buffer, offset, read);
+            {
+                read
+                    = translator.didRead(
+                            streamDesc,
+                            buffer, offset, read,
+                            flags);
+            }
         }
 
         return read;
@@ -366,19 +374,46 @@ public void transferData(PushSourceStream stream)
         if ((pkt == null) || ((buf = pkt.getBuffer()).length < len))
         {
             buf = new byte[len];
-            pkt = new SourcePacket(buf, 0, len);
+            pkt = new SourcePacket(buf, 0, 0);
         }
         else
         {
             buf = pkt.getBuffer();
             len = buf.length;
+            pkt.setFlags(0);
+            pkt.setLength(0);
+            pkt.setOffset(0);
         }
 
         int read = 0;
 
         try
         {
-            read = stream.read(buf, 0, len);
+            PushBufferStream streamAsPushBufferStream
+                = streamDesc.streamAsPushBufferStream;
+
+            if (streamAsPushBufferStream == null)
+            {
+                read = stream.read(buf, 0, len);
+            }
+            else
+            {
+                streamAsPushBufferStream.read(pkt);
+                if (pkt.isDiscard())
+                {
+                    read = 0;
+                }
+                else
+                {
+                    read = pkt.getLength();
+                    if ((read < 1)
+                            && ((pkt.getFlags() & Buffer.FLAG_EOM)
+                                    == Buffer.FLAG_EOM))
+                    {
+                        read = -1;
+                    }
+                }
+            }
         }
         catch (IOException ioe)
         {
@@ -389,7 +424,6 @@ public void transferData(PushSourceStream stream)
             if (read > 0)
             {
                 pkt.setLength(read);
-                pkt.setOffset(0);
                 pkt.streamDesc = streamDesc;
 
                 boolean yield;
@@ -441,13 +475,33 @@ else if (readQSize < readQCapacity)
     }
 
     private static class SourcePacket
-        extends RawPacket
+        extends Buffer
     {
+        private byte[] buffer;
+
         public PushSourceStreamDesc streamDesc;
 
         public SourcePacket(byte[] buf, int off, int len)
         {
-            super(buf, off, len);
+            setData(buf);
+            setOffset(off);
+            setLength(len);
+        }
+
+        public byte[] getBuffer()
+        {
+            return buffer;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void setData(Object data)
+        {
+            super.setData(data);
+
+            buffer = (byte[]) data;
         }
     }
 }
diff --git a/src/org/jitsi/impl/neomedia/rtp/translator/RTPTranslatorImpl.java b/src/org/jitsi/impl/neomedia/rtp/translator/RTPTranslatorImpl.java
index b76c2d2d..13d5ed93 100644
--- a/src/org/jitsi/impl/neomedia/rtp/translator/RTPTranslatorImpl.java
+++ b/src/org/jitsi/impl/neomedia/rtp/translator/RTPTranslatorImpl.java
@@ -522,6 +522,7 @@ public SendStream createSendStream(
      * of the received RTP or RTCP packet begin
      * @param length the number of bytes in <tt>buffer</tt> beginning at
      * <tt>offset</tt> which represent the received RTP or RTCP packet
+     * @param flags <tt>Buffer.FLAG_XXX</tt>
      * @return the number of bytes in <tt>buffer</tt> beginning at
      * <tt>offset</tt> which represent the received RTP or RTCP packet
      * @throws IOException if an I/O error occurs while the method processes the
@@ -529,7 +530,8 @@ public SendStream createSendStream(
      */
     int didRead(
             PushSourceStreamDesc streamDesc,
-            byte[] buffer, int offset, int length)
+            byte[] buffer, int offset, int length,
+            int flags)
         throws IOException
     {
         Lock lock = this.lock.readLock();
@@ -557,6 +559,13 @@ int didRead(
                 return length;
             }
 
+            // We flag an RTP packet with Buffer.FLAG_SILENCE when we want to
+            // ignore its payload. Because the payload may have skipped
+            // decryption as a result of the flag, it is unwise to
+            // translate/forward it.
+            if ((flags & Buffer.FLAG_SILENCE) == Buffer.FLAG_SILENCE)
+                return length;
+
             // Do the bytes in the specified buffer resemble (a header of) an
             // RTP packet?
             if ((length >= RTPHeader.SIZE)
diff --git a/src/org/jitsi/impl/neomedia/transform/srtp/SRTPCryptoContext.java b/src/org/jitsi/impl/neomedia/transform/srtp/SRTPCryptoContext.java
index 041481b5..fecbb38d 100644
--- a/src/org/jitsi/impl/neomedia/transform/srtp/SRTPCryptoContext.java
+++ b/src/org/jitsi/impl/neomedia/transform/srtp/SRTPCryptoContext.java
@@ -599,7 +599,7 @@ public boolean reverseTransformPacket(RawPacket pkt)
                 // we want to ignore its payload. In the context of SRTP, we
                 // want to skip its decrypting.
                 if ((pkt.getFlags()
-                            & (Buffer.FLAG_DISCARD /* | Buffer.FLAG_SILENCE */))
+                            & (Buffer.FLAG_DISCARD | Buffer.FLAG_SILENCE))
                         == 0)
                 {
                     switch (policy.getEncType())
-- 
GitLab